文档章节

介绍GLSurfaceView

来来叔叔
 来来叔叔
发布于 2017/08/04 23:57
字数 1221
阅读 1
收藏 0

转自 http://www.linuxgraphics.cn/android/gallery3d_glsurfaceview.html

 

重点有以下几点:

1.派生GLSurfaceView来实现事件交互等

2.GLSurfaceView提供了QueueEvent这个简单的方法来实现跨线程事件交互(UI线程和渲染线程)

3.对于反应式的应用,可以使用

GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);

GLSurfaceView.requestRender();来进行渲染请求。

 

简介

SDK 中的 android.opengl.GLSurfaceView 类提供如下功能:

  • OpenGL ES 和 View 系统之间建立联系;
  • 使得 OpenGL ES 可以工作在 Activity 生命周期中;
  • 可选择合适的 frame buffer 像素格式;
  • 创建并管理一个单独的渲染线程,可以实现平滑的动画;
  • 提供 debugging 工具和 API。

一个简单的 GLSurfaceView 应用

package com.example.android.apis.graphics;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class ClearActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new GLSurfaceView(this);
        mGLView.setRenderer(new ClearRenderer());
        setContentView(mGLView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLView.onResume();
    }

    private GLSurfaceView mGLView;
}

class ClearRenderer implements GLSurfaceView.Renderer {
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Do nothing special.
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
        gl.glViewport(0, 0, w, h);
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }
}

这个程序功能很简单,每帧绘制时将屏幕设置成黑色。但它是一个完整的工作在 Activity 生命周期中的 OpenGL 程序。当 activity 暂停时,它暂停渲染;当 activity 继续时,它继续渲染。可以将这个程序用作非交互式的 demo 程序。可以在 ClearRenderer.onDrawFrame() 接口中增加 OpenGL 调用做很多的绘制。

GLSurfaceView.Render 接口有三个方法:

  • onSurfaceCreated():该方法在渲染开始前调用,OpenGL ES 的绘制上下文被重建时也会被调用。当 activity 暂停时绘制上下文会丢失,当 activity 继续时,绘制上下文会被重建。另外,创建长期存在的 OpenGL 资源(如 texture)往往也在这里进行。
  • onSurfaceChanged():当 surface 的尺寸发生改变时该方法被调用。往往在这里设置 viewport。若你的 camera 是固定的,也可以在这里设置 camera。
  • onDrawFrame():每帧都通过该方法进行绘制。绘制时通常先调用 glClear 函数来清空 framebuffer,然后在调用 OpenGL ES 的起它的接口进行绘制。

输入如何处理

若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件。下面有个例子:

package com.google.android.ClearTest;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

public class ClearActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLView = new ClearGLSurfaceView(this);
        setContentView(mGLView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLView.onResume();
    }

    private GLSurfaceView mGLView;
}

class ClearGLSurfaceView extends GLSurfaceView {
    public ClearGLSurfaceView(Context context) {
        super(context);
        mRenderer = new ClearRenderer();
        setRenderer(mRenderer);
    }

    public boolean onTouchEvent(final MotionEvent event) {
        queueEvent(new Runnable(){
            public void run() {
                mRenderer.setColor(event.getX() / getWidth(),
                        event.getY() / getHeight(), 1.0f);
            }});
            return true;
        }

        ClearRenderer mRenderer;
}

class ClearRenderer implements GLSurfaceView.Renderer {
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Do nothing special.
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
        gl.glViewport(0, 0, w, h);
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }

    public void setColor(float r, float g, float b) {
        mRed = r;
        mGreen = g;
        mBlue = b;
    }

    private float mRed;
    private float mGreen;
    private float mBlue;
}

这个应用在每一帧中清空屏幕。当 tap 屏幕时,改变屏幕的颜色。这里在 ClearGLSurfaceView.onTouchEvent() 中使用了 queueEvent()。queueEvent() 方法用于在 UI 线程和渲染线程间通信。也可以用起它的 Java 线程通信技术,如 synchronized 方法,但 queueEvent 最简单的线程通信方法。

其他的 GLSurfaceView 例子

Android SDK 的 API Demo例子程序中还有很多例子:

  • GLSurfaceView
  • Kube
  • Translucent GLSurfaceView:透明背景
  • Textured Triangle:纹理贴图
  • Sprite Text:在 texture 上写文本并显示在 3D 场景中
  • Touch Rotate:旋转 3D 对象

选择一个 Surface

GLSurfaceView 提供了接口可选择 surface 的类型。默认情况下, GLSurfaceView 会使用一个 16 位 RGB frame buffer,带 16 位深度。你也可以根据自己的需要进行选择,比如在 Translucent GLSurfaceView 例子里,需要一个 Alpha 通道来实现透明。GLSurfaceView 提供了 setEGLSurfaceChooser()方法来选择 surface。

