Android纹理只显示纯色

时间:2013-01-04 14:02:33

标签: android opengl-es textures

我试图在四边形上显示单个纹理。 我有一个工作的VertexObject,它画了一个正方形(或任何几何对象)。现在我尝试扩展它以处理纹理,并且纹理不起作用。我只看到一个纯色的四边形。

坐标数据位于arrayList:

/*the vertices' coordinates*/
public int              coordCount = 0;
/*float array of 3(x,y,z)*/
public ArrayList<Float>     coordList = new ArrayList<Float>(coordCount);

/*the coordinates' indexes(if used)*/
/*maximum limit:32767*/
private int                  orderCount = 0;
private ArrayList<Short>     orderList = new ArrayList<Short>(orderCount);

/*textures*/
public boolean textured;
private boolean textureIsReady;
private ArrayList<Float>    textureList = new ArrayList<Float>(coordCount);
private Bitmap bitmap; //the image to be displayed
private int textures[]; //the textures' ids

缓冲区在以下函数中初始化:

/*Drawing is based on the buffers*/
public void refreshBuffers(){
    /*Coordinates' List*/
    float coords[] = new float[coordList.size()];
    for(int i=0;i<coordList.size();i++){
         coords[i]= coordList.get(i);
    }
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            coords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(coords);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);

    /*Index List*/
    short order[] = new short[(short)orderList.size()];
    for(int i=0;i<order.length;i++){
        order[i] = (short) orderList.get(i);
    }
    // initialize byte buffer for the draw list
    ByteBuffer dlb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 2 bytes per short)
            order.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    orderBuffer = dlb.asShortBuffer();
    orderBuffer.put(order);
    orderBuffer.position(0);

    /*texture list*/
    if(textured){
        float textureCoords[] = new float[textureList.size()];
        for(int i=0;i<textureList.size();i++){
            textureCoords[i] = textureList.get(i);
        }
        ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoords.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        textureBuffer = byteBuf.asFloatBuffer();
        textureBuffer.put(textureCoords);
        textureBuffer.position(0);
    }
}

我使用以下代码将图像加载到对象中:

public void initTexture(GL10 gl, Bitmap inBitmap){
    bitmap = inBitmap;
    loadTexture(gl);
    textureIsReady = true;
}

/*http://www.jayway.com/2010/12/30/opengl-es-tutorial-for-android-part-vi-textures/*/
public void loadTexture(GL10 gl){

    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    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);

    /*bind bitmap to texture*/
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}

根据以下代码进行绘图:

public void draw(GL10 gl){
    if(textured && textureIsReady){
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        //loadTexture(gl);
        gl.glEnable(GL10.GL_TEXTURE_2D);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
                vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 
                textureBuffer);
    }else{
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glColor4f(color[0], color[1], color[2], color[3]);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
                vertexBuffer);
    }
        if(!indexed)gl.glDrawArrays(drawMode, 0, coordCount);
            else gl.glDrawElements(drawMode, orderCount, GL10.GL_UNSIGNED_SHORT, orderBuffer);


    if(textured && textureIsReady){
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisable(GL10.GL_TEXTURE_2D);
    }else{
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

初始化如下:

    pic = new VertexObject();
    pic.indexed = true;
    pic.textured = true;

    pic.initTexture(gl,MainActivity.bp);

    pic.color[0] = 0.0f;
    pic.color[1] = 0.0f;
    pic.color[2] = 0.0f;

    float inputVertex[] = {2.0f,2.0f,0.0f};
    float inputTexture[] = {0.0f,0.0f};
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 2.0f;
    inputVertex[1] = 8.0f;
    inputTexture[0] = 0.0f;
    inputTexture[0] = 1.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 8.0f;
    inputVertex[1] = 8.0f;
    inputTexture[0] = 1.0f;
    inputTexture[0] = 1.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);
    inputVertex[0] = 8.0f;
    inputVertex[1] = 2.0f;
    inputTexture[0] = 1.0f;
    inputTexture[0] = 0.0f;
    pic.addTexturedVertex(inputVertex,inputTexture);

    pic.addIndex((short)0);
    pic.addIndex((short)1);
    pic.addIndex((short)2);
    pic.addIndex((short)0);
    pic.addIndex((short)2);
    pic.addIndex((short)3);

将坐标简单地添加到arrayList中,然后刷新缓冲区。 位图有效,因为它显示在imageView上。 该图像是可绘制文件夹中大小为128x128的png文件。 对于我收集的内容,图像将转到vertexObject,但是纹理映射不正确。关于我做错了什么的指示?

1 个答案:

答案 0 :(得分:0)

好的,我明白了!

我从互联网上下载了working example并重写了它,以便逐步类似于对象(如上所示)。我观察它是否适用于每一步。事实证明,问题不在于图形部分,因为该对象在具有不同坐标的另一个上下文中工作。长话短说:


我的纹理UV贴图错误了!


这就是为什么我得到纯色,纹理被加载,但UV贴图不正确。