{
Textures can greatly save CPU time. Haha, but this section took me a lot of time: (
Because the OpenGL auxiliary library is used, few people use the functions of this library now, but I still found it. Thanks to zdcnow (Magnetic Effect), he provided me with the Delphi version of this auxiliary library. Before studying this section, please download the glaux.dll and Glaux.pas files online and add them to the project.
Okay, let's continue on the OPENGL road.
First we need to add the SysUtils unit, because we are going to use file operations in this section, and we also need to add the Glaux unit.
Then we add several variables, xrot, yrot and zrot, based on the first lesson. These variables are used to rotate the cube around the X, Y, and Z axes. texture[] allocates storage space for a texture. If you need more than one texture, you should change the number 1 to the number you need.
}
VAR
h_RC: HGLRC; // Rendering Context (shading description table).
h_DC: HDC; // Device Context (device description table)
h_Wnd: HWND; // window handle
h_Instance: HINST; // Program Instance (instance).
keys : Array[0..255] Of Boolean; // Array for keyboard routines
xrot, // X rotation amount (new)
yrot, // Y rotation amount (new)
zrot : GLfloat; // Z rotation amount (new)
Texture : Array[0..1] Of GLuint; // Store a texture (new)
{Then load the two processes in opengl32.dll, we need to use them}
PRocedure glGenTextures(n: GLsizei; Var textures: GLuint); stdcall; external
opengl32;
Procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
opengl32;
{Next we need to add a new function to re-enter the image. The return type of this function is defined in Glaux.pas as follows:
TAUX_RGBImageRec= record
sizeX, sizeY: GLint;
data: pointer;
end;
PTAUX_RGBImageRec= ^TAUX_RGBImageRec;
The specific meaning will be introduced later}
Function LoadBmp(filename: pchar): PTAUX_RGBImageRec;
Var
BitmapFile : Thandle; // file handle
Begin
//Next check if the filename has been provided
If Filename = '' Then // Ensure filename is provided.
result := Nil; // If not provided, return NULL
//Then check if the file exists.
BitmapFile := FileOpen(Filename, fmOpenWrite); //Try to open the file
//If we can open the file, obviously the file exists.
If BitmapFile > 0 Then // Does the file exist?
Begin
//Close the file.
FileClose(BitmapFile); //Close handle
//auxDIBImageLoad(Filename) reads image data and returns it.
result := auxDIBImageLoadA(filename); //Load the bitmap and return the pointer
End
Else
//If we cannot open the file, we will return NiL.
result := Nil; // If loading fails, return NiL.
End;
//Next create a new function to load the texture map
Function LoadTexture: boolean;
//Status variable. We use this to track whether the bitmap can be loaded and whether the texture can be created.
// Status is set to FALSE by default (indicating that nothing is loaded or created).
//TextureImage variable PTAUX_RGBImageRec type stores the image record of the bitmap.
//This record contains the width, height and data of the bitmap.
Var
Status: boolean;
TextureImage : Array[0..1] Of PTAUX_RGBImageRec;
Begin
Status := false;
ZeroMemory(@TextureImage, sizeof(TextureImage)); // Set pointer to NULL
TextureImage[0] := LoadBMP('Texture.bmp');
If TextureImage[0] <> Nil Then
Begin
Status := TRUE; // Set Status to TRUE
//Now use the data in TextureImage[0] to create a texture.
//glGenTextures(1, texture[0]) tells OpenGL that we want to generate a texture name
//(If you want to load multiple textures, increase the number).
//glBindTexture(GL_TEXTURE_2D, texture[0]) tells OpenGL to bind the texture name texture[0] 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 that the memory at &texture[0] is available.
//The texture we create will be stored in the memory area pointed to by &texture[0].
glGenTextures(1, texture[0]); // Create texture
glBindTexture(GL_TEXTURE_2D, texture[0]); //Use a typical texture generated from bitmap data
//Down we create the real texture.
//The following line tells OpenGL that this texture is a 2D texture (GL_TEXTURE_2D).
//The number zero represents the detail level of the image, which is usually left at zero.
//The number three is the number of components of the data. Because the image is composed of three components: red data, green data, and blue data.
//TextureImage[0].sizeX is the width of the texture.
//If you know the width, you can fill it in here, but the computer can easily figure this out for you.
// TextureImage[0].sizey is the height of the texture.
//The number zero is the value of the border, usually zero.
// GL_RGB tells OpenGL that the image data consists of red, green, and blue color data.
//GL_UNSIGNED_BYTE means that the data making up the image is of unsigned byte type.
//Finally... TextureImage[0].data tells OpenGL the source of the texture data.
//This example points to the data stored in the TextureImage[0] 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 when displaying the image,
//When it is larger than the enlarged original texture (GL_TEXTURE_MAG_FILTER)
// Or the filtering method used by OpenGL when the texture is reduced to a size smaller than the original texture (GL_TEXTURE_MIN_FILTER).
//Usually I use GL_LINEAR in both cases. This allows textures to appear smoothly from far away to very close to the screen.
//Using GL_LINEAR requires the CPU and graphics card to do more operations.
//If your machine is slow, you should probably use GL_NEAREST.
//When the filtered texture is enlarged, it looks very mosaic (mosaic).
//You can also combine these two filtering methods. Use GL_LINEAR when near and GL_NEAREST when far away.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear filtering
End;
//Now we release the memory previously used to store bitmap data.
//We first check whether the bitmap data is stored at.
//If so, check whether the data has been stored.
//If it has been stored, delete it.
//Then release the TextureImage[0] image structure to ensure that all memory can be released.
If assigned(TextureImage[0]) Then // Whether the texture exists
If assigned(TextureImage[0].data) Then // Whether the texture image exists
TextureImage[0].data := Nil; // Release the memory occupied by the texture image
TextureImage[0] := Nil; // Release the image structure
//Finally return the status variable. If everything is OK, the variable Status has the value TRUE. Otherwise FALSE
result := Status; // Return Status
End;