1. Understand textures
In OpenGL, a texture is graphical data that is used primarily to wrap different objects.
Different wallpaper when you decorate your house, you need different wallpaper for each room. The wallpaper here is what we call texture.
- Images are displayed on the screen by decoding them into bitmaps and displaying them. The size of an image’s storage space in the frame buffer can be calculated using this formula:
Image storage space = image height * image width * number of bytes per pixel
- In OpenGL, textures are generally. TGA file. In the actual iOS development, we use OpenGL ES, which can directly use compressed images in PNG and JPG formats as texture data. Because the system decodes the compressed image into a bitmap for texture use, each pixel of the bitmap has its own color space.
2. Texture related apis
Let’s put the data tables used in the API first for easy reference
Pixel format table and pixel data type table
[Pixel Format – Format table]
[Pixel datatype -type table]
[Example to interpret type table]
Texture use steps: read file data, load texture, generate texture objects, set texture parameters
1. Read texture data
1.1 Read file data from color buffer
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei height, GLenum format, GLenum type,const void * pixels); /* // Parameter 1: x, the window coordinates in the bottom left corner of the rectangle // Parameter 2: y, the window coordinates in the bottom left corner of the rectangle // Parameter 3: width, the width of the rectangle in pixels // Parameter 4: height, the height of the rectangle in pixels // parameter 5: Format,OpenGL pixel format, such as RGBA. OpenGL specifies the data type in the cache to store colors in pixels. The data type of the pixel data is the same as the data type of the pixel data. */ / Specifies the buffer to read glReadBuffer(mode); // Specify write buffer glWriteBuffer(mode);Copy the code
1.2 Reading texture data from a TGA file
/* Parameter 1: texture file name parameter 2: file width address parameter 3: file height address parameter 4: file component address parameter 5: file format address Returned value: GltReadTGABits (<#const char *szFileName#>, <#GLint *iWidth#>, <#GLint *iHeight#>, <#GLint *iComponents#>, <#GLenum *eFormat#>)Copy the code
2. Load the texture
GlTexImage2D is generally used
//width void glTexImage1D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLint border,GLenum format,GLenum type,void *data); //width + height void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,void * data); //width + height + depth void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data); /* * target: 'GL_TEXTURE_1D', 'GL_TEXTURE_2D', 'GL_TEXTURE_3D'. * Level: Specifies the mIP map Level to load. We usually set this parameter to 0. * InternalFormat: How many color components to store in each texture unit. * Width, height, depth: indicates the width, height, and depth of the loaded texture. = = attention! These values must be raised to an integer power of 2. (This is due to a requirement left over from older versions of OpenGL. Now, of course, it's possible to support an integer power other than 2. But developers are still used to setting these parameters to the power of 2.) * Border parameter: allows specifying a border width for the texture map. * Format, type, data parameters: same as above */Copy the code
3. Generate textures
There are two steps to generating a texture:
1. Apply for texture object assignment. GlGenTextures 2, bind texture state. glBindTexture
3.1 Applying for allocating texture objects
// Use the function to allocate texture objects // specify the number of texture objects and Pointers (Pointers to an unsigned integer array filled with texture object identifiers). void glGenTextures(GLsizei n,GLuint * textTures); // e.g. GlGenTextures (1, &textureID);Copy the code
3.2 Binding texture state
// Bind texture state // parameter target:GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D // parameter texture: void glBindTexture(GLenum target,GLunit texture); GlBindTexture (GL_TEXTURE_2D, textureID);Copy the code
3.3 Deleting a Texture Object
// Remove the binding texture object // Texture object and texture object pointer (the pointer points to an unsigned integer array filled with texture object identifiers). void glDeleteTextures(GLsizei n,GLuint *textures); // Like: glDeleteTextures(1, &textureID);Copy the code
3.4 Test whether the texture object is valid
The function returns GL_TRUE if the texture is a texture object that already has space allocated, GL_FALSE otherwise. GLboolean glIsTexture(GLuint texture); // For example, glIsTexture(textureID);Copy the code
4. Set texture parameters
This is mainly to set the filter mode of the texture when zooming in and out, and the surround mode on the X /y axis. This is done by specifying parameters and setting them accordingly
/* Parameter 1:target specifies which texture mode these parameters will be applied to, such as GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D. Void glTexParameterf(GLenum target,GLenum pname,GLFloat param); void glTexParameterf(GLenum target,GLenum pname,GLFloat param); void glTexParameteri(GLenum target,GLenum pname,GLint param); void glTexParameterfv(GLenum target,GLenum pname,GLFloat *param); void glTexParameteriv(GLenum target,GLenum pname,GLint *param);Copy the code
4.1 Filtering Mode
There are two commonly used: adjacent filtering, linear filtering.
- GL_NEAREST: Select the color nearest the current location
- GL_LINEAR: A combination of colors obtained by a series of blending calculations for all colors surrounding the current position
- Suggestion: Use neighborhood filter when zooming in texture, use linear filter when zooming in texture
GlTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); GlTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); GlTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); GlTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);Copy the code
[Comparison of two filtering methods]
4.2 Surround Mode
Wraparound mode refers to the appearance of edges when texture coordinates are outside the default range
Note: s, T, R, q in the texture correspond to x, y, z, w in the coordinate system
Surround mode:
- GL_REPEAT: Default, repeat texture image
- GL_MIRRORED_REPEAT: Repetition of texture images, each repetition of which was mirrored
- GL_CLAMP_TO_EDGE: The texture coordinates are constrained between 0 and 1, and the excess part repeats the edge of the texture coordinates, creating the effect of the edge being stretched
- GL_CLAMP_TO_BORDER: The coordinate beyond is the user specified edge color
GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_TEXTURE_T, GL_TEXTURE_R GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER */ glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE); glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);Copy the code
[Comparison of 4 surround modes]
Let’s move on to the other apis
5. Storage method of texture pixels
Void glPixelStorei(GLenum pname,GLint param); Void glPixelStoref(GLenum pname,GLfloat param); /* Example: parameter 1: GL_UNPACK_ALIGNMENT Specifies how OpenGL unpacks image data from the data cache. GL_UNPACK_ALIGNMENT specifies the alignment request at the start of each pixel line in memory. 1 (byte alignment), 2 (even byte alignment), 4 (word alignment), 8 (lines start at double-byte boundaries) Parameter 2: GL_UNPACK_ALIGNMENT Specifies the GL_UNPACK_ALIGNMENT value */ glPixelStorei(GL_UNPACK_ALIGNMENT,1);Copy the code
6. Update textures
Parameters refer to the previous API
//xOffset
void glTexSubImage1D(GLenum target,GLint level,GLint xOffset,GLsizei width,GLenum format,GLenum type,const GLvoid *data);
//xOffset + yOffset
void glTexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid *data);
//xOffset + yOffset + zOffset
void glTexSubImage3D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLint zOffset,GLsizei width,GLsizei height,GLsizei depth,Glenum type,const GLvoid * data);
Copy the code
7. Insert and replace textures
Parameters refer to the previous API
//xoffset
void glCopyTexSubImage1D(GLenum target,GLint level,GLint xoffset,GLint x,GLint y,GLsizei width);
//xOffset + yOffset
void glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint x,GLint y,GLsizei width,GLsizei height);
//xOffset + yOffset + zOffset
void glCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yOffset,GLint zOffset,GLint x,GLint y,GLsizei width,GLsizei height)
Copy the code
8. Use color buffer to load data and form new texture
Parameters x,y specify the location in the color cache to start reading the texture data;
The data in the cache is set by the source cache using glReadBuffer. Note: There is no glCopyTextImage3D because we cannot get volume data from the 2D color cache.
//width
void glCopyTexImage1D(GLenum target,GLint level,GLenum internalformt,GLint x,GLint y,GLsizei width,GLint border);
//width + height
void glCopyTexImage2D(GLenum target,GLint level,GLenum internalformt,GLint x,GLint y,GLsizei width,GLsizei height,GLint border);
Copy the code
9. Compress textures
9.1 General compressed texture format
9.2 Determining compression and selecting a compression mode
// According to the selected compression texture format, select the fastest, best, self-selecting algorithm to select the compression format. glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST); glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST); glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE);Copy the code
9.3 Loading compressed Textures
//width void glCompressedTexImage1D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint border,GLsizei imageSize,void *data); //width + heigth void glCompressedTexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLint heigth,GLint border,GLsizei imageSize,void *data); //width + heigth + depth void glCompressedTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei heigth,GLsizei depth,GLint border,GLsizei imageSize,void *data); /* target: 'GL_TEXTURE_1D', 'GL_TEXTURE_2D', 'GL_TEXTURE_3D'. Level: Specifies the mIP map Level to load. We usually set this parameter to 0. Internalformat: How many color components to store in each texture unit. Width, height, depth: indicates the width, height, and depth of the loaded texture. = = attention! These values must be raised to an integer power of 2. (This is due to a requirement left over from older versions of OpenGL. Now, of course, it's possible to support an integer power other than 2. But developers are still used to setting these parameters to the power of 2.) Border parameter: Allows specifying a border width for the texture map. The format, type, and data parameters are the same as those used in the glDrawPixels functionCopy the code
Compressed texture format extracted by 9.4 glGetTexLevelParameter function
9.5 GL_EXT_texture_compression_s3tc compression format
Texture coordinates
Texture coordinate is the mapping relationship between texture and graph. Each vertex in the graph is associated with a texture coordinate, indicating that the vertex needs to read the data of texture image from this position.
- Texture coordinates range from 0 to 1,
- Vertex coordinates are generally described by (x, y, z), while texture coordinates are described by (s, t, r)
- The texture coordinates default lower left corner is (0,0), that is:
Upper left corner (1,0) upper right corner (1,1) lower left corner (0,0) lower left corner (1,0)
- In addition, the mapping relationship of texture coordinates is not fixed, and different mappings can be carried out according to the inversion of different angles of the picture. Note: do not cross the mapping of the image. Take a look at the following mappings using a very intuitive analysis picture found online: