32 static constexpr GLenum stencil_face_lut[] =
40 static constexpr GLenum stencil_op_lut[] =
52 static constexpr GLenum compare_op_lut[] =
64 static constexpr GLenum provoking_vertex_mode_lut[] =
66 GL_FIRST_VERTEX_CONVENTION,
67 GL_LAST_VERTEX_CONVENTION
70 static constexpr GLenum primitive_topology_lut[] =
79 GL_LINE_STRIP_ADJACENCY,
80 GL_TRIANGLES_ADJACENCY,
81 GL_TRIANGLE_STRIP_ADJACENCY,
85 static constexpr GLenum logic_op_lut[] =
105 static constexpr GLenum blend_factor_lut[] =
110 GL_ONE_MINUS_SRC_COLOR ,
112 GL_ONE_MINUS_DST_COLOR ,
114 GL_ONE_MINUS_SRC_ALPHA ,
116 GL_ONE_MINUS_DST_ALPHA ,
118 GL_ONE_MINUS_CONSTANT_COLOR,
120 GL_ONE_MINUS_CONSTANT_ALPHA,
121 GL_SRC_ALPHA_SATURATE ,
123 GL_ONE_MINUS_SRC1_COLOR ,
125 GL_ONE_MINUS_SRC1_ALPHA
128 static constexpr GLenum blend_op_lut[] =
132 GL_FUNC_REVERSE_SUBTRACT,
137 void gl_debug_message_callback(GLenum source, GLenum
type, GLuint
id, GLenum severity, GLsizei
length,
const GLchar* message,
const void* user_param)
139 const auto src_str = [source]() ->
const char*
143 case GL_DEBUG_SOURCE_API:
145 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
146 return "window system";
147 case GL_DEBUG_SOURCE_SHADER_COMPILER:
148 return "shader compiler";
149 case GL_DEBUG_SOURCE_THIRD_PARTY:
150 return "third party";
151 case GL_DEBUG_SOURCE_APPLICATION:
152 return "application";
153 case GL_DEBUG_SOURCE_OTHER:
159 const auto type_str = [
type]() ->
const char*
163 case GL_DEBUG_TYPE_ERROR:
165 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
166 return "deprecated behavior";
167 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
168 return "undefined behavior";
169 case GL_DEBUG_TYPE_PORTABILITY:
170 return "portability";
171 case GL_DEBUG_TYPE_PERFORMANCE:
172 return "performance";
173 case GL_DEBUG_TYPE_MARKER:
175 case GL_DEBUG_TYPE_OTHER:
181 const auto severity_str = [severity]() ->
const char*
185 case GL_DEBUG_SEVERITY_LOW:
186 return "low severity";
187 case GL_DEBUG_SEVERITY_MEDIUM:
188 return "medium severity";
189 case GL_DEBUG_SEVERITY_HIGH:
190 return "high severity";
191 case GL_DEBUG_SEVERITY_NOTIFICATION:
193 return "notification";
199 case GL_DEBUG_TYPE_ERROR:
201 std::string formatted_message;
202 std::format_to(std::back_inserter(formatted_message),
"OpenGL {} {} ({}) {}: {}", src_str, type_str, severity_str,
id, message);
204 throw std::runtime_error(formatted_message);
208 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
209 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
210 debug::log_error(
"OpenGL {} {} ({}) {}: {}", src_str, type_str, severity_str,
id, message);
213 case GL_DEBUG_TYPE_PORTABILITY:
214 case GL_DEBUG_TYPE_PERFORMANCE:
215 debug::log_warning(
"OpenGL {} {} ({}) {}: {}", src_str, type_str, severity_str,
id, message);
218 case GL_DEBUG_TYPE_MARKER:
219 case GL_DEBUG_TYPE_OTHER:
221 debug::log_debug(
"OpenGL {} {} ({}) {}: {}", src_str, type_str, severity_str,
id, message);
232 glEnable(GL_DEBUG_OUTPUT);
233 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
234 glDebugMessageCallback(gl_debug_message_callback,
nullptr);
238 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_max_sampler_anisotropy);
241 GLint gl_scissor_box[4] = {0, 0, 0, 0};
242 glGetIntegerv(GL_SCISSOR_BOX, gl_scissor_box);
243 m_default_framebuffer_dimensions[0] =
static_cast<std::uint32_t
>(gl_scissor_box[2]);
244 m_default_framebuffer_dimensions[1] =
static_cast<std::uint32_t
>(gl_scissor_box[3]);
247 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
250 glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
253 glDisable(GL_MULTISAMPLE);
256 glPixelStorei(GL_PACK_ALIGNMENT, 1);
257 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
260 fetch_vertex_input_state();
261 fetch_input_assembly_state();
262 fetch_viewport_state();
263 fetch_rasterization_state();
264 fetch_depth_stencil_state();
265 fetch_color_blend_state();
283 glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer->m_gl_named_framebuffer);
287 glBindFramebuffer(GL_FRAMEBUFFER, 0);
298 if (m_shader_program)
300 glUseProgram(m_shader_program->gl_program_id);
311 if (m_vertex_array !=
array)
313 m_vertex_array =
array;
317 glBindVertexArray(m_vertex_array->m_gl_named_array);
321 glBindVertexArray(0);
326 void pipeline::bind_vertex_buffers(std::uint32_t first_binding, std::span<const vertex_buffer* const> buffers, std::span<const std::size_t> offsets, std::span<const std::size_t> strides)
330 throw std::runtime_error(
"Failed to bind vertex buffer: no vertex array bound.");
333 if (offsets.size() < buffers.size())
335 throw std::out_of_range(
"Vertex binding offset out of range.");
338 if (strides.size() < buffers.size())
340 throw std::out_of_range(
"Vertex binding stride out of range.");
343 for (std::size_t i = 0; i < buffers.size(); ++i)
345 glVertexArrayVertexBuffer
347 m_vertex_array->m_gl_named_array,
348 static_cast<GLuint
>(first_binding + i),
349 buffers[i]->m_gl_named_buffer,
350 static_cast<GLintptr
>(offsets[i]),
351 static_cast<GLsizei
>(strides[i])
358 if (m_input_assembly_state.
topology != topology)
360 m_input_assembly_state.
topology = topology;
370 glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
374 glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
384 if (first_viewport + viewports.size() > m_max_viewports)
386 throw std::out_of_range(
"Viewport index out of range.");
390 if (!viewports.size())
395 const auto& active_viewport = m_viewport_state.
viewports.front();
396 const auto&
viewport = viewports.front();
421 std::copy(viewports.begin(), viewports.end(), m_viewport_state.
viewports.begin() + first_viewport);
427 if (first_scissor + scissors.size() > m_max_viewports)
429 throw std::out_of_range(
"Scissor region index out of range.");
433 if (scissors.empty())
438 const auto& active_scissor = m_viewport_state.
scissors.front();
439 const auto& scissor = scissors.front();
442 if (active_scissor.width != scissor.width ||
443 active_scissor.height != scissor.height ||
444 active_scissor.x != scissor.x ||
445 active_scissor.y != scissor.y)
449 static_cast<GLint
>(scissor.x),
450 static_cast<GLint
>(scissor.y),
451 std::max(0,
static_cast<GLsizei
>(scissor.width)),
452 std::max(0,
static_cast<GLsizei
>(scissor.height))
457 std::copy(scissors.begin(), scissors.end(), m_viewport_state.
scissors.begin() + first_scissor);
466 glEnable(GL_RASTERIZER_DISCARD);
470 glDisable(GL_RASTERIZER_DISCARD);
479 if (m_rasterization_state.
fill_mode != mode)
484 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
488 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
492 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
505 if (m_rasterization_state.
cull_mode != mode)
509 glDisable(GL_CULL_FACE);
515 glEnable(GL_CULL_FACE);
525 glCullFace(GL_FRONT);
529 glCullFace(GL_FRONT_AND_BACK);
557 glEnable(GL_POLYGON_OFFSET_FILL);
558 glEnable(GL_POLYGON_OFFSET_LINE);
559 glEnable(GL_POLYGON_OFFSET_POINT);
563 glDisable(GL_POLYGON_OFFSET_FILL);
564 glDisable(GL_POLYGON_OFFSET_LINE);
565 glDisable(GL_POLYGON_OFFSET_POINT);
578 glPolygonOffset(slope_factor, constant_factor);
591 glEnable(GL_DEPTH_CLAMP);
595 glDisable(GL_DEPTH_CLAMP);
608 glEnable(GL_SCISSOR_TEST);
612 glDisable(GL_SCISSOR_TEST);
623 const auto gl_provoking_vertex_mode = provoking_vertex_mode_lut[std::to_underlying(mode)];
624 glProvokingVertex(gl_provoking_vertex_mode);
641 if (m_rasterization_state.
line_width != width)
657 glEnable(GL_DEPTH_TEST);
661 glDisable(GL_DEPTH_TEST);
671 glDepthMask(enabled);
680 const auto gl_compare_op = compare_op_lut[std::to_underlying(
compare_op)];
681 glDepthFunc(gl_compare_op);
693 glEnable(GL_STENCIL_TEST);
697 glDisable(GL_STENCIL_TEST);
704 bool stencil_op_updated =
false;
705 bool compare_op_updated =
false;
716 stencil_op_updated =
true;
722 compare_op_updated =
true;
735 stencil_op_updated =
true;
741 compare_op_updated =
true;
745 if (stencil_op_updated || compare_op_updated)
747 const auto gl_face = stencil_face_lut[face_mask];
749 if (stencil_op_updated)
751 const auto gl_fail_op = stencil_op_lut[std::to_underlying(fail_op)];
752 const auto gl_pass_op = stencil_op_lut[std::to_underlying(pass_op)];
753 const auto gl_depth_fail_op = stencil_op_lut[std::to_underlying(depth_fail_op)];
754 glStencilOpSeparate(gl_face, gl_fail_op, gl_depth_fail_op, gl_pass_op);
757 if (compare_op_updated)
759 const auto gl_compare_op = compare_op_lut[std::to_underlying(
compare_op)];
788 bool compare_mask_updated =
false;
795 compare_mask_updated =
true;
804 compare_mask_updated =
true;
808 if (compare_mask_updated)
810 const auto gl_face = stencil_face_lut[face_mask];
818 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(m_depth_stencil_state.
stencil_front.
reference),
static_cast<GLuint
>(compare_mask));
822 const auto gl_compare_op_front = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_front.
compare_op)];
823 const auto gl_compare_op_back = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_back.
compare_op)];
824 glStencilFuncSeparate(GL_FRONT, gl_compare_op_front, std::bit_cast<GLint>(m_depth_stencil_state.
stencil_front.
reference), std::bit_cast<GLuint>(compare_mask));
825 glStencilFuncSeparate(GL_BACK, gl_compare_op_back, std::bit_cast<GLint>(m_depth_stencil_state.
stencil_back.
reference), std::bit_cast<GLuint>(compare_mask));
831 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(m_depth_stencil_state.
stencil_front.
reference), std::bit_cast<GLuint>(compare_mask));
835 const auto gl_compare_op = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_back.
compare_op)];
836 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(m_depth_stencil_state.
stencil_back.
reference), std::bit_cast<GLuint>(compare_mask));
843 bool reference_updated =
false;
850 reference_updated =
true;
859 reference_updated =
true;
863 if (reference_updated)
865 const auto gl_face = stencil_face_lut[face_mask];
873 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(reference), std::bit_cast<GLuint>(m_depth_stencil_state.
stencil_front.
compare_mask));
877 const auto gl_compare_op_front = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_front.
compare_op)];
878 const auto gl_compare_op_back = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_back.
compare_op)];
879 glStencilFuncSeparate(GL_FRONT, gl_compare_op_front, std::bit_cast<GLint>(reference), std::bit_cast<GLuint>(m_depth_stencil_state.
stencil_front.
compare_mask));
880 glStencilFuncSeparate(GL_BACK, gl_compare_op_back, std::bit_cast<GLint>(reference), std::bit_cast<GLuint>(m_depth_stencil_state.
stencil_back.
compare_mask));
886 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(reference), std::bit_cast<GLuint>(m_depth_stencil_state.
stencil_front.
compare_mask));
890 const auto gl_compare_op = compare_op_lut[std::to_underlying(m_depth_stencil_state.
stencil_back.
compare_op)];
891 glStencilFuncSeparate(gl_face, gl_compare_op, std::bit_cast<GLint>(reference), std::bit_cast<GLuint>(m_depth_stencil_state.
stencil_back.
compare_mask));
898 bool write_mask_updated =
false;
905 write_mask_updated =
true;
914 write_mask_updated =
true;
918 if (write_mask_updated)
920 const auto gl_face = stencil_face_lut[face_mask];
921 glStencilMaskSeparate(gl_face, std::bit_cast<GLuint>(write_mask));
933 glEnable(GL_COLOR_LOGIC_OP);
937 glDisable(GL_COLOR_LOGIC_OP);
948 const auto gl_logic_op = logic_op_lut[std::to_underlying(
logic_op)];
949 glLogicOp(gl_logic_op);
987 glBlendFuncSeparate(gl_src_rgb, gl_dst_rgb, gl_src_alpha, gl_dst_alpha);
996 const auto gl_mode_rgb = blend_op_lut[std::to_underlying(equation.
color_blend_op)];
997 const auto gl_mode_alpha = blend_op_lut[std::to_underlying(equation.
alpha_blend_op)];
999 glBlendEquationSeparate(gl_mode_rgb, gl_mode_alpha);
1024 glBlendColor(blend_constants[0], blend_constants[1], blend_constants[2], blend_constants[3]);
1028 void pipeline::draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance)
1030 glDrawArraysInstancedBaseInstance
1032 primitive_topology_lut[std::to_underlying(m_input_assembly_state.
topology)],
1033 static_cast<GLint
>(first_vertex),
1034 static_cast<GLsizei
>(vertex_count),
1035 static_cast<GLsizei
>(instance_count),
1036 static_cast<GLuint
>(first_instance)
1040 void pipeline::draw_indexed(std::uint32_t index_count, std::uint32_t instance_count, std::uint32_t first_index, std::int32_t vertex_offset, std::uint32_t first_instance)
1042 glDrawElementsInstancedBaseInstance
1044 primitive_topology_lut[std::to_underlying(m_input_assembly_state.
topology)],
1045 static_cast<GLsizei
>(instance_count),
1047 reinterpret_cast<const GLvoid*
>(first_index *
sizeof(
unsigned int)),
1048 static_cast<GLsizei
>(instance_count),
1049 static_cast<GLuint
>(first_instance)
1055 GLbitfield gl_clear_mask = 0;
1060 gl_clear_mask |= GL_COLOR_BUFFER_BIT;
1073 gl_clear_mask |= GL_DEPTH_BUFFER_BIT;
1078 glClearDepth(value.
depth);
1086 gl_clear_mask |= GL_STENCIL_BUFFER_BIT;
1091 glClearStencil(
static_cast<GLint
>(value.
stencil));
1097 glClear(gl_clear_mask);
1100 void pipeline::defaut_framebuffer_resized(std::uint32_t width, std::uint32_t height) noexcept
1102 m_default_framebuffer_dimensions = {width, height};
1105 void pipeline::fetch_vertex_input_state()
1109 void pipeline::fetch_input_assembly_state()
1114 void pipeline::fetch_viewport_state()
1117 GLint gl_viewport[4];
1118 glGetIntegerv(GL_VIEWPORT, gl_viewport);
1121 GLfloat gl_depth_range[2];
1122 glGetFloatv(GL_DEPTH_RANGE, gl_depth_range);
1125 GLint gl_scissor_box[4] = {0, 0, 0, 0};
1126 glGetIntegerv(GL_SCISSOR_BOX, gl_scissor_box);
1131 static_cast<float>(gl_viewport[0]),
1132 static_cast<float>(gl_viewport[1]),
1133 static_cast<float>(gl_viewport[2]),
1134 static_cast<float>(gl_viewport[3]),
1140 static_cast<std::int32_t
>(gl_scissor_box[0]),
1141 static_cast<std::int32_t
>(gl_scissor_box[1]),
1142 static_cast<std::uint32_t
>(
std::max(0, gl_scissor_box[2])),
1143 static_cast<std::uint32_t
>(
std::max(0, gl_scissor_box[3]))
1147 void pipeline::fetch_rasterization_state()
1150 bool gl_rasterizer_discard_enabled = glIsEnabled(GL_RASTERIZER_DISCARD);
1154 glGetIntegerv(GL_POLYGON_MODE, &gl_fill_mode);
1157 bool gl_cull_enabled = glIsEnabled(GL_CULL_FACE);
1159 glGetIntegerv(GL_CULL_FACE_MODE, &gl_cull_mode);
1162 GLint gl_front_face;
1163 glGetIntegerv(GL_FRONT_FACE, &gl_front_face);
1166 bool gl_depth_bias_enabled = glIsEnabled(GL_POLYGON_OFFSET_FILL) &&
1167 glIsEnabled(GL_POLYGON_OFFSET_LINE) &&
1168 glIsEnabled(GL_POLYGON_OFFSET_POINT);
1169 float gl_depth_bias_constant_factor;
1170 float gl_depth_bias_slope_factor;
1171 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl_depth_bias_constant_factor);
1172 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl_depth_bias_slope_factor);
1175 bool gl_depth_clamp_enabled = glIsEnabled(GL_DEPTH_CLAMP);
1178 bool gl_scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST);
1181 GLint gl_provoking_vertex;
1182 glGetIntegerv(GL_PROVOKING_VERTEX, &gl_provoking_vertex);
1185 float gl_point_size;
1186 glGetFloatv(GL_POINT_SIZE, &gl_point_size);
1189 float gl_line_width;
1190 glGetFloatv(GL_LINE_WIDTH, &gl_line_width);
1195 if (gl_cull_enabled)
1210 m_rasterization_state.
point_size = gl_point_size;
1211 m_rasterization_state.
line_width = gl_line_width;
1214 void pipeline::fetch_depth_stencil_state()
1266 GLboolean gl_depth_write_enabled;
1267 glGetBooleanv(GL_DEPTH_WRITEMASK, &gl_depth_write_enabled);
1270 GLint gl_depth_compare_op;
1271 glGetIntegerv(GL_DEPTH_FUNC, &gl_depth_compare_op);
1272 m_depth_stencil_state.
depth_compare_op = inv_compare_op_lut(gl_depth_compare_op);
1278 GLint gl_stencil_front_fail;
1279 GLint gl_stencil_front_pass_depth_pass;
1280 GLint gl_stencil_front_pass_depth_fail;
1281 GLint gl_stencil_front_func;
1282 GLint gl_stencil_front_value_mask;
1283 GLint gl_stencil_front_write_mask;
1284 GLint gl_stencil_front_ref;
1286 glGetIntegerv(GL_STENCIL_FAIL, &gl_stencil_front_fail);
1287 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &gl_stencil_front_pass_depth_pass);
1288 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &gl_stencil_front_pass_depth_fail);
1289 glGetIntegerv(GL_STENCIL_FUNC, &gl_stencil_front_func);
1290 glGetIntegerv(GL_STENCIL_VALUE_MASK, &gl_stencil_front_value_mask);
1291 glGetIntegerv(GL_STENCIL_WRITEMASK, &gl_stencil_front_write_mask);
1292 glGetIntegerv(GL_STENCIL_REF, &gl_stencil_front_ref);
1295 m_depth_stencil_state.
stencil_front.
pass_op = inv_stencil_op_lut(gl_stencil_front_pass_depth_pass);
1305 GLint gl_stencil_back_fail;
1306 GLint gl_stencil_back_pass_depth_pass;
1307 GLint gl_stencil_back_pass_depth_fail;
1308 GLint gl_stencil_back_func;
1309 GLint gl_stencil_back_value_mask;
1310 GLint gl_stencil_back_write_mask;
1311 GLint gl_stencil_back_ref;
1313 glGetIntegerv(GL_STENCIL_BACK_FAIL, &gl_stencil_back_fail);
1314 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &gl_stencil_back_pass_depth_pass);
1315 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &gl_stencil_back_pass_depth_fail);
1316 glGetIntegerv(GL_STENCIL_BACK_FUNC, &gl_stencil_back_func);
1317 glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &gl_stencil_back_value_mask);
1318 glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &gl_stencil_back_write_mask);
1319 glGetIntegerv(GL_STENCIL_BACK_REF, &gl_stencil_back_ref);
1322 m_depth_stencil_state.
stencil_back.
pass_op = inv_stencil_op_lut(gl_stencil_back_pass_depth_pass);
1326 m_depth_stencil_state.
stencil_back.
write_mask = std::bit_cast<std::uint32_t>(gl_stencil_back_write_mask);
1331 void pipeline::fetch_color_blend_state()
1341 case GL_AND_REVERSE:
1345 case GL_AND_INVERTED:
1361 case GL_COPY_INVERTED:
1363 case GL_OR_INVERTED:
1383 case GL_ONE_MINUS_SRC_COLOR:
1387 case GL_ONE_MINUS_DST_COLOR:
1391 case GL_ONE_MINUS_SRC_ALPHA:
1395 case GL_ONE_MINUS_DST_ALPHA:
1397 case GL_CONSTANT_COLOR:
1399 case GL_ONE_MINUS_CONSTANT_COLOR:
1401 case GL_CONSTANT_ALPHA:
1403 case GL_ONE_MINUS_CONSTANT_ALPHA:
1405 case GL_SRC_ALPHA_SATURATE:
1409 case GL_ONE_MINUS_SRC1_COLOR:
1413 case GL_ONE_MINUS_SRC1_ALPHA:
1425 case GL_FUNC_SUBTRACT:
1427 case GL_FUNC_REVERSE_SUBTRACT:
1440 glGetIntegerv(GL_LOGIC_OP_MODE, &gl_logic_op);
1442 m_color_blend_state.
logic_op = inv_logic_op_lut(gl_logic_op);
1446 GLint gl_blend_src_rgb;
1447 GLint gl_blend_dst_rgb;
1448 GLint gl_blend_equation_rgb;
1449 GLint gl_blend_src_alpha;
1450 GLint gl_blend_dst_alpha;
1451 GLint gl_blend_equation_alpha;
1452 glGetIntegerv(GL_BLEND_SRC_RGB, &gl_blend_src_rgb);
1453 glGetIntegerv(GL_BLEND_DST_RGB, &gl_blend_dst_rgb);
1454 glGetIntegerv(GL_BLEND_EQUATION_RGB, &gl_blend_equation_rgb);
1455 glGetIntegerv(GL_BLEND_SRC_ALPHA, &gl_blend_src_alpha);
1456 glGetIntegerv(GL_BLEND_DST_ALPHA, &gl_blend_dst_alpha);
1457 glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &gl_blend_equation_alpha);
1466 GLboolean gl_color_writemask[4];
1467 glGetBooleanv(GL_COLOR_WRITEMASK, gl_color_writemask);
1470 static_cast<std::uint8_t
>(gl_color_writemask[0]) |
1471 (
static_cast<std::uint8_t
>(gl_color_writemask[1]) << 1) |
1472 (
static_cast<std::uint8_t
>(gl_color_writemask[2]) << 2) |
1473 (
static_cast<std::uint8_t
>(gl_color_writemask[3]) << 3);
1475 glGetFloatv(GL_BLEND_COLOR, m_color_blend_state.
blend_constants.data());
1478 void pipeline::fetch_clear_value()
1481 GLfloat gl_color_clear[4];
1482 GLfloat gl_depth_clear;
1483 GLint gl_stencil_clear;
1484 glGetFloatv(GL_COLOR_CLEAR_VALUE, gl_color_clear);
1485 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &gl_depth_clear);
1486 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &gl_stencil_clear);
1489 m_clear_value.
color = {gl_color_clear[0], gl_color_clear[1], gl_color_clear[2], gl_color_clear[3]};
1490 m_clear_value.
depth = gl_depth_clear;
1491 m_clear_value.
stencil =
static_cast<std::uint32_t
>(gl_stencil_clear);
void set_stencil_op(std::uint8_t face_mask, stencil_op fail_op, stencil_op pass_op, stencil_op depth_fail_op, gl::compare_op compare_op)
Sets the stencil operations.
void set_primitive_topology(primitive_topology topology)
Sets the primitive topology to use for drawing.
void clear_attachments(std::uint8_t mask, const clear_value &value)
Clears the color, depth, or stencil buffers of current attachments.
void set_fill_mode(fill_mode mode)
Sets the polygon rasterization mode.
void bind_shader_program(const gl::shader_program *shader_program)
Sets the vertex input.
void set_color_write_mask(std::uint8_t mask)
Sets the color write mask.
void set_blend_constants(const std::array< float, 4 > &blend_constants)
Sets the values of the blend constants.
void bind_framebuffer(const gl::framebuffer *framebuffer)
Sets the vertex input.
void set_primitive_restart_enabled(bool enabled)
Controls whether a special vertex index value is treated as restarting the assembly of primitives.
void set_stencil_write_mask(std::uint8_t face_mask, std::uint32_t write_mask)
Sets the stencil write mask.
void set_depth_clamp_enabled(bool enabled)
Controls whether depth clamping is enabled.
void set_depth_bias_factors(float constant_factor, float slope_factor)
Sets depth bias factors.
void set_color_blend_enabled(bool enabled)
Controls whether blending is enabled for the corresponding color attachment.
void set_scissor_test_enabled(bool enabled)
Enables or disables scissor testing.
void set_point_size(float size)
Sets the the diameter of rasterized points.
void set_cull_mode(cull_mode mode)
Sets the triangle culling mode.
void set_front_face(front_face face)
Sets the front-facing triangle orientation.
void set_stencil_test_enabled(bool enabled)
Controls whether stencil testing is enabled.
void set_viewport(std::uint32_t first_viewport, std::span< const viewport > viewports)
Sets one or more viewports.
void set_provoking_vertex_mode(provoking_vertex_mode mode)
Sets the vertex to be used as the source of data for flat-shaded varyings.
void draw_indexed(std::uint32_t index_count, std::uint32_t instance_count, std::uint32_t first_index, std::int32_t vertex_offset, std::uint32_t first_instance)
Draws primitives with indexed vertices.
void set_depth_bias_enabled(bool enabled)
Controls whether to bias fragment depth values.
void set_depth_write_enabled(bool enabled)
Controls whether depth writes are enabled.
void set_logic_op(gl::logic_op logic_op)
Selects which logical operation to apply.
void set_scissor(std::uint32_t first_scissor, std::span< const scissor_region > scissors)
Sets one or more scissor regions.
void set_stencil_reference(std::uint8_t face_mask, std::uint32_t reference)
Sets the stencil reference value.
void bind_vertex_buffers(std::uint32_t first_binding, std::span< const vertex_buffer *const > buffers, std::span< const std::size_t > offsets, std::span< const std::size_t > strides)
Binds vertex buffers.
pipeline()
Constructs a pipeline.
void set_color_blend_equation(const color_blend_equation &equation)
Sets the color blend factors and operations.
void set_logic_op_enabled(bool enabled)
Controls whether whether logical operations are enabled.
void set_depth_compare_op(gl::compare_op compare_op)
Sets the depth comparison operator.
void draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance)
Draws primitives.
void set_depth_test_enabled(bool enabled)
Controls whether depth testing is enabled.
void bind_vertex_array(const vertex_array *array)
Binds a vertex array.
void set_rasterizer_discard_enabled(bool enabled)
Controls whether primitives are discarded before the rasterization stage.
void set_line_width(float width)
Sets the width of rasterized lines.
void set_stencil_compare_mask(std::uint8_t face_mask, std::uint32_t compare_mask)
Sets the stencil compare mask.
Shader program which can be linked to shader objects and executed.
Vertex arrays describes how vertex input attributes are stored in vertex buffers.
log_message< log_message_severity::fatal, Args... > log_fatal
Formats and logs a fatal error message.
log_message< log_message_severity::warning, Args... > log_warning
Formats and logs a warning message.
log_message< log_message_severity::debug, Args... > log_debug
Formats and logs a debug message.
log_message< log_message_severity::error, Args... > log_error
Formats and logs an error message.
Graphics library interface.
blend_factor
Source and destination color and alpha blending factors.
@ one_minus_constant_color
@ one_minus_constant_alpha
@ color_component_b_bit
Indicates that the B value is written to the color attachment for the appropriate sample.
@ color_component_r_bit
Indicates that the R value is written to the color attachment for the appropriate sample.
@ color_component_a_bit
Indicates that the A value is written to the color attachment for the appropriate sample.
@ color_component_g_bit
Indicates that the G value is written to the color attachment for the appropriate sample.
cull_mode
Triangle culling mode.
@ none
No triangles are discarded.
@ back
Back-facing triangles are discarded.
@ front_and_back
All triangles are discarded.
@ front
Front-facing triangles are discarded.
blend_op
Framebuffer blending operations.
@ stencil_face_front_bit
Only the front set of stencil state is updated.
@ stencil_face_back_bit
Only the back set of stencil state is updated.
@ stencil_face_front_and_back
Both sets of stencil state are updated.
front_face
Polygon front-facing orientation.
@ counter_clockwise
Triangle with positive area is considered front-facing.
@ clockwise
Triangle with negative area is considered front-facing.
provoking_vertex_mode
Vertex to be used as the source of data for flat-shaded varyings.
@ first
Provoking vertex is the first non-adjacency vertex.
@ last
Provoking vertex is the last non-adjacency vertex.
stencil_op
Stencil comparison functions.
@ keep
Keeps the current value.
@ increment_and_clamp
Increments the current value and clamps to the maximum representable unsigned value.
@ invert
Bitwise-inverts the current value.
@ increment_and_wrap
Increments the current value and wraps to 0 when the maximum value would have been exceeded.
@ decrement_and_wrap
Decrements the current value and wraps to the maximum possible value when the value would go below 0.
@ replace
Sets the value to reference.
@ zero
Sets the value to 0.
@ decrement_and_clamp
Decrements the current value and clamps to 0.
primitive_topology
Primitive topologies.
logic_op
Framebuffer logical operations.
fill_mode
Polygon rasterization mode.
@ line
Polygons edges are drawn as line segments.
@ point
Polygons vertices are drawn as points.
@ fill
Polygons are filled.
@ color_clear_bit
Indicates the color buffer should be cleared.
@ depth_clear_bit
Indicates the depth buffer should be cleared.
@ stencil_clear_bit
Indicates the stencil buffer should be cleared.
compare_op
Comparison operators.
@ equal
Comparison evaluates reference == test.
@ less_or_equal
Comparison evaluates reference <= test.
@ greater
Comparison evaluates reference > test.
@ not_equal
Comparison evaluates reference != test.
@ greater_or_equal
Comparison evaluates reference >= test.
@ never
Comparison always evaluates false.
@ less
Comparison evaluates reference < test.
@ always
Comparison always evaluates true.
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
T length(const quaternion< T > &q)
Calculates the length of a quaternion.
float depth
Depth clear value.
std::array< float, 4 > color
Color clear values.
std::uint32_t stencil
Stencil clear value.
Color blend factors and operations.
blend_op color_blend_op
Selects which blend operation is used to calculate the RGB values to write to the color attachment.
blend_factor dst_color_blend_factor
Selects which blend factor is used to determine the RGB destination factors.
blend_op alpha_blend_op
Selects which blend operation is used to calculate the alpha values to write to the color attachment.
blend_factor dst_alpha_blend_factor
Selects which blend factor is used to determine the alpha destination factor.
blend_factor src_alpha_blend_factor
Selects which blend factor is used to determine the alpha source factor.
blend_factor src_color_blend_factor
Selects which blend factor is used to determine the RGB source factors.
gl::logic_op logic_op
Selects which logical operation to apply.
std::array< float, 4 > blend_constants
RGBA components of the blend constant that are used in blending, depending on the blend factor.
bool blend_enabled
Controls whether blending is enabled for the corresponding color attachment.
bool logic_op_enabled
Controls whether to apply logical operations.
gl::color_blend_equation color_blend_equation
Color blend factors and operations.
std::uint8_t color_write_mask
Bitmask indicating which of the RGBA components are enabled for writing.
stencil_op_state stencil_front
Stencil testing parameters for front faces.
compare_op depth_compare_op
Comparison operator to use in the depth comparison step of the depth test.
bool stencil_test_enabled
true if stencil testing is enabled, false otherwise.
bool depth_write_enabled
true if depth writes are enabled when depth testing is enabled, false otherwise.
bool depth_test_enabled
true if depth testing is enabled, false otherwise.
stencil_op_state stencil_back
Stencil testing parameters for back faces.
bool scissor_test_enabled
true if scissor testing should be enabled, false otherwise.
bool rasterizer_discard_enabled
true if rasterizer discard should be enabled, false otherwise.
gl::cull_mode cull_mode
Triangle culling mode.
float depth_bias_constant_factor
Depth bias constant factor.
float point_size
Diameter of rasterized points.
gl::fill_mode fill_mode
Polygon rasterization mode.
gl::front_face front_face
Polygon front-facing orientation.
bool depth_clamp_enabled
true if depth clamp should be enabled, false otherwise.
gl::provoking_vertex_mode provoking_vertex_mode
Vertex to be used as the source of data for flat-shaded varyings.
bool depth_bias_enabled
true if depth bias should be enabled, false otherwise.
float line_width
Width of rasterized line segments.
float depth_bias_slope_factor
Depth bias slope factor.
std::vector< viewport > viewports
Active viewports.
std::vector< scissor_region > scissors
Active scissor regions.
stencil_op pass_op
Action performed on samples that pass both the depth and stencil tests.
std::uint32_t write_mask
Bits of the unsigned integer stencil values updated by the stencil test in the stencil framebuffer at...
stencil_op depth_fail_op
Action performed on samples that pass the stencil test and fail the depth test.
gl::compare_op compare_op
Comparison operator used in the stencil test.
std::uint32_t reference
Stencil reference value that is used in the unsigned stencil comparison.
stencil_op fail_op
Action performed on samples that fail the stencil test.
std::uint32_t compare_mask
Bits of the unsigned integer stencil values participating in the stencil test.
Viewport position, dimensions, and depth range.
float y
Y-coordinate of the viewport's lower left corner.
float x
X-coordinate of the viewport's lower left corner.
float max_depth
Maximum depth range of the viewport.
float width
Width of the viewport.
float min_depth
Minimum depth range of the viewport.
float height
Height of the viewport.