2009年12月3日 由每埃里克·伯格曼 在安卓,嵌入式,Java的 | 90评论
我已经在OpenGL ES 2.0 for android上开始了一个新的更新系列教程。请查看:OpenGL ES 2.0
我将在Android手机上编写一些关于使用OpenGL ES的教程。OpenGL ES的理论在不同的设备上是相同的,因此将它们转换到另一个平台应该很容易。
我不能总是记得我找到特定信息的位置,所以我可能无法总是给你正确的参考。如果您觉得我从您那里借来的东西但是忘了加你作为参考,请发电子邮件给我。
在代码示例中,我将为每个函数提供两个不同的链接。实际的功能将链接到android文档,之后我还将链接OpenGL文档。像这样:
1 |
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); |
那么,让我们开始吧。
在本教程中,我将向您展示如何设置OpenGL ES视图,这始终是一个很好的起点。
设置OpenGL ES视图
设置OpenGL视图从未如此艰难,在Android上它仍然很容易。开始时只需要两件事。
GLSurfaceView
GLSurfaceView是Android 1.5中的API类,可帮助您编写OpenGL ES应用程序。
- 提供粘合代码以将OpenGL ES连接到View系统。
- 提供粘合代码,使OpenGL ES与Activity生命周期一起工作。
- 可以轻松选择合适的帧缓冲像素格式。
- 创建和管理单独的渲染线程以启用平滑动画。
- 提供易于使用的调试工具,用于跟踪OpenGL ES API调用和检查错误。
如果您想快速使用OpenGL ES应用程序,那么您应该从这里开始。
您需要调用的唯一功能是:
1 |
public void setRenderer(GLSurfaceView.Renderer renderer) |
阅读更多:GLSurfaceView
GLSurfaceView.Renderer
GLSurfaceView.Renderer是一个通用的渲染界面。在您对此渲染器的实现中,您应该将所有调用放在渲染帧中。
有三个功能要实现:
1 2 3 4 5 6 7 8 |
// Called when the surface is created or recreated. public void onSurfaceCreated(GL10 gl, EGLConfig config)
// Called to draw the current frame. public void onDrawFrame(GL10 gl)
// Called when the surface changed size. public void onSurfaceChanged(GL10 gl, int width, int height) |
onSurfaceCreated
在渲染周期中设置您不经常更改的内容是一件好事。像清除屏幕的颜色,启用z缓冲区等等。
onDrawFrame
这是实际绘图的地方。
onSurfaceChanged
如果您的设备支持在横向和纵向之间翻转,则会在发生此功能时调用此功能。你在这里做的是设置新比率。
阅读更多:GLSurfaceView.Renderer
把它放在一起
首先,我们创建我们的活动,我们保持干净和简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package se.jayway.opengl.tutorial;
import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle;
public class TutorialPartI extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer()); setContentView(view); } } |
我们的渲染器需要更多的工作来设置,看看它,我会更多地解释代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
package se.jayway.opengl.tutorial;
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU; import android.opengl.GLSurfaceView.Renderer;
public class OpenGLRenderer implements Renderer { /* * (non-Javadoc) * * @see * android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax. * microedition.khronos.opengles.GL10, javax.microedition.khronos. * egl.EGLConfig) */ public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Set the background color to black ( rgba ). gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Enable Smooth Shading, default not really needed. gl.glShadeModel(GL10.GL_SMOOTH); // Depth buffer setup. gl.glClearDepthf(1.0f); // Enables depth testing. gl.glEnable(GL10.GL_DEPTH_TEST); // The type of depth testing to do. gl.glDepthFunc(GL10.GL_LEQUAL); // Really nice perspective calculations. gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); }
/* * (non-Javadoc) * * @see * android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax. * microedition.khronos.opengles.GL10) */ public void onDrawFrame(GL10 gl) { // Clears the screen and depth buffer. gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // GL10.GL_DEPTH_BUFFER_BIT); }
/* * (non-Javadoc) * * @see * android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax. * microedition.khronos.opengles.GL10, int, int) */ public void onSurfaceChanged(GL10 gl, int width, int height) { // Sets the current view port to the new size. gl.glViewport(0, 0, width, height); // Select the projection matrix gl.glMatrixMode(GL10.GL_PROJECTION); // Reset the projection matrix gl.glLoadIdentity(); // Calculate the aspect ratio of the window GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f); // Select the modelview matrix gl.glMatrixMode(GL10.GL_MODELVIEW); // Reset the modelview matrix gl.glLoadIdentity(); } } |
全屏
只需在OpenGLDemo类中添加这些行,您就会获得全屏。
1 2 3 4 5 6 7 |
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); // (NEW) getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // (NEW) ... // Previous code. } |
这几乎是您启动和运行视图所需的全部内容。如果你编译并运行它,你会看到一个漂亮的黑屏。