(switched to PyOpenGL users, which is a slightly more appropriate venue
for the discussion)
First things first, glDrawArrays:
http://pyopengl.sourceforge.net/documentation/manual/glDrawArrays.3G.html
It includes a start index, and a count of items to render. If you are
going to call this method on each pass of the renderer, you should
compute those values (start, count) for each texture and then render
with three calls to glDrawArrays from the cached values. Note, however,
that glDrawArrays assumes flat arrays of data. You would need to pull
out the data into those flat arrays, which can significantly bloat the
data going across the memory bus.
So the next approach, glDrawElements:
http://pyopengl.sourceforge.net/documentation/manual/glDrawElements.3G.html
Designed for indexed geometry, glDrawElements takes an array of indices
to draw from the enabled arrays. In your case, you would need to create
new arrays from your index array, with each being simply the actual
indices to render (no -1's) for the particular texture. You would cache
those numTexture arrays, then render the geometry with numTexture calls
to glDrawElements.
You'll find sample code for glDrawArrays and glDrawElements linked off
the pages above. Note, however, that if this is static geometry, you
might be better off simply compiling to a display list.
Hope this helps,
Mike
TheDustbustr wrote:
>My renderer is written in python, and thats about all this has to do with this
>newsgroup, hence the [OT]
>
>This one has been bugging me forever, and nobody seems to know the answer (not
>even google!) Once I have created a triangle mesh, what is the best way to
>texture it (with potentially different textures for each triangle)? My current
>method, when used with a medium sized mesh (8000 triangles), yeilds me 40
>frames per second (I have a Geforce 4)- I should be getting about 200.
>
> glVertexPointerf(VertexArray)
> prevtexture=""
> for ind_i in range(0, len(IndiceArray), 3):
> if (VertexArray[int(IndiceArray[ind_i])][1] <= 0) and (prevtexture
>!= "data/water-0.bmp"):
> glBindTexture(GL_TEXTURE_2D,
>ResourceMgr().get("data/water-0.bmp"))
> prevtexture="data/water-0.bmp"
> elif (VertexArray[int(IndiceArray[ind_i])][1] > 3 and
>VertexArray[int(IndiceArray[ind_i])][1] <= 10) and (prevtexture !=
>"data/grass-0.bmp"):
> glBindTexture(GL_TEXTURE_2D,
>ResourceMgr().get("data/grass-0.bmp"))
> prevtexture="data/grass-0.bmp"
> elif (VertexArray[int(IndiceArray[ind_i])][1] > 0 and
>VertexArray[int(IndiceArray[ind_i])][1] <= 3) and (prevtexture !=
>"data/dirt-0.bmp"):
> glBindTexture(GL_TEXTURE_2D,
>ResourceMgr().get("data/dirt-0.bmp"))
> prevtexture="data/dirt-0.bmp"
>
> glBegin(GL_TRIANGLES)
> glArrayElement(IndiceArray[ind_i])
> glArrayElement(IndiceArray[ind_i+1])
> glArrayElement(IndiceArray[ind_i+2])
> glEnd()
>
>IndiceArray is sorted by texture, so glBindTexture should only be called once
>per texture per frame (in this case, 3 times per frame). Is there a better way
>to do this?
>
>If I render the terrain with just one tiled texture, I get roughly 120 frames
>per second.
>
>
_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
|