0

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

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 并将偏移量更改为“计数器”,其中计数器应该是 6*4(每个浮点数 6 个顶点乘以 4 个字节)但这不起作用,所以我尝试将计数器设置为 0 并将其递增,但从未发现神奇将映射红色按钮的数字。顺便说一句,当我尝试这样做时,我会画出非常奇怪的图案,有时会显示 10 到 15 个迷你蓝色和红色圆圈。

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

1 回答 1

0

@Harism 对我的情况是正确的。我希望我仍然正确使用它。我在想步幅变量可以改变,但我不得不改变缓冲区的位置。这适用于 3D 表面上的纹理动画。我不知道这是否是“最好”的方法,但在那之前我会使用它。

于 2012-12-10T11:15:11.307 回答