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()函數最后一個參數變成偏移量;
紋理的概念
坐標系:紋理坐標系、世界坐標系、屏幕坐標系
着色器:頂點着色器和片元着色器
光照
視圖變換