2017-02-06 19:34:16 u014604106 阅读数 417
  • OpenGL ES2.0基础

    初级学习OpenGL ES2.0的课程,从无到有,从进本的函数讲起,每一课时都附带一个例子程序。深入浅出的讲解可编程管线技术,令人费解的文理,以及混合技术,各种优化技术:顶点缓冲区,索引缓冲区,帧缓冲区,介绍精灵的使用,并使用shader制作粒子特效。

    37506 人正在学习 去看看 张立铜

一些OpenGL相关教程

  1. http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-1-opening-a-window/这篇文章是基于pc的OpenGL讲解,知识比较基础、详细、准确。

  2. http://www.jianshu.com/p/3b532f6fcedf 这篇文章着重于iPhone中OpenGL进行讲解,讲解时比较有跳跃性,第一次接触OpenGL的话可能看不懂,但是其中的小例子比较好且多,而且都有源码。这是教程源码

iOS导入.obj模型文件

涉及到3D图像处理的相关技术,一般是使用3D制图软件制作模型文件后导出,转换成项目兼容的数据格式后倒入到项目中。这篇博客介绍了一个名为 OBJ2OPENGL 的将模型文件转换成iPhone OpenGL ES兼容的C/C++头文件的脚本。(这是原文链接

我的demo

我做了一个简单的 可拖动立方体展示示例 ,开启了深度缓存,渲染了纹理 设置了法线及光源,只实现了一下基本的操作,但是注释写的比较详细。

一些额外的收获

通过对OpenGL的学习,了解了渲染时CPU与GPU的分工,误打误撞对app界面流畅度优化的一些原理又有了些新的认识。

2016-08-04 17:19:38 yutaotst 阅读数 640
  • OpenGL ES2.0基础

    初级学习OpenGL ES2.0的课程,从无到有,从进本的函数讲起,每一课时都附带一个例子程序。深入浅出的讲解可编程管线技术,令人费解的文理,以及混合技术,各种优化技术:顶点缓冲区,索引缓冲区,帧缓冲区,介绍精灵的使用,并使用shader制作粒子特效。

    37506 人正在学习 去看看 张立铜

OpenGL ES简介:

     OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。

OpenGL ES 3.0主要新功能有:
1、渲染管线多重增强,实现先进视觉效果的加速,包括遮挡查询(Occlusion Query)、变缓反馈(Transform Feedback)、实例渲染(Instanced Rendering)、四个或更多渲染目标支持。
2、高质量ETC2/EAC纹理压缩格式成为一项标准功能,不同平台上不再需要需要不同的纹理集。
3、新版GLSL ES 3.0着色语言,全面支持整数和32位浮点操作。
4、纹理功能大幅增强,支持浮点纹理、3D纹理、深度纹理、顶点纹理、NPOT纹理、R/RG单双通道纹理、不可变纹理、2D阵列纹理、无二次幂限制纹理、阴影对比、调配(swizzle)、LOD与mip level clamps、无缝立方体贴图、采样对象、纹理MSAA抗锯齿渲染器。
5、一系列广泛的精确尺寸纹理和渲染缓冲格式,便携移动应用更简单。

     而在iOS上,可以支持opengles3.0的最低环境是iphone5s ios7.0.

iOS下环境搭建:

     关于ios下环境搭建有好几种,最简单的是在新建工程的时候选择game模板,然后如下图所示:


     不过,用这种方式,创建出来的工程有很多用不到的代码,不利于我们one by one的学习,所以,我们就从最简单的single view application工程说起,怎么一步步去搭建opengl es环境。

     首先,创建一个single view application工程,然后,引入GlKit和OpenGLES。



     紧接着,在ViewController.h文件里引入GLKit/GLKit.h,将ViewController类的父类改成GLKViewController。

[objc] view plain copy
  1. #import <UIKit/UIKit.h>  
  2. #import <GLKit/GLKit.h>  
  3. @interface ViewController : GLKViewController  
  4.   
  5.   
  6. @end  

     然后将storyboard中ViewController所对应的view的Custom Class改成GLKView。



     修改ViewController.m文件,代码如下:

[objc] view plain copy
  1. #import "ViewController.h"  
  2. #import <OpenGLES/ES3/gl.h>  
  3. #import <OpenGLES/ES3/glext.h>  
  4. @interface ViewController ()<GLKViewDelegate>  
  5. {  
  6.     EAGLContext *context; //EAGLContent是苹果在ios平台下实现的opengles渲染层,用于渲染结果在目标surface上的更新。  
  7.   
  8. }  
  9. @end  
  10.   
  11. @implementation ViewController  
  12.   
  13. - (void)viewDidLoad {  
  14.     [super viewDidLoad];  
  15.     context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];//这里用的是opengles3.  
  16.       
  17.     if (!context) {  
  18.         NSLog(@"Failed to create ES context");  
  19.     }  
  20.       
  21.     GLKView *view = (GLKView *)self.view;  
  22.     view.context = context;  
  23.     view.drawableDepthFormat = GLKViewDrawableDepthFormat24;  
  24.     [EAGLContext setCurrentContext:context];  
  25.     glEnable(GL_DEPTH_TEST); //开启深度测试,就是让离你近的物体可以遮挡离你远的物体。  
  26.     glClearColor(0.10.20.31); //设置surface的清除颜色,也就是渲染到屏幕上的背景色。  
  27. }  
  28.   
  29. - (BOOL)prefersStatusBarHidden {  
  30.     return YES;  
  31. }  
  32.   
  33. -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect  
  34. {  
  35.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //清除surface内容,恢复至初始状态。  
  36. }  
  37. @end  

     再次构建运行,如下图所示:



     至此,一个初步的opengles3的开发环境已经搭建完毕,因为ios平台的特殊性,所以我们很多时候不得不借助ios下glkit库去实现和简化我们的操作,不过,对于大部分opengles的内容,我还是会脱离glkit,原汁原味的道出,这样,对于以后的跨平台是大有裨益的。

     本文有不足之处,还望各位多多指正。


