我在一个PyOpenGL程序中使用了一种删除隐藏线的方法,其中我绘制了两次图形,一次是线框,另一次是填充的多边形.它对我自己的数字运行得很好,但不适用于基本的GluSolidCube/GluWireCube,所以我很好奇使用过剩数字expose 了我的代码中是否存在缺陷.也许在过剩的数字中有一些奇怪的东西,但我猜这些都被很好地使用和调试了……
以下是我的绘图代码(下面是正在运行的应用程序),后面是结果的屏幕截图:
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()
Screen shot (glut-based figure on left, my figure on right):