mirror of
https://github.com/LIJI32/SameBoy.git
synced 2026-10-11 22:19:50 +00:00
Add Pixelated/sharp bilinear filter, closes #746
This commit is contained in:
+1
-1
@@ -80,7 +80,7 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
@"GBRewind": @(kVK_Tab),
|
@"GBRewind": @(kVK_Tab),
|
||||||
@"GBSlow-Motion": @(kVK_Shift),
|
@"GBSlow-Motion": @(kVK_Shift),
|
||||||
|
|
||||||
@"GBFilter": @"NearestNeighbor",
|
@"GBFilter": @"Pixelated",
|
||||||
@"GBColorCorrection": @(GB_COLOR_CORRECTION_MODERN_BALANCED),
|
@"GBColorCorrection": @(GB_COLOR_CORRECTION_MODERN_BALANCED),
|
||||||
@"GBHighpassFilter": @(GB_HIGHPASS_ACCURATE),
|
@"GBHighpassFilter": @(GB_HIGHPASS_ACCURATE),
|
||||||
@"GBRewindLength": @(120),
|
@"GBRewindLength": @(120),
|
||||||
|
|||||||
@@ -116,17 +116,23 @@
|
|||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC" customClass="GBPreferencePopUpButton">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC" customClass="GBPreferencePopUpButton">
|
||||||
<rect key="frame" x="30" y="500" width="262" height="25"/>
|
<rect key="frame" x="30" y="500" width="262" height="25"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Nearest neighbor (Pixelated)" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="neN-eo-LA7" id="I1w-05-lGl">
|
<popUpButtonCell key="cell" type="push" title="Nearest neighbor" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="neN-eo-LA7" id="I1w-05-lGl">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="message"/>
|
<font key="font" metaFont="message"/>
|
||||||
<menu key="menu" id="xDC-0T-Qg9">
|
<menu key="menu" id="xDC-0T-Qg9">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Nearest neighbor (Pixelated)" state="on" id="neN-eo-LA7" customClass="GBPreferenceMenuItem">
|
<menuItem title="Nearest neighbor" id="neN-eo-LA7" customClass="GBPreferenceMenuItem">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<userDefinedRuntimeAttributes>
|
<userDefinedRuntimeAttributes>
|
||||||
<userDefinedRuntimeAttribute type="string" keyPath="preferenceValue" value="NearestNeighbor"/>
|
<userDefinedRuntimeAttribute type="string" keyPath="preferenceValue" value="NearestNeighbor"/>
|
||||||
</userDefinedRuntimeAttributes>
|
</userDefinedRuntimeAttributes>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem title="Pixelated" state="on" id="lSa-83-lEf" customClass="GBPreferenceMenuItem">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<userDefinedRuntimeAttributes>
|
||||||
|
<userDefinedRuntimeAttribute type="string" keyPath="preferenceValue" value="Pixelated"/>
|
||||||
|
</userDefinedRuntimeAttributes>
|
||||||
|
</menuItem>
|
||||||
<menuItem title="Bilinear (Blurry)" id="iDe-si-atu" customClass="GBPreferenceMenuItem">
|
<menuItem title="Bilinear (Blurry)" id="iDe-si-atu" customClass="GBPreferenceMenuItem">
|
||||||
<userDefinedRuntimeAttributes>
|
<userDefinedRuntimeAttributes>
|
||||||
<userDefinedRuntimeAttribute type="string" keyPath="preferenceValue" value="Bilinear"/>
|
<userDefinedRuntimeAttribute type="string" keyPath="preferenceValue" value="Bilinear"/>
|
||||||
|
|||||||
@@ -1531,6 +1531,7 @@ struct shader_name {
|
|||||||
} shaders[] =
|
} shaders[] =
|
||||||
{
|
{
|
||||||
{"NearestNeighbor", "Nearest Neighbor"},
|
{"NearestNeighbor", "Nearest Neighbor"},
|
||||||
|
{"Pixelated", "Pixelated"},
|
||||||
{"Bilinear", "Bilinear"},
|
{"Bilinear", "Bilinear"},
|
||||||
{"SmoothBilinear", "Smooth Bilinear"},
|
{"SmoothBilinear", "Smooth Bilinear"},
|
||||||
{"MonoLCD", "Monochrome LCD"},
|
{"MonoLCD", "Monochrome LCD"},
|
||||||
@@ -1557,7 +1558,6 @@ static void cycle_filter(unsigned index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
if (i >= sizeof(shaders) / sizeof(shaders[0])) {
|
if (i >= sizeof(shaders) / sizeof(shaders[0])) {
|
||||||
i -= sizeof(shaders) / sizeof(shaders[0]);
|
i -= sizeof(shaders) / sizeof(shaders[0]);
|
||||||
@@ -1566,7 +1566,7 @@ static void cycle_filter(unsigned index)
|
|||||||
strcpy(configuration.filter, shaders[i].file_name);
|
strcpy(configuration.filter, shaders[i].file_name);
|
||||||
free_shader(&shader);
|
free_shader(&shader);
|
||||||
if (!init_shader_with_name(&shader, configuration.filter)) {
|
if (!init_shader_with_name(&shader, configuration.filter)) {
|
||||||
init_shader_with_name(&shader, "NearestNeighbor");
|
init_shader_with_name(&shader, "Pixelated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1588,7 +1588,7 @@ static void cycle_filter_backwards(unsigned index)
|
|||||||
strcpy(configuration.filter, shaders[i].file_name);
|
strcpy(configuration.filter, shaders[i].file_name);
|
||||||
free_shader(&shader);
|
free_shader(&shader);
|
||||||
if (!init_shader_with_name(&shader, configuration.filter)) {
|
if (!init_shader_with_name(&shader, configuration.filter)) {
|
||||||
init_shader_with_name(&shader, "NearestNeighbor");
|
init_shader_with_name(&shader, "Pixelated");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1603,7 @@ static const char *current_filter_name(unsigned index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == sizeof(shaders) / sizeof(shaders[0])) {
|
if (i == sizeof(shaders) / sizeof(shaders[0])) {
|
||||||
i = 0;
|
i = 1; // Pixelated
|
||||||
}
|
}
|
||||||
|
|
||||||
return shaders[i].display_name;
|
return shaders[i].display_name;
|
||||||
|
|||||||
+1
-1
@@ -1596,7 +1596,7 @@ int main(int argc, char **argv)
|
|||||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||||
|
|
||||||
if (!init_shader_with_name(&shader, configuration.filter)) {
|
if (!init_shader_with_name(&shader, configuration.filter)) {
|
||||||
init_shader_with_name(&shader, "NearestNeighbor");
|
init_shader_with_name(&shader, "Pixelated");
|
||||||
}
|
}
|
||||||
update_viewport();
|
update_viewport();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
|
||||||
|
{
|
||||||
|
vec2 scale_factor = output_resolution / input_resolution;
|
||||||
|
vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
|
||||||
|
|
||||||
|
vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
|
||||||
|
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
|
||||||
|
vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
|
||||||
|
vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
|
||||||
|
|
||||||
|
vec2 t = fract(pixel);
|
||||||
|
vec2 w = clamp((t - 0.5) * scale_factor + 0.5, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec4 r1 = mix(q11, q21, w.x);
|
||||||
|
vec4 r2 = mix(q12, q22, w.x);
|
||||||
|
|
||||||
|
return mix(r1, r2, w.y);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user