学习Android Opengles 做游戏引擎笔记(二)

项目文件: http://download.csdn.net/detail/li6185377/4194984

上一章基本的图形已经可以画了  可是没图片是不行的

opengl 要画图 需要一个基本的图形 加图片

传送门: http://www.cnblogs.com/shengdoushi/archive/2011/01/13/1934181.html#sec-1.6

我就是学习这上面的

还有学习LGame引擎 现成的 http://blog.csdn.net/cping1982 

了解了以后 我们对Texture 进行封装

package ljh.opengl;

import java.util.HashMap;
import ljh.game.core.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;

public class LTexture {
        
	private int width, height, pow2Width, pow2Height;
	private Bitmap mBitmap;

	private float MaxW, MaxH;
	private int TextureID;
        //父纹理 因为我们经常取小图  要通过父纹理来进行绘图
	private LTexture parent = null;
        //偏移值 相对最大图 偏移多少
	private float offsetX = 0, offsetY = 0;
        //纹理图的大小
	private int TexWidth, TexHeight;
        //子纹理
	private HashMap<Integer, LTexture> subs = new HashMap<Integer, LTexture>();;

	private int Unused = 0;

	private LTexture() {

	}

	public LTexture(Bitmap bmp) {
              //上面那传送门那有
		this.width = bmp.getWidth();
		this.height = bmp.getHeight();
		TexHeight = height;
		TexWidth = width;
		pow2Width = pow2(width);
		pow2Height = pow2(height);
		MaxW = width / (float) pow2Width;
		MaxH = height / (float) pow2Height;
		Bitmap bitmap = Bitmap.createBitmap(pow2Width, pow2Height, bmp
				.hasAlpha() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(bmp, 0, 0, null);

		bmp.recycle();
		bmp = null;
		this.mBitmap = bitmap;
	}

	public LTexture(String filename) {
		this(Resources.getBitmap(filename));
	}
        //对一些临时创建的纹理图用  以后会讲到 如String 的纹理  因为Opengle 没法写字  所以采用了创建文字纹理来应对 未使用次数
	public void addUnused() {
		Unused++;
	}
        
	public void bind(GLEx gl) {
		gl.glBind(this);
	}

	public void dispose() {
		TextureID = 0;
	}

	public Bitmap getBitmap() {
		if (this.parent != null) {
			return parent.getBitmap();
		}
		return this.mBitmap;
	}

	public int getHeight() {
		return height;
	}

	public float getMaxH() {
		return MaxH;
	}

	public float getMaxW() {
		return MaxW;
	}

	public float getOX() {
		return offsetX / pow2Width;
	}

	public float getOY() {
		return offsetY / pow2Height;
	}

	public int getPow2Height() {
		return pow2Height;
	}

	public int getPow2Width() {
		return pow2Width;
	}
         //返回子图
	public LTexture getSubTexture(int x, int y, int width, int height) {

		if (x < 0)
			x = 0;
		if (y < 0)
			y = 0;
		if (width > this.width)
			width = this.width;
		if (height > this.height)
			height = this.height;
                //看看子图中是否已经创建
		LTexture sub = subs.get(x*100 + y + width + height);
		if (sub != null)
			return sub;

		sub = new LTexture();
		sub.parent = LTexture.this;
		if (TextureID != 0)
			sub.TextureID = this.TextureID;

		sub.pow2Width = this.pow2Width;
		sub.pow2Height = this.pow2Height;
		sub.width = width;
		sub.height = height;
		sub.offsetX = offsetX + x;
		sub.offsetY = offsetY + y;
		sub.TexWidth = TexWidth;
		sub.TexHeight = TexHeight;
                //关键啊
		sub.MaxW = ((sub.offsetX + sub.width) / (float) this.pow2Width);
		sub.MaxH = ((sub.offsetY + sub.height) / (float) this.pow2Height);
		subs.put(x*100 + y + width + height, sub);
		return sub;
	}

	public int getTextureID() {
                //说明被调用了
		Unused = 0;
		return this.TextureID;
	}

	public boolean isUnused() {
		if (this.parent == null && Unused > 20) {
			return true;
		}
		return false;
	}

	public int getWidth() {
		return width;
	}

	int pow2(int size) {
		int small = (int) (Math.log(size) / Math.log(2));
		if ((1 << small) >= size)
			return 1 << small;
		else
			return 1 << (small + 1);
	}

	public void recycle() {
		if (this.mBitmap != null) {
			if (this.mBitmap.isRecycled())
				this.mBitmap.recycle();
			this.mBitmap = null;
		}
	}
        //设置父子的纹理ID 都一样
	public void setTextureID(int id) {
		if (parent == null) {
			this.TextureID = id;
			for (LTexture sub : subs.values()) {
				sub.setTextureID(id);
			}
		} else if (this.parent.TextureID == 0) {
			this.parent.setTextureID(id);
		} else {
			this.TextureID = id;
			for (LTexture sub : subs.values()) {
				sub.setTextureID(id);
			}
		}

	}
}

有了他我们还是不能画图 因为我把他的调用放在GL的封装中

