Android OpenGL ES 1.1 white box textures - android

I am having an issue where textures from the resources become just white.
The issue only seems to occur on phones (Droid-X for sure), but it works just fine on the emulator.
I have researched this issue for days and tried so many things.
Textures are POT ranging from 8x8 to 128x128
Textures have been in res/drawable, res/drawable-nodpi and res/raw
Tried with and without this in the manifest file:
<supports-screens android:anyDensity="true" />
I am at a complete loss on this.
Here is the code I am using
gl is GL10 and gl11 is GL11
During onSurfaceCreated
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_LIGHTING);
gl.glShadeModel(GL10.GL_FLAT);
gl.glClearColor(0.00f, 0.00f, 0.00f, 1.00f);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_DST_ALPHA);
gl.glOrthof(-1, 1, -1, 1, -1, 1);
gl.glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
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);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
During onSurfaceChanged
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glViewport(0, 0, width, height);
Generating the VBO:
public final float vertices[] = {
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f
};
public float textureCoord[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
public final byte indices[] = {
0, 1, 3,
0, 3, 2
};
verticesBuffer = ByteBuffer.allocateDirect(vertices.length *
Constants.FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordBuffer = ByteBuffer.allocateDirect(textureCoord.length *
Constants.FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
indicesBuffer = ByteBuffer.allocateDirect(indices.length).order(ByteOrder.nativeOrder());
// fill buffers
verticesBuffer.put(vertices);
textureCoordBuffer.put(textureCoord);
indicesBuffer.put(indices);
// set pointer positions
verticesBuffer.position(0);
textureCoordBuffer.position(0);
indicesBuffer.position(0);
// temp buffer array
int[] buffer = new int[1];
// VERTICES BUFFER.
gl11.glGenBuffers(1, buffer, 0);
verticesBufferIndex = buffer[0];
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, verticesBufferIndex);
final int vertexSize = verticesBuffer.capacity() * Constants.FLOAT_SIZE;
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertexSize, verticesBuffer, GL11.GL_STATIC_DRAW);
// TEXTURE COORD BUUFER
gl11.glGenBuffers(1, buffer, 0);
textureCoordBufferIndex = buffer[0];
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordBufferIndex);
final int texCoordSize = textureCoordBuffer.capacity() * Constants.FLOAT_SIZE;
gl11.glBufferData(GL11.GL_ARRAY_BUFFER, texCoordSize, textureCoordBuffer, GL11.GL_STATIC_DRAW);
// clear buffer id
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
// Unbind the array buffer.
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
gl11.glGenBuffers(1, buffer, 0);
// INDICES BUFFER
indicesBufferIndex = buffer[0];
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indicesBufferIndex);
final int indexSize = indicesBuffer.capacity();
gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, indexSize, indicesBuffer, GL11.GL_STATIC_DRAW);
// Unbind the element array buffer.
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, verticesBufferIndex);
gl11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordBufferIndex);
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indicesBufferIndex);
BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
sBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
// many of these calls :
Bitmap bitmap = BitmapFactory.decodeStream(resources.openRawResource(resourceID), null, sBitmapOptions);
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
mCropWorkspace[0] = 0;
mCropWorkspace[1] = bitmap.getHeight();
mCropWorkspace[2] = bitmap.getWidth();
mCropWorkspace[3] = -bitmap.getHeight();
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
return texture[0]; // which gets stored into textureID for later
During onDrawFrame
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// and many of these
gl11.glPushMatrix();
// transfomations
gl11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
gl11.glDrawElements(GL10.GL_TRIANGLES, indicesCount, GL10.GL_UNSIGNED_BYTE, 0);
gl11.glPopMatrix();
Sorry for all the code but I think everything is there.
Thank you,
Will

You must enable vertex array and texture coords array and bind your buffer indexes before making any calls to your glDraw...() function.
After glBindTexture() in onDrawFrame(), put this:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
GL11 gl11 = (GL11) gl;
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, verticesBufferIndex);
gl11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordBufferIndex);
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indicesBufferIndex);
// Draw...

Related

Android 'white box' textures OpenGL ES 1.0 on some devices

I have next problem.
I'm write some android app which uses opengl es 1.0
I'm using GLSurfaceView and custom Renderer. Here are methods of my custom renderer onDrawFrame, onSurfaceChanged, onSurfaceChanged:
#Override
public void onDrawFrame(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0f, 0f, -3.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
// gl.glScalef(0.5f, 0.5f, 0.5f); // scale the square to 50%
// otherwise it will be too large
square.draw(gl, mScrollable.getIndexA(), mScrollable.getIndexB(), mScrollable.getAlphaValue()); // Draw the triangle
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, mWidth, mHeight); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square
square.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
And my Square class to render textures:
private int[] textures;
private GL10 mGl;
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.8f, 0.0f, // V1 - bottom left
-1.0f, 1.3f, 0.0f, // V2 - top left
1.0f, -1.8f, 0.0f, // V3 - bottom right
1.0f, 1.3f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private GlAnimationCache cacheHelper;
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
mGl = gl;
gl.glGenTextures(mImageEntityList.size(), textures, 0);
cacheHelper = new GlAnimationCache(mContext, mImageEntityList, mGlRenderer, mGlSurfaceView);
cacheHelper.initCache(); //it init cache in background thread
}
public void removeTextureAt(int position){
mGl.glDeleteTextures(1, textures, position);
}
public void bindTextureAt(final Bitmap bitmap, int position){
// generate one texture poi, 0);
// ...and bind it to our array
mGl.glBindTexture(GL10.GL_TEXTURE_2D, textures[position]);
mGl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
mGl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// create nearest filtered texture
mGl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
mGl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
// gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
// gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLUtils.getInternalFormat(bitmap), bitmap, GLUtils.getType(bitmap), 0);
bitmap.recycle();
}
private int prevIndex = 0;
/** The draw method for the square with the GL context */
public void draw(GL10 gl, int indexA, int indexB, float alpha) {
// bind the previously generated texture
if(prevIndex != indexA){
cacheHelper.synchronizeCache(indexA);
prevIndex = indexA;
}
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexA]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, 1f);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexB]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, Math.abs(alpha));
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
So, the problem is next: On Samsung S5, Alcatel One Touch 4033D and Motorolla Droid Razr textures are rendered fine. But on Samsung Galaxy Nexus I see only 'white box'.
I have tried to change size of texture to power of 2(512 x 512) but it not helpes.
In Square class add function:
public boolean isNPOTSupported(GL10 gl) {
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
return extensions.indexOf("GL_OES_texture_npot") != -1;
}
And when you Generate textures, add this:
final boolean isNPOTSupported = isNPOTSupported(gl);
if(isNPOTSupported) {
gl.glGenTextures(mImageEntityList.size(), textures, 0);
}else{
for(int i = 0; i < mImageEntityList.size(); i++){
gl.glGenTextures(1, textures, i);
}
}
Instead this:
gl.glGenTextures(mImageEntityList.size(), textures, 0);

Android OpenGL-ES gradient background