2016-08-04 17:22:29 jeffasd 阅读数 186
  • OpenGL ES2.0基础

    初级学习OpenGL ES2.0的课程,从无到有,从进本的函数讲起,每一课时都附带一个例子程序。深入浅出的讲解可编程管线技术,令人费解的文理,以及混合技术,各种优化技术:顶点缓冲区,索引缓冲区,帧缓冲区,介绍精灵的使用,并使用shader制作粒子特效。

    37506 人正在学习 去看看 张立铜

http://blog.163.com/luckyjackyt@126/blog/static/1404476132012323105227214

OpenGL ES on iOS【IOS的OpenGL ES】

OpenGL ES provides a procedural API for submitting primitives to be rendered by a hardware accelerated graphics pipeline.【OpenGL ES提供一个程序API来把原始数据提交给硬件加速图形管线去渲染】Graphics commands are consumed by OpenGL to generate images that can be displayed to the user or retrieved for further processing outside of OpenGL ES.【图形命令被OpenGL消耗来生成图像,这些图像显示给用户或存起来等待OpenGL ES外更多的处理】

The OpenGL ES specification defines the precise behavior for each function. 【OpenGL ES说明书为每个功能定义了精确的行为】Most commands in OpenGL ES perform one of the following activities:【大多数OpenGL ES的命令执行下列行为之一】

  • Reading detailed information provided by the implementation about its capabilities.【读取OpenGL ES的能力的执行的详细信息】 See【见】 “Determining OpenGL ES Capabilities.”

  • Reading and writing state variables defined by the specification.【说明书定义的可变读写状态】 OpenGL ES state typically represents the current configuration of the graphics pipeline. 【OpenGL ES状态通常表现了图形管道的当前设置】For example, OpenGL ES 1.1 uses state variables extensively to configure lights, materials, and the computations performed by the fixed-function pipeline.【比如,OpenGL ES1.1用状态可变广泛的设置:光、材质和固定功能管线提供的计算】

  • Creating, modifying or destroying OpenGL ES objects. 【创建、修改、销毁OpenGL对象】OpenGL ES objects are not Objective-C objects; they are OpenGL ES resources manipulated through OpenGL ES’s procedural API. 【OpenGL ES对象不是Objective-C对象,他们是通过OpenGL ES程序API操作的OpenGL ES资源】See 【更多信息见】“OpenGL ES Objects Encapsulate Resources on Behalf of Your Application” for more information.

  • Drawing primitives. Vertices are submitted to the pipeline where they are processed, assembled into primitives and rasterized to a framebuffer.【绘制原始数据,顶点被提交给管线,在那,它们被处理、装配成原始数据并且光栅化进一个帧缓存】

Which Version(s) of OpenGL ES Should I Target?【我应该以哪个版本的OpenGL ES为目标】

When designing your OpenGL ES application, a critical question you must answer is whether your application should support OpenGL ES 2.0, OpenGL ES 1.1 or both.【当你设计你的OpenGL ES程序时,有个关键问题你必须想清楚,就是你的程序应该支持OpenGL ES2.0还是1.1或都支持】

  • OpenGL ES 2.0 is more flexible and more powerful than OpenGL ES 1.1 and is the best choice for new applications. 【OpenGL ES2.0比1.1更灵活更强力,对于新程序是最好地选择】Custom vertex or fragment calculations can be implemented more clearly and concisely in shaders, with better performance. 【自定的顶点或片段计算可以更清楚和简明地在着色器里执行】To perform the same calculations in OpenGL ES 1.1 often requires multiple rendering passes or complex state configurations that obscure the intent of the algorithm.【要在OpenGL ES1.1里执行相同的计算经常需要多重的渲染通道或复杂的状态设置,不易看懂算法的目的】 As your algorithms grow in complexity, shaders convey your calculations more clearly and concisely and with better performance. 【当你的算法变得复杂时,着色器更清晰和简明地传送你的计算,而且有更好的性能】OpenGL ES 2.0 requires more work up front to build your application; you need to recreate some of the infrastructure that OpenGL ES 1.1 provides by default.【OpenGL ES2.0在你创建程序前需要更加精心制定,你需要重建某些基础结构,而这些1.1都默认提供】

  • OpenGL ES 1.1 provides a standard fixed-function pipeline that provides good baseline behavior for a 3D application, from transforming and lighting vertices to blending fragments into the framebuffer.【OpenGL ES1.1提供了一个标准固定功能管线,这个管线提供为3D程序提供很好的基础管线行为,从变形和光照顶点到混合片段进帧缓存】 If your needs are simple, OpenGL ES 1.1 requires less coding to add OpenGL ES support to your application. 【如果你的需要是简单的,OpenGL ES1.1需要更少的代码来加入OpenGL ES来支持你的程序】Your application should target OpenGL ES 1.1 if your application needs to support all iOS devices【如果你的程序需要支持所有IOS设备,那应该以OpenGL ES1.1为目标】

If you choose to implement an OpenGL ES 1.1 application primarily for compatibility with older devices, consider adding an OpenGL ES 2.0 rendering option that takes advantage of the greater power of OpenGL ES 2.0-capable graphics processors found on newer iOS devices.【如果你选择执行一个OpenGL ES1.1程序主要是为了旧设备的通用性,那么考虑加一个OpenGL ES2.0的渲染设置,好利用在新IOS设备上发现的更有力的OpenGL ES2.0的图形处理能力】

