android 控件可以用opengl es绘制吗

2025-05-15 10:27:13
推荐回答(2个)
回答1:

初始化一个opengl ES视图

初始化一个opengl 视图一向很简单,在安卓平台也不例外。你只需要从两件事入手就可以。

GLSurfaceView

GLSurfaceView是Android 1.5之后提供的一个类,可以帮助我们开发opengl ES程序。

提供glue-code用于连接opengl ES到系统视图中。

提供glue-code使opengl ES工作在Activity的生命周期。

使得选择frame buffer的像素格式变得容易。

创建并且管理一个独立的渲染线程,从而使平滑动画变得可能。

提供一个易于使用的debug工具,来跟踪opengl调用和检查错误。

如果你想要你的opengl ES应用运行流畅,这就是你需要开始了解的地方。

你唯一需要调用的方法就是:

?1public void setRenderer(GLSurfaceView.Renderer renderer)

更多可以参考这里:GLSurfaceView

GLSurfaceView.Renderer

GLSurfaceView.Renderer是GLSurfaceView的内部静态接口。在你实现这个接口的时候,你应该把你用来渲染的调用都放进来。

// 在surface被创建或者重复创建的时候调用

public void onSurfaceCreated(GL10 gl, EGLConfig config)

// 用来绘制当前帧

public void onDrawFrame(GL10 gl)

// 在surface大小改变的时候调用

public void onSurfaceChanged(GL10 gl, int width, int height)

onSurfaceCreated

这个方法适合用来初始化一些在渲染周期里不经常变动的东西。诸如用什么颜色清空屏幕,开启z-buffer等。

onDrawFrame

这是实际渲染的方法。

onSurfaceChanged

如果你的设备支持横竖屏切换,那么在切换时会被调用此方法。这个方法用来设置新的比例。

更多可以参考这里:GLSurfaceView.Renderer

组装代码

首先我们创建一个Activity,保持简洁。

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);

}

}

我们的Renderer类处理一些初始化的工作,让我们来看一下,我稍作解释。

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) {

// 设置背景色为黑色( rgba ).

gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);

// 开启平滑阴影,默认是不需要

gl.glShadeModel(GL10.GL_SMOOTH);

// 初始化depth缓冲

gl.glClearDepthf(1.0f);

// 开启depth测试

gl.glEnable(GL10.GL_DEPTH_TEST);

// 设置depth测试的类型

gl.glDepthFunc(GL10.GL_LEQUAL);

// 最佳的透视计算

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) {

// 清空屏幕和depth缓冲

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) {

// 设置当前视口大小为新值

gl.glViewport(0, 0, width, height);

// 选择投影矩阵

gl.glMatrixMode(GL10.GL_PROJECTION);

// 重置投影矩阵

gl.glLoadIdentity();

// 计算窗口的方向比例

GLU.gluPerspective(gl, 45.0f,

(float) width / (float) height,

0.1f, 100.0f);

// 选择modelview矩阵

gl.glMatrixMode(GL10.GL_MODELVIEW);

// 重置modelview矩阵

gl.glLoadIdentity();

}

}

全屏

只需要在这个openglDemo类中添加这几行代码,就可以全屏了。

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.

}

回答2:

Frame Buffer 对象的概念可以参见前面文章Android OpenGL ES 开发教程(23):FrameBuffer。
简单的和2D图像类比,Frame Buffer 如果 对应到二维图形环境中,就是一个2D的内存数组空间,缺省情况为屏幕的显存,也可以创建Offscreen 内存空间,此时Frame Buffer 可以是一个二维数组,数组每个元素代表一个像素颜色。
对于三维图形来说,除了需要代表颜色的二维数组(Color Buffer),还需要深度二维数组(Depth Buffer) 或遮罩数组(Stencil Buffer),因此在OpenGL 中的Frame Buffer为上述Color Buffer,Depth Buffer,Stencil Buffer 的集合。如果手机具有GPU,其缺省的Frame Buffer也是3D屏幕显示区域。
通过Opengl ES扩展支持,应用程序也可以创建内存中的Frame Buffer对象(不用于屏幕显示)。通过这种应用程序创建的FrameBuffer对象,OpenGL应用可以将图像显示输出重新定向到这个非屏幕显示用FrameBuffer对象中,类似于二维图形绘制中常用的Offscreen 技术。
和缺省的屏幕显示FrameBuffer一样,由应用程序创建的FrameBuffer对象也是由Color Buffer, Depth Buffer和Stencil Buffer(可选)的集合组成。这些Buffer在FrameBuffer对象中可以称为FrameBuffer-attachable 图像,FrameBuffer定义了一些接入点(Attachment Point)可以用于连接(Attach)这些Buffer数组。
OpenGL ES定义了两种FrameBuffer-attachable 图像,Texture 和 renderbuffer ,简单的可以将Texture 理解为Color buffer 或是2D图像,render buffer 对应于depth buffer。