int array to opengl texture in android - android

I'm trying to add some efects to the camera in android,
I found some things on internet but I got stuck when creating the texture,
I use the funcion decodeYUV420SP() that returns me a int[width*height] RGB array with the hex values into each array position,
Now, I want to create an openGL texture of this array but i dont know how, I can convert each hex value to its R_G_B separated and put it into opengl but it doesn't work
I do something like this:
mNewTexture = new int[width*height*4]
for(int i=0; i<mRGB.length; i=i+4){
mNewTexture[i] = getR(mRGB[i]) ; //R
mNewTexture[i+1] = getG(mRGB[i]) ; //G
mNewTexture[i+2] = getB(mRGB[i]) ; //B
mNewTexture[i+3] = getA(mRGB[i]); //A
}
To convert the hex value to RGBA (from 0 to 255)
And i do this to convert it to the openGL texture:
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, 1024, 512, 0, GL10.GL_RGBA, GL10.GL_FLOAT, FloatBuffer.wrap(mNewTexture));
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
However something is worng, cause it doesn't work...
Any idea?

Why do you try to wrap your int array as a FloatBuffer? Most of your conversions are unnecessary.
Just take your original texture, wrap it in a bytebuffer, and pass it to glTexImage with the type GL_UNSIGNED_BYTE. There's no need to create a new array from what you already have.
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, 1024, 512, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mRGB));

Related

Use glEGLImageTargetTexture2DOES to replace glReadPixels on Android

Given a textureId, I need to extract pixel data from the texture.
glReadPixels works, but it is extremely slow on some devices, even with FBO/PBO. (On Xiaomi MI 5, it is 65 ms, and even slower with PBO). So I decided to use Hardwarebuffer and eglImageKHR, which should be much faster. However, I cannot get it to work. The screen goes black, and nothing is read into the data.
//attach inputTexture to FBO
glBindFrameBuffer(GL_FRAMEBUFFER, fbo)
glFrameBufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0)
//allocate hardware buffer
AHardwareBuffer* buffer = nullptr;
AHardwareBuffer_Desc desc = {};
desc.width = width;
desc.height = height;
desc.layers = 1;
desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER
| AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT ;
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
//create eglImageKHR
EGLint eglAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
EGLImageKHR eglImageKhr = eglCreateImageKHR(eglDisplay, eglContext,
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, eglAttributes);
//read pixels to hardware buffer ????
glBindTexture(GL_TEXTURE_2D, textureId);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr);
//copy pixels into memory
void *readPtr;
AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, (void**)&readPtr);
memcpy(writePtr, readPtr, width * 4);
AHardwareBuffer_unlock(buffer, nullptr);
This is my code with glReadPixels, and it just can get the pixels after attaching the texture to framebuffer.
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboBuffer!![0])
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER,
GLES30.GL_COLOR_ATTACHMENT0,
GLES30.GL_TEXTURE_2D,
inputTextureId,
0)
GLES30.glReadPixels(0, 0, width, height, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, byteBuffer)
Please tell me where I did wrong :(
//read pixels to hardware buffer ????
glBindTexture(GL_TEXTURE_2D, textureId);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr);
This doesn't do any reading of data. This is just setting up the texture to refer to the EGLImage. If you want data to be copied into it you need to either do glCopyTexImage2D() or bind it to a framebuffer and render in to it.

byte array image show to glsurafceview using GLES20.GlTexImage2D() android xamarin

I have to draw byte array image to glsurfaceview which is continuously comes from server in xamarin android project. code is not working for direct buffer draw but its working for bitmap draw.
my code is working if I convert byte array to bitmap and draw :
mBitmap = { .. create bitmap from byte[].. }
GLUtils.TexImage2D(GLES20.GlTexture2d, 0, mBitmap, 0);
At the same code if I put following code, then its not draw. I want to draw byte array using GLES20.GlTexImage2D(). My not working code is:
// mFrameBuffer is my byte array
ByteBuffer buffer = ByteBuffer.AllocateDirect(mFrameBuffer.Length);
buffer.Order (ByteOrder.NativeOrder());
buffer.Put (mFrameBuffer);
buffer.Position (0);
GLES20.GlTexImage2D (GLES20.GlTexture2d, 0, GLES20.GlRgb565, mWidth, mHeight, 0, GLES20.GlRgb565, GLES20.GlUnsignedByte, buffer);
How to draw image using GlTexImage2D for direct byte array.
After buffer.position(0) you should bind some texture on some slot
int id = -1;
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id);
After this check your bitmap config, if it's not RGB565 you should use respective color format in glTexImage2D, for example GLES20.GL_RGBA if bitmap config is Bitmap.Config.ARGB_8888.
GLES20.glTexImage2D(GL20W.GL_TEXTURE_2D, 0, GL20W.GL_RGBA, mWidth, mHeigh, 0,
GL20W.GL_RGBA, GL20W.GL_UNSIGNED_BYTE, buffer)
Then set your screen as FrameBuffer target:
GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0);
And after this steps simply draw your texture
I found solution by change format from GLES20.GlRgb565 to GLES20.GlRgba.
GLES20.GlRGB565 and GLES20.GlRGBA4 are not valid values to pass to GLES20.GlTexImage2D(), found from glTexImage2D.

