文档章节

Cocos2dx-OpenGL ES2.0教程:纹理贴图(6)

乐逍遥jun
 乐逍遥jun
发布于 2016/02/22 21:38
字数 1057
阅读 33
收藏 0

上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object)、IBO(Index Buffer Object)和MVP(Modile-View-Projection)变换。

本文将在教程4的基础之上,添加纹理贴图支持。最后,本文会把纹理贴图扩展至3D立方体上面。

基本方法

当我们把一张图片加载到内存里面之后,它是不能直接被GPU绘制出来的,纹理贴图过程如下:

首先,我们为之前的顶点添加纹理坐标属性并传到vertex shader里面去,然后把内存里面的纹理传给GPU,最后,在fragment shader里面通过采样器,就可以根据vertex shader传递过来的纹理坐标把纹理上面的颜色值用插值的方式映射到每一个像素上去。

接下来,让我们看看具体怎么做。

准备纹理坐标(纹理坐标也叫UV坐标)

首先,我们需要修改我们的顶点属性结构体,添加一个纹理坐标属性(TexCoord):

12345
typedef struct {    float Position[2];    float Color[4];    float TexCoord[2];} Vertex;

接下来,需要修改顶点数组的值,主要就是添加UV坐标:

1234567
Vertex data[] =  {      { {-1,-1},{0,1,0,1},{0,1}},      { {1,-1},{0,1,0,1},{1,1}},      { {-1,1},{0,1,0,1},{0,0}},      { {1,1},{0,1,0,1},{1,0}}  };

注意,我们的纹理坐标的(0,0)点在图片的左上角,这个与OpenGL里面的左下角是(0,0)有所区别。所以为了让我们的图片显示正常,我们在指定左下角顶点(-1,-1)的时候,它对应的纹理坐标应该是(0,1)。其它的坐标点以此类推。


GLuint TexCoordLocation = glGetAttribLocation(glProgram->getProgram(), "a_coord");    glEnableVertexAttribArray(TexCoordLocation);    glVertexAttribPointer(TexCoordLocation,                          2,                          GL_FLOAT,                          GL_FALSE,                          sizeof(Vertex),                          (GLvoid*)offsetof(Vertex,TexCoord));



生成纹理

首先,我们在头文件里面定义一个纹理的句柄:

1
GLuint textureId;

然后是生成纹理:

1textureId =  Director::getInstance()->getTextureCache()->addImage("HelloWorld.png")->getName();


接下来,我需要处理Shader了。

修改Shader

首先,修改vertex shader,添加纹理坐标属性:

1234567891011121314
attribute vec2 a_position;attribute vec4 a_color;attribute vec2 a_coord;varying vec4 v_fragmentColor;varying vec2 v_coord;void main(){    gl_Position = CC_MVPMatrix * vec4(a_position.xy,0,1);    v_fragmentColor = a_color;    v_coord = a_coord;}

因为纹理坐标最终要传递到fragment shader里面去,所以需要定义一个varing vec2 v_coord变量。

接下来是fragment shader的代码:

12345678910
varying vec4 v_fragmentColor;varying vec2 v_coord;uniform vec4 u_color;void main(){    gl_FragColor = v_fragmentColor * texture2D(CC_Texture0,v_coord);}

这边也定义了一个同样的varing变量,同时我们看到有一个texture2D函数,它可以通过CC_Texture0这个采样器和纹理坐标(v_coord)计算出对应的颜色值。

修改draw call

在调用draw call之前,我们需要绑定纹理。我们只需要在glDrawElements方法之前调用下列方法就可以了:

1
GL::bindTexture2D(textureId);

运行结果

texturingtexturing

接下来,我们需要把立方体的六个面都添加这张纹理。

让立方体不再裸奔

这个过程大部分代码都是一样的,惟一的区别就是顶点数组的修改,我们需要为每一个面的顶点都指定UV坐标:

