Reputation: 5681
I am attempting to learn some basic OpenGL ES for iPhone development, and I have a task I can't quite get to work.
I cannot seem to change the default OpenGL ES template to display a texture on the bouncing square instead of the default rainbow-like effect. I'm trying to use a texture for this square, but so far the square just shows black. What could I be doing wrong in this simple case, and how could I modify the base template code to display my texture?
Upvotes: 0
Views: 1457
Reputation: 170317
As a side note, the default OpenGL ES template appears to have changed for the iOS 5.0 SDK, and now uses GLKit to draw rotating cubes, so I couldn't create a simple test project based on that original rainbow square that they had been using.
Instead, you might want to look at the sample application I prepared for my class on the subject. It's a fairly stripped-down application that displays textures on the faces of a rotating cube. I describe in detail how this works in the video for that class on iTunes U.
This sample application uses Apple's PVRTexture class (from one of their other sample applications) to load in a PVRTC-compressed texture file (which is more memory-efficient than normal images). The core code for setting up a texture is this:
glGenTextures(1, &_name);
glBindTexture(GL_TEXTURE_2D, _name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCompressedTexImage2D(GL_TEXTURE_2D, i, _internalFormat, width, height, 0, [data length], [data bytes]);
where _name
is the identifier that you'll later use to bind that texture. You'd use glTexImage2D()
instead of the last function if you were working with a normal uncompressed texture.
You can then enable the use of textures:
glEnable(GL_TEXTURE_2D);
and bind the texture to be displayed, using the identifier you obtained when the texture was created:
glBindTexture(GL_TEXTURE_2D, pvrTexture.name);
By default, this texture is bound to texture unit 0, but you can switch to another unit using glActiveTexture(GL_TEXTURE1)
or the like.
You then need to pass in this texture to your shader program as a uniform, with the second parameter being the texture unit that the texture is bound to:
glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
You also need corresponding texture positions for your vertices so that your texture gets mapped onto your surface in the right way:
const GLfloat cubeTexCoords[] = {
1.0, 0.0,
0.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
};
and these coordinates will be fed into your shader program as an attribute:
glVertexAttribPointer(ATTRIB_TEXTUREPOSITION, 2, GL_FLOAT, 0, 0, cubeTexCoords);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITION);
You shader program will need to be able to take in the texture uniform and its coordinates, so you'll have something that looks like this in your vertex shader:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
uniform mat4 modelViewProjMatrix;
void main()
{
gl_Position = modelViewProjMatrix * position;
textureCoordinate = inputTextureCoordinate.xy;
}
and this for a matching fragment shader:
varying highp vec2 textureCoordinate;
uniform sampler2D texture;
void main()
{
gl_FragColor = texture2D(texture, textureCoordinate);
}
You can see how the shader program takes in the texture coordinates and passes them along to the fragment shader, where the texture is sampled and used to produce the final color at that fragment.
You'll need to match attributes and uniforms when you compile this shader, but the OpenGL ES 2.0 template should show how to do that.
While I haven't provided the exact code to enable texture display on the OpenGL ES 2.0 template, you should be able to use the above as a basis to do this.
Upvotes: 2