Android之GLES2.0控制立方体旋转测试代码

来源:互联网 发布:程序员考试真题及答案 编辑:程序博客网 时间:2024/05/16 06:40
public class MainActivity extends Activity {private GLSurfaceView mGLSurfaceView;DemoRenderer mRender;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mGLSurfaceView = new GLSurfaceView(this);// Check if the system supports OpenGL ES 2.0.final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();if (configurationInfo.reqGlEsVersion >= 0x20000) {// Request an OpenGL ES 2.0 compatible context.mGLSurfaceView.setEGLContextClientVersion(2);mRender = new DemoRenderer(this);// Set the renderer to our demo renderer, defined below.mGLSurfaceView.setRenderer(mRender);} else {// This is where you could create an OpenGL ES 1.x compatible// renderer if you wanted to support both ES 1 and ES 2.return;}setContentView(mGLSurfaceView);handler.postDelayed(runnable, 1000);}float mPreviousX=0,mPreviousY=0;public boolean onTouchEvent(final MotionEvent e){     mGLSurfaceView.queueEvent(new Runnable() {             @Override            public void run() {                float x = e.getX();            float y = e.getY();            switch (e.getAction()) {            case MotionEvent.ACTION_MOVE:                float dx = y - mPreviousY;                float dy = x - mPreviousX;                mRender.mAngleX += dx;                mRender.mAngleY += dy;                mGLSurfaceView.requestRender();            }            mPreviousX = x;            mPreviousY = y;         }        });        return true;    }  Handler handler = new Handler();Runnable runnable = new Runnable() {public void run() {handler.postDelayed(this, 1000);showFPS(mRender.fps);}}; private void showFPS(int fps) {this.setTitle("fps:" + fps);}@Overrideprotected void onResume() {super.onResume();mGLSurfaceView.onResume();}@Overrideprotected void onPause() {super.onPause();mGLSurfaceView.onPause();}}class DemoRenderer implements GLSurfaceView.Renderer {private Context mContext;private final FloatBuffer mCubePositions;private final FloatBuffer mCubeTextureCoord;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[] mTextureDataHandle = new int[6];private int mMVPMatrixHandle;private int mPositionHandle;private int mTextureCoordinateHandle;private final int POSITION_DATA_SIZE = 3;private final int TEXTURE_COORDINATE_DATA_SIZE = 2;int fps;FPSCounter fpsCounter;float mAngleX = 0, mAngleY = 0;public DemoRenderer(final Context context) {mContext = context;final float cubePosition[] = {                 -1.0f, -1.0f, 0.0f,  // 0. 左-底-前              1.0f, -1.0f, 0.0f,   // 1. 右-底-前              -1.0f,  1.0f, 0.0f,  // 2. 左-顶-前              1.0f,  1.0f, 0.0f    // 3. 右-顶-前          };               final float cubeTextureCoordinate[] = {                     0.0f, 1.0f,  // A. 左-下                  1.0f, 1.0f,  // B. 右-下                   0.0f, 0.0f,  // C. 左-上                   1.0f, 0.0f   // D. 右-上             };  mCubePositions = ByteBuffer.allocateDirect(cubePosition.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();mCubePositions.put(cubePosition).position(0);mCubeTextureCoord = ByteBuffer.allocateDirect(cubeTextureCoordinate.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();mCubeTextureCoord.put(cubeTextureCoordinate).position(0);fpsCounter = new FPSCounter();}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);GLES20.glEnable(GLES20.GL_CULL_FACE);GLES20.glEnable(GLES20.GL_DEPTH_TEST);String vertexShaderCode = "uniform mat4 u_MVPMatrix; \n"+ "attribute vec4 a_Position; \n"+ "attribute vec2 a_TexCoordinate;\n"+ "varying vec2 v_TexCoordinate; \n" + "void main(){ \n"+ "  v_TexCoordinate = a_TexCoordinate;\n"+ "  gl_Position = u_MVPMatrix * a_Position; \n" + "} \n";String fragmentShaderCode = "precision mediump float; \n"+ "uniform sampler2D u_Texture; \n"+ "varying vec4 v_Color; \n"+ "varying vec2 v_TexCoordinate; \n" + "void main(){ \n"// " gl_FragColor = v_Color * texture2D(u_Texture, v_TexCoordinate); \n"+ "  gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n"+ "} \n";int mProgramHandle = createAndLinkProgram(vertexShaderCode,fragmentShaderCode);GLES20.glUseProgram(mProgramHandle);//获得参数1-3mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle,"u_MVPMatrix");mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_Position");mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_TexCoordinate");//加载纹理贴图mTextureDataHandle[0] = ToolsUtil.loadTexture(mContext, R.drawable.aa);mTextureDataHandle[1] = ToolsUtil.loadTexture(mContext, R.drawable.bb);mTextureDataHandle[2] = ToolsUtil.loadTexture(mContext, R.drawable.aa);mTextureDataHandle[3] = ToolsUtil.loadTexture(mContext, R.drawable.bb);mTextureDataHandle[4] = ToolsUtil.loadTexture(mContext, R.drawable.aa);mTextureDataHandle[5] = ToolsUtil.loadTexture(mContext, R.drawable.bb);//激活纹理GLES20.glActiveTexture(GLES20.GL_TEXTURE0);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {//竖屏:width=1080,height=1581GLES20.glViewport(0, 0, width, height);final float ratio = (float) width / height;Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 1, 10);Matrix.setLookAtM(mViewMatrix, 0, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, -5, 0.0f, 1.0f, 0.0f);}float[][] offset = {{0.0f, 0.0f, 1.0f}, //第一个面向前移,将中心点移到正方体中心,滚动就会很自然。{1.0f, 0.0f, 1.0f}, //右{1.0f, 0.0f, 1.0f}, //后{1.0f, 0.0f, 1.0f}, //左{0.0f, -1.0f, 1.0f},//下{0.0f, 0.0f, 2.0f},//上};float[] angle = {0.0f, 90.0f, 90.0f, 90.0f, 90.0f, 180.0f};@Overridepublic void onDrawFrame(GL10 gl) {GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);//矩阵乘法的一个乘数Matrix.setIdentityM(mModelMatrix, 0);Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -5.0f);Matrix.rotateM(mModelMatrix, 0, mAngleX, 1.0f, 0.0f, 0.0f);Matrix.rotateM(mModelMatrix, 0, mAngleY, 0.0f, 1.0f, 0.0f);//绑定纹理,传递参数,绘制图形for(int i = 0; i < 6; i++){GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[i]);//在上一个变换面的基础上进行旋转变换(注:坐标系也是跟着旋转的)if(i < 4)Matrix.rotateM(mModelMatrix, 0, angle[i], 0.0f, 1.0f, 0.0f);else Matrix.rotateM(mModelMatrix, 0, angle[i], 1.0f, 0.0f, 0.0f);Matrix.translateM(mModelMatrix, 0, offset[i][0], offset[i][1],offset[i][2]);drawCube(mCubePositions, mCubeTextureCoord);}fps = fpsCounter.getFPS();}private void drawCube(final FloatBuffer cubePositions,final FloatBuffer cubeTextureCoord) {//参数1传递Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);//参数2传递GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE,GLES20.GL_FLOAT, false, 0, cubePositions);GLES20.glEnableVertexAttribArray(mPositionHandle);//参数3传递GLES20.glVertexAttribPointer(mTextureCoordinateHandle,TEXTURE_COORDINATE_DATA_SIZE, GLES20.GL_FLOAT, false, 0,cubeTextureCoord);GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);//绘制GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);}private int compileShader(final int shaderType, final String shaderSource) {int shaderHandle = GLES20.glCreateShader(shaderType);if (shaderHandle != 0) {GLES20.glShaderSource(shaderHandle, shaderSource);GLES20.glCompileShader(shaderHandle);final int[] compileStatus = new int[1];GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS,compileStatus, 0);if (compileStatus[0] == 0) {Log.e("ERR","compiling: " + GLES20.glGetShaderInfoLog(shaderHandle));GLES20.glDeleteShader(shaderHandle);shaderHandle = 0;}}if (shaderHandle == 0) {throw new RuntimeException("Error creating shader.");}return shaderHandle;}private int createAndLinkProgram(final String vertexShaderCode,final String fragmentShaderCode) {int vertexShaderHandle = compileShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);int fragmentShaderHandle = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);int programHandle = GLES20.glCreateProgram();if (programHandle != 0) {GLES20.glAttachShader(programHandle, vertexShaderHandle);GLES20.glAttachShader(programHandle, fragmentShaderHandle);GLES20.glLinkProgram(programHandle);final int[] linkStatus = new int[1];GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS,linkStatus, 0);if (linkStatus[0] == 0) {Log.e("ERR","linking: "+ GLES20.glGetProgramInfoLog(programHandle));GLES20.glDeleteProgram(programHandle);programHandle = 0;}}if (programHandle == 0) {throw new RuntimeException("Error creating program.");}return programHandle;}static class ToolsUtil {public static int loadTexture(final Context context,final int resourceId) {final int[] textureHandle = new int[1];GLES20.glGenTextures(1, textureHandle, 0);if (textureHandle[0] != 0) {final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);}if (textureHandle[0] == 0) {throw new RuntimeException("failed to load texture");}return textureHandle[0];}}class FPSCounter {int FPS;int lastFPS;long tempFPStime;public FPSCounter() {FPS = 0;lastFPS = 0;tempFPStime = 0;}int getFPS() {long nowtime = SystemClock.uptimeMillis();FPS++;if (nowtime - tempFPStime >= 1000) {lastFPS = FPS;tempFPStime = nowtime;FPS = 0;}return lastFPS;}}}

0 0
原创粉丝点击