OpenGL排坑指南—贴图纹理绑定和使用

这篇具有很好参考价值的文章主要介绍了OpenGL排坑指南—贴图纹理绑定和使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

        在OpenGL学习 的纹理这一章中讲述了纹理贴图的使用方式,主要步骤是先创建一个纹理的对象,和创建顶点VAO类似,然后就开始绑定这个纹理,最后在循环中使用,有时候可能还要用到激活纹理单元的函数。然而,对于何时应该激活如何和shader里的纹理编号进行绑定没有详细的说明,导致在使用的时候产生了不少困惑。比如何时应该绑定,绑定后的索引如何匹配。

        在这一章的第一个效果案例:显示一个带贴图纹理的箱子时只用到了绑定而没有用到激活,部分主要代码如下:即使这样,在shader中也能让贴图获取到这里写进去的数据。

   while (!glfwWindowShouldClose(window))
    {
        -----
        glBindVertexArray(VAO);
        -----
    }

其shader的片段着色器代码如下,这个片段的“texture1”数据在上述循环中并未明确指定传过来的

// texture sampler
uniform sampler2D texture1;

void main()
{
	FragColor = texture(texture1, TexCoord);
}

这是我第一个猜想:如果C++代码中只创建了一个纹理数据,不用激活和指定传输到片段着色器中,使用“ glBindTexture(GL_TEXTURE_2D, texture);”函数可以默认将片段着色器中的贴图都填充同样的数据。带着这个猜想我开始验证我的想法。

二、实现

2.1、如果只有一个贴图数据,默认传输到片段着色器的每一个“uniform sampler2D”

        其他都不变,我只修改片段着色器代码,首先我创建了两个uniform sampler2D变量,分别为texture1和texture2,然后稍微修改其片段着色器代码如下:如果这两个片段都获取到同样的数据则显示两倍的贴图效果,如果不相等则屏幕显示一个绿色的片。

// texture sampler
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{

	vec4 tempColor1=texture(texture1, TexCoord);
	vec4 tempColor2=texture(texture2,TexCoord);
	if(tempColor1==tempColor2)
	{
		FragColor =tempColor1+tempColor2;
	}
	else
		FragColor=vec4(0,1,0,1);
}

试验的结果得到如下,明显比之前要亮一点,很显然两个贴图都获取到循环里传输过来的贴图数据,而且是一样的。

OpenGL排坑指南—贴图纹理绑定和使用,OpenGL,贴图,OpenGL,Shader
图2.1.1
2.2、如果C++代码只有一个贴图,但我就想传给片段着色器中指定的纹理

1)只激活第一个并不管用:这个时候我尝试使用激活,我只激活第一个试试,结果和图2.1.1是一样的,两个纹理还是被传输一样的纹理数据。

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture);

2)两个都激活,但只赋值给第二个贴图,结果两个都没有得到数据:再尝试不同的激活方式,保持只传输一个纹理数据的逻辑,将第一个激活然后不赋值,激活第二个并且赋值贴图纹理,理论上这样应该是可以的啊,结果变成了黑的,如图2.2.1所示

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture);
OpenGL排坑指南—贴图纹理绑定和使用,OpenGL,贴图,OpenGL,Shader
图2.2.1

是不是两个贴图都没有获取到数据呢,我还不确定,再修改片段着色器判断一下:如果确实没有获取到数据则让屏幕显示“黄色”的箱子,结果如图2.2.2所示,确实显示了黄色的箱子,这说明我们

uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{

	vec4 tempColor1=texture(texture1, TexCoord);
	vec4 tempColor2=texture(texture2,TexCoord);
	if(tempColor1==tempColor2)
	{
		if(tempColor1==vec4(0,0,0,1))
		{
			FragColor=vec4(1,1,0,1);
		}
		else
			FragColor =tempColor1+tempColor2;
	}
	else
		FragColor=vec4(0,1,0,1);
}
OpenGL排坑指南—贴图纹理绑定和使用,OpenGL,贴图,OpenGL,Shader
图2.2.2

贴图数据始终还是以默认的方式进行传输,第二个激活并传输并没有奏效,始终还是第一个激活才奏效。

3)再增加一个贴图的索引,结果可以精准的将数据传输到第二个贴图:代码如下,在激活之前给

		ourShader.setInt("texture2", 1);
		// bind Texture
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture);

当前的shader指定一个索引1,并且这个索引数值“1”一定要和后续绑定的“GL_TEXTURE1”对应,最后得到的结果是绿色的一个箱子,说明在片段着色器中贴图的数据不一样了。

三、总结

3.1、如果只有一个贴图数据,在C++中只用默认的绑定操作,默认传输到片段着色器的每一个“uniform sampler2D”变量中。

3.2、如果要指定传输给片段着色器中一定要使用激活贴图 glActiveTexture(GL_TEXTURE1);和        设置索引号ourShader.setInt("texture2", 1);同时使用,并且激活的序列号和设置索引值要相等,只使用索引也不行。

3.3、激活和设置索引以及绑定都要在循环里每帧都使用,尝试将索引设置不放在循环里也不行。

3.4、激活和绑定都是默认的情况下,设置索引没有任何作用,可以不用。比如在文章后续做一个2D游戏中的一篇文章里渲染精灵 其最后的游戏类代码中初始化时设置了纹理"image"的数据索引为0,但是其着色器代码中并没有”image“这个变量,而且此处

void Game::Init()
{
   ......
    ResourceManager::GetShader("sprite").Use().SetInteger("image", 0);
    .......
}

无论你修改”image"为任何变量,比如“imageeeeeeeeeeeeeeee",它依然能显示正确的结果,因为这一篇文章中就是一个默认的贴图,而且激活和绑定都是执行默认的0,这里的索引就不会发生任何作用。文章来源地址https://www.toymoban.com/news/detail-790174.html

到了这里,关于OpenGL排坑指南—贴图纹理绑定和使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Three.js纹理贴图

    目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 纹理是一种图像或图像数据,用于为物体的材质提供颜色、纹理、法线、位移等信息,从而实现更加逼真的渲染结果。 纹理可以应用于 Three.js 中的材质类型,如 MeshBasicMaterial 、 MeshLambertMaterial 、 MeshPhongMaterial 、 MeshSt

    2024年02月13日
    浏览(48)
  • 纹理贴图和渲染

    纹理映射(也就是纹理图或者叫做纹理贴图)是一种在计算机图形学中常用的技术,它可以将二维的图像(纹理)映射到三维物体的表面上,以增强视觉效果。“atlas”通常是指纹理图集,也就是将多个纹理图放在一张大图上,以便更高效地使用图形硬件。 而“rendering resol

    2024年02月14日
    浏览(46)
  • 一文看懂-纹理/贴图/材质

    纹理(Texture) 应用于网格表面上的标准位图图像,即3D 对象的 2D 贴图。 贴图(Map) 指的是绘制在对象模型表面上的那些图像数据,其所使用的图像文件称为纹理。贴图还包含纹理图在对象表面的坐标(UV坐标)等其他数据信息。 可以说, 纹理是贴图的子集 。 另外。Map也

    2024年02月08日
    浏览(53)
  • Three.js加载简单纹理贴图并应用到网格(凹凸贴图、法向贴图、移位贴图)

    纹理最基础的用法就是作为贴图被添加到材质上,当用这种方法创建网格时,网格的颜色就来源于纹理 UV贴图实质上就是指定模型上的哪一部分需要被映射到纹理的相应位置 可以用如下方法加载纹理 使用THREE.TextureLoader()从指定位置加载图片,图片格式可以是png,jpg或jpeg 纹理

    2024年02月05日
    浏览(64)
  • 7.PBR材质与纹理贴图

    友情链接:threejs 中文文档 目录 1. PBR材质简介 光照模型 网格模型材质整体回顾 2. PBR材质金属度和粗糙度 金属度metalness 粗糙度roughness  3. 环境贴图.enMap 环境贴图反射率.envMapIntensity 场景环境属性.environment 4. MeshPhysicalMaterial清漆层 清漆层属性.clearcoat 清漆层粗糙度.clearcoatRo

    2024年02月12日
    浏览(36)
  • 第二十四章 Unity 纹理贴图

    通常情况下,3D网格模型只能展示游戏对象的几何形状,而表面的细节则纹理贴图提供。纹理贴图通过UV坐标“贴附”在模型的表面。当然,这个过程不需要我们在Unity中完成,而是在建模软件中完成的。通常情况下,我们通过3ds max或者maya制作完网格模型后,需要进行一个“

    2024年02月05日
    浏览(44)
  • OpenGLES:3D立方体纹理贴图

    前几篇博文讲解了OpenGLES绘制多种3D图形,并赋予丰富的色彩,但是在这些3D图形绘制过程中,有一点还没有涉及,就是 纹理贴图。 今天这篇博文我会用如下 六张图片 对立方体进行纹理贴图,实现 六个面都是贴图 的3D旋转立方体 2.1 常规变量定义 2.2 顶点、纹理相关变量定义

    2024年02月08日
    浏览(43)
  • GLTF纹理贴图工具让模型更逼真

    要使三维模型看起来更加逼真,可以考虑以下几个方面: 高质量纹理:使用高分辨率的纹理贴图可以增强模型的细节和真实感。选择适合模型的高质量纹理图像,并确保纹理映射到模型上的UV坐标正确无误。 法线贴图和凹凸贴图:通过使用法线贴图或凹凸贴图,可以为模型添

    2024年02月07日
    浏览(61)
  • three.js实现雷达扫描效果(纹理贴图)

    three.js实现雷达扫描效果(纹理贴图) 图例 步骤 创建两个平面,分别纹理贴图,底图模型.add(光波模型) 关闭材质的深度测试 光波旋转 代码 图片(透明的)

    2024年02月01日
    浏览(45)
  • Three.js之顶点UV坐标、纹理贴图

    创建纹理贴图 … UV动画 注:基于Three.js v0.155.0 纹理贴图加载器:TextureLoader 纹理对象:Texture 颜色贴图属性.map 顶点UV坐标 圆形平面设置纹理贴图:CircleGeometry 设置阵列模式:THREE.RepeatWrapping 网格地面辅助观察:GridHelper 纹理对象.offset属性

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包