Android OpenGL ES 2.0 (一) 画三角形
2012-04-27 11:21
363 查看
看Opengl es的相关知识也有几天了。开始动手跟着例子写代码了。现在就先写个最简单的,画个三角形吧,里面包含了最基本的vertex shader和fragment shader的用法.
Activity里设置opengl es版本为2.0,如果没设,会默认用1.0,然后运行会报API未实现exception.
TestActivity.java
然后是Renderer的实现,参数很少,只有点坐标,颜色
TestRenderer.java
最后附上效果图:
Activity里设置opengl es版本为2.0,如果没设,会默认用1.0,然后运行会报API未实现exception.
TestActivity.java
package com.android.jayce.test; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ConfigurationInfo; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.os.Bundle; public class TestActivity extends Activity { private GLSurfaceView mGLSurfaceView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView = new GLSurfaceView(this); final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo(); if(configInfo.reqGlEsVersion >= 0x20000) { mGLSurfaceView.setEGLContextClientVersion(2); Renderer renderer = new TestRenderer(); mGLSurfaceView.setRenderer(renderer); } setContentView(mGLSurfaceView); } @Override protected void onResume() { // The activity must call the GL surface view's onResume() on activity onResume(). super.onResume(); mGLSurfaceView.onResume(); } @Override protected void onPause() { // The activity must call the GL surface view's onPause() on activity onPause(). super.onPause(); mGLSurfaceView.onPause(); } }
然后是Renderer的实现,参数很少,只有点坐标,颜色
TestRenderer.java
package com.android.jayce.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLES20; import android.opengl.Matrix; import android.opengl.GLSurfaceView; public class TestRenderer implements GLSurfaceView.Renderer { private final FloatBuffer mTriangle1Vertices; private static final int BYTES_PER_FLOAT = 4; private float[] mMVPMatrix = new float[16]; private float[] mViewMatrix = new float[16]; private float[] mModelMatrix = new float[16]; private float[] mProjectionMatrix = new float[16]; private int mMVPMatrixHandle; private int mPositionHandle; private int mColorHandle; private final int POSITION_OFFSET = 0; private final int COLOR_OFFSET = 3; private final int POSITION_DATA_SIZE = 3; private final int COLOR_DATA_SIZE = 4; private final int STRIDE = 7 * BYTES_PER_FLOAT; public TestRenderer() { final float[] triangle1VerticesData = { // X, Y, Z, // R, G, B, A -0.5f, -0.25f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.25f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.559016994f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}; mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()).asFloatBuffer(); mTriangle1Vertices.put(triangle1VerticesData).position(0); } @Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); Matrix.setIdentityM(mModelMatrix, 0); drawTriandle(mTriangle1Vertices); } private void drawTriandle(final FloatBuffer triangleBuffer) { triangleBuffer.position(POSITION_OFFSET); GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, STRIDE, triangleBuffer); GLES20.glEnableVertexAttribArray(mPositionHandle); triangleBuffer.position(COLOR_OFFSET); GLES20.glVertexAttribPointer(mColorHandle, COLOR_DATA_SIZE, GLES20.GL_FLOAT, false, STRIDE, triangleBuffer); GLES20.glEnableVertexAttribArray(mColorHandle); Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub GLES20.glViewport(0, 0, width, height); final float ratio = (float) width / height; final float left = -ratio; final float right = ratio; final float bottom = -1.0f; final float top = 1.0f; final float near = 1.0f; final float far = 10.0f; Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub GLES20.glClearColor(0f, 0f, 0f, 1f); // Position the eye behind the origin. final float eyeX = 0.0f; final float eyeY = 0.0f; final float eyeZ = 1.5f; // We are looking toward the distance final float lookX = 0.0f; final float lookY = 0.0f; final float lookZ = -5.0f; // Set our up vector. This is where our head would be pointing were we holding the camera. final float upX = 0.0f; final float upY = 1.0f; final float upZ = 0.0f; // Set the view matrix. This matrix can be said to represent the camera position. // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose. Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); final String vertexShader = "uniform mat4 u_MVPMatrix; \n" // A constant representing the combined model/view/projection matrix. + "attribute vec4 a_Position; \n" // Per-vertex position information we will pass in. + "attribute vec4 a_Color; \n" // Per-vertex color information we will pass in. + "varying vec4 v_Color; \n" // This will be passed into the fragment shader. + "void main() \n" // The entry point for our vertex shader. + "{ \n" + " v_Color = a_Color; \n" // Pass the color through to the fragment shader. // It will be interpolated across the triangle. + " gl_Position = u_MVPMatrix \n" // gl_Position is a special variable used to store the final position. + " * a_Position; \n" // Multiply the vertex by the matrix to get the final point in + "} \n"; // normalized screen coordinates. final String fragmentShader = "precision mediump float; \n" // Set the default precision to medium. We don't need as high of a // precision in the fragment shader. + "varying vec4 v_Color; \n" // This is the color from the vertex shader interpolated across the // triangle per fragment. + "void main() \n" // The entry point for our fragment shader. + "{ \n" + " gl_FragColor = v_Color; \n" // Pass the color directly through the pipeline. + "} \n"; int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); if(vertexShaderHandle != 0) { GLES20.glShaderSource(vertexShaderHandle, vertexShader); GLES20.glCompileShader(vertexShaderHandle); final int[] compileStatus = new int[1]; GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0); if(compileStatus[0] == 0) { GLES20.glDeleteShader(vertexShaderHandle); vertexShaderHandle = 0; } } if(vertexShaderHandle == 0) { throw new RuntimeException("failed to creating vertex shader"); } int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); if(fragmentShaderHandle != 0) { GLES20.glShaderSource(fragmentShaderHandle, fragmentShader); GLES20.glCompileShader(fragmentShaderHandle); final int[] compileStatus = new int[1]; GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0); if(compileStatus[0] == 0) { GLES20.glDeleteShader(fragmentShaderHandle); fragmentShaderHandle = 0; } } if(fragmentShaderHandle == 0) { throw new RuntimeException("failed to create fragment shader"); } int programHandle = GLES20.glCreateProgram(); if(programHandle != 0) { GLES20.glAttachShader(programHandle, vertexShaderHandle); GLES20.glAttachShader(programHandle, fragmentShaderHandle); GLES20.glBindAttribLocation(programHandle, 0, "a_Position"); GLES20.glBindAttribLocation(programHandle, 1, "a_Color"); GLES20.glLinkProgram(programHandle); final int[] linkStatus = new int[1]; GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0); if(linkStatus[0] == 0) { GLES20.glDeleteProgram(programHandle); programHandle = 0; } } if(programHandle == 0) { throw new RuntimeException("failed to create program"); } mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix"); mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position"); mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color"); GLES20.glUseProgram(programHandle); } }
最后附上效果图:
相关文章推荐
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
- Android openGL ES 2.0入门--画三角形、正方形
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
- OpenGL ES2.0入门之Android篇(一)——绘制三角形
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.2 用OpenGL ES 2.0画一个三角形
- Android OpenGL ES2.0基础(二、画个三角形)
- Android OpenGL ES 2.0绘制简单三角形
- Android中使用opengl es2.0基础(2)- 三角形的绘制
- OpenGL ES2.0入门之Android篇(一)——绘制三角形
- android opengl es 2.0里surfaceview背景透明
- Android OpenGLES2.0(二)——绘制一个三角形
- Android openGL ES2.0 Matrix.frustumM和Matrix.setLookAtM解析
- 基于Cocos2d-x学习OpenGL ES 2.0系列——你的第一个三角形(1)
- Android OpenGL ES 2.0 (五) 添加材质
- Android OpenGL ES 2.0绘图:绘制纹理
- Android OpenGL ES(十)绘制三角形Triangle .
- Android OpenGLES2.0等腰直角三角形和彩色的三角形(三)
- Android opengl es 2.0怎么学习
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.4 用OpenGL ES 2.0显示一张图片(下)
- Android OpenGL ES 2.0学习研究 (一)