java 顶点着色_顶点opengl教程

1.    前言  2.    我对OpenGL

ES2.0的理解

3.    如何告诉OpenGL我们要画什么

4.    OpenGL

ES2.0

的管线(pipeline)

Table

of  Contents

OpenGL

ES  2.0学习笔记

2  我曾经在网上搜寻各种关于OpenGL

ES2.0的资料,发现关于android中OpenGL

ES2.0开发的中文资料少的可怜,而成体系

的资料更是凤毛麟角.所以我就动了一些念头,希望将自己学习OpenGL的过程记录下来,帮助到其他希望学习OpenGL的人.在学习的过程中,我也曾经获得其他开源者的帮助,说起来这也算是投桃报李吧,哈哈.

由于这里主要是记录我学习中的一些感想.可能有些地方讲的并不直观,有些地方只做了简要阐述.大家也可以在网上找其

他资料作为参考.

网上资源:

1.OpenGL

ES1.0资料

2.NEHE

OpenGL教程,同样是成体系的教学,缺点:不是针对android,而且

讲述的是OpenGL

ES1.0固定管线的,相比2.0

之后可编程管线有些过时了.

3.NEHE

android

OpenGL

ES教程,好不容易找到的教程,附带有github的开源项目代码作为讲解.唯一的不足就是

讲解内

容为英文.

4.OpenGL

ES着色语言,学习2.0以后的OpenGL,掌握shader着色语言那是必须的.

5.OpenGL官网,英语好的就直接看这个吧

6.意外发现的学习OpenGL

ES2.0的好网站.当然仍然需要英文~~

7.依然是着色语言的教程,不过这个内容更丰富

OpenGL

ES  2.0学习笔记

3  前言  OpenGL

ES2.0是一套针对移动设备的应用程序接口,对于程序员而言他其实就是一个API文档.只不过这套API是专门针对

图形硬件的.它在Android平台上的调用是依靠

客户端-服务端的形式体现的.Android系统本身内置的OpenGL实现是服务

端,我们自己编写的Android程序是客户端.客户端负责提交命令,由服务端转化为硬件能接受的命令,最终执行并产生图像

内容.

首先因为移动设备本身的图形绘制只支持2D,想要做出绚丽的3D效果必须得借助OpenGL.也许有人会说,在android中使

用camera不也能绘制出3D效果么,对此我只能说:Camera只是对OpenGL做了一个封装,它本身仍然是属于OpenGL范畴.

其次OpenGL直接操作native层的内存.在android上会有更高的运行效率.而且由于OpenGL的绘制是在在主线程之外

的另一条线程里操作,所以会更加流畅,不会阻塞主线程.

为了能适应各种硬件平台,所以OpenGL

ES2.0并不包含任何执行窗口任务或者处理用户输入的函数,我们需要通过应用程

序本身所运行的窗口系统来提供相应操作才能处理这些操作.比如说:android手机上,我们想要调用OpenGL的话就必须得

使用GLSurfaceView来渲染图形.因为GLSurfaceView可以为自己创建一个窗口,并在视图(View

Hierarchy)层次上穿个洞

让底层的OpenGL

surface显示出来.对于大多数情况下这就足够了.(但是由于GLSurfaceView本身就是window的一部分.

所以它没法像其他的View一样进行动画和变形操作.)另外

OpenGL

ES2.0也不包含任何表达三维模型,读取图像文件的操

作,这个时候,我们需要通过一系列的几何图元(点,线,三角形)来创建三维空间的物体.GLSurfaceView和图元(点线

面)将是我们后面讲述的重点.

Android为我们提供了一个专门的用在3D画图上的GLSurfaceView.这个类被放在一个单独的包android.opengl里面,其中实

现了其他View所不具备的操作:

(1)

具有OpenGL|ES调用过程中的错误跟踪,检查工具,这样就方便了Opengl编程过程的debug

;      (2)

所有的画图是在一个专门的Surface上进行,这个Surface可以最后被组合到android的View体系中

;      (3)

它可以根据EGL的配置来选择自己的buffer类型,比如RGB565,depth=16

