mirror of
https://github.com/open-goal/jak-project
synced 2026-05-23 06:54:31 -04:00
Replace PCRTC framebuffer blit with screen quad draw (#3980)
Taking the suggestion from @Calinou (https://github.com/open-goal/jak-project/pull/3943#issuecomment-3017359144), this replaces the resolve/render framebuffer -> window framebuffer blit with an actual drawn tri-strip which covers the entire viewport, which the PCRTC blackout already does. It appears we have no guarantee what state the internal window framebuffer will be in, so drawing an actual primitive and letting the fragment shader do all the work seems to be the more compatible/functional solution here. Thanks for the suggestion!
This commit is contained in:
@@ -81,7 +81,7 @@ OpenGLRenderer::OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageCallback(opengl_error_callback, nullptr);
|
||||
// disable specific errors
|
||||
const GLuint gl_error_ignores_api_other[1] = {0x20071};
|
||||
const GLuint gl_error_ignores_api_other[1] = {0x20071}; // some annoying nvidia message
|
||||
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 1,
|
||||
&gl_error_ignores_api_other[0], GL_FALSE);
|
||||
#endif
|
||||
@@ -92,6 +92,38 @@ OpenGLRenderer::OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
||||
lg::info("OpenGL context shading language version: {}",
|
||||
(const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
// set up screen draw
|
||||
|
||||
glGenVertexArrays(1, &screen_vao);
|
||||
glGenBuffers(1, &screen_vbo);
|
||||
|
||||
struct Vertex {
|
||||
float x, y;
|
||||
};
|
||||
constexpr std::array<Vertex, 4> vertices = {
|
||||
Vertex{-1, -1},
|
||||
Vertex{-1, 1},
|
||||
Vertex{1, -1},
|
||||
Vertex{1, 1},
|
||||
};
|
||||
|
||||
glBindVertexArray(screen_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, screen_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 4, vertices.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, // location 0 in the shader
|
||||
2, // 2 floats per vert
|
||||
GL_FLOAT, // floats
|
||||
GL_TRUE, // normalized, ignored,
|
||||
sizeof(Vertex), //
|
||||
nullptr //
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
// end set up screen draw
|
||||
|
||||
const tfrag3::Level* common_level = nullptr;
|
||||
{
|
||||
auto p = scoped_prof("load-common");
|
||||
@@ -1595,30 +1627,33 @@ void OpenGLRenderer::do_pcrtc_effects(float alp,
|
||||
window_blit_src = &m_fbo_state.resources.render_buffer;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, window_blit_src->fbo_id);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, // srcX0
|
||||
0, // srcY0
|
||||
window_blit_src->width, // srcX1
|
||||
window_blit_src->height, // srcY1
|
||||
render_state->draw_offset_x, // dstX0
|
||||
render_state->draw_offset_y, // dstY0
|
||||
render_state->draw_offset_x + render_state->draw_region_w, // dstX1
|
||||
render_state->draw_offset_y + render_state->draw_region_h, // dstY1
|
||||
GL_COLOR_BUFFER_BIT, // mask
|
||||
GL_LINEAR // filter
|
||||
);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glViewport(render_state->draw_offset_x, render_state->draw_offset_y, render_state->draw_region_w,
|
||||
render_state->draw_region_h);
|
||||
glBindTexture(GL_TEXTURE_2D, *window_blit_src->tex_id);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glBindVertexArray(screen_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, screen_vbo);
|
||||
|
||||
auto& shader = render_state->shaders[ShaderId::PLAIN_TEXTURE];
|
||||
shader.activate();
|
||||
glUniform1i(glGetUniformLocation(shader.id(), "tex_T0"), 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
if (alp < 1) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glViewport(0, 0, m_fbo_state.resources.window.width, m_fbo_state.resources.window.height);
|
||||
|
||||
m_blackout_renderer.draw(Vector4f(0, 0, 0, 1.f - alp), render_state, prof);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class OpenGLRenderer {
|
||||
OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
||||
std::shared_ptr<Loader> loader,
|
||||
GameVersion version);
|
||||
// TODO delete
|
||||
|
||||
// rendering interface: takes the dma chain from the game, and some size/debug settings from
|
||||
// the graphics system.
|
||||
@@ -135,6 +136,9 @@ class OpenGLRenderer {
|
||||
Fbo* render_fbo = nullptr; // the selected fbo from the three above to use for rendering
|
||||
} m_fbo_state;
|
||||
|
||||
GLuint screen_vao = 0; // vertex array object for a screen-space draw
|
||||
GLuint screen_vbo = 0; // vertex buffer object for a screen-space draw
|
||||
|
||||
std::unique_ptr<BucketRenderer> m_jak2_eye_renderer;
|
||||
std::unique_ptr<BucketRenderer> m_jak3_eye_renderer;
|
||||
GameVersion m_version;
|
||||
|
||||
Reference in New Issue
Block a user