glActiveTexture详解

着色器程序:vertex

 1 #version 330 core
 2
 3 in vec2 _texCoord;
 4 out vec4 color;
 5
 6 uniform sampler2D tex;
 7
 8 void main()
 9 {
10     vec2 tc = vec2(_texCoord.x, 1-_texCoord.y);
11     color = texture(tex, tc);
12     //color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
13 }

着色器程序:fregment

 1 #include "App.h"
 2 #include "EventWorkSpace.h"
 3 #include <SOIL/SOIL.h>
 4
 5 class TextureTest : public EventWorkSpace
 6 {
 7 public:
 8     GLuint vao;
 9     GLuint vbo;
10     GLuint ebo;
11     Program prog;
12     GLuint tex;
13
14     void loopInit()
15     {
16         //着色器程序编译
17         prog.addShader(Program::ShaderType::VERTEX_SHADER, "glsl/texture.vert.glsl");
18         prog.addShader(Program::ShaderType::FREGMENT_SHADER, "glsl/texture.freg.glsl");
19         prog.link();
20         //--
21
22         //定点属性设置
23         GLfloat vertices[] = {
24             // 定点位置                // 纹理坐标
25             0.5f,  0.5f, 0.0f,        1.0f, 1.0f, // 上右
26             0.5f, -0.5f, 0.0f,        1.0f, 0.0f, // 下右
27             -0.5f, -0.5f, 0.0f,        0.0f, 0.0f, // 下左
28             -0.5f,  0.5f, 0.0f,        0.0f, 1.0f  // 上左
29         };
30         GLuint indices[] = {
31             0, 1, 3, // 第一个三角形
32             1, 2, 3  // 第二个三角形
33         };
34
35         glGenVertexArrays(1, &vao);
36         glBindVertexArray(vao);
37         glGenBuffers(1, &vbo);
38         glGenBuffers(1, &ebo);
39         glBindBuffer(GL_ARRAY_BUFFER, vbo);
40         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
41
42         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
43         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
44
45         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
46         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *)(3 * sizeof(GLfloat)));
47         glEnableVertexAttribArray(0);
48         glEnableVertexAttribArray(1);
49         glBindVertexArray(0);
50         // --
51
52         // 纹理生成
53         glGenTextures(1, &tex);
54         glBindTexture(GL_TEXTURE_2D, tex);
55
56         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
57         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
58         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
59         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
60
61         int width, height;
62         unsigned char *image = SOIL_load_image("resources/smile.png", &width, &height, 0, SOIL_LOAD_RGB);
63         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
64         glGenerateMipmap(GL_TEXTURE_2D);
65         SOIL_free_image_data(image);
66         glBindTexture(GL_TEXTURE_2D, 0);
67         //--
68
69         glClearColor(0.6f, 0.6f, 0.6f, 1.0f);
70     }
71     void loopContent()
72     {
73         glClear(GL_COLOR_BUFFER_BIT);
74
75         glBindTexture(GL_TEXTURE_2D, tex);
76
77         prog.use();
78         glBindVertexArray(vao);
79
80         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
81
82         glBindVertexArray(0);
83     }
84
85
86 };
87
88 int main()
89 {
90     App::init(480, 480, "texture rectangle", false, "window.settings");
91     App::run(&TextureTest());
92     return 0;
93 }

main

效果如下:

上面是一个简单个渲染方块并贴图的程序。

OpenGL初始化相关的在loopInit()函数内, 渲染相关的在loopContent()函数内。

上例中, 并没有使用glActiveTexture, 也没有向着色器程序中uniform sampler2D tex变量写入数据,  而纹理也能正常正常显示是因为OpenGL默认使用了GL_TEXTURE0这个纹理单元。GLSL中的tex变量也默认为0。

但是当我们要显示多个纹理时, 就要用到不同的纹理单元了。

OpenGL至少保证有16个纹理单元供你使用,也就是说你可以激活从GL_TEXTURE0GL_TEXTRUE15。它们都是按顺序定义的,所以我们也可以通过GL_TEXTURE0 + 8的方式获得GL_TEXTURE8,这在当我们需要循环一些纹理单元的时候会很有用。  --learnopengl-cn.github.io

所以使用多个纹理的版本如下:

时间: 2024-10-13 17:53:56

glActiveTexture详解的相关文章

OpenGL一些函数详解(二)

OpenGL ES顶点数据绘制技巧 在OpenGL中,绘制一个长方体,需要将每个顶点的坐标放在一个数组中.保存坐标时有一些技巧(由于字母下标不好表示,因此将下标表示为单引号,如A1将在后文中表示为A' ): (1)将对立面坐标保存在相邻的位置,如坐标的保存顺序为:前面(A'ABB'),后面(D'DCC'),上面(D'A'B'C'),下面(DABC),左面(D'A'AD),右面(C'B'BC).因为对立面的坐标除了其垂直的那根轴的坐标相反以外,其他坐标值一样:如前面和后面(垂直于z轴),x和y的坐

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

HttpServletResponse和HttpServletRequest详解

HttpServletResponse,HttpServletRequest详解 1.相关的接口 HttpServletRequest HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求并且接收请求的服务器端主机名及IP地址,还可以获取客户端正在使用的通信协议等信息.下表是接口HttpServletRequest的常用方法. 说明:HttpServ

POSIX 线程详解(经典必看)

总共三部分: 第一部分:POSIX 线程详解                                   Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  2000 年 7 月 01 日 第二部分:通用线程:POSIX 线程详解,第 2部分       Daniel Robbins ([email protected]), 总裁/CEO, Gentoo Technologies, Inc.  20

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

netstat状态详解

一.生产服务器netstat tcp连接状态................................................................................ 2 1.1生产服务器某个业务LVS负载均衡上连接状态数量............................................... 2 1.2生产服务器某个业务web上连接状态数量...............................................

详解go语言的array和slice 【二】

上一篇  详解go语言的array和slice [一]已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制slice的容量,在操作新slice时,如果新slice的容量大于长度时,添加新元素依然后使源的相应元素改变.这一篇里我会讲解到如何避免这些问题,以及迭代.和做为方法参数方面的知识点. slice的长度和容量设置为同一个值 如果在创建新的slice时我们把