17. OpenGL Texture Coordinate Generation (Version 2.0)
Introduction
Texture coordinate generation in OpenGL allows you to automatically calculate texture coordinates, eliminating the need for manual computation. This feature is particularly useful for creating effects like environment mapping and reflection mapping, where calculating coordinates manually would be too complex or time-consuming.
In this tutorial, we’ll discuss how to enable texture coordinate generation, the available modes, and how to implement it in a practical OpenGL example. By the end, you’ll understand how to use this feature effectively and where it can be applied.
What is Texture Coordinate Generation?
Texture coordinate generation automatically computes texture coordinates based on predefined rules. It is especially useful in cases where:
- Manual computation of texture coordinates is impractical.
- Real-time effects like reflections or environment mapping are needed.
Enabling Texture Coordinate Generation
OpenGL supports four types of texture coordinates that can be generated:
GL_TEXTURE_GEN_S // Horizontal texture coordinate GL_TEXTURE_GEN_T // Vertical texture coordinate GL_TEXTURE_GEN_R // 3D texture coordinate GL_TEXTURE_GEN_Q // Perspective correction coordinate
To enable automatic generation for a specific axis, use the following commands:
glEnable(GL_TEXTURE_GEN_S); // Enable S coordinate generation glEnable(GL_TEXTURE_GEN_T); // Enable T coordinate generation
You can enable any combination of these depending on your application.
Configuring the Generation Mode
The generation mode determines how OpenGL calculates the texture coordinates. Common modes include:
- GL_OBJECT_LINEAR: Generates coordinates based on the object’s local space.
- GL_EYE_LINEAR: Generates coordinates relative to the viewer’s perspective.
- GL_SPHERE_MAP: Calculates coordinates for spherical environment mapping.
- GL_REFLECTION_MAP: Ideal for dynamic reflections.
To set a mode for a specific axis, use:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set mode for S glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); // Set mode for T
Practical Example
Let’s implement texture coordinate generation to create an environment-mapped rotating cube. The code below demonstrates how to enable and configure the generation mode.
Tutorial Code
// Include necessary libraries #include <GL/gl.h> #include <GL/glut.h> #include <stdio.h> GLuint texture; // Texture object GLfloat angle = 0.0; // Rotation angle // Function to load a texture GLuint LoadTexture(const char* filename, int width, int height) { GLuint texture; unsigned char* data; FILE* file; // Load the texture data file = fopen(filename, "rb"); if (file == NULL) return 0; data = (unsigned char*)malloc(width * height * 3); fread(data, width * height * 3, 1, file); fclose(file); glGenTextures(1, &texture); // Generate texture glBindTexture(GL_TEXTURE_2D, texture); // Bind texture glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Set texture filters glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Set texture wrapping glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Build mipmaps gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); free(data); // Free texture data return texture; } void FreeTexture(GLuint texture) { glDeleteTextures(1, &texture); // Delete texture } // Draw a textured cube void cube(void) { glBindTexture(GL_TEXTURE_2D, texture); glRotatef(angle, 1.0f, 1.0f, 1.0f); glutSolidCube(2); } // Display callback void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); texture = LoadTexture("texture.raw", 256, 256); // Load texture glEnable(GL_TEXTURE_2D); // Enable 2D texturing glEnable(GL_TEXTURE_GEN_S); // Enable S coordinate generation glEnable(GL_TEXTURE_GEN_T); // Enable T coordinate generation glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); cube(); // Draw cube FreeTexture(texture); glutSwapBuffers(); angle++; } // Reshape callback void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); } // Main function int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("Texture Coordinate Generation"); glutDisplayFunc(display); glutIdleFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; }
If you have any questions or run into issues, feel free to email me at swiftless@gmail.com. Happy coding!
hello there,
Ihave a problem .
this error:
error C2381: ‘exit’ : redefinition; __declspec(noreturn) differs c:\program files\microsoft visual studio 10.0\vc\include\stdlib.h 353 1 tex
dont let to visual stdio to run my project
what do i do???
thank for this post and thank for answering our questions.
Why is this Windows only? Works perfect in Mac OS X. I use Netbeans for C++ applications with a window. The only thing you’ve got to keep in mind is that the working directory is / and not the directory of the compiled binary.
Hi Swiftless
I’ve tried ‘OpenGL Texture Coordinate Generation’ with XCode4 but it is looking for the header file “wndows.h”. Is there anything I can do there?
Hi Reyaad,
It should be a matter of removing windows.h and then including the OpenGL and GLUT libraries in Xcode. I can assure you that this code is portable.
Cheers,
Swiftless
Hi, Swiftless.
First of all, sorry for my English.
I’ve run this code.
But it’s not like tutorial 16.
6 sides of the cube has no texture on it.
It’s like there’s a texture on the background and I see that background through this Cube.
You know like diamond.
anyway thanks for your tutorial.
Shaleh.
I am wondering about this matter too … did you found out why?
In line 79 you load the texture and in line 86 you free it. This progress repeats every frame and it should only be done once. Load when program starts and free when programs quits
Hi Bloodust,
Yes, it would be alot more efficient to load it at the start and release it when the program ends.
The new tutorials are more improved and do this instead of loading and releasing every frame. I just haven’t rewritten this one yet.
Cheers,
Swiftless
Yeah, here it is (again)!
Thank’s for the re-up! 🙂
no tutorial 🙁
btw. your other tutorials are great!
Hey,
Thanks for the heads up, I’ve done a check and the content is up, I have to find out why it has disappeared out here though.
Cheers,
Swiftless