文档章节

在android中使用OpenGL

WolfCS
 WolfCS
发布于 2013/02/26 22:08
字数 673
阅读 6298
收藏 4
点赞 0
评论 0

在android中使用OpenGL ES需要三个步骤:

1. 创建GLSurfaceView组件,使用Activity来显示GLSurfaceView组建。

2. 为GLSurfaceView组建创建GLSurfaceView.Renderer实例,实现GLSurfaceView.Renderer类时需要实现该接口里的三个方法:

  • abstract void onDrawFrame(GL10 gl):Called to draw the current frame.

  • abstract void onSurfaceChanged(GL10 gl, int width, int height):Called when the surface changed size.

  • abstract void onSurfaceCreated(GL10 gl, EGLConfig config):Called when the surface is created or recreated.

3. 调用GLSurfaceView组建的setRenderer (GLSurfaceView.Renderer renderer) 方法指定Renderer对象,该对象将会完成GLSurfaceView里3D图形的绘制。

然后来看一个Demo,首先是主Activity:

package com.example.androidgldemo;

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

public class AndroidGLDemo extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glView = new GLSurfaceView(this);
        AndroidGLDemoRenderer renderer = new AndroidGLDemoRenderer();
        glView.setRenderer(renderer);
        setContentView(glView);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

然后是Renderer的实现:

package com.example.androidgldemo;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

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

import android.opengl.GLSurfaceView.Renderer;

public class AndroidGLDemoRenderer implements Renderer {
    float[] mTriangleData = new float[] {
            0.1f, 0.6f, 0.0f,
            -0.3f, 0.0f, 0.0f,
            0.3f, 0.1f, 0.0f
    };
    int[] mTriangleColor = new int[] {
            65535, 0, 0, 0, 
            0, 65535, 0, 0,
            0, 0, 65535, 0,
    };
    
    float[] mRectData = new float[] {
            0.4f, 0.4f, 0.0f,
            0.4f, -0.4f, 0.0f,
            -0.4f, 0.4f, 0.0f, 
            -0.4f, -0.4f, 0.0f
    };
    
    int[] mRectColor = new int[] {
            0, 65535, 0, 0, 
            0, 0, 65535, 0, 
            65535, 0, 0, 0,
            65535, 65535, 0, 0,
    };
    
    FloatBuffer mTriangleDataBuffer;
    IntBuffer mTriangleColorBuffer;
    
    FloatBuffer mRectDataBuffer;
    IntBuffer mRectColorBuffer;
    
    public AndroidGLDemoRenderer() {
        mTriangleDataBuffer= bufferUtil(mTriangleData);
        mTriangleColorBuffer = bufferUtil(mTriangleColor);
        
        mRectDataBuffer = bufferUtil(mRectData);
        mRectColorBuffer = bufferUtil(mRectColor);
    }
    
    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        
        gl.glLoadIdentity();
        gl.glTranslatef(-0.6f, 0.0f, -1.5f);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleDataBuffer);
        gl.glColorPointer(4, GL10.GL_FIXED, 0, mTriangleColorBuffer);
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        
        gl.glLoadIdentity();
        gl.glTranslatef(0.6f, 0.8f, -1.5f);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mRectDataBuffer);
        gl.glColorPointer(4, GL10.GL_FIXED, 0, mRectColorBuffer);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        
        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float) width / height;
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(0, 0, 0, 0);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
    }

    public IntBuffer bufferUtil(int []arr){  
        IntBuffer buffer;

        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        qbb.order(ByteOrder.nativeOrder());

        buffer = qbb.asIntBuffer();
        buffer.put(arr);
        buffer.position(0);

        return buffer;
   }
    
    public FloatBuffer bufferUtil(float []arr){  
        FloatBuffer buffer;

        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        qbb.order(ByteOrder.nativeOrder());

        buffer = qbb.asFloatBuffer();
        buffer.put(arr);
        buffer.position(0);

        return buffer;
   }
}

注意构造函数中那些Buffer的创建方式。在这个地方,不能直接使用FloatBuffer/IntBuffer 的wrap() method。直接用这个method创建出来的buffer会导致JE:

