`

OpenGL ES与libgdx学习笔记一:二维坐标系方向变换

 
阅读更多

二维坐标系变换为原点在左上角(测试用)

 

* GLES

* JOGL

* LWJGL

* libgdx(使用g2d与pixmap)

 

 

package com.iteye.weimingtom.testgl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class Testgl3Activity extends Activity implements GLSurfaceView.Renderer {
	private boolean USE_ORIGIN_TOPLEFT = true;
	
	private IntBuffer vertices;
	private int vertexBytes;
	private int vertexNum;
	
	private float[] arrVertices;
	private int[] tmpBuffer;
	
	private GLSurfaceView contentView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
        contentView = new GLSurfaceView(this);
        contentView.setRenderer(this);
        setContentView(contentView);
	}

	@Override
	protected void onPause() {
		super.onPause();
		contentView.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		contentView.onResume();
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		loadData();
        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(1, 1, 1, 1);
        gl.glDisable(GL10.GL_CULL_FACE);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glEnable(GL10.GL_DEPTH_TEST);
	}
	
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
	    gl.glViewport(0, 0, width, height);
	    //gl.glViewport(0, height, width, height);
	    if (USE_ORIGIN_TOPLEFT) {
	    	gl.glOrthof(0, width, -height, 0, 0, 1);
	    } else {
	    	gl.glOrthof(0, width, 0, height, 0, 1);
	    }
        updateData(width, height);
	}

	@Override
	public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        if (USE_ORIGIN_TOPLEFT) {
        	gl.glScalef(1f, -1f, 1f);
        }
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        
        vertices.position(0);
        gl.glVertexPointer(3, GL10.GL_FLOAT, vertexBytes, vertices);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        vertices.position(3);
        gl.glColorPointer(4, GL10.GL_FLOAT, vertexBytes, vertices);
        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, vertexNum);
		
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}
	
	private void loadData() {
		final float factor = 200f / 320f * 100;
        this.arrVertices = new float[] { 
        		0f * factor, 0f * factor, 0, 0, 0, 1, 1,
        		1f * factor, 0f * factor,   0, 0, 0, 1, 1,
        		1f * factor, 1f * factor, 0, 0, 0, 1, 1,
                0f * factor,  1f * factor,  0, 0, 0, 1, 1,
        };
        this.vertexBytes = (3 + 4) * (Integer.SIZE / 8);
        this.vertexNum = arrVertices.length / (this.vertexBytes / (Integer.SIZE / 8));
        this.tmpBuffer = new int[vertexNum * vertexBytes / (Integer.SIZE / 8)];
        ByteBuffer buffer = ByteBuffer.allocateDirect(vertexNum * vertexBytes);
        buffer.order(ByteOrder.nativeOrder());
        vertices = buffer.asIntBuffer();
		this.vertices.clear();
        for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
            tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
        }
        this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
        this.vertices.flip();
	}
	
	private void updateData(int width, int height) {
		arrVertices[0] = 100f;
		arrVertices[1] = 100f;
		arrVertices[0 + 7] = width - 10;
		arrVertices[1 + 7] = 0;
		arrVertices[0 + 14] = width - 10;
		arrVertices[1 + 14] = height - 10;		
		arrVertices[0 + 21] = 0;
		arrVertices[1 + 21] = height - 10;	
		this.vertices.clear();
        for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
            tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
        }
        this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
        this.vertices.flip();
	}
}

 

 

 

JOGL:

 

 

 

 

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import com.jogamp.opengl.util.FPSAnimator;

/**
 * gluegen-rt-natives-windows-i586.jar
 * gluegen-rt.jar
 * gluegen.jar
 * jogl-all-natives-windows-i586.jar
 * jogl.all.jar
 * 
 * @see sites.google.com/site/justinscsstuff/jogl-tutorial-3
 * @author Administrator
 *
 */
public class TestGLES1 implements GLEventListener {
	private boolean USE_ORIGIN_TOPLEFT = true;
	
	private IntBuffer vertices;
	private int vertexBytes;
	private int vertexNum;
	
	private float[] arrVertices;
	private int[] tmpBuffer;
	
	@Override
	public void init(GLAutoDrawable drawable) {
		GL2ES1 gl = drawable.getGL().getGL2ES1();
		loadData();
        gl.glDisable(GL2ES1.GL_DITHER);
        gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL2ES1.GL_FASTEST);
        gl.glClearColor(1, 1, 1, 1);
        gl.glDisable(GL2ES1.GL_CULL_FACE);
        gl.glShadeModel(GL2ES1.GL_SMOOTH);
        gl.glEnable(GL2ES1.GL_DEPTH_TEST);
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
		GL2ES1 gl = drawable.getGL().getGL2ES1();
		gl.glMatrixMode(GL2ES1.GL_PROJECTION);
        gl.glLoadIdentity();
	    gl.glViewport(0, 0, w, h);
	    //gl.glViewport(0, height, width, height);
	    if (USE_ORIGIN_TOPLEFT) {
	    	gl.glOrthof(0, w, -h, 0, 0, 1);
	    } else {
	    	gl.glOrthof(0, w, 0, h, 0, 1);
	    }
	    updateData(w, h);
	}
	
	@Override
	public void display(GLAutoDrawable drawable) {
		GL2ES1 gl = drawable.getGL().getGL2ES1();
        gl.glClear(GL2ES1.GL_COLOR_BUFFER_BIT | GL2ES1.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
        gl.glLoadIdentity();
        if (USE_ORIGIN_TOPLEFT) {
        	gl.glScalef(1f, -1f, 1f);
        }
        gl.glEnableClientState(GL2ES1.GL_VERTEX_ARRAY);
        
        vertices.position(0);
        gl.glVertexPointer(3, GL2ES1.GL_FLOAT, vertexBytes, vertices);
        gl.glEnableClientState(GL2ES1.GL_COLOR_ARRAY);
        vertices.position(3);
        gl.glColorPointer(4, GL2ES1.GL_FLOAT, vertexBytes, vertices);
        gl.glDrawArrays(GL2ES1.GL_TRIANGLE_FAN, 0, vertexNum);
		
        gl.glDisableClientState(GL2ES1.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL2ES1.GL_VERTEX_ARRAY);
	}

	@Override
	public void dispose(GLAutoDrawable drawable) {
		
	}
		
	private void loadData() {
		final float factor = 200f / 320f * 100;
        this.arrVertices = new float[] { 
        		0f * factor, 0f * factor, 0, 0, 0, 1, 1,
        		1f * factor, 0f * factor,   0, 0, 0, 1, 1,
        		1f * factor, 1f * factor, 0, 0, 0, 1, 1,
                0f * factor,  1f * factor,  0, 0, 0, 1, 1,
        };
        this.vertexBytes = (3 + 4) * (Integer.SIZE / 8);
        this.vertexNum = arrVertices.length / (this.vertexBytes / (Integer.SIZE / 8));
        this.tmpBuffer = new int[vertexNum * vertexBytes / (Integer.SIZE / 8)];
        ByteBuffer buffer = ByteBuffer.allocateDirect(vertexNum * vertexBytes);
        buffer.order(ByteOrder.nativeOrder());
        vertices = buffer.asIntBuffer();
		this.vertices.clear();
        for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
            tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
        }
        this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
        this.vertices.flip();
	}
	
	private void updateData(int width, int height) {
		arrVertices[0] = 100f;
		arrVertices[1] = 100f;
		arrVertices[0 + 7] = width - 10;
		arrVertices[1 + 7] = 0;
		arrVertices[0 + 14] = width - 10;
		arrVertices[1 + 14] = height - 10;		
		arrVertices[0 + 21] = 0;
		arrVertices[1 + 21] = height - 10;	
		this.vertices.clear();
        for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
            tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
        }
        this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
        this.vertices.flip();
	}
	
	public static void main(String[] args) {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        GLCanvas canvas = new GLCanvas(caps);

        Frame frame = new Frame("AWT Window Test");
        frame.setSize(240, 320);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
        frame.add(canvas);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        canvas.addGLEventListener(new TestGLES1());
        
	    FPSAnimator animator = new FPSAnimator(canvas, 60);
	    animator.add(canvas);
	    animator.start();
	}
}

 

LWJGL:

 

 

 

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

/**
 * lwjgl.jar : native library location -> testlwjgl/native/windows
 * 
 * @see http://lwjgl.org/wiki/index.php?title=LWJGL_Basics_1_(The_Display)
 * @see http://lwjgl.org/wiki/index.php?title=LWJGL_Basics_3_(The_Quad)
 * @author Administrator
 *
 */
public class Testlwjgl1 {
	private boolean USE_ORIGIN_TOPLEFT = true;
	
	private final static int SCREEN_WIDTH = 240;
	private final static int SCREEN_HEIGHT = 320;
	
	public void start() {
		try {
			Display.setDisplayMode(new DisplayMode(
					SCREEN_WIDTH, SCREEN_HEIGHT));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
		
		init();
		
		while (!Display.isCloseRequested()) {
			render();
			Display.update();
		}
		Display.destroy();
	}
	
	private void init() {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		if (USE_ORIGIN_TOPLEFT) {
			GL11.glOrtho(0, SCREEN_WIDTH, 
					-SCREEN_HEIGHT, 0, 
					1, -1);			
		} else {
			GL11.glOrtho(0, SCREEN_WIDTH, 
					0, SCREEN_HEIGHT, 
					1, -1);
		}
	}
	
	private void render() {
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
		if (USE_ORIGIN_TOPLEFT) {
			GL11.glScalef(1f, -1f, 1f);
		}
		
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | 
	    		GL11.GL_DEPTH_BUFFER_BIT);	
		GL11.glClearColor(1, 1, 1, 1);
		
		GL11.glColor3f(0.0f, 0.0f, 1.0f);
	    GL11.glBegin(GL11.GL_TRIANGLE_FAN);
	    {
		    GL11.glVertex2f(100, 100);
			GL11.glVertex2f(SCREEN_WIDTH - 10, 0);
			GL11.glVertex2f(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 10);
			GL11.glVertex2f(0, SCREEN_HEIGHT - 10);
	    }
	    GL11.glEnd();
	}
	
	public static void main(String[] args) {
		new Testlwjgl1().start();
	}
}

 

 

libgdx (使用g2d与pixmap,而非使用GLES绘画)

 

package com.iteye.weimingtom.libgdxtest;

import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.FPSLogger;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;

public class Test001Screen implements Screen {
	private final static boolean DIRECTION_DOWN = true;
	private final static int BOX_W = 50;
	private final static int BOX_H = 50;
	
	private int LOG_LEVEL = Application.LOG_DEBUG;
	private final static String TAG = "Test001Screen"; 
	private FPSLogger logger;
	
	private SpriteBatch sb;
	private Pixmap pixmap;
	private Texture texture;
	private TextureRegion textureRegion;
	private Vector2 pos;
	private Vector2 dir;

	public Test001Screen() {
		Gdx.app.setLogLevel(LOG_LEVEL);
		logger = new FPSLogger();
		init();
	}
	
	private void init() {
		log("init");
		sb = new SpriteBatch();
		int w = Gdx.graphics.getWidth();
		int h = Gdx.graphics.getHeight();
		pixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888);
		final int potW = MathUtils.nextPowerOfTwo(w);
		final int potH = MathUtils.nextPowerOfTwo(h);
		texture = new Texture(potW, potH, Pixmap.Format.RGBA8888);
		if (DIRECTION_DOWN) {
			textureRegion = new TextureRegion(texture, 0, 0, w, h);
		} else {
			textureRegion = new TextureRegion(texture, 0, h, w, -h);
		}
		pos = new Vector2(w / 2, h / 2);
		dir = new Vector2(1, 1);
	}
	
	@Override
	public void dispose() {
		log("dispose");
		texture.dispose();
		pixmap.dispose();
		sb.dispose();
	}
	
	@Override
	public void render(float delta) {
		onUpdate(delta);
		GL10 gl = Gdx.gl10;
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		gl.glClearColor(0, 0, 0, 0);
		//gl.glClearColor(1, 1, 1, 1);
		onRender();
		sb.begin();
		texture.draw(pixmap, 0, 0);
		sb.draw(textureRegion, 0, 0);
		sb.end();
		logger.log();
	}
	
	@Override
	public void resize(int width, int height) {
		sb.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
	}

	@Override
	public void show() {
		
	}

	@Override
	public void hide() {
		
	}

	@Override
	public void pause() {
		
	}

	@Override
	public void resume() {
		
	}
	
	private void onUpdate(float delta) {
		int w = pixmap.getWidth();
		int h = pixmap.getHeight();
		
		pos.x += dir.x * delta * 60;
		pos.y += dir.y * delta * 60;
		if (pos.x < 0) {
			dir.x = -dir.x;
			pos.x = 0;
		}
		if (pos.x > w) {
			dir.x = -dir.x;
			pos.x = w;
		}
		if (pos.y < 0) {
			dir.y = -dir.y;
			pos.y = 0;
		}
		if (pos.y > h) {
			dir.y = -dir.y;
			pos.y = h;
		}
	}
	
	private void onRender() {
		pixmap.setColor(0, 0, 0, 0);
		pixmap.fill();
		pixmap.setColor(Color.BLUE);
		pixmap.fillRectangle(
			(int)pos.x - BOX_W / 2, (int)pos.y - BOX_H / 2, 
			BOX_W, BOX_H);
	}
	
	private void log(String message) {
		Gdx.app.log(TAG, message);
	}
}

 

 

 

 

 

 

 

X. 参考资料:

1. Beginning Android 4 Games Development

随书代码Source Code/Downloads

http://www.apress.com/9781430239871

 

 

(TODO)

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    Libgdx入门-代码1

    Libgdx是一款基于OpenGL ES技术开发的Android游戏引擎,支持Android平台下的2D和3D游戏开发,2D物理引擎采用Box2D实现。单就性能角度来说,堪称是一款非常强大的Android游戏引擎,但缺陷在于精灵类等相关组件在使用...

    Libgdx入门-code

    Libgdx是一款基于OpenGL ES技术开发的Android游戏引擎,支持Android平台下的2D和3D游戏开发,2D物理引擎采用Box2D实现。单就性能角度来说,堪称是一款非常强大的Android游戏引擎,但缺陷在于精灵类等相关组件在使用...

    Libgdx入门-代码2

    Libgdx是一款基于OpenGL ES技术开发的Android游戏引擎,支持Android平台下的2D和3D游戏开发,2D物理引擎采用Box2D实现。单就性能角度来说,堪称是一款非常强大的Android游戏引擎,但缺陷在于精灵类等相关组件在使用...

    libgdx学习资料

    libgdx学习资料

    libGDX学习记录(一)源码

    libGDX学习记录(一)源码,搭建一个桌面端和android端的libGDX框架,展示图片。 详细地址:https://blog.csdn.net/weixin_47450795/article/details/110003413

    libgdx学习文档 DOC格式

    android 游戏框架libgdx 学习 DOC格式

    libGDX学习记录(二)阶段源码

    libGDX学习记录(二)阶段源码 展示TexturePacker合成的图片,详细地址: https://blog.csdn.net/weixin_47450795/article/details/110037945

    Libgdx专题系列第一篇 第一节

    Libgdx专题系列,第一篇第一节代码下载。

    Libgdx资源大全

    学习libgdx时整理的资料 libgdx 4 本电子书 + 6 个 github libgdx 游戏源码地址 libgdx 4本电子书: Learning LibGDX Game Development, 2nd Edition Libgdx Cross-platform Game Development Cookbook Mastering ...

    Java Game Development with LibGDX: From Beginner to Professional.pdf

    Learn to design and create video games using the Java programming language and the LibGDX software library. Working through the examples in this book, you will create 12 game prototypes in a variety ...

    Libgdx-Box2D:方块2D

    Libgdx-Box2D 方块2D

    Libgdx专题系列 第一篇 第七节

    Libgdx专题系列, 第一篇第七节代码资源文件。

    libGDX基于OpenGL(ES)的跨平台Java游戏开发框架完整项目源代码.zip

    libGDX是一个基于OpenGL(ES)的跨平台Java游戏开发框架,适用于Windows,Linux,macOS,Android,您的浏览器和iOS。libGDX 为快速原型设计和快速迭代提供了一个久经考验且强大的环境。libGDX不会强迫您使用特定的...

    libgdx_wiki学习文档

    libGdx是一个跨平台的2D/3D的游戏开发框架,它由Java/C/C++语言编写而成。libgdx兼容Windows、Linux、Max OS X、Java Applet、Javascript/WebGL与Android(1.5版本+)平台。该文档为libgdx在wiki上的官方学习文档。

    libgdx1.2版本

    libgdx是跨平台的游戏开发引擎,基于opengl es 2.0和opengl es 3.0可以一套代码开发android,ios,网页和电脑游戏,十分方便

    libGDX学习记录(二)完整源码 水果落地

    libGDX学习记录(二)完整源码水果落地 详细地址: https://editor.csdn.net/md/?articleId=110037945

    libgdx-Sprite动画文件解析

    javame框架移植到libgdx。由于libgdx采用笛卡尔坐标系,所以要处理下图片的转向。

    libgdx学习总结

    libgx学习过程总结,记录本人所遇到的问题和心得

    libgdx学习文档

    libgdx的中文学习文档,资料太少,将就用吧

Global site tag (gtag.js) - Google Analytics