Reputation: 17217
I am trying to use a bit of OpenGL. After playing around with it for a while, I was able to draw colored geometric shapes. Now, I want to put a texture on these shapes.
So, I create a texture. It seems to be created alright. Then I try to draw it, but all I get is a white rectangle.
The code is actually spread over three methods of a NSOpenGLView
, but I put it all in one code block here to save space.
// ----- Set up OpenGL (this code is adapted from the NeHe OpenGL tutorial) -----
GLuint textureName = 0;
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// ----- I load the image: (This code is adapted from some sample code from Apple) -----
NSImage *image = dataSource.image; // get the original image
NSBitmapImageRep* bitmap = [NSBitmapImageRep alloc];
[image lockFocus];
[bitmap initWithFocusedViewRect:
NSMakeRect(0.0, 0.0, image.size.width, image.size.height)];
[image unlockFocus];
// Set proper unpacking row length for bitmap.
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.pixelsWide);
// Set byte aligned unpacking (needed for 3 byte per pixel bitmaps).
if (bitmap.samplesPerPixel == 3) {
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
}
// Generate a new texture name if one was not provided.
if (textureName == 0)
glGenTextures (1, &textureName);
glBindTexture (GL_TEXTURE_2D, textureName);
// Non-mipmap filtering (redundant for texture_rectangle).
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// RGB 24 bit bitmap, or RGBA 32 bit bitmap
if(bitmap.samplesPerPixel == 3 || bitmap.samplesPerPixel == 4) {
glTexImage2D(GL_TEXTURE_2D, 0,
bitmap.samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
bitmap.pixelsWide,
bitmap.pixelsHigh,
0,
bitmap.samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
GL_UNSIGNED_BYTE,
bitmap.bitmapData);
}
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
[bitmap release];
// ----- Drawing code (This code is adapted from the NeHe OpenGL tutorial) -----
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
if (textureName) {
glBindTexture(GL_TEXTURE_2D, textureName);
glBegin(GL_QUADS);
{
glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, -0.5, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 0.5, 0.5, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, 0.5, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, 0.0);
}
glEnd();
}
glFlush();
Alas, all I get is a white rectangle of the intended size in a see of blackness.
I also tried inserting a few glGetError()
s here and there, but there seems to be no error happening.
Why does my texture not show up? Any hints would be greatly appreciated.
Edit:
The texture is drawn fine if I surround the drawing code with glEnable(GL_TEXTURE_2D)
and glDisable(GL_TEXTURE_2D)
. But I did that in the set up code already. Why do I have to do it again?
Upvotes: 3
Views: 509
Reputation: 162317
The texture is drawn fine if I surround the drawing code with glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D). But I did that in the set up code already.
I would have suggested, but you found out already.
Why do I have to do it again?
Because OpenGL is a state machine and in fact there is no such thing like "one time initialization" in OpenGL. Functionality can be enabled and disabled at any time. So the recommended practice is to keep all OpenGL operation within the display routine. This includes setting the projection, enabling required functionality.
Upvotes: 1