您的位置:首页 > 移动开发 > Android开发

Android之GLES2.0显示立方体各面不同图片测试代码2

2016-06-10 17:31 435 查看
通过旋转面来组合立方体。

package com.example.gles20test;

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.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;

public class MainActivity extends Activity {

private GLSurfaceView mGLSurfaceView;
DemoRenderer mRender;
@Override
public 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);
}

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);
}

@Override
protected void onResume() {
super.onResume();
mGLSurfaceView.onResume();
}

@Override
protected 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 angleInDegrees = 0;
public DemoRenderer(final Context context) {
mContext = context;
final float cubePosition[] = {
-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 cubeTextureCoordinate[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
};

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();
}

@Override
public 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-3
mMVPMatrixHandle = 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);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//竖屏:width=1080,height=1581
GLES20.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);
}

@Override
public 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, angleInDegrees, 1.0f, 0.0f, 0.0f);
Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 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, 90, 0.0f, 1.0f, 0.0f);
else
Matrix.rotateM(mModelMatrix, 0, 90*(i+1), 1.0f, 0.0f, 0.0f);
drawCube(mCubePositions, mCubeTextureCoord);
}
fps = fpsCounter.getFPS();
angleInDegrees += 0.5f;
}

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_TRIANGLES, 0, 6);
}

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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: