GLSL核心课程---纹理图像
来源:互联网 发布:今年最流行的网络语 编辑:程序博客网 时间:2024/05/17 02:03
大多数时候我们会将一幅纹理图像应用到模型上,或多或少就像壁纸一样。有时候纹理还可以看成是数据,不是颜色值。纹理坐标提供了在图像和模型之间的映射关系。在我们着色器中处理使用纹理之前我们需要在我们的OpenGL应用程序中做一些设置步骤。在这一节中,我们将覆盖一下经典纹理用法案例。
OpenGL
在我们着色器中使用纹理的第一步就是需要创建一个OpenGL纹理对象。一个通用的用法就是我们同样需要从文件中加载图像数据来添加到纹理中,如果你不确定如何做这一步,那么请看这一页的介绍。
在着色器中需要设置一个一致变量来储存纹理单元。注意,着色器接收的是纹理单元而不是纹理名字。OpenGL提供了多个单元,因此我们在一个着色器中使用多个纹理。纹理单元有效数据是GL_MAX_COMBIEND_TEXTURE_IMAGE_UNITS。
让我们假定在着色器中定义一个叫做texUnit的一致变量。同样假定我们仅仅只有一个纹理,因此我们将绑定到纹理单元0.
在OpenGL应用程序这一端,在设置的步骤,我们需要得到一致变量texUnit的位置。到目前为止OpenGL是将texUnit定义成整型变量。因此,假定变量p存储GLSL程序的名字,下面的代码得到位置:
GLint texUnitLoc = glGetUniformLocation(p, “texUnit”);
如果提供给着色器的纹理单元总是跟我们在应用程序设置的一样。房子我们不得不经常修改纹理单元。为了设置变量texUnit为纹理单元0我们需要这么写:
glProgramUniformli(p, texUnitLoc, 0);
绘制实现绑定纹理到纹理单元。因此,如果我们假定texture1D是纹理单元(由glGenTextures创建)和纹理是2D,我们可以这么写:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1D);
后面我们将绑定到VAOs和调用glDraw*命令。
GLSL
现在,让我们回到GLSL这一端。首先必须定义一个变量texUnit。这个变量定义成sampler*类型。Samplers是一个不透明类型,比如说,它们不能像常规变量那样处理,它们的用法在函数中有限制,必须适当使用。采样器处理的纹理是在OpenGL应用程序端定义的,输入函数可以从纹理数据中返回值。每个纹理类型都有一个合适的采样类型,实际上,就像一个纹理模板GL_TEXTURE_2D,那么采样类型会sampler2D。
为了处理纹理我们需要两个元素:纹理单元,和纹理坐标。在这里有很多函数来处理纹理数据。其中的很多都是用来查询,其他一些提供纹理数据,让我们从一些查询开始。
一个通用的着色器可以处理纹理通过它们的大小。大小信息(宽度和高度)可以通过一致变量来提供给着色器。另外一个选项就是使用textureSize函数。这个函数返回的纹理在x, y, 和z分量的大小,而w是在纹理数组或者立方体纹理的索引。这个函数同样可以使用mipmap级数,在这种情况下上面所有的信息就是相对于查询mipmap级数信息。
纹理mipmap级数大小可以有textureQueryLevels来查询。这个函数可以返回在纹理中(从OpenGL4.3有效)有效的mipmap计算数目。
Mipmap级数,或者结合mipmap等级,可以在特定片段使用textureQueryLod获取。这个函数返回一个vec2其中的x分量表示将会被使用的等级和相应的比例。实际上x=3.25然后等级3将会贡献75%和等级4是25%。
我们可以这个动作,参考下面的代码:
#version 420
uniform sampler2D texUnit;
out vec4 outputF;
void main()
{
vec2 res = textureQueryLod(texUnit, VertexIn.texCoord.xy);
if(res.x == 0)
outputF = vec4(1.0, 0.0, 0.0, 0.0);
else if(res.x < 1)
outputF = vec4(0.0, 1.0, 0.0, 0.0);
else if(res.x < 2)
outputF = vec4(0.0, 0.0, 1.0, 0.0);
else if(res.x < 3)
outputF = vec4(0.0, 1.0, 1.0, 0.0);
else if(res.x < 4)
outputF = vec4(1.0, 0.0, 1.0, 0.0);
else if(res.x < 5)
outputF = vec4(1.0, 1.0, 0.0, 0.0);
else if(res.x < 6)
outputF = vec4(0.5, 1.0, 0.0, 0.0);
else if(res.x < 7)
outputF = vec4(0.0, 1.0, 0.5, 0.0);
}
结果就像下面的图示一样:
- GLSL核心课程---纹理图像
- GLSL核心课程---纹理图像
- GLSL核心课程---纹理坐标
- GLSL核心课程---聚光灯
- GLSL 纹理贴图
- GLSL 纹理贴图
- OpenGL GLSL访问纹理
- GLSL 纹理贴图
- opengl编程glsl-纹理
- 图像纹理
- GLSL实现图像处理
- GLSL实现图像处理
- GLSL实现图像处理
- GLSL实现图像处理
- GLSL 图像处理
- GLSL入门2 关于GLSL中的纹理贴图
- GLSL的多纹理输入和输出
- GLSL 整型纹理 个人遇到的问题
- 链表空指针建立(个人想法)
- x64安装oracle 10.2.0.4无法启动em dbconsole问题解决
- PythonChallenge 挑战之路 Level-24
- js事件的一些例子探讨
- 第一次写博客
- GLSL核心课程---纹理图像
- nyoj-429-骨牌铺方格//hdu-2046-骨牌铺方格
- Java 中 Vector、ArrayList、List 使用深入剖析(转)
- java 执行bat文件 并输出信息
- 谁说Vim不是IDE?(三)
- 看人家小学生的素数的快速判断
- liux下用不了ifconfig
- HDU 1009 贪心
- centOS配置samba详细步骤及一些错误解决方案