iOS开发-OpenGLES的新手教程
OpenGLES
这里是一篇新手教程,环境是xcode7+OpenGLES2.0,主要是用一个样例,介绍OpenGLES的基本概念。
代码先行
1,到 这里 下载demo代码。打开tutorial01,核心代码如下:
#import "ViewController.h" @interface ViewController () @property (nonatomic , strong) EAGLContext* mContext; @property (nonatomic , strong) GLKBaseEffect* mEffect; @property (nonatomic , assign) int mCount; @end @implementation ViewController { dispatch_source_t timer; //临时变量的弱引用会导致定时器失效 } - (void)viewDidLoad { [super viewDidLoad]; //新建OpenGLES 上下文 self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,还有1.0和3.0 GLKView* view = (GLKView *)self.view; //storyboard记得添加 view.context = self.mContext; view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; //颜色缓冲区格式 view.drawableDepthFormat = GLKViewDrawableDepthFormat24; // 模板缓冲区格式 [EAGLContext setCurrentContext:self.mContext]; glEnable(GL_DEPTH_TEST); //开启深度测试,这里因为是2D图形,没有作用,可以尝试注释进阶里面的这句 //顶点数据,前三个是顶点坐标,法线,纹理坐标 GLfloat squareVertexData[48] = { 0.5, -0.5, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //右下 -0.5, 0.5, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, //左上 -0.5, -0.5, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //左下 0.5, 0.5, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //右上 }; //顶点索引 GLuint indices[] = { 0, 1, 2, 1, 3, 0 }; self.mCount = sizeof(indices) / sizeof(GLuint); //顶点数据缓存 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW); GLuint index; glGenBuffers(1, &index); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数据缓存 glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 0); glEnableVertexAttribArray(GLKVertexAttribNormal); //法线 glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 12); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理 glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 4 * 8, (char *)NULL + 24); //纹理贴图 NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"png"]; NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的 GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil]; //着色器 self.mEffect = [[GLKBaseEffect alloc] init]; self.mEffect.light0.enabled = GL_TRUE; self.mEffect.light0.diffuseColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f); self.mEffect.texture2d0.enabled = GL_TRUE; self.mEffect.texture2d0.name = textureInfo.name; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * 场景数据变化 */ - (void)update { //投影变换 CGSize size = self.view.bounds.size; float aspect = fabs(size.width / size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(90.0), aspect, 0.1f, 10.f); projectionMatrix = GLKMatrix4Scale(projectionMatrix, 1.0f, 1.0f, 1.0f); self.mEffect.transform.projectionMatrix = projectionMatrix; //z轴平移 GLKMatrix4 modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0f, 0.0f, -2.0f); self.mEffect.transform.modelviewMatrix = modelViewMatrix; } /** * 渲染场景代码 */ - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.3f, 0.6f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //启动着色器 [self.mEffect prepareToDraw]; glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0); } @end
概念介绍
三大缓冲区:颜色缓冲区、模板缓冲区、深度缓冲区
OpenGLES的顶点数据缓存
重点理解 glBufferData()和 glVertexAttribPointer()两个函数。
当调用过glBufferData()函数过后,glVertexAttribPointer()函数最后一个参数变成偏移量;
纹理的概念
坐标系:纹理坐标系、世界坐标系、屏幕坐标系
着色器:顶点着色器和片元着色器
光照
视图变换