前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >OpenGLES-04 绘制带颜色的立方体

OpenGLES-04 绘制带颜色的立方体

作者头像
清墨
发布于 2018-05-07 07:56:16
发布于 2018-05-07 07:56:16
1.6K00
代码可运行
举报
文章被收录于专栏:清墨_iOS分享清墨_iOS分享
运行总次数:0
代码可运行

前面几篇文章都只是绘制了平面图形,接下来我们开始绘制一个真正的3D立方体图形。代码在前一篇文章基础上修改。 绘制立方体之前,我们需要知道这个立方体的各个顶点坐标(找不到图,自己画的,请将就将就):

IMG_0004.JPG

一个立方体有8个顶点,在这里是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GLfloat vertices[] = {
        -0.5f, -0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f, -0.5f, 0.5f,
        
        0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        -0.5f, 0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
    };

它的索引是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GLubyte indices[] = {
        // Front face
        0, 3, 2, 0, 2, 1,
        
        // Back face
        7, 5, 4, 7, 6, 5,
        
        // Left face
        0, 1, 6, 0, 6, 7,
        
        // Right face
        3, 4, 5, 3, 5, 2,
        
        // Up face
        1, 2, 5, 1, 5, 6,
        
        // Down face
        0, 7, 4, 0, 4, 3
    };

所以我们修改render函数的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-(void)render
{
    //设置清屏颜色,默认是黑色,如果你的运行结果是黑色,问题就可能在这儿
    glClearColor(0.3, 0.5, 0.8, 1.0);
    /*
    glClear指定清除的buffer
    共可设置三个选项GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT
    也可组合如:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    这里我们只用了color buffer,所以只需清除GL_COLOR_BUFFER_BIT
     */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Setup viewport
    glViewport(0, 0, self.frame.size.width, self.frame.size.height);

    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f, -0.5f, 0.5f,
        
        0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        -0.5f, 0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
    };
    
    GLubyte indices[] = {
        // Front face
        0, 3, 2, 0, 2, 1,
        
        // Back face
        7, 5, 4, 7, 6, 5,
        
        // Left face
        0, 1, 6, 0, 6, 7,
        
        // Right face
        3, 4, 5, 3, 5, 2,
        
        // Up face
        1, 2, 5, 1, 5, 6,
        
        // Down face
        0, 7, 4, 0, 4, 3
    };
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(_positionSlot);
    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices);
     
    
    [_context presentRenderbuffer:_renderBuffer];
}

运行结果如下:

运行结果.png

诶,我们不是画了个立方体吗?代码画的怎么跟我在纸上画的那个不一样呢? 事实上,我们代码画的确实是一个立方体,只是我们观察的角度是从正方体正面看过去的,立体的部分全被前面的面挡住了,只要我们旋转一下立方体,就能看到立体的部分了,不过这个问题会在下一篇讲到,这里先绘制立方体,只修改它的颜色。 而且,事实上我们画的是个正方体,这里展示是个长方体,这是由于没有进行宽高等比的投影矩阵处理,这里opengl坐标是按着屏幕来的,所以是个长方体。

图中立方体的颜色是我们在片元着色器脚本文件自己定义的固定颜色

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
precision mediump float;

void main()
{
    gl_FragColor = vec4(0.9, 0.5, 0.7, 1.0);
}

如果我们想在外面的代码中动态修改它的颜色,我们需要定义一个变量来接收传入的颜色。 1.修改顶点着色器脚本文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
attribute vec4 vPosition;

attribute vec4 vSourceColor;      //新加
varying vec4 vDestinationColor;   //新加

void main(void)
{
    gl_Position = vPosition;
    vDestinationColor = vSourceColor; //新加
}

2.修改片元着色器脚本文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
precision mediump float;

varying vec4 vDestinationColor;  //新加

void main()
{
    gl_FragColor = vDestinationColor;  //修改
}

以上着色器代码在《OpenGLES-02 绘制基本图元(点、线、三角形)》中有介绍,详细了解glsl请点这里 (也希望你确实做过《拨开迷雾》里的准备工作,如果到这里你还有很多概念不理解,希望你停下来,先去查询资料,理解概念): http://www.cnblogs.com/kex1n/p/3941680.html

好啦,着色器语言已经写好了,接下来我们开始使用

