mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
hwr2: overhaul wipe rendering
This commit is contained in:
parent
0a9e9bbbae
commit
31ce947659
14 changed files with 647 additions and 154 deletions
|
|
@ -800,6 +800,9 @@ void D_SRB2Loop(void)
|
|||
HW3S_BeginFrameUpdate();
|
||||
#endif
|
||||
|
||||
I_NewTwodeeFrame();
|
||||
I_NewImguiFrame();
|
||||
|
||||
if (realtics > 0 || singletics)
|
||||
{
|
||||
// don't skip more than 10 frames at a time
|
||||
|
|
@ -1491,6 +1494,9 @@ void D_SRB2Main(void)
|
|||
CONS_Printf("I_StartupGraphics()...\n");
|
||||
I_StartupGraphics();
|
||||
|
||||
I_NewTwodeeFrame();
|
||||
I_NewImguiFrame();
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Lactozilla: Add every hardware mode CVAR and CCMD.
|
||||
// Has to be done before the configuration file loads,
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ extern UINT8 g_wipetype;
|
|||
extern UINT8 g_wipeframe;
|
||||
extern boolean g_wipereverse;
|
||||
extern boolean g_wipeskiprender;
|
||||
extern boolean g_wipeencorewiggle;
|
||||
extern boolean WipeStageTitle;
|
||||
|
||||
extern INT32 lastwipetic;
|
||||
|
|
@ -159,6 +160,14 @@ void F_WipeStageTitle(void);
|
|||
#define F_WipeColorFill(c) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, c)
|
||||
tic_t F_GetWipeLength(UINT8 wipetype);
|
||||
boolean F_WipeExists(UINT8 wipetype);
|
||||
/// @brief true if the wipetype is to-black
|
||||
boolean F_WipeIsToBlack(UINT8 wipetype);
|
||||
/// @brief true if the wipetype is to-white
|
||||
boolean F_WipeIsToWhite(UINT8 wipetype);
|
||||
/// @brief true if the wipetype is to-invert
|
||||
boolean F_WipeIsToInvert(UINT8 wipetype);
|
||||
/// @brief true if the wipetype is modulated from the previous frame
|
||||
boolean F_WipeIsCrossfade(UINT8 wipetype);
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
|||
177
src/f_wipe.c
177
src/f_wipe.c
|
|
@ -85,6 +85,138 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
|
|||
99 // wipe_cutscene_final (hardcoded)
|
||||
};
|
||||
|
||||
static boolean g_wipedef_toblack[NUMWIPEDEFS] = {
|
||||
true, // wipe_credits_intermediate (0)
|
||||
|
||||
true, // wipe_level_toblack
|
||||
true, // wipe_intermission_toblack
|
||||
true, // wipe_voting_toblack,
|
||||
true, // wipe_continuing_toblack
|
||||
true, // wipe_titlescreen_toblack
|
||||
true, // wipe_menu_toblack
|
||||
true, // wipe_credits_toblack
|
||||
true, // wipe_evaluation_toblack
|
||||
true, // wipe_gameend_toblack
|
||||
true, // wipe_intro_toblack (hardcoded)
|
||||
true, // wipe_ending_toblack (hardcoded)
|
||||
true, // wipe_cutscene_toblack (hardcoded)
|
||||
|
||||
false, // wipe_encore_toinvert
|
||||
false, // wipe_encore_towhite
|
||||
|
||||
true, // wipe_level_final
|
||||
true, // wipe_intermission_final
|
||||
true, // wipe_voting_final
|
||||
true, // wipe_continuing_final
|
||||
true, // wipe_titlescreen_final
|
||||
true, // wipe_menu_final
|
||||
true, // wipe_credits_final
|
||||
true, // wipe_evaluation_final
|
||||
true, // wipe_gameend_final
|
||||
true, // wipe_intro_final (hardcoded)
|
||||
true, // wipe_ending_final (hardcoded)
|
||||
true // wipe_cutscene_final (hardcoded)
|
||||
};
|
||||
|
||||
static boolean g_wipedef_toinvert[NUMWIPEDEFS] = {
|
||||
false, // wipe_credits_intermediate (0)
|
||||
|
||||
false, // wipe_level_toblack
|
||||
false, // wipe_intermission_toblack
|
||||
false, // wipe_voting_toblack,
|
||||
false, // wipe_continuing_toblack
|
||||
false, // wipe_titlescreen_toblack
|
||||
false, // wipe_menu_toblack
|
||||
false, // wipe_credits_toblack
|
||||
false, // wipe_evaluation_toblack
|
||||
false, // wipe_gameend_toblack
|
||||
false, // wipe_intro_toblack (hardcoded)
|
||||
false, // wipe_ending_toblack (hardcoded)
|
||||
false, // wipe_cutscene_toblack (hardcoded)
|
||||
|
||||
true, // wipe_encore_toinvert
|
||||
false, // wipe_encore_towhite
|
||||
|
||||
false, // wipe_level_final
|
||||
false, // wipe_intermission_final
|
||||
false, // wipe_voting_final
|
||||
false, // wipe_continuing_final
|
||||
false, // wipe_titlescreen_final
|
||||
false, // wipe_menu_final
|
||||
false, // wipe_credits_final
|
||||
false, // wipe_evaluation_final
|
||||
false, // wipe_gameend_final
|
||||
false, // wipe_intro_final (hardcoded)
|
||||
false, // wipe_ending_final (hardcoded)
|
||||
false // wipe_cutscene_final (hardcoded)
|
||||
};
|
||||
|
||||
static boolean g_wipedef_towhite[NUMWIPEDEFS] = {
|
||||
false, // wipe_credits_intermediate (0)
|
||||
|
||||
false, // wipe_level_toblack
|
||||
false, // wipe_intermission_toblack
|
||||
false, // wipe_voting_toblack,
|
||||
false, // wipe_continuing_toblack
|
||||
false, // wipe_titlescreen_toblack
|
||||
false, // wipe_menu_toblack
|
||||
false, // wipe_credits_toblack
|
||||
false, // wipe_evaluation_toblack
|
||||
false, // wipe_gameend_toblack
|
||||
false, // wipe_intro_toblack (hardcoded)
|
||||
false, // wipe_ending_toblack (hardcoded)
|
||||
false, // wipe_cutscene_toblack (hardcoded)
|
||||
|
||||
false, // wipe_encore_toinvert
|
||||
true, // wipe_encore_towhite
|
||||
|
||||
false, // wipe_level_final
|
||||
false, // wipe_intermission_final
|
||||
false, // wipe_voting_final
|
||||
false, // wipe_continuing_final
|
||||
false, // wipe_titlescreen_final
|
||||
false, // wipe_menu_final
|
||||
false, // wipe_credits_final
|
||||
false, // wipe_evaluation_final
|
||||
false, // wipe_gameend_final
|
||||
false, // wipe_intro_final (hardcoded)
|
||||
false, // wipe_ending_final (hardcoded)
|
||||
false // wipe_cutscene_final (hardcoded)
|
||||
};
|
||||
|
||||
static boolean g_wipedef_crossfade[NUMWIPEDEFS] = {
|
||||
false, // wipe_credits_intermediate (0)
|
||||
|
||||
false, // wipe_level_toblack
|
||||
false, // wipe_intermission_toblack
|
||||
false, // wipe_voting_toblack,
|
||||
false, // wipe_continuing_toblack
|
||||
false, // wipe_titlescreen_toblack
|
||||
false, // wipe_menu_toblack
|
||||
false, // wipe_credits_toblack
|
||||
false, // wipe_evaluation_toblack
|
||||
false, // wipe_gameend_toblack
|
||||
false, // wipe_intro_toblack (hardcoded)
|
||||
false, // wipe_ending_toblack (hardcoded)
|
||||
false, // wipe_cutscene_toblack (hardcoded)
|
||||
|
||||
false, // wipe_encore_toinvert
|
||||
false, // wipe_encore_towhite
|
||||
|
||||
true, // wipe_level_final
|
||||
true, // wipe_intermission_final
|
||||
true, // wipe_voting_final
|
||||
true, // wipe_continuing_final
|
||||
true, // wipe_titlescreen_final
|
||||
true, // wipe_menu_final
|
||||
true, // wipe_credits_final
|
||||
true, // wipe_evaluation_final
|
||||
true, // wipe_gameend_final
|
||||
true, // wipe_intro_final (hardcoded)
|
||||
true, // wipe_ending_final (hardcoded)
|
||||
true // wipe_cutscene_final (hardcoded)
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// SCREEN WIPE PACKAGE
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -94,6 +226,7 @@ UINT8 g_wipetype = 0;
|
|||
UINT8 g_wipeframe = 0;
|
||||
boolean g_wipereverse = false;
|
||||
boolean g_wipeskiprender = false;
|
||||
boolean g_wipeencorewiggle = false;
|
||||
boolean WipeStageTitle = false;
|
||||
INT32 lastwipetic = 0;
|
||||
|
||||
|
|
@ -207,8 +340,9 @@ void F_WipeStartScreen(void)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
wipe_scr_start = screens[3];
|
||||
I_ReadScreen(wipe_scr_start);
|
||||
// wipe_scr_start = screens[3];
|
||||
// I_ReadScreen(wipe_scr_start);
|
||||
I_FinishUpdateWipeStartScreen();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -224,9 +358,10 @@ void F_WipeEndScreen(void)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
wipe_scr_end = screens[4];
|
||||
I_ReadScreen(wipe_scr_end);
|
||||
V_DrawBlock(0, 0, 0, vid.width, vid.height, wipe_scr_start);
|
||||
// wipe_scr_end = screens[4];
|
||||
// I_ReadScreen(wipe_scr_end);
|
||||
// V_DrawBlock(0, 0, 0, vid.width, vid.height, wipe_scr_start);
|
||||
I_FinishUpdateWipeEndScreen();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -360,10 +495,11 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r
|
|||
|
||||
if (encorewiggle)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_opengl)
|
||||
#endif
|
||||
F_DoEncoreWiggle(wipeframe);
|
||||
g_wipeencorewiggle = wipeframe - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_wipeencorewiggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +517,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r
|
|||
#endif
|
||||
}
|
||||
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
I_FinishUpdateWipe(); // page flip or blit buffer
|
||||
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
|
|
@ -454,3 +590,24 @@ boolean F_WipeExists(UINT8 wipetype)
|
|||
return !(lumpnum == LUMPERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
boolean F_WipeIsToBlack(UINT8 wipetype)
|
||||
{
|
||||
return g_wipedef_toblack[wipetype];
|
||||
}
|
||||
|
||||
boolean F_WipeIsToWhite(UINT8 wipetype)
|
||||
{
|
||||
return g_wipedef_towhite[wipetype];
|
||||
}
|
||||
|
||||
boolean F_WipeIsToInvert(UINT8 wipetype)
|
||||
{
|
||||
return g_wipedef_toinvert[wipetype];
|
||||
}
|
||||
|
||||
boolean F_WipeIsCrossfade(UINT8 wipetype)
|
||||
{
|
||||
return g_wipedef_crossfade[wipetype];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ void LambdaPass::postpass(Rhi& rhi)
|
|||
}
|
||||
|
||||
PassManager::PassManager() = default;
|
||||
PassManager::PassManager(const PassManager&) = default;
|
||||
PassManager& PassManager::operator=(const PassManager&) = default;
|
||||
|
||||
void PassManager::insert(const std::string& name, std::shared_ptr<Pass> pass)
|
||||
{
|
||||
|
|
@ -124,13 +126,8 @@ std::weak_ptr<Pass> PassManager::for_name(const std::string& name)
|
|||
return passes_[itr->second].pass;
|
||||
}
|
||||
|
||||
void PassManager::render(Rhi& rhi) const
|
||||
void PassManager::prepass(Rhi& rhi)
|
||||
{
|
||||
if (passes_.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& pass : passes_)
|
||||
{
|
||||
if (pass.enabled)
|
||||
|
|
@ -138,27 +135,32 @@ void PassManager::render(Rhi& rhi) const
|
|||
pass.pass->prepass(rhi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handle<TransferContext> tc = rhi.begin_transfer();
|
||||
void PassManager::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||
{
|
||||
for (auto& pass : passes_)
|
||||
{
|
||||
if (pass.enabled)
|
||||
{
|
||||
pass.pass->transfer(rhi, tc);
|
||||
pass.pass->transfer(rhi, ctx);
|
||||
}
|
||||
}
|
||||
rhi.end_transfer(tc);
|
||||
}
|
||||
|
||||
Handle<GraphicsContext> gc = rhi.begin_graphics();
|
||||
void PassManager::graphics(Rhi& rhi, Handle<GraphicsContext> ctx)
|
||||
{
|
||||
for (auto& pass : passes_)
|
||||
{
|
||||
if (pass.enabled)
|
||||
{
|
||||
pass.pass->graphics(rhi, gc);
|
||||
pass.pass->graphics(rhi, ctx);
|
||||
}
|
||||
}
|
||||
rhi.end_graphics(gc);
|
||||
}
|
||||
|
||||
void PassManager::postpass(Rhi& rhi)
|
||||
{
|
||||
for (auto& pass : passes_)
|
||||
{
|
||||
if (pass.enabled)
|
||||
|
|
@ -167,3 +169,23 @@ void PassManager::render(Rhi& rhi) const
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PassManager::render(Rhi& rhi)
|
||||
{
|
||||
if (passes_.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
prepass(rhi);
|
||||
|
||||
Handle<TransferContext> tc = rhi.begin_transfer();
|
||||
transfer(rhi, tc);
|
||||
rhi.end_transfer(tc);
|
||||
|
||||
Handle<GraphicsContext> gc = rhi.begin_graphics();
|
||||
graphics(rhi, gc);
|
||||
rhi.end_graphics(gc);
|
||||
|
||||
postpass(rhi);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
namespace srb2::hwr2
|
||||
{
|
||||
|
||||
class PassManager
|
||||
class PassManager final : public Pass
|
||||
{
|
||||
struct PassManagerEntry
|
||||
{
|
||||
|
|
@ -37,11 +37,16 @@ class PassManager
|
|||
|
||||
public:
|
||||
PassManager();
|
||||
PassManager(const PassManager&) = delete;
|
||||
PassManager(const PassManager&);
|
||||
PassManager(PassManager&&) = delete;
|
||||
PassManager& operator=(const PassManager&) = delete;
|
||||
PassManager& operator=(const PassManager&);
|
||||
PassManager& operator=(PassManager&&) = delete;
|
||||
|
||||
virtual void prepass(rhi::Rhi& rhi) override;
|
||||
virtual void transfer(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx) override;
|
||||
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
|
||||
virtual void postpass(rhi::Rhi& rhi) override;
|
||||
|
||||
void insert(const std::string& name, std::shared_ptr<Pass> pass);
|
||||
void insert(const std::string& name, std::function<void(PassManager&, rhi::Rhi&)> prepass_func);
|
||||
void insert(
|
||||
|
|
@ -52,7 +57,7 @@ public:
|
|||
std::weak_ptr<Pass> for_name(const std::string& name);
|
||||
void set_pass_enabled(const std::string& name, bool enabled);
|
||||
|
||||
void render(rhi::Rhi& rhi) const;
|
||||
void render(rhi::Rhi& rhi);
|
||||
};
|
||||
|
||||
} // namespace srb2::hwr2
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ static const PipelineDesc kWipePipelineDesc = {
|
|||
{VertexAttributeName::kPosition, 0, 0},
|
||||
{VertexAttributeName::kTexCoord0, 0, 12},
|
||||
}},
|
||||
{{{{UniformName::kProjection}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1}},
|
||||
{{{{UniformName::kProjection, UniformName::kWipeColorizeMode, UniformName::kWipeEncoreSwizzle}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1, SamplerName::kSampler2}},
|
||||
std::nullopt,
|
||||
{PixelFormat::kRGBA8, std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
|
|
@ -55,7 +55,7 @@ static const PipelineDesc kWipePipelineDesc = {
|
|||
FaceWinding::kCounterClockwise,
|
||||
{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
PostprocessWipePass::PostprocessWipePass() : Pass()
|
||||
PostprocessWipePass::PostprocessWipePass()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +89,27 @@ void PostprocessWipePass::prepass(Rhi& rhi)
|
|||
uint32_t wipe_type = g_wipetype;
|
||||
uint32_t wipe_frame = g_wipeframe;
|
||||
bool wipe_reverse = g_wipereverse;
|
||||
|
||||
wipe_color_mode_ = 0; // TODO 0 = modulate, 1 = invert, 2 = MD to black, 3 = MD to white
|
||||
if (F_WipeIsToBlack(wipe_type))
|
||||
{
|
||||
wipe_color_mode_ = 2;
|
||||
}
|
||||
else if (F_WipeIsToWhite(wipe_type))
|
||||
{
|
||||
wipe_color_mode_ = 3;
|
||||
}
|
||||
else if (F_WipeIsToInvert(wipe_type))
|
||||
{
|
||||
wipe_color_mode_ = 1;
|
||||
}
|
||||
else if (F_WipeIsCrossfade(wipe_type))
|
||||
{
|
||||
wipe_color_mode_ = 0;
|
||||
}
|
||||
|
||||
wipe_swizzle_ = g_wipeencorewiggle;
|
||||
|
||||
if (wipe_type >= 100 || wipe_frame >= 100)
|
||||
{
|
||||
return;
|
||||
|
|
@ -145,7 +166,7 @@ void PostprocessWipePass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
|||
return;
|
||||
}
|
||||
|
||||
if (source_ == kNullHandle)
|
||||
if (start_ == kNullHandle || end_ == kNullHandle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -166,13 +187,17 @@ void PostprocessWipePass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
|||
rhi.update_texture(ctx, wipe_tex_, {0, 0, mask_w_, mask_h_}, PixelFormat::kR8, data);
|
||||
|
||||
UniformVariant uniforms[] = {
|
||||
{// Projection
|
||||
std::array<std::array<float, 4>, 4> {
|
||||
{{2.f, 0.f, 0.f, 0.f}, {0.f, 2.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}}}}};
|
||||
{std::array<std::array<float, 4>, 4> {
|
||||
{{2.f, 0.f, 0.f, 0.f}, {0.f, 2.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}}}},
|
||||
{static_cast<int32_t>(wipe_color_mode_)},
|
||||
{static_cast<int32_t>(wipe_swizzle_)}};
|
||||
us_ = rhi.create_uniform_set(ctx, {tcb::span(uniforms)});
|
||||
|
||||
VertexAttributeBufferBinding vbos[] = {{0, vbo_}};
|
||||
TextureBinding tx[] = {{SamplerName::kSampler0, source_}, {SamplerName::kSampler1, wipe_tex_}};
|
||||
TextureBinding tx[] = {
|
||||
{SamplerName::kSampler0, start_},
|
||||
{SamplerName::kSampler1, end_},
|
||||
{SamplerName::kSampler2, wipe_tex_}};
|
||||
bs_ = rhi.create_binding_set(ctx, pipeline_, {vbos, tx});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace srb2::hwr2
|
|||
|
||||
class PostprocessWipePass final : public Pass
|
||||
{
|
||||
// Internal RHI resources
|
||||
rhi::Handle<rhi::RenderPass> render_pass_;
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Buffer> vbo_;
|
||||
|
|
@ -28,14 +29,17 @@ class PostprocessWipePass final : public Pass
|
|||
rhi::Handle<rhi::UniformSet> us_;
|
||||
rhi::Handle<rhi::BindingSet> bs_;
|
||||
rhi::Handle<rhi::Texture> wipe_tex_;
|
||||
rhi::Handle<rhi::Texture> source_;
|
||||
uint32_t source_w_ = 0;
|
||||
uint32_t source_h_ = 0;
|
||||
int wipe_color_mode_ = 0;
|
||||
int wipe_swizzle_ = 0;
|
||||
|
||||
// Pass parameters
|
||||
rhi::Handle<rhi::Texture> start_;
|
||||
rhi::Handle<rhi::Texture> end_;
|
||||
rhi::Handle<rhi::Texture> target_;
|
||||
uint32_t target_w_ = 0;
|
||||
uint32_t target_h_ = 0;
|
||||
|
||||
// Mask lump loading
|
||||
std::vector<uint8_t> mask_data_;
|
||||
uint32_t mask_w_ = 0;
|
||||
uint32_t mask_h_ = 0;
|
||||
|
|
@ -49,12 +53,7 @@ public:
|
|||
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
|
||||
virtual void postpass(rhi::Rhi& rhi) override;
|
||||
|
||||
void set_source(rhi::Handle<rhi::Texture> source, uint32_t width, uint32_t height) noexcept
|
||||
{
|
||||
source_ = source;
|
||||
source_w_ = width;
|
||||
source_h_ = height;
|
||||
}
|
||||
void set_start(rhi::Handle<rhi::Texture> start) noexcept { start_ = start; }
|
||||
|
||||
void set_end(rhi::Handle<rhi::Texture> end) noexcept { end_ = end; }
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,16 @@ void FramebufferManager::prepass(Rhi& rhi)
|
|||
rhi.destroy_texture(post_colors_[1]);
|
||||
post_colors_[1] = kNullHandle;
|
||||
}
|
||||
if (wipe_start_color_ != kNullHandle)
|
||||
{
|
||||
rhi.destroy_texture(wipe_start_color_);
|
||||
wipe_start_color_ = kNullHandle;
|
||||
}
|
||||
if (wipe_end_color_ != kNullHandle)
|
||||
{
|
||||
rhi.destroy_texture(wipe_end_color_);
|
||||
wipe_end_color_ = kNullHandle;
|
||||
}
|
||||
}
|
||||
width_ = current_width;
|
||||
height_ = current_height;
|
||||
|
|
@ -85,6 +95,15 @@ void FramebufferManager::prepass(Rhi& rhi)
|
|||
{
|
||||
post_colors_[1] = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
||||
}
|
||||
|
||||
if (wipe_start_color_ == kNullHandle)
|
||||
{
|
||||
wipe_start_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
||||
}
|
||||
if (wipe_end_color_ == kNullHandle)
|
||||
{
|
||||
wipe_end_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManager::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||
|
|
@ -131,6 +150,45 @@ void MainPaletteManager::postpass(Rhi& rhi)
|
|||
{
|
||||
}
|
||||
|
||||
CommonResourcesManager::CommonResourcesManager() = default;
|
||||
CommonResourcesManager::~CommonResourcesManager() = default;
|
||||
|
||||
void CommonResourcesManager::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!init_)
|
||||
{
|
||||
black_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
||||
white_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
||||
transparent_ = rhi.create_texture({TextureFormat::kRGBA, 1, 1});
|
||||
}
|
||||
}
|
||||
|
||||
void CommonResourcesManager::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||
{
|
||||
if (!init_)
|
||||
{
|
||||
uint8_t black[4] = {0, 0, 0, 255};
|
||||
tcb::span<const std::byte> black_bytes = tcb::as_bytes(tcb::span(black, 4));
|
||||
uint8_t white[4] = {255, 255, 255, 255};
|
||||
tcb::span<const std::byte> white_bytes = tcb::as_bytes(tcb::span(white, 4));
|
||||
uint8_t transparent[4] = {0, 0, 0, 0};
|
||||
tcb::span<const std::byte> transparent_bytes = tcb::as_bytes(tcb::span(transparent, 4));
|
||||
|
||||
rhi.update_texture(ctx, black_, {0, 0, 1, 1}, PixelFormat::kRGBA8, black_bytes);
|
||||
rhi.update_texture(ctx, white_, {0, 0, 1, 1}, PixelFormat::kRGBA8, white_bytes);
|
||||
rhi.update_texture(ctx, transparent_, {0, 0, 1, 1}, PixelFormat::kRGBA8, transparent_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonResourcesManager::graphics(Rhi& rhi, Handle<GraphicsContext> ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void CommonResourcesManager::postpass(Rhi& rhi)
|
||||
{
|
||||
init_ = true;
|
||||
}
|
||||
|
||||
static uint32_t get_flat_size(lumpnum_t lump)
|
||||
{
|
||||
SRB2_ASSERT(lump != LUMPERROR);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class FramebufferManager final : public Pass
|
|||
std::array<rhi::Handle<rhi::Texture>, 2> main_colors_;
|
||||
rhi::Handle<rhi::Renderbuffer> main_depth_;
|
||||
std::array<rhi::Handle<rhi::Texture>, 2> post_colors_;
|
||||
rhi::Handle<rhi::Texture> wipe_start_color_;
|
||||
rhi::Handle<rhi::Texture> wipe_end_color_;
|
||||
std::size_t main_index_ = 0;
|
||||
std::size_t post_index_ = 0;
|
||||
std::size_t width_ = 0;
|
||||
|
|
@ -67,6 +69,9 @@ public:
|
|||
return post_colors_[1 - post_index_];
|
||||
};
|
||||
|
||||
rhi::Handle<rhi::Texture> wipe_start_color() const noexcept { return wipe_start_color_; }
|
||||
rhi::Handle<rhi::Texture> wipe_end_color() const noexcept { return wipe_end_color_; }
|
||||
|
||||
std::size_t width() const noexcept { return width_; }
|
||||
std::size_t height() const noexcept { return height_; }
|
||||
};
|
||||
|
|
@ -87,6 +92,27 @@ public:
|
|||
rhi::Handle<rhi::Texture> palette() const noexcept { return palette_; }
|
||||
};
|
||||
|
||||
class CommonResourcesManager final : public Pass
|
||||
{
|
||||
bool init_ = false;
|
||||
rhi::Handle<rhi::Texture> black_;
|
||||
rhi::Handle<rhi::Texture> white_;
|
||||
rhi::Handle<rhi::Texture> transparent_;
|
||||
|
||||
public:
|
||||
CommonResourcesManager();
|
||||
virtual ~CommonResourcesManager();
|
||||
|
||||
virtual void prepass(rhi::Rhi& rhi) override;
|
||||
virtual void transfer(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx) override;
|
||||
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
|
||||
virtual void postpass(rhi::Rhi& rhi) override;
|
||||
|
||||
rhi::Handle<rhi::Texture> black() const noexcept { return black_; }
|
||||
rhi::Handle<rhi::Texture> white() const noexcept { return white_; }
|
||||
rhi::Handle<rhi::Texture> transparent() const noexcept { return transparent_; }
|
||||
};
|
||||
|
||||
/*
|
||||
A note to the reader:
|
||||
|
||||
|
|
|
|||
|
|
@ -130,10 +130,25 @@ extern boolean allow_fullscreen;
|
|||
*/
|
||||
void I_UpdateNoBlit(void);
|
||||
|
||||
/** \brief Begin a new Twodee frame.
|
||||
*/
|
||||
void I_NewTwodeeFrame(void);
|
||||
|
||||
/** \brief Begin a new dear imgui frame.
|
||||
*/
|
||||
void I_NewImguiFrame(void);
|
||||
|
||||
/** \brief Update video system with updating frame
|
||||
*/
|
||||
void I_FinishUpdate(void);
|
||||
|
||||
void I_FinishUpdateWipeStartScreen(void);
|
||||
void I_FinishUpdateWipeEndScreen(void);
|
||||
|
||||
/** \brief Update video system during a wipe
|
||||
*/
|
||||
void I_FinishUpdateWipe(void);
|
||||
|
||||
/** \brief I_FinishUpdate(), but vsync disabled
|
||||
*/
|
||||
void I_UpdateNoVsync(void);
|
||||
|
|
|
|||
|
|
@ -40,13 +40,26 @@ using namespace srb2;
|
|||
using namespace srb2::hwr2;
|
||||
using namespace srb2::rhi;
|
||||
|
||||
static std::shared_ptr<PassManager> g_passmanager;
|
||||
namespace
|
||||
{
|
||||
struct InternalPassData
|
||||
{
|
||||
std::shared_ptr<PassManager> resource_passmanager;
|
||||
std::shared_ptr<PassManager> normal_rendering;
|
||||
std::shared_ptr<PassManager> wipe_capture_start_rendering;
|
||||
std::shared_ptr<PassManager> wipe_capture_end_rendering;
|
||||
std::shared_ptr<PassManager> wipe_rendering;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static std::unique_ptr<InternalPassData> g_passes;
|
||||
static Rhi* g_last_known_rhi = nullptr;
|
||||
|
||||
Handle<Rhi> srb2::sys::g_current_rhi = kNullHandle;
|
||||
|
||||
static bool rhi_changed()
|
||||
static bool rhi_changed(Rhi* rhi)
|
||||
{
|
||||
return false;
|
||||
return g_last_known_rhi != rhi;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
@ -103,50 +116,49 @@ static void finish_legacy_ogl_update()
|
|||
}
|
||||
#endif
|
||||
|
||||
static std::shared_ptr<PassManager> build_pass_manager()
|
||||
static InternalPassData build_pass_manager()
|
||||
{
|
||||
std::shared_ptr<PassManager> manager = std::make_shared<PassManager>();
|
||||
auto framebuffer_manager = std::make_shared<FramebufferManager>();
|
||||
auto palette_manager = std::make_shared<MainPaletteManager>();
|
||||
auto common_resources_manager = std::make_shared<CommonResourcesManager>();
|
||||
auto flat_texture_manager = std::make_shared<FlatTextureManager>();
|
||||
auto resource_manager = std::make_shared<PassManager>();
|
||||
|
||||
std::shared_ptr<FramebufferManager> framebuffer_manager = std::make_shared<FramebufferManager>();
|
||||
std::shared_ptr<MainPaletteManager> palette_manager = std::make_shared<MainPaletteManager>();
|
||||
std::shared_ptr<FlatTextureManager> flat_texture_manager = std::make_shared<FlatTextureManager>();
|
||||
resource_manager->insert("framebuffer_manager", framebuffer_manager);
|
||||
resource_manager->insert("palette_manager", palette_manager);
|
||||
resource_manager->insert("common_resources_manager", common_resources_manager);
|
||||
resource_manager->insert("flat_texture_manager", flat_texture_manager);
|
||||
|
||||
std::shared_ptr<SoftwarePass> software_pass = std::make_shared<SoftwarePass>();
|
||||
std::shared_ptr<BlitRectPass> blit_sw_pass = std::make_shared<BlitRectPass>(palette_manager, true);
|
||||
std::shared_ptr<TwodeePass> twodee = std::make_shared<TwodeePass>();
|
||||
// Basic Rendering is responsible for drawing 3d, 2d, and postprocessing the image.
|
||||
// This is drawn to an alternating internal color buffer.
|
||||
// Normal Rendering will output the result via final composite and present.
|
||||
// Wipe Start Screen and Wipe End Screen will save to special color buffers used for Wipe Rendering.
|
||||
auto basic_rendering = std::make_shared<PassManager>();
|
||||
|
||||
auto software_pass = std::make_shared<SoftwarePass>();
|
||||
auto blit_sw_pass = std::make_shared<BlitRectPass>(palette_manager, true);
|
||||
auto twodee = std::make_shared<TwodeePass>();
|
||||
twodee->flat_manager_ = flat_texture_manager;
|
||||
twodee->data_ = make_twodee_pass_data();
|
||||
twodee->ctx_ = &g_2d;
|
||||
std::shared_ptr<BlitRectPass> pp_simple_blit_pass = std::make_shared<BlitRectPass>(false);
|
||||
std::shared_ptr<PostprocessWipePass> pp_wipe_pass = std::make_shared<PostprocessWipePass>();
|
||||
std::shared_ptr<ScreenshotPass> screenshot_pass = std::make_shared<ScreenshotPass>();
|
||||
std::shared_ptr<ImguiPass> imgui_pass = std::make_shared<ImguiPass>();
|
||||
std::shared_ptr<BlitRectPass> final_composite_pass = std::make_shared<BlitRectPass>(true);
|
||||
auto pp_simple_blit_pass = std::make_shared<BlitRectPass>(false);
|
||||
auto screenshot_pass = std::make_shared<ScreenshotPass>();
|
||||
auto imgui_pass = std::make_shared<ImguiPass>();
|
||||
auto final_composite_pass = std::make_shared<BlitRectPass>(true);
|
||||
|
||||
manager->insert("framebuffer_manager", framebuffer_manager);
|
||||
manager->insert("palette_manager", palette_manager);
|
||||
manager->insert("flat_texture_manager", flat_texture_manager);
|
||||
|
||||
manager->insert(
|
||||
basic_rendering->insert(
|
||||
"3d_prepare",
|
||||
[framebuffer_manager](PassManager& mgr, Rhi&)
|
||||
{
|
||||
const bool sw_enabled = rendermode == render_soft;
|
||||
|
||||
mgr.set_pass_enabled("software", !g_wipeskiprender && sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw_prepare", !g_wipeskiprender && sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw", !g_wipeskiprender && sw_enabled);
|
||||
},
|
||||
[framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
if (!WipeInAction)
|
||||
{
|
||||
framebuffer_manager->swap_main();
|
||||
}
|
||||
mgr.set_pass_enabled("software", sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw_prepare", sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw", sw_enabled);
|
||||
}
|
||||
);
|
||||
manager->insert("software", software_pass);
|
||||
manager->insert(
|
||||
basic_rendering->insert("software", software_pass);
|
||||
basic_rendering->insert(
|
||||
"blit_sw_prepare",
|
||||
[blit_sw_pass, software_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
|
|
@ -154,9 +166,9 @@ static std::shared_ptr<PassManager> build_pass_manager()
|
|||
blit_sw_pass->set_output(framebuffer_manager->current_main_color(), vid.width, vid.height, false, false);
|
||||
}
|
||||
);
|
||||
manager->insert("blit_sw", blit_sw_pass);
|
||||
basic_rendering->insert("blit_sw", blit_sw_pass);
|
||||
|
||||
manager->insert(
|
||||
basic_rendering->insert(
|
||||
"2d_prepare",
|
||||
[twodee, framebuffer_manager, palette_manager](PassManager& mgr, Rhi&)
|
||||
{
|
||||
|
|
@ -166,74 +178,62 @@ static std::shared_ptr<PassManager> build_pass_manager()
|
|||
twodee->output_height_ = vid.height;
|
||||
}
|
||||
);
|
||||
manager->insert("2d", twodee);
|
||||
basic_rendering->insert("2d", twodee);
|
||||
|
||||
manager->insert(
|
||||
"pp_final_prepare",
|
||||
[](PassManager& mgr, Rhi&)
|
||||
{
|
||||
mgr.set_pass_enabled("pp_final_wipe_prepare", WipeInAction);
|
||||
mgr.set_pass_enabled("pp_final_wipe", WipeInAction);
|
||||
mgr.set_pass_enabled("pp_final_wipe_flip", WipeInAction);
|
||||
}
|
||||
);
|
||||
manager->insert(
|
||||
// basic_rendering->insert(
|
||||
// "pp_final_prepare",
|
||||
// [](PassManager& mgr, Rhi&)
|
||||
// {
|
||||
// mgr.set_pass_enabled("pp_final_wipe_prepare", WipeInAction);
|
||||
// mgr.set_pass_enabled("pp_final_wipe", WipeInAction);
|
||||
// mgr.set_pass_enabled("pp_final_wipe_flip", WipeInAction);
|
||||
// }
|
||||
// );
|
||||
basic_rendering->insert(
|
||||
"pp_final_simple_blit_prepare",
|
||||
[pp_simple_blit_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
Handle<Texture> color = framebuffer_manager->current_main_color();
|
||||
if (WipeInAction && !g_wipereverse)
|
||||
{
|
||||
// Non-reverse wipes are "fade-outs" from the previous frame.
|
||||
color = framebuffer_manager->previous_main_color();
|
||||
}
|
||||
pp_simple_blit_pass->set_texture(color, vid.width, vid.height);
|
||||
framebuffer_manager->swap_post();
|
||||
pp_simple_blit_pass->set_texture(framebuffer_manager->current_main_color(), vid.width, vid.height);
|
||||
pp_simple_blit_pass
|
||||
->set_output(framebuffer_manager->current_post_color(), vid.width, vid.height, false, false);
|
||||
->set_output(framebuffer_manager->current_post_color(), vid.width, vid.height, false, true);
|
||||
}
|
||||
);
|
||||
manager->insert("pp_final_simple_blit", pp_simple_blit_pass);
|
||||
manager->insert(
|
||||
"pp_final_simple_blit_flip",
|
||||
[framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
|
||||
);
|
||||
manager->insert(
|
||||
"pp_final_wipe_prepare",
|
||||
[pp_wipe_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
pp_wipe_pass->set_source(framebuffer_manager->previous_post_color(), vid.width, vid.height);
|
||||
pp_wipe_pass->set_end(framebuffer_manager->current_main_color());
|
||||
pp_wipe_pass->set_target(framebuffer_manager->current_post_color(), vid.width, vid.height);
|
||||
}
|
||||
);
|
||||
manager->insert("pp_final_wipe", pp_wipe_pass);
|
||||
manager->insert(
|
||||
"pp_final_wipe_flip",
|
||||
[framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
|
||||
);
|
||||
basic_rendering->insert("pp_final_simple_blit", pp_simple_blit_pass);
|
||||
// basic_rendering->insert(
|
||||
// "pp_final_simple_blit_flip",
|
||||
// [framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
|
||||
// );
|
||||
|
||||
manager->insert(
|
||||
// basic_rendering->insert(
|
||||
// "pp_final_wipe_flip",
|
||||
// [framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
|
||||
// );
|
||||
|
||||
basic_rendering->insert(
|
||||
"screenshot_prepare",
|
||||
[screenshot_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
screenshot_pass->set_source(framebuffer_manager->previous_post_color(), vid.width, vid.height);
|
||||
screenshot_pass->set_source(framebuffer_manager->current_post_color(), vid.width, vid.height);
|
||||
}
|
||||
);
|
||||
manager->insert("screenshot", screenshot_pass);
|
||||
basic_rendering->insert("screenshot", screenshot_pass);
|
||||
|
||||
manager->insert(
|
||||
// Composite-present takes the current postprocess result and outputs it to the default framebuffer.
|
||||
// It also renders imgui and presents the screen.
|
||||
auto composite_present_rendering = std::make_shared<PassManager>();
|
||||
|
||||
composite_present_rendering->insert(
|
||||
"final_composite_prepare",
|
||||
[final_composite_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
final_composite_pass->set_texture(framebuffer_manager->previous_post_color(), vid.width, vid.height);
|
||||
final_composite_pass->set_output(kNullHandle, vid.realwidth, vid.realheight, true, false);
|
||||
final_composite_pass->set_texture(framebuffer_manager->current_post_color(), vid.width, vid.height);
|
||||
final_composite_pass->set_output(kNullHandle, vid.realwidth, vid.realheight, true, true);
|
||||
}
|
||||
);
|
||||
manager->insert("final_composite", final_composite_pass);
|
||||
|
||||
manager->insert("imgui", imgui_pass);
|
||||
|
||||
manager->insert(
|
||||
composite_present_rendering->insert("final_composite", final_composite_pass);
|
||||
composite_present_rendering->insert("imgui", imgui_pass);
|
||||
composite_present_rendering->insert(
|
||||
"present",
|
||||
[](PassManager&, Rhi& rhi) {},
|
||||
[framebuffer_manager](PassManager&, Rhi& rhi)
|
||||
|
|
@ -241,25 +241,104 @@ static std::shared_ptr<PassManager> build_pass_manager()
|
|||
rhi.present();
|
||||
rhi.finish();
|
||||
framebuffer_manager->reset_post();
|
||||
|
||||
// TODO fix this: it's an ugly hack to work around issues with wipes
|
||||
// Why this works:
|
||||
// - Menus run F_RunWipe which is an inner update loop calling I_FinishUpdate, with this global set
|
||||
// - After exiting F_RunWipe, g_2d should normally be cleared by I_FinishUpdate
|
||||
// - Unfortunately, the menu has already run all its draw calls when exiting F_RunWipe
|
||||
// - That causes a single-frame flash of no 2d content, which is an epilepsy risk.
|
||||
// - By not clearing the 2d context, we are redrawing 2d every frame of the wipe
|
||||
// - This "works" because we draw 2d to the normal color buffer, not the postprocessed screen.
|
||||
// - It does result in the FPS counter being mangled during the wipe though.
|
||||
// - To fix the issues around wipes, wipes need to be a "sub" game state, and eliminate the inner tic loops.
|
||||
if (!WipeInAction)
|
||||
{
|
||||
g_2d = Twodee();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return manager;
|
||||
// Normal rendering combines basic rendering and composite-present.
|
||||
auto normal_rendering = std::make_shared<PassManager>();
|
||||
|
||||
normal_rendering->insert("resource_manager", resource_manager);
|
||||
normal_rendering->insert("basic_rendering", basic_rendering);
|
||||
normal_rendering->insert("composite_present_rendering", composite_present_rendering);
|
||||
|
||||
// Wipe Start Screen Capture rendering
|
||||
auto wipe_capture_start_rendering = std::make_shared<PassManager>();
|
||||
auto wipe_start_blit = std::make_shared<BlitRectPass>();
|
||||
|
||||
wipe_capture_start_rendering->insert("resource_manager", resource_manager);
|
||||
wipe_capture_start_rendering->insert("basic_rendering", basic_rendering);
|
||||
wipe_capture_start_rendering->insert(
|
||||
"wipe_capture_prepare",
|
||||
[framebuffer_manager, wipe_start_blit](PassManager&, Rhi&)
|
||||
{
|
||||
wipe_start_blit->set_texture(framebuffer_manager->previous_post_color(), vid.width, vid.height);
|
||||
wipe_start_blit->set_output(framebuffer_manager->wipe_start_color(), vid.width, vid.height, false, true);
|
||||
}
|
||||
);
|
||||
wipe_capture_start_rendering->insert("wipe_capture", wipe_start_blit);
|
||||
|
||||
// Wipe End Screen Capture rendering
|
||||
auto wipe_capture_end_rendering = std::make_shared<PassManager>();
|
||||
auto wipe_end_blit = std::make_shared<BlitRectPass>();
|
||||
|
||||
wipe_capture_end_rendering->insert("resource_manager", resource_manager);
|
||||
wipe_capture_end_rendering->insert("basic_rendering", basic_rendering);
|
||||
wipe_capture_end_rendering->insert(
|
||||
"wipe_capture_prepare",
|
||||
[framebuffer_manager, wipe_end_blit](PassManager&, Rhi&)
|
||||
{
|
||||
wipe_end_blit->set_texture(framebuffer_manager->current_post_color(), vid.width, vid.height);
|
||||
wipe_end_blit->set_output(framebuffer_manager->wipe_end_color(), vid.width, vid.height, false, true);
|
||||
}
|
||||
);
|
||||
wipe_capture_end_rendering->insert("wipe_capture", wipe_end_blit);
|
||||
|
||||
// Wipe rendering only runs the wipe shader on the start and end screens, and adds composite-present.
|
||||
auto wipe_rendering = std::make_shared<PassManager>();
|
||||
|
||||
auto pp_wipe_pass = std::make_shared<PostprocessWipePass>();
|
||||
|
||||
wipe_rendering->insert("resource_manager", resource_manager);
|
||||
wipe_rendering->insert(
|
||||
"pp_final_wipe_prepare",
|
||||
[pp_wipe_pass, framebuffer_manager, common_resources_manager](PassManager&, Rhi&)
|
||||
{
|
||||
framebuffer_manager->swap_post();
|
||||
Handle<Texture> start = framebuffer_manager->wipe_start_color();
|
||||
Handle<Texture> end = framebuffer_manager->wipe_end_color();
|
||||
if (g_wipereverse)
|
||||
{
|
||||
std::swap(start, end);
|
||||
}
|
||||
pp_wipe_pass->set_start(start);
|
||||
pp_wipe_pass->set_end(end);
|
||||
pp_wipe_pass->set_target(framebuffer_manager->current_post_color(), vid.width, vid.height);
|
||||
}
|
||||
);
|
||||
wipe_rendering->insert("pp_final_wipe", pp_wipe_pass);
|
||||
wipe_rendering->insert("composite_present_rendering", composite_present_rendering);
|
||||
|
||||
InternalPassData ret;
|
||||
ret.resource_passmanager = resource_manager;
|
||||
ret.normal_rendering = normal_rendering;
|
||||
ret.wipe_capture_start_rendering = wipe_capture_start_rendering;
|
||||
ret.wipe_capture_end_rendering = wipe_capture_end_rendering;
|
||||
ret.wipe_rendering = wipe_rendering;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void I_NewTwodeeFrame(void)
|
||||
{
|
||||
g_2d = Twodee();
|
||||
}
|
||||
|
||||
void I_NewImguiFrame(void)
|
||||
{
|
||||
// TODO move this to srb2loop
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize.x = vid.realwidth;
|
||||
io.DisplaySize.y = vid.realheight;
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
static void maybe_reinit_passes(Rhi* rhi)
|
||||
{
|
||||
if (rhi_changed(rhi) || !g_passes)
|
||||
{
|
||||
g_last_known_rhi = rhi;
|
||||
g_passes = std::make_unique<InternalPassData>(build_pass_manager());
|
||||
}
|
||||
}
|
||||
|
||||
void I_FinishUpdate(void)
|
||||
|
|
@ -277,17 +356,34 @@ void I_FinishUpdate(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
// TODO move this to srb2loop
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize.x = vid.realwidth;
|
||||
io.DisplaySize.y = vid.realheight;
|
||||
ImGui::NewFrame();
|
||||
rhi::Rhi* rhi = sys::get_rhi(sys::g_current_rhi);
|
||||
|
||||
if (rhi_changed() || !g_passmanager)
|
||||
if (rhi == nullptr)
|
||||
{
|
||||
g_passmanager = build_pass_manager();
|
||||
// ???
|
||||
return;
|
||||
}
|
||||
|
||||
maybe_reinit_passes(rhi);
|
||||
|
||||
g_passes->normal_rendering->render(*rhi);
|
||||
}
|
||||
|
||||
void I_FinishUpdateWipeStartScreen(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
finish_legacy_ogl_update();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rhi::Rhi* rhi = sys::get_rhi(sys::g_current_rhi);
|
||||
|
||||
if (rhi == nullptr)
|
||||
|
|
@ -296,5 +392,63 @@ void I_FinishUpdate(void)
|
|||
return;
|
||||
}
|
||||
|
||||
g_passmanager->render(*rhi);
|
||||
maybe_reinit_passes(rhi);
|
||||
|
||||
g_passes->wipe_capture_start_rendering->render(*rhi);
|
||||
}
|
||||
|
||||
void I_FinishUpdateWipeEndScreen(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
finish_legacy_ogl_update();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rhi::Rhi* rhi = sys::get_rhi(sys::g_current_rhi);
|
||||
|
||||
if (rhi == nullptr)
|
||||
{
|
||||
// ???
|
||||
return;
|
||||
}
|
||||
|
||||
maybe_reinit_passes(rhi);
|
||||
|
||||
g_passes->wipe_capture_end_rendering->render(*rhi);
|
||||
}
|
||||
|
||||
void I_FinishUpdateWipe(void)
|
||||
{
|
||||
if (rendermode == render_none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
finish_legacy_ogl_update();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rhi::Rhi* rhi = sys::get_rhi(sys::g_current_rhi);
|
||||
|
||||
if (rhi == nullptr)
|
||||
{
|
||||
// ???
|
||||
return;
|
||||
}
|
||||
|
||||
maybe_reinit_passes(rhi);
|
||||
|
||||
g_passes->wipe_rendering->render(*rhi);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,6 +334,10 @@ constexpr const char* map_uniform_attribute_symbol_name(rhi::UniformName name)
|
|||
return "u_texcoord0_transform";
|
||||
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||
return "u_sampler0_is_indexed_alpha";
|
||||
case rhi::UniformName::kWipeColorizeMode:
|
||||
return "u_wipe_colorize_mode";
|
||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||
return "u_wipe_encore_swizzle";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -353,6 +357,10 @@ constexpr const char* map_uniform_enable_define(rhi::UniformName name)
|
|||
return "ENABLE_U_TEXCOORD0_TRANSFORM";
|
||||
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||
return "ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA";
|
||||
case rhi::UniformName::kWipeColorizeMode:
|
||||
return "ENABLE_U_WIPE_COLORIZE_MODE";
|
||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||
return "ENABLE_U_WIPE_ENCORE_SWIZZLE";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,11 @@ const ProgramRequirements srb2::rhi::kProgramRequirementsPostprocessWipe = {
|
|||
ProgramVertexInputRequirements {
|
||||
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
|
||||
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, true}}},
|
||||
ProgramUniformRequirements {{{{{UniformName::kProjection, true}, {UniformName::kModelView, true}}}}},
|
||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, true}}}};
|
||||
ProgramUniformRequirements {
|
||||
{{{{UniformName::kProjection, true},
|
||||
{UniformName::kWipeColorizeMode, true},
|
||||
{UniformName::kWipeEncoreSwizzle, true}}}}},
|
||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, true}, {SamplerName::kSampler2, true}}}};
|
||||
|
||||
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -196,7 +196,9 @@ enum class UniformName
|
|||
kModelView,
|
||||
kProjection,
|
||||
kTexCoord0Transform,
|
||||
kSampler0IsIndexedAlpha
|
||||
kSampler0IsIndexedAlpha,
|
||||
kWipeColorizeMode,
|
||||
kWipeEncoreSwizzle
|
||||
};
|
||||
|
||||
enum class SamplerName
|
||||
|
|
@ -306,6 +308,10 @@ inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
|
|||
return UniformFormat::kMat3;
|
||||
case UniformName::kSampler0IsIndexedAlpha:
|
||||
return UniformFormat::kInt;
|
||||
case UniformName::kWipeColorizeMode:
|
||||
return UniformFormat::kInt;
|
||||
case UniformName::kWipeEncoreSwizzle:
|
||||
return UniformFormat::kInt;
|
||||
default:
|
||||
return UniformFormat::kFloat;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue