How it works...

The first code segment defines a simple function that loads the texture from a file, copies the texture data to OpenGL memory, and sets up the mag and min filters. It returns the texture ID. The first step, loading the texture image file, is accomplished by calling another method (Texture::loadPixels), which uses an image loader that is provided along with the example code. The loader comes from a header file stb_image.h, available on GitHub (https://github.com/nothings/stb). It reads the image and stores the pixel data into an array of unsigned bytes in RGBA order. The width and height of the image are returned via the last two parameters. We keep a pointer to the image data, simply named data.

The next two lines involve creating a new texture object by calling glGenTextures. The handle for the new texture object is stored in the tex variable.

To load and configure the texture object, we do the following.

  1. We call glBindTexture to bind the new texture object to the GL_TEXTURE_2D target.
  2. Once the texture is bound to that target, we allocate immutable storage for the texture with glTexStorage2D.
  3. After that, we copy the data for that texture into the texture object using glTexSubImage2D. The last argument to this function is a pointer to the raw data for the image.
  4. The next steps involve setting the magnification and minification filters for the texture object using glTexParameteri.  For this example, we'll use GL_LINEAR for the former and GL_NEAREST for the latter.
The texture filter setting determines whether any interpolation will be done prior to returning the color from the texture. This setting can have a strong effect on the quality of the results. In this example, GL_LINEAR indicates that it will return a weighted average of the four texels that are nearest to the texture coordinates. For details on the other filtering options, see the OpenGL documentation for glTexParameterihttp://www.opengl.org/wiki/GLAPI/glTexParameter.

Next, we delete the texture data pointed to by data. There's no need to hang on to this because it was copied into texture memory via glTexSubImage2D. To do so, we call the Texture::deletePixels function.  (Internally, that calls the function provided by the stb_image library stbi_image_free.) Then, we return the ID of the new texture object.

In the next code segment, we call our Texture::loadTexture function to load the texture, then we bind the texture to texture unit 0. To do so, first we call glActiveTexture to set the current active texture unit to GL_TEXTURE0 (the first texture unit, also called a texture channel). The subsequent texture state calls will be effective on texture unit zero. Then, we bind the new texture to that unit using glBindTextureFinally, we set the uniform variable Tex1 in the GLSL program to zero. This is our sampler variable. Note that it is declared within the fragment shader with type sampler2D. Setting its value to zero indicates to the OpenGL system that the variable should refer to texture unit zero (the same one selected previously with glActiveTexture).

The vertex shader is very similar to the one used in the previous examples except for the addition of the texture coordinate input variable VertexTexCoord, which is bound to attribute location 2. Its value is simply passed along to the fragment shader by assigning it to the shader output variable TexCoord.

The fragment shader is also very similar to those used in the recipes of previous chapters.  The primary changes are the Tex1 uniform variable and the blinnPhong function.  Tex1 is a sampler2D variable that was assigned by the OpenGL program to refer to texture unit zero. In the blinnPhong function, we use that variable along with the texture coordinate (TexCoord) to access the texture. We do so by calling the built-in function texture. This is a general purpose function, which is used to access a variety of different textures. The first parameter is a sampler variable indicating which texture unit is to be accessed, and the second parameter is the texture coordinate used to access the texture. The return value is a vec4 containing the color obtained by the texture access. We select only the first three components (.rgb) and store them in texColor. Then, we use texColor as the ambient and diffuse reflectivity terms in the Blinn-Phong model.

When using a texture for both ambient and diffuse reflectivity, it is important to set the ambient light intensity to a small value, in order to avoid wash-out.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.70.101