I am trying to get my render function to work. I am using vertex arrays. Here is the my vertex structure.
struct Vertex
{
float x, y, z; // The x, y and z floating point values
float u, v; // The u - v texture coordinates
float padding[3]; // needs to be multiple of 32
};
Here is my render code:
// Render the mesh
void WLD::render(GLuint* textures, long curRegion, CFrustum cfrustum)
{
int num = 0;
// Set up my indices
GLuint indicies[3];
// Cycle through the PVS
while(num < regions[curRegion].visibility.size())
{
int i = regions[curRegion].visibility[num];
if(!regions[i].dead && regions[i].meshptr != NULL)
{
if(cfrustum.BoxInFrustum(regions[i].meshptr->min[0], regions[i].meshptr->min[2], regions[i].meshptr->min[1], regions[i].meshptr->max[0], regions[i].meshptr->max[2], regions[i].meshptr->max[1]))
{
// Cycle through every polygon in the mesh and render it
for(int j = 0; j < regions[i].meshptr->polygonCount; j++)
{
// Assign the index for the polygon to the index in the huge vertex array
indicies[0] = regions[i].meshptr->poly[j].vertIndex[0];
indicies[1] = regions[i].meshptr->poly[j].vertIndex[1];
indicies[2] = regions[i].meshptr->poly[j].vertIndex[2];
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &verticies[0].x);
// Texture index
int tex = regions[i].meshptr->poly[j].tex;
// Need to bind this to the polygon I render.
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &verticies[0].u);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indicies);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
}
num++;
}
}
One of the arguments, GLuint* textures contains all the loaded textures. So the value returned by line int tex = regions[i].meshptr->poly[j].tex; is the index in the textures for this specific polygon. How do I bind that to each polygon when I render it? Let me know if you have any questions.
I know I need to use glClientActiveTexture() but one, it says it's undefined and I can't find the correct header, and two, I have no idea how it is used. I couldn't find any good examples. So how do I, if say the polygon references texture index 4, bind it to the polygon as I render with glClientActiveTexture.
What you are trying to do is not generally possible. You usually do not attempt to render a single stream of triangles (a glDraw*
call) with multiple textures. Well, not the way you mean, at any rate.
Each triangle within a single draw call must pull from the same set of textures as every other triangle within that draw call.
The general solution is to combine the images into a single texture. This is commonly called a "texture atlas". In this case, the texture coordinates on the vertices describe where in the texture atlas (which is a single texture) to pull image data from.
If you are using GL 4.0-capable hardware (D3D11) and GLSL, then there are tricks you can play to dynamically select between 16 textures based on arbitrary computations. And for earlier hardware, you could use shaders to pick between textures. But both cases would be slower than just massaging the data properly.
You can do this with your currect approach. You don't need glClientActiveTexture
. This function is for multitexturing and I suppose every polygon has only a single texture applied. So just bind the neccessary texture using glBindTexture(GL_TEXTURE_2D, textures[tex])
and don't forget to glEnable(GL_TEXTURE_2D)
(if not using shaders) before drawing the polygon.
But although it works, this is obviously not the best way to do it. Vertex arrays are there to render multiple primitives (triangles) in one go (one call to glDrawElements
) and you missuse them to render single triangles. The first and easiest idea would be to at least sort your polygons by texture index and then render all triangles with the same texture in one call to glDrawElements
. Look at Nicol's answer for more advanced approaches.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With