Reputation: 1261
So I just started working on something in Open GL ES 2.0. I get the general impression that the switch from the 1.1 template to the 2.0 template in Xcode has caused some confusion for everyone, so as a result, there isn't much helpful on 2.0 (if there is anything really good and informative out there like 71squared's videos on the 1.1 template except for 2.0, your welcome to post a link to it).
My problem is displaying an image on the screen.
Right now, I've got this in my drawFrame method.
[(EAGLView *)self.view setFramebuffer];
// Replace the implementation of this method to do your own custom drawing.
static float transY = 0.0f;
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
[playerCube drawAtPoint:CGPointMake(160.0f, 240.0f)];
if ([context API] == kEAGLRenderingAPIOpenGLES2)
{
// Use shader program.
glUseProgram(program);
// Update uniform value.
glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY);
transY += 0.075f;
// Validate program before drawing. This is a good check, but only really necessary in a debug build.
// DEBUG macro must be defined in your debug configurations if that's not already the case.
if (![self validateProgram:program])
{
NSLog(@"Failed to validate program: %d", program);
return;
}
}
else
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[(EAGLView *)self.view presentFramebuffer];
Essentially the template without the square bouncing around. This is in my ViewController.m by the way. That works fine on it's own. I've not had much luck with the code for displaying the image however. I'm using the Texture2D file from Apple's crash landing example, but I haven't had much luck with that no matter where the image related code is put.
I've used playerCube = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"Cubix.png"]];
to allocate it, which is probably right even if I've not been putting it in the right location, and [playerCube drawAtPoint:CGPointMake(160.0f, 240.0f)];
.
Wait, that wouldn't show anything at the start cuz I've not set the height and width of the image right? I guess I sort of answered that part of my question. Would it work if I used something like image.frame = CGRectMake ();
or would that not work with Texture 2D? Also where should I be putting this code for it to work as it would?
Hope I made some sense in this. I've never posted a question on StackOverflow before.
Upvotes: 3
Views: 3040
Reputation: 170317
I show how to display an image as a texture in OpenGL ES 2.0 on the iPhone in this example, where the image is a frame of video from the camera, and this example, where I pull in a PVR-compressed texture as an image. The former example is described in the writeup here.
I describe how the vertex and fragment shaders work, along with all the supporting code for them, in the video for the OpenGL ES 2.0 class which is part of my freely available iOS development course on iTunes U. Additionally, I highly recommend you read Jeff LaMarche's series of posted chapters from his unpublished OpenGL ES 2.0 book.
In short, once you have the texture loaded in, you'll need to attach it as a uniform to your shader program using code like the following:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, myTexture);
glUniform1i(myTextureUniform, 0);
Within your fragment shader, you'll need to define the texture uniform:
uniform sampler2D myTexture;
and then sample the color from the texture at the appropriate point:
gl_FragColor = texture2D(myTexture, textureCoordinate);
Again, I go into this in more detail within my class, and you can use these examples as starting points to work from.
Upvotes: 2
Reputation: 100652
Texture2D, as presented in Crash Landing, isn't ging to work with ES 2.x. It should correctly upload your texture, but the two drawing methods, drawAtPoint:
and drawInRect:
won't work. They rely on the GL calls glVertexPointer and glTexCoordPointer; neither of those survives into ES 2.x. The logic behind that is that ES 1.x has a fixed pipeline, so it has a defined slot for vertex positions (which you supply with glVertexPointer
), a defined slot for texture coordinates (via glTexCoordPointer
) and a series of predefined ways in which that data can end up being processed. ES 2.x is fully programmable so it has no need to supply one way for providing vertices, another for providing texture coordinates, a third for colours, etc. It has just one way to supply an attribute for a vertex and it is up to you to specify how that relates to your vertex program, then up to your vertex program to figure out what needs to be processed and passed on to your fragment shader.
Really you shouldn't be conflating providing textures and providing geometry anyway. Crash Landing was withdrawn because it suggests poor programming patterns — my personal suspicion is that this was one of them.
In addition to not having fixed attributes of a vertex, ES 2.x doesn't supply any fragment shaders. If you want to texture map, you have to write suitable vertex and fragment shaders. The ones in the new GL template do Gouraud shading only if I recall.
An additional issue hinted at in the code is that ES 2.x doesn't have a matrix stack. You need to do something yourself about communicating to your vertex shader how it should map from the original vertices to screen locations. I suspect that if you just want to draw a texture as though 2d, that isn't so much of a problem.
Probably the correct route forward is:
If you're already happy with ES 1.x, probably a good place to start is the ES 2.x reference sheet and maybe the lighthouse3d GLSL tutorial — though that's for desktop OpenGL 2.0. On desktop GL 2.0 there's a lot of support built into GLSL for emulating the old fixed pipeline. None of that is in ES 2.x. But it should at least explain things about attributes, uniforms, samplers, etc. I'm afraid I've yet to come across an ES 2.x focussed tutorial.
Upvotes: 2