open gl texturing question

what does it mean if the object on to which I attatch a texture is white instead of showing the texture? has the texture not loaded correctly or is a matter of how I’ve drawn it on an object? (I have been drawing the texture on an object of the same size) . The texture is of resolution 270x390 and I want to use a unit of the opengl coordinate system to represent a pixel.(ie the coordinates of the object would range from -270/2,390/2 (TOP LEFT) to 270/2,-390/2 (BOTTOM RIGHT)) am I right to draw the object with such large coordinates as I dont seem to be able to draw it far enough into the screen to be able to see it all? I use glTranslatef(0,0,-100) and its still too large to see all of the object, but any value smaller than -100 (even -100.1) and the object disappears completely?

Originally posted by Mr.JT:
what does it mean if the object on to which I attatch a texture is white instead of showing the texture? has the texture not loaded correctly or is a matter of how I’ve drawn it on an object? (I have been drawing the texture on an object of the same size) . The texture is of resolution 270x390 and I want to use a unit of the opengl coordinate system to represent a pixel.(ie the coordinates of the object would range from -270/2,390/2 (TOP LEFT) to 270/2,-390/2 (BOTTOM RIGHT)) am I right to draw the object with such large coordinates as I dont seem to be able to draw it far enough into the screen to be able to see it all? I use glTranslatef(0,0,-100) and its still too large to see all of the object, but any value smaller than -100 (even -100.1) and the object disappears completely?

texture size needs to be a power of 2. read the red book.

yes but I have heard there are ways round it eg. only texturing a part of an object thats size is a power of two?

You can generate a texture object with power of two size by “filling out” part of the texture to make it a power of two texture. When rendering you have to adjust your texture coordinates.

You can also use GL_NV_texture_rectangle or GL_ARB_texture_non_power_of_two.

ok thanks. currently using a power of two texture now just to try and get it working, but the square that the texture should be displayed in is still white. Is this a specific problem caused by the texture not loading correctly, or a problem displaying the texture?

If the object is disappearing completely if you translate back further than -100 you should adjust your far clipping plane to accomidate the size.

Some code would help people understand what you are trying to do.

bitmap loaded into resource file as in NeHe tutorial lesson 38. The code below is the relevant C++ class that is using OPENGL. From the main function (not included below) the function drawBackground() is called as the glut display (and also idle) function. Bitmap is 256x256. For non C++ people the constructor (ie Graphics::Graphics() is called once at the start of the program to inialise things. Im very new to opengl and glut so have mainly pulled bits a pieces from tutorials etc and therefore struggle when my adaptions havent worked! Hope it makes sense!

#include <gl\glut.h>
#include “resource.h”

class Graphics{
private:
struct object // Create A Structure Called Object
{
int tex; // Integer Used To Select Texture
float x; // X Position
float y; // Y Position
float z; // Z Position
};

GLuint texture[1]; // Storage For 1 Texture
object background;			//create object 'background that will hold' background BMP

public:
Graphics(){}; //default - currently does nothing
Graphics(int argc,char* argv[]); //overloaded constructor
~Graphics() {}; //destructor - currently does nothing

void loadBackgroundTexture(void);
void drawBackground(void);

};

Graphics::Graphics(int argc,char* argv[]){
glutInit(&argc,argv); //start glut
loadBackgroundTexture();
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); //double buffered for animation. RGB colour mode
glutInitWindowSize(270,390); //window size
glutInitWindowPosition(300,150); //window position
glutCreateWindow(“PicassoTalk! J.Trevan : 2k4”); //create window
glClearColor(0.0f ,0.0f ,0.0f ,0.0f); //clear colour = black
glMatrixMode(GL_PROJECTION); //select projection mode
glLoadIdentity(); //reset projection view
gluPerspective(45.0f,(GLfloat)270/(GLfloat)390,0.1f,100.0f); //perspective
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glClearDepth (1.0f); // Depth Buffer Setup
glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
glDisable(GL_DEPTH_TEST); // Disable Depth Testing
glShadeModel (GL_SMOOTH); // Select Smooth Shading
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBlendFunc(GL_ONE,GL_SRC_ALPHA); // Set Blending Mode (Cheap / Quick)
glEnable(GL_BLEND); // Enable Blending
}

