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