Important If your application does not support both an OpenGL ES 1.1 and an OpenGL ES 2.0 rendering path, restrict your application to devices that support the version you selected.【重要。如果你的程序不是1.1和2.0都支持,则要限制你的程序对设备版本的支持】See【见】 “Declaring the Required Device Capabilities” in iOS App Programming Guide.

Understanding the OpenGL ES Architecture【理解OpenGL ES的架构】

OpenGL ES works on a few key principles. 【OpenGL ES的工作基于很少几条关键原则】To design efficient OpenGL ES applications, you need to understand the underlying architecture.【要设计有效率的OpenGL ES程序,你需要理解底层架构】

Client-Server Model【“客户端-服务器端”模型】

OpenGL ES uses a client-server model, as shown in Figure 1-1. 【如图1-1所示,OpenGL ES使用“客户端-服务器端”模型】When your application calls an OpenGL ES function, it talks to an OpenGL ES client.【当你的程序调用一个OpenGL ES功能,它是告诉OpenGL ES客户端的】 The client processes the function call and, where necessary, converts it into commands to deliver to the OpenGL server. 【客户端处理功能调用,并在必要的地方转变成命令送往OpenGL服务器】A client-server model allows the work to process a function call to be divided between the client and the server. 【客户-服务模型允许作业在客户端-服务器间处理一个功能调用】The nature of the client, the server, and the communication path between them is specific to each implementation of OpenGL ES; on an iOS device, the workload is divided between the CPU and a dedicated graphics processor.【客户端、服务器端和它们之间的通讯路径的性质对于每个OpenGL ES的执行是特定的,在一个IOS设备上,工作负荷在CPU和专用图形处理器之间分配】

Figure 1-1  OpenGL ES client-server model【OpenGL ES客户端-服务器模型】

OpenGL ES Relies on Platform-Specific Libraries For Critical Functionality【OpenGL ES依赖特定平台的关键功能库】

The OpenGL ES specification defines how OpenGL ES works, but does not define functions to manage the interaction between OpenGL ES and the hosting operating system. 【OpenGL ES说明书定义了OpenGL ES怎样工作,但是没定义管理OpenGL ES与主操作系统之间的合作的功能】Instead, the specification expects each implementation to provide functions to allocate rendering contexts and system framebuffers.【取而代之的是,说明书希望每个执行提供功能来分配渲染内容和系统帧缓存】

A rendering context stores the internal state for the OpenGL ES state machinsettinge. 【渲染环境为OpenGL ES状态机器存储内部状态】Rendering contexts allow each OpenGL ES application to each maintain a copy of the state data without worrying about other applications. 【渲染环境允许每个OpenGL ES程序保持一个状态数据的拷贝,而不用担心其他程序】See【见】 “Configuring OpenGL ES Contexts.” You can also use multiple rendering contexts in a single application.【你也可以在一个简单的程序里用多重渲染环境】

A system framebuffer is a destination for OpenGL ES drawing commands, and is typically associated with the host operating system’s graphics subsystem. iOS does not provide system framebuffers.【系统帧缓存是OpenGL ES绘图命令的终点,通常与主系统的图形子系统有联系。IOS不提供系统帧缓存】 Instead, iOS extends the framebuffer object provided by OpenGL ES to allow framebuffers that share data with Core Animation. 【取而代之,IOS扩展OpenGL ES提供的缓存对象以允许帧缓存与核心动画分享数据】See【更多帧缓存对象的信息见】 “Framebuffer Objects are the Only Rendering Target on iOS” for more information on framebuffer objects and【关于在程序里创建和使用帧缓存的详细讨论见】 “Drawing With OpenGL ES” for a detailed discussion on creating and using framebuffers in your application.

Commands May Be Executed Asynchronously【命令可以不同步扩展】

A benefit of the OpenGL ES client-server model is that an OpenGL ES function can return control to the application before the requested operation completes.【OpenGL ES客户端-服务器模型的好处在于,OpenGL ES功能可以在需求的操作完成前把控制返回给程序】If OpenGL ES required every function to complete before returning control to your application, the CPU and GPU would run in lockstep, eliminating many opportunities for parallelism in your application. 【如果OpenGL ES在把控制返回给程序前需要每个功能都完成,则CPU和GPU会顺序运行,从而限制了很多程序里的并发执行的机会】On iOS, deferring execution of drawing commands is quite common. 【在IOS里,延迟绘图命令的执行是非常常见的】By deferring several drawing commands and handling them simultaneously, the graphics hardware can remove hidden surfaces before performing costly fragment calculations.【借助同时延迟并处理几个绘图命令,图形硬件可以在执行高代价片段计算前移除隐藏的面】

Many OpenGL ES functions implicitly or explicitly flush commands to the graphics hardware. 【许多OpenGL ES功能隐式或显式地刷新命令到图形硬件】Other OpenGL functions flush commands to the graphics processor and wait until some or all pending commands have completed. 【其他OpenGL功能刷新到图形处理器并等待,直到一些或全部未执行命令完成】Whenever possible, design your application to avoid client-server synchronizations.【尽可能把程序设计成:避免客户端-服务器同步】

Commands Are Executed In Order【命令是顺序执行的】

OpenGL ES guarantees that the results of function calls made to a rendering context act as if they executed in the same order that the functions were called by the client application. 【OpenGL ES保证调用建立渲染环境的功能的结果起作用,就像它们在客户端程序里调用功能的相同序列里执行】When your application makes a function call to OpenGL ES, your application can assume the results from previous functions are available, even if some of the commands have not finished executing.【当你的程序对OpenGL ES进行功能调用时,你的程序可以承担来自先前的可以得到的功能的结果,即使某些命令还没完成执行】

