OpenGL纹理

简介: OpenGL纹理
如果不用头文件,把所有东西堆在同一个cpp文件中,会出现“超出GPU内存的错误!”
1 //我们自己的着色器类
  2 
  3 
  4 #ifndef SHADER_H
  5 #define SHADER_H
  6 
  7 #include <GL/glew.h>    //包含glew来获取所有的必须Opengl头文件
  8 
  9 #include <string>
 10 #include <fstream>
 11 #include <sstream>
 12 #include <iostream>
 13 
 14 class Shader {
 15 public:
 16     unsigned int ID;    //程序ID
 17 
 18     //构造器读取并构建着色器
 19     Shader(const GLchar* vertexPath, const GLchar* fragmentPath);//顶点着色器的源码路径和片段着色器的源码路径
 20     
 21     void use();    //使用、激活程序
 22 
 23     //uniform工具函数
 24     void setBool(const std::string &name, bool value) const;
 25     void setInt(const std::string &name, int value) const;
 26     void setFloat(const std::string &name, float value) const;
 27 };
 28 
 29 Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
 30 {    //从文件路径中获取顶点、片段着色器
 31     
 32     std::string vertexCode;
 33     std::string fragmentCode;
 34     std::ifstream vShaderFile;
 35     std::ifstream fShaderFile;
 36 
 37     //确保fstream对象可以抛出异常
 38     vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 39     fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 40 
 41     try
 42     {
 43         //打开文件
 44         vShaderFile.open(vertexPath);
 45         fShaderFile.open(fragmentPath);
 46 
 47         std::stringstream vShaderStream, fShaderStream;
 48 
 49         vShaderStream << vShaderFile.rdbuf();    //读取文件的缓冲内容到数据流中
 50         fShaderStream << fShaderFile.rdbuf();
 51 
 52         vShaderFile.close();    //关闭文件处理器
 53         fShaderFile.close();
 54 
 55         vertexCode = vShaderStream.str();        //转换数据流到string
 56         fragmentCode = fShaderStream.str();
 57 
 58     }
 59 
 60     catch (std::ifstream::failure e)
 61     {
 62         std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
 63     }
 64 
 65     const char* vShaderCode = vertexCode.c_str();
 66     const char* fShaderCode = fragmentCode.c_str();
 67 
 68     //2.编译着色器
 69     unsigned int vertex, fragment;
 70     int success;
 71     char infoLog[512];
 72 
 73     //顶点着色器
 74     vertex = glCreateShader(GL_VERTEX_SHADER);
 75     glShaderSource(vertex, 1, &vShaderCode, NULL);
 76     glCompileShader(vertex);
 77     glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
 78     if (!success)
 79     {
 80         glGetShaderInfoLog(vertex, 512, NULL, infoLog);
 81         std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!\n" << std::endl;
 82     }
 83 
 84     fragment = glCreateShader(GL_FRAGMENT_SHADER);    //片段着色器
 85     glShaderSource(fragment, 1, &fShaderCode, NULL);
 86     glCompileShader(fragment);
 87     glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
 88     if (!success)
 89     {
 90         glGetShaderInfoLog(fragment, 512, NULL, infoLog);
 91         std::cout << "ERROR::SHADER::FRAGMENT::COMPILATON_FAILED!\n" << std::endl;
 92     }
 93 
 94     ID = glCreateProgram();    //着色器程序
 95     glAttachShader(ID, vertex);
 96     glAttachShader(ID, fragment);
 97     glLinkProgram(ID);
 98     glGetProgramiv(ID, GL_LINK_STATUS, &success);
 99     if (!success)
100     {
101         glGetProgramInfoLog(ID, 512, NULL, infoLog);
102         std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED!\n" << std::endl;
103     }
104 
105     glDeleteShader(vertex);        //删除着色器,他们已经链接到我们的程序中了,已经不需要了
106     glDeleteShader(fragment);
107 
108 }
109 
110 void Shader::use()
111 {
112     glUseProgram(ID);        //激活这个着色器程序
113 }
114 
115 void Shader::setBool(const std::string& name, bool value) const
116 {
117     glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
118 }
119 
120 void Shader::setInt(const std::string &name, int value) const
121 {
122     glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
123 }
124 
125 
126 void Shader::setFloat(const std::string &name, float value) const
127 {
128     glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
129 }
130 
131 
132 
133 
134 #endif
纹理cpp文件
 1 #include <iostream>
 2 using namespace std;
  3 
  4 #define GLEW_STATIC
  5 #include <GL/glew.h>
  6 #include <GLFW/glfw3.h>
  7 //#define STB_IMAGE_IMPLEMENTATION
  8 #include "stb_image.h"
  9 #include "Shader.h"
 10 
 11 void framebuffers_size_callback(GLFWwindow* window, int width, int height);
 12 void processInput(GLFWwindow* window);
 13 
 14 float mixValue = 0.2f;
 15 
 16 int main()
 17 {
 18     glfwInit();
 19     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 20     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 21     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 22     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpengl", NULL, NULL);
 23     if (window == NULL)
 24     {
 25         cout << "Failed to create window!\n" << endl;
 26         glfwTerminate();
 27         return -1;
 28     }
 29     glfwMakeContextCurrent(window);
 30     glfwSetFramebufferSizeCallback(window, framebuffers_size_callback);    //改变窗口大小的回调函数
 31 
 32     glewExperimental = GL_TRUE;
 33     if (glewInit() != GLEW_OK)
 34     {
 35         cout << "Fail to initialize GLEW!\n" << endl;
 36         return -1;
 37     }
 38 
 39     /*unsigned vertexShader, fragmentShader;
 40     vertexShader = glCreateShader(GL_VERTEX_SHADER);
 41     glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
 42     glCompileShader(vertexShader);
 43 
 44     int success;
 45     char infolog[512];
 46     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
 47     if (!success)
 48     {
 49         glGetShaderInfoLog(vertexShader, 512, NULL, infolog);
 50         cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!\n" << infolog << endl;
 51     }
 52 
 53     fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
 54     glShaderSource = (fragmentShader, 1, &fragmentShaderSource, NULL);
 55     glCompileShader(fragmentShader);
 56     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
 57     if (!success)
 58     {
 59         glGetShaderInfoLog(fragmentShader, 512, NULL, infolog);
 60         cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!\n" << infolog << endl;
 61     }
 62 
 63     unsigned int shaderProgram;
 64     shaderProgram = glCreateProgram();
 65     glAttachShader(shaderProgram, vertexShader);
 66     glAttachShader(shaderProgram, fragmentShader);
 67     glLinkProgram(shaderProgram);
 68     glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
 69     if (!success)
 70     {
 71         glGetProgramInfoLog(shaderProgram, 512, NULL, infolog);
 72         cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED!\n" << infolog << endl;
 73     }
 74     glDeleteShader(vertexShader);
 75     glDeleteShader(fragmentShader);*/
 76 
 77     Shader ourShader("E:\\C++\\1.txt", "E:\\C++\\2.txt");
 78     GLfloat vertices[] = {
 79          0.5f, 0.5f, 0.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f,        //4.0f控制把图赋值多少16份
 80          0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
 81         -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
 82         - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f , 0.0f, 1.0f
 83     };
 84 
 85     unsigned int indices[] = {
 86         0, 1, 3,
 87         1, 2, 3
 88     };
 89     
 90     unsigned VBO, VAO, EBO;
 91     glGenVertexArrays(1, &VAO);
 92     glGenBuffers(1, &VBO);
 93     glGenBuffers(1, &EBO);
 94 
 95     glBindVertexArray(VAO);
 96     glBindBuffer(GL_ARRAY_BUFFER, VBO);
 97     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
 98 
 99     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
100     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
101 
102     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
103     glEnableVertexAttribArray(0);
104 
105     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
106     glEnableVertexAttribArray(1);
107 
108     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
109     glEnableVertexAttribArray(2);
110 
111 
112     unsigned int texture1;
113     glGenTextures(1, &texture1);
114     glBindTexture(GL_TEXTURE_2D, texture1);
115 
116     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
117     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
118     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
119     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
120 
121     int width, height, nrChannels;
122 
123     //stbi_set_flip_vertically_on_load(true);    //倒转图片
124     //stbi_set_flip_vertically_on_load(true);    //倒转图片
125 
126     unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
127     if (data)
128     {
129         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
130         glGenerateMipmap(GL_TEXTURE_2D);
131     }
132     else
133     {
134         cout << "Failed to load texture1!\n" << endl;
135     }
136     stbi_image_free(data);
137 
138     unsigned int texture2;
139     glGenTextures(1, &texture2);
140     glBindTexture(GL_TEXTURE_2D, texture2);
141 
142     //texture1和texture2的环绕方式不同的组合效果很不一样
143     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
144     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
146     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
147     data = stbi_load("timg.jpg", &width, &height, &nrChannels, 0);
148     if (data)
149     {
150         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
151         glGenerateMipmap(GL_TEXTURE_2D);
152     }
153     else
154     {
155         cout << "Fail to load texture2!\n" << endl;
156     }
157     stbi_image_free(data);
158 
159     ourShader.use();
160     glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
161     glUniform1i(glGetUniformLocation(ourShader.ID, "texture2"), 1);
162 
163     glBindBuffer(GL_ARRAY_BUFFER, 0);
164     glBindVertexArray(0);
165 
166     while (!glfwWindowShouldClose(window))
167     {
168         processInput(window);
169         glClearColor(0.2f, 0.5f, 0.7f, 1.0f);
170         glClear(GL_COLOR_BUFFER_BIT);
171 
172         //glBindTexture(GL_TEXTURE_2D, texture);
173 
174         glActiveTexture(GL_TEXTURE1);    //在绑定纹理之前需先激活纹理单元
175         glBindTexture(GL_TEXTURE_2D, texture1);
176         glActiveTexture(GL_TEXTURE0);    //在绑定纹理之前需先激活纹理单元
177         glBindTexture(GL_TEXTURE_2D, texture2);
178 
179         ourShader.setFloat("mixValue", mixValue);
180 
181         //glUseProgram(shaderProgram);
182         glUseProgram(ourShader.ID);
183         glBindVertexArray(VAO);
184         //glDrawArrays(GL_TRIANGLES, 0, 3);
185         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
186 
187         glfwSwapBuffers(window);
188         glfwPollEvents();
189     }
190 
191     glDeleteVertexArrays(1, &VAO);
192     glDeleteBuffers(1, &VBO);
193     glDeleteBuffers(1, &EBO);
194 
195     return 0;
196 }
197 
198 void framebuffers_size_callback(GLFWwindow* window, int width, int height)
199 {
200     glViewport(0, 0, width, height);
201 }
202 
203 void processInput(GLFWwindow* window)
204 {
205     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
206         glfwSetWindowShouldClose(window, true);
207 
208     //用键盘上下键控制两个纹理的可见度比例
209     if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
210     {
211         mixValue += 0.001f;
212         if (mixValue >= 1.0f)
213             mixValue = 1.0f;
214     }
215     if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
216     {
217         mixValue -= 0.001f;
218         if (mixValue <= 0.0f)
219             mixValue = 0.0f;
220     }
221 }
E:\\C++\\1.txt文件内容:
 1 #version 330 core
 2 layout(location = 0) in vec3 aPos;
 3 layout(location = 1) in vec3 aColor;
 4 layout(location = 2) in vec2 aTexture;
 5 out vec3 ourColor;
 6 out vec2 ourTexture;
 7 void main()
 8 {
 9     gl_Position = vec4(aPos, 1.0f);
10     ourColor = aColor;
11     ourTexture = aTexture;
12 }
E:\\C++\\2.txt文件内容:
 1 #version 330 core
 2 out vec4 FragColor;
 3 in vec3 ourColor;
 4 in vec2 ourTexture;
 5 uniform float mixValue;
 6 uniform sampler2D texture1;
 7 uniform sampler2D texture2;
 8 void main()
 9 {
10      FragColor = mix(texture(texture1, vec2(ourTexture.x, 1.0 - ourTexture.y)), texture(texture2, ourTexture), mixValue);
11 }
相关文章
|
数据安全/隐私保护 索引
Opengl ES之纹理数组
Opengl ES连载系列
263 0
|
缓存 API Android开发
Android OpenGL添加纹理
Android OpenGL添加纹理
Android OpenGL添加纹理
|
Android开发 异构计算
Android OpenGL ES(八)----纹理编程框架(二)
Android OpenGL ES(八)----纹理编程框架(二)
192 0
Android OpenGL ES(八)----纹理编程框架(二)
|
存储 Java API
Android OpenGL ES(八)----纹理编程框架(一)
Android OpenGL ES(八)----纹理编程框架(一)
323 0
Android OpenGL ES(八)----纹理编程框架(一)
|
缓存 算法 机器人
Android OpenGL ES(七)----理解纹理与纹理过滤
Android OpenGL ES(七)----理解纹理与纹理过滤
270 0
Android OpenGL ES(七)----理解纹理与纹理过滤
|
图形学
学习OpenGL ES之基本纹理
学习OpenGL ES之基本纹理
学习OpenGL ES之基本纹理
|
缓存 索引
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
|
存储 缓存 C++
OpenGL学习笔记(十二):纹理的使用
OpenGL学习笔记(十二):纹理的使用
OpenGL学习笔记(十二):纹理的使用
|
索引
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
96 0
OpenGL ES 案例08:GLKit使用索引绘图 + 纹理颜色混合
|
索引
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合
339 0
OpenGL ES 案例07:GLSL使用索引绘图 + 纹理颜色混合