Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 727|回复: 0

gallery3d 代码分析之 glsurfaceview-  Android学习

[复制链接]

该用户从未签到

发表于 2011-10-24 14:27:42 | 显示全部楼层 |阅读模式
简介
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 对象

选择一个 SurfaceGLSurfaceView 提供了接口可选择 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);

}
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 11:16 , Processed in 0.357035 second(s), 46 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表