Parameters are Copied at Call-Time【参数在调用时被复制】

To allow commands to be processed asynchronously, when your application calls an OpenGL ES function, any parameter data required to complete the function call must be copied by OpenGL ES before control is returned to your application. 【当你的程序调用一个OpenGL ES功能时,为了允许命令被异步执行,在控制返回程序前,任意为了完成功能调用所需的参数数据,必须被OpenGL ES复制】If a parameter points at an array of vertex data stored in application memory, OpenGL ES must copy the vertex data before returning. 【如果一个参数指向一个数组,这个数组是存在程序内存里的顶点数据的数组,OpenGL ES必须在返回前复制顶点数据】This has a couple of important implications. 【这包括两个重要的含义】First, an application is free to change any memory it owns regardless of the calls it makes to OpenGL ES, because OpenGL ES and your application never access the same memory simultaneously. 【首先,程序是自由变换它拥有的任何内存,而不管它对OpenGL ES所做的调用,因为OpenGL ES和你的程序从来不同时存取相同的内存】Second, copying parameters and reformatting them so that the graphics hardware can read the data adds overhead to every function call. 【第二,复制参数和重新对它们定义格式,以便图形硬件可以读取数据,数据是加在为每个功能调用的开销里】For best performance, your application should define its data in format that are optimized for the graphics hardware, and it should use buffer objects to explicitly manage memory copies between your application and OpenGL ES.【要得到最佳性能,你的程序应该把它的数据定义为专为图形硬件优化的格式,并且应该用更好地缓冲对象来显示的管理程序与OpenGL ES之间的内存复制】

Implementations May Extend the Capabilities Defined in the Specification【OpenGL ES的执行可以扩展说明书中定义的能力】

An OpenGL ES implementation may extend the OpenGL ES specification in one of two ways. OpenGL ES的执行可以用两种方法扩展OpenGL ES说明书】First, the specification sets specific minimum requirements that implementations must meet, such as the size of a texture or the number of texture units that the application may access. 【第一,说明书设置了执行必须满足的专门的最小需求,例如程序可能存取的材质单元的大小或数量】An OpenGL ES implementation is free to support larger values — a larger texture, or more texture units. 【OpenGL ES的执行对支持大数值是自由的,比如大的材质或更多的材质单元】Second, OpenGL ES extensions allow an implementation to provide new OpenGL ES functions and constants. 【第二,OpenGL ES的扩展允许一个执行提供新的OpenGL ES功能和连续的(constants)】Extensions allow an implementation to add entirely new features.【扩展允许一个执行加入全新的特性】 Apple implements many extensions to allow applications to take advantage of hardware features and to help you improve the performance of your applications. 【苹果执行许多扩展来允许程序利用硬件特性并帮助你提高程序性能】The actual hardware limits and the list of extensions offered by each implementation may vary depending on which device your application runs on and the version of iOS running on the device. 【实际的硬件限制和由每个执行提供的扩展列表,可以根据程序运行的硬件和IOS的版本来改变】Your application must test the capabilities at runtime and alter its behavior to match.【你的程序必须测试运行时的能力,并改变性能来匹配】

OpenGL ES Objects Encapsulate Resources on Behalf of Your Application【OpenGL ES对象为了你的程序利益把资源打包】

Objects are opaque containers that your application uses to hold configuration state or data needed by the renderer. 【对象是不透明的容器,你的程序用它保持设置状态或渲染器需要的数据】Because the only access to objects is through the procedural API, the OpenGL ES implementation can choose different strategies when allocating objects for your application. 【因为唯一对对象的存取是通过程序API的,OpenGL ES的执行可以在给你的程序分配对象时选择不同的策略】It can store your data in a format or memory location that is optimal for the graphics processor.【它可以以一个格式或在一个专为图形优化的存储单元里存储你的数据】Another advantage to objects is that they are reusable, allowing your application to configure the object once and use it multiple times.【对象的另一个好处是他们是可重复使用的,允许你的程序设置对象一次,并多次使用】

