OpenGL着色器实现纹理合并显示

   OpenGL着色器实现纹理合并显示

       本文介绍了opengl下实现纹理的装载,同时借助顶点着色器和片源着色器实现两个不同外部纹理的合并显示。


目录

  • 1 opengl下纹理的装载
  • 2 纹理合并效果显示
  • 3 完整的代码

  • 1 opengl下纹理的装载
// 初始化GLFW
	if (!glfwInit()) {
		std::cerr << "Failed to initialize GLFW" << std::endl;
		return -1;
	}

	// 创建窗口
	GLFWwindow* window = glfwCreateWindow(800, 600, "Multiple Textures Example", NULL, NULL);
	if (!window) {
		std::cerr << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}

	glfwMakeContextCurrent(window);

	// 初始化GLEW
	if (glewInit() != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// 编译顶点着色器
	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);

	// 编译片元着色器
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	// 创建着色器程序
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	glUseProgram(shaderProgram);

	// 加载纹理1
	GLuint textureID1 = SOIL_load_OGL_texture("1.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, textureID1);
	glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);

	// 加载纹理2
	GLuint textureID2 = SOIL_load_OGL_texture("2.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, textureID2);
	glUniform1i(glGetUniformLocation(shaderProgram, "texture2"), 1);

        借助glfw实现窗口的创建,借助SOIL库实现纹理的装载,返回加载后的纹理id。

  • 2 纹理合并效果显示
// 设置顶点数据和纹理坐标
	float vertices[] = {
		// 位置            // 纹理坐标
		-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
		 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
		 1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
		- 1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
		 1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
		 -1.0f,  1.0f, 0.0f, 0.0f, 1.0f
	};

	// 创建顶点缓冲对象和顶点数组对象
	unsigned int VBO, VAO;
	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, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);

	// 渲染循环
	while (!glfwWindowShouldClose(window)) {
		glClear(GL_COLOR_BUFFER_BIT);

		// 绑定纹理并绘制
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureID1);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, textureID2);

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 6);

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// 清理资源
	glDeleteTextures(1, &textureID1);
	glDeleteTextures(1, &textureID2);
	glDeleteProgram(shaderProgram);
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	glfwTerminate();

        绘制两个三角形,并绑定两个纹理。添加顶点着色器和片元着色器,其代码如下:

const char* vertexShaderSource = R"(
#version 330 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;

out vec2 fragTexCoord;

void main() {
    fragTexCoord = texCoord;
    gl_Position = vec4(position, 1.0);
}
)";

const char* fragmentShaderSource = R"(
#version 330 core

in vec2 fragTexCoord;
out vec4 fragColor;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main() {
    vec4 color1 = texture(texture1, fragTexCoord);
    vec4 color2 = texture(texture2, fragTexCoord);
    
    // 将两个纹理的颜色进行混合
    fragColor = mix(color1, color2, 0.5);
}
)";
  • 3 完整的代码

        完整的代码如下所示,需依赖glfw实现窗口显示,依赖SOIL实现纹理装载。需将两个纹理路径换为本地路径,给出的示例代码路径为1.jpg和2.jpg。


#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <SOIL/SOIL.h>
#include <iostream>

const char* vertexShaderSource = R"(
#version 330 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;

out vec2 fragTexCoord;

void main() {
    fragTexCoord = texCoord;
    gl_Position = vec4(position, 1.0);
}
)";

const char* fragmentShaderSource = R"(
#version 330 core

in vec2 fragTexCoord;
out vec4 fragColor;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main() {
    vec4 color1 = texture(texture1, fragTexCoord);
    vec4 color2 = texture(texture2, fragTexCoord);
    
    // 将两个纹理的颜色进行混合
    fragColor = mix(color1, color2, 0.5);
}
)";

int main() {
	// 初始化GLFW
	if (!glfwInit()) {
		std::cerr << "Failed to initialize GLFW" << std::endl;
		return -1;
	}

	// 创建窗口
	GLFWwindow* window = glfwCreateWindow(800, 600, "Multiple Textures Example", NULL, NULL);
	if (!window) {
		std::cerr << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}

	glfwMakeContextCurrent(window);

	// 初始化GLEW
	if (glewInit() != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// 编译顶点着色器
	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	glCompileShader(vertexShader);

	// 编译片元着色器
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	// 创建着色器程序
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	glUseProgram(shaderProgram);

	// 加载纹理1
	GLuint textureID1 = SOIL_load_OGL_texture("1.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, textureID1);
	glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);

	// 加载纹理2
	GLuint textureID2 = SOIL_load_OGL_texture("2.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, textureID2);
	glUniform1i(glGetUniformLocation(shaderProgram, "texture2"), 1);

	// 设置顶点数据和纹理坐标
	float vertices[] = {
		// 位置            // 纹理坐标
		-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
		 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
		 1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
		- 1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
		 1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
		 -1.0f,  1.0f, 0.0f, 0.0f, 1.0f
	};

	// 创建顶点缓冲对象和顶点数组对象
	unsigned int VBO, VAO;
	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, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);

	// 渲染循环
	while (!glfwWindowShouldClose(window)) {
		glClear(GL_COLOR_BUFFER_BIT);

		// 绑定纹理并绘制
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureID1);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, textureID2);

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 6);

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// 清理资源
	glDeleteTextures(1, &textureID1);
	glDeleteTextures(1, &textureID2);
	glDeleteProgram(shaderProgram);
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	glfwTerminate();
	return 0;
}

相关推荐

  1. OpenGL着色实现纹理合并显示

    2024-04-11 17:20:04       32 阅读
  2. OpenGLOpenGL ES显示YUV图片的着色差别(一)

    2024-04-11 17:20:04       49 阅读
  3. 19 OpenGL计算着色

    2024-04-11 17:20:04       45 阅读
  4. OpenGL着色对象 Shader Objects

    2024-04-11 17:20:04       58 阅读
  5. OpenGL着色内存访问

    2024-04-11 17:20:04       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-11 17:20:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-11 17:20:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-11 17:20:04       87 阅读
  4. Python语言-面向对象

    2024-04-11 17:20:04       96 阅读

热门阅读

  1. 计算机科学与技术CS考研408资料

    2024-04-11 17:20:04       35 阅读
  2. 学习 Rust 的第一天:基础知识

    2024-04-11 17:20:04       41 阅读
  3. 小白学习python的路线

    2024-04-11 17:20:04       34 阅读
  4. c#编程基础学习之数据类型

    2024-04-11 17:20:04       35 阅读
  5. [html]网页结构以及常见标签用法

    2024-04-11 17:20:04       30 阅读
  6. C语言程序设计每日一练(1)

    2024-04-11 17:20:04       38 阅读
  7. 在前端开发中用到了哪些设计模式?

    2024-04-11 17:20:04       39 阅读
  8. python - argparse、configparser的用法

    2024-04-11 17:20:04       41 阅读