android opengl

时间:2022-06-20 22:19:44
android opengl

引用:http://weimingtom.iteye.com/blog/1616972

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

* GLES

* JOGL

* LWJGL

* libgdx(使用g2d与pixmap)

  1. package com.iteye.weimingtom.testgl;
  2. import java.nio.ByteBuffer;
  3. import java.nio.ByteOrder;
  4. import java.nio.IntBuffer;
  5. import javax.microedition.khronos.egl.EGLConfig;
  6. import javax.microedition.khronos.opengles.GL10;
  7. import android.app.Activity;
  8. import android.opengl.GLSurfaceView;
  9. import android.os.Bundle;
  10. import android.view.Window;
  11. import android.view.WindowManager;
  12. public class Testgl3Activity extends Activity implements GLSurfaceView.Renderer {
  13. private boolean USE_ORIGIN_TOPLEFT = true;
  14. private IntBuffer vertices;
  15. private int vertexBytes;
  16. private int vertexNum;
  17. private float[] arrVertices;
  18. private int[] tmpBuffer;
  19. private GLSurfaceView contentView;
  20. @Override
  21. protected void onCreate(Bundle savedInstanceState) {
  22. super.onCreate(savedInstanceState);
  23. requestWindowFeature(Window.FEATURE_NO_TITLE);
  24. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  25. WindowManager.LayoutParams.FLAG_FULLSCREEN);
  26. contentView = new GLSurfaceView(this);
  27. contentView.setRenderer(this);
  28. setContentView(contentView);
  29. }
  30. @Override
  31. protected void onPause() {
  32. super.onPause();
  33. contentView.onPause();
  34. }
  35. @Override
  36. protected void onResume() {
  37. super.onResume();
  38. contentView.onResume();
  39. }
  40. @Override
  41. public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  42. loadData();
  43. gl.glDisable(GL10.GL_DITHER);
  44. gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
  45. gl.glClearColor(1, 1, 1, 1);
  46. gl.glDisable(GL10.GL_CULL_FACE);
  47. gl.glShadeModel(GL10.GL_SMOOTH);
  48. gl.glEnable(GL10.GL_DEPTH_TEST);
  49. }
  50. @Override
  51. public void onSurfaceChanged(GL10 gl, int width, int height) {
  52. gl.glMatrixMode(GL10.GL_PROJECTION);
  53. gl.glLoadIdentity();
  54. gl.glViewport(0, 0, width, height);
  55. //gl.glViewport(0, height, width, height);
  56. if (USE_ORIGIN_TOPLEFT) {
  57. gl.glOrthof(0, width, -height, 0, 0, 1);
  58. } else {
  59. gl.glOrthof(0, width, 0, height, 0, 1);
  60. }
  61. updateData(width, height);
  62. }
  63. @Override
  64. public void onDrawFrame(GL10 gl) {
  65. gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  66. gl.glMatrixMode(GL10.GL_MODELVIEW);
  67. gl.glLoadIdentity();
  68. if (USE_ORIGIN_TOPLEFT) {
  69. gl.glScalef(1f, -1f, 1f);
  70. }
  71. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  72. vertices.position(0);
  73. gl.glVertexPointer(3, GL10.GL_FLOAT, vertexBytes, vertices);
  74. gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
  75. vertices.position(3);
  76. gl.glColorPointer(4, GL10.GL_FLOAT, vertexBytes, vertices);
  77. gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, vertexNum);
  78. gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
  79. gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  80. }
  81. private void loadData() {
  82. final float factor = 200f / 320f * 100;
  83. this.arrVertices = new float[] {
  84. 0f * factor, 0f * factor, 0, 0, 0, 1, 1,
  85. 1f * factor, 0f * factor,   0, 0, 0, 1, 1,
  86. 1f * factor, 1f * factor, 0, 0, 0, 1, 1,
  87. 0f * factor,  1f * factor,  0, 0, 0, 1, 1,
  88. };
  89. this.vertexBytes = (3 + 4) * (Integer.SIZE / 8);
  90. this.vertexNum = arrVertices.length / (this.vertexBytes / (Integer.SIZE / 8));
  91. this.tmpBuffer = new int[vertexNum * vertexBytes / (Integer.SIZE / 8)];
  92. ByteBuffer buffer = ByteBuffer.allocateDirect(vertexNum * vertexBytes);
  93. buffer.order(ByteOrder.nativeOrder());
  94. vertices = buffer.asIntBuffer();
  95. this.vertices.clear();
  96. for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
  97. tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
  98. }
  99. this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
  100. this.vertices.flip();
  101. }
  102. private void updateData(int width, int height) {
  103. arrVertices[0] = 100f;
  104. arrVertices[1] = 100f;
  105. arrVertices[0 + 7] = width - 10;
  106. arrVertices[1 + 7] = 0;
  107. arrVertices[0 + 14] = width - 10;
  108. arrVertices[1 + 14] = height - 10;
  109. arrVertices[0 + 21] = 0;
  110. arrVertices[1 + 21] = height - 10;
  111. this.vertices.clear();
  112. for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
  113. tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
  114. }
  115. this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
  116. this.vertices.flip();
  117. }
  118. }

