OpenGL在列表中给出三角形颜色

时间:2013-01-15 16:20:16

标签: python opengl pyopengl

我正在使用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()

即。我一次一个地跑过蟒蛇对象,然后分别画出它们。渲染的颜色设置为每个面,即每个三角形,作为三角形的表面颜色。

通过这种方式调试我的代码以生成构面,我希望使用原生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 。这有什么意义?顶点是根据定义无法渲染的点 - 刻面是渲染的内容和具有颜色的内容!我的系统中的每个顶点都在两个facet-collections /对象之间共享,因此其名称应该有两种颜色。

有人请说明这些数据应如何构建;我明显误解了我正在使用的模型。

1 个答案:

答案 0 :(得分: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

试试这些教程