mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
hwr2: Do postimg in hardware
Depends on updated shaders
This commit is contained in:
parent
a9fcff852d
commit
356e3317df
12 changed files with 496 additions and 206 deletions
|
|
@ -130,6 +130,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
arr_ = {{}};
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
constexpr T* begin() noexcept { return &arr_[0]; }
|
||||
|
||||
constexpr const T* begin() const noexcept { return cbegin(); }
|
||||
|
|
|
|||
|
|
@ -603,9 +603,6 @@ static void D_Display(void)
|
|||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
R_ApplyViewMorph(i);
|
||||
|
||||
if (postimgtype[i])
|
||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
target_sources(SRB2SDL2 PRIVATE
|
||||
pass_blit_postimg_screens.cpp
|
||||
pass_blit_postimg_screens.hpp
|
||||
pass_blit_rect.cpp
|
||||
pass_blit_rect.hpp
|
||||
pass_imgui.cpp
|
||||
|
|
|
|||
253
src/hwr2/pass_blit_postimg_screens.cpp
Normal file
253
src/hwr2/pass_blit_postimg_screens.cpp
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "pass_blit_postimg_screens.hpp"
|
||||
|
||||
#include <glm/mat3x3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "../p_tick.h"
|
||||
#include "../i_time.h"
|
||||
#include "../screen.h"
|
||||
|
||||
using namespace srb2;
|
||||
using namespace srb2::hwr2;
|
||||
using namespace srb2::rhi;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct BlitVertex
|
||||
{
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
float z = 0.f;
|
||||
float u = 0.f;
|
||||
float v = 0.f;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static const PipelineDesc kPostimgPipelineDesc =
|
||||
{
|
||||
PipelineProgram::kPostimg,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{{UniformName::kTime, UniformName::kProjection, UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kTexCoord0Min, UniformName::kTexCoord0Max, UniformName::kPostimgWater, UniformName::kPostimgHeat}}}},
|
||||
{{SamplerName::kSampler0}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.0, 0.0, 0.0, 1.0}
|
||||
};
|
||||
|
||||
static const PipelineDesc kPostimgIndexedPipelineDesc =
|
||||
{
|
||||
PipelineProgram::kPostimg,
|
||||
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||
{{{{UniformName::kTime, UniformName::kProjection, UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kTexCoord0Min, UniformName::kTexCoord0Max, UniformName::kPostimgWater, UniformName::kPostimgHeat}}}},
|
||||
{{SamplerName::kSampler0, SamplerName::kSampler1}},
|
||||
std::nullopt,
|
||||
{std::nullopt, {true, true, true, true}},
|
||||
PrimitiveType::kTriangles,
|
||||
CullMode::kNone,
|
||||
FaceWinding::kCounterClockwise,
|
||||
{0.0, 0.0, 0.0, 1.0}
|
||||
};
|
||||
|
||||
static const BlitVertex kVerts[] =
|
||||
{{-.5f, -.5f, 0.f, 0.f, 0.f}, {.5f, -.5f, 0.f, 1.f, 0.f}, {-.5f, .5f, 0.f, 0.f, 1.f}, {.5f, .5f, 0.f, 1.f, 1.f}};
|
||||
|
||||
static const uint16_t kIndices[] = {0, 1, 2, 1, 3, 2};
|
||||
|
||||
BlitPostimgScreens::BlitPostimgScreens(const std::shared_ptr<MainPaletteManager>& palette_mgr)
|
||||
: palette_mgr_(palette_mgr)
|
||||
{
|
||||
}
|
||||
|
||||
BlitPostimgScreens::~BlitPostimgScreens() = default;
|
||||
|
||||
void BlitPostimgScreens::prepass(Rhi& rhi)
|
||||
{
|
||||
if (!renderpass_)
|
||||
{
|
||||
renderpass_ = rhi.create_render_pass(
|
||||
{
|
||||
false,
|
||||
AttachmentLoadOp::kClear,
|
||||
AttachmentStoreOp::kStore,
|
||||
AttachmentLoadOp::kDontCare,
|
||||
AttachmentStoreOp::kDontCare,
|
||||
AttachmentLoadOp::kDontCare,
|
||||
AttachmentStoreOp::kDontCare
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!pipeline_)
|
||||
{
|
||||
pipeline_ = rhi.create_pipeline(kPostimgPipelineDesc);
|
||||
}
|
||||
|
||||
if (!indexed_pipeline_)
|
||||
{
|
||||
indexed_pipeline_ = rhi.create_pipeline(kPostimgIndexedPipelineDesc);
|
||||
}
|
||||
|
||||
if (!quad_vbo_)
|
||||
{
|
||||
quad_vbo_ = rhi.create_buffer({sizeof(kVerts), BufferType::kVertexBuffer, BufferUsage::kImmutable});
|
||||
upload_quad_buffer_ = true;
|
||||
}
|
||||
|
||||
if (!quad_ibo_)
|
||||
{
|
||||
quad_ibo_ = rhi.create_buffer({sizeof(kIndices), BufferType::kIndexBuffer, BufferUsage::kImmutable});
|
||||
upload_quad_buffer_ = true;
|
||||
}
|
||||
|
||||
screen_data_.clear();
|
||||
}
|
||||
|
||||
static Rect get_screen_viewport(uint32_t screen, uint32_t screens, uint32_t w, uint32_t h)
|
||||
{
|
||||
switch (screens)
|
||||
{
|
||||
case 1:
|
||||
return {0, 0, w, h};
|
||||
case 2:
|
||||
return {0, screen == 1 ? (static_cast<int32_t>(h) / 2) : 0, w, (h / 2)};
|
||||
default:
|
||||
switch (screen)
|
||||
{
|
||||
case 2:
|
||||
return {0, 0, w / 2, h / 2};
|
||||
case 3:
|
||||
return {static_cast<int32_t>(w) / 2, 0, w / 2, h / 2};
|
||||
case 0:
|
||||
return {0, static_cast<int32_t>(h) / 2, w / 2, h / 2};
|
||||
case 1:
|
||||
return {static_cast<int32_t>(w) / 2, static_cast<int32_t>(h) / 2, w / 2, h / 2};
|
||||
}
|
||||
}
|
||||
return {0, 0, w, h};
|
||||
}
|
||||
|
||||
void BlitPostimgScreens::transfer(Rhi& rhi, Handle<TransferContext> ctx)
|
||||
{
|
||||
// Upload needed buffers
|
||||
if (upload_quad_buffer_)
|
||||
{
|
||||
rhi.update_buffer(ctx, quad_vbo_, 0, tcb::as_bytes(tcb::span(kVerts)));
|
||||
rhi.update_buffer(ctx, quad_ibo_, 0, tcb::as_bytes(tcb::span(kIndices)));
|
||||
upload_quad_buffer_ = false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < screens_; i++)
|
||||
{
|
||||
BlitPostimgScreens::ScreenConfig& screen_config = screen_configs_[i];
|
||||
BlitPostimgScreens::ScreenData data {};
|
||||
|
||||
if (screen_config.indexed)
|
||||
{
|
||||
data.pipeline = indexed_pipeline_;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.pipeline = pipeline_;
|
||||
}
|
||||
|
||||
VertexAttributeBufferBinding vertex_bindings[] = {{0, quad_vbo_}};
|
||||
TextureBinding sampler_bindings[] =
|
||||
{
|
||||
{SamplerName::kSampler0, screen_config.source},
|
||||
{SamplerName::kSampler1, palette_mgr_->palette()}
|
||||
};
|
||||
|
||||
data.binding_set = rhi.create_binding_set(
|
||||
ctx,
|
||||
data.pipeline,
|
||||
{
|
||||
vertex_bindings,
|
||||
tcb::span(sampler_bindings, screen_config.indexed ? 2 : 1)
|
||||
}
|
||||
);
|
||||
|
||||
glm::mat4 projection = glm::scale(glm::identity<glm::mat4>(), glm::vec3(2.f, -2.f, 1.f));
|
||||
glm::mat4 modelview = glm::identity<glm::mat4>();
|
||||
|
||||
glm::vec2 flip_mirror_uv_displace {0.0, 0.0};
|
||||
if (screen_config.post.mirror)
|
||||
{
|
||||
flip_mirror_uv_displace.x = 1 - (1 - screen_config.uv_size.x);
|
||||
}
|
||||
if (screen_config.post.flip)
|
||||
{
|
||||
flip_mirror_uv_displace.y = 1 - (1 - screen_config.uv_size.y);
|
||||
}
|
||||
|
||||
glm::mat3 texcoord_transform =
|
||||
{
|
||||
glm::vec3(screen_config.uv_size.x * (screen_config.post.mirror ? -1 : 1), 0.0, 0.0),
|
||||
glm::vec3(0.0, screen_config.uv_size.y * (screen_config.post.flip ? -1 : 1), 0.0),
|
||||
glm::vec3(screen_config.uv_offset + flip_mirror_uv_displace, 1.0)
|
||||
};
|
||||
|
||||
glm::vec2 texcoord_min = screen_config.uv_offset;
|
||||
glm::vec2 texcoord_max = screen_config.uv_offset + screen_config.uv_size;
|
||||
|
||||
UniformVariant uniforms[] =
|
||||
{
|
||||
FixedToFloat(g_time.timefrac) + leveltime,
|
||||
projection,
|
||||
modelview,
|
||||
texcoord_transform,
|
||||
texcoord_min,
|
||||
texcoord_max,
|
||||
screen_config.post.water,
|
||||
screen_config.post.heat
|
||||
};
|
||||
|
||||
data.uniform_set = rhi.create_uniform_set(ctx, {uniforms});
|
||||
|
||||
screen_data_[i] = std::move(data);
|
||||
}
|
||||
}
|
||||
|
||||
void BlitPostimgScreens::graphics(Rhi& rhi, Handle<GraphicsContext> ctx)
|
||||
{
|
||||
if (target_)
|
||||
{
|
||||
rhi.begin_render_pass(ctx, {renderpass_, target_, std::nullopt, glm::vec4(0.0, 0.0, 0.0, 1.0)});
|
||||
}
|
||||
else
|
||||
{
|
||||
rhi.begin_default_render_pass(ctx, true);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < screens_; i++)
|
||||
{
|
||||
BlitPostimgScreens::ScreenData& data = screen_data_[i];
|
||||
|
||||
rhi.bind_pipeline(ctx, data.pipeline);
|
||||
rhi.set_viewport(ctx, get_screen_viewport(i, screens_, target_ ? target_width_ : vid.width, target_ ? target_height_ : vid.height));
|
||||
rhi.bind_uniform_set(ctx, 0, data.uniform_set);
|
||||
rhi.bind_binding_set(ctx, data.binding_set);
|
||||
rhi.bind_index_buffer(ctx, quad_ibo_);
|
||||
rhi.draw_indexed(ctx, 6, 0);
|
||||
}
|
||||
|
||||
rhi.end_render_pass(ctx);
|
||||
}
|
||||
|
||||
void BlitPostimgScreens::postpass(Rhi& rhi)
|
||||
{
|
||||
}
|
||||
101
src/hwr2/pass_blit_postimg_screens.hpp
Normal file
101
src/hwr2/pass_blit_postimg_screens.hpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SRB2_HWR2_PASS_BLIT_POSTIMG_SCREENS__
|
||||
#define __SRB2_HWR2_PASS_BLIT_POSTIMG_SCREENS__
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
#include "../rhi/rhi.hpp"
|
||||
#include "../doomdef.h"
|
||||
#include "pass.hpp"
|
||||
#include "pass_resource_managers.hpp"
|
||||
|
||||
namespace srb2::hwr2
|
||||
{
|
||||
|
||||
class BlitPostimgScreens : public Pass
|
||||
{
|
||||
public:
|
||||
struct PostImgConfig
|
||||
{
|
||||
bool water;
|
||||
bool heat;
|
||||
bool flip;
|
||||
bool mirror;
|
||||
};
|
||||
|
||||
struct ScreenConfig
|
||||
{
|
||||
rhi::Handle<rhi::Texture> source;
|
||||
bool indexed = false;
|
||||
glm::vec2 uv_offset {};
|
||||
glm::vec2 uv_size {};
|
||||
PostImgConfig post;
|
||||
};
|
||||
|
||||
private:
|
||||
struct ScreenData
|
||||
{
|
||||
rhi::Handle<rhi::Pipeline> pipeline;
|
||||
rhi::Handle<rhi::BindingSet> binding_set;
|
||||
rhi::Handle<rhi::UniformSet> uniform_set;
|
||||
};
|
||||
|
||||
rhi::Handle<rhi::Pipeline> pipeline_;
|
||||
rhi::Handle<rhi::Pipeline> indexed_pipeline_;
|
||||
rhi::Handle<rhi::RenderPass> renderpass_;
|
||||
rhi::Handle<rhi::Buffer> quad_vbo_;
|
||||
rhi::Handle<rhi::Buffer> quad_ibo_;
|
||||
bool upload_quad_buffer_;
|
||||
|
||||
uint32_t screens_;
|
||||
std::array<ScreenConfig, 4> screen_configs_;
|
||||
srb2::StaticVec<ScreenData, 4> screen_data_;
|
||||
rhi::Handle<rhi::Texture> target_;
|
||||
uint32_t target_width_;
|
||||
uint32_t target_height_;
|
||||
|
||||
std::shared_ptr<MainPaletteManager> palette_mgr_;
|
||||
|
||||
public:
|
||||
BlitPostimgScreens(const std::shared_ptr<MainPaletteManager>& palette_mgr);
|
||||
virtual ~BlitPostimgScreens();
|
||||
|
||||
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 set_num_screens(uint32_t screens) noexcept
|
||||
{
|
||||
SRB2_ASSERT(screens > 0 && screens <= MAXSPLITSCREENPLAYERS);
|
||||
screens_ = screens;
|
||||
}
|
||||
|
||||
void set_screen(uint32_t screen_index, const ScreenConfig& config) noexcept
|
||||
{
|
||||
SRB2_ASSERT(screen_index < MAXSPLITSCREENPLAYERS);
|
||||
screen_configs_[screen_index] = config;
|
||||
}
|
||||
|
||||
void set_target(rhi::Handle<rhi::Texture> target, uint32_t width, uint32_t height) noexcept
|
||||
{
|
||||
target_ = target;
|
||||
target_width_ = width;
|
||||
target_height_ = height;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace srb2::hwr2
|
||||
|
||||
#endif // __SRB2_HWR2_PASS_BLIT_POSTIMG_SCREENS__
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "cxxutil.hpp"
|
||||
#include "f_finale.h"
|
||||
#include "hwr2/pass_blit_postimg_screens.hpp"
|
||||
#include "hwr2/pass_blit_rect.hpp"
|
||||
#include "hwr2/pass_imgui.hpp"
|
||||
#include "hwr2/pass_manager.hpp"
|
||||
|
|
@ -205,7 +206,7 @@ static InternalPassData build_pass_manager()
|
|||
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 blit_postimg_screens = std::make_shared<BlitPostimgScreens>(palette_manager);
|
||||
auto twodee = std::make_shared<TwodeePass>();
|
||||
twodee->flat_manager_ = flat_texture_manager;
|
||||
twodee->data_ = make_twodee_pass_data();
|
||||
|
|
@ -222,20 +223,77 @@ static InternalPassData build_pass_manager()
|
|||
const bool sw_enabled = rendermode == render_soft && gamestate != GS_NULL;
|
||||
|
||||
mgr.set_pass_enabled("software", sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw_prepare", sw_enabled);
|
||||
mgr.set_pass_enabled("blit_sw", sw_enabled && !g_wipeskiprender);
|
||||
mgr.set_pass_enabled("blit_postimg_screens_prepare", sw_enabled);
|
||||
mgr.set_pass_enabled("blit_postimg_screens", sw_enabled && !g_wipeskiprender);
|
||||
}
|
||||
);
|
||||
basic_rendering->insert("software", software_pass);
|
||||
basic_rendering->insert(
|
||||
"blit_sw_prepare",
|
||||
[blit_sw_pass, software_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
"blit_postimg_screens_prepare",
|
||||
[blit_postimg_screens, software_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||
{
|
||||
blit_sw_pass->set_texture(software_pass->screen_texture(), vid.width, vid.height);
|
||||
blit_sw_pass->set_output(framebuffer_manager->main_color(), vid.width, vid.height, false, false);
|
||||
const bool sw_enabled = rendermode == render_soft && gamestate != GS_NULL;
|
||||
const int screens = std::clamp(r_splitscreen + 1, 1, MAXSPLITSCREENPLAYERS);
|
||||
|
||||
blit_postimg_screens->set_num_screens(screens);
|
||||
for (int i = 0; i < screens; i++)
|
||||
{
|
||||
if (sw_enabled)
|
||||
{
|
||||
glm::vec2 uv_offset {0.f, 0.f};
|
||||
glm::vec2 uv_size {1.f, 1.f};
|
||||
|
||||
if (screens > 2)
|
||||
{
|
||||
uv_size = glm::vec2(.5f, .5f);
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
uv_offset = glm::vec2(0.f, 0.f);
|
||||
break;
|
||||
case 1:
|
||||
uv_offset = glm::vec2(.5f, 0.f);
|
||||
break;
|
||||
case 2:
|
||||
uv_offset = glm::vec2(0.f, .5f);
|
||||
break;
|
||||
case 3:
|
||||
uv_offset = glm::vec2(.5f, .5f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (screens > 1)
|
||||
{
|
||||
uv_size = glm::vec2(1.0, 0.5);
|
||||
if (i == 1)
|
||||
{
|
||||
uv_offset = glm::vec2(0.f, .5f);
|
||||
}
|
||||
}
|
||||
|
||||
// "You should probably never have more than 3 levels of indentation" -- Eidolon, the author of this
|
||||
|
||||
blit_postimg_screens->set_screen(
|
||||
i,
|
||||
{
|
||||
software_pass->screen_texture(),
|
||||
true,
|
||||
uv_offset,
|
||||
uv_size,
|
||||
{
|
||||
postimgtype[i] == postimg_water,
|
||||
postimgtype[i] == postimg_heat,
|
||||
postimgtype[i] == postimg_flip,
|
||||
postimgtype[i] == postimg_mirror
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
blit_postimg_screens->set_target(framebuffer_manager->main_color(), vid.width, vid.height);
|
||||
}
|
||||
);
|
||||
basic_rendering->insert("blit_sw", blit_sw_pass);
|
||||
basic_rendering->insert("blit_postimg_screens", blit_postimg_screens);
|
||||
|
||||
basic_rendering->insert(
|
||||
"2d_prepare",
|
||||
|
|
|
|||
|
|
@ -348,8 +348,16 @@ constexpr const char* map_uniform_attribute_symbol_name(rhi::UniformName name)
|
|||
return "u_projection";
|
||||
case rhi::UniformName::kTexCoord0Transform:
|
||||
return "u_texcoord0_transform";
|
||||
case rhi::UniformName::kTexCoord0Min:
|
||||
return "u_texcoord0_min";
|
||||
case rhi::UniformName::kTexCoord0Max:
|
||||
return "u_texcoord0_max";
|
||||
case rhi::UniformName::kTexCoord1Transform:
|
||||
return "u_texcoord1_transform";
|
||||
case rhi::UniformName::kTexCoord1Min:
|
||||
return "u_texcoord1_min";
|
||||
case rhi::UniformName::kTexCoord1Max:
|
||||
return "u_texcoord1_max";
|
||||
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||
return "u_sampler0_is_indexed_alpha";
|
||||
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
||||
|
|
@ -370,6 +378,10 @@ constexpr const char* map_uniform_attribute_symbol_name(rhi::UniformName name)
|
|||
return "u_wipe_colorize_mode";
|
||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||
return "u_wipe_encore_swizzle";
|
||||
case rhi::UniformName::kPostimgWater:
|
||||
return "u_postimg_water";
|
||||
case rhi::UniformName::kPostimgHeat:
|
||||
return "u_postimg_heat";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -387,8 +399,16 @@ constexpr const char* map_uniform_enable_define(rhi::UniformName name)
|
|||
return "ENABLE_U_MODELVIEW";
|
||||
case rhi::UniformName::kTexCoord0Transform:
|
||||
return "ENABLE_U_TEXCOORD0_TRANSFORM";
|
||||
case rhi::UniformName::kTexCoord0Min:
|
||||
return "ENABLE_U_TEXCOORD0_MIN";
|
||||
case rhi::UniformName::kTexCoord0Max:
|
||||
return "ENABLE_U_TEXCOORD0_MAX";
|
||||
case rhi::UniformName::kTexCoord1Transform:
|
||||
return "ENABLE_U_TEXCOORD1_TRANSFORM";
|
||||
case rhi::UniformName::kTexCoord1Min:
|
||||
return "ENABLE_U_TEXCOORD1_MIN";
|
||||
case rhi::UniformName::kTexCoord1Max:
|
||||
return "ENABLE_U_TEXCOORD1_MAX";
|
||||
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||
return "ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA";
|
||||
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
||||
|
|
@ -409,6 +429,10 @@ constexpr const char* map_uniform_enable_define(rhi::UniformName name)
|
|||
return "ENABLE_U_WIPE_COLORIZE_MODE";
|
||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||
return "ENABLE_U_WIPE_ENCORE_SWIZZLE";
|
||||
case rhi::UniformName::kPostimgWater:
|
||||
return "ENABLE_U_POSTIMG_WATER";
|
||||
case rhi::UniformName::kPostimgHeat:
|
||||
return "ENABLE_U_POSTIMG_HEAT";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,23 @@ const ProgramRequirements srb2::rhi::kProgramRequirementsPostprocessWipe = {
|
|||
{UniformName::kWipeEncoreSwizzle, true}}}}},
|
||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, true}, {SamplerName::kSampler2, true}}}};
|
||||
|
||||
const ProgramRequirements srb2::rhi::kProgramRequirementsPostimg = {
|
||||
ProgramVertexInputRequirements {
|
||||
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
|
||||
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, true}}},
|
||||
ProgramUniformRequirements {
|
||||
{{
|
||||
{UniformName::kTime, true},
|
||||
{UniformName::kProjection, true},
|
||||
{UniformName::kModelView, true},
|
||||
{UniformName::kTexCoord0Transform, true},
|
||||
{UniformName::kTexCoord0Min, true},
|
||||
{UniformName::kTexCoord0Max, true},
|
||||
{UniformName::kPostimgWater, true},
|
||||
{UniformName::kPostimgHeat, true}}}},
|
||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, false}}}
|
||||
};
|
||||
|
||||
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept
|
||||
{
|
||||
switch (program)
|
||||
|
|
@ -60,6 +77,8 @@ const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram
|
|||
return kProgramRequirementsUnshadedPaletted;
|
||||
case PipelineProgram::kPostprocessWipe:
|
||||
return kProgramRequirementsPostprocessWipe;
|
||||
case PipelineProgram::kPostimg:
|
||||
return kProgramRequirementsPostimg;
|
||||
default:
|
||||
std::terminate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,8 @@ enum class PipelineProgram
|
|||
{
|
||||
kUnshaded,
|
||||
kUnshadedPaletted,
|
||||
kPostprocessWipe
|
||||
kPostprocessWipe,
|
||||
kPostimg
|
||||
};
|
||||
|
||||
enum class BufferType
|
||||
|
|
@ -201,7 +202,11 @@ enum class UniformName
|
|||
kModelView,
|
||||
kProjection,
|
||||
kTexCoord0Transform,
|
||||
kTexCoord0Min,
|
||||
kTexCoord0Max,
|
||||
kTexCoord1Transform,
|
||||
kTexCoord1Min,
|
||||
kTexCoord1Max,
|
||||
kSampler0IsIndexedAlpha,
|
||||
kSampler1IsIndexedAlpha,
|
||||
kSampler2IsIndexedAlpha,
|
||||
|
|
@ -211,7 +216,9 @@ enum class UniformName
|
|||
kSampler2Size,
|
||||
kSampler3Size,
|
||||
kWipeColorizeMode,
|
||||
kWipeEncoreSwizzle
|
||||
kWipeEncoreSwizzle,
|
||||
kPostimgWater,
|
||||
kPostimgHeat
|
||||
};
|
||||
|
||||
enum class SamplerName
|
||||
|
|
@ -277,6 +284,7 @@ struct ProgramRequirements
|
|||
extern const ProgramRequirements kProgramRequirementsUnshaded;
|
||||
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
|
||||
extern const ProgramRequirements kProgramRequirementsPostprocessWipe;
|
||||
extern const ProgramRequirements kProgramRequirementsPostimg;
|
||||
|
||||
const ProgramRequirements& program_requirements_for_program(PipelineProgram program) noexcept;
|
||||
|
||||
|
|
@ -311,8 +319,16 @@ inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
|
|||
return UniformFormat::kMat4;
|
||||
case UniformName::kTexCoord0Transform:
|
||||
return UniformFormat::kMat3;
|
||||
case UniformName::kTexCoord0Min:
|
||||
return UniformFormat::kFloat2;
|
||||
case UniformName::kTexCoord0Max:
|
||||
return UniformFormat::kFloat2;
|
||||
case UniformName::kTexCoord1Transform:
|
||||
return UniformFormat::kMat3;
|
||||
case UniformName::kTexCoord1Min:
|
||||
return UniformFormat::kFloat2;
|
||||
case UniformName::kTexCoord1Max:
|
||||
return UniformFormat::kFloat2;
|
||||
case UniformName::kSampler0IsIndexedAlpha:
|
||||
return UniformFormat::kInt;
|
||||
case UniformName::kSampler1IsIndexedAlpha:
|
||||
|
|
@ -333,6 +349,10 @@ inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
|
|||
return UniformFormat::kInt;
|
||||
case UniformName::kWipeEncoreSwizzle:
|
||||
return UniformFormat::kInt;
|
||||
case UniformName::kPostimgWater:
|
||||
return UniformFormat::kInt;
|
||||
case UniformName::kPostimgHeat:
|
||||
return UniformFormat::kInt;
|
||||
default:
|
||||
return UniformFormat::kFloat;
|
||||
}
|
||||
|
|
@ -365,7 +385,7 @@ struct UniformInputDesc
|
|||
|
||||
struct SamplerInputDesc
|
||||
{
|
||||
std::vector<SamplerName> enabled_samplers;
|
||||
srb2::StaticVec<SamplerName, 4> enabled_samplers;
|
||||
};
|
||||
|
||||
struct ColorMask
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ static constexpr const char* pipeline_lump_slug(rhi::PipelineProgram program)
|
|||
return "unshadedpaletted";
|
||||
case rhi::PipelineProgram::kPostprocessWipe:
|
||||
return "postprocesswipe";
|
||||
case rhi::PipelineProgram::kPostimg:
|
||||
return "postimg";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
190
src/v_video.cpp
190
src/v_video.cpp
|
|
@ -2898,196 +2898,6 @@ INT32 V_LevelNameHeight(const char *string)
|
|||
return w;
|
||||
}
|
||||
|
||||
boolean *heatshifter = NULL;
|
||||
INT32 lastheight = 0;
|
||||
INT32 heatindex[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
||||
|
||||
//
|
||||
// V_DoPostProcessor
|
||||
//
|
||||
// Perform a particular image postprocessing function.
|
||||
//
|
||||
#include "p_local.h"
|
||||
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
{
|
||||
#if NUMSCREENS < 5
|
||||
// do not enable image post processing for ARM, SH and MIPS CPUs
|
||||
(void)view;
|
||||
(void)type;
|
||||
(void)param;
|
||||
#else
|
||||
INT32 yoffset, xoffset;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (view < 0 || view > 3 || view > r_splitscreen)
|
||||
return;
|
||||
|
||||
if ((view == 1 && r_splitscreen == 1) || view >= 2)
|
||||
yoffset = viewheight;
|
||||
else
|
||||
yoffset = 0;
|
||||
|
||||
if ((view == 1 || view == 3) && r_splitscreen > 1)
|
||||
xoffset = viewwidth;
|
||||
else
|
||||
xoffset = 0;
|
||||
|
||||
if (type == postimg_water)
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y;
|
||||
angle_t disStart = (leveltime * 128) & FINEMASK; // in 0 to FINEANGLE
|
||||
INT32 newpix;
|
||||
INT32 sine;
|
||||
//UINT8 *transme = R_GetTranslucencyTable(tr_trans50);
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
sine = (FINESINE(disStart)*5)>>FRACBITS;
|
||||
newpix = abs(sine);
|
||||
|
||||
if (sine < 0)
|
||||
{
|
||||
M_Memcpy(&tmpscr[(y*vid.width)+xoffset+newpix], &srcscr[(y*vid.width)+xoffset], viewwidth-newpix);
|
||||
|
||||
// Cleanup edge
|
||||
while (newpix)
|
||||
{
|
||||
tmpscr[(y*vid.width)+xoffset+newpix] = srcscr[(y*vid.width)+xoffset];
|
||||
newpix--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
M_Memcpy(&tmpscr[(y*vid.width)+xoffset+0], &srcscr[(y*vid.width)+xoffset+sine], viewwidth-newpix);
|
||||
|
||||
// Cleanup edge
|
||||
while (newpix)
|
||||
{
|
||||
tmpscr[(y*vid.width)+xoffset+viewwidth-newpix] = srcscr[(y*vid.width)+xoffset+(viewwidth-1)];
|
||||
newpix--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Unoptimized version
|
||||
for (x = 0; x < vid.width*vid.bpp; x++)
|
||||
{
|
||||
newpix = (x + sine);
|
||||
|
||||
if (newpix < 0)
|
||||
newpix = 0;
|
||||
else if (newpix >= vid.width)
|
||||
newpix = vid.width-1;
|
||||
|
||||
tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
|
||||
}*/
|
||||
disStart += 22;//the offset into the displacement map, increment each game loop
|
||||
disStart &= FINEMASK; //clip it to FINEMASK
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_motion) // Motion Blur!
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 x, y;
|
||||
|
||||
// TODO: Add a postimg_param so that we can pick the translucency level...
|
||||
UINT8 *transme = R_GetTranslucencyTable(param);
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
for (x = xoffset; x < xoffset+viewwidth; x++)
|
||||
{
|
||||
tmpscr[y*vid.width + x]
|
||||
= colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))];
|
||||
}
|
||||
}
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_flip) // Flip the screen upside-down
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y, y2;
|
||||
|
||||
for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--)
|
||||
M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_heat) // Heat wave
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y;
|
||||
|
||||
// Make sure table is built
|
||||
if (heatshifter == NULL || lastheight != viewheight)
|
||||
{
|
||||
if (heatshifter)
|
||||
Z_Free(heatshifter);
|
||||
|
||||
heatshifter = static_cast<boolean*>(Z_Calloc(viewheight * sizeof(boolean), PU_STATIC, NULL));
|
||||
|
||||
for (y = 0; y < viewheight; y++)
|
||||
{
|
||||
if (M_RandomChance(FRACUNIT/8)) // 12.5%
|
||||
heatshifter[y] = true;
|
||||
}
|
||||
|
||||
heatindex[0] = heatindex[1] = heatindex[2] = heatindex[3] = 0;
|
||||
lastheight = viewheight;
|
||||
}
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
if (heatshifter[heatindex[view]++])
|
||||
{
|
||||
// Shift this row of pixels to the right by 2
|
||||
tmpscr[(y*vid.width)+xoffset] = srcscr[(y*vid.width)+xoffset];
|
||||
M_Memcpy(&tmpscr[(y*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset+vid.dupx], viewwidth-vid.dupx);
|
||||
}
|
||||
else
|
||||
M_Memcpy(&tmpscr[(y*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
|
||||
|
||||
heatindex[view] %= viewheight;
|
||||
}
|
||||
|
||||
heatindex[view]++;
|
||||
heatindex[view] %= vid.height;
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_mirror) // Flip the screen on the x axis
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y, x, x2;
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
for (x = xoffset, x2 = xoffset+((viewwidth*vid.bpp)-1); x < xoffset+(viewwidth*vid.bpp); x++, x2--)
|
||||
tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x];
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Generates a RGB565 color look-up table
|
||||
void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -409,8 +409,6 @@ void V_DrawRightAlignedLSTitleHighString(INT32 x, INT32 y, INT32 option, const c
|
|||
void V_DrawCenteredLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);
|
||||
|
||||
void V_DrawPatchFill(patch_t *pat);
|
||||
|
||||
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue