学习Android(安卓)Opengles 做游戏引擎笔记(一)
项目文件:http://download.csdn.net/detail/li6185377/4194984
在Activity onCreate 中
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//这3句是横屏 满屏幕的 可有可无
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setRenderer(new MyRender());
setContentView(glSurfaceView);
}
创建一个MyRender 类 实现GLSurfaceView.Renderer
package ljh.opengl;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import ljh.game.core.GameSystem;import ljh.game.core.SystemTimer;import ljh.game.geom.RectBox;import android.opengl.GLSurfaceView.Renderer;import android.opengl.GLU;public class MyRender implements Renderer{public void onDrawFrame(GL10 gl) {// TODO Auto-generated method stub//画图}GLEx glex;public void onSurfaceChanged(GL10 gl, int width, int height) {// TODO Auto-generated method stub//重新设置窗口大小 gl.glViewport(0, 0, width, height);//投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);gl.glLoadIdentity();//gl.glOrthof(0, width, height, 0, 1, -100);//2D投影大小(gl,left,right,down,top) 上面一样加了近远距离GLU.gluOrtho2D(gl, 0, width, height, 0);//切换回modeviewgl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();}public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {// TODO Auto-generated method stubgl.glClearColor(0, 0, 0, 1);//透视修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);//阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);gl.glClearDepthf(1);//深度测试gl.glEnable(GL10.GL_DEPTH_TEST);gl.glDepthFunc(GL10.GL_LEQUAL);}}
因为GL10 要频繁的开启一些功能和关闭一些功能 我就把他们集合在一起
public static void clear(GL10 gl){ //清除颜色缓存和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);gl.glLoadIdentity();}public static void openTexture(GL10 gl){//开启纹理gl.glEnable(GL10.GL_TEXTURE_2D);//开启纹理映射gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//开启顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);}public static void openTransparent(GL10 gl){//开启纹理透明 如果不开启纹理的Alpha值不起作用 就不透明了gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);gl.glEnable(GL10.GL_BLEND);}public static void openVertex(GL10 gl){//开启顶点gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);}//关闭纹理需要的项public static void disableTexture(GL10 gl){gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);gl.glDisable(GL10.GL_TEXTURE_2D);}public static void disableVertex(GL10 gl){gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);}public static void disableBlend(GL10 gl){gl.glDisable(GL10.GL_BLEND);}
这样我们开启关闭一些东西就方便了
要开始绘图了 GL10 绘图不够直接我们对他进行封装 也是图形的核心
package ljh.opengl;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10;public class GLOval { //画有关椭圆方面的图形 如圆、椭圆、弧 // 中心x,y 大小 width、height 绘画的模式 开始角度 结束角度 private static void drawOval(GL10 gl,float x,float y, float width,float height,int mode,int startAngle,int endAngle){//上面封装过的 开启顶点GLHelper.openVertex(gl);while(endAngle<startAngle){endAngle+=360;} //顶点的数量int length = endAngle-startAngle + 1;//一个顶点有 x,y 所以要2个 length = length * 2; //申请顶点的缓存块ByteBuffer byteBuffer = ByteBuffer.allocateDirect(length*4);byteBuffer.order(ByteOrder.nativeOrder());FloatBuffer vertexBuffer = byteBuffer.asFloatBuffer();float[] vertex = new float[length];float a = width/2;float b = height/2;for(int i=0;i<length;i+=2){ //椭圆的方程 x=a cos(@);y=b sin(@); 顶点的值是连续的 vertex[i] =(float)(a * Math.cos(Math.toRadians(i/2+startAngle))) + x; vertex[i+1] =(float)(b * Math.sin(Math.toRadians(i/2 +startAngle))) + y;}vertexBuffer.put(vertex);vertexBuffer.position(0);//把顶点加入gl中gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer); //绘图 GL10.GL_Line_loop 首尾相连的线 用来画椭圆 //GL10.GL_TRIANGLE_FAN 第一个顶点为公共点的三角形合并 用来画 填充椭圆 //GL10.GL_LINE_STRIP 没有首尾相连 用来画圆弧 //模式 间隔 顶点的数量gl.glDrawArrays(mode, 0, length/2);GLHelper.disableVertex(gl);}public static void drawOval(GL10 gl,float x,float y, float width,float height){drawOval(gl, x, y, width, height, GL10.GL_LINE_LOOP,0,360);}public static void fillOval(GL10 gl,float x,float y, float width,float height){drawOval(gl, x, y, width, height, GL10.GL_TRIANGLE_FAN,0,360);}public static void drawArc(GL10 gl,float x,float y,float width,float height,int startAngle,int endAngle){drawOval(gl, x, y, width, height, GL10.GL_LINE_STRIP, startAngle, endAngle);} //单独出来 因为填充圆弧比上面的多一个中心点public static void fillArc(GL10 gl,float x,float y,float width,float height,int startAngle,int endAngle){GLHelper.openVertex(gl);while(endAngle<startAngle){endAngle+=360;}int length = endAngle-startAngle + 2;ByteBuffer byteBuffer = ByteBuffer.allocateDirect(length*2*4);byteBuffer.order(ByteOrder.nativeOrder());FloatBuffer vertexBuffer = byteBuffer.asFloatBuffer();float[] vertex = new float[length*2];float a = width/2;float b = height/2;for(int i=2;i<length*2;i+=2){ vertex[i] =(float)(a * Math.cos(Math.toRadians(i/2-1+startAngle))) + x; vertex[i+1] =(float)(b * Math.sin(Math.toRadians(i/2-1+startAngle))) + y;} //第一个点为圆心vertex[0] = x;vertex[1] = y;vertexBuffer.put(vertex);vertexBuffer.position(0);gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, length);GLHelper.disableVertex(gl);}}
下面是多边形的封装
package ljh.opengl;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10;public class GLPolygon { //vertex 多边形的顶点数组public static void drawPolygon(GL10 gl,float [] vertex){drawPolygon(gl, vertex,GL10.GL_LINE_LOOP);} private static void drawPolygon(GL10 gl,float [] vertex,int mode){GLHelper.openVertex(gl);ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertex.length*4);byteBuffer.order(ByteOrder.nativeOrder());FloatBuffer vertexs = byteBuffer.asFloatBuffer();vertexs.put(vertex);vertexs.position(0);gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexs);gl.glDrawArrays(mode, 0, vertex.length/2);GLHelper.disableVertex(gl);} //GL10.GL_TRIANGLE_STRIP 一堆相邻的三角形public static void fillPolygon(GL10 gl,float[] vertex){drawPolygon(gl, vertex, GL10.GL_TRIANGLE_STRIP);}public static void drawLine(GL10 gl,float x1,float y1,float x2,float y2){drawPolygon(gl, new float[]{x1,y1,x2,y2});}public static void drawRect(GL10 gl,float x,float y,float width,float height){drawPolygon(gl,new float[]{x,y,x,y+height,x+width,y+height,x+width,y});}public static void drawTriangle(GL10 gl,float x1,float y1,float x2,float y2,float x3,float y3){drawPolygon(gl,new float[]{x1,y1,x2,y2,x3,y3});}public static void fillTriangle(GL10 gl,float x1,float y1,float x2,float y2,float x3,float y3){fillPolygon(gl, new float[]{x1,y1,x2,y2,x3,y3});}public static void fillRect(GL10 gl,float x,float y,float width,float height){fillPolygon(gl,new float[]{x,y,x,y+height,x+width,y+height,x+width,y});}}
下一章介绍纹理的映射和封装
由于是学习 笔记 各位给点建议啊 我看别人的代码 都不太懂为什么。。 只好按自己想法写了
更多相关文章
- Android(安卓)OpenGLES2.0(十三)——流畅的播放逐帧动画
- Android(安卓)OpenGL ES(八)----纹理编程框架
- Android(安卓)NDK 开发 —— 从 Assets 文件夹加载图片并上传纹
- Android(安卓)OpenGL ES(一)开发入门
- Android(安卓)OpenGL ES: 第一个程序
- Android(安卓)3D壁纸开发设计
- android opengl es 绘制位图字体
- 最短路径之狄克斯特拉(Dijkstra)算法
- 被裁老程序员再就业计划之我可以用Dijkstra算法在回龙观送外卖