123456789101112131415161718192021222324252627282930313233
#define TEX_COORD_MAX 1    Vertex Vertices[] = {        // Front        { {1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {-1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},        { {-1, -1, 0}, {0, 0, 0, 1}, {0, 0}},        // Back        { {1, 1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {-1, -1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {1, -1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},        { {-1, 1, -2}, {0, 0, 0, 1}, {0, 0}},        // Left        { {-1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {-1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},        { {-1, -1, -2}, {0, 0, 0, 1}, {0, 0}},        // Right        { {1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},        { {1, -1, 0}, {0, 0, 0, 1}, {0, 0}},        // Top        { {1, 1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},        { {-1, 1, 0}, {0, 0, 0, 1}, {0, 0}},        // Bottom        { {1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}},        { {1, -1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}},        { {-1, -1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}},         { {-1, -1, -2}, {0, 0, 0, 1}, {0, 0}}    };

下面是立方体的六个面贴上纹理之后的效果:

3dtexturing3dtexturing

结语

3D旋转立方体(带纹理贴图)源代码下载 master分支

单个图片的纹理贴图源码下载

Reference

本文转载自:

共有 人打赏支持
乐逍遥jun
粉丝 6
博文 79
码字总数 39510
作品 0
东城
技术主管
私信 提问
零基础使用cocos2dx-lua和skynet全栈式开发网游三(客户端配置)

客户端配置 一、扯几个概念 问题:cocos2dx引擎到底如何运作的? 在解答这个问题前,需要了解几个概念。 1.颜色 在自然界中,存在一种场,叫电磁场。电荷粒子运动状态变化时,就会释放电磁波...

量子出击
2018/06/21
0
0
cocos2dx- call to OpenGL ES API with no current context(logged once per thread)

Android APP 在红米2(Android 5.1系统)上进行全屏应用切换的时候,会出现卡屏,不会闪退并且出现频繁.在红米note和moto x1(Android 4.4系统)中偶尔出现. 其他手机上暂时还未出现全屏切换...

GLancelot
2015/08/14
1K
3
Box2d系列 – 如何在cocos2d-x中激活 debug draw(转)

本文的读者要求是, 熟悉cocos2d-x流程, 熟悉box2d的基本代码。 很久没写cocos2dx的东西了,最近比赛接近,做题太郁闷就练习下使用box2d,好歹也发时间看完了官方文档的。。 本来很想发时间...

睡到自然醒
2012/05/08
0
0
Xcode6编译Cocos2d-x3.1.1 link错误

Xcode6编译Cocos2d-x3.1.1 link错误 原来苹果公司打算自己整一套OPenGL的东西,所有,有些东西需要根据IOS平台来加入它的东西。这个问题的解决方案如下: 在工程目录下cocos/platform/CCImag...

Nov_Eleven
2015/01/19
0
2
blender导出的骨骼动画加载在webgl后变形

@李勇2 你好,想跟你请教个问题: 我看到您写的《cocos2dx blender 骨骼动画实现》里面讲到了骨骼的变换和opengl中不同。我在做的时候,也发现代码加载动画和我在blender中设置的动画不同,但...

蚊子蚊子
2014/05/25
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 —— 看来我只适合当一个千斤顶

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《我想我是伟大的》 《我想我是伟大的》- 九天 手机党少年们想听歌,请使劲儿戳(这里) 最近面试的好多呀, 面试了一个漂...

小小编辑
29分钟前
263
9
grafana安装使用及与zabbix集成

grafana简介 Grafana是一个完全开源的度量分析与可视化平台,可对来自各种各种数据源的数据进行查询、分析、可视化处理以及配置告警。 Grafana支持的数据源: 官方:Graphite,InfluxDB,Ope...

阿dai学长
今天
12
0
带你看数据挖掘与机器学习-厦大EDP上课出勤预测

带你看数据挖掘与机器学习-厦大EDP上课出勤预测 标签: 数据挖掘 特征工程 机器学习 出勤预测 write by xmhexi 2019/3/22 内容提要 首先说明本文是一篇科普文章,通过一个实际案例,帮助理解什...

xmhexi
今天
134
0
IOS  学习记录

1.StackView=>IOS 9及以上支持 2.布局方式: AutoLayout / StackView 堆布局 (线性布局) 3.屏幕适配 (资源分辨率、设计分辨率、屏幕分辨率) Size Class技术 可以针对 屏幕的方向进行设置...

萨x姆
今天
5
0
第四次工业革命:自主经济的崛起

https://36kr.com/p/5170370.html

shengjuntu
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部