Opengl - Convert Texture to Array

in my android App, i have a Frame Buffer Object that takes me the rendered Scene As a texture.
the app is an Origami game and user can fold a paper freely:
in every Fold, the current rendered scene saves to a texture using fbo and then i redraw the paper with new coordinates with new texture attached to it, to seem like folded paper. and this way the user can fold the paper as many time as he wants.
I want in every frame Check the rendered scene, to determinate does the user riches to the final shape (assume that i have the final shape in a 2d-array with 0 and 1 filled, 0 for transparency and 1 for colored pixels)
what i want, is to some How, Convert this Texture to A 2d-Array filled with 0 and 1,
0 for transparency pixel, and 1 for Colored pixel of texture.
i need this to then compare this result with a previously Known 2d-Array to determinate if the texture is the shape i want or not.
is it possible to save the texture data to an array?
i cant use glreadPixels because it is so heavy and its not possible to call it every frame.
here is the FBO class (i want to have renderTex[0] as array):
public class FBO {
int [] fb, renderTex;
int texW;
int texH;
public FBO(int width,int height){
texW = width;
texH = height;
fb = new int[1];
renderTex= new int[1];
}
public void setup(GL10 gl){
// generate
((GL11ExtensionPack)gl).glGenFramebuffersOES(1, fb, 0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glGenTextures(1, renderTex, 0);// generate texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_CLAMP_TO_EDGE);
//texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();
//gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, texW, texH, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
public boolean RenderStart(GL10 gl){
Log.d("TextureAndFBO", ""+renderTex[0] + " And " +fb[0]);
// Bind the framebuffer
((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);
// specify texture as color attachment
((GL11ExtensionPack)gl).glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);
int error = gl.glGetError();
if (error != GL10.GL_NO_ERROR) {
Log.d("err", "FIRST Background Load GLError: " + error+" ");
}
int status = ((GL11ExtensionPack)gl).glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)
{
Log.d("err", "SECOND Background Load GLError: " + status+" ");;
return true;
}
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
return true;
}
public void RenderEnd(GL10 gl){
((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
gl.glColor4f(1.0f,1.0f,1.0f,1.0f);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
public int getTexture(){
return renderTex[0];
}
public int getFBO(){
return fb[0];
}
}
If you are using openGL ES 3.0 and later then pbo would be a good solution. But I think you can use EGLImage. Because this only needs OpenGL ES 1.1 or 2.0.
The function to create an EGLImageKHR is:
EGLImageKHR eglCreateImageKHR(EGLDisplay dpy,
EGLContext ctx,
EGLenum target,
EGLClientBuffer buffer,
const EGLint *attrib_list)
To allocate an ANativeWindowBuffer, Android has a simple wrapper called GraphicBuffer:
GraphicBuffer *window = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE);
struct ANativeWindowBuffer *buffer = window->getNativeBuffer();
EGLImageKHR *image = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, *attribs);
to read pixels from an FBO use one of these two methods below:
void EGLImageTargetTexture2DOES(enum target, eglImageOES image)
void EGLImageTargetRenderbufferStorageOES(enum target, eglImageOES image)
These two methods will esablish all the properties of the target GL_TEXTURE_2D or GL_RENDERBUFFER
uint8_t *ptr;
glBindTexture(GL_TEXTURE_2D, texture_id);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
window->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &ptr);
memcpy(pixels, ptr, width * height * 4);
window->unlock();
To accomplish what you want, you need to use a PBO (Pixel Buffer Object): You can map it to an array to read it if it were a regular array.
OpenGL ARB_pixel_buffer_object extension is very close to
ARB_vertex_buffer_object. It simply expands ARB_vertex_buffer_object
extension in order to store not only vertex data but also pixel data
into the buffer objects. This buffer object storing pixel data is
called Pixel Buffer Object (PBO). ARB_pixel_buffer_object extension
borrows all VBO framework and APIs, plus, adds 2 additional "target"
tokens. These tokens assist the PBO memory manger (OpenGL driver) to
determine the best location of the buffer object; system memory,
shared memory or video memory. Also, the target tokens clearly specify
that the bound PBO will be used in one of 2 different operations;
GL_PIXEL_PACK_BUFFER_ARB to transfer pixel data to a PBO, or
GL_PIXEL_UNPACK_BUFFER_ARB to transfer pixel data from PBO.
It can be created similiar to other buffer objects:
glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, size, 0, GL_DYNAMIC_READ);
Then you can read from an FBO (or a texture) easily:
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
GLubyte *array = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, size, GL_MAP_READ_BIT);
// TODO: Do your checking of the shape inside of this 'array' pointer or copy it somewhere using memcpy()
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
Here GL_COLOR_ATTACHMENT0 is used as input - see the specification of glReadBuffer for further details how to specify front or backbuffer to be used.

