Android OpenGL中带有TextureBuffer指针的按钮类

Android OpenGL中带有TextureBuffer指针的按钮类,android,opengl-es,textures,uv-mapping,Android,Opengl Es,Textures,Uv Mapping,我正在创建一个button类,如果它没有被按下,它将显示一个蓝色的圆圈,如果它被按下,它将显示一个红色的圆圈。我首先构建一个由两个三角形组成的4顶点四边形。我生成自己的位图,并在位图上从左到右相邻地画两个圆。然后我用4个uv点创建一个纹理缓冲区,我用8个uv点创建它,一个映射出蓝色圆圈,一个映射出红色圆圈。然后我想在按下按钮时渲染红色圆圈。理想情况下,我想打电话给 gl.glTexCoordPointer 方法并传入偏移量,但该偏移量无效。这是我用来生成位图的方法,使用画布和绘制对象在位图上绘

我正在创建一个button类,如果它没有被按下,它将显示一个蓝色的圆圈,如果它被按下,它将显示一个红色的圆圈。我首先构建一个由两个三角形组成的4顶点四边形。我生成自己的位图,并在位图上从左到右相邻地画两个圆。然后我用4个uv点创建一个纹理缓冲区,我用8个uv点创建它,一个映射出蓝色圆圈,一个映射出红色圆圈。然后我想在按下按钮时渲染红色圆圈。理想情况下,我想打电话给

gl.glTexCoordPointer
方法并传入偏移量,但该偏移量无效。这是我用来生成位图的方法,使用画布和绘制对象在位图上绘制,然后尝试映射纹理。请注意,我必须生成一个2的幂的纹理,因此其中有一些数学,允许我根据构造函数中指定的按钮的宽度和高度变量生成比我需要的更大的位图

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();
}
因此,最终在渲染方法中,我希望能够将纹理贴图上的不同坐标渲染到相同的顶点。所以我调用glTexCoordPointer并将偏移量更改为“counter”,其中counter应该是6*4(6个顶点乘以每个浮点4个字节),但这不起作用,所以我尝试将counter设置为0并将其递增,但从未找到映射红色按钮的神奇数字。另一方面,当我试着这样做时,我会画出非常奇怪的图案,有时会画出10到15个蓝色和红色的小圆圈

    if(isdown)
        gl.glTexCoordPointer(2,GL10.GL_FLOAT,counter,textureBuffer);
    else
        gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,textureBuffer);

@哈里斯主义适合我的情况。我希望我仍然正确地使用这个。我认为步幅变量可以更改,但我必须更改缓冲区的位置。这适用于在3D曲面上设置纹理动画。我不知道这是否是最好的方法,但在此之前我将使用它。

gl.glTexCoordPointer(…)
第三个参数是元素之间的跨距,而不是精确的偏移量。如果您想要偏移量,可以在调用
glTexCoordPointer
之前调用
textureBuffer.position(startPosition)
@哈里斯天才!真管用!当按钮按下时,我将位置改为8,一切正常!更改缓冲区的位置是否会影响性能?(不是抄袭什么的?)还有,如果你不介意回答这个问题,我投票并接受它!