public class MainActivity extends Activity {
private MyTDView myTDView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置界面显示为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
myTDView = new MyTDView(this);
myTDView.requestFocus();
myTDView.setFocusableInTouchMode(true);
setContentView(myTDView);
}
@Override
public void onResume() {
super.onResume();
myTDView.onResume();
}
@Override
public void onPause() {
super.onPause();
myTDView.onPause();
}
}
class MyTDView extends GLSurfaceView {
public static float[] mProjMatrix = new float[16]; //4 * 4 投影矩阵
public static float[] mVMatrix = new float[16]; //摄影机位置朝向参数矩阵
public static float[] mMVPMatrix; //最后起作用的总变换矩阵
int mProgram; //自定义渲染管线着色程序id
int muMVPMatrixHandle; //总变换矩阵的引用
int maPositionHandle; //顶点位置属性引用
int maColorHandle; //顶点颜色属性引用
static float[] mMMatrix = new float[16]; //具体物体的3D变换矩阵, 包括旋转, 平移, 缩放
FloatBuffer mVertexBuffer; //顶点坐标数据缓冲
FloatBuffer mColorBuffer; //顶点着色数据缓冲
float xAngle = 0; //绕x轴旋转角度
Context context;
private SceneRenderer mSceneRender;
public MyTDView(Context context) {
super(context);
this.context = context;
//设置OpenGLES版本为2.0
this.setEGLContextClientVersion(2);
mSceneRender = new SceneRenderer();
this.setRenderer(mSceneRender);
this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
private class SceneRenderer implements Renderer{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0, 0, 0, 1.0f);
float vertices[] = new float[]{
-0.8f, 0 , 0, //第1个点位置:x轴左边的坐标
0, -0.8f, 0, //第2个点位置:y轴坐标
0.8f, 0, 0 //第3个点位置:x轴右边的坐标
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
float colors[] = {
1, 0, 0, 0,//红色
0, 1, 0, 0,//绿色
0, 0, 1, 0 //蓝色
};
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
//加载着色器程序
// String mVertexShaderCode = ShaderUtil.loadFromAssetsFile("vertex.sh", context.getResources());
// String mFragmentShaderCode = ShaderUtil.loadFromAssetsFile("frag.sh", context.getResources());
String mVertexShaderCode = "uniform mat4 uMVPMatrix;"+
"attribute vec3 aPosition;"+
"attribute vec4 aColor;"+
"varying vec4 vColor;"+
"void main(){"+
" gl_Position = uMVPMatrix * vec4(aPosition,1);"+
" vColor = aColor;"+
"}";
String mFragmentShaderCode ="precision mediump float;"+
"varying vec4 vColor;"+
"void main(){"+
" gl_FragColor = vColor;"+
"}";
mProgram = ShaderUtil.loadCompileRunProgram(mVertexShaderCode, mFragmentShaderCode);
//获得着色器程序相关变量操作句柄
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float)width/height;
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
Matrix.setLookAtM(mVMatrix, 0, 0f,0f,3f,0f,0f,0f,0f,1.0f,0.0f);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);
Matrix.translateM(mMMatrix, 0, 0, 0, 1);
Matrix.rotateM(mMMatrix, 0, xAngle, 1, 0, 0);
mMVPMatrix = new float[16];
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);
GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 4 * 4, mColorBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maColorHandle);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);//3个顶点
xAngle = xAngle + 0.3f;
}
}
}
class ShaderUtil {
public static int loadCompileShader(int shaderType , String source){
int shader = GLES20.glCreateShader(shaderType);
if(shader == 0) return 0;
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if(compiled[0] == 0){
Log.e("ES20_ERROR", "编译程序"+shaderType+":"+GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
return shader;
}
public static void checkGLError(String op){
int error;
while( (error = GLES20.glGetError()) != GLES20.GL_NO_ERROR ){
Log.e("ES20_ERROR", op + ": glError " + error);
throw new RuntimeException(op + ": glError " + error);
}
}
public static int loadCompileRunProgram(String vertexCode , String fragmentCode){
int vertexShader = loadCompileShader(GLES20.GL_VERTEX_SHADER, vertexCode);
if(vertexShader == 0) return 0;
int fragShader = loadCompileShader(GLES20.GL_FRAGMENT_SHADER, fragmentCode);
if(fragShader == 0) return 0;
int program = GLES20.glCreateProgram();
if(program == 0) return 0;
GLES20.glAttachShader(program, vertexShader);
checkGLError("glAttachShader");
GLES20.glAttachShader(program, fragShader);
checkGLError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if(linkStatus[0] != GLES20.GL_TRUE){
Log.e("ES20.ERROR", "链接程序: "+GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
return program;
}
public static String loadFromAssetsFile(String fileName, Resources resources){
String result = null;
try {
InputStream is = resources.getAssets().open(fileName);
int ch = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((ch = is.read()) != -1){
baos.write(ch);
}
byte[] buffer = baos.toByteArray();
baos.close();
is.close();
result = new String(buffer, "UTF-8");
result = result.replaceAll("\\r\\n", "\n");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Android之GLES2.0画三角形测试代码
最新推荐文章于 2019-10-15 20:28:16 发布