02-26 23:12:08.945: E/OpenGLES(2750): Application com.example.androidgldemo (SDK target 17) called a GL11 Pointer method with an indirect Buffer.
02-26 23:12:08.968: W/dalvikvm(2750): threadid=11: thread exiting with uncaught exception (group=0x40d57930)
02-26 23:12:08.984: E/AndroidRuntime(2750): FATAL EXCEPTION: GLThread 16938
02-26 23:12:08.984: E/AndroidRuntime(2750): java.lang.IllegalArgumentException: Must use a native order direct Buffer
02-26 23:12:08.984: E/AndroidRuntime(2750): 	at com.google.android.gles_jni.GLImpl.glVertexPointerBounds(Native Method)
02-26 23:12:08.984: E/AndroidRuntime(2750): 	at com.google.android.gles_jni.GLImpl.glVertexPointer(GLImpl.java:1122)
02-26 23:12:08.984: E/AndroidRuntime(2750): 	at com.example.androidgldemo.AndroidGLDemoRenderer.onDrawFrame(AndroidGLDemoRenderer.java:63)
02-26 23:12:08.984: E/AndroidRuntime(2750): 	at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
02-26 23:12:08.984: E/AndroidRuntime(2750): 	at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)


© 著作权归作者所有

共有 人打赏支持
WolfCS
粉丝 79
博文 147
码字总数 505099
作品 4
杭州
高级程序员
OpenGL实现物体动画和视频特效

OpenGL实现视频的水印、滤镜?OpenGL实现视频的剪裁、旋转? 2D/3D物体的 旋转,平移,缩放? OpenGL图片滤镜与视频滤镜? 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方...

shareus
04/24
0
0
图片和图形之用OpenGL ES显示图形(9)

原文 概要 Android框架提供了大量用于创建有吸引力的功能性图形用户界面的标准工具。但是,如果您想要更多地控制应用程序在屏幕上绘制的内容,或者冒险进入三维图形,则需要使用其他工具。A...

lichong951
05/26
0
0
图片和图形之构建一个OpenGL ES环境(10)

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

lichong951
05/26
0
0
Android Graphic : apk and Skia/OpenGL|ES

Android apk里面的画图分为2D和3D两种:2D是由 Skia 来实现的,也就是我们在框架图上看到的SGL,SGL也会调用部分opengl的内容来实现简单的3D效果;3D部分是由OpenGL|ES实现的,OpenGL|ES是O...

Jerikc
2014/05/27
0
0
Android 自定义相机开发(三) —— 了解下EGL

胡说八道 如果要使用OpenGl来自定义相机,这个还是要了解下的。可能大多数开发者使用过OpengGL但是不知道EGL是什么?EGL的作用是什么?这其实一点都不奇怪,因为Android中的GlSurfaceView已经...

aserbao
05/10
0
0
3D引擎--可移植到Android的开源的引擎及调查报告

随着android在全球的风靡,越来越多的人将自己的目光投向搭载android的移动设备,但由于手持设备的局限性,怎样利用有限的资源来达到很好的体验,是设备厂商必须要考虑的问题,其中炫目的界面...

我希冀着
2011/11/28
0
2
通过FFmpeg解码和OpenGL的YUV转RGB实现Android视频播放

前言 在我的博文 https://blog.csdn.net/ericbar/article/details/80506390 中,我们在Android平台上,实现了通过FFmpeg在native(C/C++)层进行视频解码,并通过OpenGL实现了硬件渲染工作,...

ericbar
05/30
0
0
跨平台图像引擎 - Octoon

Octoon 是一个免费和开源的跨平台图形引擎,采用MIT协议。 用户可以使用一组统一的API轻松创建图形应用程序。 应用程序可以导出到许多平台,包括Linux,Mac OSX,Windows,Android和HTML5。 ...

匿名
05/27
0
0
为什么没有好用的Android游戏引擎?

随着Android平台的不断发展,近期Android开发者数量呈现出上升势头,就连以往较为冷门的游戏开发领域也涌现出不少生力军。然而,全新的问题正摆在了初学者面前,很多他们从未遇过的问题开始浮...

GWISOFT
2011/02/21
0
3
Android 音视频开发入门指南(2)

GLSurfaceView是OpenGL中的一个类,也是可以预览Camera的,而且在预览Camera上有其独到之处。独到之处在哪?当使用Surfaceview无能为力、痛不欲生时就只有使用GLSurfaceView了,它能够真正做...

shareus
04/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
2
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
1
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
161
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部