|
Texture Mapping in OpenGL
An Introduction |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
void glGenTextures(GLsizei n, GLuint* names)
n unused "names" (actually integers)
void glBindTexture(GLenum target, GLuint name)
GL_TEXTURE_1D, GL_TEXTURE_2D,
GL_TEXTURE_3D or GL_TEXTURE_CUBE_MAP
void glTexParameter*(GLenum target, GLenum name, TYPE value)
target is either
GL_TEXTURE_1D, GL_TEXTURE_2D,
GL_TEXTURE_3D or GL_TEXTURE_CUBE_MAP
GL_TEXTURE_WRAP_S or
GL_TEXTURE_WRAP_T (the \(s\) and \(t\)
directions)
GL_CLAMP, GL_REPEAT,
(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER,
GL_MIRRORED_REPEAT)
GL_TEXTURE_BORDER_COLOR
GL_TEXTURE_MAG_FILTER and
GL_TEXTURE_MIN_FILTER
GL_NEAREST and GL_LINEAR
(and others)
// Specify the parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
void glTexEnvf(GLenum target, Glenum name, TYPE value)
target is GL_TEXTURE_ENV
and name is
GL_TEXTURE_ENV_MODE
GL_REPLACE, GL_ADD,
GL_COMBINE, or GL_BLEND
void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint borderWidth, GLenum format, Glenum type const GLvoid* texels)
target is GL_TEXTURE_2D (or one of several
other values)
GL_RGB, GL_RGBA,
GL_COLOR_INDEX (or others)
glDeleteTextures()
// Create the texture object
glTexImage2D(GL_TEXTURE_2D, 0, // One resolution (i.e. level 0)
3, // 3 components (i.e., RGB)
256, // Width
256, // Height
0, // Border width
GL_RGB, // Format
GL_UNSIGNED_BYTE, // Data type of the texels
image);
void glEnable(GLenum capability)
GL_TEXTURE_2D, GL_TEXTURE_3D,
(or one of several others)
glBindTexture() again
glTexCoord*(TYPE coords)
/**
* The display callback
*/
void display() {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textureName);
// Draw the cube
for (int f = 0; f < 6; f++) {
glBegin(GL_POLYGON);
int v;
v = faces[f][0];
glTexCoord2f(0.0, 0.0); // Map to the bottom left texel
glVertex3fv(vertices[v]);
v = faces[f][1];
glTexCoord2f(0.0, 1.0); // Map to the bottom right texel
glVertex3fv(vertices[v]);
v = faces[f][2];
glTexCoord2f(1.0, 1.0); // Map to the top right texel
glVertex3fv(vertices[v]);
v = faces[f][3];
glTexCoord2f(1.0, 0.0); // Map to the top left texel
glVertex3fv(vertices[v]);
glEnd();
}
// Force the rendering (off-screen)
glFlush();
// Handle the double buffering
glutSwapBuffers();
}
glmReadPPM()
that reads .ppm files
SDL_LoadBMP() for
reading .bmp files
/**
* Fill the given matrix with a RAW image
*
* @param data The matrix to fill
*/
void readRAWImage(char* filename, GLbyte data[256][256][3]) {
FILE * file;
file = fopen(filename, "rb");
if (file != NULL) {
fread(data, 256 * 256 * 3, 1, file);
fclose(file);
}
}
// Read the "image"
GLbyte image[256][256][3];
readRAWImage("oak.raw", image);
/**
* Initializations
*/
void init() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
// Read the images
GLbyte image[6][256][256][3];
readRAWImage("brick.raw", image[0]);
readRAWImage("brownpaper.raw", image[1]);
readRAWImage("flagstone.raw", image[2]);
readRAWImage("frostedglass.raw", image[3]);
readRAWImage("lake.raw", image[4]);
readRAWImage("oak.raw", image[5]);
// Get "names" for the textures
glGenTextures(6, textureNames);
for (int i = 0; i < 6; i++) {
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textureNames[i]);
// Set the parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Create the texture object
glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE,
image[i]);
}
// Enable textures
glEnable(GL_TEXTURE_2D);
}
/**
* The display callback.
*/
void display() {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Create the cube
for (int f = 0; f < 6; f++) {
// Select a texture object
glBindTexture(GL_TEXTURE_2D, textureNames[f]);
// Create the face
glBegin(GL_QUADS);
int v;
v = faces[f][0];
glTexCoord2f(0.0, 0.0); // Use bottom left texel
glVertex3fv(vertices[v]);
v = faces[f][1];
glTexCoord2f(0.0, 1.0); // Use bottom right texel
glVertex3fv(vertices[v]);
v = faces[f][2];
glTexCoord2f(1.0, 1.0); // Use top right texel
glVertex3fv(vertices[v]);
v = faces[f][3];
glTexCoord2f(1.0, 0.0); // Use top left texel
glVertex3fv(vertices[v]);
glEnd();
}
// Force the rendering (off-screen)
glFlush();
// Handle the double buffering
glutSwapBuffers();
}
gluScaleImage()
glCopyTexImage2D()
glTexSubImage2D()
glTexParameter*() with a
GL_TEXTURE_MIN_FILTER of either
GL_NEAREST_MIMPAP_NEAREST,
GL_NEAREST_MIMPAP_LINEAR,
GL_LINEAR_MIMPAP_NEAREST or
GL_LINEAR_MIMPAP_LINEAR
/**
* The display callback.
*/
void display() {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textureName);
// Create the sphere
glPushMatrix();
glRotatef(90.0, 1.0, 0.0, 0.0);
GLUquadric *quadric = gluNewQuadric();
gluQuadricDrawStyle(quadric, GLU_FILL);
gluQuadricNormals(quadric, GLU_SMOOTH);
gluQuadricTexture(quadric, GL_TRUE);
gluSphere(quadric, 1.0, 20, 20);
gluDeleteQuadric(quadric);
glPopMatrix();
// Force the rendering (off-screen)
glFlush();
// Handle the double buffering
glutSwapBuffers();
}
/**
* The display callback
*/
void display() {
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textureName);
// Create the teapot
glutSolidTeapot(1.0);
// Force the rendering (off-screen)
glFlush();
// Handle the double buffering
glutSwapBuffers();
}