Add nearest neighbor texture filter (#6189)
Closes https://github.com/citra-emu/citra/issues/4707 closes https://github.com/citra-emu/citra/issues/5274
This commit is contained in:
parent
664562f988
commit
4f715b6718
6 changed files with 92 additions and 1 deletions
|
@ -69,6 +69,8 @@ add_library(video_core STATIC
|
||||||
renderer_opengl/texture_filters/anime4k/anime4k_ultrafast.h
|
renderer_opengl/texture_filters/anime4k/anime4k_ultrafast.h
|
||||||
renderer_opengl/texture_filters/bicubic/bicubic.cpp
|
renderer_opengl/texture_filters/bicubic/bicubic.cpp
|
||||||
renderer_opengl/texture_filters/bicubic/bicubic.h
|
renderer_opengl/texture_filters/bicubic/bicubic.h
|
||||||
|
renderer_opengl/texture_filters/nearest_neighbor/nearest_neighbor.cpp
|
||||||
|
renderer_opengl/texture_filters/nearest_neighbor/nearest_neighbor.h
|
||||||
renderer_opengl/texture_filters/scale_force/scale_force.cpp
|
renderer_opengl/texture_filters/scale_force/scale_force.cpp
|
||||||
renderer_opengl/texture_filters/scale_force/scale_force.h
|
renderer_opengl/texture_filters/scale_force/scale_force.h
|
||||||
renderer_opengl/texture_filters/texture_filter_base.h
|
renderer_opengl/texture_filters/texture_filter_base.h
|
||||||
|
@ -117,6 +119,7 @@ set(SHADER_FILES
|
||||||
renderer_opengl/texture_filters/anime4k/x_gradient.frag
|
renderer_opengl/texture_filters/anime4k/x_gradient.frag
|
||||||
renderer_opengl/texture_filters/anime4k/y_gradient.frag
|
renderer_opengl/texture_filters/anime4k/y_gradient.frag
|
||||||
renderer_opengl/texture_filters/bicubic/bicubic.frag
|
renderer_opengl/texture_filters/bicubic/bicubic.frag
|
||||||
|
renderer_opengl/texture_filters/nearest_neighbor/nearest_neighbor.frag
|
||||||
renderer_opengl/texture_filters/scale_force/scale_force.frag
|
renderer_opengl/texture_filters/scale_force/scale_force.frag
|
||||||
renderer_opengl/texture_filters/tex_coord.vert
|
renderer_opengl/texture_filters/tex_coord.vert
|
||||||
renderer_opengl/texture_filters/xbrz/xbrz_freescale.frag
|
renderer_opengl/texture_filters/xbrz/xbrz_freescale.frag
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "video_core/renderer_opengl/texture_filters/nearest_neighbor/nearest_neighbor.h"
|
||||||
|
|
||||||
|
#include "shaders/nearest_neighbor.frag"
|
||||||
|
#include "shaders/tex_coord.vert"
|
||||||
|
|
||||||
|
namespace OpenGL {
|
||||||
|
|
||||||
|
NearestNeighbor::NearestNeighbor(u16 scale_factor) : TextureFilterBase(scale_factor) {
|
||||||
|
program.Create(tex_coord_vert.data(), nearest_neighbor_frag.data());
|
||||||
|
vao.Create();
|
||||||
|
src_sampler.Create();
|
||||||
|
|
||||||
|
state.draw.shader_program = program.handle;
|
||||||
|
state.draw.vertex_array = vao.handle;
|
||||||
|
state.draw.shader_program = program.handle;
|
||||||
|
state.texture_units[0].sampler = src_sampler.handle;
|
||||||
|
|
||||||
|
// linear minification still makes sense
|
||||||
|
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(src_sampler.handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NearestNeighbor::Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||||
|
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) {
|
||||||
|
const OpenGLState cur_state = OpenGLState::GetCurState();
|
||||||
|
state.texture_units[0].texture_2d = src_tex.handle;
|
||||||
|
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||||
|
state.viewport = {static_cast<GLint>(dst_rect.left), static_cast<GLint>(dst_rect.bottom),
|
||||||
|
static_cast<GLsizei>(dst_rect.GetWidth()),
|
||||||
|
static_cast<GLsizei>(dst_rect.GetHeight())};
|
||||||
|
state.Apply();
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex.handle,
|
||||||
|
0);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
cur_state.Apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OpenGL
|
|
@ -0,0 +1,12 @@
|
||||||
|
//? #version 330
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
in vec2 tex_coord;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
uniform sampler2D input_texture;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = texture(input_texture, tex_coord);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state.h"
|
||||||
|
#include "video_core/renderer_opengl/texture_filters/texture_filter_base.h"
|
||||||
|
|
||||||
|
namespace OpenGL {
|
||||||
|
|
||||||
|
class NearestNeighbor : public TextureFilterBase {
|
||||||
|
public:
|
||||||
|
static constexpr std::string_view NAME = "Nearest Neighbor";
|
||||||
|
|
||||||
|
explicit NearestNeighbor(u16 scale_factor);
|
||||||
|
void Filter(const OGLTexture& src_tex, Common::Rectangle<u32> src_rect,
|
||||||
|
const OGLTexture& dst_tex, Common::Rectangle<u32> dst_rect) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLState state{};
|
||||||
|
OGLProgram program{};
|
||||||
|
OGLVertexArray vao{};
|
||||||
|
OGLSampler src_sampler{};
|
||||||
|
};
|
||||||
|
} // namespace OpenGL
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/anime4k/anime4k_ultrafast.h"
|
#include "video_core/renderer_opengl/texture_filters/anime4k/anime4k_ultrafast.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/bicubic/bicubic.h"
|
#include "video_core/renderer_opengl/texture_filters/bicubic/bicubic.h"
|
||||||
|
#include "video_core/renderer_opengl/texture_filters/nearest_neighbor/nearest_neighbor.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/scale_force/scale_force.h"
|
#include "video_core/renderer_opengl/texture_filters/scale_force/scale_force.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/texture_filter_base.h"
|
#include "video_core/renderer_opengl/texture_filters/texture_filter_base.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
||||||
|
@ -28,6 +29,7 @@ static const std::unordered_map<std::string_view, TextureFilterContructor> filte
|
||||||
{TextureFilterer::NONE, [](u16) { return nullptr; }},
|
{TextureFilterer::NONE, [](u16) { return nullptr; }},
|
||||||
FilterMapPair<Anime4kUltrafast>(),
|
FilterMapPair<Anime4kUltrafast>(),
|
||||||
FilterMapPair<Bicubic>(),
|
FilterMapPair<Bicubic>(),
|
||||||
|
FilterMapPair<NearestNeighbor>(),
|
||||||
FilterMapPair<ScaleForce>(),
|
FilterMapPair<ScaleForce>(),
|
||||||
FilterMapPair<XbrzFreescale>(),
|
FilterMapPair<XbrzFreescale>(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace OpenGL {
|
||||||
|
|
||||||
class TextureFilterer {
|
class TextureFilterer {
|
||||||
public:
|
public:
|
||||||
static constexpr std::string_view NONE = "none";
|
static constexpr std::string_view NONE = "Linear (Default)";
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TextureFilterer(std::string_view filter_name, u16 scale_factor);
|
explicit TextureFilterer(std::string_view filter_name, u16 scale_factor);
|
||||||
|
|
Loading…
Reference in a new issue