选择一个 RGB (565)的16位 framebuffer,接口如下:

setEGLConfigChooser(boolean needDepth)

若要定制 red, green, blue, alpha 和 depth,则用如下接口:

setEGLConfigChooser(int redSize, int greenSize,int blueSize, int alphaSize,int depthSize, int stencilSize)

使用自己实现的 EGLConfigChooser,用如下的接口:

setEGLConfigChooser(EGLConfigChooser configChooser)

持续型渲染模式 & 通知型渲染模式

大多数 3D 应用,如游戏、模拟等都是持续型渲染的动画,还有些 3D 应用是反应式的(reactive),它们往往先被动等待,当用户有了动作再做出反应。对于这种应用,持续渲染屏幕是浪费时间。若开发反应式的应用,可以调用下面的方法

GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);

停止持续渲染。当调用

GLSurfaceView.requestRender()

时,程序再渲染屏幕。

调试

GLSurfaceView.setDebugFlags() 方法可以激活 log 或者错误检测,它们可以帮助调试 OpenGL ES 调用。具体使用时,在 GLSurfaceView 的构造函数中,调用 setRender() 之前调用 GLSurfaceView.setDebugFlags()就可以了。下面是个例子:

public ClearGLSurfaceView(Context context) {
    super(context);
    // Turn on error-checking and logging
    setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
    mRenderer = new ClearRenderer();
    setRenderer(mRenderer);
}

© 著作权归作者所有

来来叔叔
粉丝 0
博文 100
码字总数 55732
作品 0
广州
高级程序员
私信 提问
OpenGL ES之GLSurfaceView学习一:介绍

from: http://blog.csdn.net/chenjie19891104/article/details/6311209 GLSurfaceView是一个视图,继承至SurfaceView,它内嵌的surface专门负责OpenGL渲染。 GLSurfaceView提供了下列特性: ......

aspirs
2016/02/02
77
0
图片和图形之构建一个OpenGL ES环境(10)

原文 概要 构建一个OpenGL ES环境 为了在Android应用程序中使用OpenGL ES绘制图形,您必须为它们创建一个视图容器。其中一种更直接的方法是实现a GLSurfaceView和a GLSurfaceView.Renderer。...

lichong951
2018/05/26
0
0
Android中的OpenGL ES使用基础

一、OpenGL/EGL 因为Android的GUI系统是基于OpenGL/EGL实现的,所以先介绍相关基础知识。 OpenGL(Open Graphics Library)已占据虚拟现实、CAD、能源、游戏研发等多个行业领域,是跨语言,跨平...

liaowenhao
2017/11/23
0
0
Android videoview glsurfaceview 冲突

在videoview加上glsurfaceview videoview'是用于播放视频 glsurfaceview是现实摄像头实时传输的画面 刚进去glsurfaceview显示视频了没有显示glsurfaceview 把手机手动失去焦点 在获得焦点 gl...

potential
2015/03/04
1K
0
Android 使用 OpenGL ES 绘制三角形

1. OpenGL ES 简介 OpenGL 是一个跨平台的图形 API,为 3D 图形处理硬件制定了一个标准软件接口。OpenGL ES 是为嵌入式设备设计的 OpenGL 规范,Android 提供了对 OpenGL ES 的支持。 OpenGL...

落英坠露
05/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java FOR-EACH循环

FOR-EACH循环使得代码更加的简短,也让代码更加易懂,其实他并没有加入什么新的功能。他的功能完全可以用简单的FOR循环代替。 for-each的用法: int a[] = {1,2,3,4,5,6} for(int s:a){ Syst...

无名氏的程序员
15分钟前
2
0
使用HTML5的History API

本文转载于:专业的前端网站➣使用HTML5的History API   HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL。这个功能很有用,例如通过一段JavaScript代...

前端老手
17分钟前
2
0
JAVA 编写redisUtils工具类,防止高并发获取缓存出现并发问题

import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.BoundHashOperations;import org.springframework.data.redis.core.BoundValueOperations;import org.......

huangkejie
59分钟前
7
0
JMM内存模型(一)&volatile关键字的可见性

在说这个之前,我想先说一下计算机的内存模型: CPU在执行的时候,肯定要有数据,而数据在内存中放着呢,这里的内存就是计算机的物理内存,刚开始还好,但是随着技术的发展,CPU处理的速度越...

走向人生巅峰的大路
今天
98
0
你对AJAX认知有多少(2)?

接着昨日内容,我们几天继续探讨ajax的相关知识点 提到ajax下面几个问题又是必须要了解的啦~~~ 8、在浏览器端如何得到服务器端响应的XML数据。 通过XMLHttpRequest对象的responseXMl属性 9、 ...

理性思考
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部