|
In this tutorial, we will explore textures. Please note that the zip file for this tutorial has not yet been updated.
First we must turn textures on in our OpenGL context. We do this in initGL with the simple statement:
If we also wish to be able to modify the color of the texture (or any other simple colored objects), we must also write:
glEnable(GL_COLOR_MATERIAL);
|
We will need to load the textures into texture space. First, we generate texture identifiers with glGenTextures. texture is an array of GLint with size NUMTEXTURES defined in the kGLView class. In this case, we need space for 6 textures (for 6 sides of the die) so NUMTEXTURES is defined as 6.
- (void)getTextures
{
glGenTextures( NUMTEXTURES, texture );
glBindTexture( GL_TEXTURE_2D, texture[0] );
[self loadPicture: @"one"];
|
glBindTexture tells OpenGL what kind of texture we will be using (in this case, a 2D texture) and what identifier to use.
We will define a new method called loadPicture. It takes one argument, namely the name of the image to load. Load picture will accept any named picture, which includes pictures that were loaded into the NIB and pictures that had a name set with NSImage's setName method.
- (void) loadPicture: (NSString *) name
{
NSBitmapImageRep *bitmap;
NSImage *image;
image = [ NSImage imageNamed: name ];
bitmap = [[NSBitmapImageRep alloc]initWithData: [image TIFFRepresentation]];
if (bitmap == nil)
{ NSLog(@"in LoadGLTextures : NSBitmapImageRep not loaded"); return; }
NSLog(@"spp: %d, bps: %d, brp: %d", [bitmap samplesPerPixel], [bitmap bitsPerSample], [bitmap bytesPerRow]);
NSBitmapImageRep *destinationBitmap =
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:[bitmap pixelsWide]
pixelsHigh:[bitmap pixelsHigh]
bitsPerSample:8
samplesPerPixel:3
hasAlpha:NO
isPlanar:YES
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:4*[bitmap pixelsWide]
bitsPerPixel:32];
if ([bitmap samplesPerPixel] == 2 && [bitmap bitsPerSample] == 8 )
{
for ( i = 0; i < [bitmap pixelsWide]*[bitmap pixelsHigh]; i++ ) {
dstBuffer[i*3] = srcBuffer[i*2]; //put grayscale value into R
dstBuffer[i*3+1] = srcBuffer[i*2]; //put grayscale value into G
dstBuffer[i*3+2] = srcBuffer[i*2]; //put grayscale value into B
}
}
else if( [bitmap samplesPerPixel] == 1 && [bitmap bitsPerSample] == 8 )
{
for ( i = 0; i < [bitmap pixelsWide]*[bitmap pixelsHigh]; i++ ) {
dstBuffer[i*3] = srcBuffer[i]; //put grayscale value into R
dstBuffer[i*3+1] = srcBuffer[i]; //put grayscale value into G
dstBuffer[i*3+2] = srcBuffer[i]; //put grayscale value into B
}
}
else if( [bitmap samplesPerPixel] == 3 && [bitmap bitsPerSample] == 8 )
{
destinationBitmap = bitmap;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
[destinationBitmap size].width, [destinationBitmap size].height, 0,
GL_RGB, GL_UNSIGNED_BYTE, [destinationBitmap bitmapData]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
|
We will need to load the textures into texture space. First, we generate texture identifiers with glGenTextures. texture is an array of GLint with size NUMTEXTURES defined in the kGLView class. In this case, we need space for 6 textures (for 6 sides of the die) so NUMTEXTURES is defined as 6.
glTranslatef(-2.0,0.0,-10.0);
glRotatef(dieangle,1,1.4,0.1);
dieangle += 1;
glColor3f(1.0,1.0,1.0);
[self drawDie];
glLoadIdentity();
glTranslatef(2.0,0.0,-15.0);
glRotatef(dieangle,-1,1,-0.1);
glColor3f(0.5,0.5,1.0);
[self drawDie];
|
The drawDie method is the same as the drawCube method from the last lesson, except that we will now add some additional code for the textures. We first bind the texture, so that OpenGL knows what texture we are refering to in the subsequent calls. After binding the texture, we draw each face as we normally would. At each of the vertices, we add a texture coordinate. This is just like putting a different color on each vertex.
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(drawing_type);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glEnd();
|
|
|