@@ -40,6 +40,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
40
40
41
41
using namespace ruis ::render::opengl;
42
42
43
+ // namespace {
44
+ // unsigned get_max_texture_size()
45
+ // {
46
+ // // the val variable is initialized via output argument, so no need to initialize
47
+ // // it here
48
+
49
+ // // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
50
+ // GLint val;
51
+ // glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
52
+ // ASSERT(val > 0)
53
+ // return unsigned(val);
54
+ // }
55
+ // } // namespace
56
+
57
+ #ifdef DEBUG
58
+ namespace {
59
+ void GLAPIENTRY opengl_error_callback (
60
+ GLenum source,
61
+ GLenum type,
62
+ GLuint id,
63
+ GLenum severity,
64
+ GLsizei length,
65
+ const GLchar* message,
66
+ const void * user_param
67
+ )
68
+ {
69
+ std::cout << " OpenGL" << (type == GL_DEBUG_TYPE_ERROR ? " ERROR" : " " ) << " : " << message << std::endl;
70
+ }
71
+ } // namespace
72
+ #endif
73
+
74
+ context::context () :
75
+ ruis::render::context(
76
+ {.initial_matrix = ruis::matrix4 ()
77
+ // OpenGL identity matrix:
78
+ // viewport edges: left = -1, right = 1, top = 1, bottom = -1
79
+ // z-axis towards viewer
80
+ .set_identity ()
81
+ // x-axis right, y-axis down, z-axis away
82
+ .scale (1 , -1 , -1 )
83
+ // viewport edges: left = 0, top = 0
84
+ .translate (-1 , -1 )
85
+ // viewport edges: right = 1, bottom = 1
86
+ .scale (2 , 2 )}
87
+ )
88
+ {
89
+ LOG ([](auto & o) {
90
+ o << " OpenGL version: " << glGetString (GL_VERSION) << std::endl;
91
+ })
92
+
93
+ // On some platforms the default framebuffer is not 0, so because of this
94
+ // check if default framebuffer value is saved or not everytime some
95
+ // framebuffer is going to be bound and save the value if needed.
96
+
97
+ // the old_fb variable is initialized via output argument, so no need to initialize
98
+ // it here
99
+
100
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
101
+ GLint old_fb;
102
+ glGetIntegerv (GL_FRAMEBUFFER_BINDING, &old_fb);
103
+ LOG ([&](auto & o) {
104
+ o << " old_fb = " << old_fb << std::endl;
105
+ })
106
+ this ->default_framebuffer = GLuint (old_fb);
107
+
108
+ #ifdef DEBUG
109
+ glEnable (GL_DEBUG_OUTPUT);
110
+ glDebugMessageCallback (opengl_error_callback, nullptr );
111
+ #endif
112
+
113
+ glEnable (GL_CULL_FACE);
114
+ }
115
+
43
116
utki::shared_ref<ruis::render::context::shaders> context::create_shaders ()
44
117
{
45
118
// TODO: are those lint supressions still valid?
@@ -265,3 +338,181 @@ utki::shared_ref<ruis::render::frame_buffer> context::create_framebuffer( //
265
338
std::move (stencil)
266
339
);
267
340
}
341
+
342
+ void context::set_framebuffer_internal (ruis::render::frame_buffer* fb)
343
+ {
344
+ if (!fb) {
345
+ glBindFramebuffer (GL_FRAMEBUFFER, this ->default_framebuffer );
346
+ assert_opengl_no_error ();
347
+ return ;
348
+ }
349
+
350
+ ASSERT (dynamic_cast <frame_buffer*>(fb))
351
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
352
+ auto & ogl_fb = static_cast <frame_buffer&>(*fb);
353
+
354
+ glBindFramebuffer (GL_FRAMEBUFFER, ogl_fb.fbo );
355
+ assert_opengl_no_error ();
356
+ }
357
+
358
+ void context::clear_framebuffer_color ()
359
+ {
360
+ // Default clear color is RGBA = (0, 0, 0, 0);
361
+ glClear (GL_COLOR_BUFFER_BIT);
362
+ assert_opengl_no_error ();
363
+ }
364
+
365
+ void context::clear_framebuffer_depth ()
366
+ {
367
+ // Default clear depth value is 1, see glClearDepth()
368
+ glClear (GL_DEPTH_BUFFER_BIT);
369
+ assert_opengl_no_error ();
370
+ }
371
+
372
+ void context::clear_framebuffer_stencil ()
373
+ {
374
+ // Default clear stencil value is 0, see glClearStencil()
375
+ glClear (GL_STENCIL_BUFFER_BIT);
376
+ assert_opengl_no_error ();
377
+ }
378
+
379
+ r4::vector2<uint32_t > context::to_window_coords (ruis::vec2 point) const
380
+ {
381
+ auto vp = this ->get_viewport ();
382
+
383
+ point += ruis::vec2 (1 , 1 );
384
+ point = max (point, {0 , 0 }); // clamp to >= 0
385
+ point /= 2 ;
386
+ point.comp_multiply (vp.d .to <real>());
387
+ point = round (point);
388
+ return point.to <uint32_t >() + vp.p ;
389
+ }
390
+
391
+ bool context::is_scissor_enabled () const noexcept
392
+ {
393
+ return glIsEnabled (GL_SCISSOR_TEST) ? true : false ; // "? true : false" is to avoid warning under MSVC
394
+ }
395
+
396
+ void context::enable_scissor (bool enable)
397
+ {
398
+ if (enable) {
399
+ glEnable (GL_SCISSOR_TEST);
400
+ } else {
401
+ glDisable (GL_SCISSOR_TEST);
402
+ }
403
+ }
404
+
405
+ r4::rectangle<uint32_t > context::get_scissor () const
406
+ {
407
+ std::array<GLint, 4 > osb{};
408
+ glGetIntegerv (GL_SCISSOR_BOX, osb.data ());
409
+
410
+ #ifdef DEBUG
411
+ for (auto n : osb) {
412
+ ASSERT (n >= 0 )
413
+ }
414
+ #endif
415
+
416
+ return {
417
+ uint32_t (osb[0 ]), //
418
+ uint32_t (osb[1 ]),
419
+ uint32_t (osb[2 ]),
420
+ uint32_t (osb[3 ])
421
+ };
422
+ }
423
+
424
+ void context::set_scissor (r4::rectangle<uint32_t > r)
425
+ {
426
+ glScissor (GLint (r.p .x ()), GLint (r.p .y ()), GLint (r.d .x ()), GLint (r.d .y ()));
427
+ assert_opengl_no_error ();
428
+ }
429
+
430
+ r4::rectangle<uint32_t > context::get_viewport () const
431
+ {
432
+ std::array<GLint, 4 > vp{};
433
+
434
+ glGetIntegerv (GL_VIEWPORT, vp.data ());
435
+
436
+ #ifdef DEBUG
437
+ for (auto n : vp) {
438
+ ASSERT (n >= 0 )
439
+ }
440
+ #endif
441
+
442
+ return {
443
+ uint32_t (vp[0 ]), //
444
+ uint32_t (vp[1 ]),
445
+ uint32_t (vp[2 ]),
446
+ uint32_t (vp[3 ])
447
+ };
448
+ }
449
+
450
+ void context::set_viewport (r4::rectangle<uint32_t > r)
451
+ {
452
+ glViewport (GLint (r.p .x ()), GLint (r.p .y ()), GLint (r.d .x ()), GLint (r.d .y ()));
453
+ assert_opengl_no_error ();
454
+ }
455
+
456
+ void context::enable_blend (bool enable)
457
+ {
458
+ if (enable) {
459
+ glEnable (GL_BLEND);
460
+ } else {
461
+ glDisable (GL_BLEND);
462
+ }
463
+ }
464
+
465
+ namespace {
466
+
467
+ const std::array<GLenum, size_t (ruis::render::context::blend_factor::enum_size)> blend_func = {
468
+ GL_ZERO,
469
+ GL_ONE,
470
+ GL_SRC_COLOR,
471
+ GL_ONE_MINUS_SRC_COLOR,
472
+ GL_DST_COLOR,
473
+ GL_ONE_MINUS_DST_COLOR,
474
+ GL_SRC_ALPHA,
475
+ GL_ONE_MINUS_SRC_ALPHA,
476
+ GL_DST_ALPHA,
477
+ GL_ONE_MINUS_DST_ALPHA,
478
+ GL_CONSTANT_COLOR,
479
+ GL_ONE_MINUS_CONSTANT_COLOR,
480
+ GL_CONSTANT_ALPHA,
481
+ GL_ONE_MINUS_CONSTANT_ALPHA,
482
+ GL_SRC_ALPHA_SATURATE
483
+ };
484
+
485
+ } // namespace
486
+
487
+ void context::set_blend_func (
488
+ blend_factor src_color,
489
+ blend_factor dst_color,
490
+ blend_factor src_alpha,
491
+ blend_factor dst_alpha
492
+ )
493
+ {
494
+ glBlendFuncSeparate (
495
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
496
+ blend_func[unsigned (src_color)],
497
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
498
+ blend_func[unsigned (dst_color)],
499
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
500
+ blend_func[unsigned (src_alpha)],
501
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
502
+ blend_func[unsigned (dst_alpha)]
503
+ );
504
+ }
505
+
506
+ bool context::is_depth_enabled () const noexcept
507
+ {
508
+ return glIsEnabled (GL_DEPTH_TEST) ? true : false ; // "? true : false" is to avoid warning under MSVC
509
+ }
510
+
511
+ void context::enable_depth (bool enable)
512
+ {
513
+ if (enable) {
514
+ glEnable (GL_DEPTH_TEST);
515
+ } else {
516
+ glDisable (GL_DEPTH_TEST);
517
+ }
518
+ }
0 commit comments