OBJ Loader, texture binding and texture buffers

I'm currently developing an .obj file loader on Android. I have done the basics, and the 3d mesh is drawn correctly with OpenGl. Unfortunately I have a problem in binding the texture. Let me explain with more details:
The .obj file has the following structure:
v -0.751804 0.447968 -1.430558
v -0.751802 2.392585 -1.428428
... etc list with all the vertices ...
vt 0.033607 0.718905
vt 0.033607 0.718615
... etc list with all the texture coordinates ...
f 237/1 236/2 253/3 252/4
f 236/2 235/5 254/6 253/3
... etc list with all the faces ...
The f lines idicate the index where the appropriate vertex and texture coordinates are stored, like
f vertex_index/texture_coord_index
So my program
parses the vertices and stores them in a Vector<Float>,
parses the texture coordinates and stores them in a Vector<Float>
and finally parses the faces and stores every vertex index in a Vector<Short> and every texture coordinate index in a Vector<Short>
After all this code, I'm creating the appropriate buffers:
public void buildVertexBuffer(){
ByteBuffer vBuf = ByteBuffer.allocateDirect(vertices.size() * 4);
vBuf.order(ByteOrder.nativeOrder());
vertexBuffer = vBuf.asFloatBuffer();
vertexBuffer.put(toFloatArray(vertices));
vertexBuffer.position(0);
}
where vertices is the vector that stores the float vertices
public void buildFaceBuffer(){
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(faces.size() * 2);
byteBuffer.order(ByteOrder.nativeOrder());
faceBuffer = byteBuffer.asShortBuffer();
faceBuffer.put(toShortArray(faces));
faceBuffer.position(0);
}
where faces is the vector that stores the indices and
public void buildTextureBuffer(Vector<Float> textures){
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(texturePointers.size() * 4 * 2);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
for(int i=0; i<texturePointers.size(); i++){
float u = textures.get(texturePointers.get(i) * 2);
float v = textures.get(texturePointers.get(i) * 2 + 1);
textureBuffer.put(u);
textureBuffer.put(v);
}
textureBuffer.position(0);
}
where textures are the float texture coordinates and texturePointers point to the textures' values.
The binding happens here:
public int[] loadTexture(GL10 gl, Context context){
if(textureFile == null)
return null;
int resId = getResourceId(textureFile, R.drawable.class);
if(resId == -1){
Log.d("Bako", "Texture not found...");
return null;
}
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
/*gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);*/
/*int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
bitmap.copyPixelsToBuffer(buffer);
gl.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_INT, buffer);*/
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
return textures;
}
Finally my draw() method of my mesh looks like this
public void draw(GL10 gl){
if(bindedTextures != null){
gl.glBindTexture(GL10.GL_TEXTURE_2D, bindedTextures[0]);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CW);
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
for(int i=0; i<parts.size(); i++){
ModelPart modelPart = parts.get(i);
Material material = modelPart.getMaterial();
if(material != null){
FloatBuffer a = material.getAmbientColorBuffer();
FloatBuffer d = material.getDiffuseColorBuffer();
FloatBuffer s = material.getSpecularColorBuffer();
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, a);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, s);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, d);
}
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, modelPart.getTextureBuffer()); // returns the texture buffer created with the buildTextureBuffer() method
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, modelPart.getNormalBuffer());
gl.glDrawElements(GL10.GL_TRIANGLES, modelPart.getFacesSize(), GL10.GL_UNSIGNED_SHORT, modelPart.getFaceBuffer());
//gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
When i run this application the 3d model is drawn like a charm, but the texture is somehow streched. The image that contains the texture has a red background with the appropriate image in the center and this red background is drawn onto the whole 3d model.
Well my first question is if the textureBuffer built correctly. Do i have to change the code in buildTextureBuffer() ?
And the second one; is the the draw() method correct? Does my problem have to be with the faces buffer?
So, in OpenGL a vertex is whatever combination of information describes a particular point on the model. You're using the old fixed pipeline so a vertex is one or more of a location, some texture coordinates, a normal and a colour.
In OBJ a vt is only a location. The thing that maps to the OpenGL concept of a vertex is each unique combination of — in your case — location + texture coordinate pairs given after an f.
You need a mapping whereby if the f says 56/92 then you can lookup the 56/92 and find out that you consider that to be, say, vertex 23 and have communicated suitable arrays to OpenGL such that the location value in slot 23 was the 56th thing the OBJ gave as a v and the 92nd thing it gave as a vt.
Putting it another way, OBJ files have an extra level of indirection that OpenGL does not.
It looks to me like you're not resolving that difference. A common approach would be to use a HashMap from v/vt pair to output index, building your output arrays on demand as you parse the f.

VBO's on Android: Pointing out the correct image in texture coordinate buffers

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.

Categories

Resources