zoukankan      html  css  js  c++  java
  • OpenGL纹理

    着色器类头文件

    //我们自己的着色器类
    
    
    #ifndef SHADER_H
    #define SHADER_H
    
    #include <GL/glew.h>	//包含glew来获取所有的必须Opengl头文件
    
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <iostream>
    
    class Shader {
    public:
    	unsigned int ID;	//程序ID
    
    	//构造器读取并构建着色器
    	Shader(const GLchar* vertexPath, const GLchar* fragmentPath);//顶点着色器的源码路径和片段着色器的源码路径
    	
    	void use();	//使用、激活程序
    
    	//uniform工具函数
    	void setBool(const std::string &name, bool value) const;
    	void setInt(const std::string &name, int value) const;
    	void setFloat(const std::string &name, float value) const;
    };
    
    Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
    {	//从文件路径中获取顶点、片段着色器
    	
    	std::string vertexCode;
    	std::string fragmentCode;
    	std::ifstream vShaderFile;
    	std::ifstream fShaderFile;
    
    	//确保fstream对象可以抛出异常
    	vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    	fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    
    	try
    	{
    		//打开文件
    		vShaderFile.open(vertexPath);
    		fShaderFile.open(fragmentPath);
    
    		std::stringstream vShaderStream, fShaderStream;
    
    		vShaderStream << vShaderFile.rdbuf();	//读取文件的缓冲内容到数据流中
    		fShaderStream << fShaderFile.rdbuf();
    
    		vShaderFile.close();	//关闭文件处理器
    		fShaderFile.close();
    
    		vertexCode = vShaderStream.str();		//转换数据流到string
    		fragmentCode = fShaderStream.str();
    
    	}
    
    	catch (std::ifstream::failure e)
    	{
    		std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
    	}
    
    	const char* vShaderCode = vertexCode.c_str();
    	const char* fShaderCode = fragmentCode.c_str();
    
    	//2.编译着色器
    	unsigned int vertex, fragment;
    	int success;
    	char infoLog[512];
    
    	//顶点着色器
    	vertex = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(vertex, 1, &vShaderCode, NULL);
    	glCompileShader(vertex);
    	glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
    	if (!success)
    	{
    		glGetShaderInfoLog(vertex, 512, NULL, infoLog);
    		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!
    " << std::endl;
    	}
    
    	fragment = glCreateShader(GL_FRAGMENT_SHADER);	//片段着色器
    	glShaderSource(fragment, 1, &fShaderCode, NULL);
    	glCompileShader(fragment);
    	glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
    	if (!success)
    	{
    		glGetShaderInfoLog(fragment, 512, NULL, infoLog);
    		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATON_FAILED!
    " << std::endl;
    	}
    
    	ID = glCreateProgram();	//着色器程序
    	glAttachShader(ID, vertex);
    	glAttachShader(ID, fragment);
    	glLinkProgram(ID);
    	glGetProgramiv(ID, GL_LINK_STATUS, &success);
    	if (!success)
    	{
    		glGetProgramInfoLog(ID, 512, NULL, infoLog);
    		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED!
    " << std::endl;
    	}
    
    	glDeleteShader(vertex);		//删除着色器,他们已经链接到我们的程序中了,已经不需要了
    	glDeleteShader(fragment);
    
    }
    
    void Shader::use()
    {
    	glUseProgram(ID);		//激活这个着色器程序
    }
    
    void Shader::setBool(const std::string& name, bool value) const
    {
    	glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
    }
    
    void Shader::setInt(const std::string &name, int value) const
    {
    	glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
    }
    
    
    void Shader::setFloat(const std::string &name, float value) const
    {
    	glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
    }
    
    
    
    
    #endif

    纹理cpp文件

    #include <iostream>
    using namespace std;
    
    #define GLEW_STATIC
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    //#define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"
    #include "Shader.h"
    
    void framebuffers_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    
    float mixValue = 0.2f;
    
    int main()
    {
    	glfwInit();
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    	GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpengl", NULL, NULL);
    	if (window == NULL)
    	{
    		cout << "Failed to create window!
    " << endl;
    		glfwTerminate();
    		return -1;
    	}
    	glfwMakeContextCurrent(window);
    	glfwSetFramebufferSizeCallback(window, framebuffers_size_callback);	//改变窗口大小的回调函数
    
    	glewExperimental = GL_TRUE;
    	if (glewInit() != GLEW_OK)
    	{
    		cout << "Fail to initialize GLEW!
    " << endl;
    		return -1;
    	}
    
    	/*unsigned vertexShader, fragmentShader;
    	vertexShader = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    	glCompileShader(vertexShader);
    
    	int success;
    	char infolog[512];
    	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    	if (!success)
    	{
    		glGetShaderInfoLog(vertexShader, 512, NULL, infolog);
    		cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!
    " << infolog << endl;
    	}
    
    	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    	glShaderSource = (fragmentShader, 1, &fragmentShaderSource, NULL);
    	glCompileShader(fragmentShader);
    	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    	if (!success)
    	{
    		glGetShaderInfoLog(fragmentShader, 512, NULL, infolog);
    		cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!
    " << infolog << endl;
    	}
    
    	unsigned int shaderProgram;
    	shaderProgram = glCreateProgram();
    	glAttachShader(shaderProgram, vertexShader);
    	glAttachShader(shaderProgram, fragmentShader);
    	glLinkProgram(shaderProgram);
    	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    	if (!success)
    	{
    		glGetProgramInfoLog(shaderProgram, 512, NULL, infolog);
    		cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED!
    " << infolog << endl;
    	}
    	glDeleteShader(vertexShader);
    	glDeleteShader(fragmentShader);*/
    
    	Shader ourShader("E:\C++\1.txt", "E:\C++\2.txt");
    	GLfloat vertices[] = {
    		 0.5f, 0.5f, 0.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f,		//4.0f控制把图赋值多少16份
    		 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 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, 1.0f
    	};
    
    	unsigned int indices[] = {
    		0, 1, 3,
    		1, 2, 3
    	};
    	
    	unsigned VBO, VAO, EBO;
    	glGenVertexArrays(1, &VAO);
    	glGenBuffers(1, &VBO);
    	glGenBuffers(1, &EBO);
    
    	glBindVertexArray(VAO);
    	glBindBuffer(GL_ARRAY_BUFFER, VBO);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    	glEnableVertexAttribArray(0);
    
    	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    	glEnableVertexAttribArray(1);
    
    	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    	glEnableVertexAttribArray(2);
    
    
    	unsigned int texture1;
    	glGenTextures(1, &texture1);
    	glBindTexture(GL_TEXTURE_2D, texture1);
    
    	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_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    
    	int width, height, nrChannels;
    
    	//stbi_set_flip_vertically_on_load(true);	//倒转图片
    	//stbi_set_flip_vertically_on_load(true);	//倒转图片
    
    	unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
    	if (data)
    	{
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    		glGenerateMipmap(GL_TEXTURE_2D);
    	}
    	else
    	{
    		cout << "Failed to load texture1!
    " << endl;
    	}
    	stbi_image_free(data);
    
    	unsigned int texture2;
    	glGenTextures(1, &texture2);
    	glBindTexture(GL_TEXTURE_2D, texture2);
    
    	//texture1和texture2的环绕方式不同的组合效果很不一样
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    	data = stbi_load("timg.jpg", &width, &height, &nrChannels, 0);
    	if (data)
    	{
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    		glGenerateMipmap(GL_TEXTURE_2D);
    	}
    	else
    	{
    		cout << "Fail to load texture2!
    " << endl;
    	}
    	stbi_image_free(data);
    
    	ourShader.use();
    	glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
    	glUniform1i(glGetUniformLocation(ourShader.ID, "texture2"), 1);
    
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
    	glBindVertexArray(0);
    
    	while (!glfwWindowShouldClose(window))
    	{
    		processInput(window);
    		glClearColor(0.2f, 0.5f, 0.7f, 1.0f);
    		glClear(GL_COLOR_BUFFER_BIT);
    
    		//glBindTexture(GL_TEXTURE_2D, texture);
    
    		glActiveTexture(GL_TEXTURE1);	//在绑定纹理之前需先激活纹理单元
    		glBindTexture(GL_TEXTURE_2D, texture1);
    		glActiveTexture(GL_TEXTURE0);	//在绑定纹理之前需先激活纹理单元
    		glBindTexture(GL_TEXTURE_2D, texture2);
    
    		ourShader.setFloat("mixValue", mixValue);
    
    		//glUseProgram(shaderProgram);
    		glUseProgram(ourShader.ID);
    		glBindVertexArray(VAO);
    		//glDrawArrays(GL_TRIANGLES, 0, 3);
    		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    
    		glfwSwapBuffers(window);
    		glfwPollEvents();
    	}
    
    	glDeleteVertexArrays(1, &VAO);
    	glDeleteBuffers(1, &VBO);
    	glDeleteBuffers(1, &EBO);
    
    	return 0;
    }
    
    void framebuffers_size_callback(GLFWwindow* window, int width, int height)
    {
    	glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow* window)
    {
    	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    		glfwSetWindowShouldClose(window, true);
    
    	//用键盘上下键控制两个纹理的可见度比例
    	if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
    	{
    		mixValue += 0.001f;
    		if (mixValue >= 1.0f)
    			mixValue = 1.0f;
    	}
    	if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
    	{
    		mixValue -= 0.001f;
    		if (mixValue <= 0.0f)
    			mixValue = 0.0f;
    	}
    }
  • 相关阅读:
    计算系数
    N皇后问题
    矩阵取数游戏
    过河卒
    经营与开发
    软件开发记录01
    搭建android开发环境
    软件工程结对作业01
    学习总结和教师评价
    站立会议14
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12373453.html
Copyright © 2011-2022 走看看