A 3D game engine from scratch.
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
2
3#pragma once
4
5#include "logs.hpp"
6#include "glutil.hpp"
7
8
9char const *
10glutil::stringify_glenum(GLenum thing)
11{
12 switch (thing) {
13 case 0:
14 return "(none)";
15 case GL_BYTE:
16 return "GLbyte";
17 case GL_UNSIGNED_BYTE:
18 return "GLubyte";
19 case GL_SHORT:
20 return "GLshort";
21 case GL_UNSIGNED_SHORT:
22 return "GLushort";
23 case GL_INT:
24 return "GLint";
25 case GL_UNSIGNED_INT:
26 return "GLuint";
27 case GL_HALF_FLOAT:
28 return "GLhalf";
29 case GL_FLOAT:
30 return "GLfloat";
31 case GL_DOUBLE:
32 return "GLdouble";
33 case GL_RGB8:
34 return "GL_RGB8";
35 case GL_RGBA8:
36 return "GL_RGBA8";
37 case GL_SRGB8:
38 return "GL_SRGB8";
39 case GL_UNSIGNED_INT_8_8_8_8:
40 return "GL_UNSIGNED_INT_8_8_8_8";
41 case GL_UNSIGNED_INT_8_8_8_8_REV:
42 return "GL_UNSIGNED_INT_8_8_8_8_REV";
43 case GL_DEPTH_COMPONENT:
44 return "GL_DEPTH_COMPONENT";
45 case GL_DEPTH_STENCIL:
46 return "GL_DEPTH_STENCIL";
47 case GL_RED:
48 return "GL_RED";
49 case GL_RGB:
50 return "GL_RGB";
51 case GL_RGBA:
52 return "GL_RGBA";
53 default:
54 logs::warning("Unknown GLenum %d", thing);
55 return "Unknown GLenum";
56 }
57}
58
59
60GLenum
61glutil::get_texture_format_from_n_components(i32 n_components)
62{
63 if (n_components == 1) {
64 return GL_RED;
65 } else if (n_components == 3) {
66 return GL_BGR;
67 } else if (n_components == 4) {
68 return GL_BGRA;
69 } else {
70 logs::fatal("Don't know what to do with n_components = %d", n_components);
71 return 0;
72 }
73}
74
75
76void
77glutil::print_texture_internalformat_info(GLenum internal_format)
78{
79 if (!GLAD_GL_ARB_internalformat_query) {
80 logs::warning("Not printing texture_internalformat as this feature is not supported on this system.");
81 return;
82 }
83
84 if (!GLAD_GL_ARB_internalformat_query2) {
85 logs::warning("Printing texture_internalformat, but some information may be missing, as internalformat_query2 is not supported on this system.");
86 }
87
88 GLint preferred_format;
89 GLint optimal_image_format;
90 GLint optimal_image_type;
91
92 glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_INTERNALFORMAT_PREFERRED, 1, &preferred_format);
93 glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_FORMAT, 1, &optimal_image_format);
94 glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_TYPE, 1, &optimal_image_type);
95
96 logs::info("internal format: %s", stringify_glenum(internal_format));
97 logs::info("preferred format: %s", stringify_glenum(preferred_format));
98 logs::info("optimal image format: %s", stringify_glenum(optimal_image_format));
99 logs::info("optimal image type: %s", stringify_glenum(optimal_image_type));
100 logs::print_newline();
101}
102
103
104void APIENTRY
105glutil::debug_message_callback(
106 GLenum source,
107 GLenum type,
108 unsigned int id,
109 GLenum severity,
110 GLsizei length,
111 char const *message,
112 const void *userParam
113) {
114 // Ignore insignificant error/warning codes
115 if (
116 // Framebuffer detailed info: The driver allocated storage for
117 // renderbuffer 1.
118 id == 131169 ||
119 // Program/shader state performance warning: Vertex shader in program 19
120 // is being recompiled based on GL state.
121 id == 131218 ||
122 // Buffer detailed info: Buffer object 1522 (bound to
123 // GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), and GL_ARRAY_BUFFER_ARB,
124 // usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for
125 // buffer object operations.
126 id == 131185 ||
127 // Texture state usage warning: The texture object (0) bound to texture
128 // image unit 4 does not have a defined base level and cannot be used for
129 // texture mapping.
130 id == 131204 ||
131 // Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering.
132 id == 131154
133 ) {
134 return;
135 }
136
137 logs::warning("Debug message (%d): %s", id, message);
138
139 switch (source) {
140 case GL_DEBUG_SOURCE_API:
141 logs::warning("Source: API");
142 break;
143 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
144 logs::warning("Source: Window System");
145 break;
146 case GL_DEBUG_SOURCE_SHADER_COMPILER:
147 logs::warning("Source: Shader Compiler");
148 break;
149 case GL_DEBUG_SOURCE_THIRD_PARTY:
150 logs::warning("Source: Third Party");
151 break;
152 case GL_DEBUG_SOURCE_APPLICATION:
153 logs::warning("Source: Application");
154 break;
155 case GL_DEBUG_SOURCE_OTHER:
156 logs::warning("Source: Other");
157 break;
158 }
159
160 switch (type) {
161 case GL_DEBUG_TYPE_ERROR:
162 logs::warning("Type: Error");
163 break;
164 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
165 logs::warning("Type: Deprecated Behaviour");
166 break;
167 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
168 logs::warning("Type: Undefined Behaviour");
169 break;
170 case GL_DEBUG_TYPE_PORTABILITY:
171 logs::warning("Type: Portability");
172 break;
173 case GL_DEBUG_TYPE_PERFORMANCE:
174 logs::warning("Type: Performance");
175 break;
176 case GL_DEBUG_TYPE_MARKER:
177 logs::warning("Type: Marker");
178 break;
179 case GL_DEBUG_TYPE_PUSH_GROUP:
180 logs::warning("Type: Push Group");
181 break;
182 case GL_DEBUG_TYPE_POP_GROUP:
183 logs::warning("Type: Pop Group");
184 break;
185 case GL_DEBUG_TYPE_OTHER:
186 logs::warning("Type: Other");
187 break;
188 }
189
190 switch (severity) {
191 case GL_DEBUG_SEVERITY_HIGH:
192 logs::warning("Severity: high");
193 break;
194 case GL_DEBUG_SEVERITY_MEDIUM:
195 logs::warning("Severity: medium");
196 break;
197 case GL_DEBUG_SEVERITY_LOW:
198 logs::warning("Severity: low");
199 break;
200 case GL_DEBUG_SEVERITY_NOTIFICATION:
201 logs::warning("Severity: notification");
202 break;
203 }
204
205 logs::print_newline();
206}