Displaying Graphics with OpenGL ES(一)——构建一个OpenGL ES环境

翻译自官方文档http://developer.android.com

为了在app里绘制图形,你必须创建一个容器。最直接的方式就是实现GLSurfaceView和GLSurfaceView.Render接口。GLSurfaceView是图形和OpenGL绘图的视图控制器而GLSurefaceView.Renderer控制在视图里绘图(理解为画笔)。想了解更多这些classes,点击OpenGL ES

GLSurfaceView 只是一种在app里包含OpenGL ES图形的方式,对于全屏或接近全屏的图形视图,他是一个合理的选择。开发者们如果想在layout的小部分里体现OpenGL ES图形,你应该看一下TextureView。说真的,程序猿自己动手,也可以构建一个OpenGL ES视图用SurfaceView,但是得写相当多得额外代码。

本课程介绍怎样实现用GLSurfaceView和GLSurfaceView.Renderer做一个简单的app

1. 在Manifests声明

为了能够使用OpenGL ES 2.0 API,必须添加如下声明。

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

如果app使用了纹理压缩,必须声明压缩格式,使其只在兼容设备安装。

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

关于更多纹理压缩的格式,可参考OpenGL

2.创建一个OpenGL ES图形Activity

public class OpenGLES20Activity extends Activity {

    private GLSurfaceView mGLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        mGLView = new MyGLSurfaceView(this);
        setContentView(mGLView);
    }
}

OpenGL ES 2.0 需要api 2.2以上

3.构建一个GLSuerfaceView

GLSurfaceView 是一个特殊的veiw, 你可以在其中画OpenGL ES 图形,它本身虽然没有太多代码实现,但你也别不实现它或者直接使用它,你实现它为了获得touch events,

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        mRenderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);
    }
}

还有一个可选的设置是,把渲染模式改为 GLSurfaceView.RENDERMODE_WHEN_DIRTY ,这样仅在你的数据有变化时重新进行渲染。

// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

除非你调用requestRender(),这个设置会阻止帧被重画,有些情况下这样效率更高。

4.构建一个Render

这是一个渲染类,它控制着与之关联的GLSuerfaceView在上面画什么东西,其中3个方法需要被重写:

onSurfaceCreated() - 调用一次以建立视图的OpenGL ES的环境。
onDrawFrame() - 被执行每个重绘。

onSurfaceChanged() - 视图改变时被调用,比如屏幕方向改变

一个非常简单的实例:

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

一切就是这么简单!上面的例子使用OpenGL 显示一个黑色背景的app。尽管此代码不能做任何事情很有意思,通过创建这些类,你已经奠定需要开始绘制用OpenGL图形元素的基础。

你可能想知道为什么这些方法都有一个GL10参数,当您使用的OpenGL ES2.0 API。这些方法签名只是重复使用为2.0 API来保持Android框架代码更简单。

如果你熟悉了OpenGL ES APIS,你应该能建立一个OpenGL ES 在app里绘图。如果你需要更多的了解,请看下一课

>>Defining Shapes

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个类内部创建另一个类的对象,通常被称为“实例嵌套”或“对象作为成员”。这种做法在某些场景下是有意义并且有用的。例如,在某些系统设计中,一个类可能会封装一组相关的功能,而每个功能都可以通过创建特定类的实例来实现。 ### 实现方式 在面向对象编程语言中,如Python、C++、Java等,类内部创建对象是一种常见的实践。下面是一些基本的例子: #### Python 示例: ```python class OuterClass: def __init__(self): self.inner_obj = InnerClass() class InnerClass: def print_message(self): print("Hello from inner class") # 使用示例 outer_instance = OuterClass() outer_instance.inner_obj.print_message() # 输出 "Hello from inner class" ``` #### C++ 示例: ```cpp #include <iostream> class OuterClass { public: void displayInnerObject() { std::cout << "Displaying inner object." << std::endl; } private: class InnerClass { public: void printMessage() { std::cout << "This is an inner message." << std::endl; } }; InnerClass innerObj; }; int main() { OuterClass outerInstance; outerInstance.innerObj.printMessage(); // 输出 "This is an inner message." return 0; } ``` #### Java 示例: ```java public class OuterClass { private InnerClass innerObj; public void displayInnerObject() { System.out.println("Displaying inner object."); } static class InnerClass { public void printMessage() { System.out.println("This is an inner message."); } } public static void main(String[] args) { OuterClass.outerInstance.displayInnerObject(); new OuterClass().innerObj.printMessage(); // 输出 "This is an inner message." } } // 注意:这里的 `new OuterClass()` 实际上是静态上下文,因此需要显式创建 `OuterClass` 的实例并访问其私有字段 `innerObj` ``` ### 优点与应用场景 1. **代码复用**: 如果外类和内类之间存在紧密耦合的功能,将它们合并到一起可以减少冗余代码。 2. **模块化**: 对象作为成员允许在更复杂的模块结构中分组相关操作。 3. **封装性增强**: 将复杂的功能分解成较小的独立部分有助于更好地控制和管理程序的不同方面。 ### 注意事项 尽管实例化类在某些情况下非常有用,但也需要注意避免过度依赖于这种方法,因为它可能导致代码难以理解和维护。特别是在大型项目中,应当谨慎使用实例化类作为成员的方式,并考虑是否使用接口、抽象类或其他设计模式来提高系统的灵活性和可扩展性。 ### 相关问题: 1. **实例化类作为成员的主要目的是什么?** 2. **如何在实际应用中有效利用类的实例化特性?** 3. **何时应该避免在一个类内部实例化另一个类?**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值