mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	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/bicubic/bicubic.cpp | ||||
|     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.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/y_gradient.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/tex_coord.vert | ||||
|     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 "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/nearest_neighbor/nearest_neighbor.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_filterer.h" | ||||
|  | @ -28,6 +29,7 @@ static const std::unordered_map<std::string_view, TextureFilterContructor> filte | |||
|     {TextureFilterer::NONE, [](u16) { return nullptr; }}, | ||||
|     FilterMapPair<Anime4kUltrafast>(), | ||||
|     FilterMapPair<Bicubic>(), | ||||
|     FilterMapPair<NearestNeighbor>(), | ||||
|     FilterMapPair<ScaleForce>(), | ||||
|     FilterMapPair<XbrzFreescale>(), | ||||
| }; | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ namespace OpenGL { | |||
| 
 | ||||
| class TextureFilterer { | ||||
| public: | ||||
|     static constexpr std::string_view NONE = "none"; | ||||
|     static constexpr std::string_view NONE = "Linear (Default)"; | ||||
| 
 | ||||
| public: | ||||
|     explicit TextureFilterer(std::string_view filter_name, u16 scale_factor); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue