Files
jak-project/game/graphics/opengl_renderer/foreground/Generic2.cpp
T
water111 0fcc7eb8e9 [merc2] Support emerc (#2147)
This adds environment mapping support to `Merc2`, and turns it on for
Jak 1 and Jak 2.

- The performance is much better
- Jak 1 can be toggled back to the old behavior with `(set! *emerc-hack*
#f)`. The new environment mapping is identical to the old one everywhere
I checked.
- Jak 1 still falls back to generic for ripple/texscroll/blerc/eyes -
there's still no dynamic texture or vertex updating support. The eye
detection stuff will sometimes flag stuff as eyes which is not eyes,
which is fine, but means that generic will be used in some places where
emerc could be used. For example, the shiny plates on jak's arm will be
drawn with generic because jak has eyes.
- Jak 2 hasn't been checked super carefully against PCSX2 yet.
- Jak 2 still isn't technically using emerc, but instead putting emerc
models in the merc bucket.
- The interface to merc is a lot different now and totally custom
OpenGOAL DMA code. The original merc drawing asm doesn't run anymore.
- The FR3 format changed
- Something funky going on with foreground lighting in escape, but
doesn't seem to be related to this change?

Performance comparison, jak 1, in likely the most generic-merc heavy
spot:

![image](https://user-images.githubusercontent.com/48171810/213882718-feb2ab59-95a9-44a2-b0e5-95fba860c7b0.png)

![image](https://user-images.githubusercontent.com/48171810/213882736-8dbbf4c9-6bbf-4d0b-96ce-78d63274660c.png)
2023-01-22 18:30:31 -05:00

90 lines
3.1 KiB
C++

#include "Generic2.h"
#include "game/graphics/opengl_renderer/AdgifHandler.h"
#include "third-party/imgui/imgui.h"
Generic2::Generic2(const std::string& name,
int my_id,
u32 num_verts,
u32 num_frags,
u32 num_adgif,
u32 num_buckets)
: BucketRenderer(name, my_id) {
m_verts.resize(num_verts);
m_fragments.resize(num_frags);
m_adgifs.resize(num_adgif);
m_buckets.resize(num_buckets);
m_indices.resize(num_verts * 3);
opengl_setup();
}
Generic2::~Generic2() {
opengl_cleanup();
}
void Generic2::draw_debug_window() {
ImGui::Checkbox("Alpha 1", &m_alpha_draw_enable[0]);
ImGui::Checkbox("Alpha 2", &m_alpha_draw_enable[1]);
ImGui::Checkbox("Alpha 3", &m_alpha_draw_enable[2]);
ImGui::Checkbox("Alpha 4", &m_alpha_draw_enable[3]);
ImGui::Checkbox("Alpha 5", &m_alpha_draw_enable[4]);
ImGui::Checkbox("Alpha 6", &m_alpha_draw_enable[5]);
ImGui::Checkbox("Alpha 7", &m_alpha_draw_enable[6]);
ImGui::Text("Max Seen:");
ImGui::Text(" frag: %d/%d %.1f%%", m_max_frags_seen, (int)m_fragments.size(),
100.f * m_max_frags_seen / (float)m_fragments.size());
ImGui::Text(" vert: %d/%d %.1f%%", m_max_verts_seen, (int)m_verts.size(),
100.f * m_max_verts_seen / (float)m_verts.size());
ImGui::Text(" adgif: %d/%d %.1f%%", m_max_frags_seen, (int)m_adgifs.size(),
100.f * m_max_adgifs_seen / (float)m_adgifs.size());
ImGui::Text(" idx: %d/%d %.1f%%", m_max_frags_seen, (int)m_indices.size(),
100.f * m_max_indices_seen / (float)m_indices.size());
ImGui::Text(" bucket: %d/%d %.1f%%", m_max_frags_seen, (int)m_fragments.size(),
100.f * m_max_frags_seen / (float)m_fragments.size());
}
/*!
* Main render function for Generic2. This will be passed a DMA "follower" from the main
* OpenGLRenderer that can read a DMA chain, starting at the DMA "bucket" that was filled by the
* generic renderer. This renderer is expected to follow the chain until it reaches "next_bucket"
* and then return.
*/
void Generic2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) {
// completely clear out state. These will get populated by the rendering functions, then displayed
// by draw_debug_window() if the user opens that window
m_debug.clear();
m_stats = Stats();
// if the user has asked to disable the renderer, just advance the dma follower to the next
// bucket and return immediately.
if (!m_enabled) {
while (dma.current_tag_offset() != render_state->next_bucket) {
dma.read_and_advance();
}
return;
}
// Generic2 has 3 passes.
{
// our first pass is to go over the DMA chain from the game and extract the data into buffers
auto p = prof.make_scoped_child("dma");
process_dma(dma, render_state->next_bucket);
}
{
// the next pass is to look at all of that data, and figure out the best order to draw it
// using OpenGL
auto p = prof.make_scoped_child("setup");
setup_draws();
}
{
// the final pass is the actual drawing.
auto p = prof.make_scoped_child("drawing");
do_draws(render_state, p);
}
}