zoukankan      html  css  js  c++  java
  • Android OpenGL ES 2.0 (一) 画三角形

    看Opengl es的相关知识也有几天了。开始动手跟着例子写代码了。现在就先写个最简单的,画个三角形吧,里面包含了最基本的vertex shader和fragment shader的用法.

    Activity里设置opengl es版本为2.0,如果没设,会默认用1.0,然后运行会报API未实现exception.

    TestActivity.java

     1 package com.android.jayce.test;
     2 
     3 import android.app.Activity;
     4 import android.app.ActivityManager;
     5 import android.content.Context;
     6 import android.content.pm.ConfigurationInfo;
     7 import android.opengl.GLSurfaceView;
     8 import android.opengl.GLSurfaceView.Renderer;
     9 import android.os.Bundle;
    10 
    11 public class TestActivity extends Activity
    12 {
    13     private GLSurfaceView mGLSurfaceView;
    14     
    15     public void onCreate(Bundle savedInstanceState)
    16     {
    17         super.onCreate(savedInstanceState);
    18         mGLSurfaceView = new GLSurfaceView(this);
    19         final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
    20         final ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
    21         if(configInfo.reqGlEsVersion >= 0x20000)
    22         {
    23             mGLSurfaceView.setEGLContextClientVersion(2);
    24             Renderer renderer = new TestRenderer();
    25             mGLSurfaceView.setRenderer(renderer);
    26         }
    27         
    28         setContentView(mGLSurfaceView);
    29     }
    30     
    31     @Override
    32     protected void onResume() 
    33     {
    34         // The activity must call the GL surface view's onResume() on activity onResume().
    35         super.onResume();
    36         mGLSurfaceView.onResume();
    37     }
    38 
    39     @Override
    40     protected void onPause() 
    41     {
    42         // The activity must call the GL surface view's onPause() on activity onPause().
    43         super.onPause();
    44         mGLSurfaceView.onPause();
    45     }    
    46 }

    然后是Renderer的实现,参数很少,只有点坐标,颜色

    TestRenderer.java

      1 package com.android.jayce.test;
      2 
      3 import java.nio.ByteBuffer;
      4 import java.nio.ByteOrder;
      5 import java.nio.FloatBuffer;
      6 
      7 import javax.microedition.khronos.egl.EGLConfig;
      8 import javax.microedition.khronos.opengles.GL10;
      9 
     10 import android.opengl.GLES20;
     11 import android.opengl.Matrix;
     12 import android.opengl.GLSurfaceView;
     13 
     14 
     15 public class TestRenderer implements GLSurfaceView.Renderer
     16 {
     17 
     18     private final FloatBuffer mTriangle1Vertices;
     19     private static final int BYTES_PER_FLOAT = 4;
     20     private float[] mMVPMatrix = new float[16];
     21     private float[] mViewMatrix = new float[16];
     22     private float[] mModelMatrix = new float[16];
     23     private float[] mProjectionMatrix = new float[16];
     24     private int mMVPMatrixHandle;
     25     private int mPositionHandle;
     26     private int mColorHandle;
     27     private final int POSITION_OFFSET = 0;
     28     private final int COLOR_OFFSET = 3;
     29     private final int POSITION_DATA_SIZE = 3;
     30     private final int COLOR_DATA_SIZE = 4;
     31     private final int STRIDE = 7 * BYTES_PER_FLOAT;
     32     
     33     public TestRenderer()
     34     {
     35         final float[] triangle1VerticesData = {
     36                 // X, Y, Z, 
     37                 // R, G, B, A
     38                 -0.5f, -0.25f, 0.0f, 
     39                 1.0f, 0.0f, 0.0f, 1.0f,
     40                 
     41                 0.5f, -0.25f, 0.0f,
     42                 0.0f, 0.0f, 1.0f, 1.0f,
     43                 
     44                 0.0f, 0.559016994f, 0.0f, 
     45                 0.0f, 1.0f, 0.0f, 1.0f};
     46         
     47         mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * BYTES_PER_FLOAT)
     48                 .order(ByteOrder.nativeOrder()).asFloatBuffer();
     49         mTriangle1Vertices.put(triangle1VerticesData).position(0);
     50     }
     51     
     52     @Override
     53     public void onDrawFrame(GL10 gl) {
     54         // TODO Auto-generated method stub
     55         GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
     56         
     57         Matrix.setIdentityM(mModelMatrix, 0);
     58         drawTriandle(mTriangle1Vertices);
     59     }
     60 
     61     private void drawTriandle(final FloatBuffer triangleBuffer)
     62     {
     63         triangleBuffer.position(POSITION_OFFSET);
     64         GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, STRIDE, triangleBuffer);
     65         GLES20.glEnableVertexAttribArray(mPositionHandle);
     66         
     67         triangleBuffer.position(COLOR_OFFSET);
     68         GLES20.glVertexAttribPointer(mColorHandle, COLOR_DATA_SIZE, GLES20.GL_FLOAT, false, STRIDE, triangleBuffer);
     69         GLES20.glEnableVertexAttribArray(mColorHandle);
     70         
     71         Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
     72         Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
     73         
     74         GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
     75         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
     76     }
     77     
     78     @Override
     79     public void onSurfaceChanged(GL10 gl, int width, int height) {
     80         // TODO Auto-generated method stub
     81         GLES20.glViewport(0, 0, width, height);
     82         
     83         final float ratio = (float) width / height;
     84         final float left = -ratio;
     85         final float right = ratio;
     86         final float bottom = -1.0f;
     87         final float top = 1.0f;
     88         final float near = 1.0f;
     89         final float far = 10.0f;
     90         
     91         Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
     92     }
     93 
     94     @Override
     95     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     96         // TODO Auto-generated method stub
     97         GLES20.glClearColor(0f, 0f, 0f, 1f);
     98         
     99         // Position the eye behind the origin.
    100         final float eyeX = 0.0f;
    101         final float eyeY = 0.0f;
    102         final float eyeZ = 1.5f;
    103 
    104         // We are looking toward the distance
    105         final float lookX = 0.0f;
    106         final float lookY = 0.0f;
    107         final float lookZ = -5.0f;
    108 
    109         // Set our up vector. This is where our head would be pointing were we holding the camera.
    110         final float upX = 0.0f;
    111         final float upY = 1.0f;
    112         final float upZ = 0.0f;
    113 
    114         // Set the view matrix. This matrix can be said to represent the camera position.
    115         // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
    116         // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
    117         Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
    118         
    119         final String vertexShader =
    120                 "uniform mat4 u_MVPMatrix;      \n"        // A constant representing the combined model/view/projection matrix.
    121                 
    122               + "attribute vec4 a_Position;     \n"        // Per-vertex position information we will pass in.
    123               + "attribute vec4 a_Color;        \n"        // Per-vertex color information we will pass in.              
    124               
    125               + "varying vec4 v_Color;          \n"        // This will be passed into the fragment shader.
    126               
    127               + "void main()                    \n"        // The entry point for our vertex shader.
    128               + "{                              \n"
    129               + "   v_Color = a_Color;          \n"        // Pass the color through to the fragment shader. 
    130                                                           // It will be interpolated across the triangle.
    131               + "   gl_Position = u_MVPMatrix   \n"     // gl_Position is a special variable used to store the final position.
    132               + "               * a_Position;   \n"     // Multiply the vertex by the matrix to get the final point in                                                                      
    133               + "}                              \n";    // normalized screen coordinates.
    134             
    135         final String fragmentShader =
    136                 "precision mediump float;       \n"        // Set the default precision to medium. We don't need as high of a 
    137                                                         // precision in the fragment shader.                
    138               + "varying vec4 v_Color;          \n"        // This is the color from the vertex shader interpolated across the 
    139                                                           // triangle per fragment.              
    140               + "void main()                    \n"        // The entry point for our fragment shader.
    141               + "{                              \n"
    142               + "   gl_FragColor = v_Color;     \n"        // Pass the color directly through the pipeline.          
    143               + "}                              \n";    
    144             
    145         int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    146         if(vertexShaderHandle != 0)
    147         {
    148             GLES20.glShaderSource(vertexShaderHandle, vertexShader);
    149             GLES20.glCompileShader(vertexShaderHandle);
    150             
    151             final int[] compileStatus = new int[1];
    152             GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
    153             
    154             if(compileStatus[0] == 0)
    155             {
    156                 GLES20.glDeleteShader(vertexShaderHandle);
    157                 vertexShaderHandle = 0;
    158             }
    159         }
    160         
    161         if(vertexShaderHandle == 0)
    162         {
    163             throw new RuntimeException("failed to creating vertex shader");
    164         }
    165         
    166         int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    167         if(fragmentShaderHandle != 0)
    168         {
    169             GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
    170             GLES20.glCompileShader(fragmentShaderHandle);
    171             
    172             final int[] compileStatus = new int[1];
    173             GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
    174             
    175             if(compileStatus[0] == 0)
    176             {
    177                 GLES20.glDeleteShader(fragmentShaderHandle);
    178                 fragmentShaderHandle = 0;
    179             }
    180             
    181         }
    182         
    183         if(fragmentShaderHandle == 0)
    184         {
    185             throw new RuntimeException("failed to create fragment shader");
    186         }
    187         
    188         int programHandle = GLES20.glCreateProgram();
    189         if(programHandle != 0)
    190         {
    191             GLES20.glAttachShader(programHandle, vertexShaderHandle);
    192             GLES20.glAttachShader(programHandle, fragmentShaderHandle);
    193             
    194             GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
    195             GLES20.glBindAttribLocation(programHandle, 1, "a_Color");
    196             
    197             GLES20.glLinkProgram(programHandle);
    198             
    199             final int[] linkStatus = new int[1];
    200             GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
    201             
    202             if(linkStatus[0] == 0)
    203             {
    204                 GLES20.glDeleteProgram(programHandle);
    205                 programHandle = 0;
    206             }
    207         }
    208         
    209         if(programHandle == 0)
    210         {
    211             throw new RuntimeException("failed to create program");
    212         }
    213         
    214         mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");
    215         mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
    216         mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");
    217         
    218         GLES20.glUseProgram(programHandle);
    219     }
    220 
    221     
    222     
    223 }

    最后附上效果图:

  • 相关阅读:
    VirtualBox4.3.12 安装ubuntu 14.04 分辨率过小(600*480)问题的解决方法
    asp.net 权限管理系统
    rdlc 格式设置
    Could not load file or assembly 'Microsoft.ReportViewer.Common, Version=11.0.0.0 异常处理
    Asp.Net Web Forms/MVC/Console App中使用Autofac
    Mysql优化小记1
    Zyan 一个通信框架
    RDLC
    通过.NET客户端异步调用Web API(C#)
    ECharts问题--散点图中对散点添加点击事件
  • 原文地址:https://www.cnblogs.com/jayceli/p/2473203.html
Copyright © 2011-2022 走看看