3.代码绘制 我们在MyGLView中新定义一个变量:GLuint _colorSlot; //颜色槽位

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface MyGLView ()
{
    CAEAGLLayer *_eaglLayer;  //OpenGL内容只会在此类layer上描绘
    EAGLContext *_context;    //OpenGL渲染上下文
    GLuint _renderBuffer;     //
    GLuint _frameBuffer;      //

    GLuint _programHandle;
    GLuint _positionSlot; //顶点槽位
    GLuint _colorSlot;   //颜色槽位
}

然后在setupProgram函数中获取这个_colorSlot:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_positionSlot = glGetAttribLocation(_programHandle, "vPosition");
_colorSlot    = glGetAttribLocation(_programHandle, "vSourceColor"); //新加

接下来我们需要构造自己的颜色数据,对于OpenGL,它支持两种着色模式:单调着色(Flat)与平滑着色(smooth,也称Gouraud着色)。单调着色就是整个图元的颜色就是它的任何一个顶点的颜色,比如上面固定颜色的三角形效果;平滑着色下每个顶点都是单独进行的,顶点之间的点是所有顶点颜色的均匀插值计算而得,顶点与顶点颜色是在一起的,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GLfloat vertices[] = {
        -0.5f, -0.5f, 0.5f, 1.0, 0.0, 0.0, 1.0,     // red
        -0.5f, 0.5f, 0.5f, 1.0, 1.0, 0.0, 1.0,      // yellow
        0.5f, 0.5f, 0.5f, 0.0, 0.0, 1.0, 1.0,       // blue
        0.5f, -0.5f, 0.5f, 1.0, 1.0, 1.0, 1.0,      // white
        
        0.5f, -0.5f, -0.5f, 1.0, 1.0, 0.0, 1.0,     // yellow
        0.5f, 0.5f, -0.5f, 1.0, 0.0, 0.0, 1.0,      // red
        -0.5f, 0.5f, -0.5f, 1.0, 1.0, 1.0, 1.0,     // white
        -0.5f, -0.5f, -0.5f, 0.0, 0.0, 1.0, 1.0,    // blue
    };

索引数据是不变的,然后我们需要使用颜色槽位数据,修改render函数如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-(void)render
{
    //设置清屏颜色,默认是黑色,如果你的运行结果是黑色,问题就可能在这儿
    glClearColor(0.3, 0.5, 0.8, 1.0);
    /*
    glClear指定清除的buffer
    共可设置三个选项GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT
    也可组合如:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    这里我们只用了color buffer,所以只需清除GL_COLOR_BUFFER_BIT
     */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Setup viewport
    glViewport(0, 0, self.frame.size.width, self.frame.size.height);
    
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.5f, 1.0, 0.0, 0.0, 1.0,     // red
        -0.5f, 0.5f, 0.5f, 1.0, 1.0, 0.0, 1.0,      // yellow
        0.5f, 0.5f, 0.5f, 0.0, 0.0, 1.0, 1.0,       // blue
        0.5f, -0.5f, 0.5f, 1.0, 1.0, 1.0, 1.0,      // white
        
        0.5f, -0.5f, -0.5f, 1.0, 1.0, 0.0, 1.0,     // yellow
        0.5f, 0.5f, -0.5f, 1.0, 0.0, 0.0, 1.0,      // red
        -0.5f, 0.5f, -0.5f, 1.0, 1.0, 1.0, 1.0,     // white
        -0.5f, -0.5f, -0.5f, 0.0, 0.0, 1.0, 1.0,    // blue
    };
    
    GLubyte indices[] = {
        // Front face
        0, 3, 2, 0, 2, 1,
        
        // Back face
        7, 5, 4, 7, 6, 5,
        
        // Left face
        0, 1, 6, 0, 6, 7,
        
        // Right face
        3, 4, 5, 3, 5, 2,
        
        // Up face
        1, 2, 5, 1, 5, 6,
        
        // Down face
        0, 7, 4, 0, 4, 3
    };
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), vertices);
    glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), vertices+3);
    glEnableVertexAttribArray(_positionSlot);
    glEnableVertexAttribArray(_colorSlot);
    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices);
     
    
    [_context presentRenderbuffer:_renderBuffer];
}

到这里就得回过来看glVertexAttribPointer()了,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);

