CoriEngine
Loading...
Searching...
No Matches
GL_ShaderProgram.cpp
Go to the documentation of this file.
2#include <glad/gl.h>
4
5namespace Cori {
6 namespace Graphics {
7 namespace Internal {
8 OpenGLShaderProgram::OpenGLShaderProgram(const std::filesystem::path& vertexPath, const std::filesystem::path& fragmentPath, const std::filesystem::path& geometryPath) {
9 bool geometryShaderPresent = false;
10
11 if (!geometryPath.empty()) {
12 geometryShaderPresent = true;
13 }
14
15 if (!std::filesystem::exists(vertexPath)) {
16 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "Could not find vertex shader at the specified path: '{}', file does not exist. This will likely not crash the application but will seriously mess up with rendering.", vertexPath.string());
17 }
18 if (!std::filesystem::exists(fragmentPath)) {
19 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "Could not find fragment shader at the specified path: '{}', file does not exist. This will likely not crash the application but will seriously mess up with rendering.", fragmentPath.string());
20 }
21 if (!geometryPath.empty()) {
22 if (!std::filesystem::exists(geometryPath)) {
23 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "Could not find geometry shader at the specified path: '{}', file does not exist. This will likely not crash the application but will seriously mess up with rendering.", geometryPath.string());
24 }
25 }
26
27#ifdef DEBUG_BUILD
28 m_ShaderNames = CORI_SECOND_LINE_SPACING + "Vertex shader: " + vertexPath.filename().string() + "\n" + CORI_SECOND_LINE_SPACING + "Fragment shader: " + fragmentPath.filename().string() + "\n" + CORI_SECOND_LINE_SPACING + "Geometry shader: " + (geometryShaderPresent ? geometryPath.filename().string() + "" : "Not specified (not an error)");
29#endif
30
31 const std::string vertexCode = FileSystem::FileManager::ReadTextFile(vertexPath);
32 const char* vertexSource = vertexCode.c_str();
33
34
35 const std::string fragmentCode = FileSystem::FileManager::ReadTextFile(fragmentPath);
36 const char* fragmentSource = fragmentCode.c_str();
37
38 GLuint geometry;
39 const GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
40 glShaderSource(vertex, 1, &vertexSource, nullptr);
41 glCompileShader(vertex);
42 if (CheckCompileErrors(vertex, "VERTEX") == false) {
43 m_CreationSuccessful = false;
44 }
45 const GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
46 glShaderSource(fragment, 1, &fragmentSource, nullptr);
47 glCompileShader(fragment);
48 if (CheckCompileErrors(fragment, "FRAGMENT") == false) {
49 m_CreationSuccessful = false;
50 }
51 if (geometryShaderPresent) {
52
53 const std::string geometryCode = FileSystem::FileManager::ReadTextFile(geometryPath);
54 const char* geometrySource = geometryCode.c_str();
55
56 geometry = glCreateShader(GL_GEOMETRY_SHADER);
57 glShaderSource(geometry, 1, &geometrySource, nullptr);
58 glCompileShader(geometry);
59 if (CheckCompileErrors(geometry, "GEOMETRY") == false) {
60 m_CreationSuccessful = false;
61 }
62 }
63 m_ID = glCreateProgram();
64 //glProgramParameteri(m_ID, GL_PROGRAM_SEPARABLE, GL_TRUE);
65 glAttachShader(m_ID, vertex);
66 glAttachShader(m_ID, fragment);
67 if (geometryShaderPresent) {
68 glAttachShader(m_ID, geometry);
69 }
70 glLinkProgram(m_ID);
71
72 if (CheckCompileErrors(m_ID, "PROGRAM") == false) {
73 m_CreationSuccessful = false;
74 }
75
76 glDeleteShader(vertex);
77 glDeleteShader(fragment);
78 if (geometryShaderPresent) {
79 glDeleteShader(geometry);
80 }
81
82 if (m_CreationSuccessful) {
83 CORI_CORE_INFO_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "(GL_RuntimeID: {}): Creation of {} with shaders:\n{}\n{}Has been successful", m_ID, m_DebugName, m_ShaderNames, CORI_SECOND_LINE_SPACING);
84 }
85 else {
86 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "(GL_RuntimeID: {}): Creation of {} with shaders:\n{}\n{}Has failed", m_ID, m_DebugName,m_ShaderNames, CORI_SECOND_LINE_SPACING);
87 }
88 }
89
91 glDeleteProgram(m_ID);
92 }
93
95 glUseProgram(m_ID);
96 }
97
99 glUseProgram(0);
100 }
101
102 void OpenGLShaderProgram::SetBool(const char* name, const bool value) const {
103 if (!m_UniformLocations.contains(name)) {
104 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
105 }
106
107 glProgramUniform1i(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), static_cast<GLint>(value));
108 }
109
110 void OpenGLShaderProgram::SetInt(const char* name, const int32_t value) const {
111 if (!m_UniformLocations.contains(name)) {
112 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
113 }
114
115 glProgramUniform1i(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), value);
116 }
117
118 void OpenGLShaderProgram::SetFloat(const char* name, const float value) const {
119 if (!m_UniformLocations.contains(name)) {
120 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
121 }
122
123 glProgramUniform1f(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), value);
124 }
125
126 void OpenGLShaderProgram::SetVec2(const char* name, const glm::vec2& value) const {
127 if (!m_UniformLocations.contains(name)) {
128 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
129 }
130
131 glProgramUniform2fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, &value[0]);
132 }
133
134 void OpenGLShaderProgram::SetVec3(const char* name, const glm::vec3& value) const {
135 if (!m_UniformLocations.contains(name)) {
136 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
137 }
138
139 glProgramUniform3fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, &value[0]);
140 }
141
142 void OpenGLShaderProgram::SetVec4(const char* name, const glm::vec4& value) const {
143 if (!m_UniformLocations.contains(name)) {
144 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
145 }
146
147 glProgramUniform4fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, &value[0]);
148 }
149
150 void OpenGLShaderProgram::SetMat2(const char* name, const glm::mat2& value) const {
151 if (!m_UniformLocations.contains(name)) {
152 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
153 }
154
155 glProgramUniformMatrix2fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, GL_FALSE, &value[0][0]);
156 }
157
158 void OpenGLShaderProgram::SetMat3(const char* name, const glm::mat3& value) const {
159 if (!m_UniformLocations.contains(name)) {
160 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
161 }
162
163 glProgramUniformMatrix3fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, GL_FALSE, &value[0][0]);
164 }
165
166 void OpenGLShaderProgram::SetMat4(const char* name, const glm::mat4& value) const {
167 if (!m_UniformLocations.contains(name)) {
168 m_UniformLocations.insert({ name, static_cast<int32_t>(glGetUniformLocation(m_ID, name)) });
169 }
170
171 glProgramUniformMatrix4fv(m_ID, static_cast<GLint>(m_UniformLocations.find(name)->second), 1, GL_FALSE, &value[0][0]);
172 }
173
174 bool OpenGLShaderProgram::CheckCompileErrors(const uint32_t shader, std::string type) {
175 GLint success;
176 GLchar infoLog[1024];
177 bool result = true;
178 if (type != "PROGRAM") {
179 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
180 if (!success) {
181 glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
182 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "(GL_RuntimeID: {0}): Shader compilation error in with shaders:\n{4}{1}\n{4}Problematic type: {2}\n{4}InfoLog: {3}", m_ID, m_ShaderNames, type, infoLog, CORI_SECOND_LINE_SPACING);
183 result = false;
184 }
185 }
186 else {
187 glGetProgramiv(shader, GL_LINK_STATUS, &success);
188 if (!success) {
189 glGetProgramInfoLog(shader, 1024, nullptr, infoLog);
190 CORI_CORE_ERROR_TAGGED({ Logger::Tags::Graphics::Self, Logger::Tags::Graphics::OpenGL, Logger::Tags::Graphics::ShaderProgram }, "(GL_RuntimeID: {0}): Shader linking error in with shaders:\n{4}{1}\n{4}Problematic type: {2}\n{4}InfoLog: {3}", m_ID, m_ShaderNames, type, infoLog, CORI_SECOND_LINE_SPACING);
191 result = false;
192 }
193 }
194 return result;
195 }
196 }
197 }
198}
const std::string CORI_SECOND_LINE_SPACING
Definition Logger.hpp:1001
#define CORI_CORE_ERROR_TAGGED(...)
Definition Logger.hpp:1039
#define CORI_CORE_INFO_TAGGED(...)
Definition Logger.hpp:1027
static std::string ReadTextFile(const std::filesystem::path &filepath)
Reads any file as a string.
void SetVec3(const char *name, const glm::vec3 &value) const override
void SetInt(const char *name, const int32_t value) const override
void SetMat4(const char *name, const glm::mat4 &value) const override
void SetBool(const char *name, const bool value) const override
void SetVec4(const char *name, const glm::vec4 &value) const override
void SetMat3(const char *name, const glm::mat3 &value) const override
void SetVec2(const char *name, const glm::vec2 &value) const override
OpenGLShaderProgram(const std::filesystem::path &vertexPath, const std::filesystem::path &fragmentPath, const std::filesystem::path &geometryPath)
void SetFloat(const char *name, const float value) const override
void SetMat2(const char *name, const glm::mat2 &value) const override
Almost everything connected to graphics is in this namespace.
Definition Window.hpp:7
Global engine namespace.
static constexpr char OpenGL[]
Definition Logger.hpp:49
static constexpr char ShaderProgram[]
Definition Logger.hpp:56
static constexpr char Self[]
Definition Logger.hpp:47