Ok, so the power-of-two rule hasnt annoyed me so much, because I can just rescale it in OpenGL to make it non-power-of-two etc etc, but one thing that's boggled my mind, is how to use textures that arent squares...
So far I can use squares, that's all well and good, but supposing I want to use a 640x480 bitmap as a texture, how would I go about it?
From what I have heard you would load it as a square texture, but only draw a section of it. Never done it myself tho, so i guess it might not be a very good answer.
You have to do then when doing something like drawing a terrain, because you draw them as a series of triangles. I haven't done it in a long time, but here is what I used as my texture coordinates when generating a terrain...
I forgot what it means, but it worked when I was drawing my polygonal terrain three points at a time.
I've been out of the loop for a while.
Let's say you have a 640x480 texture. You would load it, then create a blank 1024x1024 texture (the smallest power of two <= the textures largest dimension). Then, blit your texture to the blank texture. Use the 1024x1024 one with OpenGL. You're UV coordinates for a rectangle would be
Of course, this works with textures of any width and height.
I thought he meant use square textures on triangles in Opengl.
Ok, I'm trying to do this but I'm unsure how to go about it...
Originally Posted by CrazyNorman
I havent really been using OpenGL for too long, so I'm falling back on some GLAux code from NeHe's tut...
Here's some code that's relevant:
This code loads the bitmap and creates a texture out of it, which it then assigns an ID in the Tiles (or SplashScr), allowing it to use my Tile Map to easily display the tiles.
GLuint Tiles; // Holds all our tiles' textures
GLuint StartScr; // Holds our start-screen's texture
AUX_RGBImageRec* LoadBMP(char *Filename) // Load a bitmap from a file as a texture
FILE* File; // File handle
if(!Filename) // Check we've been given a filename
return NULL; // Dont want to open nothing, so return
File=fopen(Filename,"r"); // Make sure the file exists
if(File) // Check it exists
fclose(File); // Close the file
return auxDIBImageLoadA(Filename); // Load the bitmap and return pointer
MessageBoxA(hWnd,"File not found",Filename,MB_OK|MB_ICONSTOP);
return NULL; // If all failed, return NULL;
int LoadGLTextures() // Load the textures
int Status=0; // Status indicator
AUX_RGBImageRec* TextureImage; // Holds storage for the textures
memset(TextureImage,0,sizeof(void *)*1); // Fill with null
// Load Start Screen texture
glGenTextures(1,&StartScr); // Generate a texture from the bitmap
glBindTexture(GL_TEXTURE_2D, StartScr); // Bind the texture as 2D
// Generate texture properly
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
if(TextureImage) // Does Texture Exist
if(TextureImage->data) // Does The Texture Data Exist
free(TextureImage->data); // Release the data
free(TextureImage); // Release the texture
Here's yeah, comments explain it all...
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(0.0f,0.0f,-3.5f); // Set our depth into the screen
if(resetAmbience==0) BeginAmbience(); // If we need to initiate the sound, do so
if(startScreen==1) // If we need to display the start screen
glBindTexture(GL_TEXTURE_2D,StartScr); // Bind texture ready for display
glTexCoord2f(0.0f,0.0f); // Bottom left
glTexCoord2f(1.0f,0.0f); // Bottom right
glTexCoord2f(1.0f,1.0f); // Top right
glTexCoord2f(0.0f,1.0f); // Top left
return TRUE; // Everything Went OK
This is the last code that works, and draws my "Square" Start Screen, which is 512x512, but I need to draw the 640x480 one, and I've tried fiddling around with the co-ordinates and getting them into 4:3 ratio but that doesnt seem to be working =|
The power of 2 limitation is rather dated and I'm not sure newer cards restrict you to it. Also it only applies to either the X axis or the Y axis but does not require both at the same time. So a power of 2 on X and a power of 2 on Y is a power of 2 texture regardless if they are the same power of 2. Textures are either always square or always rectangular. I'm not sure what you are asking here?
Well, I have a bitmap that's 512x512 and it works perfectly, but that's just a test one.
When I then replace the bitmap with one that's 640x480, I just get a white box/rectangle on the screen <_<
You should be able to query your device capabilities to find out if your card enforces the power of 2 texture. If it does then you will have to turn 640 x 480 into the next power of two or just use your 512 x 512.
My card does not force me into the power of 2 texture size, however, I believe it still utilizes a power of 2 even if I do not specify one. You should in theory try to maintain power of 2 textures because they are faster to access and with the way video memory is laid out they offer optimum performance.
Ah yes, indeed that appears to be the case, just checked my graphics cards' specs, it's pretty crappy/can only just run Spore.
I've put it in a 1024x1024 bitmap and I've set the co-ordinates out so it fills the screen with the non-blank texture, and that appears to have worked. Thanks :)
As I said, remember power of 2 is for u and v but they do not have to be identical. As long as both are some power of 2 it should work.