Experiment 4: texture mapping experiment
Nature of experiment project: Design Experiment
Course Name: computer graphics A
Experimental planned class hours: 3 class hours
1, Purpose and requirements of the experiment
Master the basic principle of texture mapping, and use VC++ OpenGL to realize texture mapping technology.
2, Experimental principle
Texture mapping is an important part of realistic graphics production. Using texture mapping can produce realistic graphics in many ways without taking more time to consider the surface texture of the object. For example, the wood grain on the surface of a wooden table is nonstandard and looks so natural. If texture mapping is not used in graphic production, it will take a lot of energy to design the texture of the table, and the design result may not be as natural as in reality. If the use of texture mapping is very convenient, you can use a scanner to scan such a table into a bitmap. Then, in the specific operation, just draw the desktop shape with polygons and paste the desktop texture.
In addition, texture mapping can still ensure the consistency between the texture pattern and the polygon when the polygon is transformed. For example, when viewing the wall in perspective projection, the bricks at the far end will become smaller and the bricks near will be larger.
In addition, texture mapping can also be used in other aspects. For example, the image of a large area of vegetation is mapped to some continuous polygons to simulate the landform, or the image of natural substances such as marble and wood grain is mapped to the corresponding polygons as the texture as the real surface of the object.
OpenGL provides a series of complete texture operation functions. Users can use them to construct an ideal object surface, process the illuminated object and make it map the scene of the environment. They can be applied to the surface in different ways, and can change with the transformation of the geometric attributes of the geometric object, So as to make the 3D scene and 3D object more realistic and natural.
To realize texture mapping in OpenGL, we need to go through several processes: creating texture, specifying texture application mode, enabling texture mapping, and drawing scene with texture coordinates and geometric coordinates.
The functions used to specify one-dimensional, two-dimensional and three-dimensional textures are:
Void glTexImage1D(GLenum target, Glint level, Glint components, GLsizei width, Glint border, GLenum format, GLenum type, const GLvoid *texels);
Void glTexImage2D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *texels);
Void glTexImage3D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLsizei depth, Glint border, GLenum format, GLenum type, const GLvoid *texels);
Among them, the value of parameter target is generally GL_TEXTURE_1D, GL_TEXTURE_2D and GL_TEXTURE_3D, corresponding to one-dimensional, two-dimensional and three-dimensional textures respectively. The parameter Level indicates the number of texture multi-resolution layers, usually 0, indicating that there is only one resolution. The possible values of parameter components are integers from 1 to 4 and various symbolic constants (such as GL_RGBA), indicating which components (RGBA color, depth, etc.) stored in texture elements are used in texture mapping. 1 indicates the use of R color components, 2 indicates the use of R and A color components, 3 indicates the use of RGB color components, and 4 indicates the use of RGBA color components. The parameters width, height and depth specify the width, height and depth of the texture respectively. Parameter format and type represent the data format and data type of the given image data. The values of these two parameters are symbolic constants (for example, format is specified as GL_RGBA,type is specified as GL_UNSIGNED_BYTE, and parameter textels points to the texture image data specified in memory.
For example: glteximage2d (gl_text_2d, 0, 3, 64, 64, 0, gl_rgb, gl_unsigned_byte, image);
After defining the texture, you need to enable the function of the texture:
glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D);
After starting the texture, it is necessary to establish the corresponding relationship between the points on the surface of the object and the texture space, that is, when the basic primitive is drawn, call the glTexCoord function before the glVertex function call, and specify the corresponding texture coordinates of the current vertex, for example:
glBegin(GL_TRIANGLES);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex2f(15.0, 15.0);
glTexCoord2f(1.0, 0.0); glVertex2f(30.0, 0.0);
glEnd();
The texture coordinates of the internal points of the primitive are calculated by linear interpolation using the texture coordinates at the vertices.
In OpenGL, the range of texture coordinates is specified between [0,1]. When using the mapping function to calculate texture coordinates, it is possible to obtain coordinates not between [0,1]. At this time, OpenGL has two processing methods, one is truncation and the other is repetition. They are called surround mode. In truncation mode (GL_CLAMP), set texture coordinates greater than 1.0 to 1.0 and texture coordinates less than 0.0 to 0.0. In GL_REPEAT mode, if the texture coordinates are not between [0,1], the integer part of the texture coordinate value is discarded and only the decimal part is used, so that the texture image appears repeatedly on the object surface. For example, use the following function:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Specify the s coordinates in the 2D texture respectively, and adopt the truncation or repeated processing method.
In addition, after transformation and texture mapping, a pixel on the screen may correspond to a small part of the texture element (zoom in) or a large number of processing elements (zoom out). In OpenGL, it is allowed to specify a variety of ways to determine how to complete the calculation method (filtering) corresponding to pixels and texture elements. For example, the following function can specify the filtering methods of amplification and reduction:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Among them, the first parameter of glTexParameteri function specifies that one-dimensional, two-dimensional or three-dimensional textures are used; The second parameter is GL_TEXTURE_MAG_FILTER or GL_TEXTURE_MIN_FILTER, indicating whether to specify the reduction or amplification filtering algorithm; The last parameter specifies the filtering method.
The functions that define texture parameters and specify texture can be placed in init function or main function.
3, Experimental content
The texture data used in texture mapping in OpenGL can be either a set of data generated by the program or read directly from external files.
- The method of directly creating texture is used to generate two-dimensional texture and map it to quadrilateral.
2D texture generation code:
void makeImage(void)
{
int i, j, r,g,b;
for (i = 0; i < ImageWidth; i++)
{
for (j = 0; j < ImageHeight; j++)
{
r=(i*j)%255;
g=(4*i)%255;
b=(4*j)%255;
Image[i][j][0] = (GLubyte) r;
Image[i][j][1] = (GLubyte) g;
Image[i][j][2] = (GLubyte) b;
}
}
}
- Read the texture directly from the external file, realize the texture mapping of each face of the cube, and rotate the cube. The whole process requires three steps: creating texture objects and binding textures, enabling texture mapping and painting using texture coordinates and geometric coordinates. Next, we mainly describe the process of creating and binding textures, and give reference codes.
1) Create texture objects and bind textures
Texture creation is to create an array to save texture data in memory. Generally, we read an image file first and store the RGBA information of the image file into the texture space we create. Of course, the texture space structure will be different if the image bitmap is different. To make this process easier to understand, we use uncompressed textures.
code:
GLuint texture[1]; / / create a texture space
AUX_RGBImageRec *LoadBMP(CHAR *Filename) / / load bitmap image
{
FILE *File=NULL; / / file handle
if(!Filename) / / make sure the file name is provided
{
return NULL;
}
File=fopen(Filename, "r"); / / try to open the file
if(File)
{
fclose(File); / / close the file
return auxDIBImageLoadA(Filename); / / load bitmap and return pointer
}
return NULL; / / if loading fails, null is returned
}
int LoadGLTextures() / / load bitmap and convert to texture
{
int Status=FALSE; / / status indicator
AUX_RGBImageRec *TextureImage[1]; / / create texture storage space
memset(TextureImage, 0, sizeof(void *)*1);// initialization
//Load the bitmap and check for errors. If the bitmap is not found, exit
if(TextureImage[0]=LoadBMP("data.bmp"))
{
Status=TRUE;
//Textures generated using data from bitmaps
glBindTexture(GL_TEXTURE_2D, 0);
//Specifies a 2D texture
glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
if(TextureImage[0]) / / does the texture exist
{
If (textureimage [0] - [data) / / whether the texture image exists
{
free(TextureImage[0]->data); / / free the memory occupied by texture image
}
free(TextureImage[0]); / / release image structure
}
return Status; / / return status
}
2) Enable texture mapping operation and initialize relevant parameters
3) Paint using texture and geometric coordinates
- Realize the effect of adding different textures to six faces of the cube.
Apply texture object:
Gluint my_texture=1;
glBindTexture(GL_TEXTURE_2D, my_texture);
- Texture the table drawn in Experiment 2.
Optional: 1) texture the surface with texture coordinates (sphere, teapot)
GLfloat planes[] = { 0.5,0.0,0.0,0.5 };
GLfloat planet[] = { 0.0,0.5,0.0,0.5 };
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes);
glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
2) Use OpenGL function to realize spherical environment mapping effect:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
4, Experimental design ideas
1. Modify the code according to the example
2. Create a cube, load the texture image with the given code, and use glTexCoord2f(); glVertex3f(); The function makes the coordinates of the texture correspond to each face of the quadrilateral vertex of the cube, and then uses the glBindTexture() function to map each face.
3. Corresponding to 2, assign different maps to each face using glBindTexture() function.
4. Texture the chair in Experiment 2. Similar to the above method, load the texture image with the given code to map the model texture.
5. In the same way as 4, it mainly constructs the teapot model and the correspondence of texture coordinates and points.
5, Experimental code
1.
// texture2.cpp: defines the entry point for the console application. // //#include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> // Create a checkerboard texture pattern #define checkImageWidth 128 #define checkImageHeight 128 static GLubyte checkImage[checkImageHeight][checkImageWidth][4]; #ifdef GL_VERSION_1_1 static GLuint texName; #endif void makeCheckImage(void) { int i, j, r, g, b; for (i = 0; i < checkImageWidth; i++) { for (j = 0; j < checkImageHeight; j++) { r = (i * j) % 255; g = (4 * i) % 255; b = (4 * j) % 255; checkImage[i][j][0] = (GLubyte)r; checkImage[i][j][1] = (GLubyte)g; checkImage[i][j][2] = (GLubyte)b; } } } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); makeCheckImage(); // glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, 4, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glColor3f(1.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0); glTexCoord2f(0.0, 2.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(2.0, 2.0); glVertex3f(2.41421, 1.0, -1.41421); glTexCoord2f(2.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421); glEnd(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 30.0); // glOrtho(-3, 3, -2, 2, 0,10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -3.6); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 's': glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glutPostRedisplay(); break; case 'S': glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glutPostRedisplay(); break; case 't': glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glutPostRedisplay(); break; case 'T': glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glutPostRedisplay(); break; case 27: exit(0); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(250, 250); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
2.
#include <GL/glut.h> #include <GL/glaux.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma comment(lib, "openGL32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma comment( lib,"openGL32.lib" ) GLuint texture[1];//Create texture space GLfloat xRot, yRot, zRot;//Controls the rotation of the cube //Load bitmap image AUX_RGBImageRec* LoadBMP(CHAR* Filename) { //Load bitmap image FILE* File = NULL; //File handle if (!Filename) { //Make sure the file name is provided return NULL; } File = fopen(Filename, "r"); //Attempt to open file if (File) { fclose(File); //Close file return auxDIBImageLoadA(Filename); //Load bitmap and return pointer } return NULL; //NULL if load fails } int LoadGLTextures() //Load bitmap and convert to texture { int Status = FALSE; //Status indicator AUX_RGBImageRec* TextureImage[1]; //Storage space for creating textures memset(TextureImage, 0, sizeof(void*) * 1);//initialization //Load the bitmap and check for errors. If the bitmap is not found, exit if (TextureImage[0] = LoadBMP((CHAR*)"texture6.bmp")) { Status = TRUE; //Textures generated using data from bitmaps glBindTexture(GL_TEXTURE_2D, 0); //Specifies a 2D texture glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (TextureImage[0]) //Does the texture exist { if (TextureImage[0]->data) //Does the texture image exist { free(TextureImage[0]->data); //Free up memory occupied by texture images } free(TextureImage[0]); //Release image structure } return Status; //Return to Status } int InitGL(GLvoid) { if (!LoadGLTextures()) { //Calling the texture loading subroutine return FALSE; } glEnable(GL_TEXTURE_2D); //Enable texture mapping glShadeModel(GL_SMOOTH); //Enable shadow smoothing glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black background glClearDepth(1.0f); //Set depth cache glEnable(GL_DEPTH_TEST); //Enable depth test return TRUE; } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); //Draw a cube, paste a texture and rotate it glBindTexture(GL_TEXTURE_2D, texture[0]); //Select texture glBegin(GL_QUADS); //front 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(); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); //after 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); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); // upper glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 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); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); //lower glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); //right 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); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); //Left 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(); glutPostRedisplay(); glutSwapBuffers(); } void reshape(int w, int h) { if (0 == h) h = 1; glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (GLfloat)w / (GLfloat)h, 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void spinDisplay(void) { xRot += 0.2f; yRot += 0.2f; glutPostRedisplay(); } void mouse(int button, int state, int x, int y) //Mouse monitor { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); //Functions called when the device is idle break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400, 400); glutInitWindowPosition(100, 100); glutCreateWindow("Texture Map"); InitGL(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse);//Mouse monitor glutMainLoop(); return 0; }
3.
#include <GL/glut.h> #include <GL/glaux.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma comment(lib, "openGL32.lib") #pragma comment(lib, "glu32.lib") #pragma comment(lib, "glaux.lib") #pragma comment( lib,"openGL32.lib" ) GLuint texture[1];//Create texture space GLfloat xRot, yRot, zRot;//Controls the rotation of the cube //Load bitmap image AUX_RGBImageRec* LoadBMP(CHAR* Filename) { //Load bitmap image FILE* File = NULL; //File handle if (!Filename) { //Make sure the file name is provided return NULL; } File = fopen(Filename, "r"); //Attempt to open file if (File) { fclose(File); //Close file return auxDIBImageLoadA(Filename); //Load bitmap and return pointer } return NULL; //NULL if load fails } //int LoadGLTextures() / / load bitmap and convert to texture //{ // int Status = FALSE; // Status indicator // AUX_RGBImageRec* TextureImage[1]; // Storage space for creating textures // memset(TextureImage, 0, sizeof(void*) * 1);// initialization Load the bitmap and check for errors. If the bitmap is not found, exit // if (TextureImage[0] = LoadBMP((CHAR*)"texture6.bmp")) // { // Status = TRUE; // //Textures generated using data from bitmaps // glBindTexture(GL_TEXTURE_2D, 0); // //Specifies a 2D texture // glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // } // // if (TextureImage[0]) / / does the texture exist // { // If (textureimage [0] - [data) / / whether the texture image exists // { // free(TextureImage[0]->data); // Free up memory occupied by texture images // } // free(TextureImage[0]); // Release image structure // } // return Status; // Return to status //} int LoadGLTextures() //Load bitmap and convert to texture { int Status = FALSE; //Status indicator AUX_RGBImageRec* TextureImage[6]; //Storage space for creating textures memset(TextureImage, 0, sizeof(void*) * 6);//initialization //Load the bitmap and check for errors. If the bitmap is not found, exit char* image[] = { (char*)"texture1.bmp", (char*)"texture2.bmp", (char*)"texture3.bmp", (char*)"texture4.bmp", (char*)"texture5.bmp", (char*)"texture6.bmp", }; for (int i = 0; i < 6; i++) { if (TextureImage[i] = LoadBMP(image[i])) { Status = TRUE; glGenTextures(1, &texture[i]); //Textures generated using data from bitmaps glBindTexture(GL_TEXTURE_2D, texture[i]); //Specifies a 2D texture glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (i == 5) { printf("cecewce"); } if (TextureImage[i]) //Does the texture exist { if (TextureImage[i]->data) //Does the texture image exist { printf("Texture exists"); free(TextureImage[i]->data); //Free up memory occupied by texture images } free(TextureImage[i]); //Release image structure } } return Status; //Return to Status } int InitGL(GLvoid) { if (!LoadGLTextures()) { //Calling the texture loading subroutine return FALSE; } glEnable(GL_TEXTURE_2D); //Enable texture mapping glShadeModel(GL_SMOOTH); //Enable shadow smoothing glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black background glClearDepth(1.0f); //Set depth cache glEnable(GL_DEPTH_TEST); //Enable depth test return TRUE; } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); //Draw a cube, paste a texture and rotate it glBindTexture(GL_TEXTURE_2D, texture[0]); //Select texture glBegin(GL_QUADS); //front 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(); glBindTexture(GL_TEXTURE_2D, texture[1]); glBegin(GL_QUADS); //after 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); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[4]); glBegin(GL_QUADS); // upper glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 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); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[3]); glBegin(GL_QUADS); //lower glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[4]); glBegin(GL_QUADS); //right 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); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, texture[5]); glBegin(GL_QUADS); //Left 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(); glutPostRedisplay(); glutSwapBuffers(); } void reshape(int w, int h) { if (0 == h) h = 1; glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (GLfloat)w / (GLfloat)h, 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void spinDisplay(void) { xRot += 0.2f; yRot += 0.2f; glutPostRedisplay(); } void mouse(int button, int state, int x, int y) //Mouse monitor { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); //Functions called when the device is idle break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400, 400); glutInitWindowPosition(100, 100); glutCreateWindow("Texture Map"); InitGL(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse);//Mouse monitor glutMainLoop(); return 0; }
4.
#define _CRT_SECURE_NO_WARNINGS #include <GL/glut.h> #include <stdlib.h> #include<GL/glaux.h> #include<stdio.h> float size = 0.25; //zoom float fRotate = 0; float fScale = 1.0f; // set inital scale value to 1.0f float x = 1, y = 0, z = 0; static GLfloat spin = 0.0; static GLfloat i = 0.0; // Initialize material properties, lights, lighting models, and depth buffers GLuint texture[1]; //Create a texture space AUX_RGBImageRec* LoadBMP(CHAR* Filename) //Load bitmap image { FILE* File = NULL; //File handle if (!Filename) //Make sure the file name is provided { return NULL; } File = fopen(Filename, "r"); //Attempt to open file if (File) { fclose(File); //Close file return auxDIBImageLoadA(Filename); //Load bitmap and return pointer } return NULL; //NULL if load fails } int LoadGLTextures() //Load bitmap and convert to texture { int Status = FALSE; //Status indicator AUX_RGBImageRec* TextureImage[1]; //Storage space for creating textures memset(TextureImage, 0, sizeof(void*) * 1);//initialization //Load the bitmap and check for errors. If the bitmap is not found, exit if (TextureImage[0] = LoadBMP((CHAR*)"texture.bmp")) { Status = TRUE; //Textures generated using data from bitmaps glBindTexture(GL_TEXTURE_2D, 0); //Specifies a 2D texture glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (TextureImage[0]) //Does the texture exist { if (TextureImage[0]->data) //Does the texture image exist { free(TextureImage[0]->data); //Free up memory occupied by texture images } free(TextureImage[0]); //Release image structure } return Status; //Return to Status } void myinit(void) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); GLfloat mat_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat light0_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light0_specular[] = { 0.0, 1.0, 1.0, 1.0 }; GLfloat light0_position[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light1_ambient[] = { 0.2, 0.2, 0.2, 1.0 };//Ambient light GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };//diffuse reflection GLfloat light1_specular[] = { 0.0, 0.0, 1.0, 1.0 };//Specular reflection GLfloat light1_position[] = { 0.0, -1.5, -4.0, 1.0 }; GLfloat spot_direction[] = { 0.0, 1.5, -6.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular); glLightfv(GL_LIGHT1, GL_POSITION, light1_position); glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 30.0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); LoadGLTextures(); GLfloat planes[] = { 0.5,0.0,0.0,0.5 }; GLfloat planet[] = { 0.0,0.5,0.0,0.5 }; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } void Draw_Leg() // This function draws one of the table leg { //Draw a table leg glPushMatrix(); glScalef(1.0f, 1.0f, 3.0f); glutSolidCube(1.0 * size); glPopMatrix(); } void Draw_Table() // This function draws a Table { glPushMatrix(); //Save the current matrix to the top of the stack (save the current matrix). glScalef(5.0f, 4.0f, 1.0f); //Scaling function glColor3f(1.0, 0.0, 1.0); glutSolidCube(1 * size); //Draw a line cube glPopMatrix(); //pop out glPushMatrix(); //Save the current matrix to the top of the stack (save the current matrix). glScalef(4.0f, 1.0f, 4.0f); //Scaling function glTranslatef(0.0 * size, 1.5 * size, 0.5 * size); glColor3f(0.0, 0.0, 1.0); glutSolidCube(1 * size); //Draw a line cube glPopMatrix(); //pop out glPushMatrix(); //The column in the lower left corner glTranslatef(-1.5 * size, -1 * size, -1.5 * size); //The size is the coordinate origin relative to the center, according to the size in the experimental guidance Draw_Leg(); glPopMatrix(); glPushMatrix(); //The column in the lower right corner glTranslatef(1.5 * size, -1 * size, -1.5 * size); Draw_Leg(); glPopMatrix(); glPushMatrix(); //The column in the upper right corner glTranslatef(1.5 * size, 1 * size, -1.5 * size); Draw_Leg(); glPopMatrix(); glPushMatrix(); //The column in the upper left corner glTranslatef(-1.5 * size, 1 * size, -1.5 * size); Draw_Leg(); glPopMatrix(); } void display(void) { GLfloat position[] = { 0.0, -1.5, -4.0, 1.0 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0f, 0.0f, -6.0f); // Place the triangle at Center glRotatef(fRotate, 1, 0, 0); // Rotate around Y axis Draw_Table(); // Draw triangle glPopMatrix(); fRotate += 0.05; glutSwapBuffers(); //Swap dual cache glFlush(); } void myReshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case'x': exit(0); break; default: break; } } void spinDisplay(void) { spin = spin + 0.02; if (spin > 360.0) spin = spin - 360.0; glutPostRedisplay(); } void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); //Functions called when the device is idle break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } //The main function initializes the window size, RGBA display mode and handles input events int main(int argc, char* argv[]) { glutInit(&argc, argv); //glutIni tDi splayMode (GLUT. SINGLE| GLUT_ RGB); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); //Use dual cache mode glutInitWindowSize(640, 480); glutInitWindowPosition(0, 0); glutCreateWindow("Position light and multi light demonstration"); glutReshapeFunc(myReshape); glutDisplayFunc(display); myinit(); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
5.
#define _CRT_SECURE_NO_WARNINGS #include <GL/glut.h> #include<GL/glaux.h> #include<stdio.h> static GLfloat theta[] = { 0.0,0.0,0.0 }; static GLint axis = 2; GLuint texture[1]; //Create a texture space AUX_RGBImageRec* LoadBMP(CHAR* Filename) //Load bitmap image { FILE* File = NULL; //File handle if (!Filename) //Make sure the file name is provided { return NULL; } File = fopen(Filename, "r"); //Attempt to open file if (File) { fclose(File); //Close file return auxDIBImageLoadA(Filename); //Load bitmap and return pointer } return NULL; //NULL if load fails } int LoadGLTextures() //Load bitmap and convert to texture { int Status = FALSE; //Status indicator AUX_RGBImageRec* TextureImage[1]; //Storage space for creating textures memset(TextureImage, 0, sizeof(void*) * 1);//initialization //Load the bitmap and check for errors. If the bitmap is not found, exit if (TextureImage[0] = LoadBMP((CHAR*)"texture3.bmp")) { Status = TRUE; //Textures generated using data from bitmaps glBindTexture(GL_TEXTURE_2D, 0); //Specifies a 2D texture glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (TextureImage[0]) //Does the texture exist { if (TextureImage[0]->data) //Does the texture image exist { free(TextureImage[0]->data); //Free up memory occupied by texture images } free(TextureImage[0]); //Release image structure } return Status; //Return to Status } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); glutSolidTeapot(1.0); // glutSolidCube(3.0); // glutSolidSphere(1.0, 50, 50); glutSwapBuffers(); } void spinCube() { theta[axis] += 0.05; if (theta[axis] > 360.0) theta[axis] -= 360.0; glutPostRedisplay(); } void mouse(int btn, int state, int x, int y) { if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0; if (btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1; if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2; } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat)h / (GLfloat)w, 2.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0); else glOrtho(-2.0 * (GLfloat)w / (GLfloat)h, 2.0 * (GLfloat)w / (GLfloat)h, -2.0, 2.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); } void key(unsigned char k, int x, int y) { if (k == '1') glutIdleFunc(spinCube); if (k == '2') glutIdleFunc(NULL); if (k == 'q') exit(0); } void Init() { glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); LoadGLTextures(); GLfloat planes[] = { 0.5,0.0,0.0,0.5 }; GLfloat planet[] = { 0.0,0.5,0.0,0.5 }; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_LINEAR, planes); glTexGenfv(GL_T, GL_OBJECT_LINEAR, planet); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("colorcube"); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutIdleFunc(spinCube); glutMouseFunc(mouse); Init(); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glutKeyboardFunc(key); glutMainLoop(); }
6, Experimental results and experience
In this experiment, the texture mapping of three-dimensional graphics makes the object more realistic. The texture mapping is carried out through the mapping, and the surface texture is given through the coordinates. Through this experiment, I learned the texture mapping in graphics and gained a lot, which is of great help to the study of this course in the future.