void Graphics::loadBackgroundTexture(void){
background.tex = 0; //define texture ie. which bitmap
background.x = 0; //set background position in window
background.y = 0;
background.z = 0;

HBITMAP hBMP; // Handle Of The Bitmap
BITMAP BMP; // Bitmap Structure

byte Texture[]={ IDB_BACKGROUND1 };			// The ID of background bitmap to load

glGenTextures(sizeof(Texture), &texture[0]); // Generate Texture (sizeof(Texture)=1 ID)

//The following loads the bitmap image. MAKEINTRESOURCE converts int to resource number
//ie. which bitmap to load. IMAGE_BITMAP defines that image being loaded is a bitmap. The
//next 2 zero's are the required size of the image, x and y. Want to use the default image
//size so leave as zero. The last parameter (LR_CREATEDIBSECTION) returns a DIB section bitmap, 
//which is a bitmap without all the color information stored in the data.
hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(Texture[0]), IMAGE_BITMAP, 0,
0, LR_CREATEDIBSECTION);
//hBMP  now points to the bitmap data that is loaded by LoadImage( ).

if (hBMP) { // Does The Bitmap Exist?
	GetObject(hBMP,sizeof(BMP), &BMP); // Get The Object
	// hBMP: Handle To Graphics Object
	// sizeof(BMP): Size Of Buffer For Object Information
	// Buffer For Object Information
	glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
	glBindTexture(GL_TEXTURE_2D, texture[0]); // Bind Our Texture
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); // Mipmap Linear Filtering
	// Generate Mipmapped Texture (3 Bytes, Width, Height And Data From The BMP)
	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE,
		BMP.bmBits);
	DeleteObject(hBMP); // Delete The Bitmap Object
}

else
	cerr &lt;&lt; "hBMP doesn't point to anything!! Error loading background bitmap!" &lt;&lt; endl;

}

void Graphics::drawBackground(void){
glLoadIdentity(); //Reset modelview matrix
glTranslatef(0.0f,0.0f,-10.0f); //into screen
glBindTexture(GL_TEXTURE_2D, texture[background.tex]); // Bind background texture

glBegin(GL_QUADS);
glTexCoord2f(-1.0f, 1.0f); glVertex2f(-1.0f, 1.0f);		//map texture to an object
glTexCoord2f( 1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
glTexCoord2f( 1.0f,-1.0f); glVertex2f( 1.0f,-1.0f);
glTexCoord2f(-1.0f,-1.0f); glVertex2f(-1.0f,-1.0f);
glEnd();
glLoadIdentity();
glutSwapBuffers();

}

ps. there may be the odd unrequired line in there as I havent streamlined the code yet!!

the texture coordinates are obviously wrong…but correcting them still doesnt help

I don’t see you setting the wrapping mode for the texture anywhere.

Try adding:
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,…);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,…);

Maybe that would help.

where would it be best to add it?

Where you specify the other texture parameters(MIN/MAG filter).

thanks but didnt work! arghhh…!

Look sharper! It’s really simple.
glutInitDisplayMode() initializes the pixelformat and rendering context! (You have no depth specified, in case you need that in the future.)
The function loadBackgroundTexture() uses OpenGL functions before the rendering context has been created. All these will be ingored if there is no rendering context current.

[This message has been edited by Relic (edited 02-12-2004).]

thank you…that has loaded the texture! nice one! Unfortunately the texture appears to be corrupt…all i get is a load of noise at the top and a bit of a windows folder at the bottom?!?will work on that, but any ideas based on the code would be apprieciated. (moved the loadBachgroundTexture() function to the end of the constructor)

For reference code is now as follows (texture does not appear to load correctly)

#include <gl\glut.h>
#include “resource.h”

class Graphics{
private:
struct object // Create A Structure Called Object
{
int tex; // Integer Used To Select Texture
float x; // X Position
float y; // Y Position
float z; // Z Position
};

GLuint texture[1]; // Storage For 1 Texture
object background;			//create object 'background that will hold' background BMP

HBITMAP hBMP; // Handle Of The Bitmap
BITMAP BMP; // Bitmap Structure

public:
Graphics(){}; //default - currently does nothing
Graphics(int argc,char* argv[]); //overloaded constructor
~Graphics() {}; //destructor - currently does nothing

void loadBackgroundTexture(void);
void drawBackground(void);

};

