Handle multiple meshes in Open GL ES 2.0 (iOS GLKit)? - ios5

I've managed to create a single mesh in Open GL ES 2.0 using iOS's GLKit. What I can't figure out is how to create a second mesh that looks identical to the first except with a different position.
I think what would be most helpful would be if someone could simply provide some sample code that draws multiple meshes, as I think I'm going about this entirely wrong. Nonetheless, here's a list of what I've done to try make this work.
I created two C-arrays of vertex information. The first is my template (hardcoded coordinates centered at 0,0,0) and the second is what I'd like displayed (initially empty).
I created two C-arrays of indice information. Same deal as with the vertex information.
I have two global variable ints, vertexCount and indiceCount, both initially 0.
I have a c function, createAt(float x, float y, float z). This function copies my vertex template into my vertex display array and then applies the passed in offsets to each vertex. It also copies indices in and applies an offset so that they point at the new display vertexes.
This doesn't work though. Only one object gets drawn on screen.
Looking through other people's questions and answers, it sounds like maybe I should have multiple vertex buffers? I don't know; I'm horribly confused.

Rendering multiple meshes with the same geometry but different positions or orientations is quite easy with GLKit, thanks to the GLKBaseEffect class. Take a look at the "OpenGL Game" template provided by Xcode, which renders a cube with GLKit and another cube with OpenGL ES 2.0.
Here's a modification of the OpenGL Game sample which adds a new cube above the two spinning ones:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render another version of the object with GLKit
// First put it in a different place (you would normally
// do this in the update loop):
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 1.5, -0.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Now render it:
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
The code in-between the "Render another version" and "Render the object again" comments is new. The first thing it needs to do is come up with a new modelview matrix for the additional cube; this is based on the code in update: (not shown). Normally I'd put the code up there but I wanted to keep the sample short.
Next it renders the cube, which is pretty simple with GLKit. Yay GLKit!
I hope this helps. It sounds like you're barking up the wrong tree with additional vertex and index arrays; this is necessary if you want to render different geometries, but you said the same model in different places. That's something GLKit is ideal for.

Since there is only 1 base effect, I take it you would do the matrix calculations in the update, and just assign it to the base effect modelviewmatrix before drawing again?

John Riselvato comments above that he really wishes he could see the update: method contents. I really wished to see this myself as I was having difficulty wrapping my head around putting multiple objects on screen, while using the same GLKBaseEffect object. Here's how I finally did it:
// update method where I create 3 different modelViewMatrices to use with my GLKBaseEffect object later in the draw method
- (void)updateWithDeltaTime:(NSTimeInterval)deltaTime
{
_rotation1 += 120.0 * deltaTime;
_rotation2 += 150.0 * deltaTime;
_rotation3 += 180.0 * deltaTime;
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, -1.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation1));
_modelViewMatrix1 = modelViewMatrix;
modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation2));
_modelViewMatrix2 = modelViewMatrix;
modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 1.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation3));
_modelViewMatrix3 = modelViewMatrix;
}
// draw method where I re-use my GLKBaseEffect object, applying the 3 modelViewMatrices I set in the update: method above
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_effect.transform.modelviewMatrix = _modelViewMatrix1;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
_effect.transform.modelviewMatrix = _modelViewMatrix2;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
_effect.transform.modelviewMatrix = _modelViewMatrix3;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
}
// how i initially setup my GLKBaseEffect object and my opengl buffers
- (void)_setupGL
{
[EAGLContext setCurrentContext:_context];
//glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
_effect = [[GLKBaseEffect alloc] init];
[self _createEffect];
[_effect prepareToDraw];
glGenBuffers(1, &_vertexBuffer1);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_vertexBuffer2);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_vertexBuffer3);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Texel));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Normal));
}
Hope this helps someone.

Related

GL_LINES drawing back to first point at the end of verticies

Using GLKit (OpenGLES 2.0) on iOS.
I'm modifying some code that renders cubes in a 3d environment so that it will render waveforms in 2 dimensions in a 3d scene. I have it working great except for one problem which is:
Suppose I render n x/y coordinates using GL_LINES. It will draw a line from 0 -> 1, then 1 -> 2, and so on. But then point N will always have a line drawn back to point 0. I would expect GL_LINE_LOOP to this, but not GL_LINES.
I have a work around in mind if I cannot solve this and that is to use 2 GL_TRIANGLE_STRIP to draw each line segment. I'd really rather just understand why this isn't working though.
Here are the important parts of the code:
typedef struct {
float Position[3];
} Vertex;
const NSUInteger kVerticiesSize = 320;
Vertex Vertices[kVersiciesSize] = {};
const GLubyte Indices[] = {
0,1,
1,2,
2,3,
3,4,
4,5,
5,6,
6,7,
7,8,
8,9,
9,10,
// keeps going to kVerticiesSize
The GL setup
- (void)setupGL {
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition,
3,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
offsetof(Vertex, Position));
float aspect = fabsf(self.bounds.size.width / self.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.0f, 50.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
}
And the Update and Render methods:
// Always called once before "render"
-(void)update {
static bool hasRun = NO;
for(int x = 0; x < kVersiciesSize; x++){
// normalize x variable to x coord -1 .. 1 and set Y to math function
Vertex v = Vertices[x];
v.Position[0] = [self normalizedX:x];
v.Position[1] = cos(x);
v.Position[2] = 0;
Vertices[x] = v;
if(!hasRun){
NSLog(#"x=%f y=%f z=%f", v.Position[0], v.Position[1], v.Position[2]);
}
}
hasRun = YES;
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
[self updateTransforms];
}
-(void)render {
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_LINE_STRIP,
sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE,
0);
}
You have:
glVertexAttribPointer(GLKVertexAttribPosition,
3,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
offsetof(Vertex, Position));
But the signature of glVertexAttribPointer is:
glVertexAttribPointer (GLuint indx, // GLKVertexAttribPosition
GLint size, // 3 floats per vertex
GLenum type, // Vertices are GL_FLOAT-s
GLboolean normalized, // GL_FALSE
GLsizei stride, // *** Should be 0, no?
const GLvoid* ptr); // *** Should be &Vertices[0], no?
I'm pretty sure that, if you make the commented suggestions above, it would work. Then you just render the whole thing with:
glDrawArrays(GL_LINES, 0, kVerticiesSize);
or
glDrawArrays(GL_LINES, startIndex, lineCount);
...right?
DISCLAIMER: I'm not fluent with the whole bound-buffers pipeline, but it strikes me as unnecessary complication, in this case.
ALSO NOTE: Your text mentions GL_LINES, but your sample code uses GL_LINE_STRIP. A line-strip works like a triangle-strip, where the first 2 vertices define the first line segment but, after that, each single vertex defines the next line-segment, which picks-up where the previous one left off. Hence, your vertex indices are correct for GL_LINES but, for GL_LINE_STRIP, you'd just want { 0, 1, 2, 3, 4, 5... }

How we are assigning values to GLFloat to draw a line in iPhone app?

Finally Mr.Chris helped me to draw a line using GLKview and drawInRect: method. It is working fine. But, i need some clarifications,
How we are assigning values to GLFloat?
const GLfloat line[] =
{
-1.0f, -1.5f, //point A : What is -1.0f and -1.5f ? These are x and y or something.
1.5f, -1.0f, //point B : What is 1.5f and -1.0f ? These are x and y or something.
};
Because, i am confusing to set a values here. How it is taking x,y or length? If it is silly question please accept my apologies. Please clarify my doubts on this.
How to set background image for GLKViewController? I have an image to set background but, i don't know where i need to set that?
Sample viewDidLoad code
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"GameDesign03.png"]];
self.context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease];
if (!self.context) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self.effect prepareToDraw]; // Prepare the effect for rendering
const GLfloat line[]=
{
-1.0f, -1.5f,
1.5f, -1.0f
};
GLuint bufferObjectNameArray; //Create an handle for a buffer object array
glGenBuffers(1, &bufferObjectNameArray); //Have OpenGL generate a buffer name and store it in the buffer object array
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray); //Bind the buffer object array to the GL_ARRAY_BUFFER target buffer
//Send the line data over to the target buffer in GPU RAM
glBufferData(GL_ARRAY_BUFFER, sizeof(line), line, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition); //Enable vertex data to be fed down the graphics pipeline to be drawn
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 2, NULL); //Specify how the GPU looks up the data
glDrawArrays(GL_LINES, 0, 2); // render
}
Please help on this. Thanks in advance.
So to answer your first question, on this line:
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 2, NULL); //Specify how the GPU looks up the data
you're setting the size argument to 2, which tells OpenGL that there are 2 components per vertex attribute. They are the endpoints of the lines.
And to answer your second question, you need to draw the background image before drawing the lines, as mentioned in my comment above.

Draw a straight line using OpenGL ES in iPhone?

Finally i tried to draw a line using OpenGL ES framework in XCode 4.2 for iPhone simple game app.I studied something about GLKView and GLKViewController to draw a line in iPhone. Here is my sample code that was i tried in my project,
#synthesize context = _context;
#synthesize effect = _effect;
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[EAGLContext setCurrentContext:self.context];
//[self setupGL];
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
NSLog(#"DrawInRect Method");
[EAGLContext setCurrentContext:self.context];
// This method is calling multiple times....
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const GLfloat line[] =
{
-0.5f, -0.5f, //point A
0.5f, -0.5f, //point B
};
glVertexPointer(2, GL_FLOAT, 0, line);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_LINES, 0, 2);
}
When i run the project only the gray color only appearing in the screen, the line not showing. And also the - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect delegate is calling infinite time. Please guide me where i am doing wrong. Why the line not appearing or drawing? Can you please help? Am trying this 2 days. Thanks in advance.
I'm rather a student of OpenGL ES 2.0 right now myself. I recommend first starting a new project in Xcode with the "OpenGL Game" template Apple provides.
Among other things, the Apple template code will include creation of a GLKBaseEffect, which provides some Shader functionality that seems to be required in order to be able to draw with OpenGL ES 2.0. (Without the GLKBaseEffect, you would need to use GLSL. The template provides an example of both with and without explicit GLSL Shader code.)
The template creates a "setupGL" function, which I modified to look like this:
- (void)setupGL
{
[EAGLContext setCurrentContext:self.context];
self.effect = [[[GLKBaseEffect alloc] init] autorelease];
// Let's color the line
self.effect.useConstantColor = GL_TRUE;
// Make the line a cyan color
self.effect.constantColor = GLKVector4Make(
0.0f, // Red
1.0f, // Green
1.0f, // Blue
1.0f);// Alpha
}
I was able to get the line to draw by including a few more steps. It all involves sending data over to the GPU to be processed. Here's my glkView:drawInRect function:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Prepare the effect for rendering
[self.effect prepareToDraw];
const GLfloat line[] =
{
-1.0f, -1.5f, //point A
1.5f, -1.0f, //point B
};
// Create an handle for a buffer object array
GLuint bufferObjectNameArray;
// Have OpenGL generate a buffer name and store it in the buffer object array
glGenBuffers(1, &bufferObjectNameArray);
// Bind the buffer object array to the GL_ARRAY_BUFFER target buffer
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray);
// Send the line data over to the target buffer in GPU RAM
glBufferData(
GL_ARRAY_BUFFER, // the target buffer
sizeof(line), // the number of bytes to put into the buffer
line, // a pointer to the data being copied
GL_STATIC_DRAW); // the usage pattern of the data
// Enable vertex data to be fed down the graphics pipeline to be drawn
glEnableVertexAttribArray(GLKVertexAttribPosition);
// Specify how the GPU looks up the data
glVertexAttribPointer(
GLKVertexAttribPosition, // the currently bound buffer holds the data
2, // number of coordinates per vertex
GL_FLOAT, // the data type of each component
GL_FALSE, // can the data be scaled
2*4, // how many bytes per vertex (2 floats per vertex)
NULL); // offset to the first coordinate, in this case 0
glDrawArrays(GL_LINES, 0, 2); // render
}
Btw, I've been going through Learning OpenGL ES for iOS by Erik Buck, which you can buy in "Rough Cut" form through O'Reilly (an early form of the book since it is not going to be fully published until the end of the year). The book has a fair number of typos at this stage and no pictures, but I've still found it quite useful. The source code for the book seems to be very far along, which you can grab at his blog. The author also wrote the excellent book Cocoa Design Patterns.