(这里有点疑问,SurfaceHolder的类型是SURFACE_TYPE_GPU,内存就是从EGL分配过来的

(4)

所有画图的操作都通过render来提供,而且render对Opengl的调用是在一个单独的线程中

(5)

Opengl的运行周期与Activity的生命周期可以协调

下面我们再看看利用GLSurface画3D图形的一个典型的Sequence

(1)

选择你的EGL配置(就是你画图需要的buffer类型)

[optional]

:                  setEGLConfigChooser(boolean)

setEGLConfigChooser(EGLConfigChooser)

setEGLConfigChooser(int,

int,

int,

int,

int,

int)

(2)

选择是否需要Debug信息

[optional]

:                setDebugFlags(int)

setGLWrapper(GLSurfaceView.GLWrapper).

(3)

为GLSurfaceView注册一个画图的renderer

:  setRenderer(GLSurfaceView.Renderer)

(4)

设置reander

mode,可以为持续渲染或者根据命令

来渲染,默认是continuous

rendering

[optional]:

setRenderMode(int)

这里有一个要注意的地方就是必须将Opengl的运行和Activity的生命周期绑定在一起,也就是说Activity

pause的时候,opengl的渲染也必须pause.另外GLSurfaceView还

class

MyGLSurfaceView

extends

GLSurfaceView

{    private

MyRenderer

mMyRenderer;

public

void

start()

{            mMyRenderer

=  ...;

setRenderer(mMyRenderer);

}    public

boolean

onKeyDown(int

keyCode,

KeyEvent

event)

{            if  (keyCode

==  KeyEvent.KEYCODE_DPAD_CENTER)

{  queueEvent(new

Runnable()

{  This

method

will

be  called

on  the

rendering

thread:

public

void

run()

{  mMyRenderer.handleDpadCenter();

return

true;

1.我对OpenGL

ES2.0的理解

(1)OpenGL

ES2.0是什么(2)为什么要用OpenGL

ES2.0呢(3)怎么在android上使用OpenGL

ES2.0呢OpenGL

ES  2.0学习笔记

4  我对OpenGL

ES2.0的理解

}            return

super.onKeyDown(keyCode,

event);

}  }  GLSurfaceView是Android提供的一个非常值得学习

的类,它实际上是一个如何在View中添加画图线程的例子,如何在Java

中使用线程的例子,如何添加事件队列的例子,一个使用SurfaceView画图的经典Sequence,一个如何定义Debug信息的例

子,觉得把它看懂了可以学到很多知识

,具体的源码在:/framworks/base/opengl/java/android/opengl/GLSurfaceView.java

.  OpenGL

ES  2.0学习笔记

5  我对OpenGL

ES2.0的理解

在讲后面内容的时候我们需要先思考一个问题,假设让你来画一幅画的话,你需要知道哪些要素了才能开始去画这幅画呢Android中View的源码实现绘制的时候经历了三步,首先是测量控件的大小,因为只有知道大小了才能在布局中进行定位.

其次就是确定位置,不确定位置的话就不知道要画在哪.最后才是开始绘制.

如果按照这个步骤,那么OpenGL

ES2中是如何去测量,定位还有绘制的呢相比起Android中View,OpenGL的的定位测量要简单的多,他只需要我们在它的坐标系上

定义一些顶点,这些顶点可以有

很多属性,但最重要的属性就是位置.位置属性通过x,y,z坐标来体现.通过这些顶点与顶点的组合就形成了不同的图形,

而这些图形的位置也根据每个点的位置而确定了下来.

通过代码来体现就是

float[]

tableVertices

=  {  0f,

0f,0f,

0.5f,-0.8f,0f,

0.5f,-0.8f,0f,

0.5f,0.8f,0f,

0.5f,0.8f,0f,

0.5f,-0.8f,0f

但这不就是一个普通的float数组么,float数组是java的类型,而OpenGL使用的是却是另外一种语言.那么我们怎么把这份数

据传递给运行在本地环境的OpenGL呢?下面就会解答这个问题.

要知道,Android运行代码的时候并不是直接运行在硬件上的,而是运行在Dalvik虚拟机上的.运行在虚拟机上的代码不能直

接访问本地环境.除非通过特定的API的接口.Android这样设计其实也是为了降低系统的耦合性,让开发者不用去关心CPU

等硬件,专心搞软件就行了.这样做一般也没问题,但在与本地系统交互的时候就比较麻烦了,比如说OpenGL.OpenGL作

为本地系统库直接运行在硬件上.

继续上面那个问题:如何将java数据传递给本地系统库中的OpenGL.

有两种技术可以实现:1.使用本地接口JNI技术,这个

技术已经集成在Android系统android.opengl.GLES20中,我们可以直接调用.

2.改变内存分配的方式,java有一个特殊的集

合,他们可以分配本地内存快,并且把java的数据复制到本地内存.而本地内存是可以被本地环境读取,这样就可以达到传

递数据的目的.

代码实现如下:

private

FloatBuffer

vertexData;

//缓存的顶点数据

vertexData

=  allocateDirect分配本地内存float数组的长度乘以每一个float类型占用的字节数

ByteBuffer.allocateDirect(tableVertices.length

*  BYTES_PER_FLOAT)

告诉字节缓冲区按照本地字节序组织它的内容

当一个值占用多个字节,比如32位整形数,字节按照从高位到低位

或者从

排什么顺序其实不重要,重要的是程序运行过程中所有的字节都得按同样的顺序排序,

//不能有的排正序,有的排倒序.

而      //order(ByteOrder.nativeOrder()就能达到这个目的.

order(ByteOrder.nativeOrder())

根据分配的内存获取一个能分配本地内存的FloatBuffer实例对象.

asFloatBuffer();

将顶点数据

内存从虚拟机中拷贝到本地

vertexData.put(tableVertices);

如何告诉OpenGL我们要画什么

1.OpenGL中的定位和测量

2.如何将java数据传递给本地系统库中的OpenGL.

OpenGL

ES  2.0学习笔记

6  如何告诉OpenGL我们要画什么

现在OpenGL已经可以读取这些数据,那么它会如何去使用这些数据呢这就涉及到OpenGL管线的概念了.

OpenGL

ES  2.0学习笔记

7  如何告诉OpenGL我们要画什么

OpenGL

ES  2.0学习笔记

8  OpenGL

ES2.0

的管线(pipeline)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值