ok、好了今天学习了“openGL ES 2.0”
现在把今天学习到的东东做一个总结,本demo是运行在安装有android sdk的Eclipse上实现的:
好了总结开始:
起先是ShaderUtil.java文件:
package com.example.initopengles_mine;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.res.Resources;
import android.opengl.GLES20;
import android.util.Log;
public class ShaderUtil {
public static int loadShader(
int shaderType, String source){
int shader = GLES20.glCreateShader(shaderType);
if(shader !=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","Could not compile shader" + shaderType + ":");
Log.e("ES20_ERROR",GLES20.glGetShaderInfoLog(shader));
shader = 0;
}
}
return shader;
}
public static int createProgram(
String vertexSource, String fragmentSource){
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexSource);
if(vertexShader == 0){
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentSource);
if(pixelShader == 0){
return 0;
}
int program = GLES20.glCreateProgram();
if(program !=0 ){
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
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","could not link program:");
Log.e("ES20_ERROR",GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
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 String loadFromAssetsFile(
String fname,Resources r){
String result = null;
try {
InputStream in = r.getAssets().open(fname);
int ch = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((ch=in.read()) != -1){
baos.write(ch);
}
byte[] buff = baos.toByteArray();
baos.close();
in.close();
result = new String(buff,"UTF-8");
result = result.replaceAll("\\r\\n", "\n");
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return result;
}
}
好了,现在是MyTDView.java文件:
package com.example.initopengles_mine;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
public class MyTDView extends GLSurfaceView{
final float ANGLE_SPAN = 0.375f;
RotateThread rthread;
SceneRenderer mRenderer;
public MyTDView(Context context) {
super(context);
// TODO 自动生成的构造函数存根
this.setEGLContextClientVersion(2);
mRenderer = new SceneRenderer();
this.setRenderer(mRenderer);
this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
private class SceneRenderer implements GLSurfaceView.Renderer{
Triangle tle;
@Override
public void onDrawFrame(GL10 gl) {
// TODO 自动生成的方法存根
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
tle.drawSelf();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO 自动生成的方法存根
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
//错在这里了~
Matrix.frustumM(Triangle.mProjMatrix, 0, -ratio, ratio, -1, 1, 1 , 10);
Matrix.setLookAtM(Triangle.mVMatrix, 0 , 0 , 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO 自动生成的方法存根
GLES20.glClearColor(0, 0, 0, 1.0f);
tle = new Triangle(MyTDView.this);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
rthread = new RotateThread();
rthread.start();
}
}
public class RotateThread extends Thread{
public boolean flag = true;
@Override
public void run() {
// TODO 自动生成的方法存根
//super.run();
while(flag){
mRenderer.tle.xAngle = mRenderer.tle.xAngle + ANGLE_SPAN;
try{
Thread.sleep(20);
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
ok、现在就是Triangle.java文件的配置:
package com.example.initopengles_mine;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import android.opengl.Matrix;
public class Triangle {
public static float[] mProjMatrix = new float[16];
public static float[] mVMatrix = new float[16];
public static float[] mMVPMatrix;
int mProgram;
int muMVPMatrixHandle;
int maPositionHandle;
int maColorHandle;
String mVertexShader;
String mFragmentShader;
static float[] mMMatrix = new float[16];
FloatBuffer mVertexBuffer;
FloatBuffer mColorBuffer;
int vCount = 0;
float xAngle = 0;
public Triangle(MyTDView mv){
initVertexData();
intShader(mv);
}
public void initVertexData(){
vCount = 3;
final float UNIT_SIZE = 0.2f;
float vertices[] = new float[]{
-4 * UNIT_SIZE, 0,0,0,-4*UNIT_SIZE,0,4*UNIT_SIZE,0,0};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
float colors[] = new float[]{
1,1,1,0,0,0,1,0,0,1,0,0};
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
}
public void intShader(MyTDView mv){
mVertexShader = ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());
mFragmentShader = ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources());
mProgram = ShaderUtil.createProgram(mVertexShader,mFragmentShader);
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//这里不对
maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
public void drawSelf(){
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);
GLES20.glUniformMatrix4fv(
muMVPMatrixHandle, 1, false, Triangle.getFinalMatrix(mMMatrix),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, vCount);
}
public static float[] getFinalMatrix(float[] spec){
mMVPMatrix = new float[16];
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, spec, 0);
//少了一句:
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
return mMVPMatrix;
}
}
,万事俱备,之前东风:
最后最后配置MainActivity.javj文件:
package com.example.initopengles_mine;
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.Menu;
public class MainActivity extends Activity {
MyTDView mview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mview = new MyTDView(this);
mview.requestFocus();
mview.setFocusableInTouchMode(true);
setContentView(mview);
}
@Override
protected void onPause() {
// TODO 自动生成的方法存根
super.onPause();
mview.onPause();
}
@Override
protected void onResume() {
// TODO 自动生成的方法存根
super.onResume();
mview.onResume();
}
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
*/
}
好了,
今天就总结到这里~~
祝大家周末愉快~