I am creating a button class that will display a blue circle if it is not being pressed and a red circle if it is being pressed. I start by building a 4 vertex quad composed of two triangles. I generate my own bitmap and draw two circles on the bitmap next to each other, left to right. I then create a texture buffer with instead 4 uv points, I create it with 8, one that maps out the blue circle, one that maps out the red circle. I would then like to render the red circle when the button is pressed. Ideally I would like to call the
gl.glTexCoordPointer
method and pass in an offset, but that is not working. Here is my method that I used to generate the bitmap, draw on the bitmap using the canvas and paint objects and then attempt to map the textures. Note that I have to generate a texture that is a power of 2 so there is some math in there that allows me to generate a bigger bitmap than I need based of the width and height variables of the button that were specified in the constructor.
public void InitializeButton(GL10 gl, int upcolor, int downcolor, String symbol)
{
//Our variables for creating a bitmap and texture
Canvas canvas = null;
Bitmap bitmap = null;
Paint paint = null;
//Set up the bitmap type
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
/*
* We now want to calculate the size of the texture. Remember it is best to be a square
* texture or at least a power of 2. The below equation below will do this. For example
* if the width of the button was say 20, we need to find the smallest power of 2 that is
* greater than 20. In this case we know it is 32. But how do we calculate that? First we
* have to find out the exponent of what 2^x = 20. Then we find the ceiling of tha number.
* In order to make that calculation we have to take the log of that, but in order to use
* the log function which is base 10, we have to switch to base 2 so that means
* we have to take the log(width)/log(2) to switch to base 2, then get the ceiling of that
* number because it would be between 4 and 5 in this case. When we take the ceiling we get
* 5 and 2^5 is 32.
*
* Side note, we want to double the size to make sure there is room for the up and the down
* actions.
*/
widthTexture = (int) Math.pow(2,Math.ceil((Math.log(this.width*2)/Math.log(2))));
heightTexture = (int) Math.pow(2,Math.ceil((Math.log(this.height*2)/Math.log(2))));
/*
* Now we will create the bitmap for the creation of the button
*/
bitmap = Bitmap.createBitmap(widthTexture,heightTexture,conf);
//Now create a new canvas from that bitmap
canvas = new Canvas(bitmap);
//Create a new Paint
paint = new Paint();
/*
* Now we want to render the draw the up and down button on the texture. We are just going
* to use two different colors to represent up and down. So we will draw the up circle button
* starting at 0 0 and the down button off to the right.
*/
paint.setColor(upcolor);
paint.setAlpha(120);
canvas.drawOval(new RectF(0,0,width,height), paint);
paint.setColor(Color.BLACK);
canvas.drawText(symbol, width/2, height/2, paint);
paint.setColor(Color.WHITE);
canvas.drawText(symbol, width/2+3, height/2+3, paint);
//Draw the down color button
paint.setColor(downcolor);
paint.setAlpha(120);
canvas.drawOval(new RectF(width,0,width*2,height), paint);
paint.setColor(Color.WHITE);
canvas.drawText(symbol, width+(width/2), height/2, paint);
paint.setColor(Color.BLACK);
canvas.drawText(symbol, width+(width/2)+3, height/2+3, paint);
float widthpercent = ((float)width/(float)widthTexture);
float heightpercent = ((float)height/(float)heightTexture);
/*
* Now create two texture maps. One for the up button and one for the down button
* You can change the offset of the draw texture thing to change the animations now
*/
float uvTextures[] = {0f, heightpercent,
widthpercent, heightpercent,
widthpercent, 0f,
0f, 0f,
widthpercent, heightpercent,
widthpercent*2, heightpercent,
widthpercent*2, 0f,
widthpercent, 0f,
};
/*
* Allocate the byte buffer so it is a normal array of floats and not a java array.
* load the uvTexture values inside.
*/
ByteBuffer tbb = ByteBuffer.allocateDirect(uvTextures.length*4);
tbb.order(ByteOrder.nativeOrder());
textureBuffer = tbb.asFloatBuffer();
textureBuffer.put(uvTextures);
textureBuffer.position(0);
int [] textures = new int[1];
gl.glGenTextures(1, textures,0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
textureID = 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_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bitmap,0);
//Don't forget to deallocate the bitmap
bitmap.recycle();
}
So eventually in the render method, I want to be able to render different coordinates on the texture map to the same vertices. So I call glTexCoordPointer and change the offset to "counter" where counter should have been 6*4 (6 vertices times 4 bytes per float) but that doesn't work, so I tried counter at 0 and incremented it and never found the magical number that will map the red button. On a side note, when I tried that, I would get very weird patterns drawn, sometimes showing 10 to 15 mini blue and red circles.
if(isdown)
gl.glTexCoordPointer(2,GL10.GL_FLOAT,counter,textureBuffer);
else
gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,textureBuffer);