学习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);
		//切换回modeview
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}


	public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
		// TODO Auto-generated method stub
		
		gl.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});
	}
}

下一章介绍纹理的映射和封装


由于是学习 笔记 各位给点建议啊  我看别人的代码 都不太懂为什么。。 只好按自己想法写了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值