学习OpenGL ES之绘制一个正方体

本系列所有文章目录

获取示例代码


经过前面7篇文章的铺垫,绘制正方体已经不是什么难事了。正方体其实就是由6个矩形组成的几何体,X,Y,Z轴上各两个矩形。下面是Z轴上两个矩形的示意图。


绘制Z轴两个矩形的代码如下。

- (void)drawZPlanes {
    static GLfloat triangleData[] = {
        -0.5,   0.5f,  0.5,   0,  0,  1,
        -0.5f,  -0.5f,  0.5,  0,  0,  1,
        0.5f,   -0.5f,  0.5,  0,  0,  1,
        0.5,    -0.5f, 0.5,   0,  0,  1,
        0.5f,  0.5f,  0.5,    0,  0,  1,
        -0.5f,   0.5f,  0.5,  0,  0,  1,
        -0.5,   0.5f,  -0.5,   0,  0,  1,
        -0.5f,  -0.5f,  -0.5,  0,  0,  1,
        0.5f,   -0.5f,  -0.5,  0,  0,  1,
        0.5,    -0.5f, -0.5,   0,  0,  1,
        0.5f,  0.5f,  -0.5,    0,  0,  1,
        -0.5f,   0.5f,  -0.5,  0,  0,  1,
    };
    [self bindAttribs:triangleData];
    glDrawArrays(GL_TRIANGLES, 0, 12);
}

其他轴的平面绘制规则一样,将Z轴数据第三列移到第一列和第二列即可生成X,Y轴上的矩形数据。

- (void)drawXPlanes {
    static GLfloat triangleData[] = {
// X轴0.5处的平面
      0.5,  -0.5,    0.5f, 1,  0,  0,
      0.5,  -0.5f,  -0.5f, 1,  0,  0,
      0.5,  0.5f,   -0.5f, 1,  0,  0,
      0.5,  0.5,    -0.5f, 1,  0,  0,
      0.5,  0.5f,    0.5f, 1,  0,  0,
      0.5,  -0.5f,   0.5f, 1,  0,  0,
// X轴-0.5处的平面
      -0.5,  -0.5,    0.5f, 1,  0,  0,
      -0.5,  -0.5f,  -0.5f, 1,  0,  0,
      -0.5,  0.5f,   -0.5f, 1,  0,  0,
      -0.5,  0.5,    -0.5f, 1,  0,  0,
      -0.5,  0.5f,    0.5f, 1,  0,  0,
      -0.5,  -0.5f,   0.5f, 1,  0,  0,
    };
    [self bindAttribs:triangleData];
    glDrawArrays(GL_TRIANGLES, 0, 12);
}

- (void)drawYPlanes {
    static GLfloat triangleData[] = {
        -0.5,  0.5,  0.5f, 0,  1,  0,
        -0.5f, 0.5, -0.5f, 0,  1,  0,
        0.5f, 0.5,  -0.5f, 0,  1,  0,
        0.5,  0.5,  -0.5f, 0,  1,  0,
        0.5f, 0.5,   0.5f, 0,  1,  0,
        -0.5f, 0.5,  0.5f, 0,  1,  0,
         -0.5, -0.5,   0.5f, 0,  1,  0,
         -0.5f, -0.5, -0.5f, 0,  1,  0,
         0.5f, -0.5,  -0.5f, 0,  1,  0,
         0.5,  -0.5,  -0.5f, 0,  1,  0,
         0.5f, -0.5,   0.5f, 0,  1,  0,
         -0.5f, -0.5,  0.5f, 0,  1,  0,
    };
    [self bindAttribs:triangleData];
    glDrawArrays(GL_TRIANGLES, 0, 12);
}

我将每个轴上的平面赋予不同的颜色便于区分。

我移除了modelMatrix2,将modelMatrix1改为modelMatrix。每一次update的时候我将modelMatrix的赋值修改为围绕1,1,1轴旋转。

- (void)update {
    [super update];
    float varyingFactor = (sin(self.elapsedTime) + 1) / 2.0; // 0 ~ 1
    self.cameraMatrix = GLKMatrix4MakeLookAt(0, 0, 2 * (varyingFactor + 1), 0, 0, 0, 0, 1, 0);
    
    GLKMatrix4 rotateMatrix = GLKMatrix4MakeRotation(varyingFactor * M_PI * 2, 1, 1, 1);
    self.modelMatrix = rotateMatrix;
}

增加一个drawCube方法,绘制各个矩形。

- (void)drawCube {
    [self drawXPlanes];
    [self drawYPlanes];
    [self drawZPlanes];
}

最后调用drawCube绘制正方体。

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    [super glkView:view drawInRect:rect];
  
    GLuint projectionMatrixUniformLocation = glGetUniformLocation(self.shaderProgram, "projectionMatrix");
    glUniformMatrix4fv(projectionMatrixUniformLocation, 1, 0, self.projectionMatrix.m);
    GLuint cameraMatrixUniformLocation = glGetUniformLocation(self.shaderProgram, "cameraMatrix");
    glUniformMatrix4fv(cameraMatrixUniformLocation, 1, 0, self.cameraMatrix.m);
    
    GLuint modelMatrixUniformLocation = glGetUniformLocation(self.shaderProgram, "modelMatrix");
    glUniformMatrix4fv(modelMatrixUniformLocation, 1, 0, self.modelMatrix.m);
    [self drawCube];
}

效果如下。

效果很奇怪是不是?因为我们缺少一个很重要的配置glEnable(GL_DEPTH_TEST);。他有什么用呢?默认情况下,谁后绘制谁在最上面,而glEnable(GL_DEPTH_TEST);之后;绘制顺序则按照Z轴的坐标为准。为了配合glEnable(GL_DEPTH_TEST);,还要将glClear(GL_COLOR_BUFFER_BIT)改成glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);,因为按照Z轴排序是要激活一个新的深度缓存区的,所以每次清除缓存区的时候不仅要清除颜色缓存数据还要清除深度缓存数据,否则会影响新的深度数据的写入。修改了两处之后,效果如下。

这次就正常了。本文主要介绍了绘制正方体的思路和方法,读者可以拓展一下,比如绘制由4个三角形构成的三角锥。立体几何体基本都可以分解成很多三角形,只要找到规律,绘制起来就很简单。

下一篇开始讲解基本的光照模型,让立方体看起来更真实。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容