The most important OpenGL ES object types include:【最重要的OpenGL ES对象类型包括】

  • texture is an image that can be sampled by the graphics pipeline.【texture(材质)是一个图片,可以被图形管线抽样】This is typically used to map a color image onto primitives but can also be used to map other data, such as a normal map or pre-calculated lighting information. 【典型的用于原始数据的彩色图片的贴图,也可用于其他数据贴图,比如普通贴图或提前计算好的光影信息】The chapter “Best Practices for Working with Texture Data” discusses critical topics for using textures on iOS.【章节《Best Practices for Working with Texture Data》讨论了在IOS里用贴图的关键题目】

  • buffer object is a block of memory owned by OpenGL ES used to store data for your application. 【buffer(缓存)对象是一块儿OpenGL ES拥有的内存,常用于为你的程序存储数据】Buffers are used to precisely control the process of copying data between your application and OpenGL ES. 【缓存常用于精确地控制你的程序和OpenGL ES之间复制数据】For example, if you provide a vertex array to OpenGL ES, it must copy the data every time you submit a drawing call. 【例如,如果你提供了一个顶点数组给OpenGL ES,它必须在你每次提交绘图调用时复制数据】In contrast, if your application stores its data in a vertex buffer object, the data is copied only when your application sends commands to modify the contents of the vertex buffer object. 【相比之下,如果你的程序把数据存进一个顶点缓存对象里,则数据仅在程序发送命令改变顶点缓存对象的内容时被复制】Using buffers to manage your vertex data can significantly boost the performance of your application.【用缓存管理你的顶点数据可以显著地提升程序的性能】

  • vertex array object holds a configuration for the vertex attributes that are to be read by the graphics pipeline.【vertex array(顶点数组)对象保持对顶点属性的设置,这些属性被图形管线读取】 Many applications require different pipeline configurations for each entity it intends to render. 【许多程序针对每个要渲染的实体需要不同的管线设置】By storing a configuration in a vertex array, you avoid the cost of reconfiguring the pipeline and may allow the implementation to optimize its handling of that particular vertex configuration.【借助把设置存进顶点数组,你节省了重新设置管线的代价,并可以允许程序的执行来优化它对特殊顶点设置的处理】

  • Shader programs, also known as shaders, are also objects. 【shader programs(着色器程序)也叫着色器,也是对象】An OpenGL ES 2.0 application creates vertex and fragment shaders to specify the calculations that are to be performed on each vertex or fragment, respectively.【一个OpenGL ES2.0程序创建顶点和片断着色器,来指定在每个顶点或片断上分别执行的计算】

  • renderbuffer is a simple 2D graphics image in a specified format.【renderbuffer(渲染缓存)是一个简单的指定格式的2D图形图片】This format usually is defined as color, depth or stencil data. 【这个格式通常被定义为颜色、深度或模板数据】Renderbuffers are not usually used in isolation, but are instead used as attachments to a framebuffer.【渲染缓存通常不单独用,而是用于帧缓存的附件】

  • Framebuffer objects are the ultimate destination of the graphics pipeline.【framebuffer(帧缓存)对象是图形管线的最终目的地】A framebuffer object is really just a container that attaches textures and renderbuffers to itself to create a complete configuration needed by the renderer. 【帧缓存对象恰是一个真正的容器,这个容器把材质和渲染缓存贴在自己身上以创建一个完整的渲染需要的设置】A later chapter, “Drawing With OpenGL ES,” describes strategies for creating and using framebuffers in iOS applications.【后面的章节《Drawing With OpenGL ES》讨论了在IOS程序里创建和使用帧缓存的策略】

Although each object type in OpenGL ES has its own functions to manipulate it, all objects share a similar programming model:【虽然OpenGL ES里的每个对象的类型有他自己的功能来操作它,但是所有对象分享一个相似的程序模型】

  1. Generate an object identifier.【生成一个对象标识】

    An identifier is a plain integer used to identify a specific object instance. 【一个标识是一个自然数,用于标明一个确切的对象实例】Whenever you need a new object, call OpenGL ES to create a new identifier. 【当你需要一个新对象时,调用OpenGL ES来创建一个新的标识】Creating the object identifier does not actually allocate an object, it simply allocates a reference to it.【创建对象标识不是实际上分配一个对象,它简单地分配一个引文】

     

  2. Bind your object to the OpenGL ES context.【把你的对象捆绑到OpenGL ES环境】

    Most OpenGL ES functions act implicitly on an object, rather than requiring you to explicitly identify the object in every function call. 【大多数OpenGL ES功能隐式地对对象起作用,而不需要你在每个功能调用时显式地标识对象】You set the object to be configured by binding it to the context. 【你借助把对象捆绑进环境来设置对象】Each object type uses different functions to bind it to the context. 【每个对象用不同的方法来捆绑进环境】The first time you bind an object identifier, OpenGL ES allocates and initializes the object.【第一次捆绑对象标识时,OpenGL ES分配和初始化对象】

     

  3. Modify the state of the object.【改变对象的状态】

    Your application makes one or more function calls to configure the object.【你的程序用一个或更多的功能调用来设置对象】For example, after binding a texture object, you typically would configure how the texture is filtered and then load image data into the texture object.【例如,在捆绑一个材质对象后,你通常会设置材质怎样过滤,然后载入图片到材质对象】

    Changing an object can potentially be expensive, as it may require new data to be sent to the graphics hardware. 【当它需要新的数据送往图形硬件时,换一个对象可能要潜在地贵的】Where reasonable, create and configure your objects once, and avoid changing them afterwards for the duration of your application.【在适度的地方,创建和设置你的对象一次,并避免后来在整个程序期间换它们】

  4. Use the object for rendering.【使用渲染用的对象】

    Once you’ve created and configured all the objects needed to render a scene, you bind the objects needed by the pipeline and execute one or more drawing functions. 【一旦你已经创建和设置了全部的渲染场景所需的对象,你捆绑管线需要的对象并执行一个或更多的绘图功能】OpenGL ES uses the data stored in the objects to render your primitives. 【OpenGL ES用存在对象里的数据渲染你的原始模型】The results are sent to the bound framebuffer object.【把结果送进捆绑好的帧缓存里】

     

  5. Delete the object.【删除对象】

    When you are done with an object, your application should delete it. 【当一个对象用完后,你的程序应该删除它】When an object is deleted, its contents are destroyed and the object identifier is recycled.【当一个对象被删除了,它的容器就被毁掉,对象标识被回收】

Framebuffer Objects are the Only Rendering Target on iOS【帧缓存对象是IOS里唯一的渲染目标】

Framebuffer objects are the destination for rendering commands. 【帧缓存对象是渲染命令的终点】OpenGL ES 2.0 provides framebuffer objects as part of the core specification; they are provided on OpenGL ES 1.1 by theOES_framebuffer_object extension. 【OpenGL ES2.0提供帧缓存对象作为核心说明书的部分】Because framebuffer objects are the only rendering target on iOS, Apple guarantees that the OES_framebuffer_object extension will always be provided by every OpenGL ES 1.1 implementation on iOS.【因为帧缓存对象是IOS里唯一的渲染目标,苹果保证OES_framebuffer_object扩展总是会被IOS里的每个OpenGL ES1.1的执行提供】

