OpenGL ES(3) - 绘制形状

初始化形状

在绘制前,你必须初始化和加载形状。除非形状的构造在运行中会改变,不然你应该在onSurfaceCreated()方法中初始化它们。
<span class="kwd" style="color: rgb(0, 0, 136);">public</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> onSurfaceCreated</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">GL10 unused</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">EGLConfig</span><span class="pln" style="color: rgb(0, 0, 0);"> config</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">...</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// initialize a triangle</span><span class="pln" style="color: rgb(0, 0, 0);">
    mTriangle </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Triangle</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">// initialize a square</span><span class="pln" style="color: rgb(0, 0, 0);">
    mSquare </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Square</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
绘制形状

绘制前你需要做下面这些定义:
  • 顶点着色器 - OpenGL ES图形代码通过顶点渲染一个形状。
  • 碎片着色器 - 绘制形状表面的颜色或者纹理。
  • 工程 - 包含使用的着色器。
你至少需要一个顶点着色器和一个碎片着色器。它们必须被编译然后添加到一个OpenGL ES工程中:
<span class="kwd" style="color: rgb(0, 0, 136);">private</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">final</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">String</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexShaderCode </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"attribute vec4 vPosition;"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"void main() {"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"  gl_Position = vPosition;"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"}"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">private</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">final</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">String</span><span class="pln" style="color: rgb(0, 0, 0);"> fragmentShaderCode </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"precision mediump float;"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"uniform vec4 vColor;"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"void main() {"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"  gl_FragColor = vColor;"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="str" style="color: rgb(0, 136, 0);">"}"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span>
着色器包含GLSL代码,需要在OpenGL ES环境下编译:
<span class="kwd" style="color: rgb(0, 0, 136);">public</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">static</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> loadShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> type</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">String</span><span class="pln" style="color: rgb(0, 0, 0);"> shaderCode</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// create a vertex shader type (GLES20.GL_VERTEX_SHADER)</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> shader </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glCreateShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">type</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// add the source code to the shader and compile it</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glShaderSource</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">shader</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> shaderCode</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glCompileShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">shader</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> shader</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
一般在构造函数中完成编译和连接到工程:
<span class="kwd" style="color: rgb(0, 0, 136);">public</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Triangle</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">...</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexShader </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> loadShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">GL_VERTEX_SHADER</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexShaderCode</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> fragmentShader </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> loadShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">GL_FRAGMENT_SHADER</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> fragmentShaderCode</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    mProgram </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glCreateProgram</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">             </span><span class="com" style="color: rgb(136, 0, 0);">// create empty OpenGL ES Program</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glAttachShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexShader</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">   </span><span class="com" style="color: rgb(136, 0, 0);">// add the vertex shader to program</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glAttachShader</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> fragmentShader</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// add the fragment shader to program</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glLinkProgram</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">                  </span><span class="com" style="color: rgb(136, 0, 0);">// creates OpenGL ES program executables</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
创建一个draw()方法来绘制形状。代码设置了位置和颜色值给顶点着色器和碎片着色器使用,然后执行绘制功能:
<span class="kwd" style="color: rgb(0, 0, 136);">public</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">void</span><span class="pln" style="color: rgb(0, 0, 0);"> draw</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">// Add program to OpenGL ES environment</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glUseProgram</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// get handle to vertex shader's vPosition member</span><span class="pln" style="color: rgb(0, 0, 0);">
    mPositionHandle </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glGetAttribLocation</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"vPosition"</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// Enable a handle to the triangle vertices</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glEnableVertexAttribArray</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mPositionHandle</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// Prepare the triangle coordinate data</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glVertexAttribPointer</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mPositionHandle</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> COORDS_PER_VERTEX</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
                                 GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">GL_FLOAT</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">false</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
                                 vertexStride</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexBuffer</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// get handle to fragment shader's vColor member</span><span class="pln" style="color: rgb(0, 0, 0);">
    mColorHandle </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glGetUniformLocation</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mProgram</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"vColor"</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// Set color for drawing the triangle</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glUniform4fv</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mColorHandle</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> color</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// Draw the triangle</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glDrawArrays</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">GL_TRIANGLES</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> vertexCount</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">// Disable vertex array</span><span class="pln" style="color: rgb(0, 0, 0);">
    GLES20</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">glDisableVertexAttribArray</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mPositionHandle</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span>
完成这些后,在renderer的onDrawFrame()方法中调用draw()方法,运行效果如下:

上面的实例代码还有一些问题,第一,不能给别人留下深刻的印象。第二,旋转屏幕的时候,三角形被压扁了。原因是顶点坐标没有根据屏幕区域进行调整。下面章节会使用投射和摄像视图来解决这个问题。

猜你喜欢

转载自blog.csdn.net/lutherluov/article/details/52637424