Opengl ES( Opengl for Embedded Systems)是 Opengl三維圖形API的子集,針對手機、
PDA和游戲主機等嵌入式設備而設計。API由圖形軟硬件行業(yè)協(xié)會 Khronos Group定義推廣
該協(xié)會主要關注圖形和多媒體方面的開放標準。
Opengl ES是從 Opengl裁剪定制而來的,去除了 glbegin/glend、四邊形(GL_ QUADS)、
多邊形( GL POLYGONS)等復雜圖元中許多非絕對必要的特性。經(jīng)過多年發(fā)展,現(xiàn)在主
要有兩個版本: Opengl ES1.x,針對固定管線硬件; Opengl ES2x,針對可編程管線硬件。
以下轉(zhuǎn)載自網(wǎng)絡:
- CAEAGLLayer,在CAEAGLLayer層上進行OpenGL的繪制.
- EAGLContext,創(chuàng)建OpenGL context,管理所有使用OpenGL ES進行繪制的狀態(tài),命令及資源信息。
需要生命API,設置為當前context - 渲染緩沖區(qū) renderbuffer,三種colorbuffer,depthbuffer,stencilbuffer
void glGenRenderbuffers (GLsizei n, GLuint* renderbuffers) 將分配到的renderbuffer的id存于renderbuffers中。
void glBindRenderbuffer (GLenum target, GLuint renderbuffer) 將指定id的renderbuffer設置為當前renderbuffer。
(BOOL)renderbufferStorage:(NSUInteger)target fromDrawable:(id<EAGLDrawable>)drawable 為renderbuffer分配存儲空間
- 幀緩沖區(qū) framebuffer,
void glGenFramebuffers (GLsizei n, GLuint* framebuffers)
void glBindFramebuffer (GLenum target, GLuint framebuffer) 設置為當前framebuffer
void glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 將renderbuffer裝配到attachment這個裝配點上
- 設置clearColor
glClearColor(1.0, 1.0, 1.0, 1.0)// 設置clearColor
glClear(GL_COLOR_BUFFER_BIT)
調(diào)用presentRenderbuffer方法, 將renderbuffer和colorbuffer呈現(xiàn)到UIView上.
著色器由類似C的語言GLSL編寫.
Vertex shader: 頂點著色器. 如在長方形中vertex shader會被調(diào)用四次.
負責執(zhí)行燈光, 幾何變換等計算, 得出最終的頂點位置后, 為片段著色器提供數(shù)據(jù).
Fragment shader: 片段著色器, 負責計算每個像素的最終顏色.
著色器使用之前要先編譯,以及其他的一些操作.glVertexAttribPointer指定了渲染時索引值為index的頂點屬性數(shù)組的數(shù)據(jù)格式和位置.
void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,const GLvoid * pointer)
size和type分別指定每個頂點屬性的組件數(shù)量和數(shù)據(jù)類型, normalized指定當被訪問時, 固定點數(shù)據(jù)值是否應該被歸一化或直接轉(zhuǎn)換為固定點值.
stride指定連續(xù)頂點屬性之間的偏移量, 用于描述每個vertex數(shù)據(jù)大小.
pointer指定第一個組件在數(shù)組的第一個頂點屬性中的偏移量, 與GL_ARRAY_BUFFER綁定存儲于緩沖區(qū)中.
如:
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)(sizeof(float)*3));
- 指定triangle的三個頂點, 然后調(diào)用glVertexAttribPointer和glEnableVertexAttribArray來加載vertex數(shù)據(jù).
最后調(diào)用glDrawArrays(GL_TRIANGLES, 0, 3)來繪制triangle. - 在compileShaders中的glGetAttribLocation方法, "vPosition"要和shader中的對應一致.
使用CoreImage的filter.
導入CIImage圖片->創(chuàng)建CIFilter->用CIContext將濾鏡中的圖片渲染出來->導出并顯示圖片.使用CoreImage+OpenGL ES實現(xiàn)filter.
獲取OpenGL ES渲染的context->創(chuàng)建渲染buffer->創(chuàng)建CoreImage使用的CIContext->設置CoreImage->渲染圖片.使用OpenGL ES繪制已有圖片.
創(chuàng)建并添加GLKView到view, 調(diào)用[_glkView bindDrawable];和[_glkView display];
繪制長方形(通過vertex), 啟用顏色.
啟用vertex貼圖坐標:
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
// 因為讀取圖片信息的時候默認是從圖片左上角讀取的, 而OpenGL繪制卻是從左下角開始的.所以我們要從左下角開始讀取圖片數(shù)據(jù).
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(YES), GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:image.CGImage options:options error:nil];
創(chuàng)建并設置GLKBaseEffect:
GLKBaseEffect *baseEffect = [[GLKBaseEffect alloc] init];
// 創(chuàng)建一個二維的投影矩陣, 即定義一個視野區(qū)域(鏡頭看到的東西)
// GLKMatrix4MakeOrtho(float left, float right, float bottom, float top, float nearZ, float farZ)
baseEffect.transform.projectionMatrix = GLKMatrix4MakeOrtho(-1, 1, -1, 1, -1, 1);
baseEffect.texture2d0.name = textureInfo.name;
[baseEffect prepareToDraw];
// 最后繪制圖片
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- 使用CGContextRef等繪制圖片:
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef image = CGImageRetain([[UIImage imageNamed:@"testImage.png"] CGImage]);
CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), image);
在圖片上使用畫筆:
先通過touchesMoved等方法將劃過的點(調(diào)用UITouch的locationInView方法取得CGPoint)存入_linesCompleted中, 然后在drawRect中:
CGContextSetLineWidth(context, 5.0);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 0.5);
for (Line *l in _linesCompleted) {
CGContextMoveToPoint(context, l.begin.x, l.begin.y);
CGContextAddLineToPoint(context, l.end.x, l.end.y);
CGContextStrokePath(context);
}