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

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

基本方法

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

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

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

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

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

1
2
3
4
5
typedef struct {
float Position[2];
float Color[4];
float TexCoord[2];
} Vertex;

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

1
2
3
4
5
6
7
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;

然后是生成纹理:

1

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

 

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

修改Shader

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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的代码:

1
2
3
4
5
6
7
8
9
10
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);

运行结果

texturing

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

让立方体不再裸奔

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#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}}
};

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

3dtexturing

结语

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

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

Reference

(转载)Cocos2dx-OpenGL ES2.0教程:纹理贴图(6)的更多相关文章

  1. Cocos2d-x中使用OpenGL ES2.0编写shader

    这几天在看子龙山人的关于OpenGL的文章,先依葫芦画瓢,能看到些东西,才能慢慢深入了解,当入门文章不错,但是其中遇到的一些问题,折腾了一些时间,为了方便和我一样的小白们,在这篇文章中进行写补充. O ...

  2. OpenGL ES2.0 入门经典例子

    原文链接地址:http://www.raywenderlich.com/3664/opengl-es-2-0-for-iphone-tutorial 免责申明(必读!):本博客提供的所有教程的翻译原稿 ...

  3. OPENGL ES2.0如何不使用glActiveTexture而显示多个图片

    https://www.oschina.net/question/253717_72107 用opengl es 2.0显示多个图片的话,我只会一种方式,先将图片生成纹理,然后用下面的方式渲染 // ...

  4. iOS开发——图形编程OC篇&OpenGL ES2.0编程步骤

    OpenGL ES2.0编程步骤 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设 ...

  5. Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤

    原文地址: Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤 - 网络资源是无限的 - 博客频道 - CSDN.NET http://blog.csdn.net/fen ...

  6. OpenGL ES2.0入门详解

    引自:http://blog.csdn.net/wangyuchun_799/article/details/7736928  1.决定你要支持的OpenGL ES的版本.目前,OpenGL ES包含 ...

  7. Android +NDK+eclipse+opengl ES2.0 开启深度測试

    參考:https://www.opengl.org/discussion_boards/showthread.php/172736-OpenGL-ES-Depth-Buffer-Problem 环境: ...

  8. OpenGL ES2.0 基本编程

    1. EGL OpenGL ES命令须要一个rendering context和一个drawing surface. Rendering Context: 保存当前的OpenGL ES状态. Draw ...

  9. 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)

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

随机推荐

  1. rpmdb: BDB0113 错误

    解决方法: rpm --rebuilddb yum clean all

  2. 【概率】Uva 10900 - So you want to be a 2n-aire?

    写完这题赶紧开新题... 话说这题让我重新翻了概率论课本,果然突击完了接着还给老师了,毫无卵用. 很多人拿这位大神的题解作引,在这我也分享给大家~ 对于其中的公式在这里做一点简要的说明.因为自己也是理 ...

  3. 20个2014年最优秀的PHP框架

    http://www.php100.com/html/it/mobile/2014/0813/7198.htmlhttp://medoo.in/api/select 

  4. 解决c#,wpf程序带环境安装包体积太大问题

    在.net开发客户端的时候,一定会遇到用户没有安装.net环境的问题,特别是现在win7,win8,win10多系统并用的时间段,很多开发者使用的是4.5的目标环境,用户却是使用win7的系统,这样势 ...

  5. 微信小程序(原名微信应用号)开发工具0.9版安装教程

    微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...

  6. 【AngularJs】---$sce 输出Html

    [问题描述] angular js的强大之处之一就是他的数据双向绑定功能----->ng-bind和针对form的ng-model 但在我们的项目当中会遇到这样的情况,后台返回的数据中带有各种各 ...

  7. jquery之css()改变字体大小,颜色,背景色

    转: <script type="text/javascript"> $(document).ready(function() {         $("#f ...

  8. HDOJ2024C语言合法标识符

    C语言合法标识符 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  9. jFinal中报对应模型不存在的错误(The Table mapping of model: demo.User not exists)

    jFinal中报对应模型不存在的错误(The Table mapping of model: demo.User not exists) 贴出错误: java.lang.RuntimeExceptio ...

  10. jquery学习全面总结

    本文仅针对jquery的部分知识点做总结,更为全面的可以去官网看中文文档.可以更为详细的了解jquery及其特性. window.onload 和$(document).ready() 我 windo ...