美文网首页iOS开发iOS程序猿程序员
OpenGL ES 开篇:OpenGL ES与硬件和iOS 系统

OpenGL ES 开篇:OpenGL ES与硬件和iOS 系统

作者: 我是熊大啊 | 来源:发表于2017-05-30 12:05 被阅读73次

前言:

OpenGL ES是跨平台的可应用于WindowsPhone、Andriod、iOS 等移动平台。

GLKit和OpenGL ES的关系:
GLKit是在iOS 开发中OpenGL ES 的框架,其地位等同于AVFoundation、UIKit等框架。
GLKit对OpenGL ES进行封装、极大地简化了我们使用OpenGL ES的步骤和代码。
其实我们常用的CoreAnimation也是对OpenGL ES进行了封装。

u=2857221768,1992251917&fm=23&gp=0.jpg

其实上面这张图并非十分准确,因为OpenGL ES主要作用于GPU,其次还会作用于CPU,如:从CPU数据进行数据缓存,协调GPU和CPU的数据交换。

涉及到的英语:

我们需要掌握一些简单地英文,方便我们记忆,我整理到常用的主要有这几个

英语 | 汉语 | 发音
----------|-----------
Vector | 矢量 | ['vektə]
Coords | 坐标| ['kurz]
Scene | 场景 | [siːn]
position | 位置 | [pə'zɪʃ(ə)n]
Vertex |顶点 | ['vɜːteks]
vertices| vertex的复数|--
buffer|缓冲|['bʌfə]
Gen(generate)|使形成;发生;生殖;产生物理反应|['dʒenəreɪt]
Bind|绑;约束|[baɪnd]
Elements|n. 基础;原理|['elimənts]

绘制图形的7个步骤:
步骤 C语言函数
1.生成独一无二的标识符 glGenBuffers()
2.绑定 glBindBuffer()
3.缓存数据(分配内存并从CPU控制的内存复制到刚刚分配的内存) glBufferData()
4.启用或禁止使用缓存数据 glEnableVertexAttribArray()或glDisableVertexAttribArray()
5.设置指针 glVertexAttribPointer()
6.绘图 glDrawArrays()或者glDrawElements()
7.删除 glDelegateBuffers()

以上这7个步骤是绘图的必要步骤。

在OpenGL ES 应用程序开发指南中创建了下面两个类:

AGLKContext以及AGLKVertexAttribArrayBuffer分别用于清除顶点缓存和简化这七个步骤。
AGLKContext继承于EAGLContentext ,添加了clearColor属性和设置上下文的帧缓存中的每个像素为clearColor.

AGLKVertexAttribArrayBuffer添加了 三个方法 用于简化这七个步骤:

方法一:

//其中包含了绑定、生成、缓存数据三个步骤
- (id)initWithAttribStride:(GLsizei)stride
   numberOfVertices:(GLsizei)count
   bytes:(const GLvoid *)dataPtr
   usage:(GLenum)usage;

封装了1、2、3三个步骤(绑定、生成、缓存数据):

   NSParameterAssert(0 < aStride);
   NSAssert((0 < count && NULL != dataPtr) ||
      (0 == count && NULL == dataPtr),
      @"data must not be NULL or count > 0");
      
   if(nil != (self = [super init]))
   {
      stride = aStride;
      bufferSizeBytes = stride * count;
      
      glGenBuffers(1,                // STEP 1
         &name);
      glBindBuffer(GL_ARRAY_BUFFER,  // STEP 2
         self.name); 
      glBufferData(                  // STEP 3
         GL_ARRAY_BUFFER,  // Initialize buffer contents
         bufferSizeBytes,  // Number of bytes to copy
         dataPtr,          // Address of bytes to copy
         usage);           // Hint: cache in GPU memory
         
      NSAssert(0 != name, @"Failed to generate name");
   }
   
   return self;

方法二:

- (void)prepareToDrawWithAttrib:(GLuint)index
   numberOfCoordinates:(GLint)count
   attribOffset:(GLsizeiptr)offset
   shouldEnable:(BOOL)shouldEnable;

封装了2、4、5三个步骤

   NSParameterAssert((0 < count) && (count < 4));
   NSParameterAssert(offset < self.stride);
   NSAssert(0 != name, @"Invalid name");

   glBindBuffer(GL_ARRAY_BUFFER,     // STEP 2
      self.name);

   if(shouldEnable)
   {
      glEnableVertexAttribArray(     // Step 4
         index); 
   }

   glVertexAttribPointer(            // Step 5
      index,               // Identifies the attribute to use
      count,               // number of coordinates for attribute
      GL_FLOAT,            // data is floating point
      GL_FALSE,            // no fixed point scaling
      (self.stride),       // total num bytes stored per vertex
      NULL + offset);      // offset from start of each vertex to 
                           // first coord for attribute
#ifdef DEBUG
   {  // Report any errors 
      GLenum error = glGetError();
      if(GL_NO_ERROR != error)
      {
         NSLog(@"GL Error: 0x%x", error);
      }
   }
#endif
}

方法三:

- (void)drawArrayWithMode:(GLenum)mode
   startVertexIndex:(GLint)first
   numberOfVertices:(GLsizei)count

封装了6

   NSAssert(self.bufferSizeBytes >= 
      ((first + count) * self.stride),
      @"Attempt to draw more vertex data than available.");
      
   glDrawArrays(mode, first, count); // Step 6```
以及重写7:
  • (void)dealloc
    {
    // Delete buffer from current context
    if (0 != name)
    {
    glDeleteBuffers (1, &name); // Step 7
    name = 0;
    }
    }
****
###绘制一个三角形
- 引入GLKit
- 继承GLKViewContriller
- 绘制
- 重写viewDidUnload

#####C知识:
   定义一个C结构体 GLKVector3类型 可以用来保存三个坐标(x\y\z)

typedef struct{
GLKVector3 positionCoords;
}
SceneVertex;

定义一个C数组 储存的 `SceneVertex`类型数组 --上面定义的
`SceneVertex :GLKVector3`  (3个向量的)

static const SceneVertex vertices[] = {
{{-0.5f, -0.5f, 0.0}},//第三象限的点
{{ 0.5f, -0.5f, 0.0}},//第四象限的点
{{-0.5f, 0.5f, 0.0}}//第二象限的点
};


  • (void)viewDidLoad {
    [super viewDidLoad];

    GLKView *view = (GLKView *)self.view;
    NSAssert([view isKindOfClass:[GLKView class]], @"不是GLKView");

    view.context = [[AGLKContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [AGLKContext setCurrentContext:view.context];

    self.baseEffect = [[GLKBaseEffect alloc]init];
    self.baseEffect.useConstantColor = GL_TRUE;
    self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);

    ((AGLKContext *)view.context).clearColor = GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f);

    self.vertexBuffer = [[AGLKVertexAttribArrayBuffer alloc]
    initWithAttribStride:sizeof(SceneVertex)
    numberOfVertices:sizeof(vertices)/sizeof(SceneVertex)
    bytes:vertices
    usage:GL_STATIC_DRAW];

}



  • (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
    {
    [self.baseEffect prepareToDraw];

    [(AGLKContext *)view.context clear:GL_COLOR_BUFFER_BIT];

    [self.vertexBuffer prepareToDrawWithAttrib:GLKVertexAttribPosition
    numberOfCoordinates:3
    attribOffset:offsetof(SceneVertex, positionCoords)
    shouldEnable:YES];

    [self.vertexBuffer drawArrayWithMode:GL_TRIANGLES
    startVertexIndex:0
    numberOfVertices:3];

}

  • (void)viewDidUnload{
    [super viewDidUnload];
    GLKView *view = (GLKView *)self.view;
    [AGLKContext setCurrentContext:view.context];

    self.vertexBuffer = nil;
    ((GLKView *)self.view).context = nil;

    [EAGLContext setCurrentContext:nil];
    }

[Demo1使用原生 ](https://coding.net/u/Xoxo_x/p/OpenGL-ES1/git/blob/master/OpenGL_ES_1.zip)
[Demo2使用简化的类](https://coding.net/u/Xoxo_x/p/OpenGL_ES_2/git/blob/master/OpenGL_ES_2.zip)
****
####绘制三角形注释版:http://www.jianshu.com/p/3988825ef858

相关文章

网友评论

    本文标题:OpenGL ES 开篇:OpenGL ES与硬件和iOS 系统

    本文链接:https://www.haomeiwen.com/subject/jptrfxtx.html