Graphics::Graphics(int argc,char* argv[]){
glutInit(&argc,argv); //start glut
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); //double buffered for animation. RGB colour mode
glutInitWindowSize(300,300); //window size
glutInitWindowPosition(300,150); //window position
glutCreateWindow(“PicassoTalk! J.Trevan : 2k4”); //create window
glClearColor(0.0f ,0.0f ,0.0f ,0.0f); //clear colour = black
glMatrixMode(GL_PROJECTION); //select projection mode
glLoadIdentity(); //reset projection view
gluPerspective(45.0f,(GLfloat)300/(GLfloat)300,0.1f,100.0f); //perspective
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glClearDepth (1.0f); // Depth Buffer Setup
glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
glDisable(GL_DEPTH_TEST); // Disable Depth Testing
glShadeModel (GL_SMOOTH); // Select Smooth Shading
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
loadBackgroundTexture();
}

void Graphics::loadBackgroundTexture(void){
background.tex = 0; //define texture ie. which bitmap
background.x = 0; //set background position in window
background.y = 0;
background.z = 0;

byte Texture[]={ IDB_BACKGROUND2 };			// The ID of background bitmap to load

glGenTextures(1, texture); // Generate Texture (sizeof(Texture)=1 ID)

//The following loads the bitmap image. MAKEINTRESOURCE converts int to resource number
//ie. which bitmap to load. IMAGE_BITMAP defines that image being loaded is a bitmap. The
//next 2 zero's are the default size of the image, x and y. 
hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(Texture[0]), IMAGE_BITMAP, 0,
0, LR_DEFAULTCOLOR);
//hBMP  now points to the bitmap data that is loaded by LoadImage( ).

if (hBMP) { // Does The Bitmap Exist?
	GetObject(hBMP,sizeof(BMP), &BMP); // Get The Object
	// hBMP: Handle To Graphics Object
	// sizeof(BMP): Size Of Buffer For Object Information
	// Buffer For Object Information
	glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
	glBindTexture(GL_TEXTURE_2D, texture[0]); // Bind Our Texture
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	DeleteObject(hBMP); // Delete The Bitmap Object
}

else
	cerr &lt;&lt; "hBMP doesn't point to anything!! Error loading background bitmap!" &lt;&lt; endl;

}

void Graphics::drawBackground(void){
glLoadIdentity(); //Reset modelview matrix
glTranslatef(0.0f,0.0f,-3.0f); //into screen
glBindTexture(GL_TEXTURE_2D, texture[0]); // Bind background texture

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_RGBA,GL_UNSIGNED_BYTE,BMP.bmBits);
//glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0); glVertex3f(-1.0,-1.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-1.0, 1.0,0.0);
glTexCoord2f(1.0,1.0); glVertex3f( 1.0, 1.0,0.0);
glTexCoord2f(1.0,0.0); glVertex3f( 1.0,-1.0,0.0);
glEnd();
glLoadIdentity();
glutSwapBuffers();

}

Man, one step at a time!
Now you changed the loadBackgroundFunction() from working to non-working.
The GetObject() on a bitmap gives you a pointer to the bitmap data. But you DeleteObject() on the hBMP before you access the data and expect the pointer to be still valid. That doesn’t look ok.

Change it back to the old style and it should get better, but I’m not sure if you have the alignment and everything right afterwards. Probably for a 256*256, but try this with something which has no 4 byte alignement like 2x2…

I also remember having the same problem with my textures. Try experimenting with the posible types of GL_RGBA (GL_RED, GL_RGB, GL_BGR and stuff), in glTexImage2D. Also I think sometimes the GL_UNSIGNED_BYTE needed experimenting. I’m almost sure that among other things this should be the solution. Can anyone ellaborate on how we can read a bitmap properly so we set the correct type of GL_RGB, BGR etc.?

Originally posted by moucard:
I also remember having the same problem with my textures. Try experimenting with the posible types of GL_RGBA (GL_RED, GL_RGB, GL_BGR and stuff), in glTexImage2D. Also I think sometimes the GL_UNSIGNED_BYTE needed experimenting. I’m almost sure that among other things this should be the solution. Can anyone ellaborate on how we can read a bitmap properly so we set the correct type of GL_RGB, BGR etc.?

Windows bitmap files are always stored in BGR format. Further more, if I remember correctly, the files are stored upside down after Windows loads them! Then the other question is how many bpp does the picture have? The best option is to simply write your own bitmap loader (not particularly difficult to do) and have it convert all the file types you want to load into some specific format. This reduces a lot of unnecessary computations by OpenGL, and gives you a lot more control over the situation.

Relic: You said i delete hBMP to early…but i dont use that pointer after I’ve deleted it, as GetObject transfers the bitmap data to the bitmap structure BMP, and subsequently I use this to access the bitmap data. Surely this is ok as all the data has been transfered to the BMP structure and then i delete hBMP?