参数 index :为顶点数据(如顶点,颜色,法线,纹理或点精灵大小)在着色器程序中的槽位;
参数 size :指定每一种数据的组成大小,比如顶点由 x, y, z 3个组成部分,纹理由 u, v 2个组成部分;
参数 type :表示每一个组成部分的数据格式;
参数 normalized : 表示当数据为法线数据时,是否需要将法线规范化为单位长度,对于其他顶点数据设置为 GL_FALSE 即可。如果法线向量已经为单位长度设置为 GL_FALSE 即可,这样可免去不必要的计算,提升效率;
stride : 表示上一个数据到下一个数据之间的间隔(同样是以字节为单位),OpenGL ES根据该间隔来从由多个顶点数据混合而成的数据块中跳跃地读取相应的顶点数据;
ptr :值得注意,这个参数是个多面手。这里它指向 CPU 内存中的顶点数据数组;

代码中我们给stride填值,以前都是写的0,现在是写出了具体步长,写0是针对单一数据,如只有顶点数据或颜色数据的时候,系统会自己计算匹配,这时候可以写0,若不是单一数据,如上有顶点有颜色,需要自己计算出具体步长。 再看后面ptr的填值,对颜色数据,我们给出的是vertices+3,表示颜色数据从vertices的第4位开始,往后4位是颜色数据(size为4)。

代码的运行结果如下:

颜色运行结果.png

结果显示了我们立方体正面的颜色,顶点用到了(0,1,2,3),所以颜色是红黄蓝白的线性插值。下一篇文章,我们将对这个立方体进行3D变换以看清它确实是个立方体。

