OpenGL ES /OpenGL ES /OpenGL ES /OpenGL ES /OpenGL ES Image rendering implementation and rendering problems OpenGL/OpenGL ES introduction: basic transformation – beginning vector/matrix OpenGL/OpenGL ES introduction: texture exploration – common API parsing OpenGL/OpenGL ES introduction: OpenGL/OpenGL ES: Vertex shaders and slice shaders (OpenGL transition OpenGL ES) Introduction to OpenGL/OpenGL ES: GLKit usage and case studies
Texture applications
In our last article OpenGL/OpenGL ES Texture Primer – Common API parsing, we covered the common API related to texture. Loading textures is just the first step in applying textures to geometry. At a minimum we had to provide texture coordinates and set texture coordinate surround mode and texture filter. Finally, we can choose to Mip map the texture to improve texture mapping performance and/or visual quality.
Texture coordinates
In general, texture mapping is performed directly on the geometry by specifying a texture coordinate for each vertex. Texture coordinates are either specified as a property of the shader or calculated by an algorithm.
A texture unit in a texture map is addressed as a more abstract (often floating-point) texture coordinate rather than as a memory location (which is the case in pixel maps). Typically, texture coordinates are specified as floating point values between 0.0 and 1.0.
Texture coordinates, named S, T, R, and Q (similar to vertex coordinates X, y, z, and W), support texture coordinates from one to three dimensions, and optionally have a way to scale the coordinates.
Q coordinate for the geometric coordinate W. This is a scaling factor that applies to other texture coordinates. That is, the texture coordinates used are actually S/Q, T /q, and R /q. By default, q is set to 1.0.
Focus on 2D texture coordinates, ranging from 0 to 1 on the X and y axes. Using texture coordinates to obtain texture color is called Sampling. Texture coordinates start at (0,0), the lower left corner of the texture image, and end at (1,1). The upper right corner of the texture image
See the map below for texture coordinates:
Pyramid case
The following will explain the use of texture through the pyramid case, the effect picture is as follows:
SetupRC function
Set the background color, initialize, etc
void SetupRC() {// Set the background color glClearColor(0.7, 0.7, 0.7, 1.0); / / initialize shaderManager shaderManager. InitializeStockShaders (); // Enable the depth test glEnabel(GL_DEPTH_TEST); GlGenTextures (1, &textureid); glGenTextures(1, &textureid); GlBindTexture (GL_TEXTURE_2D, textureID); glBindTexture(GL_TEXTURE_2D, textureID) // Load the TGA file as a 2D texture /* Parameter 1: texture file name Parameter 2 and parameter 3: required zoom and zoom filter parameter 4: Texture coordinates surround mode */ LoadTGATexture("stone.tga", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, GL_CLAMP_TO_EDGE); // Build pyramidBatch MakePyramid(pyramidBatch); Camerafame.MoveForward(-10); camerafame. }Copy the code
Load the texture file LoadTGATexture
// Load the TGA file as a 2D texture. bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) { GLbyte *pBits; int nWidth, nHeight, nComponents; GLenum eFormat; 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: */ pBits = gltReadTGABits(szFileName, &nWidth, &nheight, &nComponents, &eformat);if(pBits == NULL)
return false; Parameteri: wrapMode, wrapMode */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); /* Parameter 1: texture dimension parameter 2: linear filter parameter 3: wrapMode, filter mode */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); //3. Load texture /* Parameter 1: texture dimension parameter 2: MIP texture layer parameter 3: texture unit stored color component (obtained from reading pixel map) parameter 4: load texture width parameter 5: Load texture high parameter 6: load texture depth parameter 7: The data type of pixel data (GL_UNSIGNED_BYTE, where each color component is an 8-bit unsigned integer) parameter 8: Pointer to texture image data */ glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits); PBits free(pBits); GL_TEXTURE_2D GL_TEXTURE_3D glGenerateMipmap(GL_TEXTURE_2D); GL_TEXTURE_2D GL_TEXTURE_3D glGenerateMipmap(GL_TEXTURE_2D)return true;
}
Copy the code
Draw pyramid (get points, texture coordinates)
-------- Previously imported --------- 1. Set normal void Normal3f(GL)float x, GLfloat y, GLfloatz); Surface normals are directional vectors that represent the direction that the surface or Vertex faces (the opposite direction). Void MultiTexCoord2f(GLuint texture, GLclampf s, GLclampf t); Parameter 1: texture, set to 0 for rendering with storage shader parameter 2: s: x in vertex coordinates parameter 3: t: Corresponding vertex coordinates of the y (s, t, r, q) corresponding to the vertex coordinates x, y, z, w) pyramidBatch. MultiTexCoord2f (0, s, t); Void Vertex3f(GL)float x, GLfloat y, GLfloatz); void Vertex3fv(M3DVector3f vVertex); Add vertex data (x,y,z) to the triangle batch class; PyramidBatch. Vertex3f (1.0 f, 1.0 f, 1.0 f); Void m3dFindNormal(result, point1, point2, point3); Parameter 1: Result parameters 2-4:3 vertex dataCopy the code
Pyramid coordinates analysis:
Draws a pyramid in a coordinate system with the origin at the center of the pyramid
Vertex coordinates VBackLeft tower coordinates (0.0, 1.0, 0.0) (1.0, 1.0, 1.0) vBackRight (1.0-1.0, 1.0) vFrontRight (1.0, 1.0, 1.0) vFrontLeft (1.0, 1.0, 1.0)
Look at the image below which depicts the texture coordinates of the two triangles at the base of the pyramid
Texture coordinates Triangle A Texture coordinates vBackLeft(0.0, 0.0, 0.0) vBackRight(0.0, 1.0, 0.0) vFrontRight(0.0, 1.0, 1.0)
Triangle B texture coordinates vFrontLeft(0.0, 0.0, 1.0) vBackLeft(0.0, 0.0, 0.0) vFrontRight(0.0, 1.0, 1.0)
Void MakePyramid(GLBatch& pyramidBatch) {* Parameter 1: type parameter 2: number of vertices Parameter 3: One texture will be applied to this batch note: If you leave this argument unchecked, the default is 0, using 1 texture */ pyramidBatch.Begin(GL_TRIANGLES, 18, 1); M3DVector3f vApex = {0.0f, 1.0f, 0.0f}; M3DVector3f vFrontLeft = {-1.0f, -1.0f, 1.0f}; M3DVector3f vFrontRight = {1.0f, -1.0f, 1.0f}; M3DVector3f vFrontRight = {1.0f, -1.0f, 1.0f}; M3DVector3f vBackLeft = {-1.0f, -1.0f, -1.0f}; M3DVector3f vBackRight = {1.0f, -1.0f, -1.0f}; M3DVector3f n; // Bottom of pyramid // bottom quadrilateral = triangle A + triangle B // Triangle A = (vBackLeft, vBackRight, vFrontRight) //1 Find triangle A normal m3dFindNormal(n, vBackLeft, vBackRight, vFrontRight); //vBackLeft pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackLeft); //vBackRight pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackRight); //vFrontRight pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 1.0 f); pyramidBatch.Vertex3fv(vFrontRight); / / triangle B = (vFrontLeft vBackLeft, vFrontRight) / / 1. Find triangle B normal m3dFindNormal(n, vFrontLeft, vBackLeft, vFrontRight); //vFrontLeft pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 1.0 f); pyramidBatch.Vertex3fv(vFrontLeft); //vBackLeft pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackLeft); //vFrontRight pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 1.0 f); pyramidBatch.Vertex3fv(vFrontRight); // Triangle (Apex, vFrontLeft, vFrontRight) m3dFindNormal(N, vApex, vFrontLeft, vFrontRight); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.5 f, 1.0 f); pyramidBatch.Vertex3fv(vApex); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vFrontLeft); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 0.0 f); pyramidBatch.Vertex3fv(vFrontRight); // triangle :(vApex, vBackLeft, vFrontLeft) m3dFindNormal(n, vApex, vBackLeft, vFrontLeft); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.5 f, 1.0 f); pyramidBatch.Vertex3fv(vApex); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackLeft); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vFrontLeft); // pyramid right // triangle :(vApex, vFrontRight, vBackRight) m3dFindNormal(n, vApex, vFrontRight, vBackRight); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.5 f, 1.0 f); pyramidBatch.Vertex3fv(vApex); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 0.0 f); pyramidBatch.Vertex3fv(vFrontRight); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackRight); (vApex, vBackRight, vBackLeft) m3dFindNormal(n, vApex, vBackRight, vBackLeft); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.5 f, 1.0 f); pyramidBatch.Vertex3fv(vApex); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 0.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackRight); pyramidBatch.Normal3fv(n); PyramidBatch. MultiTexCoord2f (0, 1.0 f, 0.0 f); pyramidBatch.Vertex3fv(vBackLeft); // set pyramidBatch.end (); }Copy the code
RenderScene function
Void RenderScene(void) {//1floatVLightPos [] = {1.0f, 1.0f, 0.0f}; static GLfloatVWhite [] = {1.0f, 1.0f, 1.0f, 1.0f}; / / 2. Clear the cache area glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); / / 3. The current model of video compression stack modelViewMatrix. PushMatrix (); // Add camera matrix M3DMatrix44f mCamera; / / get from camraFrame a 4 * 4 matrix cameraFrame. GetCameraMatrix (mCamera); / / matrix multiplied by the matrix stack at the top of the matrix multiplication results stored to the top of the stack will camera matrix and the matrix multiplication model Pressure into the stack modelViewMatrix. MultMatrix (mCamera); // Create a mObjectFrame matrix M3DMatrix44f mObjectFrame; GetMatrix(mObjectFrame); GetMatrix(mObjectFrame); / / matrix multiplied by the matrix stack at the top of the matrix multiplication results stored to the top of the stack The world transformation matrix and the current model of matrix multiplication Pressure into the stack modelViewMatrix. MultMatrix (mObjectFrame); //4. Bind textures, because we only have one texture in our project. If you have multiple textures. GlBindTexture (GL_TEXTURE_2D, textureID); /*5. Point light shader parameter 1: GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF (shader tag) parameter 2: model view matrix parameter 3: projection matrix parameter 4: light position parameter in viewpoint coordinate system 5: Basic diffuse color parameter 6: Graphics colors (With textures you do not need to set colors. Is set to 0) * / shaderManager. UseStockShader (GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, transformPipeline GetModelViewMatrix (), transformPipeline.GetProjectionMatrix(), vLightPos, vWhite, 0); / / pyramidBatch Draw pyramidBatch. The Draw (); / / model view out of the stack, restore matrix (push pop a) and a modelViewMatrix. PopMatrix (); //6. Buffers(); }Copy the code
ShutdownRC function
Void ShutdownRC(void) {// Clean... Delete texture objects glDeleteTextures(1, &textureID); }Copy the code
SpecialKeys function
void SpecialKeys(int key, int x, int y)
{
ifRotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);ifRotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);ifRotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);ifRotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f); glutPostRedisplay(); }Copy the code
ChangeSize function
void ChangeSize(int w, int h) { //1. Set viewport glViewport(0, 0, w, h); / / 2. Create the projection matrix viewFrustum. SetPerspective (35.0 f,float(w) / float(h), 1.0 f, 500.0 f); / / viewFrustum. GetProjectionMatrix () to obtain viewFrustum projection matrix / / and loads it into the projection matrix on the stack projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); Set up transformPipeline to use two matrix stacks (transform matrix modelViewMatrix, projectionMatrix projectionMatrix) // initialize GLGeometryTransform instance transformPipeline. Initialize it by setting its internal Pointers to the model view matrix stack and projection matrix stack instances // of course this can also be done in the SetupRC function, but it does no harm to set them when the window size changes or when the window is created. And you can set up the matrix and pipeline all at once. transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); }Copy the code
This article mainly describes the code for texture. RenderScene, SpecialKeys, ChangeSize, etc., have been covered in detail in previous articles, so I’ll cover them briefly here.
The following is a flow chart for your reference only: