I was new to opengl es, So I use the sample code "HelloEffect" in android4.1 to do some tests. I use the function below to do render. if the "glCopyTexImage2D" function not been call at the end of renderTexture, then I can re-render the texture correctly, but if the glCopyTexImage2D function is used, then the second time I call renderTexture, GLToolbox.checkGlError("glViewport") will throw exceptions.
public void renderTexture(int texId, int savetexture) {
if(savetexture == 2)
texId = mCaptureTexture[0];
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
GLToolbox.checkGlError("glViewport");
// Disable blending
GLES20.glDisable(GLES20.GL_BLEND);
// Set the vertex attributes
GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false,
0, mTexVertices);
GLES20.glEnableVertexAttribArray(mTexCoordHandle);
GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false,
0, mPosVertices);
GLES20.glEnableVertexAttribArray(mPosCoordHandle);
GLToolbox.checkGlError("vertex attribute setup");
// Set the input texture
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLToolbox.checkGlError("glActiveTexture");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
GLToolbox.checkGlError("glBindTexture");
GLES20.glUniform1i(mTexSamplerHandle, 0);
GLES20.glUniform1i(mEffectTypeHandle, 1);
// Draw
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
if(savetexture == 1)
GLES20.glCopyTexImage2D(mCaptureTexture[0], 0, GLES20.GL_RGBA, 0, 0, mTexWidth, mTexHeight, 0);
return;
}
//main workflow
renderTexture(srctexture, 0);
renderTexture(srctexture, 0);
//+above steps is work normal.
renderTexture(srctexture, 1);
renderTexture(srctexture, 2);
//in above steps, when call renderTexture(srctexture, 2)
//gLToolbox.checkGlError ("glViewport")will throw exception
my purpose to do this is that I will keep a copy of framebuffer's color buffer, as I have done some post-processing work to the texId texture, so it will save time if I don't have to do the post-processing work again.
I wonder if I have omit some critical steps above, or opengl es 2.0 is not prefect for this work
best wishes!
Your usage and interpretation of checkGLError is likely to be incorrect: OpenGL error reporting is stateful, the error flag isn't reset until you actually check it.
Most likely, the line
GLES20.glCopyTexImage2D(...);
is the one setting the error flag. You just don't check (and reset) it until after the next call to glViewPort.
...
On to the actual problem: if you could post your exact error message, we could provide further assistance as to what is wrong at that line. It looks like your parameters are specified incorrectly, it should probably be something like
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, mCaptureTexture[0] );
GLES20.glCopyTexImage2D( GLES20.GL_TEXTURE_2D, ... );
Related
I want to use booth SDL and gles 1 on Android using a native activity.
SDL offers a function to create an OpenGL-context( SDL_GL_CreateContext ).
Clearing the screen and swapping the buffer works, but every draw-attempt fails.
To make sure, that i made nothing wrong, i made the drawing-attempt as small as possible.
Here is the small sample.
// creating OpengGL-context [...]
while (true) // basic mainloop
{
// set viewport and projectionmatrix
glViewport(0, 0, engine->getWidth(), engine->getHeight()); // width and height in pixels
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrthof(-1, 1, 1, -1, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//draw shape
GLfloat vertices[] = {1,0,0, 0,1,0, -1,0,0};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
}
// free memory [...]
The problem is now that nothing is drawn. But my OpenGL-context is valid.
Any help would be appreciated :)
Thanks
Edit:
I actually forgot to force OpenGL 1, using
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
My Android application show the unexpected behaviour for PowerVR SGX 544MP.
In case render setting to "RENDERMODE_WHEN_DIRTY" it seems that the
depth buffer don't work, however, if the mode set
"RENDERMODE_CONTINUOUSLY" the drawing come to right:
Wrong result:
Proper result:
The emulator draw right in both case.
The default buffer of device is 24 bit, setting the buffer to same
range as emulator (16bit) unchanged drawing. I tried the varying witn
values of Near and Far of projection matrix but it was unsuccessful.
Only one of the my matrices have modification of near plane.The
martix may make bad data in the depth buffer. I turn off the
writing in the depth buffer before drawing using this matrix. In that
case, I sets "GLES20.glDepthMask( false )" before to call
"glDrawElements".
Initialisation OPENGL ES and work with VBOs are new for me, so perhaps my misunderstanding of trouble is more deep than that seems to me.
I sends to uniform different matrix values and draw with same VBOs.
I do "Enabling" for attributes globally only one time and I don't use Disable for them later.
//MyGLSurfaceView
public MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2);
// super.setEGLConfigChooser(8,8,8,8,16,0); // same result
mRenderer = new MyGLRenderer(context);
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
//MyGLRenderer
#Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthRangef(0.f, 1.f);
GLES20.glClearDepthf(1.f);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glFrontFace(GLES20.GL_CCW);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
}
#Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
// Adjust the viewport based on geometry changes,
// such as screen rotation
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
perspectiveFieldOfViewRH(mProjectionMatrix, 0, 28.4f, ratio, 0.4f, 28.f);
}
#Override
public void onDrawFrame(GL10 unused) {
GLES20.glDepthMask( true );
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
int i,j;
// turn off the writing. Only read
GLES20.glDepthMask( false );
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ZERO);
GLES20.glUseProgram(prg_shaderCube);
// draw with modified projection matrix:
for (i = 0; i < 4; i++){
for (j = 0; j < 6; j++){
System.arraycopy(arrFacesMatrices[i][j], 0, mModelMatrix, 0, 16);
mModelMatrix[14] = translations[i];
Matrix.multiplyMM(mMirrorFlankWithClippingMVP, 0, mMirrorFlankViewProjectionWithClippingMatrix, 0, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(u_changematrixCube, 1, false, mMirrorFlankWithClippingMVP, 0);
GLES20.glUniformMatrix4fv(u_modelmatrixCube, 1, false, mModelMatrix, 0);
GLES20.glCullFace(GLES20.GL_BACK);
switch(pattern[i][j]){
case 0:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
GLES20.glVertexAttribPointer(attr_position_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 0);
GLES20.glVertexAttribPointer(attr_color_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 12);
GLES20.glVertexAttribPointer(attr_normal_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 24);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, capacityFlat1, GLES20.GL_UNSIGNED_SHORT, 0);
break;
case 1:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[1]);
....
break;
....
....
}
}
}
// others
GLES20.glDepthMask( true );
for (i = 3; i >= 0; i--){
for (j = 0; j < 6; j++){
System.arraycopy(arrFacesMatrices[i][j], 0, mModelMatrix, 0, 16);
mModelMatrix[14] = translations[i];
Matrix.multiplyMM(mMirrorFlankMVP, 0, mMirrorFlankViewProjectionMatrix, 0, mModelMatrix, 0);
Matrix.multiplyMM(mMirrorDownMVP, 0, mMirrorDownViewProjectionMatrix, 0, mModelMatrix, 0);
Matrix.multiplyMM(mMVP, 0, mViewMatrix, 0, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(u_modelmatrixCube, 1, false, mModelMatrix, 0);
switch(pattern[i][j]){
case 0:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
GLES20.glVertexAttribPointer(attr_position_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 0);
GLES20.glVertexAttribPointer(attr_color_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 12);
GLES20.glVertexAttribPointer(attr_normal_cube, 3, GLES20.GL_FLOAT, false, STRIDE_IN_FLAT, 24);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
GLES20.glCullFace(GLES20.GL_FRONT);
GLES20.glUniformMatrix4fv(u_changematrixCube, 1, false, mMirrorFlankMVP, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, capacityFlat1, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glUniformMatrix4fv(u_changematrixCube, 1, false, mMirrorDownMVP, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, capacityFlat1, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glUniformMatrix4fv(u_changematrixCube, 1, false, mMVP, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, capacityFlat1, GLES20.GL_UNSIGNED_SHORT, 0);
break;
case 1:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[1]);
....
break;
....
....
}
}
}
}
I would prefer to work on a mode RENDERMODE_WHEN_DIRTY,and I would like to understand what is happening with my depth buffer?
The following is not as conclusive as I normally like answers to be. Particularly, I have no explanation why this would behave differently between RENDERMODE_WHEN_DIRTY and RENDERMODE_CONTINUOUSLY. But there is one point in your question that is worth explaining anyway.
Only one of the my matrices have modification of near plane. The matrix may make bad data in the depth buffer.
You'll have to be very careful here. The range between near and far plane gets mapped to the range of the depth buffer. So if you use a standard projection matrix, and change the near plane, this mapping will change.
In other words, say you use a vertex at a given z-value (in eye coordinates) for your rendering while your projection matrix was set up with a near value of near1. Now you set the projection matrix with near value near2, and use a vertex with the same z-value. This vertex will now be mapped to a different depth buffer value. So depending on your projection, the same vertex will be mapped to different depth buffer values. Or a vertex that is farther away from the camera can end up with a smaller (closer) depth buffer value because you changed your projection matrix.
You could try to compensate for this by setting the depth range accordingly. But even that seems tricky if you use a perspective projection, because the mapping of eye space depth is to depth buffer values is not linear.
If you need to clip away close parts of some of your geometry, you're probably better off keeping the projection matrix unchanged, and clipping explicitly. OpenGL ES does not support arbitrary clip planes, so the easiest approach is to pass the distance to the fragment shader, and discard the clipped fragments there. Or if it's anyway possible, have logic in your app code to avoid rendering the geometry that would be clipped.
Adding of calling the glSurfaceView.requestRender() improve a performance. My focus on depth buffer dragged away from realy cause of problem.
Firsty what am I creating: 2d tile based rpg game.
What I am currently doing I will post here, and comment some spots that I am not sure if I am using them correctly.
In GlSurfaceViewRenderer:
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//I enable some attributes
//Don't know if its needed in GLES20, there isnt GL20.GL_PERSPECTIVE_CORRECTION_HINT attribute at all
GLES20.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
//next I don't really know if I need them all:
GLES20.glClearColor(0, 0, 0, 1);
GLES20.glClearDepthf(1.0f);
GLES20.glDisable(GLES20.GL_CULL_FACE);// No culling of back faces
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glDisable(GLES20.GL_DITHER);
GLES20.glDisable(GL10.GL_LIGHTING);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// for transperent pixels
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//Load shaders: (1 vertex and fragment shader I hope is enouph)
iProgId = Utils.LoadProgram(vertexShaderCode, fragmentShaderCode);
GLES20.glUseProgram(iProgId);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(iProgId, "vPosition");
// get handle to textures shader's a_TexCoordinate member
mTextureCoordinateHandle = GLES20.glGetAttribLocation(iProgId, "a_TexCoordinate");
// get handle to transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix");
//Now in here not sure: some people enable arrays in every draw frame, I do it once:
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Enable a handle to the texture vertices
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
Matrix.frustumM(mProjMatrix, 0, ratio, -ratio, 1, -1, 1, 10000);
//.... and other
}
#Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//set camera position
Matrix.setLookAtM(...);
Matrix.multiplyMM(...);
//begin drawing:
for(Sprite spr : Sprite_list){
spr.draw(){
//whats happening in draw:
//First setting the location of the sprite:
Matrix.setIdentityM(...x & y...);
Matrix.translateM(...);
Matrix.setIdentityM(...);
Matrix.multiplyMM(...);
//Some developers enables vertex attrib arrays here and then disables at the end of this drawing method. But I enable it in on surface created and don't disable it, maybe it's faster this way, not sure.
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(GLRenderer.mPositionHandle, DIMENSION, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(GLRenderer.mTextureCoordinateHandle, DIMENSION, GLES20.GL_FLOAT, false, vertexStride, textureBuffer);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textID);
GLES20.glUniformMatrix4fv(GLRenderer.mMVPMatrixHandle, 1, false, GLRenderer.mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
}
And everything works, for now, but I really not sure if I am doing any mistakes here, can someone elaborate?
The code itself does not necessarily do anything incorrect from what I can see.
Apart from GLES20.glDisable(GL10.GL_LIGHTING); as it's not a feature available in ES2.
Although the code is very limited to what it will be able to do. Reason is that you're uploading most of the rendering states in surfaceCreated, not when you actually might need them/change renderstates.
For example:
//Now in here not sure: some people enable arrays in every draw frame, I do it once:
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Enable a handle to the texture vertices
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
It's perfectly fine to just enable the attribute arrays at one place, however if you would like to utilize a different shader program for a particular piece of geometry in your scene, this would become quite problematic.
Consider this, if you would want to change program, you need to potentially Enable/Disable the particular attributes for that program. You would also need to bind the program (glUseProgram)
Therefore as you referenced yourself in the code comment, that others normally enable/disable these during rendering is for that specific reason.
However it's not just for attribute streams but also all types of renderstates like changing program, enabling Cullmode, blending and so forth.
Now one shouldn't go crazy and just upload and change all of these before every draw call, as changing states are expensive.
One will try to batch all the draw calls that will use the same type of renderstates and resources such as textures/programs and so forth together to minimize number of renderstates changes.
So in your renderloop you would then render the sorted scene of renderable objects, then upload any renderstate that might need to change or been invalidated.
I am very new to OpenGL, and I am trying to create a 2 pass shader. Basically, it has two frame buffers and two shader programs. It runs the first pass as usual, and then I need to take the resulting texture and pass it as an input to the second shader. How is this done? I cannot seem to see how you take a resulting texture and use it as an input to the next texture?
Here is some code: This code assumes I have setup the second filter program, and some attributes and uniforms in the program correctly
#Override
public void onDraw(final int textureId, final FloatBuffer cubeBuffer,final FloatBuffer textureBuffer){
//this draws the first pass (this is tested and working)
super.onDraw(textureId, cubeBuffer, textureBuffer);
//change the program
GLES20.glUseProgram(secondFilterProgram);
//clear the old colors
GLES20.glClearColor(0, 0, 0, 1);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glActiveTexture(GLES20.GL_TEXTURE3); //change the texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, secondFilterOutputTexture[0]);
GLES20.glUniform1i(secondFilterInputTextureUniform, 3);
cubeBuffer.position(0);
GLES20.glVertexAttribPointer(secondFilterPositionAttribute, 2, GLES20.GL_FLOAT, false, 0, cubeBuffer);
GLES20.glEnableVertexAttribArray(secondFilterPositionAttribute);
textureBuffer.position(0);
GLES20.glVertexAttribPointer(secondFilterTextureCoordinateAttribute, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
GLES20.glEnableVertexAttribArray(secondFilterTextureCoordinateAttribute); //same as line from init
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(secondFilterPositionAttribute);
GLES20.glDisableVertexAttribArray(secondFilterTextureCoordinateAttribute);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
I feel like I am missing a piece of the puzzle here. Again, I am very new to OpenGL, so any help, even conceptually is appreciated
What you want to achieve is called Render to Texture
A small tutorial how to do this with android can be found here:
http://blog.shayanjaved.com/2011/05/13/android-opengl-es-2-0-render-to-texture/
Does anyone know how to point out a given section of the texture buffer array stored in a HW buffer? I'm drawing a triangle strip and filling it with a square image. In my texture I have two square images next to each other, so the texture coordinate buffer points out them out with a total of 16 floats.
With software buffers I'm doing this to access the second image in the texture:
textureCoordinateBuffer.position(8);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordinateBuffer);
With hardware buffers I assumed I do something like this:
// setup HW buffers
// ...
// select HW buffers
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,vertexCoordinateBufferIndex);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordinateBufferIndex);
// Point out the first image in the texture coordinate buffer
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
// Draw
// ...
Which works nicely if you want to point out the first image in the texture.
But I would like to access the second image - so I assumed I do this in the last line:
// Point out the second image in the texture coordinate buffer - doesn't work!
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 8);
But this renders a scewed and discolored image.
Anyone who knows how to to this correctly?
You might want to take a look at the NeHe Android Tutorials. They go into this in detail and show you what you need to do.
Specifically, the lesson you are looking for is here:
http://insanitydesign.com/wp/projects/nehe-android-ports/
Lesson 6
You might not be binding and enabling the buffers, here's a snippet from the tutorial:
public void draw(GL10 gl) {
//Bind our only previously generated texture in this case
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
//Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
//Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangles, based on the Index Buffer information
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
Credit: Insanity Design - http://insanitydesign.com/
Edit:
I see what you're asking. Here's more code that should be able to help you then. If you look into the SpriteMethodTest app for android:
http://apps-for-android.googlecode.com/svn/trunk/SpriteMethodTest
You'll notice that Chris Pruett (The developer of this app) shows you the multitude of ways to draw textures to the screen. Below is the code (I believe) you're looking for.
Grid.java
public void beginDrawingStrips(GL10 gl, boolean useTexture) {
beginDrawing(gl, useTexture);
if (!mUseHardwareBuffers) {
gl.glVertexPointer(3, mCoordinateType, 0, mVertexBuffer);
if (useTexture) {
gl.glTexCoordPointer(2, mCoordinateType, 0, mTexCoordBuffer);
}
} else {
GL11 gl11 = (GL11)gl;
// draw using hardware buffers
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex);
gl11.glVertexPointer(3, mCoordinateType, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex);
gl11.glTexCoordPointer(2, mCoordinateType, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferIndex);
}
}
// Assumes beginDrawingStrips() has been called before this.
public void drawStrip(GL10 gl, boolean useTexture, int startIndex, int indexCount) {
int count = indexCount;
if (startIndex + indexCount >= mIndexCount) {
count = mIndexCount - startIndex;
}
if (!mUseHardwareBuffers) {
gl.glDrawElements(GL10.GL_TRIANGLES, count,
GL10.GL_UNSIGNED_SHORT, mIndexBuffer.position(startIndex));
} else {
GL11 gl11 = (GL11)gl;
gl11.glDrawElements(GL11.GL_TRIANGLES, count,
GL11.GL_UNSIGNED_SHORT, startIndex * CHAR_SIZE);
}
}
Specifically, you'll want to look at the code where it takes the false branch of !mUseHardwareBuffers. I suggest you look at the full Grid.java file for a better representation of how to do it because he also sets up the texture pointers and enables OpenGL to start drawing.
On a Side Note: I suggest reading this from Chris also:
http://www.scribd.com/doc/16917369/Writing-Real-Time-Games-for-Android
He goes into what this app does and what he found the most effective way of drawing textures was.