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 T* begin() noexcept { return &arr_[0]; }
|
||||||
|
|
||||||
constexpr const T* begin() const noexcept { return cbegin(); }
|
constexpr const T* begin() const noexcept { return cbegin(); }
|
||||||
|
|
|
||||||
|
|
@ -603,9 +603,6 @@ static void D_Display(void)
|
||||||
for (i = 0; i <= r_splitscreen; i++)
|
for (i = 0; i <= r_splitscreen; i++)
|
||||||
{
|
{
|
||||||
R_ApplyViewMorph(i);
|
R_ApplyViewMorph(i);
|
||||||
|
|
||||||
if (postimgtype[i])
|
|
||||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
target_sources(SRB2SDL2 PRIVATE
|
target_sources(SRB2SDL2 PRIVATE
|
||||||
|
pass_blit_postimg_screens.cpp
|
||||||
|
pass_blit_postimg_screens.hpp
|
||||||
pass_blit_rect.cpp
|
pass_blit_rect.cpp
|
||||||
pass_blit_rect.hpp
|
pass_blit_rect.hpp
|
||||||
pass_imgui.cpp
|
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 "cxxutil.hpp"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "hwr2/pass_blit_postimg_screens.hpp"
|
||||||
#include "hwr2/pass_blit_rect.hpp"
|
#include "hwr2/pass_blit_rect.hpp"
|
||||||
#include "hwr2/pass_imgui.hpp"
|
#include "hwr2/pass_imgui.hpp"
|
||||||
#include "hwr2/pass_manager.hpp"
|
#include "hwr2/pass_manager.hpp"
|
||||||
|
|
@ -205,7 +206,7 @@ static InternalPassData build_pass_manager()
|
||||||
auto basic_rendering = std::make_shared<PassManager>();
|
auto basic_rendering = std::make_shared<PassManager>();
|
||||||
|
|
||||||
auto software_pass = std::make_shared<SoftwarePass>();
|
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>();
|
auto twodee = std::make_shared<TwodeePass>();
|
||||||
twodee->flat_manager_ = flat_texture_manager;
|
twodee->flat_manager_ = flat_texture_manager;
|
||||||
twodee->data_ = make_twodee_pass_data();
|
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;
|
const bool sw_enabled = rendermode == render_soft && gamestate != GS_NULL;
|
||||||
|
|
||||||
mgr.set_pass_enabled("software", sw_enabled);
|
mgr.set_pass_enabled("software", sw_enabled);
|
||||||
mgr.set_pass_enabled("blit_sw_prepare", sw_enabled);
|
mgr.set_pass_enabled("blit_postimg_screens_prepare", sw_enabled);
|
||||||
mgr.set_pass_enabled("blit_sw", sw_enabled && !g_wipeskiprender);
|
mgr.set_pass_enabled("blit_postimg_screens", sw_enabled && !g_wipeskiprender);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
basic_rendering->insert("software", software_pass);
|
basic_rendering->insert("software", software_pass);
|
||||||
basic_rendering->insert(
|
basic_rendering->insert(
|
||||||
"blit_sw_prepare",
|
"blit_postimg_screens_prepare",
|
||||||
[blit_sw_pass, software_pass, framebuffer_manager](PassManager&, Rhi&)
|
[blit_postimg_screens, software_pass, framebuffer_manager](PassManager&, Rhi&)
|
||||||
{
|
{
|
||||||
blit_sw_pass->set_texture(software_pass->screen_texture(), vid.width, vid.height);
|
const bool sw_enabled = rendermode == render_soft && gamestate != GS_NULL;
|
||||||
blit_sw_pass->set_output(framebuffer_manager->main_color(), vid.width, vid.height, false, false);
|
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(
|
basic_rendering->insert(
|
||||||
"2d_prepare",
|
"2d_prepare",
|
||||||
|
|
|
||||||
|
|
@ -348,8 +348,16 @@ constexpr const char* map_uniform_attribute_symbol_name(rhi::UniformName name)
|
||||||
return "u_projection";
|
return "u_projection";
|
||||||
case rhi::UniformName::kTexCoord0Transform:
|
case rhi::UniformName::kTexCoord0Transform:
|
||||||
return "u_texcoord0_transform";
|
return "u_texcoord0_transform";
|
||||||
|
case rhi::UniformName::kTexCoord0Min:
|
||||||
|
return "u_texcoord0_min";
|
||||||
|
case rhi::UniformName::kTexCoord0Max:
|
||||||
|
return "u_texcoord0_max";
|
||||||
case rhi::UniformName::kTexCoord1Transform:
|
case rhi::UniformName::kTexCoord1Transform:
|
||||||
return "u_texcoord1_transform";
|
return "u_texcoord1_transform";
|
||||||
|
case rhi::UniformName::kTexCoord1Min:
|
||||||
|
return "u_texcoord1_min";
|
||||||
|
case rhi::UniformName::kTexCoord1Max:
|
||||||
|
return "u_texcoord1_max";
|
||||||
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||||
return "u_sampler0_is_indexed_alpha";
|
return "u_sampler0_is_indexed_alpha";
|
||||||
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
||||||
|
|
@ -370,6 +378,10 @@ constexpr const char* map_uniform_attribute_symbol_name(rhi::UniformName name)
|
||||||
return "u_wipe_colorize_mode";
|
return "u_wipe_colorize_mode";
|
||||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||||
return "u_wipe_encore_swizzle";
|
return "u_wipe_encore_swizzle";
|
||||||
|
case rhi::UniformName::kPostimgWater:
|
||||||
|
return "u_postimg_water";
|
||||||
|
case rhi::UniformName::kPostimgHeat:
|
||||||
|
return "u_postimg_heat";
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -387,8 +399,16 @@ constexpr const char* map_uniform_enable_define(rhi::UniformName name)
|
||||||
return "ENABLE_U_MODELVIEW";
|
return "ENABLE_U_MODELVIEW";
|
||||||
case rhi::UniformName::kTexCoord0Transform:
|
case rhi::UniformName::kTexCoord0Transform:
|
||||||
return "ENABLE_U_TEXCOORD0_TRANSFORM";
|
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:
|
case rhi::UniformName::kTexCoord1Transform:
|
||||||
return "ENABLE_U_TEXCOORD1_TRANSFORM";
|
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:
|
case rhi::UniformName::kSampler0IsIndexedAlpha:
|
||||||
return "ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA";
|
return "ENABLE_U_SAMPLER0_IS_INDEXED_ALPHA";
|
||||||
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
case rhi::UniformName::kSampler1IsIndexedAlpha:
|
||||||
|
|
@ -409,6 +429,10 @@ constexpr const char* map_uniform_enable_define(rhi::UniformName name)
|
||||||
return "ENABLE_U_WIPE_COLORIZE_MODE";
|
return "ENABLE_U_WIPE_COLORIZE_MODE";
|
||||||
case rhi::UniformName::kWipeEncoreSwizzle:
|
case rhi::UniformName::kWipeEncoreSwizzle:
|
||||||
return "ENABLE_U_WIPE_ENCORE_SWIZZLE";
|
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:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,23 @@ const ProgramRequirements srb2::rhi::kProgramRequirementsPostprocessWipe = {
|
||||||
{UniformName::kWipeEncoreSwizzle, true}}}}},
|
{UniformName::kWipeEncoreSwizzle, true}}}}},
|
||||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, true}, {SamplerName::kSampler2, 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
|
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept
|
||||||
{
|
{
|
||||||
switch (program)
|
switch (program)
|
||||||
|
|
@ -60,6 +77,8 @@ const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram
|
||||||
return kProgramRequirementsUnshadedPaletted;
|
return kProgramRequirementsUnshadedPaletted;
|
||||||
case PipelineProgram::kPostprocessWipe:
|
case PipelineProgram::kPostprocessWipe:
|
||||||
return kProgramRequirementsPostprocessWipe;
|
return kProgramRequirementsPostprocessWipe;
|
||||||
|
case PipelineProgram::kPostimg:
|
||||||
|
return kProgramRequirementsPostimg;
|
||||||
default:
|
default:
|
||||||
std::terminate();
|
std::terminate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,8 @@ enum class PipelineProgram
|
||||||
{
|
{
|
||||||
kUnshaded,
|
kUnshaded,
|
||||||
kUnshadedPaletted,
|
kUnshadedPaletted,
|
||||||
kPostprocessWipe
|
kPostprocessWipe,
|
||||||
|
kPostimg
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BufferType
|
enum class BufferType
|
||||||
|
|
@ -201,7 +202,11 @@ enum class UniformName
|
||||||
kModelView,
|
kModelView,
|
||||||
kProjection,
|
kProjection,
|
||||||
kTexCoord0Transform,
|
kTexCoord0Transform,
|
||||||
|
kTexCoord0Min,
|
||||||
|
kTexCoord0Max,
|
||||||
kTexCoord1Transform,
|
kTexCoord1Transform,
|
||||||
|
kTexCoord1Min,
|
||||||
|
kTexCoord1Max,
|
||||||
kSampler0IsIndexedAlpha,
|
kSampler0IsIndexedAlpha,
|
||||||
kSampler1IsIndexedAlpha,
|
kSampler1IsIndexedAlpha,
|
||||||
kSampler2IsIndexedAlpha,
|
kSampler2IsIndexedAlpha,
|
||||||
|
|
@ -211,7 +216,9 @@ enum class UniformName
|
||||||
kSampler2Size,
|
kSampler2Size,
|
||||||
kSampler3Size,
|
kSampler3Size,
|
||||||
kWipeColorizeMode,
|
kWipeColorizeMode,
|
||||||
kWipeEncoreSwizzle
|
kWipeEncoreSwizzle,
|
||||||
|
kPostimgWater,
|
||||||
|
kPostimgHeat
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SamplerName
|
enum class SamplerName
|
||||||
|
|
@ -277,6 +284,7 @@ struct ProgramRequirements
|
||||||
extern const ProgramRequirements kProgramRequirementsUnshaded;
|
extern const ProgramRequirements kProgramRequirementsUnshaded;
|
||||||
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
|
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
|
||||||
extern const ProgramRequirements kProgramRequirementsPostprocessWipe;
|
extern const ProgramRequirements kProgramRequirementsPostprocessWipe;
|
||||||
|
extern const ProgramRequirements kProgramRequirementsPostimg;
|
||||||
|
|
||||||
const ProgramRequirements& program_requirements_for_program(PipelineProgram program) noexcept;
|
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;
|
return UniformFormat::kMat4;
|
||||||
case UniformName::kTexCoord0Transform:
|
case UniformName::kTexCoord0Transform:
|
||||||
return UniformFormat::kMat3;
|
return UniformFormat::kMat3;
|
||||||
|
case UniformName::kTexCoord0Min:
|
||||||
|
return UniformFormat::kFloat2;
|
||||||
|
case UniformName::kTexCoord0Max:
|
||||||
|
return UniformFormat::kFloat2;
|
||||||
case UniformName::kTexCoord1Transform:
|
case UniformName::kTexCoord1Transform:
|
||||||
return UniformFormat::kMat3;
|
return UniformFormat::kMat3;
|
||||||
|
case UniformName::kTexCoord1Min:
|
||||||
|
return UniformFormat::kFloat2;
|
||||||
|
case UniformName::kTexCoord1Max:
|
||||||
|
return UniformFormat::kFloat2;
|
||||||
case UniformName::kSampler0IsIndexedAlpha:
|
case UniformName::kSampler0IsIndexedAlpha:
|
||||||
return UniformFormat::kInt;
|
return UniformFormat::kInt;
|
||||||
case UniformName::kSampler1IsIndexedAlpha:
|
case UniformName::kSampler1IsIndexedAlpha:
|
||||||
|
|
@ -333,6 +349,10 @@ inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
|
||||||
return UniformFormat::kInt;
|
return UniformFormat::kInt;
|
||||||
case UniformName::kWipeEncoreSwizzle:
|
case UniformName::kWipeEncoreSwizzle:
|
||||||
return UniformFormat::kInt;
|
return UniformFormat::kInt;
|
||||||
|
case UniformName::kPostimgWater:
|
||||||
|
return UniformFormat::kInt;
|
||||||
|
case UniformName::kPostimgHeat:
|
||||||
|
return UniformFormat::kInt;
|
||||||
default:
|
default:
|
||||||
return UniformFormat::kFloat;
|
return UniformFormat::kFloat;
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +385,7 @@ struct UniformInputDesc
|
||||||
|
|
||||||
struct SamplerInputDesc
|
struct SamplerInputDesc
|
||||||
{
|
{
|
||||||
std::vector<SamplerName> enabled_samplers;
|
srb2::StaticVec<SamplerName, 4> enabled_samplers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ColorMask
|
struct ColorMask
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ static constexpr const char* pipeline_lump_slug(rhi::PipelineProgram program)
|
||||||
return "unshadedpaletted";
|
return "unshadedpaletted";
|
||||||
case rhi::PipelineProgram::kPostprocessWipe:
|
case rhi::PipelineProgram::kPostprocessWipe:
|
||||||
return "postprocesswipe";
|
return "postprocesswipe";
|
||||||
|
case rhi::PipelineProgram::kPostimg:
|
||||||
|
return "postimg";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
190
src/v_video.cpp
190
src/v_video.cpp
|
|
@ -2898,196 +2898,6 @@ INT32 V_LevelNameHeight(const char *string)
|
||||||
return w;
|
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
|
// Generates a RGB565 color look-up table
|
||||||
void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors)
|
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_DrawCenteredLSTitleLowString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||||
void V_DrawRightAlignedLSTitleLowString(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 V_DrawPatchFill(patch_t *pat);
|
||||||
|
|
||||||
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue