返回

Android OpenGl Es 学习(八):构建简单物体

Android

前言

本系列文章将从零开始学习OpenGl Es,本文是系列的第八篇,主要讲解如何构建简单的3D物体。

构建简单物体

顶点数据

在OpenGL ES中,一个顶点是由一个三维坐标和一个法向量组成的。我们可以使用一个顶点数组来存储多个顶点。

float vertices[] = {
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
     0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
    -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
    -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
};

索引数据

索引数据用于告诉OpenGL ES如何将顶点数据组合成三角形。我们可以使用一个索引数组来存储索引数据。

short indices[] = {
    0, 1, 2,
    3, 4, 5,
    6, 7, 8,
    9, 10, 11,
    12, 13, 14,
    15, 16, 17,
    18, 19, 20,
    21, 22, 23,
    24, 25, 26,
    27, 28, 29,
    30, 31, 32,
    33, 34, 35
};

着色器程序

着色器程序用于告诉OpenGL ES如何处理顶点数据和索引数据。我们可以使用一个顶点着色器和一个片段着色器来创建着色器程序。

String vertexShaderCode =
    "uniform mat4 uMVPMatrix;" +
    "attribute vec4 aPosition;" +
    "attribute vec3 aNormal;" +
    "varying vec3 vNormal;" +
    "void main() {" +
    "  vNormal = aNormal;" +
    "  gl_Position = uMVPMatrix * aPosition;" +
    "}";

String fragmentShaderCode =
    "precision mediump float;" +
    "uniform vec3 uLightPosition;" +
    "uniform vec3 uColor;" +
    "varying vec3 vNormal;" +
    "void main() {" +
    "  vec3 lightVector = normalize(uLightPosition - gl_FragCoord.xyz);" +
    "  float diffuse = max(dot(vNormal, lightVector), 0.0);" +
    "  gl_FragColor = vec4(uColor * diffuse, 1.0);" +
    "}";

渲染

为了渲染一个物体,我们需要执行以下步骤:

  1. 启用顶点属性数组。
  2. 设置顶点属性数组的指针。
  3. 设置Uniform变量。
  4. 绘制物体。
// 启用顶点属性数组
glEnableVertexAttribArray(aPositionHandle);
glEnableVertexAttribArray(aNormal