mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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/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…
	
	Add table
		Add a link
		
	
		Reference in a new issue