OpenGL学习笔记7——贴图练习

本文详细介绍了使用OpenGL进行贴图的几种实用技巧,包括改变笑脸方向、在物体表面多个位置放置相同贴图、使用GL_NEAREST纹理过滤方式以及通过代码动态调整纹理混合度,适合初学者和进阶用户学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


做一下 LearnOpenGL后面的练习

1 让笑脸改方向

题目:修改片段着色器,仅让笑脸图案朝另一个方向看,参考解答

就是只让笑脸的UV的横坐标反转。

#version 330 core
uniform sampler2D texture1;
uniform sampler2D texture2;
in vec3 Color;
in vec2 TexCoord;

out vec4 FragColor;

void main(){
        vec2 reverseXTexCoord = TexCoord;
        reverseXTexCoord.x *= -1;
        FragColor = mix(texture(texture1,TexCoord),texture(texture2,reverseXTexCoord), 0.2);
}

这个还是挺简单的。
在这里插入图片描述

2 在箱子的角落放置4个笑脸

题目:尝试用不同的纹理环绕方式,设定一个从0.0f到2.0f范围内的(而不是原来的0.0f到1.0f)纹理坐标。试试看能不能在箱子的角落放置4个笑脸:参考解答结果。记得一定要试试其它的环绕方式。

这个也挺简单的。首先环绕方式显然是采用重复的方式,可以想下面这样设置。不过它默认的环绕方式就是重复,其实也可以不用设置。

	// 水平和垂直两个方向可以采用不同的环绕方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // 设置水平方向的环绕方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // 设置垂直方向的环绕方式

看了文档发现,除了GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T之外,还有一个GL_TEXTURE_WRAP_R。应该是第三个方向,也许是三维纹理的范畴,这里我就不太清楚了。

然后就是把uv改成0.0到2.0,但是如果直接改了顶点的数据,箱子的uv也会改。所以我打算还是到Shader里面单独改箱子贴图的uv。

#version 330 core
uniform sampler2D texture1;
uniform sampler2D texture2;
in vec3 Color;
in vec2 TexCoord;

out vec4 FragColor;

void main(){
        vec2 reverseXTexCoord = TexCoord;
        reverseXTexCoord *= 2;
        FragColor = mix(texture(texture1,TexCoord),texture(texture2,reverseXTexCoord), 0.2);
}

在这里插入图片描述
然后再看下题目给的结果,发现我和题目想的不一样,不过算了,也差不多。

3 尝试使用GL_NEAREST

题目:尝试在矩形上只显示纹理图像的中间一部分,修改纹理坐标,达到能看见单个的像素的效果。尝试使用GL_NEAREST的纹理过滤方式让像素显示得更清晰:参考解答

更简单啦,先把uv改得很小(0.1),实现放大的效果。

	// 三角形的顶点数据
	float vertices[] = {
	//     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
		 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   0.1f, 0.1f,   // 右上
		 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   0.1f, 0.0f,   // 右下
		-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
		-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 0.1f    // 左上
	};

然后设置环绕模式为邻近的。

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // 其实现在是放大,设置这一个就行了

GL_NEAREST:
在这里插入图片描述GL_LINEAR:在这里插入图片描述

4 动态改变混合度

使用一个uniform变量作为mix函数的第三个参数来改变两个纹理可见度,使用上和下键来改变箱子或笑脸的可见度:参考解答

需要用上些交互了。也不难,首先修改fragmentShader。添加unifrom。

#version 330 core
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform float mixValue;
uniform float uvScale; // 顺便加一个uv缩放

in vec3 Color;
in vec2 TexCoord;

out vec4 FragColor;

void main(){
        FragColor = mix(texture(texture1,TexCoord),texture(texture2,TexCoord * uvScale), mixValue);
}

在main.cpp中添加两个全局变量。

float mixValue = 0;
float uvScale = 1;

在渲染循环中

		myShader.setFloat("mixValue", mixValue);
		myShader.setFloat("uvScale", uvScale);

然后处理输入实现用键盘改变mixValue和uvScale的值。顺带限制一下mixValue在0-1中间。

// 处理输入
void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)// 判断是否按下Esc
		glfwSetWindowShouldClose(window, true);// 将窗口设置为需要关闭

	if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
		mixValue += 0.002;
		if (mixValue > 1)
			mixValue = 1;
	}
	if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
		mixValue -= 0.002;
		if (mixValue < 0)
			mixValue = 0;
	}
	if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
		uvScale -= 0.01;
	}
	if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
		uvScale += 0.01;
	}
}

然后就好了。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值