Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
rtoumazet committed Oct 18, 2024
1 parent a79e471 commit 9d0bb2d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 89 deletions.
8 changes: 4 additions & 4 deletions saturnin/src/video/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,17 +951,17 @@ void showRenderingWindow(core::EmulatorContext& state) {
ImGui::Begin("Video rendering", nullptr, flags);

if (state.opengl()->areFbosInitialized()) {
if (state.opengl()->isThereSomethingToRender()) {
if (state.opengl()->render()->isThereSomethingToRender()) {
state.opengl()->generateTextures();
state.opengl()->renderSelector();
state.opengl()->render()->renderSelector();
}
const auto alpha = 0xff;
gui::addTextureToDrawList(state.opengl()->getRenderedBufferTextureId(video::GuiTextureType::render_buffer),
width,
height,
alpha);
if ((state.debugStatus() != core::DebugStatus::disabled) && state.opengl()->isSaturnResolutionSet()) {
state.opengl()->renderVdp1DebugOverlay();
state.opengl()->render()->renderVdp1DebugOverlay();
const auto overlay_alpha = 0x80;
// gui::addTextureToDrawList(state.opengl()->vdp1DebugOverlayTextureId(), width, height, overlay_alpha);
gui::addTextureToDrawList(state.opengl()->getRenderedBufferTextureId(video::GuiTextureType::vdp1_debug_buffer),
Expand Down Expand Up @@ -1737,7 +1737,7 @@ void showDebugVdp2Window(core::EmulatorContext& state, bool* opened) {

if (state.debugStatus() != core::DebugStatus::disabled) {
if (state.vdp2()->screenInDebug() != video::ScrollScreen::none) {
state.opengl()->renderVdp2DebugLayer(state);
state.opengl()->render()->renderVdp2DebugLayer(state);
}
const auto tex_id = state.opengl()->vdp2DebugLayerTextureId();
const auto preview_size = ImVec2(500, 500);
Expand Down
45 changes: 25 additions & 20 deletions saturnin/src/video/opengl/opengl.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ const std::unordered_map<VdpLayer, std::string> layer_to_name = {
{VdpLayer::undefined, "undefined"}
};

class OpenglRender;

class Opengl {
public:
// Constructors / Destructors
Expand Down Expand Up @@ -252,29 +254,9 @@ class Opengl {
// Checks if the Framebuffer Objects (FBO) are initialized.
auto areFbosInitialized() const -> bool { return fbo_type_to_id_.at(FboType::general) != 0; }

// Renders data if available.
void render();
void renderByScreenPriority();
void renderByParts();

// Renders test data if available.
void renderTest();

// Selects the renderer to use, depending on conditions
void renderSelector();

// Checks if there's something to render.
auto isThereSomethingToRender() const -> bool;

// Gets the texture ID of the buffer currently being rendered to.
auto getRenderedBufferTextureId(const GuiTextureType type) -> u32;

// Renders the vertexes of the vdp1 part currently saved to a specific overlay layer. Useful for debugging.
void renderVdp1DebugOverlay();

// Renders the vertexes of the vdp2 layer currently selected for display in the debug window.
void renderVdp2DebugLayer(core::EmulatorContext& state);

// Texture key is added so the linked texture is created or marked for recreation. Layer is used for cache management.
void addOrUpdateTexture(const size_t key, const VdpLayer layer);

Expand Down Expand Up @@ -358,6 +340,9 @@ class Opengl {
// Sets FBO texture status for every priority of a specific screen.
void setFboTextureStatus(const ScrollScreen screen, const FboTextureStatus state);

// Interface to the OpenglRender object.
auto render() -> OpenglRender* { return opengl_render_.get(); };

private:
friend class OpenglRender;

Expand Down Expand Up @@ -507,6 +492,26 @@ class OpenglRender {
// Renders a specific FBO texture.
void renderFboTexture(const u32 texture_id);

// Renders data if available.
void render();
void renderByScreenPriority();
void renderByParts();

// Renders test data if available.
void renderTest();

// Renders the vertexes of the vdp1 part currently saved to a specific overlay layer. Useful for debugging.
void renderVdp1DebugOverlay();

// Renders the vertexes of the vdp2 layer currently selected for display in the debug window.
void renderVdp2DebugLayer(core::EmulatorContext& state);

// Selects the renderer to use, depending on conditions
void renderSelector();

// Checks if there's something to render.
auto isThereSomethingToRender() const -> bool;

private:
Opengl* opengl_;
};
Expand Down
130 changes: 65 additions & 65 deletions saturnin/src/video/opengl/opengl_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,95 +217,95 @@ void OpenglRender::renderFboTexture(const u32 texture_id) {
// gl::glDeleteBuffers(1, &elements_buffer);
}

void Opengl::render() {
void OpenglRender::render() {
if constexpr (uses_fbo) {
renderByScreenPriority();
} else {
renderByParts();
}
}

void Opengl::renderByScreenPriority() {
void OpenglRender::renderByScreenPriority() {
MapOfPartsList global_parts_list;

const auto getPartsFromThread = [&]() {
std::lock_guard lock(getMutex(MutexType::parts_list));
if (!parts_lists_.empty()) { global_parts_list = std::move(parts_lists_); }
std::lock_guard lock(opengl_->getMutex(MutexType::parts_list));
if (!opengl_->parts_lists_.empty()) { global_parts_list = std::move(opengl_->parts_lists_); }
};
getPartsFromThread();

clearFboTextures();
clearFboKeys();
opengl_->clearFboTextures();
opengl_->clearFboKeys();

// Rendering is done to FBOs depending on the priority and layer combo.
for (const auto& [key, parts] : global_parts_list) {
opengl_render_->renderToAvailableTexture(key, parts);
opengl_->opengl_render_->renderToAvailableTexture(key, parts);
}

opengl_render_->preRender();
preRender();

// :TODO: Render the FBOs to the current framebuffer
std::ranges::reverse_view rv{fbo_key_to_fbo_pool_index_};
std::ranges::reverse_view rv{opengl_->fbo_key_to_fbo_pool_index_};
for (const auto& [key, index] : rv) {
opengl_render_->renderFboTexture(fbo_texture_pool_[index]);
renderFboTexture(opengl_->fbo_texture_pool_[index]);
}

opengl_render_->postRender();
postRender();

const auto notifyMainThread = [this, &global_parts_list]() {
std::lock_guard lk(getMutex(MutexType::parts_list));
std::lock_guard lk(opengl_->getMutex(MutexType::parts_list));
MapOfPartsList().swap(global_parts_list);
data_condition_.notify_one();
opengl_->data_condition_.notify_one();
};
notifyMainThread();
}

void Opengl::renderByParts() {
void OpenglRender::renderByParts() {
PartsList parts_list;

opengl_render_->preRender();
preRender();

const auto getParts = [this, &parts_list]() {
std::lock_guard lock(getMutex(MutexType::parts_list));
if (!parts_lists_[mixed_parts_key].empty()) { parts_list = std::move(parts_lists_[mixed_parts_key]); }
std::lock_guard lock(opengl_->getMutex(MutexType::parts_list));
if (!opengl_->parts_lists_[mixed_parts_key].empty()) { parts_list = std::move(opengl_->parts_lists_[mixed_parts_key]); }
};
getParts();

opengl_render_->renderParts(parts_list, texture_array_id_);
renderParts(parts_list, opengl_->texture_array_id_);

const auto notifyMainThread = [this, &parts_list]() {
std::lock_guard lk(getMutex(MutexType::parts_list));
std::lock_guard lk(opengl_->getMutex(MutexType::parts_list));
PartsList().swap(parts_list);
data_condition_.notify_one();
opengl_->data_condition_.notify_one();
};
notifyMainThread();

opengl_render_->postRender();
postRender();
}

void Opengl::renderTest() {
opengl_render_->preRender();
void OpenglRender::renderTest() {
preRender();

const auto [vao, vertex_buffer] = initializeVao();
const auto [vao, vertex_buffer] = opengl_->initializeVao();

glUseProgram(shaders_.programs[ProgramShader::main]);
glUseProgram(opengl_->shaders_.programs[ProgramShader::main]);
glBindVertexArray(vao); // binding VAO
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); // binding vertex buffer

// Calculating the ortho projection matrix
const auto proj_matrix = calculateDisplayViewportMatrix();
const auto proj_matrix = opengl_->calculateDisplayViewportMatrix();

// Sending the ortho projection matrix to the shader
const auto uni_proj_matrix = glGetUniformLocation(shaders_.programs[ProgramShader::main], "proj_matrix");
const auto uni_proj_matrix = glGetUniformLocation(opengl_->shaders_.programs[ProgramShader::main], "proj_matrix");
glUniformMatrix4fv(uni_proj_matrix, 1, GL_FALSE, glm::value_ptr(proj_matrix));

glActiveTexture(GLenum::GL_TEXTURE0);
const auto sampler_loc = glGetUniformLocation(shaders_.programs[ProgramShader::main], "sampler");
const auto sampler_loc = glGetUniformLocation(opengl_->shaders_.programs[ProgramShader::main], "sampler");
// glUniform1i(sampler_loc, GLenum::GL_TEXTURE0);
glUniform1i(sampler_loc, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array_id_);
glBindTexture(GL_TEXTURE_2D_ARRAY, opengl_->texture_array_id_);

const auto texture_used_loc = glGetUniformLocation(shaders_.programs[ProgramShader::main], "is_texture_used");
const auto texture_used_loc = glGetUniformLocation(opengl_->shaders_.programs[ProgramShader::main], "is_texture_used");
// Sending the variable to configure the shader to use texture data.
const auto is_texture_used = GLboolean(false);
glUniform1i(texture_used_loc, is_texture_used);
Expand Down Expand Up @@ -415,7 +415,7 @@ void Opengl::renderTest() {
const auto&& [indices, draw_ranges] = generateVertexIndicesAndDrawRanges(parts);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), indices.data(), GL_STATIC_DRAW);

const auto vertexes = readVertexes(parts);
const auto vertexes = opengl_->readVertexes(parts);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexes.size(), vertexes.data(), GL_STATIC_DRAW);

for (const auto& range : draw_ranges) {
Expand All @@ -437,34 +437,17 @@ void Opengl::renderTest() {
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
gl::glDeleteBuffers(1, &elements_buffer);

opengl_render_->postRender();
}

void Opengl::renderSelector() {
if constexpr (render_type == RenderType::RenderType_drawElements) { render(); }
if constexpr (render_type == RenderType::RenderType_drawTest) { renderTest(); }
}

auto Opengl::isThereSomethingToRender() const -> bool {
if constexpr (render_type == RenderType::RenderType_drawElements) {
if constexpr (uses_fbo) {
return !parts_lists_.empty();
} else {
if (parts_lists_.contains(mixed_parts_key)) { return !parts_lists_.at(mixed_parts_key).empty(); }
return false;
}
}
if constexpr (render_type == RenderType::RenderType_drawTest) { return true; }
postRender();
}

void Opengl::renderVdp1DebugOverlay() {
void OpenglRender::renderVdp1DebugOverlay() {
//----------- Pre render -----------//
glBindFramebuffer(GLenum::GL_FRAMEBUFFER, fbo_type_to_id_[FboType::general]);
glBindFramebuffer(GLenum::GL_FRAMEBUFFER, opengl_->fbo_type_to_id_[FboType::general]);

attachTextureLayerToFbo(fbo_texture_array_id_,
getFboTextureLayer(FboTextureType::vdp1_debug_overlay),
GLenum::GL_FRAMEBUFFER,
GLenum::GL_COLOR_ATTACHMENT0);
opengl_->attachTextureLayerToFbo(opengl_->fbo_texture_array_id_,
opengl_->getFboTextureLayer(FboTextureType::vdp1_debug_overlay),
GLenum::GL_FRAMEBUFFER,
GLenum::GL_COLOR_ATTACHMENT0);

// Viewport is the entire Saturn framebuffer
glViewport(0, 0, saturn_framebuffer_width, saturn_framebuffer_height);
Expand All @@ -474,15 +457,15 @@ void Opengl::renderVdp1DebugOverlay() {

// Scissor test calculation, to remove from display everything outside the current Saturn resolution.
glEnable(GL_SCISSOR_TEST);
auto [scissor_x, scissor_y, scissor_width, scissor_height] = calculateViewportPosAndSize();
auto [scissor_x, scissor_y, scissor_width, scissor_height] = opengl_->calculateViewportPosAndSize();
glScissor(scissor_x, scissor_y, scissor_width, scissor_height);

//----------- Render -----------------//
// Calculating the ortho projection matrix
const auto [vao_simple, vertex_buffer_simple] = initializeVao();
const auto proj_matrix = calculateDisplayViewportMatrix();
const auto [vao_simple, vertex_buffer_simple] = opengl_->initializeVao();
const auto proj_matrix = opengl_->calculateDisplayViewportMatrix();

auto part = partToHighlight();
auto part = opengl_->partToHighlight();

auto vertexes = std::vector<Vertex>{};

Expand All @@ -501,19 +484,19 @@ void Opengl::renderVdp1DebugOverlay() {
vertexes.emplace_back(part.common_vdp_data_.vertexes[2]);
vertexes.emplace_back(part.common_vdp_data_.vertexes[3]);

glUseProgram(shaders_.programs[ProgramShader::main]);
glUseProgram(opengl_->shaders_.programs[ProgramShader::main]);
glBindVertexArray(vao_simple); // binding VAO
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_simple); // binding vertex buffer

// Sending vertex buffer data to the GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexes.size(), vertexes.data(), GL_STATIC_DRAW);

// Sending the ortho projection matrix to the shader
const auto uni_proj_matrix = glGetUniformLocation(shaders_.programs[ProgramShader::main], "proj_matrix");
const auto uni_proj_matrix = glGetUniformLocation(opengl_->shaders_.programs[ProgramShader::main], "proj_matrix");
glUniformMatrix4fv(uni_proj_matrix, 1, GL_FALSE, glm::value_ptr(proj_matrix));

// Sending the variable to configure the shader to use color.
const auto uni_use_texture = glGetUniformLocation(shaders_.programs[ProgramShader::main], "is_texture_used");
const auto uni_use_texture = glGetUniformLocation(opengl_->shaders_.programs[ProgramShader::main], "is_texture_used");
const auto is_texture_used = GLboolean(false);
glUniform1i(uni_use_texture, is_texture_used);

Expand All @@ -527,9 +510,9 @@ void Opengl::renderVdp1DebugOverlay() {
glBindFramebuffer(GLenum::GL_FRAMEBUFFER, 0);
};

void Opengl::renderVdp2DebugLayer(core::EmulatorContext& state) {
void OpenglRender::renderVdp2DebugLayer(core::EmulatorContext& state) {
//----------- Pre render -----------//
glBindFramebuffer(GLenum::GL_FRAMEBUFFER, fbo_type_to_id_[FboType::vdp2_debug]);
glBindFramebuffer(GLenum::GL_FRAMEBUFFER, opengl_->fbo_type_to_id_[FboType::vdp2_debug]);

// Viewport is the entire Saturn framebuffer
glViewport(0, 0, saturn_framebuffer_width, saturn_framebuffer_height);
Expand All @@ -549,11 +532,28 @@ void Opengl::renderVdp2DebugLayer(core::EmulatorContext& state) {
}
}

if (!parts_list.empty()) { opengl_render_->renderParts(parts_list, texture_array_id_); }
if (!parts_list.empty()) { renderParts(parts_list, opengl_->texture_array_id_); }

//------ Post render --------//
// Framebuffer is released
gl::glBindFramebuffer(GL_FRAMEBUFFER, 0);
};

void OpenglRender::renderSelector() {
if constexpr (render_type == RenderType::RenderType_drawElements) { render(); }
if constexpr (render_type == RenderType::RenderType_drawTest) { renderTest(); }
};

auto OpenglRender::isThereSomethingToRender() const -> bool {
if constexpr (render_type == RenderType::RenderType_drawElements) {
if constexpr (uses_fbo) {
return !opengl_->parts_lists_.empty();
} else {
if (opengl_->parts_lists_.contains(mixed_parts_key)) { return !opengl_->parts_lists_.at(mixed_parts_key).empty(); }
return false;
}
}
if constexpr (render_type == RenderType::RenderType_drawTest) { return true; }
}

} // namespace saturnin::video

0 comments on commit 9d0bb2d

Please sign in to comment.