所有教程代码在此 : https://github.com/qingmomo/iOS-OpenGLES-

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.11.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
读PolarDB论文有感 : 异构计算和数据库软硬一体化设计
作者:熊中哲,现任才云科技工程VP,负责产品和研发工作。曾就职于阿里巴巴、沃趣科技、美团。超过12年数据库领域的工作经历,目前对云原生,机器学习和异构计算也很感兴趣。
用户1278550
2020/06/01
8930
2020年度20多款主流数据库重大更新及技术要点回顾
为方便阅读、重点呈现,本文对各板块内容进行了精简,需阅读完整版可点击文末【阅读原文】或登录云盘下载:https://pan.baidu.com/s/1h8plZz-amxxOMMWTL2eicQ(提取码:dwqg)
jeanron100
2021/02/25
1.8K0
2020年度20多款主流数据库重大更新及技术要点回顾
SIGMOD 2021 | 业务驱动背景下,腾讯云原生数据库TDSQL-C的技术演变之路
6月20-25日,数据库国际顶会2021 ACM SIGMOD在西安举行。本届大会上,腾讯云数据库技术总监邱敏带来了主题为“腾讯云数据库技术演变之路”的演讲。 演讲视频 以下为演讲内容的文字实录: 数据库是三大基础软件之一。近年来,腾讯也在不断加强各类数据库产品的研发投入。企业级分布式数据库TDSQL是腾讯云数据库的代表性产品,同时具备OLTP、OLAP,以及混合OLTP和OLAP的HTAP能力。它包括以下几个系列的产品: 企业级MySQL即腾讯云数据库RDS系统(CDB),相对原生MySQL进行
腾讯云数据库 TencentDB
2021/07/12
8580
数据库“焕然新生”:架构视角下,云原生数据库的创新实践 | Q推荐
从传统关系型数据库到云数据库,数据库在不断演进。与此同时,它也发挥着越来越重要的作用。从云计算、新媒体、音视频、云游戏到移动 App,几乎各行各业都离不开数据库。一方面,数据库作为 IT 基础设施的关键一环,对企业业务的发展起着支撑作用;另一方面,数字化在经济社会中不断深入,数据成为核心要素,围绕数据的生产、存储和消费均依赖数据库。
深度学习与Python
2022/11/28
7920
数据库“焕然新生”:架构视角下,云原生数据库的创新实践 | Q推荐
云原生数据库TDSQL-C PostgreSQL版内核解密
导语 TDSQL-C 原(CynosDB)是腾讯云数据库团队自研的新一代云原生数据库,融合了传统数据库、云计算与新硬件技术的优势,采用计算和存储分离的架构,100%兼容 PostgreSQL,提供具备极致弹性、高性能、海量存储、安全可靠的数据库服务。 本文旨在从数据库内核的角度揭秘TDSQL-C PostgreSQL的核心架构与关键技术。本文适合读者:腾讯云售后服务、TDSQL-C用户、TDSQL-C开发者,需要有基本的数据库与存储知识。 TDSQL-C 概述 TDSQL-C采用计算和存储分离的架构
腾讯云数据库 TencentDB
2021/09/26
2K0
数据库的下一场革命:S3 延迟已降至原先的 10%,云数据库架构该进化了
众所周知,在数据库的历史上,每次存储介质的变化都会引发软件的变革。从 SAN 存储到 SSD 到大内存到 NVM,都触发了数据库内核从理论到工程的演进。
深度学习与Python
2023/12/28
3420
数据库的下一场革命:S3 延迟已降至原先的 10%,云数据库架构该进化了
数据库漫谈(九)----云数据库
本文作者系Scott(中文名陈晓辉),现任大连华信资深分析师 ,ORACLE数据库专家,曾就职于甲骨文中国。个人主页:segmentfault.com/u/db_perf ,经其本人授权发布。
SQLplusDB
2022/08/19
1.3K0
数据库漫谈(九)----云数据库
MYSQL 开始学习POLARDB for MYSQL (1)
不做铺垫,因为公司在进行数据库转型,ORACLE to MYSQL 基于云上的MYSQL 在使用中主要分为两派 1 传统型的RDS ,也就是与我们自己安装的数据库有差别,但差别不大, 2 根据云上的硬件环境,最大最充分的修改数据库的内部结构,让数据库更能使用到我们的硬件环境,去适配他。
AustinDatabases
2022/04/05
9070
MYSQL  开始学习POLARDB for MYSQL (1)
数据库如果多上云,DBA 还有什么发展
随着问问题的同学越来越多,公众号内部私信回答问题已经很困难了,所以建立了一个群,关于各种数据库的问题都可以,目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS 等,期待你的加入,加群请添加微信liuaustin3.
AustinDatabases
2023/02/28
4250
数据库如果多上云,DBA 还有什么发展
美国知名大学开授China数据库理论,你没看错!
Austindatabases公众号已经开启了,AI 文章分析,AI 文章问答,比如你想知道AustinDatabases 里面,说了多少种数据库,那些是讲 MySQL,那些是PostgreSQL, 那些是OB ,POLARDB ,MongoDB ,SQL Server, 阿里云的,问他他会列出来,同时如果有问题不明白,可以将文章的文字粘贴到公众号提供的专用AI ,公众号将通过众多文章(目前1300多篇)来进行尝试性的解释。使用方法,直接到微信公众号中点击服务,选择AI问答。如下示例
AustinDatabases
2025/04/09
490
美国知名大学开授China数据库理论,你没看错!
相比原生,腾讯云数据库MySQL 8.0带来了哪些新的极致体验?
官方MySQL 8.0 是非常大的版本,以前的版本号是 5.6、5.7,现在一下飞跃到 8.0,对于 Oracle MySQL官方来说也是非常大的版本,有很多的更新。
腾讯云开发者
2020/08/20
5.6K2
Amazon Aurora:云时代的数据库 ( 上)
导语:文章是 Amazon 在SIGMOD'17 上最新发表的关于 Aurora论文的翻译版本,详尽的介绍了 Aurora 设计背后的驱动和思考,以及如何在云上实现一个同时满足高并发、高吞吐量、高稳定
谭伟华)
2017/08/02
5.9K0
Amazon Aurora:云时代的数据库 ( 上)
TDSQL-C PostgreSQL(CynosDB) 内核解密-披荆斩棘,勇往直前的腾讯云数据库
TDSQL-C采用计算和存储分离的架构,所有计算节点共享一份数据,存储容量高达128TB,单库最高可扩展至16节点,提供秒级的配置升降级、秒级的故障恢复和数据备份容灾服务。TDSQL-C既融合了商业数据库稳定可靠、高性能、可扩展的特征,又具有开源云数据库简单开放、自我迭代的优势。TDSQL-C不仅在性能、扩展性和高可用方面有大幅提升,计算存储的解耦使得计算层和存储层都获得了很大的独立优化空间,本文下面将介绍TDSQL-C架构的实现,以及在新架构上的关键技术优势。
腾讯云数据库 TencentDB
2021/09/17
1K0
云原生数据库设计新思路
在讲新的思路之前,先为过去没有关注过数据库技术的朋友们做一个简单的历史回顾,接下来会谈谈未来的数据库领域,在云原生数据库设计方面的新趋势和前沿思考。首先来看看一些主流数据库的设计模式。
PingCAP
2021/01/14
1.7K0
分布式数据库创新技术奖,TDSQL他来了!
日前,Distributed Cloud|2021全球分布式云大会·上海站隆重召开。腾讯云凭借其信息技术系统的安全可控性和前沿技术的创新性,在一众企业中脱颖而出,荣获“分布式数据库创新技术奖”。这是继腾讯云数据库TDSQL获第四届中国保险大数据分析与人工智能创新国际峰会年度“保险创新者大奖”之后再次获评。 在云原生专题论坛上,腾讯云数据库产品专家梁文灿先生就腾讯云企业级分布式数据库TDSQL生态发展战略、落地应用案例做出了详细介绍。同时腾讯云数据库专家工程师张远先生对云原生数据库TDSQL-C的内核关键技
腾讯云数据库 TencentDB
2021/09/22
1.3K0
开发者关注的数据库技术与创新
说到这个问题的话,那么从PolarDB入手来说,作为开发者关注的数据库技术与创新基本就在里面了。 PolarDB MySQL版是阿里巴巴自研的云原生HTAP数据库。PolarDB MySQL版100%兼容原生MySQL的多个版本,包括MySQL 5.6、MySQL 5.7和MySQL 8.0。PolarDB MySQL版的企业版基于云原生架构、计算存储分离、软硬件一体化设计,为用户提供具备超高弹性和性能、高可用和高可靠保障、高性价比的数据库服务。可以说关于数据库技术和创新,云原生数据库PolarDB 体现的很全面了,下面看一下云原生数据库PolarDB的产品架构图
六月的雨在Tencent
2024/04/08
1620
开发者关注的数据库技术与创新
(文中有惊喜)走进云时代的数据库
最近几年,随着云计算相关技术的发展,各种不同类型的云层出不穷,服务越来越多不同类型的企业业务,传统企业也渐渐开始探索上云的道路。在云上,作为业务最核心的数据库,相比之前的传统方案会有哪些变化呢?
数据和云
2018/12/07
1.1K0
在阿里达摩院搞了四年数据库,我来聊聊实际情况 | 卓越技术团队访谈录
嘉宾 | 汪晟、谭剑、谢炯 编辑 | 钰莹 2017 年的云栖大会,阿里巴巴达摩院宣布成立。 5 大研究方向,16 个实验室,数据库与存储实验室便是达摩院下设实验室之一。 成立伊始,达摩院定位发力硬核基础科技。 前沿数据库技术,就是发力方向之一。 五年时间,社交媒体上每隔一段时间就有人出来问“阿里达摩院搞出来什么成果了?”,“阿里达摩院的技术水平是什么样的?”,“达摩院里面的人平常的 KPI 是什么?”,“什么样的人可以进阿里达摩院?”...... InfoQ 日前对达摩院数据库与存储实验室的三个核心
深度学习与Python
2023/03/29
8650
在阿里达摩院搞了四年数据库,我来聊聊实际情况 | 卓越技术团队访谈录
腾讯云数据库CDB技术演进之路
作者简介:程彬,腾讯基础架构部数据库研发负责人。2008年毕业加入腾讯,一直从事数据存储相关研发工作;在云计算浪潮涌来之时参与到腾讯云存储产品的打造。目前在腾讯TEG基础架构部,负责数据库(CDB)和云硬盘(CBS)研发相关工作。
腾讯 架构师
2021/07/15
2.2K0
腾讯云数据库CDB技术演进之路
MySQL痿了,放不下这么多数据!
MySQL在达到一定数据量(我的经验是3T、单表1亿)时,复杂查询会有明显的延迟。继续分库分表,会严重增加业务复杂性,尤其对很多非互联网产品来说,急需一个分布式存储。
xjjdog
2019/07/10
1.2K0
MySQL痿了,放不下这么多数据!
推荐阅读
相关推荐
读PolarDB论文有感 : 异构计算和数据库软硬一体化设计
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档