Elevate Engine 1
Loading...
Searching...
No Matches
OpenGLShader.cpp
Go to the documentation of this file.
1#include "eepch.h"
2
3#include <vector>
4
5#define GLFW_INCLUDE_NONE
6#include <GLFW/glfw3.h>
8
9#include "glm/gtc/type_ptr.hpp"
10
14
15namespace Elevate
16{
17 OpenGLShader::OpenGLShader(const std::string& vertexSource, const std::string& fragmentSouce)
18 {
19 // Create an empty vertex shader handle
20 GLuint vertexShader = GLCheck(glCreateShader(GL_VERTEX_SHADER));
21
22 // Send the vertex shader source code to GL
23 // Note that std::string's .c_str is NULL character terminated.
24 const GLchar* source = vertexSource.c_str();
25 GLCheck(glShaderSource(vertexShader, 1, &source, 0));
26
27 // Compile the vertex shader
28 GLCheck(glCompileShader(vertexShader));
29
30 GLint isCompiled = 0;
31 GLCheck(glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled));
32
33 if (isCompiled == GL_FALSE)
34 {
35 GLint maxLength = 0;
36 glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
37
38 // The maxLength includes the NULL character
39
40 std::vector<GLchar> infoLog(maxLength);
41 glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);
42
43 // We don't need the shader anymore.
44 glDeleteShader(vertexShader);
45
46 EE_CORE_ERROR("{}", infoLog.data());
47 EE_CORE_ASSERT(false, "Vertex shader compilation failure.");
48 return;
49 }
50
51
52 // Create an empty fragment shader handle
53 GLuint fragmentShader = GLCheck(glCreateShader(GL_FRAGMENT_SHADER));
54
55 // Send the fragment shader source code to GL
56 // Note that std::string's .c_str is NULL character terminated.
57 source = fragmentSouce.c_str();
58 GLCheck(glShaderSource(fragmentShader, 1, &source, 0));
59
60 // Compile the fragment shader
61 GLCheck(glCompileShader(fragmentShader));
62
63 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
64
65 if (isCompiled == GL_FALSE)
66 {
67 GLint maxLength = 0;
68 glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
69
70 // The maxLength includes the NULL character
71 // TODO optimiser et ne pas utiliser les vecteurs.
72 std::vector<GLchar> infoLog(maxLength);
73 glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);
74
75 // We don't need the shader anymore.
76 glDeleteShader(fragmentShader);
77 // Either of them. Don't leak shaders.
78 glDeleteShader(vertexShader);
79
80 EE_CORE_ERROR("{}", infoLog.data());
81 EE_CORE_ASSERT(false, "Fragment shader compilation failure.");
82 return;
83 }
84
85 // Vertex and fragment shaders are successfully compiled.
86 // Now time to link them together into a program.
87 // Get a program object.
88 m_RendererID = glCreateProgram();
89
90 // Attach our shaders to our program
91 glAttachShader(m_RendererID, vertexShader);
92 glAttachShader(m_RendererID, fragmentShader);
93
94 // Link our program
95 glLinkProgram(m_RendererID);
96
97 // Note the different functions here: glGetProgram* instead of glGetShader*.
98 GLint isLinked = 0;
99 glGetProgramiv(m_RendererID, GL_LINK_STATUS, (int*)&isLinked);
100 if (isLinked == GL_FALSE)
101 {
102 GLint maxLength = 0;
103 glGetProgramiv(m_RendererID, GL_INFO_LOG_LENGTH, &maxLength);
104
105 // The maxLength includes the NULL character
106 // TODO optimiser et ne pas utiliser les vecteurs.
107 std::vector<GLchar> infoLog(maxLength);
108 glGetProgramInfoLog(m_RendererID, maxLength, &maxLength, &infoLog[0]);
109
110 // We don't need the program anymore.
111 glDeleteProgram(m_RendererID);
112 // Don't leak shaders either.
113 glDeleteShader(vertexShader);
114 glDeleteShader(fragmentShader);
115
116 // Use the infoLog as you see fit.
117
118 // Log and leave
119 EE_CORE_ERROR("{}", infoLog.data());
120 EE_CORE_ERROR("Error : Unable to link shaders.");
121 return;
122 }
123
124 // Always detach shaders after a successful link.
125 glDetachShader(m_RendererID, vertexShader);
126 glDetachShader(m_RendererID, fragmentShader);
127
129 }
130
132 {
133 glDeleteProgram(m_RendererID);
134 }
135
136 uint32_t OpenGLShader::GetID() const
137 {
138 return m_RendererID;
139 }
140
142 {
143 GLCheck(glUseProgram(m_RendererID));
144 }
145
147 {
148 glUseProgram(0);
149 }
150
152 {
153 return m_RendererID;
154 }
155
156 void OpenGLShader::SetUniform1f(const std::string& location, float value) const
157 {
158 GLCheck(glUniform1f(glGetUniformLocation(m_RendererID, location.c_str()), value));
159 }
160
161 void OpenGLShader::SetUniform2f(const std::string& location, float x, float y) const
162 {
163 GLCheck(glUniform2f(glGetUniformLocation(m_RendererID, location.c_str()), x, y));
164 }
165
166 void OpenGLShader::SetUniform3f(const std::string& location, float x, float y, float z) const
167 {
168 GLCheck(glUniform3f(glGetUniformLocation(m_RendererID, location.c_str()), x, y, z));
169 }
170
171 void OpenGLShader::SetUniform4f(const std::string& location, float x, float y, float z, float w) const
172 {
173 GLCheck(glUniform4f(glGetUniformLocation(m_RendererID, location.c_str()), x, y, z, w));
174 }
175
176 void OpenGLShader::SetUniform1i(const std::string& location, int value) const
177 {
178 GLCheck(glUniform1i(glGetUniformLocation(m_RendererID, location.c_str()), value));
179 }
180
181 void OpenGLShader::SetUniform2i(const std::string& location, int x, int y) const
182 {
183 GLCheck(glUniform2i(glGetUniformLocation(m_RendererID, location.c_str()), x, y));
184 }
185
186 void OpenGLShader::SetUniform3i(const std::string& location, int x, int y, int z) const
187 {
188 GLCheck(glUniform3i(glGetUniformLocation(m_RendererID, location.c_str()), x, y, z));
189 }
190
191 void OpenGLShader::SetUniform4i(const std::string& location, int x, int y, int z, int w) const
192 {
193 GLCheck(glUniform4i(glGetUniformLocation(m_RendererID, location.c_str()), x, y, z, w));
194 }
195
196 void OpenGLShader::SetUniform1fv(const std::string& location, int count, float* value) const
197 {
198 GLCheck(glUniform1fv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
199 }
200
201 void OpenGLShader::SetUniform2fv(const std::string& location, int count, float* value) const
202 {
203 GLCheck(glUniform2fv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
204 }
205
206 void OpenGLShader::SetUniform3fv(const std::string& location, int count, float* value) const
207 {
208 GLCheck(glUniform3fv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
209 }
210
211 void OpenGLShader::SetUniform4fv(const std::string& location, int count, float* value) const
212 {
213 GLCheck(glUniform4fv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
214 }
215
216 void OpenGLShader::SetUniform1iv(const std::string& location, int count, int* value) const
217 {
218 GLCheck(glUniform1iv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
219 }
220
221 void OpenGLShader::SetUniform2iv(const std::string& location, int count, int* value) const
222 {
223 GLCheck(glUniform2iv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
224 }
225
226 void OpenGLShader::SetUniform3iv(const std::string& location, int count, int* value) const
227 {
228 GLCheck(glUniform3iv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
229 }
230
231 void OpenGLShader::SetUniform4iv(const std::string& location, int count, int* value) const
232 {
233 GLCheck(glUniform4iv(glGetUniformLocation(m_RendererID, location.c_str()), count, value));
234 }
235
236 void OpenGLShader::SetUniformMatrix2fv(const std::string& location, float* data) const
237 {
238 GLCheck(glUniformMatrix2fv(glGetUniformLocation(m_RendererID, location.c_str()), 1, GL_FALSE, data));
239 }
240
241 void OpenGLShader::SetUniformMatrix3fv(const std::string& location, float* data) const
242 {
243 GLCheck(glUniformMatrix3fv(glGetUniformLocation(m_RendererID, location.c_str()), 1, GL_FALSE, data));
244 }
245
246 void OpenGLShader::SetUniformMatrix4fv(const std::string& location, float* data) const
247 {
248 //GLCheck(glUniformMatrix4fv(glGetUniformLocation(m_RendererID, location.c_str()), 1, GL_FALSE, data));
249 // todo remove this debug code
250 int loc = glGetUniformLocation(m_RendererID, location.c_str());
251 if (loc == -1) {
252 EE_CORE_ERROR("Uniform '{0}' introuvable dans le shader ID {1}!", location, m_RendererID);
253 }
254 glUniformMatrix4fv(loc, 1, GL_FALSE, data);
255 }
256
257 static EngineDataType GLTypeToEngineDataType(GLenum type)
258 {
259 switch (type)
260 {
261 case GL_FLOAT: return EngineDataType::Float;
262 case GL_FLOAT_VEC2: return EngineDataType::Float2;
263 case GL_FLOAT_VEC3: return EngineDataType::Float3;
264 case GL_FLOAT_VEC4: return EngineDataType::Float4;
265 case GL_INT: return EngineDataType::Int;
266 case GL_INT_VEC2: return EngineDataType::Int2;
267 case GL_INT_VEC3: return EngineDataType::Int3;
268 case GL_INT_VEC4: return EngineDataType::Int4;
269 case GL_BOOL: return EngineDataType::Bool;
270 case GL_FLOAT_MAT3: return EngineDataType::Mat3;
271 case GL_FLOAT_MAT4: return EngineDataType::Mat4;
272 case GL_SAMPLER_2D: return EngineDataType::Sampler2D;
273 }
275 }
276
278 {
279 GLint uniformCount = 0;
280 glGetProgramiv(m_RendererID, GL_ACTIVE_UNIFORMS, &uniformCount);
281
282 std::vector<BufferElement> elements;
283 elements.reserve(uniformCount);
284
285 GLint maxNameLength = 0;
286 glGetProgramiv(m_RendererID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
287 std::vector<GLchar> nameBuffer(maxNameLength);
288
289 EE_CORE_TRACE("Starting reflection for shader ID {}", m_RendererID);
290 for (GLint i = 0; i < uniformCount; i++)
291 {
292 GLsizei length;
293 GLint size;
294 GLenum type;
295 glGetActiveUniform(m_RendererID, i, maxNameLength, &length, &size, &type, nameBuffer.data());
296 std::string name(nameBuffer.data(), length);
297 elements.push_back({ GLTypeToEngineDataType(type), name });
298 EE_CORE_TRACE(" - Found uniform {}", name);
299 }
300 EE_CORE_TRACE("Completed shader reflection.");
301 return BufferLayout(elements);
302 }
303}
#define GLCheck(x)
Definition GLDebug.h:11
virtual void SetUniform4i(const std::string &location, int x, int y, int z, int w) const override
virtual BufferLayout ExtractReflectionData() const override
virtual void SetUniform4fv(const std::string &location, int count, float *value) const override
virtual void SetUniform3fv(const std::string &location, int count, float *value) const override
virtual void SetUniformMatrix4fv(const std::string &location, float *data) const override
virtual void SetUniform3f(const std::string &location, float x, float y, float z) const override
virtual void SetUniform2iv(const std::string &location, int count, int *value) const override
virtual void SetUniform1i(const std::string &location, int value) const override
virtual void Unbind() const override
virtual void SetUniform2f(const std::string &location, float x, float y) const override
virtual void SetUniform2fv(const std::string &location, int count, float *value) const override
virtual void Bind() const override
virtual void SetUniform2i(const std::string &location, int x, int y) const override
virtual void SetUniformMatrix3fv(const std::string &location, float *data) const override
virtual void SetUniform1fv(const std::string &location, int count, float *value) const override
OpenGLShader(const std::string &vertexSource, const std::string &fragmentSouce)
virtual void SetUniform4iv(const std::string &location, int count, int *value) const override
virtual void SetUniform1f(const std::string &location, float value) const override
UNIFORMS.
virtual uint32_t GetHashCode() const override
virtual void SetUniform4f(const std::string &location, float x, float y, float z, float w) const override
virtual void SetUniformMatrix2fv(const std::string &location, float *data) const override
virtual uint32_t GetID() const override
virtual void SetUniform3i(const std::string &location, int x, int y, int z) const override
virtual void SetUniform3iv(const std::string &location, int count, int *value) const override
virtual void SetUniform1iv(const std::string &location, int count, int *value) const override
void SetInitializationStatus(bool initialized)
Definition Shader.h:115
EngineDataType
Definition Data.h:106
unsigned int GLenum