引用: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

android opengl的更多相关文章

  1. 【Android】一道Android OpenGL笔试题

    一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...

  2. Android OpenGL 编写简单滤镜

    Android 上使用Opengl进行滤镜渲染效率较高,比起单纯的使用CPU给用户带来的体验会好很多.滤镜的对象是图片,图片是以Bitmap的形式表示,Opengl不能直接处理Bitmap,在Andr ...

  3. Android OpenGL ES 开发教程 从入门到精通

    感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...

  4. [工作记录] Android OpenGL ES: non-square texture - continue

    previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...

  5. Android OpenGL 学习笔记 --开始篇

    转自: http://www.cnblogs.com/TerryBlog/archive/2010/07/09/1774475.html 1.什么是 OpenGL? OpenGL 是个专业的3D程序接 ...

  6. Android OpenGL ES(一)----必备知识

    1.手机的坐标空间 我们都知道要想在手机上随心所欲的绘制图形,就必须了解手机的坐标体系.下图就是将坐标映射到手机屏幕的坐标. 图1手机屏幕基本坐标系 2.OpenGL基本图形 在OpenGL里,只能绘 ...

  7. Android OpenGL ES 3.0 纹理应用

    本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...

  8. EGL接口介绍-----Android OpenGL ES底层开发

    引自:http://www.cnitblog.com/zouzheng/archive/2011/05/30/74326.html EGL 是 OpenGL ES 和底层 Native 平台视窗系统之 ...

  9. Android OpenGL ES(十三)通用的矩阵变换指令 .

    Android OpenGL ES 对于不同坐标系下坐标变换,大都使用矩阵运算的方法来定义和实现的.这里介绍对应指定的坐标系(比如viewmodel, projection或是viewport) An ...

随机推荐

  1. GO语言练习:不定参数函数

    1.代码 2.运行 1.代码 package main import "fmt" func MyPrintf(args ...interface{}){ for _, arg := ...

  2. winform中键盘和鼠标事件的捕捉和重写(转)

    在 编写winform应用程序时,有时需要无论在哪个控件获取焦点时,对某一个键盘输入或者鼠标事件都进行同样的操作.比如编写一个处理图片的应用程序时, 希望无论当前哪个控件获得焦点,当用户按上.下.左. ...

  3. MVVM deep dive

    You can get a different instance each time by passing a different key to the GetInstance method. How ...

  4. StoryBoard--看上去很美

    StoryBoard--看上去很美 介绍 StoryBoard 是苹果在 2011 年的 WWDC Session 309<Introducing Interface Builder Story ...

  5. Linux_linux中profile、bashrc、bash_profile之间的区别和联系(转)

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. 英文描述为: # /etc/p ...

  6. Linux_文件及文件夹[创建][复制][移动][删除][重命名]

    一.文件/文件夹创建 1.文件的创建 touch , vi/vim/nano , ... 语   法: touch [-acfm][-d <日期时间>][-r <参考文件或目 录&g ...

  7. 用一段JS代码来比较各浏览器的极限内存与运算速度

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. c# 复习

    一.输入输出语句 二.异常语句 try catch  fina 保护程序,在出错的情况下也不会终止. 三.输入一个日期,判断是否正确. 每日一语:觉得自己做得到和做不到,其实只在一念之间.

  9. C++中嵌入Lua脚本环境搭建

    第一步(环境准备工作): 工具: ●LuaForWindows_v5.1.4-46.exe傻瓜式安装. 作用:此工具可以在windows环境下编译运行Lua脚本程序.安装完成后会有两个图标:Lua和S ...

  10. Android课程---环境配置很重要