二维坐标系变换为原点在左上角(测试用)
* 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);
}
protected void onPause() {
super.onPause();
contentView.onPause();
protected void onResume() {
super.onResume();
contentView.onResume();
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);
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);
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
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;
}
JOGL:
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
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 {
public void init(GLAutoDrawable drawable) {
GL2ES1 gl = drawable.getGL().getGL2ES1();
gl.glDisable(GL2ES1.GL_DITHER);
gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL2ES1.GL_FASTEST);
gl.glDisable(GL2ES1.GL_CULL_FACE);
gl.glShadeModel(GL2ES1.GL_SMOOTH);
gl.glEnable(GL2ES1.GL_DEPTH_TEST);
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
gl.glMatrixMode(GL2ES1.GL_PROJECTION);
gl.glViewport(0, 0, w, h);
gl.glOrthof(0, w, -h, 0, 0, 1);
gl.glOrthof(0, w, 0, h, 0, 1);
updateData(w, h);
public void display(GLAutoDrawable drawable) {
gl.glClear(GL2ES1.GL_COLOR_BUFFER_BIT | GL2ES1.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
gl.glEnableClientState(GL2ES1.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL2ES1.GL_FLOAT, vertexBytes, vertices);
gl.glEnableClientState(GL2ES1.GL_COLOR_ARRAY);
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);
public void dispose(GLAutoDrawable drawable) {
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)
public class Testlwjgl1 {
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();
GL11.glOrtho(0, SCREEN_WIDTH,
-SCREEN_HEIGHT, 0,
1, -1);
0, SCREEN_HEIGHT,
1, -1);
private void render() {
GL11.glMatrixMode(GL11.GL_MODELVIEW);
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();
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();
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);
textureRegion = new TextureRegion(texture, 0, h, w, -h);
pos = new Vector2(w / 2, h / 2);
dir = new Vector2(1, 1);
public void dispose() {
log("dispose");
texture.dispose();
pixmap.dispose();
sb.dispose();
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();
public void resize(int width, int height) {
sb.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
public void show() {
public void hide() {
public void pause() {
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) {
pos.x = w;
if (pos.y < 0) {
dir.y = -dir.y;
pos.y = 0;
if (pos.y > h) {
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
<a href="http://www.apress.com/9781430239871">http://www.apress.com/9781430239871</a>