mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
92c4390f0a
Some checks are pending
Build / 🖥️ Windows (push) Waiting to run
Build / 🐧 Linux (push) Waiting to run
Build / 🍎 MacOS (push) Waiting to run
Inform Pages Repo / Generate Documentation (push) Waiting to run
Lint / 📝 Formatting (push) Waiting to run
Lint / 📝 Required Checks (push) Waiting to run
Lint / 📝 Optional Checks (push) Waiting to run
This attempts to do a best-effort quick fix for the sprite alignment in the menus and first person views on higher aspect ratios. This: - Hides the binocular borders completely when using a non-standard ratio ![Screenshot 2024-07-20 021430](https://github.com/user-attachments/assets/c56d3a6c-13b0-43e1-b99b-83292993728c) - Hides the borders in jak's first person view when using a non-standard ratio ![Screenshot 2024-07-20 021310](https://github.com/user-attachments/assets/fefca993-960b-4741-87b7-6d7c17efe89d) - Uses a combination of manual alignment and approximation to get the pause menu closer. ![Screenshot 2024-07-20 151725](https://github.com/user-attachments/assets/2c8aa759-b33a-4fbe-abc6-b5861fc33208) > 32:9 screenshot. I accomplished the last one by manually aligning all of the core sprites and text for the most popular aspect ratios. This means that from a practical standpoint, things should align "perfectly". However, I then used all of those values to derive a polynomial for each adjustment based on the aspect ratio. This allows the game to do a half-decent approximation/interpolation for every aspect ratio in-between the common ones. It won't be perfect, but it will be better than this: ![image](https://github.com/user-attachments/assets/420b1e38-6f88-436a-8e8c-21df6b49428e)
142 lines
5.2 KiB
C++
142 lines
5.2 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/Fbo.h"
|
|
#include "game/graphics/opengl_renderer/Profiler.h"
|
|
#include "game/graphics/opengl_renderer/Shader.h"
|
|
#include "game/graphics/opengl_renderer/TextureAnimator.h"
|
|
#include "game/graphics/opengl_renderer/foreground/Generic2.h"
|
|
#include "game/graphics/opengl_renderer/foreground/Merc2.h"
|
|
#include "game/graphics/opengl_renderer/opengl_utils.h"
|
|
#include "game/tools/filter_menu/filter_menu.h"
|
|
#include "game/tools/subtitle_editor/subtitle_editor.h"
|
|
|
|
struct RenderOptions {
|
|
bool draw_render_debug_window = false;
|
|
bool draw_profiler_window = false;
|
|
bool draw_loader_window = false;
|
|
bool draw_small_profiler_window = false;
|
|
bool draw_subtitle_editor_window = false;
|
|
bool draw_filters_window = false;
|
|
|
|
// internal rendering settings - The OpenGLRenderer will internally use this resolution/format.
|
|
int msaa_samples = 2;
|
|
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;
|
|
|
|
bool save_screenshot = false;
|
|
bool quick_screenshot = false;
|
|
bool internal_res_screenshot = false;
|
|
std::string screenshot_path;
|
|
|
|
float pmode_alp_register = 1.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;
|
|
};
|
|
|
|
/*!
|
|
* 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 dispatch_buckets_jak3(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
|
|
|
|
void do_pcrtc_effects(float alp, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
|
void blit_display();
|
|
void init_bucket_renderers_jak1();
|
|
void init_bucket_renderers_jak2();
|
|
void init_bucket_renderers_jak3();
|
|
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,
|
|
bool quick_screenshot);
|
|
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;
|
|
}
|
|
|
|
const std::vector<GLuint>* anim_slot_array() {
|
|
return m_texture_animator ? m_texture_animator->slots() : nullptr;
|
|
}
|
|
|
|
SharedRenderState m_render_state;
|
|
Profiler m_profiler;
|
|
SmallProfiler m_small_profiler;
|
|
SubtitleEditor* m_subtitle_editor = nullptr;
|
|
FiltersMenu m_filters_menu;
|
|
|
|
std::shared_ptr<Merc2> m_merc2;
|
|
std::shared_ptr<Generic2> m_generic2;
|
|
std::shared_ptr<TextureAnimator> m_texture_animator;
|
|
std::vector<std::unique_ptr<BucketRenderer>> m_bucket_renderers;
|
|
std::vector<BucketCategory> m_bucket_categories;
|
|
class BlitDisplays* m_blit_displays = nullptr;
|
|
|
|
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;
|
|
std::string m_renderer_filter = "";
|
|
|
|
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;
|
|
|
|
std::unique_ptr<BucketRenderer> m_jak2_eye_renderer;
|
|
std::unique_ptr<BucketRenderer> m_jak3_eye_renderer;
|
|
GameVersion m_version;
|
|
};
|