Display lists and texture coordinates
Hi.
Yes you need to provide the tex-coords before the vertex - any vertex attribute has to be set before the glVertex call which effectively tells GL that you're done specifying attributes for that vertex.
What I suggest you do is to change from display list to buffer objects. You can have the positions in one buffer (ArrayElement) and the texture coordinates (ArrayElement) in other buffers. When rendering your quad, you always use bind the position buffer and then for the quad, select and bind the appropriate buffer with texture coordinates. Then you draw your buffer object.
If the texture coordinates are easily (algorithmically) computable you can stay with display list and compute the texture coordinates in a vertex shader.
It sounds a bit as if you're using a texture atlas approach... If that is the case, it might be possible to supply the texture coordinates as Uniform variables. You would need to supply the offset and extent for each tile, and then compute the per-vertex texture coordinates.
kind regards,
Nicolai
If I specify a variable outside of glNewList() and then utilize that variable inside, is it used as that value at that given time, or does the list expect that variable when the list is called each time so it can compute based on the variable value when the list is called?
When you are finished defining a display list with glEndList() it is never modified again. The list is compiled and you can not change anything, anymore, forever. When you use variables to define the display list, they are only evaluated once - "it is used as that value at that given time".
Example:
float lineLength = 30;
glNewList(id, GL_COMPILE);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(lineLength, 0, 0);
glEnd();
glEndList();
When this code is run, the line drawn will be 30 units along the x-axis - forever. If you want another lineLength, you would have to destroy the display list and create a new one. Display lists may be fast but they are not flexible. Use them only for things that never change (like setting up a considerable, fixed number of OpenGL states). For everything else, look into Vertex Buffer Objects (VBO).
-----
The uniform variables I talked about are programmable shader variables. A shader is small program that can be enabled or disabled like any other OpenGL state. Uniform variables are used to parameterize your shade. A shader can change the texture coordinates by using uniform variables. It could look something like this when rendering (lets assume the shader program has been set up already):
// texture coordinates
float texCoordS = 0.5;
float texCoordT = 0.5;
// specify a uniform variable
glUniform2f(locationOfShaderVariable, texCoordS, texCoordT);
// enable the shader program
glUseProgram(programID);
// use your previously defined display list
glCallList(myDisplayListID);
The shader program could then modify the texture coordinates in the display list using the uniform variables you specified.
-----
Using shaders may be a bit too advanced at the moment. Instead, I recommend you look into using Vertex Buffer Objects to solve your problem with different texture coordinates. VBO's are more complicated than display lists but you have a lot more flexibility. VBO's also tend to take up less memory than display lists and when used correctly they are as fast as display lists.
kind regards,
Nicolai
If you use a texture atlas (a texture containing all the tile images) you could use the texture matrix to scale, translate and even rotate the texture coordinates. Just switch to GL_TEXTURE matrix mode and use your normal glTranslatef etc.
Another way would be just using different textures for each tile but that would be slow.
Rendering each tile indivually (which you'd have to do even with the texture matrix) is very slow. I'd recommend using VBOs, like ndhb said, defining the visible grid of quads and as you scroll over the map you just update the texture coordinates.
Or you could use shaders and do all the scrolling in the shader (using an atlas and assuming your geometry is always the same, but I think so since you want to use a single DL). This way you could just draw a single fullscreen quad, use a texture that defines the tilemap (one pixel per tile), the texture atlas (that contains the tiles) and just pass your current position to the shader. But I agree with ndhb: this is too advanced for you atm.
My game has 3 possible layers per tile. Here's what I was going to do.
1 Render tile layer 1 (no collision, no alpha layer).
2 Render tile layer 2 (possible collision, buildings, etc).
3 Render objects such as players, weapons, booty, etc.
4 Render tile layer 3 (clouds, walk behind objects, etc. -- no collision).
Is this a smart way to do this? On screen we're talking about 60x40 tiles or so to be rendered * 3 layers + players and weapons. Am I going to be safe with a standard rendering method like I want to go with? Or even better with vertex buffer objects? Or is it going to be necessary to do something more complex down the road to receive fairly decent performance?
Hi Feta.
Your plan doesn't sound bad. As already mentioned by Lord_Evil, the only problem be holding you back performance wise, is the number of texture switches. You have to minimize texture switches when rendering so many small textures. The only other thing that would limit performance is fill rate but I highly doubt you will experience that.
A very common method is to put a lot of images into the same texture object and adjust the texture coordinates for each quad (visible object) accordingly. This is called a Texture Atlas. If you're not using those already, but bind the texture for each quad individually, you will probably run into performance issues. Google a bit around on "Texture Atlas" or read "http://download.nvidia.com/developer/NVTextureSuite/Atlas_Tools/Texture_Atlas_Whitepaper.pdf"
When you have sorted out the texture problem, you could look into VBO's to get rid of the large number of display lists.
kind regards,
Nicolai
Thanks again and any info on multitexturing pro's and con's would be appreciated.