iPhone OpenGL : Moving the view back from an object

A bit of a weird one here. I have a 3d cube that rotates on the screen but I had to change the view from glOrthof to glFrustumf. Now the cube is place on me and not a in front of me.
So I thought I use a glTranslate (or even scale) to move it back so I can properly so it but the object continues redraws from its old position and adds a bit to it so by moving, the rotation goes Pete Tong. I never used used glGetFloatv and glMultMatrixf before but I guessing they take the old rotation and add a bit to it to keep the object moving. Just wish I could step back from it
Cube code
GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glLoadIdentity();
glRotatef(self.angle, self.dy,self.dx,0);
/* reapply other rotations so far */
glMultMatrixf(matrix);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0, 1.0, 1.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[0]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[6]);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[12]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[18]);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[24]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[30]);
I fixed it by a 1 time only move of -5 then reset the matrix
/* save current rotation state */
GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
/* re-center cube, apply new rotation */
glLoadIdentity();
if (firstRunOnly == NO) {
firstRunOnly = YES;
glTranslatef(0, 0, -5);
} else {
glTranslatef(0, 0, 0);
}
/* reapply other rotations so far */
glMultMatrixf(matrix);
glRotatef(self.angle, self.dy,self.dx,0);

How to render image with OpenGL ES?

I am new in OpenGL ES. I earlier developed games in cocoa with objective-c. Now I want to develope 3D game for iPhone by using OpenGL ES. I am at beginner stage. I am able to create triangle, square, cube, pyramid by usng OpenGL ES. But if we have any .png image with us and we have to render it in our game then what we have to do? For that we require any other tool like unity or what? I cant able to understand it exactly. or we have to do it like the GLSprite example which is given in apple.developer.com site. In that example they draw a tea pot by using one teapot.h file. teapot.h file contain some points and by using that points they plot triangle which formed a tea pot. So is this a way to draw any image. I think I am thinking in wrong direction so please guide me for this.
Thank you in advance
To draw an image you need to first define the geometry that the image can be applied to:
float w = width / 2;
float h = height / 2;
float x = 10.0f;
float y = 10.0f;
float z = 0.0f;
float scaleX = 1.0f;
float scaleY = 1.0f;
float scaleZ = 1.0f;
const GLfloat squareVertices[] = {
-w, -h,
w, -h,
-w, h,
w, h,
};
const GLfloat textureCoords[] = {
0, 0,
1, 0,
0, 1,
1, 1,
};
Then, you can apply your texture and render this geometry:
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// apply texture -- how to create and bind a physical image is a whole different question
glBindTexture(GL_TEXTURE_2D, yourTextureID);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);
glPushMatrix();
glTranslatef(x, y, z);
glScalef(scaleX, scaleY, scaleZ);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
Note that these code-snippets assume that you have setup a working view/projection.
The Crash Landing sample that used to be in the SDK is also a good place to start (apparently the audio code was broken and that's why it was removed, but the OpenGL code is still good)
You can find a link to the sample here.