PyOpenGL,隐藏线去除和过剩

问题描述 投票:0回答:1

我正在 PyOpenGL 程序中使用一种去除隐藏线的方法,其中我绘制了两次图形,一次作为线框,然后再次作为填充多边形。它对于我自己的数字工作得很好,但对于基本的 glutSolidCube/glutWireCube 却不起作用,所以我很好奇我的代码中是否存在使用 glut 数字所暴露的缺陷。也许过剩的数字有些奇怪,但我猜这些都得到了很好的使用和调试......

这是我的绘制代码(如下是工作应用程序),然后是结果的屏幕截图:

def render_scene():
    glEnableClientState(GL_VERTEX_ARRAY)
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLineWidth(2)

    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    
    glRotate(rot[0], 1, 0, 0)
    glRotate(rot[1], 0, 1, 0)
    #
    # =============
    # pass 1: lines
    # =============
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)    
    glColor(0, 0, 0)
    # my cube
    glVertexPointer(3, GL_FLOAT, 0, cube_vertices)
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutWireCube(1)
    glPopMatrix()
    #
    # ================
    # pass 2: filled polygons
    # ================
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
    glEnable(GL_POLYGON_OFFSET_FILL)
    glPolygonOffset(2, 2)
    glColor(1, 1, 1)
    # my cube
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutSolidCube(1)
    glPopMatrix()
   
    glPopMatrix()
    pg.display.flip()
    return

提前致谢!

运行代码:

import pygame as pg
from pygame.locals import *
from numpy import array, float32, uint32
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *

FPS = 60
WIDTH = 800
HEIGHT = 600
clock = pg.time.Clock()
rot = [10, 10]

cube_vertices = array([
    -0.5, -0.5, -0.5,
    0.5, -0.5, -0.5,
    0.5, 0.5, -0.5,
    -0.5, 0.5, -0.5,
    -0.5, -0.5, 0.5,
    0.5, -0.5, 0.5,
    0.5, 0.5, 0.5,
    -0.5, 0.5, 0.5], dtype=float32)   

cube_indices = array([
    0, 1, 2, 3,   # front 
    4, 5, 1, 0,   # top
    3, 2, 6, 7,   # bottom
    5, 4, 7, 6,   # back
    1, 5, 6, 2,   # right
    4, 0, 3, 7], dtype=uint32)    


def setup_rc():
    
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    glCullFace(GL_FRONT)
    glClearColor(1, 1, 1, 0)  
    
    pg.event.post(pg.event.Event(VIDEORESIZE, {'size':(WIDTH, HEIGHT)}))

    return


def on_video_resize(event):
    w = event.size[0]
    h = event.size[1]
    if h == 0: h = 1
    aspect_ratio = w/h

    glViewport (0, 0, w, h)
    glMatrixMode (GL_PROJECTION)
    glLoadIdentity()
    if w <= h:
        glOrtho (-1.5, 1.5, -1.5*h/w, 1.5*h/w, -10.0, 10.0)
    else:
        glOrtho (-1.5*w/h, 1.5*w/h, -1.5, 1.5, -10.0, 10.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    return True

def render_scene():
    glEnableClientState(GL_VERTEX_ARRAY)
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLineWidth(2)

    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    
    glRotate(rot[0], 1, 0, 0)
    glRotate(rot[1], 0, 1, 0)
    #
    # =============
    # pass 1: lines
    # =============
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)    
    glColor(0, 0, 0)
    # my cube
    glVertexPointer(3, GL_FLOAT, 0, cube_vertices)
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutWireCube(1)
    glPopMatrix()
    #
    # ================
    # pass 2: filled polygons
    # ================
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
    glEnable(GL_POLYGON_OFFSET_FILL)
    glPolygonOffset(2, 2)
    glColor(1, 1, 1)
    # my cube
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutSolidCube(1)
    glPopMatrix()
   
    glPopMatrix()
    pg.display.flip()
    return

def update():
    clock.tick(FPS)
    return

def on_keydown(event):
    key = event.key
    if key == K_LEFT:
        rot[1] -= 2
    elif key == K_RIGHT:
        rot[1] += 2
    if key == K_UP:
        rot[0] -= 2
    elif key == K_DOWN:
        rot[0] += 2
    elif key == K_ESCAPE:    
        pg.event.post(pg.event.Event(QUIT))
    return True

def main():
    pg.init()
    pg.display.set_mode((WIDTH, HEIGHT), DOUBLEBUF|OPENGL|RESIZABLE)
    pg.key.set_repeat(200, 100)
    pg.display.set_caption("Use arrow keys to rotate scene")
    glutInit()

    setup_rc()
    
    add_event_handler(VIDEORESIZE, on_video_resize)
    add_event_handler(KEYDOWN, on_keydown)
    
    while do_events():
        render_scene()
        update()

    pg.quit()
    return 

# =======================================
# my simplified pygame event handling, 
# normally in a separate module but wanted
# to make this code standalone
# =======================================
#
event_map = {pg.QUIT : (lambda e: False)}

def add_event_handler(key, func):  
    event_map[key] = func
    return

def try_to_apply(e):
    try:
        return event_map[e.type](e)
    except KeyError:
        return True

def do_events():
    return all(try_to_apply(e) for e in pg.event.get())

# ========================================

main()

屏幕截图(左边是基于过剩的图,右边是我的图):

python opengl glut pyopengl
1个回答
0
投票

问题在于您正在混合面剔除和多边形偏移。

glutSolidCube
/
glutWireCube
的缠绕顺序似乎与您自己的网格体的缠绕顺序相反。禁用面部剔除。另请注意,
glutSolidCube
/
glutWireCube
可能会更改客户端状态,因此在绘制几何图形之前,您应该始终使用
glVertexPointer
指定顶点指针:

def setup_rc():    
    glEnable(GL_DEPTH_TEST)
    #glEnable(GL_CULL_FACE)
    #glCullFace(GL_FRONT)
    glClearColor(1, 1, 1, 0)  
def render_scene():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLineWidth(2)

    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    
    glRotate(rot[0], 1, 0, 0)
    glRotate(rot[1], 0, 1, 0)
    #
    # =============
    # pass 1: lines
    # =============
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)  
    glDisable(GL_POLYGON_OFFSET_FILL)  
    glColor(0, 0, 0)
    # my cube
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, cube_vertices)
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutWireCube(1)
    glPopMatrix()
    #
    # ================
    # pass 2: filled polygons
    # ================
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
    glEnable(GL_POLYGON_OFFSET_FILL)
    glPolygonOffset(2, 2)
    glColor(1, 1, 0)
    # my cube
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, cube_vertices)
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cube_indices)
    # glut cube
    glPushMatrix()
    glTranslate(-1.1, 0, 0)
    glutSolidCube(1)
    glPopMatrix()
   
    glPopMatrix()
    glFlush()
© www.soinside.com 2019 - 2024. All rights reserved.