天天看点

android opengl

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

* GLES

* JOGL

* LWJGL

* libgdx(使用g2d与pixmap)

android opengl

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:

android opengl

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:

android opengl

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绘画)

android opengl

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>

继续阅读