# Rectangular Textures

• 06-24-2008
Dark Dude
Rectangular Textures
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?
• 06-24-2008
mike_g
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.
• 06-24-2008
indigo0086
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...

more specifically

http://cboard.cprogramming.com/showp...48&postcount=7

Code:

`glTexCoord2f((float)x/terrain.getX()*8, (float)row/terrain.getY()*8);`
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.
• 06-24-2008
CrazyNorman
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

(0,0)
(0,480/1024)
(640/1024,480/1024)
(640/1024,0)

Of course, this works with textures of any width and height.
• 06-24-2008
indigo0086
I thought he meant use square textures on triangles in Opengl.
• 06-24-2008
Dark Dude
Quote:

Originally Posted by CrazyNorman
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

(0,0)
(0,480/1024)
(640/1024,480/1024)
(640/1024,0)

Of course, this works with textures of any width and height.

Ok, I'm trying to do this but I'm unsure how to go about it...

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:

Code:

```GLuint Tiles[255];                        // 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[1];                // Holds storage for the textures                 memset(TextureImage,0,sizeof(void *)*1); // Fill with null         // Load Start Screen texture         if(TextureImage[0]=LoadBMP("Graphics\\Splash.bmp"))         {                         Status=TRUE;                         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[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->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[0])                                // Does Texture Exist         {                 if(TextureImage[0]->data)        // Does The Texture Data Exist                 {                         free(TextureImage[0]->data);        // Release the data                 }                 free(TextureImage[0]);        // Release the texture         }         return Status; }```
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.

Code:

```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                 glBegin(GL_QUADS);                         glTexCoord2f(0.0f,0.0f);                // Bottom left                         glVertex3f(-1.0f,-1.0f,1.0f);        //                         glTexCoord2f(1.0f,0.0f);                // Bottom right                         glVertex3f(1.0f,-1.0f,1.0f);        //                         glTexCoord2f(1.0f,1.0f);                // Top right                         glVertex3f(1.0f,1.0f,1.0f);                //                         glTexCoord2f(0.0f,1.0f);                // Top left                         glVertex3f(-1.0f,1.0f,1.0f);        //                 glEnd();         }         return TRUE;                                                                                // Everything Went OK }```
Here's yeah, comments explain it all...

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 =|
• 06-24-2008
VirtualAce
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?
• 06-24-2008
Dark Dude
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 <_<
• 06-25-2008
VirtualAce
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.
• 06-25-2008
Dark Dude
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 :)
• 06-25-2008
VirtualAce
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.