Skip to content

Commit 9f87b57

Browse files
committed
stuff
1 parent 2c6d61f commit 9f87b57

File tree

4 files changed

+298
-363
lines changed

4 files changed

+298
-363
lines changed

src/ruis/render/opengl/context.cpp

+251
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
4040

4141
using namespace ruis::render::opengl;
4242

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+
43116
utki::shared_ref<ruis::render::context::shaders> context::create_shaders()
44117
{
45118
// TODO: are those lint supressions still valid?
@@ -265,3 +338,181 @@ utki::shared_ref<ruis::render::frame_buffer> context::create_framebuffer( //
265338
std::move(stencil)
266339
);
267340
}
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+
}

src/ruis/render/opengl/context.hpp

+47
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2121

2222
#pragma once
2323

24+
#include <GL/glew.h>
2425
#include <ruis/render/context.hpp>
2526
#include <utki/shared.hpp>
2627

2728
namespace ruis::render::opengl {
2829

2930
class context : public ruis::render::context
3031
{
32+
GLuint default_framebuffer;
33+
3134
public:
35+
context();
36+
37+
// ===============================
38+
// ====== factory functions ======
39+
3240
utki::shared_ref<shaders> create_shaders() override;
3341

3442
utki::shared_ref<ruis::render::texture_2d> create_texture_2d(
@@ -91,6 +99,45 @@ class context : public ruis::render::context
9199
utki::span<const uint8_t> data,
92100
texture_2d_parameters params
93101
);
102+
103+
public:
104+
// =====================================
105+
// ====== state control functions ======
106+
107+
void set_framebuffer_internal(ruis::render::frame_buffer* fb) override;
108+
109+
void clear_framebuffer_color() override;
110+
111+
void clear_framebuffer_depth() override;
112+
113+
void clear_framebuffer_stencil() override;
114+
115+
r4::vector2<uint32_t> to_window_coords(ruis::vec2 point) const override;
116+
117+
bool is_scissor_enabled() const noexcept override;
118+
119+
void enable_scissor(bool enable) override;
120+
121+
r4::rectangle<uint32_t> get_scissor() const override;
122+
123+
void set_scissor(r4::rectangle<uint32_t> r) override;
124+
125+
r4::rectangle<uint32_t> get_viewport() const override;
126+
127+
void set_viewport(r4::rectangle<uint32_t> r) override;
128+
129+
void enable_blend(bool enable) override;
130+
131+
void set_blend_func(
132+
blend_factor src_color,
133+
blend_factor dst_color,
134+
blend_factor src_alpha,
135+
blend_factor dst_alpha
136+
) override;
137+
138+
bool is_depth_enabled() const noexcept override;
139+
140+
void enable_depth(bool enable) override;
94141
};
95142

96143
} // namespace ruis::render::opengl

0 commit comments

Comments
 (0)