Android OpenGL ES 2.0 (二) 画立方体
2012-04-27 17:59
483 查看
画过三角形后,再来画立方体。
Activity还是和画三角形的一样,只是Renderer换了。
为加强立体感,加了旋转效果。
Test2Renderer.java
下面是效果图:
总结一下写此程序过程中犯的错误:
1,在构造方法里创建了mCubePositions和mCubeColors后忘了调mCubePositions.put(cubePosition).position(0)和mCubeColors.put(cubeColor).position(0)。
导致运行后是一片黑屏,什么都没画出来。这是个低级错误。以后不要再犯。
2,在onDrawFrame里glClear不小心把GL_DEPTH_BUFFER_BIT给删除了,然后出来的效果~~不是预想的。
Activity还是和画三角形的一样,只是Renderer换了。
为加强立体感,加了旋转效果。
Test2Renderer.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; import android.os.SystemClock; public class Test2Renderer implements GLSurfaceView.Renderer { private static final int BYTES_PER_FLOAT = 4; private final FloatBuffer mCubePositions; private final FloatBuffer mCubeColors; 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 int mProgramHandle; private final int POSITION_DATA_SIZE = 3; private final int COLOR_DATA_SIZE = 4; public Test2Renderer() { final float cubePosition[] = { // Front face -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // Right face 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, // Back face 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, // Left face -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Top face -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, // Bottom face 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, }; final float[] cubeColor = { // Front face (red) 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Right face (green) 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, // Back face (blue) 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Left face (yellow) 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // Top face (cyan) 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom face (magenta) 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; mCubePositions = ByteBuffer.allocateDirect(cubePosition.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()).asFloatBuffer(); mCubePositions.put(cubePosition).position(0); mCubeColors = ByteBuffer.allocateDirect(cubeColor.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()).asFloatBuffer(); mCubeColors.put(cubeColor).position(0); } @Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); long time = SystemClock.uptimeMillis() % 10000L; float angleInDegrees = (360.0f / 10000.0f) * ((int) time); GLES20.glUseProgram(mProgramHandle); mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix"); mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position"); mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color"); Matrix.setIdentityM(mModelMatrix, 0); Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -5.0f); Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 1.0f, 1.0f, 0.0f); drawCube(mCubePositions, mCubeColors); } private void drawCube(final FloatBuffer cubePositionsBuffer, final FloatBuffer cubeColorsBuffer) { cubePositionsBuffer.position(0); GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, cubePositionsBuffer); GLES20.glEnableVertexAttribArray(mPositionHandle); cubeColorsBuffer.position(0); GLES20.glVertexAttribPointer(mColorHandle, COLOR_DATA_SIZE, GLES20.GL_FLOAT, false, 0, cubeColorsBuffer); 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, 36); } @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(0.0f, 0.0f, 0.0f, 0.0f); GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glEnable(GLES20.GL_DEPTH_TEST); // Position the eye behind the origin. final float eyeX = 0.0f; final float eyeY = 0.0f; final float eyeZ = -0.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"); } mProgramHandle = GLES20.glCreateProgram(); if(mProgramHandle != 0) { GLES20.glAttachShader(mProgramHandle, vertexShaderHandle); GLES20.glAttachShader(mProgramHandle, fragmentShaderHandle); GLES20.glBindAttribLocation(mProgramHandle, 0, "a_Position"); GLES20.glBindAttribLocation(mProgramHandle, 1, "a_Color"); GLES20.glLinkProgram(mProgramHandle); final int[] linkStatus = new int[1]; GLES20.glGetProgramiv(mProgramHandle, GLES20.GL_LINK_STATUS, linkStatus, 0); if(linkStatus[0] == 0) { GLES20.glDeleteProgram(mProgramHandle); mProgramHandle = 0; } } if(mProgramHandle == 0) { throw new RuntimeException("failed to create program"); } } }
下面是效果图:
总结一下写此程序过程中犯的错误:
1,在构造方法里创建了mCubePositions和mCubeColors后忘了调mCubePositions.put(cubePosition).position(0)和mCubeColors.put(cubeColor).position(0)。
导致运行后是一片黑屏,什么都没画出来。这是个低级错误。以后不要再犯。
2,在onDrawFrame里glClear不小心把GL_DEPTH_BUFFER_BIT给删除了,然后出来的效果~~不是预想的。
相关文章推荐
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.2 用OpenGL ES 2.0画一个三角形
- Android OpenGL ES 2.0 (七) FramebufferObject(FBO)
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- Android openGL ES2.0 Matrix.frustumM和Matrix.setLookAtM解析
- Android OpenGL ES 2.0学习研究 (一)
- OpenGL ES2.0入门之Android篇(二)——添加动作及触摸事件
- Android OpenGL ES 2.0绘图:搭建OpenGL ES环境
- Android OpenGL ES 2.0 屏幕坐标和3D世界坐标转换
- android OpenGL ES 2.0 Shader相关介绍
- [置顶] 使用Android OpenGL ES 2.0绘图之五:添加运动
- Android OpenGL ES 2.0之开发流程
- android OpenGL ES2.0编程初学
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- Android OpenGL ES 2.0 (五) 添加材质
- 基于Cocos2d-x学习OpenGL ES 2.0系列——你的第一个立方体(5)
- Android OpenGL ES2.0基础(二、画个三角形)
- Android OpenGL ES 2.0-学习笔记(一)
- android opengl es 立方体
- Android OpenGl ES2.0编程_相关概念与绘制顶点
- openGL es2.0 创建物理世界_颜色立方体刚体_颜色平面刚体以及四元数转换