Framebuffer objects provide storage for color, depth and/or stencil data by attaching images to the framebuffer, as shown in Figure 1-2. 【借助把图片附在帧缓存上,帧缓存对象提供对颜色、深度和(或)模板数据的存储,如图1-2】The most common image attachment is a renderbuffer object. 【最通常的图片附着是一个渲染缓存对象】However, a OpenGL ES texture can be attached to the color attachment point of a framebuffer instead, allowing image to be rendered directly into a texture. 【然而,一个OpenGL ES材质可以被附在帧缓存的颜色附着点上,取而代之,允许图片被直接渲染进材质】Later, the texture can act as an input to future rendering commands.【再后来,材质可以作为一个对未来渲染命令的输入起作用】

Figure 1-2  Framebuffer with color and depth renderbuffers【带颜色和深度渲染缓存的帧缓存】Framebuffer with attachments.

Creating a framebuffer uses the following steps:【用下列步骤创建帧缓存】

  1. Generate and bind a framebuffer object.【生成并绑定一个帧缓存的对象】

  2. Generate, bind, and configure an image.【生成、捆绑、设置一个图片】

  3. Attach the image to one of the framebuffer’s attachment points.【把图片贴在其中一个帧缓存的附着点上】

  4. Repeat steps 2 and 3 for other images.【对其他图片重复2、3步骤】

  5. Test the framebuffer for completeness. 【测试帧缓存的完整性】The rules for completeness are defined in the OpenGL ES specification. 【OpenGL ES的说明书定义了完整性的规则】These rules ensure the framebuffer and its attachments are well-defined.【这些规则确保帧缓存和它的附属物是清晰可辨的】




? 2011 Apple Inc. All Rights Reserved. (Last updated: 2011-02-24)

Did this document help you? Yes It's good, but... Not helpful...

2017-02-27 15:02:16 Forever_wj 阅读数 282
  • OpenGL ES2.0基础

    初级学习OpenGL ES2.0的课程,从无到有,从进本的函数讲起,每一课时都附带一个例子程序。深入浅出的讲解可编程管线技术,令人费解的文理,以及混合技术,各种优化技术:顶点缓冲区,索引缓冲区,帧缓冲区,介绍精灵的使用,并使用shader制作粒子特效。

    37506 人正在学习 去看看 张立铜

一、什么是 OpenGL ES?

iOS上绘制图形的方式很多,UIKit,CoreGraphics,SpriteKit,OpenGL ES,Metal等。OpenGL ES是一套非常底层但使用非常广泛的C语言API,专为移动设备定制,可在不同的手机系统或浏览器上使用,渲染效果很好。

二、iOS的OpenGL ES的使用:

  • 新建一个工程之后,在系统库中需要添加导入OpenGLES.framework和QuartzCore.framework两个库;
  • 新建一个单独实现OpenGL ES的类,命名为OpenGLView,并引入
#import "OpenGLView.h"
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
  • 在OpenGLView的.m的延展中声明如下实例变量:
@interface OpenGLView () {
    CAEAGLLayer *eaglLayer; //OpenGL context,管理使用openGLES进行绘制的状态,命令及资源
    EAGLContext *eaglContext;
    GLuint      colorRenderBuffer;//渲染缓冲区
    GLuint      frameBuffer;//帧缓冲区
}
  • 继续在.m中实现layerClass方法:
 + (Class)layerClass {
    //为了让 UIView 显示 openGL 内容,必须将默认的layer类型修改为CAEAGLLayer类型
    return [CAEAGLLayer class];
}
  • CAEAGLLayer的配置:默认的 CALayer 是透明的,需要将它设置为 opaque == YES 才能看到在它上面描绘的东西。为此,使用匿名 category 技巧,在 OpenGLView.m的开头(在@interface OpenGLView 的上面)添加匿名 category,并声明私有函数 setupLayer并在implementation中实现:
 + (void)setupLayer {
    eaglLayer = (CAEAGLLayer *)self.layer;
    eaglLayer.opaque = YES;
    // 描绘属性:这里不维持渲染内容
    // kEAGLDrawablePropertyRetainedBacking:若为YES,则使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)计算得到的最终结果颜色的透明度会考虑目标颜色的透明度值。
    // 若为NO,则不考虑目标颜色的透明度值,将其当做1来处理。
    // 使用场景:目标颜色为非透明,源颜色有透明度,若设为YES,则使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)得到的结果颜色会有一定的透明度(与实际不符)。若未NO则不会(符合实际)。
    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],kEAGLDrawablePropertyRetainedBacking,kEAGLColorFormatRGBA8,kEAGLDrawablePropertyColorFormat, nil];
}
  • EAGLContext渲染上下文
 - (void)setupContext {
    eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    if (!eaglContext) {
        exit(1);
    }

    if (![EAGLContext setCurrentContext:eaglContext]) {
        exit(1);
    }
}
  • 创建RenderBuffer:用于存储渲染的内容(OpenGL ES 总共有三大不同用途的color buffer,depth buffer 和 stencil buffer,这里创建私有方法setupRenderBuffer来生成 color buffer;
 - (void)setupRenderBuffer {
    if (colorRenderBuffer) {
        glDeleteBuffers(1, &colorRenderBuffer);
        frameBuffer = 0;
    }
    // 生成一个renderBuffer,id是colorRenderBuffer
    glGenBuffers(1, &colorRenderBuffer);
    // 设置为当前renderBuffer,则后面引用GL_RENDERBUFFER,即指的是colorRenderBuffer
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderBuffer);
    // 为colorRenderBuffer分配存储空间
    [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer];
}
  • FrameBuffer:renderBuffer对象本身不能直接使用,不能挂载到GPU上直接输出内容,要使用frameBuffer(OpenGlES的FrameBuffer包含:renderBuffer,depthBuffer,stencilBuffer和accumulationBuffer);
