mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-03 06:33:14 +00:00
Add Sharp Bilinear mode, make default
This commit is contained in:
parent
0156db0dc1
commit
123477dac9
10 changed files with 115 additions and 2 deletions
|
|
@ -430,7 +430,7 @@ consvar_t cv_scr_depth = Player("scr_depth", "16 bits").values({{8, "8 bits"}, {
|
||||||
//added : 03-02-98: default screen mode, as loaded/saved in config
|
//added : 03-02-98: default screen mode, as loaded/saved in config
|
||||||
consvar_t cv_scr_width = Player("scr_width", "640").values(CV_Unsigned);
|
consvar_t cv_scr_width = Player("scr_width", "640").values(CV_Unsigned);
|
||||||
consvar_t cv_scr_height = Player("scr_height", "400").values(CV_Unsigned);
|
consvar_t cv_scr_height = Player("scr_height", "400").values(CV_Unsigned);
|
||||||
consvar_t cv_scr_effect = Player("scr_effect", "Nearest").values({{0, "Nearest"}, {1, "SalCRT"}}).save();
|
consvar_t cv_scr_effect = Player("scr_effect", "Sharp Bilinear").values({{0, "Nearest"}, {1, "Sharp Bilinear"}, {2, "SalCRT"}}).save();
|
||||||
|
|
||||||
consvar_t cv_scr_scale = Player("scr_scale", "1.0").floating_point();
|
consvar_t cv_scr_scale = Player("scr_scale", "1.0").floating_point();
|
||||||
consvar_t cv_scr_x = Player("scr_x", "0.0").floating_point();
|
consvar_t cv_scr_x = Player("scr_x", "0.0").floating_point();
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,20 @@ static const PipelineDesc kUnshadedPipelineDescription = {
|
||||||
FaceWinding::kCounterClockwise,
|
FaceWinding::kCounterClockwise,
|
||||||
{0.f, 0.f, 0.f, 1.f}};
|
{0.f, 0.f, 0.f, 1.f}};
|
||||||
|
|
||||||
|
/// @brief Pipeline used for sharp bilinear special blit.
|
||||||
|
static const PipelineDesc kSharpBilinearPipelineDescription = {
|
||||||
|
PipelineProgram::kSharpBilinear,
|
||||||
|
{{{sizeof(BlitVertex)}}, {{VertexAttributeName::kPosition, 0, 0}, {VertexAttributeName::kTexCoord0, 0, 12}}},
|
||||||
|
{{{UniformName::kProjection}, {{UniformName::kModelView, UniformName::kTexCoord0Transform, UniformName::kSampler0Size}}}},
|
||||||
|
{{// RGB/A texture
|
||||||
|
SamplerName::kSampler0}},
|
||||||
|
std::nullopt,
|
||||||
|
{std::nullopt, {true, true, true, true}},
|
||||||
|
PrimitiveType::kTriangles,
|
||||||
|
CullMode::kNone,
|
||||||
|
FaceWinding::kCounterClockwise,
|
||||||
|
{0.f, 0.f, 0.f, 1.f}};
|
||||||
|
|
||||||
/// @brief Pipeline used for CRT special blit
|
/// @brief Pipeline used for CRT special blit
|
||||||
static const PipelineDesc kCrtPipelineDescription = {
|
static const PipelineDesc kCrtPipelineDescription = {
|
||||||
PipelineProgram::kCrt,
|
PipelineProgram::kCrt,
|
||||||
|
|
@ -85,6 +99,9 @@ void BlitRectPass::prepass(Rhi& rhi)
|
||||||
case BlitRectPass::BlitMode::kNearest:
|
case BlitRectPass::BlitMode::kNearest:
|
||||||
pipeline_ = rhi.create_pipeline(kUnshadedPipelineDescription);
|
pipeline_ = rhi.create_pipeline(kUnshadedPipelineDescription);
|
||||||
break;
|
break;
|
||||||
|
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||||
|
pipeline_ = rhi.create_pipeline(kSharpBilinearPipelineDescription);
|
||||||
|
break;
|
||||||
case BlitRectPass::BlitMode::kCrt:
|
case BlitRectPass::BlitMode::kCrt:
|
||||||
pipeline_ = rhi.create_pipeline(kCrtPipelineDescription);
|
pipeline_ = rhi.create_pipeline(kCrtPipelineDescription);
|
||||||
break;
|
break;
|
||||||
|
|
@ -243,6 +260,30 @@ void BlitRectPass::transfer(Rhi& rhi, Handle<GraphicsContext> ctx)
|
||||||
binding_set_ = rhi.create_binding_set(ctx, pipeline_, {vbs, tbs});
|
binding_set_ = rhi.create_binding_set(ctx, pipeline_, {vbs, tbs});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case BlitRectPass::BlitMode::kSharpBilinear:
|
||||||
|
{
|
||||||
|
std::array<rhi::UniformVariant, 3> g2_uniforms = {
|
||||||
|
// ModelView
|
||||||
|
glm::scale(
|
||||||
|
glm::identity<glm::mat4>(),
|
||||||
|
glm::vec3(taller ? 2.f : 2.f * aspect, taller ? 2.f * (1.f / aspect) : 2.f, 1.f)
|
||||||
|
),
|
||||||
|
// Texcoord0 Transform
|
||||||
|
glm::mat3(
|
||||||
|
glm::vec3(1.f, 0.f, 0.f),
|
||||||
|
glm::vec3(0.f, output_flip_ ? -1.f : 1.f, 0.f),
|
||||||
|
glm::vec3(0.f, output_flip_ ? 1.f : 0.f, 1.f)
|
||||||
|
),
|
||||||
|
// Sampler0 size
|
||||||
|
glm::vec2(texture_details.width, texture_details.height)
|
||||||
|
};
|
||||||
|
uniform_sets_[1] = rhi.create_uniform_set(ctx, {g2_uniforms});
|
||||||
|
|
||||||
|
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
|
||||||
|
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, texture_}}};
|
||||||
|
binding_set_ = rhi.create_binding_set(ctx, pipeline_, {vbs, tbs});
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
std::array<rhi::UniformVariant, 2> g2_uniforms = {
|
std::array<rhi::UniformVariant, 2> g2_uniforms = {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public:
|
||||||
enum class BlitMode
|
enum class BlitMode
|
||||||
{
|
{
|
||||||
kNearest,
|
kNearest,
|
||||||
|
kSharpBilinear,
|
||||||
kCrt,
|
kCrt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ struct HardwareState
|
||||||
std::unique_ptr<BlitPostimgScreens> blit_postimg_screens;
|
std::unique_ptr<BlitPostimgScreens> blit_postimg_screens;
|
||||||
std::unique_ptr<PostprocessWipePass> wipe;
|
std::unique_ptr<PostprocessWipePass> wipe;
|
||||||
std::unique_ptr<BlitRectPass> blit_rect;
|
std::unique_ptr<BlitRectPass> blit_rect;
|
||||||
|
std::unique_ptr<BlitRectPass> sharp_bilinear_blit_rect;
|
||||||
std::unique_ptr<BlitRectPass> crt_blit_rect;
|
std::unique_ptr<BlitRectPass> crt_blit_rect;
|
||||||
std::unique_ptr<ScreenshotPass> screen_capture;
|
std::unique_ptr<ScreenshotPass> screen_capture;
|
||||||
std::unique_ptr<UpscaleBackbuffer> backbuffer;
|
std::unique_ptr<UpscaleBackbuffer> backbuffer;
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ static void reset_hardware_state(Rhi* rhi)
|
||||||
g_hw_state.blit_postimg_screens = std::make_unique<BlitPostimgScreens>(g_hw_state.palette_manager.get());
|
g_hw_state.blit_postimg_screens = std::make_unique<BlitPostimgScreens>(g_hw_state.palette_manager.get());
|
||||||
g_hw_state.wipe = std::make_unique<PostprocessWipePass>();
|
g_hw_state.wipe = std::make_unique<PostprocessWipePass>();
|
||||||
g_hw_state.blit_rect = std::make_unique<BlitRectPass>(BlitRectPass::BlitMode::kNearest);
|
g_hw_state.blit_rect = std::make_unique<BlitRectPass>(BlitRectPass::BlitMode::kNearest);
|
||||||
|
g_hw_state.sharp_bilinear_blit_rect = std::make_unique<BlitRectPass>(BlitRectPass::BlitMode::kSharpBilinear);
|
||||||
g_hw_state.crt_blit_rect = std::make_unique<BlitRectPass>(BlitRectPass::BlitMode::kCrt);
|
g_hw_state.crt_blit_rect = std::make_unique<BlitRectPass>(BlitRectPass::BlitMode::kCrt);
|
||||||
g_hw_state.screen_capture = std::make_unique<ScreenshotPass>();
|
g_hw_state.screen_capture = std::make_unique<ScreenshotPass>();
|
||||||
g_hw_state.backbuffer = std::make_unique<UpscaleBackbuffer>();
|
g_hw_state.backbuffer = std::make_unique<UpscaleBackbuffer>();
|
||||||
|
|
@ -295,22 +296,31 @@ void I_FinishUpdate(void)
|
||||||
float y = (vid.realheight - h) * (0.5f + (FixedToFloat(cv_scr_y.value) * 0.5f));
|
float y = (vid.realheight - h) * (0.5f + (FixedToFloat(cv_scr_y.value) * 0.5f));
|
||||||
|
|
||||||
g_hw_state.blit_rect->set_output(x, y, w, h, true, true);
|
g_hw_state.blit_rect->set_output(x, y, w, h, true, true);
|
||||||
|
g_hw_state.sharp_bilinear_blit_rect->set_output(x, y, w, h, true, true);
|
||||||
g_hw_state.crt_blit_rect->set_output(x, y, w, h, true, true);
|
g_hw_state.crt_blit_rect->set_output(x, y, w, h, true, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_hw_state.blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true);
|
g_hw_state.blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true);
|
||||||
|
g_hw_state.sharp_bilinear_blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true);
|
||||||
g_hw_state.crt_blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true);
|
g_hw_state.crt_blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true);
|
||||||
}
|
}
|
||||||
g_hw_state.blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
|
g_hw_state.blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
|
||||||
|
g_hw_state.sharp_bilinear_blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
|
||||||
g_hw_state.crt_blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
|
g_hw_state.crt_blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
|
||||||
|
|
||||||
switch (cv_scr_effect.value)
|
switch (cv_scr_effect.value)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
rhi->update_texture_settings(ctx, g_hw_state.backbuffer->color(), TextureWrapMode::kClamp, TextureWrapMode::kClamp, TextureFilterMode::kLinear, TextureFilterMode::kLinear);
|
||||||
|
g_hw_state.sharp_bilinear_blit_rect->draw(*rhi, ctx);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rhi->update_texture_settings(ctx, g_hw_state.backbuffer->color(), TextureWrapMode::kClamp, TextureWrapMode::kClamp, TextureFilterMode::kNearest, TextureFilterMode::kNearest);
|
||||||
g_hw_state.crt_blit_rect->draw(*rhi, ctx);
|
g_hw_state.crt_blit_rect->draw(*rhi, ctx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
rhi->update_texture_settings(ctx, g_hw_state.backbuffer->color(), TextureWrapMode::kClamp, TextureWrapMode::kClamp, TextureFilterMode::kNearest, TextureFilterMode::kNearest);
|
||||||
g_hw_state.blit_rect->draw(*rhi, ctx);
|
g_hw_state.blit_rect->draw(*rhi, ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -685,6 +685,34 @@ void Gl2Rhi::update_texture(
|
||||||
GL_ASSERT;
|
GL_ASSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gl2Rhi::update_texture_settings(
|
||||||
|
Handle<GraphicsContext> ctx,
|
||||||
|
Handle<Texture> texture,
|
||||||
|
TextureWrapMode u_wrap,
|
||||||
|
TextureWrapMode v_wrap,
|
||||||
|
TextureFilterMode min,
|
||||||
|
TextureFilterMode mag
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SRB2_ASSERT(graphics_context_active_ == true);
|
||||||
|
|
||||||
|
SRB2_ASSERT(texture_slab_.is_valid(texture) == true);
|
||||||
|
auto& t = texture_slab_[texture];
|
||||||
|
|
||||||
|
gl_->ActiveTexture(GL_TEXTURE0);
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->BindTexture(GL_TEXTURE_2D, t.texture);
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, map_texture_wrap(u_wrap));
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, map_texture_wrap(v_wrap));
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, map_texture_filter(min));
|
||||||
|
GL_ASSERT;
|
||||||
|
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, map_texture_filter(mag));
|
||||||
|
GL_ASSERT;
|
||||||
|
}
|
||||||
|
|
||||||
rhi::Handle<rhi::Buffer> Gl2Rhi::create_buffer(const rhi::BufferDesc& desc)
|
rhi::Handle<rhi::Buffer> Gl2Rhi::create_buffer(const rhi::BufferDesc& desc)
|
||||||
{
|
{
|
||||||
GLenum target = map_buffer_type(desc.type);
|
GLenum target = map_buffer_type(desc.type);
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,14 @@ public:
|
||||||
srb2::rhi::PixelFormat data_format,
|
srb2::rhi::PixelFormat data_format,
|
||||||
tcb::span<const std::byte> data
|
tcb::span<const std::byte> data
|
||||||
) override;
|
) override;
|
||||||
|
virtual void update_texture_settings(
|
||||||
|
Handle<GraphicsContext> ctx,
|
||||||
|
Handle<Texture> texture,
|
||||||
|
TextureWrapMode u_wrap,
|
||||||
|
TextureWrapMode v_wrap,
|
||||||
|
TextureFilterMode min,
|
||||||
|
TextureFilterMode mag
|
||||||
|
) override;
|
||||||
virtual Handle<UniformSet>
|
virtual Handle<UniformSet>
|
||||||
create_uniform_set(Handle<GraphicsContext> ctx, const CreateUniformSetInfo& info) override;
|
create_uniform_set(Handle<GraphicsContext> ctx, const CreateUniformSetInfo& info) override;
|
||||||
virtual Handle<BindingSet>
|
virtual Handle<BindingSet>
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,16 @@ const ProgramRequirements srb2::rhi::kProgramRequirementsPostimg = {
|
||||||
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, false}}}
|
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}, {SamplerName::kSampler1, false}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ProgramRequirements srb2::rhi::kProgramRequirementsSharpBilinear = {
|
||||||
|
ProgramVertexInputRequirements {
|
||||||
|
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
|
||||||
|
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
|
||||||
|
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}}},
|
||||||
|
ProgramUniformRequirements {
|
||||||
|
{{{{UniformName::kProjection, true}}},
|
||||||
|
{{{UniformName::kModelView, true}, {UniformName::kTexCoord0Transform, true}, {UniformName::kSampler0Size, true}}}}},
|
||||||
|
ProgramSamplerRequirements {{{SamplerName::kSampler0, true}}}};
|
||||||
|
|
||||||
const ProgramRequirements srb2::rhi::kProgramRequirementsCrt = {
|
const ProgramRequirements srb2::rhi::kProgramRequirementsCrt = {
|
||||||
ProgramVertexInputRequirements {
|
ProgramVertexInputRequirements {
|
||||||
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
|
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
|
||||||
|
|
@ -89,6 +99,8 @@ const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram
|
||||||
return kProgramRequirementsPostprocessWipe;
|
return kProgramRequirementsPostprocessWipe;
|
||||||
case PipelineProgram::kPostimg:
|
case PipelineProgram::kPostimg:
|
||||||
return kProgramRequirementsPostimg;
|
return kProgramRequirementsPostimg;
|
||||||
|
case PipelineProgram::kSharpBilinear:
|
||||||
|
return kProgramRequirementsSharpBilinear;
|
||||||
case PipelineProgram::kCrt:
|
case PipelineProgram::kCrt:
|
||||||
return kProgramRequirementsCrt;
|
return kProgramRequirementsCrt;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ enum class PipelineProgram
|
||||||
kUnshadedPaletted,
|
kUnshadedPaletted,
|
||||||
kPostprocessWipe,
|
kPostprocessWipe,
|
||||||
kPostimg,
|
kPostimg,
|
||||||
|
kSharpBilinear,
|
||||||
kCrt
|
kCrt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -286,6 +287,7 @@ extern const ProgramRequirements kProgramRequirementsUnshaded;
|
||||||
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
|
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
|
||||||
extern const ProgramRequirements kProgramRequirementsPostprocessWipe;
|
extern const ProgramRequirements kProgramRequirementsPostprocessWipe;
|
||||||
extern const ProgramRequirements kProgramRequirementsPostimg;
|
extern const ProgramRequirements kProgramRequirementsPostimg;
|
||||||
|
extern const ProgramRequirements kProgramRequirementsSharpBilinear;
|
||||||
extern const ProgramRequirements kProgramRequirementsCrt;
|
extern const ProgramRequirements kProgramRequirementsCrt;
|
||||||
|
|
||||||
const ProgramRequirements& program_requirements_for_program(PipelineProgram program) noexcept;
|
const ProgramRequirements& program_requirements_for_program(PipelineProgram program) noexcept;
|
||||||
|
|
@ -495,8 +497,8 @@ struct TextureDesc
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
TextureWrapMode u_wrap;
|
TextureWrapMode u_wrap;
|
||||||
TextureWrapMode v_wrap;
|
TextureWrapMode v_wrap;
|
||||||
TextureFilterMode mag;
|
|
||||||
TextureFilterMode min;
|
TextureFilterMode min;
|
||||||
|
TextureFilterMode mag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferDesc
|
struct BufferDesc
|
||||||
|
|
@ -628,6 +630,14 @@ struct Rhi
|
||||||
srb2::rhi::PixelFormat data_format,
|
srb2::rhi::PixelFormat data_format,
|
||||||
tcb::span<const std::byte> data
|
tcb::span<const std::byte> data
|
||||||
) = 0;
|
) = 0;
|
||||||
|
virtual void update_texture_settings(
|
||||||
|
Handle<GraphicsContext> ctx,
|
||||||
|
Handle<Texture> texture,
|
||||||
|
TextureWrapMode u_wrap,
|
||||||
|
TextureWrapMode v_wrap,
|
||||||
|
TextureFilterMode min,
|
||||||
|
TextureFilterMode mag
|
||||||
|
) = 0;
|
||||||
virtual Handle<UniformSet> create_uniform_set(Handle<GraphicsContext> ctx, const CreateUniformSetInfo& info) = 0;
|
virtual Handle<UniformSet> create_uniform_set(Handle<GraphicsContext> ctx, const CreateUniformSetInfo& info) = 0;
|
||||||
virtual Handle<BindingSet>
|
virtual Handle<BindingSet>
|
||||||
create_binding_set(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
|
create_binding_set(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ static constexpr const char* pipeline_lump_slug(rhi::PipelineProgram program)
|
||||||
return "postprocesswipe";
|
return "postprocesswipe";
|
||||||
case rhi::PipelineProgram::kPostimg:
|
case rhi::PipelineProgram::kPostimg:
|
||||||
return "postimg";
|
return "postimg";
|
||||||
|
case rhi::PipelineProgram::kSharpBilinear:
|
||||||
|
return "sharpbilinear";
|
||||||
case rhi::PipelineProgram::kCrt:
|
case rhi::PipelineProgram::kCrt:
|
||||||
return "crt";
|
return "crt";
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue