PDA

View Full Version : Texture not working - Cocoa/Obj-C


mahalis
2006.07.29, 04:01 AM
I'm just starting to learn OpenGL, and I've got a fairly good grasp of polygons, vertex coloring, transformations, lighting, that kind of thing. I'm now trying to learn texturing and am completely hitting the wall.
My app uses an NSOpenGLView subclass. I get all the polygons drawn, no errors, but the one I'm trying to texture just sits there and looks gray.


GLuint tex;
- (void)prepareOpenGL
{
NSSize bounds = [self bounds].size;
if(! [self loadTexes])
[[NSApplication sharedApplication] terminate:nil];
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 70, bounds.width/bounds.height, 0.1f, 100.0f );
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
}
- (BOOL)loadTexes
{
if([self loadImage:@"/blah.bmp" toTex:&tex])
{
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D,tex);
return YES;
}
else
{
NSLog(@"No load texes.");
return NO;
}
return NO;
}
This next part came pretty much directly from Apple's sample code, so I'm almost certain it's not the problem:
- (BOOL)loadImage:(NSString *)filename toTex:(GLuint *)texName
{
NSBitmapImageRep *theImage = [ NSBitmapImageRep imageRepWithContentsOfFile:filename ];
glPixelStorei(GL_UNPACK_ROW_LENGTH,[theImage pixelsWide]);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1,texName);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB,*texName);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTUR E_MIN_FILTER,GL_LINEAR);
int samplesPerPixel = [theImage samplesPerPixel];
if(![theImage isPlanar] && (samplesPerPixel==3 || samplesPerPixel == 4))
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,samplesPer Pixel==4?GL_RGBA8 : GL_RGB8,[theImage pixelsWide],[theImage pixelsHigh],0,samplesPerPixel==4?GL_RGBA:GL_RGB,GL_UNSIGNED_B YTE,[theImage bitmapData]);
}
else
{
NSLog(@"Error.");
return NO;
}
[theImage release];

return YES;
}

- (void)drawRect:(NSRect)bounds
{
glClearColor(0,0,0,0);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glTranslatef(-1.5,0,-3);
glRotatef(30,0.0,1.0,0.0);
glBindTexture(GL_TEXTURE_2D,tex);
glBegin(GL_QUADS);
{
glVertex3f(-0.8,0.6,0);
glVertex3f(0.8,0.6,0);
glVertex3f(0.8,-0.6,0);
glVertex3f(-0.8,-0.6,0);
}
glEnd();

glFlush();
}
I've seen some resources say to use
[[self openGLContext] flushBuffer];
rather than glFlush(), but if I use that the view goes white and the app crashes as soon as it redraws.

Anyone know what might be going on here? Am I missing something obvious? Is my code totally messed up? What? :\

OneSadCookie
2006.07.29, 04:20 AM
you're calling glGenTextures and glBindTexture after loadImage:, instead of before.

mahalis
2006.07.29, 12:03 PM
Hmm... I just realized the same thing's being called twice, once in loadTexes and once in loadImage itself. What exactly do glGenTextures and glBindTexture do?

ThemsAllTook
2006.07.29, 01:27 PM
glGenTextures gives you a unique identifier (known as a texture name) for use with your texture.

glBindTexture, given a texture name, makes that texture active, so that any primitive you draw will use that texture (provided GL_TEXTURE_2D is enabled).

In your -drawRect: method, you'll probably want to make a glTexCoord2f call before each glVertex3f. Otherwise, your entire primitive will be the color of one pixel in your texture image (most likely the one in the lower left corner). Reading this thread (http://www.idevgames.com/forum/showthread.php?t=12391) might help explain.

mahalis
2006.07.29, 01:47 PM
Okay - I've got a texture loading and displaying. For some reason, though, everything in the scene is now apparently filtered with the main color of the image. I have a begradiented polygon in the background - black to gray - and it becomes orange with an orange image, blue with a blue one. Is there some blending option I have to fiddle with?

ThemsAllTook
2006.07.29, 04:46 PM
Presumably, you've left the texture bound and enabled before/after drawing the primitive you wanted textured. You'll need to enable GL_TEXTURE_2D when you want to draw textured primitives, and disable it when you want to draw untextured primitives.