I would like to have a gradient background in OpenGL
I found these two links, but I cannot reproduce it:
OpenGL gradient fill on iPhone looks striped
OpenGL gradient banding on Android
I tried the following of the first link:
// Begin Render
//IntBuffer redBits = null, greenBits = null, blueBits = null;
//gl.glGetIntegerv (GL10.GL_RED_BITS, redBits); // ==> 8
//gl.glGetIntegerv (GL10.GL_GREEN_BITS, greenBits); // ==> 8
//gl.glGetIntegerv (GL10.GL_BLUE_BITS, blueBits); // ==> 8
gl.glDisable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_FOG);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
float[] vertices = {
0, 0,
320, 0,
0, 480,
320, 480,
};
FloatBuffer vertsBuffer = makeFloatBuffer(vertices);
int[] colors = {
255, 255, 255, 255,
255, 255, 255, 255,
200, 200, 200, 255,
200, 200, 200, 255,
};
IntBuffer colorBuffer = makeIntBuffer(colors);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
// End Render
protected static FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
protected static IntBuffer makeIntBuffer(int[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
IntBuffer ib = bb.asIntBuffer();
ib.put(arr);
ib.position(0);
return ib;
}
But it just shows a rectangle in the right upper corner. But I don't know if the
glGetIntegerv
would have an effect? Any ideas/links how to make it run?
SOLUTION
// set orthographic perspective
setOrtho2D(activity, gl);
gl.glDisable(GL10.GL_BLEND);
//gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_FOG);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
float[] vertices = {
0, 0,
_winWidth, 0,
0, _winHeight,
_winWidth, _winHeight
};
FloatBuffer vertsBuffer = makeFloatBuffer(vertices);
float[] colors = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.2f, 0.2f, 0.2f, 1.0f,
0.2f, 0.2f, 0.2f, 1.0f
};
FloatBuffer colorBuffer = makeFloatBuffer(colors);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
I forgot to comment in the perspective line again. I also changed the vertices layed order from "U" shape to the "Z" shape (as commented from Nick).
Now it looks like how I want it:
This is a problem:
int[] colors;
....
gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
You are using signed four-byte integers for your color channels, and then telling opengl that they are unsigned one-byte integers. You should be using a buffer full of unsigned bytes.
It would be easier however, to just use floats instead:
float[] colors = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f,
};
float vertices[] = {
0, 0,
800, 0,
0, 480,
480, 800,
};
FloatBuffer colorBuffer = makeFloatBuffer(colors);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

Write Pixels to a Texture via OpenGL ES Android