JOGL:

  1. import java.awt.Frame;
  2. import java.awt.event.WindowAdapter;
  3. import java.awt.event.WindowEvent;
  4. import java.nio.ByteBuffer;
  5. import java.nio.ByteOrder;
  6. import java.nio.IntBuffer;
  7. import javax.media.opengl.GL2ES1;
  8. import javax.media.opengl.GLAutoDrawable;
  9. import javax.media.opengl.GLCapabilities;
  10. import javax.media.opengl.GLEventListener;
  11. import javax.media.opengl.GLProfile;
  12. import javax.media.opengl.awt.GLCanvas;
  13. import com.jogamp.opengl.util.FPSAnimator;
  14. /**
  15. * gluegen-rt-natives-windows-i586.jar
  16. * gluegen-rt.jar
  17. * gluegen.jar
  18. * jogl-all-natives-windows-i586.jar
  19. * jogl.all.jar
  20. *
  21. * @see sites.google.com/site/justinscsstuff/jogl-tutorial-3
  22. * @author Administrator
  23. *
  24. */
  25. public class TestGLES1 implements GLEventListener {
  26. private boolean USE_ORIGIN_TOPLEFT = true;
  27. private IntBuffer vertices;
  28. private int vertexBytes;
  29. private int vertexNum;
  30. private float[] arrVertices;
  31. private int[] tmpBuffer;
  32. @Override
  33. public void init(GLAutoDrawable drawable) {
  34. GL2ES1 gl = drawable.getGL().getGL2ES1();
  35. loadData();
  36. gl.glDisable(GL2ES1.GL_DITHER);
  37. gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL2ES1.GL_FASTEST);
  38. gl.glClearColor(1, 1, 1, 1);
  39. gl.glDisable(GL2ES1.GL_CULL_FACE);
  40. gl.glShadeModel(GL2ES1.GL_SMOOTH);
  41. gl.glEnable(GL2ES1.GL_DEPTH_TEST);
  42. }
  43. @Override
  44. public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
  45. GL2ES1 gl = drawable.getGL().getGL2ES1();
  46. gl.glMatrixMode(GL2ES1.GL_PROJECTION);
  47. gl.glLoadIdentity();
  48. gl.glViewport(0, 0, w, h);
  49. //gl.glViewport(0, height, width, height);
  50. if (USE_ORIGIN_TOPLEFT) {
  51. gl.glOrthof(0, w, -h, 0, 0, 1);
  52. } else {
  53. gl.glOrthof(0, w, 0, h, 0, 1);
  54. }
  55. updateData(w, h);
  56. }
  57. @Override
  58. public void display(GLAutoDrawable drawable) {
  59. GL2ES1 gl = drawable.getGL().getGL2ES1();
  60. gl.glClear(GL2ES1.GL_COLOR_BUFFER_BIT | GL2ES1.GL_DEPTH_BUFFER_BIT);
  61. gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
  62. gl.glLoadIdentity();
  63. if (USE_ORIGIN_TOPLEFT) {
  64. gl.glScalef(1f, -1f, 1f);
  65. }
  66. gl.glEnableClientState(GL2ES1.GL_VERTEX_ARRAY);
  67. vertices.position(0);
  68. gl.glVertexPointer(3, GL2ES1.GL_FLOAT, vertexBytes, vertices);
  69. gl.glEnableClientState(GL2ES1.GL_COLOR_ARRAY);
  70. vertices.position(3);
  71. gl.glColorPointer(4, GL2ES1.GL_FLOAT, vertexBytes, vertices);
  72. gl.glDrawArrays(GL2ES1.GL_TRIANGLE_FAN, 0, vertexNum);
  73. gl.glDisableClientState(GL2ES1.GL_COLOR_ARRAY);
  74. gl.glDisableClientState(GL2ES1.GL_VERTEX_ARRAY);
  75. }
  76. @Override
  77. public void dispose(GLAutoDrawable drawable) {
  78. }
  79. private void loadData() {
  80. final float factor = 200f / 320f * 100;
  81. this.arrVertices = new float[] {
  82. 0f * factor, 0f * factor, 0, 0, 0, 1, 1,
  83. 1f * factor, 0f * factor,   0, 0, 0, 1, 1,
  84. 1f * factor, 1f * factor, 0, 0, 0, 1, 1,
  85. 0f * factor,  1f * factor,  0, 0, 0, 1, 1,
  86. };
  87. this.vertexBytes = (3 + 4) * (Integer.SIZE / 8);
  88. this.vertexNum = arrVertices.length / (this.vertexBytes / (Integer.SIZE / 8));
  89. this.tmpBuffer = new int[vertexNum * vertexBytes / (Integer.SIZE / 8)];
  90. ByteBuffer buffer = ByteBuffer.allocateDirect(vertexNum * vertexBytes);
  91. buffer.order(ByteOrder.nativeOrder());
  92. vertices = buffer.asIntBuffer();
  93. this.vertices.clear();
  94. for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
  95. tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
  96. }
  97. this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
  98. this.vertices.flip();
  99. }
  100. private void updateData(int width, int height) {
  101. arrVertices[0] = 100f;
  102. arrVertices[1] = 100f;
  103. arrVertices[0 + 7] = width - 10;
  104. arrVertices[1 + 7] = 0;
  105. arrVertices[0 + 14] = width - 10;
  106. arrVertices[1 + 14] = height - 10;
  107. arrVertices[0 + 21] = 0;
  108. arrVertices[1 + 21] = height - 10;
  109. this.vertices.clear();
  110. for (int i = 0, j = 0; i < arrVertices.length; i++, j++) {
  111. tmpBuffer[j] = Float.floatToRawIntBits(arrVertices[i]);
  112. }
  113. this.vertices.put(tmpBuffer, 0, tmpBuffer.length);
  114. this.vertices.flip();
  115. }
  116. public static void main(String[] args) {
  117. GLProfile glp = GLProfile.getDefault();
  118. GLCapabilities caps = new GLCapabilities(glp);
  119. GLCanvas canvas = new GLCanvas(caps);
  120. Frame frame = new Frame("AWT Window Test");
  121. frame.setSize(240, 320);
  122. frame.setResizable(false);
  123. frame.setLocationRelativeTo(null);
  124. frame.add(canvas);
  125. frame.setVisible(true);
  126. frame.addWindowListener(new WindowAdapter() {
  127. public void windowClosing(WindowEvent e) {
  128. System.exit(0);
  129. }
  130. });
  131. canvas.addGLEventListener(new TestGLES1());
  132. FPSAnimator animator = new FPSAnimator(canvas, 60);
  133. animator.add(canvas);
  134. animator.start();
  135. }
  136. }

LWJGL:

  1. import org.lwjgl.LWJGLException;
  2. import org.lwjgl.opengl.Display;
  3. import org.lwjgl.opengl.DisplayMode;
  4. import org.lwjgl.opengl.GL11;
  5. /**
  6. * lwjgl.jar : native library location -> testlwjgl/native/windows
  7. *
  8. * @see http://lwjgl.org/wiki/index.php?title=LWJGL_Basics_1_(The_Display)
  9. * @see http://lwjgl.org/wiki/index.php?title=LWJGL_Basics_3_(The_Quad)
  10. * @author Administrator
  11. *
  12. */
  13. public class Testlwjgl1 {
  14. private boolean USE_ORIGIN_TOPLEFT = true;
  15. private final static int SCREEN_WIDTH = 240;
  16. private final static int SCREEN_HEIGHT = 320;
  17. public void start() {
  18. try {
  19. Display.setDisplayMode(new DisplayMode(
  20. SCREEN_WIDTH, SCREEN_HEIGHT));
  21. Display.create();
  22. } catch (LWJGLException e) {
  23. e.printStackTrace();
  24. System.exit(0);
  25. }
  26. init();
  27. while (!Display.isCloseRequested()) {
  28. render();
  29. Display.update();
  30. }
  31. Display.destroy();
  32. }
  33. private void init() {
  34. GL11.glMatrixMode(GL11.GL_PROJECTION);
  35. GL11.glLoadIdentity();
  36. if (USE_ORIGIN_TOPLEFT) {
  37. GL11.glOrtho(0, SCREEN_WIDTH,
  38. -SCREEN_HEIGHT, 0,
  39. 1, -1);
  40. } else {
  41. GL11.glOrtho(0, SCREEN_WIDTH,
  42. 0, SCREEN_HEIGHT,
  43. 1, -1);
  44. }
  45. }
  46. private void render() {
  47. GL11.glMatrixMode(GL11.GL_MODELVIEW);
  48. GL11.glLoadIdentity();
  49. if (USE_ORIGIN_TOPLEFT) {
  50. GL11.glScalef(1f, -1f, 1f);
  51. }
  52. GL11.glClear(GL11.GL_COLOR_BUFFER_BIT |
  53. GL11.GL_DEPTH_BUFFER_BIT);
  54. GL11.glClearColor(1, 1, 1, 1);
  55. GL11.glColor3f(0.0f, 0.0f, 1.0f);
  56. GL11.glBegin(GL11.GL_TRIANGLE_FAN);
  57. {
  58. GL11.glVertex2f(100, 100);
  59. GL11.glVertex2f(SCREEN_WIDTH - 10, 0);
  60. GL11.glVertex2f(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 10);
  61. GL11.glVertex2f(0, SCREEN_HEIGHT - 10);
  62. }
  63. GL11.glEnd();
  64. }
  65. public static void main(String[] args) {
  66. new Testlwjgl1().start();
  67. }
  68. }

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

  1. package com.iteye.weimingtom.libgdxtest;
  2. import com.badlogic.gdx.Application;
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.Screen;
  5. import com.badlogic.gdx.graphics.Color;
  6. import com.badlogic.gdx.graphics.FPSLogger;
  7. import com.badlogic.gdx.graphics.GL10;
  8. import com.badlogic.gdx.graphics.Pixmap;
  9. import com.badlogic.gdx.graphics.Texture;
  10. import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  11. import com.badlogic.gdx.graphics.g2d.TextureRegion;
  12. import com.badlogic.gdx.math.MathUtils;
  13. import com.badlogic.gdx.math.Vector2;
  14. public class Test001Screen implements Screen {
  15. private final static boolean DIRECTION_DOWN = true;
  16. private final static int BOX_W = 50;
  17. private final static int BOX_H = 50;
  18. private int LOG_LEVEL = Application.LOG_DEBUG;
  19. private final static String TAG = "Test001Screen";
  20. private FPSLogger logger;
  21. private SpriteBatch sb;
  22. private Pixmap pixmap;
  23. private Texture texture;
  24. private TextureRegion textureRegion;
  25. private Vector2 pos;
  26. private Vector2 dir;
  27. public Test001Screen() {
  28. Gdx.app.setLogLevel(LOG_LEVEL);
  29. logger = new FPSLogger();
  30. init();
  31. }
  32. private void init() {
  33. log("init");
  34. sb = new SpriteBatch();
  35. int w = Gdx.graphics.getWidth();
  36. int h = Gdx.graphics.getHeight();
  37. pixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888);
  38. final int potW = MathUtils.nextPowerOfTwo(w);
  39. final int potH = MathUtils.nextPowerOfTwo(h);
  40. texture = new Texture(potW, potH, Pixmap.Format.RGBA8888);
  41. if (DIRECTION_DOWN) {
  42. textureRegion = new TextureRegion(texture, 0, 0, w, h);
  43. } else {
  44. textureRegion = new TextureRegion(texture, 0, h, w, -h);
  45. }
  46. pos = new Vector2(w / 2, h / 2);
  47. dir = new Vector2(1, 1);
  48. }
  49. @Override
  50. public void dispose() {
  51. log("dispose");
  52. texture.dispose();
  53. pixmap.dispose();
  54. sb.dispose();
  55. }
  56. @Override
  57. public void render(float delta) {
  58. onUpdate(delta);
  59. GL10 gl = Gdx.gl10;
  60. gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  61. gl.glClearColor(0, 0, 0, 0);
  62. //gl.glClearColor(1, 1, 1, 1);
  63. onRender();
  64. sb.begin();
  65. texture.draw(pixmap, 0, 0);
  66. sb.draw(textureRegion, 0, 0);
  67. sb.end();
  68. logger.log();
  69. }
  70. @Override
  71. public void resize(int width, int height) {
  72. sb.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
  73. }
  74. @Override
  75. public void show() {
  76. }
  77. @Override
  78. public void hide() {
  79. }
  80. @Override
  81. public void pause() {
  82. }
  83. @Override
  84. public void resume() {
  85. }
  86. private void onUpdate(float delta) {
  87. int w = pixmap.getWidth();
  88. int h = pixmap.getHeight();
  89. pos.x += dir.x * delta * 60;
  90. pos.y += dir.y * delta * 60;
  91. if (pos.x < 0) {
  92. dir.x = -dir.x;
  93. pos.x = 0;
  94. }
  95. if (pos.x > w) {
  96. dir.x = -dir.x;
  97. pos.x = w;
  98. }
  99. if (pos.y < 0) {
  100. dir.y = -dir.y;
  101. pos.y = 0;
  102. }
  103. if (pos.y > h) {
  104. dir.y = -dir.y;
  105. pos.y = h;
  106. }
  107. }
  108. private void onRender() {
  109. pixmap.setColor(0, 0, 0, 0);
  110. pixmap.fill();
  111. pixmap.setColor(Color.BLUE);
  112. pixmap.fillRectangle(
  113. (int)pos.x - BOX_W / 2, (int)pos.y - BOX_H / 2,
  114. BOX_W, BOX_H);
  115. }
  116. private void log(String message) {
  117. Gdx.app.log(TAG, message);
  118. }
  119. }

X. 参考资料:

1. Beginning Android 4 Games Development

随书代码Source Code/Downloads

http://www.apress.com/9781430239871