1414#include " ../resources/resources.h"
1515#include " gl.h"
1616
17+ #include < debugbreak.h>
18+
1719namespace renderer {
1820
21+ #ifndef SIM_GL_LOG_LEVEL
22+ #define SIM_GL_LOG_LEVEL 0
23+ #endif
24+
25+ inline constexpr int gl_log_level = SIM_GL_LOG_LEVEL;
26+
27+ template <typename ... Args> inline void gl_debug_printf (const char * fmt, Args&&... args) {
28+ if constexpr (gl_log_level > 0 ) {
29+ if constexpr (sizeof ...(Args)) printf (fmt, std::forward<Args>(args)...);
30+ else puts (fmt);
31+ }
32+ }
33+
34+ // #define gl_debug_printf(...)
35+
36+ constexpr std::string_view gl_error_to_sv (const uint32_t gl_error) {
37+ switch (gl_error) {
38+ case GL_NO_ERROR: return " GL_NO_ERROR" ;
39+ case GL_INVALID_ENUM: return " GL_INVALID_ENUM" ;
40+ case GL_INVALID_VALUE: return " GL_INVALID_VALUE" ;
41+ case GL_INVALID_OPERATION: return " GL_INVALID_OPERATION" ;
42+ case GL_INVALID_FRAMEBUFFER_OPERATION: return " GL_INVALID_FRAMEBUFFER_OPERATION" ;
43+ case GL_OUT_OF_MEMORY: return " GL_OUT_OF_MEMORY" ;
44+ default : return " Invalid return value from glGetError" ;
45+ }
46+ }
47+
48+ inline void gl_log_error () {
49+ if constexpr (gl_log_level == 0 ) {
50+ return ;
51+ } else {
52+ auto gl_error_value = glGetError ();
53+ if (gl_error_value == 0 ) return ;
54+ gl_debug_printf (" GL Error: [%d]: %s\n " , gl_error_value, std::string (gl_error_to_sv (gl_error_value)).c_str ());
55+ if constexpr (gl_log_level > 1 ) {
56+ debug_break ();
57+ }
58+ }
59+ }
60+
1961using mesh_id_t = size_t ;
2062class Mesh ;
2163extern mesh_id_t next_mesh_index;
@@ -71,32 +113,44 @@ class ShaderProgram {
71113
72114 GLuint shader_program = glCreateProgram ();
73115 glAttachShader (shader_program, vertex_shader);
116+ gl_log_error ();
74117 glAttachShader (shader_program, fragment_shader);
75- if (geometry_shader) glAttachShader (shader_program, geometry_shader);
118+ gl_log_error ();
119+ if (geometry_shader) {
120+ glAttachShader (shader_program, geometry_shader);
121+ gl_log_error ();
122+ }
76123
77124 glLinkProgram (shader_program);
125+ gl_log_error ();
78126
79127 GLint result = 0 ;
80128 glGetProgramiv (shader_program, GL_LINK_STATUS, &result);
81129 if (result == GL_TRUE) {
82130 glUseProgram (shader_program);
131+ gl_debug_printf (" ShaderProgram::load_program: shader program(%d) linked and activated\n " , shader_program);
132+ gl_log_error ();
83133 } else {
84134 glDeleteProgram (shader_program);
85135 shader_program = 0 ;
136+ gl_debug_printf (" ShaderProgram::load_program: unable to link shaders\n " );
86137 }
87138
88139 if (vertex_shader) glDeleteShader (vertex_shader);
89140 if (fragment_shader) glDeleteShader (fragment_shader);
90141 if (geometry_shader) glDeleteShader (geometry_shader);
91142
143+ gl_log_error ();
92144 return shader_program;
93145 }
94146
95147 static GLuint load_shader (GLuint shader_type, char const * shader_string) {
96148 GLuint shader_id = glCreateShader (shader_type);
97149 int length = strlen (shader_string);
98150 glShaderSource (shader_id, 1 , (GLchar const **)&shader_string, &length);
151+ gl_log_error ();
99152 glCompileShader (shader_id);
153+ gl_log_error ();
100154
101155 GLint status;
102156 glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
@@ -106,10 +160,11 @@ class ShaderProgram {
106160 std::vector<GLchar> errorLog (maxLength + 1 );
107161 errorLog[maxLength] = 0 ;
108162 glGetShaderInfoLog (shader_id, maxLength, &maxLength, errorLog.data ());
109- printf (" %s\n " , errorLog.data ());
163+ gl_debug_printf (" %s\n " , errorLog.data ());
110164 glDeleteShader (shader_id);
111165 return 0 ;
112166 }
167+ gl_log_error ();
113168 return shader_id;
114169 }
115170
@@ -143,6 +198,7 @@ class ShaderProgram {
143198 }
144199
145200 void build_cache () {
201+ gl_debug_printf (" ShaderProgram::build_cache\n " );
146202 GLint size {}; // size of the variable
147203 GLenum type {}; // type of the variable (float, vec3 or mat4, etc)
148204
@@ -155,19 +211,31 @@ class ShaderProgram {
155211 attr.second .active = false ; // disable all current attributes for reload
156212 }
157213 glGetProgramiv (m_program_id, GL_ACTIVE_ATTRIBUTES, &attribute_count);
214+ gl_debug_printf (" attribute:\n " );
215+ gl_log_error ();
158216 for (GLint i = 0 ; i < attribute_count; i++) {
159217 glGetActiveAttrib (m_program_id, (GLuint)i, bufSize, &length, &size, &type, (char *)name);
160- m_attributes[name] = shader_attr_t {(uint32_t )i, name, type, size};
218+ gl_log_error ();
219+ auto attrib_loc = glGetAttribLocation (m_program_id, name);
220+ gl_log_error ();
221+ gl_debug_printf (" index: %d, location: %d, name: %s, type: %d, size: %d\n " , i, attrib_loc, name, type, size);
222+ m_attributes[name] = shader_attr_t {(uint32_t )attrib_loc, name, type, size};
161223 }
162224
163225 GLint uniform_count;
164226 for (auto & uniform : m_uniforms) {
165227 uniform.second .active = false ; // disable all current uniforms for reload
166228 }
167229 glGetProgramiv (m_program_id, GL_ACTIVE_UNIFORMS, &uniform_count);
230+ gl_debug_printf (" uniform:\n " );
231+ gl_log_error ();
168232 for (GLint i = 0 ; i < uniform_count; i++) {
169233 glGetActiveUniform (m_program_id, (GLuint)i, bufSize, &length, &size, &type, (char *)name);
170- m_uniforms[name] = shader_attr_t {(uint32_t )i, name, type, size};
234+ gl_log_error ();
235+ auto uniform_loc = glGetUniformLocation (m_program_id, name);
236+ gl_log_error ();
237+ gl_debug_printf (" index: %d, location: %d, name: %s, type: %d, size: %d\n " , i, uniform_loc, name, type, size);
238+ m_uniforms[name] = shader_attr_t {(uint32_t )uniform_loc, name, type, size};
171239 }
172240 }
173241
@@ -190,14 +258,19 @@ class ShaderProgramInstance {
190258 };
191259
192260 void bind_immediate () {
261+ gl_log_error ();
262+ if (m_program == nullptr ) return ;
193263 glUseProgram (m_program->m_program_id );
264+ gl_log_error ();
194265 for (auto & [location, uniform] : m_uniforms) {
195266 uniform.gl_uniform_call (uniform.desc , uniform.uniform_data );
196267 }
197268 }
198269
199270 template <typename T> void set_uniform (std::string name, T* value) {
200- using gl_uniform_type = gl_uniform<type_to_gl_enum<T>::value>;
271+ using gl_uniform_type = gl_uniform<type_to_gl_enum<T>::value>;
272+ if (m_program == nullptr ) return ;
273+ if (!m_program->m_uniforms .count (name)) return ;
201274 auto uniform = m_program->m_uniforms [name];
202275 m_uniforms[uniform.location ] = shader_uniform_t {
203276 uniform,
@@ -210,6 +283,7 @@ class ShaderProgramInstance {
210283 } else {
211284 gl_uniform_type ().invoke (uniform_desc.location , uniform_desc.size , glm::value_ptr (*std::get<gl_uniform_type>(uniform_data).value ));
212285 }
286+ gl_log_error ();
213287 },
214288 };
215289 return ;
@@ -242,14 +316,20 @@ template<typename ElementType> class Buffer : public BufferBase {
242316public:
243317 virtual void generate () override {
244318 glGenVertexArrays (1 , &m_vao);
319+ gl_log_error ();
245320 glGenBuffers (1 , &m_vbo);
321+ gl_log_error ();
246322 glBindVertexArray (m_vao);
323+ gl_log_error ();
247324 glBindBuffer (GL_ARRAY_BUFFER, m_vbo);
325+ gl_log_error ();
248326
249327 size_t index = 0 , offset = 0 ;
250328 for (auto & attrib : ElementType::descriptor) {
251329 glEnableVertexAttribArray (index);
330+ gl_log_error ();
252331 glVertexAttribPointer (index, attrib.elements , attrib.gl_enum , GL_FALSE, sizeof (ElementType), (void *)offset);
332+ gl_log_error ();
253333 ++index;
254334 offset += attrib.length ;
255335 }
@@ -272,13 +352,16 @@ template<typename ElementType> class Buffer : public BufferBase {
272352 if (!m_generated) generate ();
273353 if (m_vao == 0 || m_vbo == 0 ) return false ;
274354 glBindVertexArray (m_vao);
355+ gl_log_error ();
275356 glBindBuffer (GL_ARRAY_BUFFER, m_vbo);
357+ gl_log_error ();
276358 return true ;
277359 }
278360
279361 virtual void upload () override {
280362 if (m_dirty && m_data.size () > 0 ) {
281363 glBufferData (GL_ARRAY_BUFFER, m_data.size () * sizeof (ElementType), &m_data[0 ], m_storage_hint);
364+ gl_log_error ();
282365 m_dirty = false ;
283366 }
284367 }
@@ -287,6 +370,7 @@ template<typename ElementType> class Buffer : public BufferBase {
287370 if (bind ()) {
288371 upload ();
289372 glDrawArrays ((GLenum)m_geometry_type, m_geometry_offset, m_data.size ());
373+ gl_log_error ();
290374 }
291375 }
292376
@@ -381,7 +465,7 @@ class Mesh {
381465 bool m_shader_dirty = true ;
382466 bool m_delete = false ;
383467 std::vector<std::shared_ptr<BufferBase>> m_buffer {};
384- std::shared_ptr<ShaderProgramInstance> m_shader_instance = 0 ;
468+ std::shared_ptr<ShaderProgramInstance> m_shader_instance {} ;
385469
386470private:
387471 Mesh () { }
0 commit comments