0

我在 python/PyOpenGL 中工作,但是这些调用基本上直接映射到 OpenGL 本身,所以我正在寻求任何知道的人的帮助。

我有一个大型 3D 系统,我自己将其分解为多个方面。我对代码的第一次尝试看起来像这样:

from OpenGL.GL import *

def render(facets):
  for facet in facets:
    glColor( facet['color'] )
    glBegin(GL_TRIANGLES)
    for v in facet['vertices']:
      glVertex(v)
    glEnd()

即我一次一个地遍历python对象,并分别绘制它们。渲染的颜色被设置为每个 facet,即每个三角形,作为三角形的表面颜色。

在调试了以这种方式生成构面的代码后,我想使用原生 OpenGL 列表更快地呈现它们,如下所示(基于 pyglet 的源代码片段):

def build_compiled_gllist(vertices, facets):
  """this time, the vertices must be specified globally, and referenced by
  indices in order to use the list paradigm. vertices is a list of 3-vectors, and
  facets are dicts containing 'normal' (a 3-vector) 'vertices' (indices to the 
  other argument) and 'color' (the color the triangle should be)."""

  # first flatten out the arrays:
  vertices = [x for point in vertices for x in point]
  normals = [x for facet in facets for x in facet['normal']]
  indices = [i for facet in facets for i in facet['vertices']]
  colors = [x for facet in facets for x in facet['color']]

  # then convert to OpenGL / ctypes arrays:
  vertices = (GLfloat * len(vertices))(*vertices)
  normals = (GLfloat * len(normals))(*normals)
  indices = (GLuint * len(indices))(*indices)
  colors = (GLfloat * len(colors))(*colors)

  # finally, build the list:
  list = glGenLists(1)
  glNewList(list, GL_COMPILE)

  glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
  glEnableClientState(GL_VERTEX_ARRAY)
  glEnableClientState(GL_NORMAL_ARRAY)
  glEnableClientState(GL_COLOR_ARRAY)
  glVertexPointer(3, GL_FLOAT, 0, vertices)
  glNormalPointer(GL_FLOAT, 0, normals)
  glColorPointer(3, GL_FLOAT, 0, colors)
  glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, indices)
  glPopClientAttrib()

  glEndList()

  return list

def run_gl_render(render_list):
  """trivial render function"""
  glCallList(render_list)

但是,我的颜色完全错误。刻面被分组到对象中,并且在一个对象内,所有的刻面颜色应该是相同的;相反,它们似乎是完全随机的。

查看其他示例,似乎这个颜色数组是per-vertex而不是per-facet。这有什么意义?顶点是根据定义不能渲染的点——刻面是渲染的和有颜色的!我系统中的每个顶点都在两个方面集合/对象之间共享,因此它的名称应该有两种颜色。

有人请澄清这些数据应该如何构造;我显然误解了我正在使用的模型。

4

1 回答 1

3

是的,颜色是按顶点指定的。根据阴影模型,只能使用其中一种颜色,但每个顶点仍会获得一种颜色。如果您替换,您的代码应该可以工作

colors = [x for facet in facets for x in facet['color']]

colors = [x for facet in facets for x in facet['color']*3]

复制每个顶点的颜色。如果您的普通数据是按人脸计算的,那么您必须对普通数据执行相同的操作。另请注意,颜色和法线值必须与顶点参数匹配,而不是索引。

顺便说一句,您仍然可以使用原始代码创建显示列表。也就是说,这样做是完全有效的

def compile_object(facets):
  displist = glGenLists(1)
  glNewList(displist, GL_COMPILE)
  # You can call glColor inside of glBegin/glEnd, so I moved them
  # outside the loop, which might improve performance somewhat
  glBegin(GL_TRIANGLES)
  for facet in facets:
    glColor( facet['color'] )
    for v in facet['vertices']:
      glVertex(v)
  glEnd()
  glEndList()
  return displist

试试这些教程

于 2013-01-15T17:16:03.883 回答