如果不用头文件,把所有东西堆在同一个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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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!
" << 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 }