b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

韩语入门_读取renderbuffer_ios opengl es编程指南

电脑杂谈  发布时间:2017-01-16 10:07:58  来源:网络整理

前面iTyran翻译、转载的OpenGL教程都是使用文章作者自己的project,并没有提及默认的工程。默认工程的代码比较多,不利于刚开始初学入门。进过几天的研究,摸清楚了大部分的逻辑,在这与大家共同探讨学习。

工程居于xcode4.2 for iOS5创建,做了部分修改。

下载:OpenglStart.zip (60.69 KB, 下载次数: 13)

预备知识:

完成了从零开始学习OpenGL ES 和 OpenGL ES2.0–Iphone开发指引的学习。

1.使用GLKView简化OpenGL初始化。

在前面的教程里面,介绍了如何从一个UIView来建立OpenGL工程,里面做了很多初始化工作,比如:创建render buffer 和 frame buffer等。这些重复性的工作,apple提供了一个基础类GLKView给我使用。

在TTAppDelegate.m中初始化了一个TTViewController为rootViewController。

self.viewController = [[[TTViewController alloc]initWithNibName:@"TTViewController" bundle:nil] autorelease];

self.window.rootViewController = self.viewController;复制代码

复制代码

点击TTViewController.xib 我们可以看到它的属性是GLKView,而不是通常的UIView。

TTViewController继承于,GLKViewController在标准viewcontroller函数的基础上添加了OpenGL ES rendering loop相关的函数。

2. EAGLContext初始化

EAGLContext是OpenGL ES RenderingContext的iOS实现。

每个程序有自己的EAGLContext,这保证了各个OpenGL ES程序互不干扰。

在EAGLContext需要在调用任何OpenGL ES api前创建并初始化。

下面的代码在- (void)viewDidLoad函数的最前面。

创建了一个OpenGL ES 2.0的EAGLContext,并设为view的context。

self.context = [[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease];

if (!self.context) {

NSLog(@"Failedto create ES context");

}

GLKView *view = (GLKView *)self.view;

view.context = self.context;

view.drawableDepthFormat =GLKViewDrawableDepthFormat24;复制代码

复制代码

3. setupGL初始化

在解析[self setupGL]前,我们来看下这个工程运行的结果。

2个不同颜色的正方体在旋转,但是这里只有一个顶点法线数组gCubeVertexData。

仔细观察代码,会发现这里有2个着色器,

一个是GLKBaseEffect,为了方便OpenGL ES 1.0转移到2.0的通用着色器。

一个是OpenGL ES 2.0新添加的可编程着色器,使用跨平台的着色语言GLSL。

为了方便观察,我在原始代码上加了2个宏来控制打开其中某一个还是两个一起。

从宏块可以方便的看出哪些代码是属于哪个着色器相关的,哪些代码是共用的。

屏蔽某一个宏可以屏蔽某个正方体的显示输出。

回到setupGL,第一行代码是

在某个线程调用OpenGL api前,需要设置api作用与哪个context,

这个函数设置当前线程操作的context。

注意:不要多个线程同时操控同一个context。

然后是GLSL着色器初始化,后面再详细分析。

GLKBaseEffect着色器初始化。

#if defined (SHADER_1)

self.effect= [[[GLKBaseEffect alloc] init] autorelease];

self.effect.light0.enabled = GL_TRUE;

self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f,1.0f);

#endif复制代码

复制代码

最后是顶点数组和法线的初始化。

//在涉及到消隐等情况(可能遮挡),都要开启深度测。

//glEnable(GL_DEPTH_TEST),硬件上打开了深度缓存区,当有新的同样XY坐标的片断到来时,

//比较两者的深度。开启这个选项,在绘制每一帧前需要glClear(GL_DEPTH_BUFFER_BIT),后面会看到。

glEnable(GL_DEPTH_TEST);

//这里使用VertexArray Objects加载顶点法线数据。

glGenVertexArraysOES(1, &_vertexArray);

glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);

读取renderbuffer_韩语入门_ios opengl es编程指南

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData,GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);

// GLKVertexAttribPosition顶点属性指针类型:顶点坐标

// 3 一个顶点坐标由几个值来表示,x,y,z

// GL_FLOAT 每个数值的数据类型

//直接使用24并不优雅,24 = sizoef(GLfloat) * 6; 到下一个顶点坐标数据的步长。

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE,24, BUFFER_OFFSET(0));

glEnableVertexAttribArray(GLKVertexAttribNormal);

//直接使用12并不优雅,12 = sizoef(GLfloat) * 3;

glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24,BUFFER_OFFSET(12));

glBindVertexArrayOES(0);

}复制代码

关于VertexArray Objects请猛击。

这里我简单画了个关系图,可能更好理解。

2012-3-22 11:15 上传下载附件 (7.75 KB)

4. loadShaders初始化GLSL着色器

与可编程着色器相关的几个函数如下:

- (BOOL)loadShaders;

- (BOOL)compileShader:(GLuint *)shadertype:(GLenum)type file:(NSString *)file;

- (BOOL)linkProgram:(GLuint)prog;

