6#include <brenta/gl.hpp>
7#include <brenta/logger.hpp>
8#include <brenta/window.hpp>
9#include <brenta/text.hpp>
13using namespace brenta;
19const std::string gl::subsystem_name =
"gl";
27bool gl::initialized =
false;
30void APIENTRY glDebugOutput([[maybe_unused]] GLenum source,
31 [[maybe_unused]] GLenum type,
32 [[maybe_unused]] GLuint
id,
33 [[maybe_unused]] GLenum severity,
34 [[maybe_unused]] GLsizei length,
35 [[maybe_unused]]
const GLchar *message,
36 [[maybe_unused]]
const void *userParam);
42std::expected<void, subsystem::error> gl::initialize()
47 if (!gladLoadGLLoader(loadproc))
49 ERROR(
"{}: failed to initialize GLAD", gl::subsystem_name);
50 return std::unexpected(
"Failed to initialize GLAD");
53 int width = window::get_width();
54 int height = window::get_height();
56 glViewport(0, 0, width, height);
58 if (gl::init_config.enable_depth_test)
60 glEnable(GL_DEPTH_TEST);
61 INFO(
"{}: enabled GL_DEPTH_TEST", gl::subsystem_name);
64 if (gl::init_config.enable_blending)
67 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
68 INFO(
"{}: enabled GL_BLEND (transparency)", gl::subsystem_name);
71 if (gl::init_config.enable_cull_face)
73 glEnable(GL_CULL_FACE);
74 INFO(
"{}: enabled GL_CULL_FACE", gl::subsystem_name);
77 if (gl::init_config.enable_multisample)
79 glEnable(GL_MULTISAMPLE);
80 INFO(
"{}: enabled GL_MULTISAMPLE", gl::subsystem_name);
84 glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
85 if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
88 glEnable(GL_DEBUG_OUTPUT);
89 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
90 glDebugMessageCallback(glDebugOutput,
nullptr);
91 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE,
93 INFO(
"{}: configured GL_DEBUG_OUTPUT", gl::subsystem_name);
96 GLenum errcode = gl::check_error();
97 if (errcode != GL_NO_ERROR)
99 return std::unexpected(
"GL error");
102 gl::initialized =
true;
103 INFO(
"{}: initialized", gl::subsystem_name);
107std::expected<void, subsystem::error> gl::terminate()
111 gl::initialized =
false;
112 INFO(
"{}: terminated", gl::subsystem_name);
118 return gl::subsystem_name;
123 return gl::initialized;
134 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
135 INFO(
"{}: enabled GL_POLYGON_MODE (wireframe)", gl::subsystem_name);
139 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
140 INFO(
"{}: disabled GL_POLYGON_MODE (fill)", gl::subsystem_name);
152 glViewport(x, y, width, height);
157 glClearColor(r, g, b, a);
162 glDrawArrays(mode, first, count);
167 glDrawElements(mode, count, type, indices);
170void gl::bind_vertex_array(
unsigned int n)
172 glBindVertexArray(n);
177 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
183 while ((errorCode = glGetError()) != GL_NO_ERROR)
185 std::string error =
"";
188 case GL_INVALID_ENUM: error =
"invalid enum";
break;
189 case GL_INVALID_VALUE: error =
"invalid value";
break;
190 case GL_INVALID_OPERATION: error =
"invalid operation";
break;
191 case GL_STACK_OVERFLOW: error =
"stack overflow";
break;
192 case GL_STACK_UNDERFLOW: error =
"stack underflow";
break;
193 case GL_OUT_OF_MEMORY: error =
"out of memory";
break;
194 case GL_INVALID_FRAMEBUFFER_OPERATION:
195 error =
"invalid framebuffer operation";
break;
196 default: error =
"unknown error";
break;
199 error +=
" | " + std::string(file) +
" (" + std::to_string(line) +
")";
200 ERROR(
"{}: {}", gl::subsystem_name, error);
209void APIENTRY glDebugOutput([[maybe_unused]] GLenum source,
210 [[maybe_unused]] GLenum type,
211 [[maybe_unused]] GLuint
id,
212 [[maybe_unused]] GLenum severity,
213 [[maybe_unused]] GLsizei length,
214 [[maybe_unused]]
const GLchar *message,
215 [[maybe_unused]]
const void *userParam)
218 if(
id == 131169 ||
id == 131185 ||
id == 131218 ||
id == 131204)
return;
220 std::stringstream out;
221 out <<
"Debug message (" <<
id <<
"): " << message << std::endl;
225 case GL_DEBUG_SOURCE_API:
226 out <<
"Source: API";
break;
227 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
228 out <<
"Source: Window System";
break;
229 case GL_DEBUG_SOURCE_SHADER_COMPILER:
230 out <<
"Source: Shader Compiler";
break;
231 case GL_DEBUG_SOURCE_THIRD_PARTY:
232 out <<
"Source: Third Party";
break;
233 case GL_DEBUG_SOURCE_APPLICATION:
234 out <<
"Source: Application";
break;
235 case GL_DEBUG_SOURCE_OTHER:
236 out <<
"Source: Other";
break;
241 case GL_DEBUG_TYPE_ERROR:
242 out <<
"Type: Error";
break;
243 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
244 out <<
"Type: Deprecated Behaviour";
break;
245 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
246 out <<
"Type: Undefined Behaviour";
break;
247 case GL_DEBUG_TYPE_PORTABILITY:
248 out <<
"Type: Portability";
break;
249 case GL_DEBUG_TYPE_PERFORMANCE:
250 out <<
"Type: Performance";
break;
251 case GL_DEBUG_TYPE_MARKER:
252 out <<
"Type: Marker";
break;
253 case GL_DEBUG_TYPE_PUSH_GROUP:
254 out <<
"Type: Push Group";
break;
255 case GL_DEBUG_TYPE_POP_GROUP:
256 out <<
"Type: Pop Group";
break;
257 case GL_DEBUG_TYPE_OTHER:
258 out <<
"Type: Other";
break;
263 case GL_DEBUG_SEVERITY_HIGH:
264 out <<
"Severity: high";
break;
265 case GL_DEBUG_SEVERITY_MEDIUM:
266 out <<
"Severity: medium";
break;
267 case GL_DEBUG_SEVERITY_LOW:
268 out <<
"Severity: low";
break;
269 case GL_DEBUG_SEVERITY_NOTIFICATION:
270 out <<
"Severity: notification";
break;
274 ERROR(
"{}: {}", gl::subsystem_name, out.str());
283 this->conf.enable_blending =
true;
289 this->conf.enable_cull_face =
true;
295 this->conf.enable_multisample =
true;
301 this->conf.enable_depth_test =
true;
307 gl::init_config = this->conf;
308 return gl::instance();
static void set_color(float r, float g, float b, float a)
Set Clear Color.
static GLenum _check_error(const char *file, int line)
Check OpenGL error.
static void clear()
Clear.
std::string name() override
Returns the name of the sybsystem.
static void set_poligon_mode(GLboolean enable)
Set Poligon Mode.
static void draw_elements(GLenum mode, int count, GLenum type, const void *indices)
Draw Elements.
bool is_initialized() override
Returns true if the subsystem is initialized.
static void set_viewport(int x, int y, int width, int height)
Set Viewport.
static void draw_arrays(GLenum mode, int first, int count)
Draw Arrays.
static GLFWglproc get_proc_address()
Get the OpenGL function pointer.