In the last article, we learned how to color graphics, so now let’s do a more interesting thing: attach a picture (texture) to the graphics.

  • Loading textures
  • To activate the texture
  • Render texture

Loading textures

GLKit provides us with a very square method to load a Texture. If we don’t use the system method, I can do it myself. Basically, it reads the RGB data of the image, creates the Texture, and passes the data to the Texture.

- (void)setupTexture {
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flower" ofType:@"jpg"];
    NSError *theError;
    _flowerTexture = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:&theError];
}
Copy the code

We also need a texture to tell OpenGL how to display the coordinates of the texture, the texture coordinates is the lower left corner (0, 0) is the top right corner (1, 1), but there are some pictures on the system and is not stored in the coordinates of this, so when the display and direct preview picture effect is not the same, change the value of the corresponding coordinates.

- (void)setupVBO {
    GLfloat rectangleVertices[] = {
        //position texcoord
        0.4.0.4.0.0.0.0.0.0.0.4.0.8.0.0.0.0.1.0.0.4.0.8.0.0.1.0.1.0.0.4.0.4.0.0.1.0.0.0}; glGenBuffers(1, &_rectangleVBO);
    glBindBuffer(GL_ARRAY_BUFFER, _rectangleVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(rectangleVertices), rectangleVertices, GL_STATIC_DRAW);
}
Copy the code

To activate the texture

Before drawing the image, we activate the texture and bind the texture, and the fragment shader reads the currently active texture.

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    GLKView *glView = (GLKView *)self.view;
    [EAGLContext setCurrentContext:glView.context];
    glClearColor(0.0.0.1);
    glClear(GL_COLOR_BUFFER_BIT);
    
    [_rectangleShader prepareToDraw];
    glBindBuffer(GL_ARRAY_BUFFER, _rectangleVBO);
    
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0.3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1.2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void(*)3 * sizeof(float)));
    
    glActiveTexture(_flowerTexture.target);
    glBindTexture(_flowerTexture.target, _flowerTexture.name);
    
    glDrawArrays(GL_TRIANGLE_FAN, 0.4);
}
Copy the code

Render texture

Receives the coordinates of the texture and passes them to the fragment shader.

attribute vec3 a_Position;
attribute vec2 a_TexCoord;

varying lowp vec2 TexCoord;

void main(void) {
    gl_Position = vec4(a_Position, 1.0);
    TexCoord = a_TexCoord;
}
Copy the code

The fragment shader calculates the actual color value from the texture’s data and coordinates.

varying lowp vec2 TexCoord;

uniform sampler2D texture0;

void main(void) {
    gl_FragColor = texture2D(texture0, TexCoord);
}
Copy the code

Run the project and you’ll see a rectangle with two flowers stuck on it.

Making the address