使用OpenGL ES着色和纹理化3d形状

时间:2014-09-18 11:33:56

标签: android opengl-es

我正在尝试为Android学习一些OpenGL ES,完全是为了好玩。图形编程对我来说很新鲜,如果这是一个愚蠢的问题,那就很抱歉。

我已经阅读了一些示例和教程,可以创建形状,使用触摸事件移动相机等。按照Google的教程,我修改它以制作一些3d形状。到目前为止,我对这一切感到满意。

目前我的形状在各个方面都有相同的颜色,我不清楚我是如何使用我当时得到的代码分别对它们进行着色/纹理化的(我刚刚通过实验在Google教程上构建)基本上)。

我看到的所有其他示例都使用glDrawArrays而不是glDrawElements。以这种方式定义一个形状似乎很笨拙,但是你有一组独特的顶点,这使得着色(和法线)看起来更加明显。

我的立方体的绘制方法如下所示,你可以看到我在哪里。我是否必须以不同的方式进一步推进?如果是这样,那是否会使glDrawElements的用处更少?

public void draw(float[] mvpMatrix) {
    // Add program to OpenGL environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the cube coordinate data
    GLES20.glVertexAttribPointer(
            mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the Cube
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the cube, tell it that vertices describe triangles
    GLES20.glDrawElements(
            GLES20.GL_TRIANGLES, drawOrder.length,
            GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}

1 个答案:

答案 0 :(得分:2)

要为形状的某个部分着色,您需要定义每个顶点的颜色。在您的情况下,这意味着您需要vPosition旁边的另一个属性来表示颜色。在着色器中,您需要添加此新属性并添加变量向量以将颜色传递给片段着色器。但顶点着色器中不需要转换。另外,不要忘记启用颜色属性数组并设置指针...

首先尝试这样做,并为每个顶点指定不同的颜色以查看发生的情况。

如果您将正确执行此操作,您将看到立方体的每个面现在都具有渐变颜色,并且只有立方体的角具有您指定的确切颜色。这是由于插值,你可以做很多事情来解决这个问题,但不同地创建顶点缓冲区:

因此,这是绘图数组或元素之间的区别。通过使用元素,您有一个索引缓冲区,通过重用相同的顶点来降低实际的顶点缓冲区大小。但是对于带有彩色面的立方体,这些顶点不能再共享,因为它们不相同。如果你想要一个有6种不同颜色的立方体,每个颜色代表一个面,你可以看到每个顶点(角)实际上包含3种不同的颜色,每个面都有一种颜色。所以包含位置和颜色的顶点必须具有相同的位置和颜色才能实际相同......

所以在这里必须要做的是你需要创建不是8个但是3 * 8的顶点和索引来绘制这样的立方体。在您这样做之后,您可以看到索引和使用的顶点的数量是相同的,因此您无法通过使用元素获得任何东西(但如果您愿意,您仍然可以),因此更容易简单地绘制数组。

对于法线或纹理坐标,立方体上会出现同样的情况,您只需要制作8 * 3个顶点。

请注意,立方体只是您需要执行此操作的不友好形状之一。如果您更喜欢绘制具有大量三角形的球体,则不需要对顶点计数进行膨胀以进行漂亮的纹理或照明(使用法线)。实际上,将球体顶点计数增加三倍并执行与立方体相同的步骤会使形状看起来更糟。

我建议你尝试使用这种形状,法线,颜色,纹理,你将从自己的经验中学到很多东西。