LearningTexture mapTexture ing has many benefits. For example, you want a missile to fly over the screen. Based on the knowledge of the previous lessons, the most feasible method is to build a missile profile with a lot of polygon and add interesting colors. With texture ing, you can use real missile images and let them fly over the screen. Which one do you think is better? Are there still a lot of triangles and quadrilateral photos? The benefits of using texture ing are not only better-looking, but also faster program running. Missile textures may be just a quadrilateral flying over a window. A missile built on polygon may include hundreds of thousands of polygon. Obviously, pasters greatly save CPU time. Now we add the new five lines of code at the beginning of the first lesson. The first line added is# Include <stdio. h>. It allows us to operate on files, in order to useFopen (), We added this line. Then we added three new floating point variables...Xrot,YrotAndZrt. These variables are used to rotate the cube around the X, Y, and Z axes. Last lineGluint texture [1]Allocate storage space for a texture. If you need more than one texture, change number 1 to the number you need. |
# Include <windows. h> // windows header file # Include <stdio. h> // header file of the standard input/output Library (new) # Include <Gl/Gl. h> // header file of the opengl32 Library # Include <Gl/Glu. h> // header file of the glu32 Library # Include <Gl/Glaux. h> // header file of the Glaux LibraryHglrc HRC = NULL; // permanent coloring description table HDC = NULL; // Private GDI device description table Hwnd = NULL; // save our window handle Hinstance; // The instance that saves the program Bool keys [256]; // Array Used for keyboard routines Bool active = true; // The activity flag of the window. The default value is true. Bool fullscreen = true; // The full screen flag is set to full screen by default.
Glfloat xrot; // X rotation volume (new) Glfloat yrot; // y rotation volume (new) Glfloat Zrt; // Z rotation volume (new) Gluint texture [1]; // store a texture (new)
Lresult callback wndproc (hwnd, uint, wparam, lparam); // wndproc Definition
|
Keep up with the above CodeResizeglscene ()Previously, we added the following code. This code is used to load bitmap files. If the object does not existNullInform the program that the bitmap cannot be loaded. Before I start to explain this code, it is important to have a few points about the image used as a texture, and you must understand it. The width and height of the image must be the N power of 2; the width and height must be at least 64 pixels; and for compatibility reasons, the width and height of the image should not exceed 256 pixels. If the width and height of your raw material are not 64,128,256 pixels, use the image processing software to re-resize the image. There is certainly a way to bypass these limitations, but now we only need to use standard texture sizes. First, create a file handle. A handle is a value used to identify a resource. It enables the program to access this resource. Let's set the handleNull. |
Aux_rgbimagerec * loadbmp (char * filename) // load the bitmap image { File * file = NULL; // file handle |
Next, check whether the file name is provided. BecauseLoadbmp ()There can be no parameter calls, so we have to check it. You don't want to load anything .....:) |
If (! Filename) // make sure the file name is provided. { Return NULL; // if not provided, null is returned. } |
Then, check whether the file exists. The following line tries to open the file. |
File = fopen (filename, "R"); // try to open the file |
If we can open the file, it is obvious that the file exists. UseFclose (file)Close the file.Auxdibimageload (filename)Read image data and return it. |
If (File) // does the file exist? { Fclose (File); // close the handle Return auxdibimageload (filename); // load the bitmap and return the pointer } |
If the file cannot be opened, null is returned. This means that the file cannot be loaded. The program will check whether the file has been loaded. If no, the program is exited and an error message is displayed. |
Return NULL; // If loading fails, null is returned. } |
The next part of the code loads the bitmap (call the code above) and converts it to a texture. |
Int loadgltextures () // load a bitmap (call the code above) and convert it to a texture { |
Then setStatus. We use it to track whether bitmap can be loaded and whether texture can be created.StatusThe default value isFalse(It indicates that no data is loaded or created ). |
Int status = false; // Status Indicator |
Now we create an image record that stores bitmap. The record contains the width, height, and data of the bitmap. |
Aux_rgbimagerec * textureimage [1]; // create a texture Bucket |
Clear image records and make sure the content is empty. |
Memset (textureimage, 0, sizeof (void *) * 1); // set the pointer to null |
Now load the bitmap and convert it to a texture.Textureimage [0] = loadbmp ("Data/nehe.bmp ")CallLoadbmp (). LoadDataDirectoryNehe.bmpBitmap File. If everything is normal, the image data will be stored inTextureimage [0]Medium,StatusSetTrueAnd then we start to create the texture. |
// Load the bitmap and check for any errors. Exit if the bitmap is not found. If (textureimage [0] = loadbmp ("Data/nehe.bmp ")) { Status = true; // set status to true |
In useTextureimage [0]Data to create a texture. First lineGlgentextures (1, & texture [0])Tell OpenGL that we want to generate a texture name (if you want to load multiple textures, increase the number ). It is worth noting that we started usingGluint texture [1]To create a texture storage space, you may think that the first texture is stored in& Texture [1]But this is wrong. The correct address should be& Texture [0]. If you useGluint texture [2]The second texture is stored inTexture [1]. "NOTE: there should be no obstacle in learning C. arrays start from scratch .』 Row 2Glbindtexture (gl_texture_2d, texture [0])Tell OpenGL to name the textureTexture [0]Bind to the texture target. 2d textures only have height (on the Y axis) and width (on the X axis ). The main function assigns the texture name to the texture data. In this example, we tell OpenGL,& Texture [0]The memory is available. The texture we created will be stored in& Texture [0]OfTo the memory area. |
Glgentextures (1, & texture [0]); // create a texture // Use a typical texture generated from the bitmap data Glbindtexture (gl_texture_2d, texture [0]); |
Next we will create a true texture. The following line tells OpenGL that this texture is a 2D texture (Gl_texture_2d). The number zero represents the degree of detail of the image, which usually goes from zero. Number 3 is the score of the data. Because the image consists of three components: Red Data, green data, and blue data.Textureimage [0]-> sizexIs the width of the texture. If you know the width, you can enter it here, but the computer can easily point this value for you.Textureimage [0]-> sizeyIs the texture height. Zero is the border value, usually zero.Gl_rgbTells OpenGL that image data is composed of three colors: Red, green, and blue. Gl_unsigned_byteThis means that the data that makes up the image is of the unsigned byte type. Last...Textureimage [0]-> dataTells OpenGL the source of texture data. In this example, pointTextureimage [0]The data in the record. |
// Generate texture Glteximage2d (gl_texture_2d, 0, 3, textureimage [0]-> sizex, textureimage [0]-> sizey, 0, gl_rgb, gl_unsigned_byte, textureimage [0]-> data ); |
The following two lines tell OpenGL that when displaying an image, it is larger than the enlarged original texture (Gl_texture_mag_filter) Or smaller than the original texture (Gl_texture_min_filter. In both cases, I usually useGl_linear. This allows the texture to be smoothly displayed from a very distance to a very close to the screen. UseGl_linearCPU and video card are required for more operations. If your machine is slow, you may need to useGl_nearest. When the filtered texture is amplified, it looks very mottled "Translator's note: Mosaic 』. You can also combine these two filtering methods. Use nearGl_linearIn the distanceGl_nearest. |
Gltexparameteri (gl_texture_2d, gl_texture_min_filter, gl_linear); // Linear Filter Gltexparameteri (gl_texture_2d, gl_texture_mag_filter, gl_linear); // Linear Filter } |
Now we release the memory used to store bitmap data. First, check whether the bitmap data is stored. If yes, check whether the data is stored. If it is already stored, delete it. Then releaseTextureimage [0]Image structure to ensure that all memory is released. |
If (textureimage [0]) // whether the texture exists { If (textureimage [0]-> data) // whether the texture image exists { Free (textureimage [0]-> data); // release the memory occupied by the texture image }Free (textureimage [0]); // release the image structure }
|
Finally, the status variable is returned. If everything is OK, the variableStatusIsTrue. OtherwiseFalse. |
Return status; // return status } |
I onlyInitglA few lines of code are added. However, to help you check which lines have been added, I re-paste all this code.If (! Loadgltextures ())This line of code calls the subroutine mentioned above to load the bitmap and generate the texture. If for any reasonLoadgltextures ()If the call fails, false is returned for the next row. If everything is OK and the texture is created, we enable 2D Texture ing. If you forget to enable it, your object will always look pure white, which is definitely not a good thing. |
Int initgl (glvoid) // All OpenGL settings are started here { If (! Loadgltextures () // call the texture loading subroutine (new) { Return false; // If loading fails, false is returned (new) }Glable (gl_texture_2d); // enable texture ing (new) Glshademodel (gl_smooth); // enables shadow smoothing. Glclearcolor (0.0f, 0.0f, 0.0f, 0.5f); // black background Glcleardepth (1.0f); // sets the depth cache. Glable (gl_depth_test); // enable deep Test Gldepthfunc (gl_lequal); // type of the deep Test Glhint (gl_perspective_correction_hint, gl_nicest); // truly fine-grained perspective correction Return true; // initialize OK } |
Now, let's draw a texture: texture ing. It is difficult to replace the term. I want to write less words. Cube _ ^. This code has been commented out and should be very understandable. Start two lines of codeGlclear ()AndGlloadidentity ()It is the code in the first lesson.Glclear (gl_color_buffer_bit | gl_depth_buffer_bit)Clear the screen and set itInitgl ()The selected color. In this example, it is black. The deep cache is also cleared. The model observation matrix is also Reset using glloadidentity. |
Int drawglscene (glvoid) // start to draw all { Glclear (gl_color_buffer_bit | gl_depth_buffer_bit); // clear the screen and depth Cache Glloadidentity (); // reset the current model observation matrix Gltranslatef (0.0f, 0.0f,-5.0f); // move 5 units into the screen |
The following three rows rotate the cube around the X, Y, and Z axes. Variable-dependent RotationXrot,YrotAndZrt. |
Glrotatef (xrot, 1.0f, 0.0f, 0.0f); // rotate around the X axis Glrotatef (yrot, 0.0f, 1.0f, 0.0f); // rotate around the Y axis Glrotatef (Zrt, 0.0f, 0.0f, 1.0f); // rotate around the Z axis |
Select the texture for the next line of code. If you use multiple textures in your scenario, you should useGlbindtexture (gl_texture_2d, texture [Number corresponding to the texture used])Select the texture to bind. When you want to change the texture, you should bind the new texture. It is worth noting that you cannotGlbegin ()AndGlend ()The texture must beGlbegin ()Before orGlend ()Then bind. Note how we use it laterGlbindtextureTo specify and bind the texture. |
Glbindtexture (gl_texture_2d, texture [0]); // select the texture |
To correctly map a texture to a quadrilateral, you must map the upper-right corner of the texture to the upper-right corner of the Quadrilateral, the upper-left corner of the texture to the upper-left corner of the Quadrilateral, and the lower-right corner of the texture to the lower-right corner of the Quadrilateral, the lower left corner of the texture maps to the lower left corner of the Quadrilateral. If the ing is incorrect, the image may be displayed upside down and upside down. The lateral side or nothing is displayed. Gltexcoord2fThe first parameter is the X coordinate.0.0fIs the left side of the texture.0.5fIs the midpoint of the texture,1.0fIs the right side of the texture.Gltexcoord2fThe second parameter is Y coordinate.0.0fIs the bottom of the texture.0.5fIs the midpoint of the texture,1.0fIs the top of the texture. So the top left coordinate of the texture isX: 0.0f, Y: 1.0fThe top left vertex of the quadrilateral isX:-1.0f, Y: 1.0f. The other three points are as follows. Try to playGltexcoord2f. Set1.0fChange0.5fOnly the left half of the texture is displayed.0.0fChange0.5fOnly the right half of the texture is displayed. |
Glbegin (gl_quads ); // Front Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // left bottom of texture and quadrilateral Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // right bottom of texture and quadrilateral Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f, 1.0f); // texture and top right of the Quadrilateral Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // top left of texture and quadrilateral // After Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // right bottom of texture and quadrilateral Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // texture and top right of the Quadrilateral Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // top left of texture and quadrilateral Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f,-1.0f); // left bottom of texture and quadrilateral // Top surface Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // top left of texture and quadrilateral Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // left bottom of texture and quadrilateral Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f, 1.0f, 1.0f); // texture and bottom right of the Quadrilateral Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // texture and top right of the Quadrilateral // Bottom Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // top right of texture and quadrilateral Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f,-1.0f,-1.0f); // top left of texture and quadrilateral Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // left bottom of texture and quadrilateral Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // right bottom of texture and quadrilateral // Right Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f,-1.0f,-1.0f); // right bottom of texture and quadrilateral Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // texture and top right of the Quadrilateral Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f, 1.0f, 1.0f); // texture and top left of the Quadrilateral Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // left bottom of texture and quadrilateral // Left Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // left bottom of texture and quadrilateral Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // right bottom of texture and quadrilateral Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // texture and top right of the Quadrilateral Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // top left of texture and quadrilateral Glend ();
|
Add nowXrot,YrotAndZrt. Change the value of each variable to adjust the rotation speed of the cube, or change the plus or minus sign to adjust the orientation of the cube. |
Xrot + = 0.3f; // X axis rotation Yrot + = 0.2f; // y axis rotation Zrt + = 0.4f; // Z axis rotation Return true; // continue running } |
Now you should better understand texture ing. You should have mastered the technology of attaching your favorite image to any quadrilateral surface. Once you are confident in understanding 2D Texture ing, try pasting different textures on the six sides of the cube. Texture ing is not difficult to understand after you understand the concept of texture coordinates .! If you have any comments or suggestions, please email me. If you think there is something wrong or can be improved, please let me know. |
"Translator: the document of nehe seems very simple and arrogant. But how many other experts have you ever seen? I am not a master. I hope you are sincere .』 Below is the source code download link. Good luck! |
* Download visual c ++ code for this lesson. |