I'm trying to do some pixel work in a texture old school by accessing it using an array. My approach is to generate a texture, then use that texture each successive frame write and modify my texture as necessary. However, when I run this code in the Android Emulator, all I get is a white image. My texture size is a power of two, so I was a bit surprised. If anything, I would have expected to see a completely black image. Here is my custom renderer code:
package com.gltest;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
public class OpenGLRenderer implements Renderer {
private ByteBuffer buf;
private int cwidth, cheight;
private FloatBuffer vertexBuffer, texelBuffer;
private ShortBuffer indexBuffer;
int[] textures = new int[1];
float vertices[] = {
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
private float texels[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
private short[] indices = { 0, 1, 2, 0, 2, 3 };
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
updateTexture(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, 0, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
buf = ByteBuffer.allocateDirect(128 * 128 * 3).order(ByteOrder.nativeOrder());
cwidth = width;
cheight= height;;
for( int i=0; i<vertices.length; i+=3 ) {
vertices[i] *= cwidth;
vertices[i+1] *= cheight;
}
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, 3, 128, 128, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, buf);
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(texels.length * 4);
tbb.order(ByteOrder.nativeOrder());
texelBuffer = tbb.asFloatBuffer();
texelBuffer.put(texels);
texelBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
void updateTexture(GL10 gl)
{
// Update pixels
// write random r g or b values to random locations
for(int y = 0; y < 128; ++y)
for(int x = 0; x < 128; ++x)
buf.put(x+y*128, (byte)(Math.random()*255));
buf.position(0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(gl.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, buf);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texelBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
Honestly I do not believe it is a very convenient solution performance wise.
This kind of alteration/effects should be done in a programmable pipeline model such as OPENGL ES 2.0 using vertex and fragment shaders.
The solution you are trying to achieve is not convenient for the following reasons:
The load is entirely on the CPU and you are not using the power of the GPU at all
Texture data manipulation functions are well known to be a performance killer for nowadays GPUs
I strongly suggest you to implement the effects possibly in a fragment shader to have the best performances possible.
After some poking around, I've discovered that gl.glTexSubImage2D is not supported in GLES 1.1 on Android (it's built in but it doesn't do anything: https://www.google.com/search?ix=hea&sourceid=chrome&ie=UTF-8&q=android+opengl+glTexSubImage2D)
Also, so no one else wastes their time in the future, forget about trying to use glDrawPixels to send to the framebuffer. That isn't support either, in any GLES 1.1 / 2.0 implementation (Android, iPhone) etc.
The solution is to use the NDK as outlined in this excellent article by some coder named "Richard Quirk" who has his own blog: http://quirkygba.blogspot.com/2010/10/android-native-coding-in-c.html and, as it happens, also is a Stack Overflow regular: https://stackoverflow.com/users/4596/richq
Thanks Richard!

Drawing text as textures on squares does not show anything

I'm new to OpenGL and I'm developing an Augmented-reality application for Android.
Until now, I was drawing white squares, perpendicular to the camera, pointing the user to the direction where a "Point of interest" would be.
Now, I'm trying to show some text into the squares.
I've read a lot and it seems that creating a texture with the text is the most direct and easiest approach, so I'm creating the textures as soon as I get data of the Points of interest and stick them to their squares. For that, I use bitmaps.
Let's see some code. Within my onDrawFrame method, I do something like this:
public void onDrawFrame(GL10 gl) {
// Get sensors matrix
...
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Load remapped matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
// List of Points of interest (modified when some data is downloaded)
synchronized (poiList) {
if(mNewData){ // True if new data has been dowloaded)
if(textures != null) // Delete old textures
gl.glDeleteTextures(textures.length, textures, 0);
textures = loadGLTexture(gl, soapPoiList.getPoiList());
mNewData = false;
}
int i = 0;
// Iterate the list
for (PointOfInterest c : poiList) {
gl.glLoadIdentity();
gl.glLoadMatrixf(remappedRotationMatrix, 0);
// Get bearing
...
// Place polygon in the right place
gl.glRotatef(-bearing, 0, 0, 1);
gl.glTranslatef(0, ICONS_SIZE_RATIO, 0);
// Actually draws the polygon with text
c.draw(gl, textures[i]);
i++;
}
}
}
Where loadGLTextures is:
protected int[] loadGLTexture(GL10 gl, List<PointOfInterest> l){
int res[] = new int[l.size()];
gl.glGenTextures(res.length, res, 0);
int i = 0;
for(PointOfInterest p : l) {
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
bitmap.eraseColor(Color.BLACK);
Canvas canvas = new Canvas(bitmap);
Paint textPaint = new Paint();
textPaint.setTextSize(35);
textPaint.setFakeBoldText(true);
textPaint.setAntiAlias(true);
textPaint.setARGB(255, 255, 255, 255);
// Draw the text centered
canvas.drawText(Float.toString(p.getDinstanceToOrigin()) + " m.", 10,35, textPaint);
// Bind the texture to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, res[i]);
// Create Nearest Filtered Texture
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);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
i++;
}
return res;
}
It basically creates a bitmap for each Point of Interest, and generate a texture with it. The texture will be applied over a white square later, as it is shown in this class:
public class PointOfInterest {
// MEMBERS ----------------------------------------------------------------
....
....
// OpenGL necessary variables
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The initial vertex definition */
private float vertices[] = {
-1.0f, 0.0f, -1.0f, //Bottom Left V1
-1.0f, 0.0f, 1.0f, //Top Left V2
1.0f, 0.0f, -1.0f, //Bottom Right V3
1.0f, 0.0f, 1.0f, //Top Right V4
};
private FloatBuffer textureBuffer;
private float texture[] = {
0.0f, 0.0f, // V1
1.0f, 0.0f, // V3
0.0f, 1.0f, // V2
1.0f, 1.0f // V4
};
// CONSTRUCTORS -----------------------------------------------------------
public PointOfInterest(Location originLocation){
currentLocation = originLocation;
mPoiLocation = new Location(LocationManager.GPS_PROVIDER);
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
// PUBLIC METHODS ---------------------------------------------------------
public void draw(GL10 gl, int textureId){
// Bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// set the colour for the square
//gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);
//Set the face rotation
gl.glFrontFace(GL10.GL_CW);
//Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
....
....
}
I have tried to map the texture as it is taught here and here with no success. I really don't know what to do to get some letters drawn on the squares and am really lost here... Maybe the text is being drawn on the other face of the square, maybe the textures are not being generated... I don't know.
Any kind of help would be very appreciated.
Okay, I had forgotten to enable texture mapping. You can do that within any method that uses the GL10 object. I prefer to do it within the draw method of my objects, so any other object is not affected by the texture. It's as simple as this (just changed 2 lines, the ones that say NEW!!):
public void draw(GL10 gl, int textureId){
gl.glEnable(GL10.GL_TEXTURE_2D); //NEW !!! Enable Texture Mapping
// Bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// set the colour for the square
//gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);
//Set the face rotation
gl.glFrontFace(GL10.GL_CW);
//Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D); ////NEW !!! Disable texture mapping
}

I can't make my texturing using GL_REPEAT to work on my Android Galaxy Tab 10.1 but it works on my phone and emulator

Hi I am new in Android and OpenGLES development. I am trying to develop a simple Android game using OpenGL. The background image of my game is a tiling where I want to use the texture mapping wrap as GL_REPEAT. It is working fine in my Samsung Galaxy S and with the emulator for the platform 3.0. The problem is with my Samsung 10.1 Galaxy Tab where I cant get it to repeat the texture. It is always using the texture clamp to edge. I have found a texturing tutorial and when I modify the texture mapping and wrap parameters for this tutorial the texture is repeated as expected so I know that it is not a tablet bug in the tablet. The question is what is wrong in my code that is only being a problem for the tablet?
I am doing all texture setup in my a class that implements GLSurfaceView.Renderer. Is this a problem?
package com.droidev.games.bubbilliards;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.util.Log;
public class BBGLRenderer implements GLSurfaceView.Renderer {
private BBGame game;
private int width;
private int height;
private float ratio_w_h;
private ShortBuffer indicesBuffer;
private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
private FloatBuffer backgroundVertexBuffer;
private FloatBuffer backgroundTextureBuffer;
private Context context;
private BBGLSurfaceView glSurfaceView;
private int ball_textures[];
private int hole_open_textures[];
private int hole_closed_textures[];
private int background_textures[];
private float length;
private boolean texture_set;
private Bitmap green_ball;
private Bitmap orange_ball;
private Bitmap purple_ball;
private Bitmap green_hole_open;
private Bitmap orange_hole_open;
private Bitmap purple_hole_open;
private Bitmap green_hole_closed;
private Bitmap orange_hole_closed;
private Bitmap purple_hole_closed;
private Bitmap background;
public BBGLRenderer(Context context_, BBGLSurfaceView sv){
super();
context = context_;
glSurfaceView = sv;
game = new BBGame(sv);
texture_set = false;
}
public void onSurfaceCreated(GL10 gl, EGLConfig config){
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glEnable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
// reading images from resources
green_ball = BitmapFactory.decodeResource(context.getResources(), R.drawable.green_ball);
orange_ball = BitmapFactory.decodeResource(context.getResources(), R.drawable.orange_ball);
purple_ball = BitmapFactory.decodeResource(context.getResources(), R.drawable.purple_ball);
green_hole_open = BitmapFactory.decodeResource(context.getResources(), R.drawable.green_hole_open);
orange_hole_open = BitmapFactory.decodeResource(context.getResources(), R.drawable.orange_hole_open);
purple_hole_open = BitmapFactory.decodeResource(context.getResources(), R.drawable.purple_hole_open);
green_hole_closed = BitmapFactory.decodeResource(context.getResources(), R.drawable.green_hole_closed);
orange_hole_closed = BitmapFactory.decodeResource(context.getResources(), R.drawable.orange_hole_closed);
purple_hole_closed = BitmapFactory.decodeResource(context.getResources(), R.drawable.purple_hole_closed);
background = BitmapFactory.decodeResource(context.getResources(), R.drawable.tile);
// creating textures IDS
int num_colors = BBColor.values().length;
ball_textures = new int[num_colors];
hole_open_textures = new int[num_colors];
hole_closed_textures = new int[num_colors];
background_textures = new int[1];
gl.glGenTextures(num_colors, ball_textures , 0);
// balls
initializeTexture(gl, green_ball , ball_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_ball, ball_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_ball, ball_textures, (int)BBColor.PURPLE.ordinal());
gl.glGenTextures(num_colors, hole_open_textures , 0);
// holes open
initializeTexture(gl, green_hole_open , hole_open_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_hole_open, hole_open_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_hole_open, hole_open_textures, (int)BBColor.PURPLE.ordinal());
gl.glGenTextures(num_colors, hole_closed_textures, 0);
// holes closed
initializeTexture(gl, green_hole_closed, hole_closed_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_hole_closed, hole_closed_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_hole_closed, hole_closed_textures, (int)BBColor.PURPLE.ordinal());
gl.glGenTextures(1 , background_textures , 0);
initializeTexture(gl, background, background_textures, 0);
// initializeBuffers();
}
public void initializeTextures(GL10 gl){
int num_colors = BBColor.values().length;
gl.glGenTextures(num_colors, ball_textures , 0);
gl.glGenTextures(num_colors, hole_open_textures , 0);
gl.glGenTextures(num_colors, hole_closed_textures, 0);
gl.glGenTextures(1 , background_textures , 0);
// balls
initializeTexture(gl, green_ball , ball_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_ball, ball_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_ball, ball_textures, (int)BBColor.PURPLE.ordinal());
// holes open
initializeTexture(gl, green_hole_open , hole_open_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_hole_open, hole_open_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_hole_open, hole_open_textures, (int)BBColor.PURPLE.ordinal());
// holes closed
initializeTexture(gl, green_hole_closed, hole_closed_textures, (int)BBColor.GREEN.ordinal());
initializeTexture(gl, orange_hole_closed, hole_closed_textures, (int)BBColor.ORANGE.ordinal());
initializeTexture(gl, purple_hole_closed, hole_closed_textures, (int)BBColor.PURPLE.ordinal());
initializeTexture(gl, background, background_textures, 0);
texture_set = true;
}
public void initializeTexture(GL10 gl, Bitmap bmp, int textures[], int color){
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[color]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
// gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bmp.getWidth(), bmp.getHeight(), 0, GL10.GL_RGBA, GL10.GL_, pixels)
}
public void initializeBuffers(int w, int h){
length = Math.min(ratio_w_h/(float)game.getWidth(), 1.0f/(float)game.getHeight());
// Vertices Position //////////////////////////////////////////////////////////
float vertices[] = {0.0f , 0.0f , 0.0f,
length, 0.0f , 0.0f,
0.0f , length, 0.0f,
length, length, 0.0f};
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = vertexByteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// indices ////////////////////////////////////////////////////////////////////
short[] indices = new short[] { 0, 1, 2, 1, 3, 2 };
ByteBuffer indicesByteBuffer = ByteBuffer.allocateDirect(indices.length * 2);
indicesByteBuffer.order(ByteOrder.nativeOrder());
indicesBuffer = indicesByteBuffer.asShortBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
// Texture Coords /////////////////////////////////////////////////////////////
float coords[] = {0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f};
ByteBuffer textureByteBuffer = ByteBuffer.allocateDirect(coords.length * 4);
textureByteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = textureByteBuffer.asFloatBuffer();
textureBuffer.put(coords);
textureBuffer.position(0);
//////////////////////////////////////////////////////////////////////
// Vertices Position //////////////////////////////////////////////////////////
float verticesBackground[] = {0.0f , 0.0f, 0.0f,
game.getWidth()*length, 0.0f, 0.0f,
0.0f , game.getHeight()*length, 0.0f,
game.getWidth()*length, game.getHeight()*length, 0.0f};
ByteBuffer backgroundVertexByteBuffer = ByteBuffer.allocateDirect(verticesBackground.length * 4);
backgroundVertexByteBuffer.order(ByteOrder.nativeOrder());
backgroundVertexBuffer = backgroundVertexByteBuffer.asFloatBuffer();
backgroundVertexBuffer.put(verticesBackground);
backgroundVertexBuffer.position(0);
// Texture Coords /////////////////////////////////////////////////////////////
float coordsBackground[] = {0.0f, game.getHeight(),
game.getWidth(), game.getHeight(),
0.0f, 0.0f,
game.getWidth(), 0.0f};
ByteBuffer backgroundTextureByteBuffer = ByteBuffer.allocateDirect(coordsBackground.length * 4);
backgroundTextureByteBuffer.order(ByteOrder.nativeOrder());
backgroundTextureBuffer = backgroundTextureByteBuffer.asFloatBuffer();
backgroundTextureBuffer.put(coordsBackground);
backgroundTextureBuffer.position(0);
//////////////////////////////////////////////////////////////////////
game.setResolution(w, h);
game.setRatio_W_H(ratio_w_h);
game.setSquareLength(length);
}
public void onSurfaceChanged(GL10 gl, int w, int h){
width = w;
height = h;
ratio_w_h = (float)width/(float)height;
gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0.0f, ratio_w_h*1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
initializeBuffers(w, h);
}
public void onDrawFrame(GL10 gl){
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, backgroundTextureBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, background_textures[0]);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
// if(!texture_set){
// initializeTextures(gl);
// initializeBuffers(width, height);
// }
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, backgroundVertexBuffer);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indicesBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
for(BBHole h: game.getHoles()){
gl.glPushMatrix();
gl.glTranslatef(h.getX()*length, h.getY()*length, 0.0f);
gl.glBindTexture(GL10.GL_TEXTURE_2D, (h.isOpen())?hole_open_textures[h.getColor().ordinal()]:hole_closed_textures[h.getColor().ordinal()]);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indicesBuffer);
gl.glPopMatrix();
}
for(BBBubble b: game.getBubbles()){
synchronized (b) {
gl.glPushMatrix();
gl.glTranslatef(b.getX()*length+b.getTx(), b.getY()*length+b.getTy(), 0.0f);
gl.glBindTexture(GL10.GL_TEXTURE_2D, ball_textures[b.getColor().ordinal()]);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indicesBuffer);
gl.glPopMatrix();
b.notifyAll();
}
}
// gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D);
// gl.glFlush();
// Log.i("GL_ERROR = ", Integer.toString( gl.glGetError()));
glSurfaceView.setDirty(false);
}
public BBGame getGame(){
return game;
}
}
So I basically have an Activity a class that extends the GLSurfaceView, a class presented above that implements the GLSurfaceView.Renderer and a class that have the game rules, etc.
Thanks in advance!
I think GL_REPEAT only works with POT (power of two) textures and your drawable-xyz probably got scaled up or down to a non-POT size.
OK I found the solution for my problem but it does not make sense for me. The project that was created in eclipse had in the res folder only the folders drawable-hdpi, drawable-mdpi and drawable-ldpi but not a drawable folder such as in the tutorial I have mentioned before.
So the solution was to create this "drawable" folder and put the image there. Then GL_REPEAT "magically" worked for the galaxy tab. I wasted 2 days because of this folder problem :(.
I am curious if it makes sense or not and if I should put all my textures inside these drawable folder always.

Categories

Resources