- (void)setupFrameBuffer {
    if (frameBuffer) {
        glGenBuffers(1, &frameBuffer);
        frameBuffer = 0;
    }
    // FBO用于管理colorRenderBuffer,离屏渲染
    glGenFramebuffers(1, &frameBuffer);
    // 设置为当前frameBuffer
    glBindRenderbuffer(GL_FRAMEBUFFER, frameBuffer);
    // 将colorRenderBuffer装配到GL_COLOR_ATTACHMENT0这个装配点上
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
}
  • 当 UIView 在进行布局变化之后,由于 layer 的宽高变化,导致原来创建的 renderbuffer不再相符,需要销毁既有的 renderbuffer 和 framebuffer;
 - (void)destoryRenderAndFrameBuffer {
    glDeleteFramebuffers(1, &frameBuffer);
    frameBuffer = 0;
    glDeleteRenderbuffers(1, &colorRenderBuffer);
    colorRenderBuffer = 0;
}
  • 声明一个render方法进行真实描绘:
 - (void)render {
    // 设置清屏颜色
    glClearColor(0, 1.0, 0, 1.0);
    // 用来指定要用清屏颜色来清除由mask指定的buffer,此处是color buffer
    glClear(GL_COLOR_BUFFER_BIT);

    [eaglContext presentRenderbuffer:GL_RENDERBUFFER];
}
  • 最后在实现layoutSubviews方法:
- (void)layoutSubviews {
    [self setupLayer];
    [self setupContext];
    [self destoryRenderAndFrameBuffer];
    [self setupRenderBuffer];
    [self setupFrameBuffer];
    [self render];
}
  • 完成了OpenGLView的基本构造之后,利用OpenGLView在界面上进行渲染:在ViewController中导入#import “OpenGLView.h”,并声明一个OpenGLView的实例属性,在viewDidLoad中调用即可:
    self.glView = [[OpenGLView alloc] init];
    self.glView.frame = self.view.frame;
    [self.view addSubview:self.glView];
    self.view.backgroundColor = [UIColor redColor];
2016-08-04 17:22:31 yutaotst 阅读数 576
  • OpenGL ES2.0基础

    初级学习OpenGL ES2.0的课程,从无到有,从进本的函数讲起,每一课时都附带一个例子程序。深入浅出的讲解可编程管线技术,令人费解的文理,以及混合技术,各种优化技术:顶点缓冲区,索引缓冲区,帧缓冲区,介绍精灵的使用,并使用shader制作粒子特效。

    37506 人正在学习 去看看 张立铜

 上文我们讲解了如何构建一个hello world开发环境,那么这一篇我们就来画一个简单的三角形出来。

       首先,我要向大家介绍下opengl es的渲染流程,在2.0之前,es的渲染采用的是固定管线,何为固定管线,就是一套固定的模板流程,局部坐标变换 -> 世界坐标变换 ->观察坐标变换->背面消除->光照->裁剪->投影->视口计算->光栅化,程序员只需要调用固定的api修改一些配置参数就可以完成整个渲染流程了。而到了2.0,固定管线改成了可编程管线,我们对整个渲染流程可以再编程,没有固定的api给你调用,一切都依靠shader来完成。那么什么是shader呢:

Shader分为Vertex Shader顶点着色器和Pixel Shader像素着色器两种。其中Vertex Shader主要负责顶点的几何关系等的运算,Pixel Shader主要负责片源颜色等的计算。
着色器替代了传统的固定渲染管线,可以实现3D图形学计算中的相关计算,由于其可编辑性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。这极大的提高了图像的画质。
好了,介绍完渲染流程,我们变进入正题,如何在上一篇的基础上完成一个简单三角形的渲染呢?
首先,我们要建立一个三角形的局部坐标系,也就是三角形每个点的顶点坐标。
[objc] view plain copy
  1. GLKVector3 vec[3]={  
  2.     {0.5,0.5,0.5},  
  3.     {-0.5,-0.5,0.5},  
  4.     {0.5,-0.5,-0.5}  
  5. };  
        然后,因为我们介绍的是opengl es3.0的编程,所以我们用的是可编程管线,那么我们就应该建立一个vertex shader文件和一个pixel shader文件,分别命名为shader.vsh和shader.fsh。
shader.vsh:
[objc] view plain copy
  1. attribute vec3 position;   //入参,主程序会将数值传入  
  2. void main()  
  3. {  
  4.     gl_Position = vec4(position,1);  //顶点经过投影变换变换后的位置  
  5. }  
       shader.fsh:
[objc] view plain copy
  1. void main()  
  2. {  
  3.     gl_FragColor = vec4(0.5,0.5,0.5,1);   //顶点的颜色  
  4. }  
       可以看到,每一个着色器文件都一个类似于c语言的main函数入口,这个就是着色器的入口,所有的代码都从这里开始执行。