- (BOOL)validateProgram:(GLuint)prog;复制代码

复制代码

validateProgram没有使用,compileShader和linkProgram可以作为公共库函数,不需要修改。

唯一需要根据需求修改的是loadShaders函数。

loadShaders大部分步骤都有英文注释,标准的加载流程:

1.创建程序。

2.创建并编译 顶点着色器和片段着色器。

3.把 顶点着色器和片段着色器 与 程序连接起来。

4.设置 顶点着色器和片段着色器 的输入参数。

5.链接程序。ios opengl es编程指南

6.获取 uniform 指针。

注意:这步只能在5成功后才能调用,在linkProgrom前,uniform位置是不确定的。

7.断开 顶点着色器和片段着色器 ,并释放它们。

注意:程序并没释放。

第4步是会变化的部分,第6步为可选。

先来看看Shader.vsh顶点着色器的代码。

- (BOOL)loadShaders;

- (BOOL)compileShader:(GLuint *)shadertype:(GLenum)type file:(NSString *)file;

- (BOOL)linkProgram:(GLuint)prog;

- (BOOL)validateProgram:(GLuint)prog;复制代码

再来看片段着色器代码。

// varying在片段着色器里面表示从顶点着色器传过来的输入参数

//片段着色器不能直接传如参数,只能接收顶点着色器的输出。

varying lowp ve colorVarying;

void main()

{

gl_FragColor = colorVarying;

}复制代码

我们现在回头再看看loadShaders函数里面的第4步。

glBindAttribLocation(_program, ATTRIB_VERTEX,"position");

glBindAttribLocation(_program, ATTRIB_NORMAL, "normal");复制代码

"position"和"normal"与顶点着色器代码里面的两个attribute对应,

分别与setupGL加载的顶点数组里面的顶点和法线数据对应起来。

5.update更新数据

update是一个delegate 方法用来更新数据,不做UI更新。ios opengl es编程指南

好吧,这部分是很头痛的矩阵变换,暂时不去分析他的算法(其实是我不懂=,=)。

对于GLKBaseEffect着色器,下面的代码用来更新矩阵。

self.effect.transform.projectionMatrix = projectionMatrix;

读取renderbuffer_韩语入门_ios opengl es编程指南

self.effect.transform.modelviewMatrix = modelViewMatrix;复制代码

而可编程着色器,先保存在下面2个变量中,然后再draw的时候作为输入参数传递给着色器。

_normalMatrix =GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

_modelViewProjectionMatrix =GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);复制代码

6.drawInRect输出到屏幕

- (void)glkView:(GLKView *)viewdrawInRect:(CGRect)rect

{

glClearColor(0.65f, 0.65f, 0.65f, 1.0f);

//GL_DEPTH_BUFFER_BIT与前面的glEnable(GL_DEPTH_TEST)对应。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//指定Draw使用的顶点数组。

glBindVertexArrayOES(_vertexArray);

#if defined (SHADER_1)

// Renderthe object with GLKit

// prepareToDraw绑定着色器到当前的OpenGL ES context。

[self.effect prepareToDraw];

//画出第一个正方体

glDrawArrays(GL_TRIANGLES, 0, 36);

#endif

#if defined (SHADER_2)

// Renderthe object again with ES2

//绑定着色器到当前的OpenGLES context。

glUseProgram(_program);

//Uniform变量参数输入。

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0,_modelViewProjectionMatrix.m);

glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0,_normalMatrix.m);

//画出第二个正方体

glDrawArrays(GL_TRIANGLES, 0, 36);

#endif

}复制代码

复制代码

默认工程的不足:

1)顶点数组并没有优化,应使用顶点与索引的方式减少重复点。

参考 有关glDrawElements的部分。

2)演示了2种着色器的同时使用,可只选其一来使用。

附:GLSL数据类型

void – 用于没有返回值的函式

bool – 条件类型,其值可以是真或假

int – 带负号整数

float – 浮点数

vec2 – 2 个浮点数组成的向量

vec3 – 3 个浮点数组成的向量

ve – 4 个浮点数组成的向量

bvec2 – 2 个布林组成的向量

bvec3 – 3 个布林组成的向量

bve – 4 个布林组成的向量

ivec2 – 2 个整数组成的向量

ivec3 – 3 个整数组成的向量

ive – 4 个整数组成的向量

mat2 – 浮点数的 2X2 矩阵

mat3 – 浮点数的 3X3 矩阵

mat4 – 浮点数的 4X4 矩阵

sampler1D – 用来存取一维纹理的句柄(handle)(或:操作,作名词解。)

sampler2D – 用来存取二维纹理的句柄

sampler3D – 用来存取三维纹理的句柄

samplerCube – 用来存取立方映射纹理的句柄

sampler1Dshadow – 用来存取一维深度纹理的句柄

sampler2Dshadow – 用来存取二维深度纹理的句柄

9Tech·Android开发交流群:259753725


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-26661-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 笠原留美
        笠原留美

        必将来犯之敌全部葬送于南海海域

        • 宋子侯
          宋子侯

          所有的朋友们一起都来

      每日福利
      热点图片
      拼命载入中...