【问题标题】:OpenGL ES 2.0 Android drawing textured trianglesOpenGL ES 2.0 Android 绘制带纹理的三角形
【发布时间】:2020-01-29 14:59:22
【问题描述】:

我有《OpenGL ES 2 for Android A Quick-Start Guide》一书,它正在阅读关于 OpenGL 和 android 的一个很好的教程。我遇到的问题是它的示例不使用索引缓冲区来创建它们的形状。

我正在尝试对一个正方形进行纹理处理,我定义了正方形的 4 个顶点(加上纹理的 S 坐标和 T 坐标),然后使用索引缓冲区进行渲染。但是,正方形的颜色只是 PNG 纹理文件的左下角,并且在我的正方形上没有正确渲染。

这是我的渲染函数:

 public void onDrawFrame(float[] matrixViewProjection)
    {
        super.onDrawFrame(matrixViewProjection);

        GLES20.glUseProgram(this.shaderProgram);
        int posHandle = GLES20.glGetAttribLocation(shaderProgram,"vPosition");
        GLES20.glEnableVertexAttribArray(posHandle);

        GLES20.glVertexAttribPointer(posHandle,coordsPerVertex,GLES20.GL_FLOAT,false,vertexStride,vertexBuffer);

        int colHandle = GLES20.glGetUniformLocation(shaderProgram,"vColor");
        GLES20.glUniform4fv(colHandle,1,color,0);

        int mvpHandle = GLES20.glGetUniformLocation(shaderProgram,"uMVPMatrix");
        GLES20.glUniformMatrix4fv(mvpHandle,1,false,matrixSum,0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES,indexBufferCount,GLES20.GL_UNSIGNED_SHORT,drawListBuffer);
        GLES20.glDisableVertexAttribArray(posHandle);
    }

这是我的方形对象的构造函数:

 public ShapeSquare(Context context, int program, float size)
    {
        float squareCoords[] = {
                -(size/2.0f),-(size/2.0f),0f, 0f, 0f,
                -(size/2.0f), (size/2.0f),0f, 0f, 1f,
                 (size/2.0f), (size/2.0f),0f, 1f, 1f,
                 (size/2.0f),-(size/2.0f),0f, 0f, 0f
        };

        short drawOrder[] = {0,1,3,1,2,3};

        indexBufferCount = drawOrder.length;

        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length*4);
        bb.order(ByteOrder.nativeOrder());

        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);

        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length*2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);

        shaderProgram = program;

        shaderProgram = program;

        textureID = TextureHelper.loadTexture(context, R.raw.texture1);
    }

这些是我的一些定义,虽然我不知道它们是否正确

    protected static int coordsPerVertex = 3;
    protected int vertexCount = 12/coordsPerVertex;
    protected static final int vertexStride = coordsPerVertex*4+8;

这是渲染的...

这就是我拥有的纹理。 (注意左下角)

【问题讨论】:

    标签: android opengl-es glsl opengl-es-2.0


    【解决方案1】:

    您必须指定 2 个顶点属性数据数组 (glVertexAttribPointer)。 1 表示顶点坐标,1 表示纹理坐标:

    int posHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
    int texHandle = GLES20.glGetAttribLocation(shaderProgram, ???);
    
    GLES20.glEnableVertexAttribArray(posHandle);
    GLES20.glEnableVertexAttribArray(texHandle );
    
    vertexBuffer.position(0);       
    GLES20.glVertexAttribPointer(posHandle, coordsPerVertex, GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);
    
    vertexBuffer.position(3);        
    GLES20.glVertexAttribPointer(texHandle, coordsPerVertex, GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);
    

    注意vertexBuffer 包含 5 个元素(x、y、z、u、v)的元组。以字节为单位的步幅为 5*4。顶点坐标的偏移量为0,纹理坐标的偏移量为3*4,分别是浮动缓冲区中的3个元素。

    由于您不使用Vertex Buffer Objects,您应该更愿意为属性创建单独的数组(分别为浮点缓冲区)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      相关资源
      最近更新 更多