编写完着色器后,我们便需要在主程序里加载shader了,加载shader的代码基本上不需要变动什么,直接copy过来就可以了。
[objc] view plain copy
  1. - (BOOL)loadShaders  
  2. {  
  3.     GLuint vertShader, fragShader;  
  4.     NSString *vertShaderPathname, *fragShaderPathname;  
  5.       
  6.     // Create shader program.  
  7.     program = glCreateProgram();  
  8.       
  9.     // Create and compile vertex shader.  
  10.     vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];  
  11.     if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {  
  12.         NSLog(@"Failed to compile vertex shader");  
  13.         return NO;  
  14.     }  
  15.       
  16.     // Create and compile fragment shader.  
  17.     fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];  
  18.     if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {  
  19.         NSLog(@"Failed to compile fragment shader");  
  20.         return NO;  
  21.     }  
  22.       
  23.     // Attach vertex shader to program.  
  24.     glAttachShader(program, vertShader);  
  25.       
  26.     // Attach fragment shader to program.  
  27.     glAttachShader(program, fragShader);  
  28.       
  29.     // Link program.  
  30.     if (![self linkProgram:program]) {  
  31.         NSLog(@"Failed to link program: %d", program);  
  32.           
  33.         if (vertShader) {  
  34.             glDeleteShader(vertShader);  
  35.             vertShader = 0;  
  36.         }  
  37.         if (fragShader) {  
  38.             glDeleteShader(fragShader);  
  39.             fragShader = 0;  
  40.         }  
  41.         if (program) {  
  42.             glDeleteProgram(program);  
  43.             program = 0;  
  44.         }  
  45.           
  46.         return NO;  
  47.     }  
  48.     // Release vertex and fragment shaders.  
  49.     if (vertShader) {  
  50.         glDetachShader(program, vertShader);  
  51.         glDeleteShader(vertShader);  
  52.     }  
  53.     if (fragShader) {  
  54.         glDetachShader(program, fragShader);  
  55.         glDeleteShader(fragShader);  
  56.     }  
  57.       
  58.     return YES;  
  59. }  
  60.   
  61. - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file  
  62. {  
  63.     GLint status;  
  64.     const GLchar *source;  
  65.       
  66.     source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];  
  67.     if (!source) {  
  68.         NSLog(@"Failed to load vertex shader");  
  69.         return NO;  
  70.     }  
  71.       
  72.     *shader = glCreateShader(type);  
  73.     glShaderSource(*shader, 1, &source, NULL);  
  74.     glCompileShader(*shader);  
  75.       
  76. #if defined(DEBUG)  
  77.     GLint logLength;  
  78.     glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);  
  79.     if (logLength > 0) {  
  80.         GLchar *log = (GLchar *)malloc(logLength);  
  81.         glGetShaderInfoLog(*shader, logLength, &logLength, log);  
  82.         NSLog(@"Shader compile log:\n%s", log);  
  83.         free(log);  
  84.     }  
  85. #endif  
  86.       
  87.     glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);  
  88.     if (status == 0) {  
  89.         glDeleteShader(*shader);  
  90.         return NO;  
  91.     }  
  92.       
  93.     return YES;  
  94. }  
  95.   
  96. - (BOOL)linkProgram:(GLuint)prog  
  97. {  
  98.     GLint status;  
  99.     glLinkProgram(prog);  
  100.       
  101. #if defined(DEBUG)  
  102.     GLint logLength;  
  103.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);  
  104.     if (logLength > 0) {  
  105.         GLchar *log = (GLchar *)malloc(logLength);  
  106.         glGetProgramInfoLog(prog, logLength, &logLength, log);  
  107.         NSLog(@"Program link log:\n%s", log);  
  108.         free(log);  
  109.     }  
  110. #endif  
  111.       
  112.     glGetProgramiv(prog, GL_LINK_STATUS, &status);  
  113.     if (status == 0) {  
  114.         return NO;  
  115.     }  
  116.       
  117.     return YES;  
  118. }  
  119.   
  120. - (BOOL)validateProgram:(GLuint)prog  
  121. {  
  122.     GLint logLength, status;  
  123.       
  124.     glValidateProgram(prog);  
  125.     glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);  
  126.     if (logLength > 0) {  
  127.         GLchar *log = (GLchar *)malloc(logLength);  
  128.         glGetProgramInfoLog(prog, logLength, &logLength, log);  
  129.         NSLog(@"Program validate log:\n%s", log);  
  130.         free(log);  
  131.     }  
  132.       
  133.     glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);  
  134.     if (status == 0) {  
  135.         return NO;  
  136.     }  
  137.       
  138.     return YES;  
  139. }  
      然后再viewdidload里面添加如下代码:
[objc] view plain copy
  1. [self loadShaders];  
  2.     glEnable(GL_DEPTH_TEST);  
  3.     glClearColor(0.10.20.31);  
  4.     glGenVertexArrays(1, &vertexID);//生成一个vao对象  
  5.     glBindVertexArray(vertexID); //绑定vao  
  6.     GLuint bufferID;  
  7.     glGenBuffers(1, &bufferID);  //生成vbo  
[objc] view plain copy
  1. glBindBuffer(GL_ARRAY_BUFFER, bufferID);  //绑定  
  2.     glBufferData(GL_ARRAY_BUFFER, sizeof(vec), vec, GL_STATIC_DRAW); //填充缓冲对象  
  3.     GLuint loc=glGetAttribLocation(program, "position");   //获得shader里position变量的索引  
  4.     glEnableVertexAttribArray(loc);     //启用这个索引  
  5.     glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLKVector3), 0);  //设置这个索引需要填充的内容  
  6.     glBindVertexArray(0);   //释放vao  
  7.     glBindBuffer(GL_ARRAY_BUFFER, 0);  //释放vbo  
       这里我们用到了es 3.0里面的新技术vao(vertex array object)以及2.0里面的vbo。关于vao和vbo,我们会专门展开一章来探讨,现在大家知道就行啦。
       接下来便到了渲染阶段,这里的代码需要写在-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法里。
[objc] view plain copy
  1. -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect  
  2. {  
  3.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //清除颜色缓冲和深度缓冲  
  4.     glBindVertexArray(vertexID);      
  5.     glUseProgram(program);      //使用shader  
  6.     glDrawArrays(GL_TRIANGLES, 03);     //绘制三角形  
  7.     glBindVertexArray(0);  
  8.     glBindBuffer(GL_ARRAY_BUFFER, 0);  
  9.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);  
  10. }  
      代码阶段便编写完成啦,保存运行,出现如下界面便大功告成啦。



没有更多推荐了,返回首页