OpenGL南邮计算机图形学实验报告二——两个纹理的渐变变换和移动

OpenGL南邮计算机图形学实验报告二——两个纹理的渐变变换和移动

计算机图形学的题目要求

OpenGL配置参考:
南邮老前辈wonz哥的OpenGL配置(Shader.h始终不用改)、SOIL2 环境配置

学习网站:LearnOpenGL CN

思路:

1.wonz哥的参考
wonz哥选择的方法是使用一个纹理单元glActiveTexture(GL_TEXTURE0);而随时间绑定不同的纹理,无法做到渐进。
2.但是这次的要求是渐进变化/渐变,通过查阅LearnOpenGL CN可以知道有一个mix()函数是用来改变纹理透明度的,那么就可以通过改变mix()函数的融合因子(第三个参数),使他随时间time参数而来回变化即可实现渐变。
3.移动的实现:由于纹理环绕方式glTexParameteri()GL_REPEAT 对纹理的默认行为为重复纹理图像。如果我们要实现一直向右移动,只要一直加x坐标即可,而左边则会用相同的纹理填充。

注:有个好笑的事情是,复制文件名到下面的时候多打了一个空格,导致第二张图片一直显示不出来,害的我检查了好几遍,最后还是朋友看出来的。太逆天了。 所以图片无法显示绝对是文件路径的问题!

效果:
在这里插入图片描述
在这里插入图片描述

话不多说上代码:
main.cpp

#include<iostream>

//实现两个纹理直接的变化
//GLEW
#define GLEW_STATIC
#include<GL/glew.h>

//GLFW
#include<GLFW/glfw3.h>
#include"shader.h"

#include "SOIL2/SOIL2.h"
#include "SOIL2/stb_image.h"


const GLint WIDTH = 800, HEIGTH = 600;

int i = 1;
void parameter();

int main()
{
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGTH, "Learn OpenGL", nullptr, nullptr);
	if (nullptr == window)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	//next two lines are for mac retina display
	int screenWidth, screenHeight;
	glfwGetFramebufferSize(window, &screenWidth, &screenHeight);


	glfwMakeContextCurrent(window);

	glewExperimental = GL_TRUE;

	if (GLEW_OK != glewInit())
	{
		std::cout << "Failed to initialise GLEW" << std::endl;
		return -1;
	}
	glViewport(0, 0, screenWidth, screenHeight);

	Shader ourShader = Shader("res/shaders/core.vs", "res/shaders/core.fs");
	
	GLfloat vertices[] =
	{
		// position					//color				//txture coords

		0.5f, 0.5f, 0.0f,			1.0f, 1.0f,0.0f,		1.0f,1.0f,//top right				0
		0.5f, -0.5f, 0.0f,			1.0f, 0.0f,0.0f,		1.0f,0.0f,//bottom right		1
		-0.5f, -0.5f, 0.0f,		0.0f, 0.0f,0.0f,		0.0f,0.0f,//bottom left			2
		-0.5f, 0.5f, 0.0f,			0.0f, 1.0f,0.0f,		0.0f,1.0f,//top left				3
	};
	
	unsigned int indices[] =
	{
		0,1,3,//画第0,1,3个点
		1,2,3
	};
	
	// the data should transfer to the memory on Graphic Card
	GLuint VAO, VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glBindVertexArray(VAO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
	glEnableVertexAttribArray(2);

	GLuint EBO;
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

	//Texture
	GLuint texture1,texture2;
	int width, height;
	
	//绑定第一个纹理
	glGenTextures(1,&texture1);
	glBindTexture(GL_TEXTURE_2D, texture1);
	parameter();
	unsigned char* image1 = SOIL_load_image("res/images/image1.BMP", &width, &height, 0, SOIL_LOAD_RGBA);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
	glGenerateMipmap(GL_TEXTURE_2D);
	SOIL_free_image_data(image1);
	glBindTexture(GL_TEXTURE_2D, 0);
	//绑定第二个纹理
	glGenTextures(1, &texture2);
	glBindTexture(GL_TEXTURE_2D, texture2);
	parameter();
	unsigned char* image2=SOIL_load_image("res/images/image2.BMP", &width, &height, 0, SOIL_LOAD_RGBA);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2);
	glGenerateMipmap(GL_TEXTURE_2D);
	SOIL_free_image_data(image2);
	glBindTexture(GL_TEXTURE_2D, 0);

	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		ourShader.Use();
		//注意要把time参数传回片段着色器fs,否则得不到变化的值
		GLfloat time = glfwGetTime();
		glUniform1f(glGetUniformLocation(ourShader.Program, "time"), time);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture1);
		glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture0"), 0);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture2);
		glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 1);

		glBindVertexArray(VAO);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
		//glDrawArrays(GL_TRIANGLES, 0, 36);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glBindVertexArray(0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glfwSwapBuffers(window);
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	//glDeleteProgram(shaderProgram);
	glDeleteTextures(1, &texture1);
	glDeleteTextures(1, &texture1);
	ourShader.~Shader();
	glfwTerminate();
	return 0;
}

void parameter() {
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

core.vs

 #version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
layout(location = 2) in vec2 textureCoords;
out vec3 ourColor;

out vec2 ourTextureCoords;
void main()
{
	gl_Position =vec4(position, 1.0f);
	ourColor=color;
	ourTextureCoords=vec2(textureCoords.x,1-textureCoords.y);
}

core.fs

#version 330 core
in vec3 ourColor;
in vec2 ourTextureCoords;
out vec4 color;
uniform float time;

uniform sampler2D ourTexture0;
uniform sampler2D ourTexture1;

void main()
{
       vec2 MovingTextureCoords=vec2(ourTextureCoords.x+time,ourTextureCoords.y);//向右移动
       //color=texture(ourTexture0,MovingTextureCoords);
       color = mix(texture(ourTexture0, MovingTextureCoords), texture(ourTexture1,MovingTextureCoords), sin(time*2)/2.0f+0.5f);//渐变
}
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岚-岚岚岚岚岚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值