	public void delete(LTexture texture) {
		delete(texture.getTextureID());
		texture.recycle();
	}

	public void delete(int textureID) {
		if (textureID != 0) {
			gl.glDeleteTextures(1, new int[] { textureID }, 0);
			System.out.println("Delete Texture :" + textureID);
		}
	}

	public void drawTexture(LTexture texture,float x,float y)
	{	
		drawTexture(texture, x, y, texture.getWidth(), texture.getHeight());
	}
	public void drawTexture(LTexture texture,float x,float y,float width,float height)
	{				
		openTexture();		
		glBind(texture);
		//获得顶点的Buffer
		FloatBuffer pointer = GLHelper.getVertex(x, y, width, height);
                //获得纹理映射
		FloatBuffer coord = GLHelper.getCoord(texture.getOX(),texture.getOY(),texture.getMaxW(), texture.getMaxH());		
                //绑定到gl中
		gl.glVertexPointer(2, GL10.GL_FLOAT, 0, pointer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, coord);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);		
		
		disableTexture();		
	}

	public void glBind(LTexture texture) {
		if (texture.getTextureID() == 0) 
		{						
			int[] textures = new int[1];			
			gl.glGenTextures(1, textures, 0);
			texture.setTextureID(textures[0]);
			gl.glBindTexture(GL10.GL_TEXTURE_2D, texture.getTextureID());
                        //不管纹理放大还是缩小都显得平滑
			gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
					GL10.GL_LINEAR);
			gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
					GL10.GL_LINEAR);
                        
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);			
//			GL10.GL_CLAMP_TO_EDGE 不重复
			//绑定Bitmap到纹理中
			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture.getBitmap(), 0);
			//对Bitmap进行回收
			texture.recycle();
		}

		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture.getTextureID());
	}

还有个获得顶点和纹理映射的封装

public static FloatBuffer getVertex(float x,float y,float width,float height)
	{
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8*4);
		byteBuffer.order(ByteOrder.nativeOrder());
		FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
		floatBuffer.put(new float[]{
				x,y,
				x+width,y,
				x,y+height,
				x+width,y+height
				
		});
		floatBuffer.position(0);
		return floatBuffer;
	}
	public static FloatBuffer getCoord(float maxW,float maxH)
	{
		return getCoord(0, 0, maxW, maxH);
	}
	public static FloatBuffer getCoord(float x,float y,float maxW,float maxH)
	{	
//		System.out.println(x+"  " + y + " " +maxW + "  "+ maxH );
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8*4);
		byteBuffer.order(ByteOrder.nativeOrder());
		FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
		floatBuffer.put(new float[]{
				x,y,
				maxW,y,
				x,maxH,
				maxW,maxH
				
		});
		floatBuffer.position(0);
		return floatBuffer;
	}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值