To render a simple shape with a 2D texture, use the following steps:
- We'll define a simple (static) function for loading and initializing textures:
GLuint Texture::loadTexture( const std::string & fName ) {
int width, height;
unsigned char * data = Texture::loadPixels(fName, width, height);
GLuint tex = 0;
if( data != nullptr ) {
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
Texture::deletePixels(data);
}
return tex;
}
- In the initialization of the OpenGL application, use the following code to load the texture, bind it to texture unit 0, and set the uniform variable Tex1 to that texture unit:
GLuint tid = Texture::loadTexture("brick1.png");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tid); // Set the Tex1 sampler uniform to refer to texture unit 0 int loc = glGetUniformLocation(programHandle, "Tex1"); glUniform1i(loc, 0);
- The vertex shader passes the texture coordinate to the fragment shader:
layout (location = 0) in vec3 VertexPosition; layout (location = 1) in vec3 VertexNormal; layout (location = 2) in vec2 VertexTexCoord; out vec3 Position; out vec3 Normal; out vec2 TexCoord; // Other uniforms...
void main() { TexCoord = VertexTexCoord; // Assign other output variables here... }
- The fragment shader looks up the texture value and applies it to the diffuse reflectivity in the Blinn-Phong model:
in vec3 Position; in vec3 Normal; in vec2 TexCoord;
// The texture sampler object uniform sampler2D Tex1; // Light/material uniforms...
void blinnPhong( vec3 pos, vec3 n ) {
vec3 texColor = texture(Tex1, TexCoord).rgb;
vec3 ambient = Light.La * texColor;
// ...
vec3 diffuse = texColor * sDotN;
// Compute spec... return ambient + Light.L * (diffuse + spec); } void main() { FragColor = vec4( blinnPhong(Position, normalize(Normal) ), 1 ); }