I'm working in python / PyOpenGL, but the calls are basically mapped straight to OpenGL itself so I'm asking for help from people who know either.
I've got a big 3D system which I've decomposed into facets myself. My first attempt at the code looked something like this:
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()
i.e. I ran over the python objects one at a time, and drew them each individually. The color rendered was set per facet, i.e. per triangle, as the triangle's surface color.
Having debugged my code for generating the facets this way, I wanted to render them faster using a native OpenGL list, like this (based on a source snippet from 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)
However, my colors come out completely wrong. The facets are grouped into objects, and within an object all the facet colors should be the same; instead they seem to be completely random.
Looking at other examples, it seems that this array of colors is per-vertex rather than per-facet. How does that make sense? Vertices are points which by definition can't be rendered - the facets are what are rendered and what have colors! Every vertex in my system is shared between two of the facet-collections / objects, and thus should have two colours to its name.
Someone please clarify how this data is supposed to be structured; I have clearly misunderstood the model I'm working with.