mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
b5d21be9c5
* temp * temp * before cleaning up * cleanup merge * fix warnings * merge fix * clang format
162 lines
5.3 KiB
C++
162 lines
5.3 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <memory>
|
|
|
|
#include "common/dma/dma_chain_read.h"
|
|
|
|
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
|
#include "game/graphics/opengl_renderer/CollideMeshRenderer.h"
|
|
#include "game/graphics/opengl_renderer/Profiler.h"
|
|
#include "game/graphics/opengl_renderer/Shader.h"
|
|
#include "game/graphics/opengl_renderer/opengl_utils.h"
|
|
#include "game/tools/subtitles/subtitle_editor.h"
|
|
|
|
struct RenderOptions {
|
|
bool draw_render_debug_window = false;
|
|
bool draw_profiler_window = false;
|
|
bool draw_small_profiler_window = false;
|
|
bool draw_subtitle_editor_window = false;
|
|
|
|
// internal rendering settings - The OpenGLRenderer will internally use this resolution/format.
|
|
int msaa_samples = 4;
|
|
int game_res_w = 640;
|
|
int game_res_h = 480;
|
|
|
|
// size of the window's framebuffer (framebuffer 0)
|
|
// The renderer needs to know this to do an optimization to render directly to the window's
|
|
// framebuffer when possible.
|
|
int window_framebuffer_height = 0;
|
|
int window_framebuffer_width = 0;
|
|
|
|
// the part of the window that we should draw to. The rest is black. This value is determined by
|
|
// logic inside of the game - it needs to know the desired aspect ratio.
|
|
int draw_region_height = 0;
|
|
int draw_region_width = 0;
|
|
|
|
// windows-specific tweaks to the size of the drawing area in borderless.
|
|
bool borderless_windows_hacks = false;
|
|
|
|
bool save_screenshot = false;
|
|
std::string screenshot_path;
|
|
|
|
float pmode_alp_register = 0.f;
|
|
|
|
// when enabled, does a `glFinish()` after each major rendering pass. This blocks until the GPU
|
|
// is done working, making it easier to profile GPU utilization.
|
|
bool gpu_sync = false;
|
|
};
|
|
|
|
struct Fbo {
|
|
bool valid = false; // do we have an OpenGL fbo_id?
|
|
GLuint fbo_id = -1;
|
|
|
|
// optional rgba/zbuffer/stencil data.
|
|
std::optional<GLuint> tex_id;
|
|
std::optional<GLuint> zbuf_stencil_id;
|
|
|
|
bool multisampled = false;
|
|
int multisample_count = 0; // Should be 1 if multisampled is disabled
|
|
|
|
bool is_window = false;
|
|
int width = 640;
|
|
int height = 480;
|
|
|
|
// Does this fbo match the given format? MSAA = 1 will accept a normal buffer, or a multisample 1x
|
|
bool matches(int w, int h, int msaa) const {
|
|
int effective_msaa = multisampled ? multisample_count : 1;
|
|
return valid && width == w && height == h && effective_msaa == msaa;
|
|
}
|
|
|
|
// Free opengl resources, if we have any.
|
|
void clear() {
|
|
if (valid) {
|
|
glDeleteFramebuffers(1, &fbo_id);
|
|
fbo_id = -1;
|
|
|
|
if (tex_id) {
|
|
glDeleteTextures(1, &tex_id.value());
|
|
tex_id.reset();
|
|
}
|
|
|
|
if (zbuf_stencil_id) {
|
|
glDeleteRenderbuffers(1, &zbuf_stencil_id.value());
|
|
zbuf_stencil_id.reset();
|
|
}
|
|
|
|
valid = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
/*!
|
|
* Main OpenGL renderer.
|
|
* This handles the glClear and all game rendering, but not actual setup, synchronization or imgui
|
|
* stuff.
|
|
*
|
|
* It is simply a collection of bucket renderers, and a few special case ones.
|
|
*/
|
|
class OpenGLRenderer {
|
|
public:
|
|
OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
|
std::shared_ptr<Loader> loader,
|
|
GameVersion version);
|
|
|
|
// rendering interface: takes the dma chain from the game, and some size/debug settings from
|
|
// the graphics system.
|
|
void render(DmaFollower dma, const RenderOptions& settings);
|
|
|
|
private:
|
|
void setup_frame(const RenderOptions& settings);
|
|
void dispatch_buckets(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
|
|
void dispatch_buckets_jak1(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
|
|
void dispatch_buckets_jak2(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
|
|
|
|
void do_pcrtc_effects(float alp, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
|
void init_bucket_renderers_jak1();
|
|
void init_bucket_renderers_jak2();
|
|
void draw_renderer_selection_window();
|
|
void finish_screenshot(const std::string& output_name,
|
|
int px,
|
|
int py,
|
|
int x,
|
|
int y,
|
|
GLuint fbo,
|
|
int read_buffer);
|
|
template <typename T, typename U, class... Args>
|
|
T* init_bucket_renderer(const std::string& name, BucketCategory cat, U id, Args&&... args) {
|
|
auto renderer = std::make_unique<T>(name, (int)id, std::forward<Args>(args)...);
|
|
T* ret = renderer.get();
|
|
m_bucket_renderers.at((int)id) = std::move(renderer);
|
|
m_bucket_categories.at((int)id) = cat;
|
|
return ret;
|
|
}
|
|
|
|
SharedRenderState m_render_state;
|
|
Profiler m_profiler;
|
|
SmallProfiler m_small_profiler;
|
|
SubtitleEditor m_subtitle_editor;
|
|
|
|
std::vector<std::unique_ptr<BucketRenderer>> m_bucket_renderers;
|
|
std::vector<BucketCategory> m_bucket_categories;
|
|
|
|
std::array<float, (int)BucketCategory::MAX_CATEGORIES> m_category_times;
|
|
FullScreenDraw m_blackout_renderer;
|
|
CollideMeshRenderer m_collide_renderer;
|
|
|
|
float m_last_pmode_alp = 1.;
|
|
bool m_enable_fast_blackout_loads = true;
|
|
|
|
struct FboState {
|
|
struct {
|
|
Fbo window; // provided by glfw
|
|
Fbo render_buffer; // temporary buffer to render to
|
|
Fbo resolve_buffer; // temporary buffer to resolve to
|
|
} resources;
|
|
|
|
Fbo* render_fbo = nullptr; // the selected fbo from the three above to use for rendering
|
|
} m_fbo_state;
|
|
|
|
GameVersion m_version;
|
|
};
|