Merge pull request #693 from Sonicadvance1/PP-shaders-improvement
Improved system for post processing shaders.
This commit is contained in:
commit
f2a1dd91fe
|
@ -1,10 +1,3 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
//Change this number to increase the pixel size.
|
||||
|
@ -14,9 +7,9 @@ void main()
|
|||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
||||
vec2 pos = floor(uv0 * resolution.xy / pixelSize) * pixelSize * resolution.zw;
|
||||
float2 pos = floor(GetCoordinates() * GetResolution() / pixelSize) * pixelSize * GetInvResolution();
|
||||
|
||||
vec4 c0 = texture(samp9, pos);
|
||||
float4 c0 = SampleLocation(pos);
|
||||
|
||||
if (c0.r < 0.1)
|
||||
red = 0.1;
|
||||
|
@ -57,5 +50,5 @@ void main()
|
|||
else
|
||||
green = 1.0;
|
||||
|
||||
ocol0 = vec4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
//Change this number to increase the pixel size.
|
||||
|
@ -14,9 +7,9 @@ void main()
|
|||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
||||
vec2 pos = floor(uv0 * resolution.xy / pixelSize) * pixelSize * resolution.zw;
|
||||
float2 pos = floor(GetCoordinates() * GetResolution() / pixelSize) * pixelSize * GetInvResolution();
|
||||
|
||||
vec4 c0 = texture(samp9, pos);
|
||||
float4 c0 = SampleLocation(pos);
|
||||
|
||||
if (c0.r < 0.06)
|
||||
red = 0.06;
|
||||
|
@ -82,5 +75,5 @@ void main()
|
|||
else
|
||||
green = 1.0;
|
||||
|
||||
ocol0 = vec4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -12,26 +12,20 @@
|
|||
|
||||
// 0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
||||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
#define FXAA_REDUCE_MIN (1.0/ 128.0)
|
||||
#define FXAA_REDUCE_MUL (1.0 / 8.0)
|
||||
#define FXAA_SPAN_MAX 8.0
|
||||
|
||||
vec4 applyFXAA(vec2 fragCoord, sampler2D tex)
|
||||
|
||||
float4 applyFXAA(float2 fragCoord)
|
||||
{
|
||||
vec4 color;
|
||||
vec2 inverseVP = resolution.zw;
|
||||
vec3 rgbNW = texture(tex, (fragCoord + vec2(-1.0, -1.0)) * inverseVP).xyz;
|
||||
vec3 rgbNE = texture(tex, (fragCoord + vec2(1.0, -1.0)) * inverseVP).xyz;
|
||||
vec3 rgbSW = texture(tex, (fragCoord + vec2(-1.0, 1.0)) * inverseVP).xyz;
|
||||
vec3 rgbSE = texture(tex, (fragCoord + vec2(1.0, 1.0)) * inverseVP).xyz;
|
||||
vec3 rgbM = texture(tex, fragCoord * inverseVP).xyz;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
float4 color;
|
||||
float2 inverseVP = GetInvResolution();
|
||||
float3 rgbNW = SampleLocation((fragCoord + float2(-1.0, -1.0)) * inverseVP).xyz;
|
||||
float3 rgbNE = SampleLocation((fragCoord + float2(1.0, -1.0)) * inverseVP).xyz;
|
||||
float3 rgbSW = SampleLocation((fragCoord + float2(-1.0, 1.0)) * inverseVP).xyz;
|
||||
float3 rgbSE = SampleLocation((fragCoord + float2(1.0, 1.0)) * inverseVP).xyz;
|
||||
float3 rgbM = SampleLocation(fragCoord * inverseVP).xyz;
|
||||
float3 luma = float3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
|
@ -39,8 +33,8 @@ vec4 applyFXAA(vec2 fragCoord, sampler2D tex)
|
|||
float lumaM = dot(rgbM, luma);
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
|
||||
float2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
|
@ -48,26 +42,26 @@ vec4 applyFXAA(vec2 fragCoord, sampler2D tex)
|
|||
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir = min(float2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * inverseVP;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
texture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +
|
||||
texture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(tex, fragCoord * inverseVP + dir * -0.5).xyz +
|
||||
texture(tex, fragCoord * inverseVP + dir * 0.5).xyz);
|
||||
|
||||
float3 rgbA = 0.5 * (
|
||||
SampleLocation(fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +
|
||||
SampleLocation(fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);
|
||||
float3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
SampleLocation(fragCoord * inverseVP + dir * -0.5).xyz +
|
||||
SampleLocation(fragCoord * inverseVP + dir * 0.5).xyz);
|
||||
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if ((lumaB < lumaMin) || (lumaB > lumaMax))
|
||||
color = vec4(rgbA, 1.0);
|
||||
color = float4(rgbA, 1.0);
|
||||
else
|
||||
color = vec4(rgbB, 1.0);
|
||||
color = float4(rgbB, 1.0);
|
||||
return color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = applyFXAA(uv0 * resolution.xy, samp9);
|
||||
SetOutput(applyFXAA(GetCoordinates() * GetResolution()));
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
//dummy shader:
|
||||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0);
|
||||
}
|
||||
|
||||
/*
|
||||
And now that's over with, the contents of this readme file!
|
||||
For best results, turn Wordwrap formatting on...
|
||||
The shaders shown in the dropdown box in the video plugin configuration window are kept in the directory named User/Data/Shaders. They are linked in to the dolphin source from the repository at <http://dolphin-shaders-database.googlecode.com/svn/trunk/>. See <http://code.google.com/p/dolphin-shaders-database/wiki/Documentation> for more details on the way shaders work.
|
||||
|
||||
This file will hopefully hold more content in future...
|
||||
*/
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float blue = 0.0;
|
||||
|
||||
|
@ -17,5 +12,5 @@ void main()
|
|||
|
||||
float green = max(c0.r + c0.b, c0.g);
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = (texture(samp9, uv0+resolution.zw) - texture(samp9, uv0-resolution.zw)) * 8.0;
|
||||
SetOutput((SampleOffset(int2(1, 1)) - SampleOffset(int2(-1, -1))) * 8.0);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 a = texture(samp9, uv0+resolution.zw);
|
||||
vec4 b = texture(samp9, uv0-resolution.zw);
|
||||
ocol0 = ( a*a*1.3 - b ) * 8.0;
|
||||
float4 a = SampleOffset(int2( 1, 1));
|
||||
float4 b = SampleOffset(int2(-1, -1));
|
||||
SetOutput(( a*a*1.3 - b ) * 8.0);
|
||||
}
|
||||
|
|
|
@ -1,48 +1,39 @@
|
|||
// textures
|
||||
SAMPLER_BINDING(8) uniform sampler2D samp8;
|
||||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
const int char_width = 8;
|
||||
const int char_height = 13;
|
||||
const int char_count = 95;
|
||||
const int char_pixels = char_width*char_height;
|
||||
const vec2 char_dim = vec2(char_width, char_height);
|
||||
const vec2 font_scale = vec2(1.0/float(char_width)/float(char_count), 1.0/float(char_height));
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
const float2 char_dim = float2(char_width, char_height);
|
||||
const float2 font_scale = float2(1.0/float(char_width)/float(char_count), 1.0/float(char_height));
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 char_pos = floor(uv0*resolution.xy/char_dim);
|
||||
vec2 pixel_offset = floor(uv0*resolution.xy) - char_pos*char_dim;
|
||||
float2 char_pos = floor(GetCoordinates()*GetResolution()/char_dim);
|
||||
float2 pixel_offset = floor(GetCoordinates()*GetResolution()) - char_pos*char_dim;
|
||||
|
||||
// just a big number
|
||||
float mindiff = float(char_width*char_height) * 100.0;
|
||||
|
||||
float minc = 0.0;
|
||||
vec4 mina = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 minb = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 mina = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 minb = float4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (int i=0; i<char_count; i++)
|
||||
{
|
||||
vec4 ff = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 f = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 ft = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 t = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 tt = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 ff = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 f = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 ft = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 t = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float4 tt = float4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (int x=0; x<char_width; x++)
|
||||
{
|
||||
for (int y=0; y<char_height; y++)
|
||||
{
|
||||
vec2 tex_pos = char_pos*char_dim + vec2(x,y) + 0.5;
|
||||
vec4 tex = texture(samp9, tex_pos * resolution.zw);
|
||||
float2 tex_pos = char_pos*char_dim + float2(x,y) + 0.5;
|
||||
float4 tex = SampleLocation(tex_pos * GetInvResolution());
|
||||
|
||||
vec2 font_pos = vec2(x+i*char_width, y) + 0.5;
|
||||
vec4 font = texture(samp8, font_pos * font_scale);
|
||||
float2 font_pos = float2(x+i*char_width, y) + 0.5;
|
||||
float4 font = SampleFontLocation(font_pos * font_scale);
|
||||
|
||||
// generates sum of texture and font and their squares
|
||||
ff += font*font;
|
||||
|
@ -63,7 +54,7 @@ void main()
|
|||
|
||||
// In the next steps, "a" is the font color, "b" is the background color, "f" is the font value at this pixel, "t" is the texture value
|
||||
|
||||
// So the square error of one pixel is:
|
||||
// So the square error of one pixel is:
|
||||
// e = ( t - a⋅f - b⋅(1-f) ) ^ 2
|
||||
|
||||
// In longer:
|
||||
|
@ -78,11 +69,11 @@ void main()
|
|||
|
||||
// So, both equations must be zero at minimum and there is only one solution.
|
||||
|
||||
vec4 a = (f*ft - ff*t + f*t - ft*float(char_pixels)) / (f*f - ff*float(char_pixels));
|
||||
vec4 b = (f*ft - ff*t) / (f*f - ff*float(char_pixels));
|
||||
float4 a = (f*ft - ff*t + f*t - ft*float(char_pixels)) / (f*f - ff*float(char_pixels));
|
||||
float4 b = (f*ft - ff*t) / (f*f - ff*float(char_pixels));
|
||||
|
||||
vec4 diff = a*a*ff + 2.0*a*b*f - 2.0*a*b*ff - 2.0*a*ft + b*b *(-2.0*f + ff + float(char_pixels)) + 2.0*b*ft - 2.0*b*t + tt;
|
||||
float diff_f = dot(diff, vec4(1.0, 1.0, 1.0, 1.0));
|
||||
float4 diff = a*a*ff + 2.0*a*b*f - 2.0*a*b*ff - 2.0*a*ft + b*b *(-2.0*f + ff + float(char_pixels)) + 2.0*b*ft - 2.0*b*t + tt;
|
||||
float diff_f = dot(diff, float4(1.0, 1.0, 1.0, 1.0));
|
||||
|
||||
if (diff_f < mindiff)
|
||||
{
|
||||
|
@ -93,8 +84,8 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
vec2 font_pos_res = vec2(minc * float(char_width), 0.0) + pixel_offset + 0.5;
|
||||
float2 font_pos_res = float2(minc * float(char_width), 0.0) + pixel_offset + 0.5;
|
||||
|
||||
vec4 col = texture(samp8, font_pos_res * font_scale);
|
||||
ocol0 = mina * col + minb * (vec4(1.0,1.0,1.0,1.0) - col);
|
||||
float4 col = SampleFontLocation(font_pos_res * font_scale);
|
||||
SetOutput(mina * col + minb * (float4(1.0,1.0,1.0,1.0) - col));
|
||||
}
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 to_gray = vec4(0.3,0.59,0.11,0);
|
||||
float4 to_gray = float4(0.3,0.59,0.11,0);
|
||||
|
||||
float x1 = dot(to_gray, texture(samp9, uv0+vec2(1,1)*resolution.zw));
|
||||
float x0 = dot(to_gray, texture(samp9, uv0+vec2(-1,-1)*resolution.zw));
|
||||
float x3 = dot(to_gray, texture(samp9, uv0+vec2(1,-1)*resolution.zw));
|
||||
float x2 = dot(to_gray, texture(samp9, uv0+vec2(-1,1)*resolution.zw));
|
||||
float x1 = dot(to_gray, SampleOffset(int2( 1, 1)));
|
||||
float x0 = dot(to_gray, SampleOffset(int2(-1,-1)));
|
||||
float x3 = dot(to_gray, SampleOffset(int2( 1,-1)));
|
||||
float x2 = dot(to_gray, SampleOffset(int2(-1, 1)));
|
||||
|
||||
float edge = (x1 - x0) * (x1 - x0) + (x3 - x2) * (x3 - x2);
|
||||
|
||||
float4 color = texture(samp9, uv0).rgba;
|
||||
float4 color = Sample();
|
||||
|
||||
ocol0 = color - vec4(edge, edge, edge, edge) * 12.0;
|
||||
SetOutput(color - float4(edge, edge, edge, edge) * 12.0);
|
||||
}
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//Changethis to increase the number of colors.
|
||||
int numColors =8;
|
||||
|
||||
float4 to_gray = float4(0.3,0.59,0.11,0);
|
||||
float x1 = dot(to_gray, texture(samp9, uv0+vec2(1,1)*resolution.zw));
|
||||
float x0 = dot(to_gray, texture(samp9, uv0+vec2(-1,-1)*resolution.zw));
|
||||
float x3 = dot(to_gray, texture(samp9, uv0+vec2(1,-1)*resolution.zw));
|
||||
float x2 = dot(to_gray, texture(samp9, uv0+vec2(-1,1)*resolution.zw));
|
||||
float x1 = dot(to_gray, SampleOffset(int2( 1, 1)));
|
||||
float x0 = dot(to_gray, SampleOffset(int2(-1,-1)));
|
||||
float x3 = dot(to_gray, SampleOffset(int2( 1,-1)));
|
||||
float x2 = dot(to_gray, SampleOffset(int2(-1, 1)));
|
||||
float edge = (x1 - x0) * (x1 - x0) + (x3 - x2) * (x3 - x2);
|
||||
float4 color = texture(samp9, uv0).rgba;
|
||||
float4 color = Sample();
|
||||
|
||||
float4 c0 = color - float4(edge, edge, edge, edge) * 12.0;
|
||||
|
||||
|
@ -66,7 +58,7 @@ void main()
|
|||
blue = 0.95;
|
||||
else
|
||||
blue = colorN ;
|
||||
|
||||
|
||||
bb = true;
|
||||
}
|
||||
|
||||
|
@ -92,5 +84,5 @@ void main()
|
|||
break;
|
||||
}
|
||||
|
||||
ocol0 = float4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,43 +1,36 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c_center = texture(samp9, uv0);
|
||||
float4 c_center = Sample();
|
||||
|
||||
float4 bloom_sum = float4(0.0, 0.0, 0.0, 0.0);
|
||||
vec2 pos = uv0 + float2(0.3, 0.3) * resolution.zw;
|
||||
float2 radius1 = 1.3 * resolution.zw;
|
||||
bloom_sum += texture(samp9, pos + float2(-1.5, -1.5) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(-2.5, 0.0) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(-1.5, 1.5) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(0.0, 2.5) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(1.5, 1.5) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(2.5, 0.0) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(1.5, -1.5) * radius1);
|
||||
bloom_sum += texture(samp9, pos + float2(0.0, -2.5) * radius1);
|
||||
float2 pos = GetCoordinates() + float2(0.3, 0.3) * GetInvResolution();
|
||||
float2 radius1 = 1.3 * GetInvResolution();
|
||||
bloom_sum += SampleLocation(pos + float2(-1.5, -1.5) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(-2.5, 0.0) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(-1.5, 1.5) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(0.0, 2.5) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(1.5, 1.5) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(2.5, 0.0) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(1.5, -1.5) * radius1);
|
||||
bloom_sum += SampleLocation(pos + float2(0.0, -2.5) * radius1);
|
||||
|
||||
float2 radius2 = 4.6 * resolution.zw;
|
||||
bloom_sum += texture(samp9, pos + float2(-1.5, -1.5) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(-2.5, 0.0) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(-1.5, 1.5) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(0.0, 2.5) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(1.5, 1.5) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(2.5, 0.0) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(1.5, -1.5) * radius2);
|
||||
bloom_sum += texture(samp9, pos + float2(0.0, -2.5) * radius2);
|
||||
float2 radius2 = 4.6 * GetInvResolution();
|
||||
bloom_sum += SampleLocation(pos + float2(-1.5, -1.5) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(-2.5, 0.0) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(-1.5, 1.5) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(0.0, 2.5) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(1.5, 1.5) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(2.5, 0.0) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(1.5, -1.5) * radius2);
|
||||
bloom_sum += SampleLocation(pos + float2(0.0, -2.5) * radius2);
|
||||
|
||||
bloom_sum *= 0.07;
|
||||
bloom_sum -= float4(0.3, 0.3, 0.3, 0.3);
|
||||
bloom_sum = max(bloom_sum, float4(0.0, 0.0, 0.0, 0.0));
|
||||
|
||||
float2 vpos = (uv0 - float2(0.5, 0.5)) * 2.0;
|
||||
float2 vpos = (GetCoordinates() - float2(0.5, 0.5)) * 2.0;
|
||||
float dist = (dot(vpos, vpos));
|
||||
dist = 1.0 - 0.4*dist;
|
||||
|
||||
ocol0 = (c_center * 0.7 + bloom_sum) * dist;
|
||||
SetOutput((c_center * 0.7 + bloom_sum) * dist);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0) * 3.0;
|
||||
SetOutput(Sample()* 3.0);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
|
||||
|
@ -14,5 +9,5 @@ void main()
|
|||
else
|
||||
red = c0.r + 0.4;
|
||||
|
||||
ocol0 = vec4(red, green, 0.0, 1.0);
|
||||
SetOutput(float4(red, green, 0.0, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -21,5 +16,5 @@ void main()
|
|||
green = c0.r;
|
||||
}
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0);
|
||||
float4 c1 = texture(samp9, uv0 - float2(1.0, 0.0) * resolution.zw);
|
||||
float4 c2 = texture(samp9, uv0 - float2(0.0, 1.0) * resolution.zw);
|
||||
float4 c3 = texture(samp9, uv0 + float2(1.0, 0.0) * resolution.zw);
|
||||
float4 c4 = texture(samp9, uv0 + float2(0.0, 1.0) * resolution.zw);
|
||||
float4 c0 = Sample();
|
||||
float4 c1 = SampleOffset(int2(-1, 0));
|
||||
float4 c2 = SampleOffset(int2( 0, -1));
|
||||
float4 c3 = SampleOffset(int2( 1, 0));
|
||||
float4 c4 = SampleOffset(int2( 0, 1));
|
||||
|
||||
float red = c0.r;
|
||||
float blue = c0.b;
|
||||
|
@ -36,5 +29,5 @@ void main()
|
|||
else
|
||||
blue = c0.b - c0.b / 2.0;
|
||||
|
||||
ocol0 = float4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,17 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c1 = texture(samp9, uv0 + float2(5.0,5.0)*resolution.zw).rgba;
|
||||
float y = (0.222 * c1.r) + (0.707 * c1.g) + (0.071 * c1.b);
|
||||
float y2 = ((0.222 * c0.r) + (0.707 * c0.g) + (0.071 * c0.b)) / 3.0;
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
float alpha = c0.a;
|
||||
float4 c0 = Sample();
|
||||
float4 c1 = SampleOffset(int2(5, 5));
|
||||
float y = (0.222 * c1.r) + (0.707 * c1.g) + (0.071 * c1.b);
|
||||
float y2 = ((0.222 * c0.r) + (0.707 * c0.g) + (0.071 * c0.b)) / 3.0;
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
float alpha = c0.a;
|
||||
|
||||
red = y2 + (1.0 - y);
|
||||
green = y2 + (1.0 - y);
|
||||
blue = y2 + (1.0 - y);
|
||||
|
||||
ocol0 = float4(red, green, blue, alpha);
|
||||
SetOutput(float4(red, green, blue, alpha));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -30,5 +25,5 @@ void main()
|
|||
if (((c0.r + c0.g + c0.b) / 3.0) > 0.9)
|
||||
green = c0.r / 3.0;
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -14,5 +9,5 @@ void main()
|
|||
red = c0.r + (c0.g / 2.0) + (c0.b / 3.0);
|
||||
green = c0.r / 3.0;
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0);
|
||||
float4 c1 = texture(samp9, uv0 + float2(1,1)*resolution.zw);
|
||||
float4 c2 = texture(samp9, uv0 + float2(-1,-1)*resolution.zw);
|
||||
float4 c0 = Sample();
|
||||
float4 c1 = SampleOffset(int2( 1, 1));
|
||||
float4 c2 = SampleOffset(int2(-1, -1));
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
|
@ -18,5 +11,5 @@ void main()
|
|||
red = c0.r - c1.b;
|
||||
blue = c0.b - c2.r + (c0.g - c0.r);
|
||||
|
||||
ocol0 = float4(red, 0.0, blue, alpha);
|
||||
SetOutput(float4(red, 0.0, blue, alpha));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float avg = (c0.r + c0.g + c0.b) / 3.0;
|
||||
ocol0 = vec4(avg, avg, avg, c0.a);
|
||||
SetOutput(float4(avg, avg, avg, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
// Info: http://www.oreillynet.com/cs/user/view/cs_msg/8691
|
||||
float avg = (0.222 * c0.r) + (0.707 * c0.g) + (0.071 * c0.b);
|
||||
ocol0 = vec4(avg, avg, avg, c0.a);
|
||||
SetOutput(float4(avg, avg, avg, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = vec4(1.0, 1.0, 1.0, 1.0) - texture(samp9, uv0);
|
||||
SetOutput(float4(1.0, 1.0, 1.0, 1.0) - Sample());
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = vec4(0.0, 0.0, 0.7, 1.0) - texture(samp9, uv0);
|
||||
SetOutput(float4(0.0, 0.0, 0.7, 1.0) - Sample());
|
||||
}
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0);
|
||||
float4 c1 = texture(samp9, uv0 + float2(5,5)*resolution.zw);
|
||||
float4 c0 = Sample();
|
||||
float4 c1 = SampleOffset(int2(5, 5));
|
||||
|
||||
ocol0 = c0 - c1;
|
||||
SetOutput(c0 - c1);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,19 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 emboss = (texture(samp9, uv0+resolution.zw) - texture(samp9, uv0-resolution.zw))*2.0;
|
||||
emboss -= (texture(samp9, uv0+float2(1,-1)*resolution.zw).rgba - texture(samp9, uv0+float2(-1,1)*resolution.zw).rgba);
|
||||
float4 color = texture(samp9, uv0).rgba;
|
||||
float4 emboss = (SampleLocation(GetCoordinates()+GetInvResolution()) - SampleLocation(GetCoordinates()-GetInvResolution()))*2.0;
|
||||
emboss -= (SampleLocation(GetCoordinates()+float2(1,-1)*GetInvResolution()).rgba - SampleLocation(GetCoordinates()+float2(-1,1)*GetInvResolution()).rgba);
|
||||
float4 color = Sample();
|
||||
|
||||
if (color.r > 0.8 && color.b + color.b < 0.2)
|
||||
{
|
||||
ocol0 = float4(1,0,0,0);
|
||||
SetOutput(float4(1,0,0,0));
|
||||
}
|
||||
else
|
||||
{
|
||||
color += emboss;
|
||||
if (dot(color.rgb, float3(0.3, 0.5, 0.2)) > 0.5)
|
||||
ocol0 = float4(1,1,1,1);
|
||||
SetOutput(float4(1,1,1,1));
|
||||
else
|
||||
ocol0 = float4(0,0,0,0);
|
||||
SetOutput(float4(0,0,0,0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
float green = c0.g;
|
||||
|
||||
if (c0.g < 0.50)
|
||||
green = c0.r + c0.b;
|
||||
|
||||
ocol0 = float4(0.0, green, 0.0, 1.0);
|
||||
SetOutput(float4(0.0, green, 0.0, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
//variables
|
||||
float internalresolution = 1278.0;
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
|
||||
//blur
|
||||
float4 blurtotal = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float blursize = 1.5;
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, -blursize) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, blursize) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, -blursize) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, blursize) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, 0.0) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, 0.0) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( 0.0, -blursize) * resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( 0.0, blursize) * resolution.zw);
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, -blursize) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, blursize) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, -blursize) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, blursize) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, 0.0) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, 0.0) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( 0.0, -blursize) * GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( 0.0, blursize) * GetInvResolution());
|
||||
blurtotal *= 0.125;
|
||||
c0 = blurtotal;
|
||||
|
||||
|
@ -32,8 +25,8 @@ void main()
|
|||
grey = grey * 0.5 + 0.7;
|
||||
|
||||
// darken edges
|
||||
float x = uv0.x * resolution.x;
|
||||
float y = uv0.y * resolution.y;
|
||||
float x = GetCoordinates().x * GetResolution().x;
|
||||
float y = GetCoordinates().y * GetResolution().y;
|
||||
if (x > internalresolution/2.0)
|
||||
x = internalresolution-x;
|
||||
if (y > internalresolution/2.0)
|
||||
|
@ -65,5 +58,5 @@ void main()
|
|||
grey -= y / 200.0;
|
||||
|
||||
// output
|
||||
ocol0 = float4(0.0, grey, 0.0, 1.0);
|
||||
SetOutput(float4(0.0, grey, 0.0, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
//variables
|
||||
float internalresolution = 1278.0;
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
|
||||
//blur
|
||||
float4 blurtotal = float4(0.0, 0.0, 0.0, 0.0);
|
||||
float blursize = 1.5;
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, -blursize)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, blursize)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, -blursize)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, blursize)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2(-blursize, 0.0)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( blursize, 0.0)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( 0.0, -blursize)*resolution.zw);
|
||||
blurtotal += texture(samp9, uv0 + float2( 0.0, blursize)*resolution.zw);
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, -blursize)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, blursize)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, -blursize)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, blursize)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2(-blursize, 0.0)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( blursize, 0.0)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( 0.0, -blursize)*GetInvResolution());
|
||||
blurtotal += SampleLocation(GetCoordinates() + float2( 0.0, blursize)*GetInvResolution());
|
||||
blurtotal *= 0.125;
|
||||
c0 = blurtotal;
|
||||
|
||||
|
@ -31,14 +24,14 @@ void main()
|
|||
// brighten and apply horizontal scanlines
|
||||
// This would have been much simpler if I could get the stupid modulo (%) to work
|
||||
// If anyone who is more well versed in Cg knows how to do this it'd be slightly more efficient
|
||||
// float lineIntensity = ((uv0[1] % 9) - 4) / 40;
|
||||
float vPos = uv0.y*resolution.y / 9.0;
|
||||
// float lineIntensity = ((GetCoordinates()[1] % 9) - 4) / 40;
|
||||
float vPos = GetCoordinates().y*GetResolution().y / 9.0;
|
||||
float lineIntensity = (((vPos - floor(vPos)) * 9.0) - 4.0) / 40.0;
|
||||
grey = grey * 0.5 + 0.7 + lineIntensity;
|
||||
|
||||
// darken edges
|
||||
float x = uv0.x * resolution.x;
|
||||
float y = uv0.y * resolution.y;
|
||||
float x = GetCoordinates().x * GetResolution().x;
|
||||
float y = GetCoordinates().y * GetResolution().y;
|
||||
|
||||
if (x > internalresolution/2.0)
|
||||
x = internalresolution-x;
|
||||
|
@ -74,5 +67,5 @@ void main()
|
|||
grey -= y / 200.0;
|
||||
|
||||
// output
|
||||
ocol0 = float4(0.0, grey, 0.0, 1.0);
|
||||
SetOutput(float4(0.0, grey, 0.0, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -19,5 +14,5 @@ void main()
|
|||
if (c0.b > 0.25)
|
||||
blue = c0.b;
|
||||
|
||||
ocol0 = float4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
float bound(float color)
|
||||
{
|
||||
if (color < 0.35)
|
||||
|
@ -18,6 +13,6 @@ float bound(float color)
|
|||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0);
|
||||
ocol0 = float4(bound(c0.r), bound(c0.g), bound(c0.b), c0.a);
|
||||
float4 c0 = Sample();
|
||||
SetOutput(float4(bound(c0.r), bound(c0.g), bound(c0.b), c0.a));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = c0.r;
|
||||
float blue = c0.b;
|
||||
float green = c0.g;
|
||||
|
@ -78,5 +73,5 @@ void main()
|
|||
green = 0.05;
|
||||
}
|
||||
}
|
||||
ocol0 = vec4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
|
||||
// Same coefficients as grayscale2 at this point
|
||||
float avg = (0.222 * c0.r) + (0.707 * c0.g) + (0.071 * c0.b);
|
||||
|
@ -14,5 +9,5 @@ void main()
|
|||
// Not sure about these coefficients, they just seem to produce the proper yellow
|
||||
float green=avg*.75;
|
||||
float blue=avg*.5;
|
||||
ocol0 = vec4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,17 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
float4 tmp = float4(0.0, 0.0, 0.0, 0.0);
|
||||
tmp += c0 - texture(samp9, uv0 + float2(2.0, 2.0)*resolution.zw).rgba;
|
||||
tmp += c0 - texture(samp9, uv0 - float2(2.0, 2.0)*resolution.zw).rgba;
|
||||
tmp += c0 - texture(samp9, uv0 + float2(2.0, -2.0)*resolution.zw).rgba;
|
||||
tmp += c0 - texture(samp9, uv0 - float2(2.0, -2.0)*resolution.zw).rgba;
|
||||
tmp += c0 - SampleOffset(int2( 2, 2));
|
||||
tmp += c0 - SampleOffset(int2(-2, -2));
|
||||
tmp += c0 - SampleOffset(int2( 2, -2));
|
||||
tmp += c0 - SampleOffset(int2(-2, 2));
|
||||
float grey = ((0.222 * tmp.r) + (0.707 * tmp.g) + (0.071 * tmp.b));
|
||||
|
||||
// get rid of the bottom line, as it is incorrect.
|
||||
if (uv0.y*resolution.y < 163.0)
|
||||
if (GetCoordinates().y*GetResolution().y < 163.0)
|
||||
tmp = float4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
c0 = c0 + 1.0 - grey * 7.0;
|
||||
ocol0 = float4(c0.r, c0.g, c0.b, 1.0);
|
||||
SetOutput(float4(c0.r, c0.g, c0.b, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float blue = 0.0;
|
||||
|
||||
|
@ -19,5 +14,5 @@ void main()
|
|||
blue = c0.r + c0.b;
|
||||
}
|
||||
|
||||
ocol0 = vec4(red, 0.0, blue, 1.0);
|
||||
SetOutput(float4(red, 0.0, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -21,5 +16,5 @@ void main()
|
|||
green = c0.r + c0.b;
|
||||
}
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -1,31 +1,24 @@
|
|||
// Omega's 3D Stereoscopic filtering
|
||||
// TODO: Need depth info!
|
||||
|
||||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Source Color
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float sep = 5.0;
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
float4 c0 = Sample();
|
||||
const int sep = 5;
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
|
||||
// Left Eye (Red)
|
||||
float4 c1 = texture(samp9, uv0 + float2(sep,0.0)*resolution.zw).rgba;
|
||||
float4 c1 = SampleOffset(int2(sep, 0));
|
||||
red = max(c0.r, c1.r);
|
||||
|
||||
// Right Eye (Cyan)
|
||||
float4 c2 = texture(samp9, uv0 + float2(-sep,0.0)*resolution.zw).rgba;
|
||||
float4 c2 = SampleOffset(int2(-sep, 0));
|
||||
float cyan = (c2.g + c2.b) / 2.0;
|
||||
green = max(c0.g, cyan);
|
||||
blue = max(c0.b, cyan);
|
||||
|
||||
ocol0 = float4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,31 +1,24 @@
|
|||
// Omega's 3D Stereoscopic filtering (Amber/Blue)
|
||||
// TODO: Need depth info!
|
||||
|
||||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
uniform vec4 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Source Color
|
||||
float4 c0 = texture(samp9, uv0).rgba;
|
||||
float4 c0 = Sample();
|
||||
float sep = 5.0;
|
||||
float red = c0.r;
|
||||
float green = c0.g;
|
||||
float blue = c0.b;
|
||||
|
||||
// Left Eye (Amber)
|
||||
float4 c2 = texture(samp9, uv0 + float2(sep,0.0)*resolution.zw).rgba;
|
||||
float4 c2 = SampleLocation(GetCoordinates() + float2(sep,0.0)*GetInvResolution()).rgba;
|
||||
float amber = (c2.r + c2.g) / 2.0;
|
||||
red = max(c0.r, amber);
|
||||
green = max(c0.g, amber);
|
||||
|
||||
// Right Eye (Blue)
|
||||
float4 c1 = texture(samp9, uv0 + float2(-sep,0.0)*resolution.zw).rgba;
|
||||
float4 c1 = SampleLocation(GetCoordinates() + float2(-sep,0.0)*GetInvResolution()).rgba;
|
||||
blue = max(c0.b, c1.b);
|
||||
|
||||
ocol0 = float4(red, green, blue, c0.a);
|
||||
SetOutput(float4(red, green, blue, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
ocol0 = vec4(c0.r * 1.5, c0.g, c0.b * 0.5, c0.a);
|
||||
float4 c0 = Sample();
|
||||
SetOutput(float4(c0.r * 1.5, c0.g, c0.b * 0.5, c0.a));
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0).bgra;
|
||||
SetOutput(Sample().bgra);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0).brga;
|
||||
SetOutput(Sample().brga);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0).gbra;
|
||||
SetOutput(Sample());
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0).grba;
|
||||
SetOutput(Sample());
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
ocol0 = texture(samp9, uv0).rbga;
|
||||
SetOutput(Sample().rbga);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
SAMPLER_BINDING(9) uniform sampler2D samp9;
|
||||
|
||||
out vec4 ocol0;
|
||||
in vec2 uv0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = texture(samp9, uv0);
|
||||
float4 c0 = Sample();
|
||||
float red = 0.0;
|
||||
float green = 0.0;
|
||||
float blue = 0.0;
|
||||
|
@ -21,5 +16,5 @@ void main()
|
|||
green = c0.r + c0.b;
|
||||
}
|
||||
|
||||
ocol0 = vec4(red, green, blue, 1.0);
|
||||
SetOutput(float4(red, green, blue, 1.0));
|
||||
}
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
#include "Common/IniFile.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut)
|
||||
void IniFile::ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut)
|
||||
{
|
||||
if (line[0] == '#')
|
||||
return;
|
||||
|
@ -40,8 +38,6 @@ void ParseLine(const std::string& line, std::string* keyOut, std::string* valueO
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string& IniFile::NULL_STRING = "";
|
||||
|
||||
void IniFile::Section::Set(const std::string& key, const std::string& newValue)
|
||||
|
|
|
@ -116,6 +116,11 @@ public:
|
|||
|
||||
Section* GetOrCreateSection(const std::string& section);
|
||||
|
||||
// This function is related to parsing data from lines of INI files
|
||||
// It's used outside of IniFile, which is why it is exposed publicly
|
||||
// In particular it is used in PostProcessing for its configuration
|
||||
static void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut);
|
||||
|
||||
private:
|
||||
std::list<Section> sections;
|
||||
|
||||
|
|
|
@ -75,6 +75,23 @@ static bool TryParse(const std::string &str, N *const output)
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename N>
|
||||
bool TryParseVector(const std::string& str, std::vector<N>* output, const char delimiter = ',')
|
||||
{
|
||||
output->clear();
|
||||
std::istringstream buffer(str);
|
||||
std::string variable;
|
||||
|
||||
while (std::getline(buffer, variable, delimiter))
|
||||
{
|
||||
N tmp = 0;
|
||||
if (!TryParse(variable, &tmp))
|
||||
return false;
|
||||
output->push_back(tmp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: kill this
|
||||
bool AsciiToHex(const std::string& _szValue, u32& result);
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ set(GUI_SRCS
|
|||
MemoryCards/WiiSaveCrypted.cpp
|
||||
NetWindow.cpp
|
||||
PatchAddEdit.cpp
|
||||
PostProcessingConfigDiag.cpp
|
||||
SoftwareVideoConfigDialog.cpp
|
||||
TASInputDlg.cpp
|
||||
VideoConfigDiag.cpp
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="TASInputDlg.cpp" />
|
||||
<ClCompile Include="VideoConfigDiag.cpp" />
|
||||
<ClCompile Include="PostProcessingConfigDiag.cpp" />
|
||||
<ClCompile Include="WiimoteConfigDiag.cpp" />
|
||||
<ClCompile Include="WXInputBase.cpp" />
|
||||
<ClCompile Include="WxUtils.cpp" />
|
||||
|
@ -144,6 +145,7 @@
|
|||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="TASInputDlg.h" />
|
||||
<ClInclude Include="VideoConfigDiag.h" />
|
||||
<ClInclude Include="PostProcessingConfigDiag.h" />
|
||||
<ClInclude Include="WiimoteConfigDiag.h" />
|
||||
<ClInclude Include="WXInputBase.h" />
|
||||
<ClInclude Include="WxUtils.h" />
|
||||
|
@ -228,4 +230,4 @@
|
|||
<Message Text="Copy: @(BinaryFiles) -> $(BinaryOutputDir)" Importance="High" />
|
||||
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -93,6 +93,9 @@
|
|||
<ClCompile Include="Debugger\DebuggerPanel.cpp">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PostProcessingConfigDiag.cpp">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VideoConfigDiag.cpp">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClCompile>
|
||||
|
@ -217,6 +220,9 @@
|
|||
<ClInclude Include="Debugger\DebuggerPanel.h">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PostProcessingConfigDiag.h">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VideoConfigDiag.h">
|
||||
<Filter>GUI\Video</Filter>
|
||||
</ClInclude>
|
||||
|
@ -296,4 +302,4 @@
|
|||
<Filter>Resources</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <math.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/slider.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "DolphinWX/PostProcessingConfigDiag.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
|
||||
PostProcessingConfigDiag::PostProcessingConfigDiag(wxWindow* parent, const std::string& shader)
|
||||
: wxDialog(parent, -1,
|
||||
wxString::Format(_("Post Processing Shader Configuration"))),
|
||||
m_shader(shader)
|
||||
{
|
||||
// Depending on if we are running already, either use the one from the videobackend
|
||||
// or generate our own.
|
||||
if (g_renderer && g_renderer->GetPostProcessor())
|
||||
{
|
||||
m_post_processor = g_renderer->GetPostProcessor()->GetConfig();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_post_processor = new PostProcessingShaderConfiguration();
|
||||
m_post_processor->LoadShader(m_shader);
|
||||
}
|
||||
|
||||
// Create our UI classes
|
||||
const PostProcessingShaderConfiguration::ConfigMap& config_map = m_post_processor->GetOptions();
|
||||
for (const auto& it : config_map)
|
||||
{
|
||||
if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_BOOL)
|
||||
{
|
||||
ConfigGrouping* group = new ConfigGrouping(ConfigGrouping::WidgetType::TYPE_TOGGLE,
|
||||
it.second.m_gui_name, it.first, it.second.m_dependent_option,
|
||||
&it.second);
|
||||
m_config_map[it.first] = group;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigGrouping* group = new ConfigGrouping(ConfigGrouping::WidgetType::TYPE_SLIDER,
|
||||
it.second.m_gui_name, it.first, it.second.m_dependent_option,
|
||||
&it.second);
|
||||
m_config_map[it.first] = group;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrange our vectors based on dependency
|
||||
for (const auto& it : m_config_map)
|
||||
{
|
||||
const std::string parent_name = it.second->GetParent();
|
||||
if (parent_name.size())
|
||||
{
|
||||
// Since it depends on a different object, push it to a parent's object
|
||||
m_config_map[parent_name]->AddChild(m_config_map[it.first]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It doesn't have a child, just push it to the vector
|
||||
m_config_groups.push_back(m_config_map[it.first]);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate our UI
|
||||
wxNotebook* const notebook = new wxNotebook(this, -1);
|
||||
wxPanel* const page_general = new wxPanel(notebook, -1);
|
||||
wxFlexGridSizer* const szr_general = new wxFlexGridSizer(2, 5, 5);
|
||||
|
||||
// Now let's actually populate our window with our information
|
||||
bool add_general_page = false;
|
||||
for (const auto& it : m_config_groups)
|
||||
{
|
||||
if (it->HasChildren())
|
||||
{
|
||||
// Options with children get their own tab
|
||||
wxPanel* const page_option = new wxPanel(notebook, -1);
|
||||
wxFlexGridSizer* const szr_option = new wxFlexGridSizer(2, 10, 5);
|
||||
it->GenerateUI(this, page_option, szr_option);
|
||||
|
||||
// Add all the children
|
||||
for (const auto& child : it->GetChildren())
|
||||
{
|
||||
child->GenerateUI(this, page_option, szr_option);
|
||||
}
|
||||
page_option->SetSizerAndFit(szr_option);
|
||||
notebook->AddPage(page_option, _(it->GetGUIName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Options with no children go in to the general tab
|
||||
if (!add_general_page)
|
||||
{
|
||||
// Make it so it doesn't show up if there aren't any options without children.
|
||||
add_general_page = true;
|
||||
}
|
||||
it->GenerateUI(this, page_general, szr_general);
|
||||
}
|
||||
}
|
||||
|
||||
if (add_general_page)
|
||||
{
|
||||
page_general->SetSizerAndFit(szr_general);
|
||||
notebook->InsertPage(0, page_general, _("General"));
|
||||
}
|
||||
|
||||
// Close Button
|
||||
wxButton* const btn_close = new wxButton(this, wxID_OK, _("Close"));
|
||||
btn_close->Bind(wxEVT_BUTTON, &PostProcessingConfigDiag::Event_ClickClose, this);
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, &PostProcessingConfigDiag::Event_Close, this);
|
||||
|
||||
wxBoxSizer* const szr_main = new wxBoxSizer(wxVERTICAL);
|
||||
szr_main->Add(notebook, 1, wxEXPAND | wxALL, 5);
|
||||
szr_main->Add(btn_close, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 5);
|
||||
|
||||
SetSizerAndFit(szr_main);
|
||||
Center();
|
||||
SetFocus();
|
||||
|
||||
UpdateWindowUI();
|
||||
}
|
||||
|
||||
PostProcessingConfigDiag::~PostProcessingConfigDiag()
|
||||
{
|
||||
m_post_processor->SaveOptionsConfiguration();
|
||||
if (g_renderer && g_renderer->GetPostProcessor())
|
||||
m_post_processor = nullptr;
|
||||
else
|
||||
delete m_post_processor;
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::ConfigGrouping::GenerateUI(PostProcessingConfigDiag* dialog, wxWindow* parent, wxFlexGridSizer* sizer)
|
||||
{
|
||||
if (m_type == WidgetType::TYPE_TOGGLE)
|
||||
{
|
||||
m_option_checkbox = new wxCheckBox(parent, wxID_ANY, _(m_gui_name));
|
||||
m_option_checkbox->SetValue(m_config_option->m_bool_value);
|
||||
m_option_checkbox->Bind(wxEVT_CHECKBOX, &PostProcessingConfigDiag::Event_CheckBox,
|
||||
dialog, wxID_ANY, wxID_ANY, new UserEventData(m_option));
|
||||
|
||||
sizer->Add(m_option_checkbox);
|
||||
sizer->AddStretchSpacer();
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t vector_size = 0;
|
||||
if (m_config_option->m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
vector_size = m_config_option->m_integer_values.size();
|
||||
else
|
||||
vector_size = m_config_option->m_float_values.size();
|
||||
|
||||
wxFlexGridSizer* const szr_values = new wxFlexGridSizer(vector_size + 1, 0, 0);
|
||||
wxStaticText* const option_static_text = new wxStaticText(parent, wxID_ANY, _(m_gui_name));
|
||||
sizer->Add(option_static_text);
|
||||
|
||||
for (size_t i = 0; i < vector_size; ++i)
|
||||
{
|
||||
// wxSlider uses a signed integer for it's minimum and maximum values
|
||||
// This won't work for floats.
|
||||
// Let's determine how many steps we can take and use that instead.
|
||||
int steps = 0;
|
||||
int current_value = 0;
|
||||
std::string string_value;
|
||||
if (m_config_option->m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
{
|
||||
// Find out our range by taking the max subtracting the minimum.
|
||||
double range = m_config_option->m_integer_max_values[i] - m_config_option->m_integer_min_values[i];
|
||||
|
||||
// How many steps we have is the range divided by the step interval configured.
|
||||
// This may not be 100% spot on accurate since developers can have odd stepping intervals set.
|
||||
// Round up so if it is outside our range, then set it to the minimum or maximum
|
||||
steps = ceil(range / (double)m_config_option->m_integer_step_values[i]);
|
||||
|
||||
// Default value is just the currently set value here
|
||||
current_value = m_config_option->m_integer_values[i];
|
||||
string_value = std::to_string(m_config_option->m_integer_values[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Same as above but with floats
|
||||
float range = m_config_option->m_float_max_values[i] - m_config_option->m_float_min_values[i];
|
||||
steps = ceil(range / m_config_option->m_float_step_values[i]);
|
||||
|
||||
// We need to convert our default float value from a float to the nearest step value range
|
||||
current_value = (m_config_option->m_float_values[i] / m_config_option->m_float_step_values[i]);
|
||||
string_value = std::to_string(m_config_option->m_float_values[i]);
|
||||
}
|
||||
|
||||
wxSlider* slider = new wxSlider(parent, wxID_ANY, current_value, 0, steps,
|
||||
wxDefaultPosition, wxSize(200, -1), wxSL_HORIZONTAL | wxSL_BOTTOM);
|
||||
wxTextCtrl* text_ctrl = new wxTextCtrl(parent, wxID_ANY, string_value);
|
||||
|
||||
// Disable the textctrl, it's only there to show the absolute value from the slider
|
||||
text_ctrl->Enable(false);
|
||||
|
||||
// wxWidget takes over the pointer provided to it in the event handler.
|
||||
// This won't be a memory leak, it'll be destroyed on dialog close.
|
||||
slider->Bind(wxEVT_SLIDER, &PostProcessingConfigDiag::Event_Slider,
|
||||
dialog, wxID_ANY, wxID_ANY, new UserEventData(m_option));
|
||||
|
||||
m_option_sliders.push_back(slider);
|
||||
m_option_text_ctrls.push_back(text_ctrl);
|
||||
}
|
||||
|
||||
if (vector_size == 1)
|
||||
{
|
||||
szr_values->Add(m_option_sliders[0], wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
szr_values->Add(m_option_text_ctrls[0]);
|
||||
|
||||
sizer->Add(szr_values);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFlexGridSizer* const szr_inside = new wxFlexGridSizer(2, 0, 0);
|
||||
for (size_t i = 0; i < vector_size; ++i)
|
||||
{
|
||||
szr_inside->Add(m_option_sliders[i], wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL));
|
||||
szr_inside->Add(m_option_text_ctrls[i]);
|
||||
}
|
||||
|
||||
szr_values->Add(szr_inside);
|
||||
sizer->Add(szr_values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::ConfigGrouping::EnableDependentChildren(bool enable)
|
||||
{
|
||||
// Enable or disable all the children
|
||||
for (auto& it : m_children)
|
||||
{
|
||||
if (it->m_type == ConfigGrouping::WidgetType::TYPE_TOGGLE)
|
||||
{
|
||||
it->m_option_checkbox->Enable(enable);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& slider : it->m_option_sliders)
|
||||
slider->Enable(enable);
|
||||
}
|
||||
// Set this objects children as well
|
||||
it->EnableDependentChildren(enable);
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::Event_CheckBox(wxCommandEvent &ev)
|
||||
{
|
||||
UserEventData* config_option = (UserEventData*)ev.GetEventUserData();
|
||||
ConfigGrouping* config = m_config_map[config_option->GetData()];
|
||||
|
||||
m_post_processor->SetOptionb(config->GetOption(), ev.IsChecked());
|
||||
|
||||
config->EnableDependentChildren(ev.IsChecked());
|
||||
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::Event_Slider(wxCommandEvent &ev)
|
||||
{
|
||||
UserEventData* config_option = (UserEventData*)ev.GetEventUserData();
|
||||
ConfigGrouping* config = m_config_map[config_option->GetData()];
|
||||
|
||||
const auto& option_data = m_post_processor->GetOption(config->GetOption());
|
||||
|
||||
size_t vector_size = 0;
|
||||
if (option_data.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
vector_size = option_data.m_integer_values.size();
|
||||
else
|
||||
vector_size = option_data.m_float_values.size();
|
||||
|
||||
for (size_t i = 0; i < vector_size; ++i)
|
||||
{
|
||||
// Got to do this garbage again.
|
||||
// Convert current step in to the real range value
|
||||
int current_step = config->GetSliderValue(i);
|
||||
std::string string_value;
|
||||
if (option_data.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
{
|
||||
s32 value = option_data.m_integer_step_values[i] * current_step + option_data.m_integer_min_values[i];
|
||||
m_post_processor->SetOptioni(config->GetOption(), i, value);
|
||||
string_value = std::to_string(value);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
float value = option_data.m_float_step_values[i] * current_step + option_data.m_float_min_values[i];
|
||||
m_post_processor->SetOptionf(config->GetOption(), i, value);
|
||||
string_value = std::to_string(value);
|
||||
}
|
||||
// Update the text box to include the new value
|
||||
config->SetSliderText(i, string_value);
|
||||
}
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::Event_ClickClose(wxCommandEvent&)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void PostProcessingConfigDiag::Event_Close(wxCloseEvent& ev)
|
||||
{
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/slider.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
|
||||
class PostProcessingConfigDiag : public wxDialog
|
||||
{
|
||||
public:
|
||||
PostProcessingConfigDiag(wxWindow* parent, const std::string& shader);
|
||||
~PostProcessingConfigDiag();
|
||||
|
||||
private:
|
||||
|
||||
// This is literally the stupidest thing ever
|
||||
// wxWidgets takes ownership of any pointer given to a event handler
|
||||
// Instead of passing them a pointer to a std::string, we wrap around it here.
|
||||
class UserEventData : public wxObject
|
||||
{
|
||||
public:
|
||||
UserEventData(const std::string& data) : m_data(data) {}
|
||||
const std::string& GetData() { return m_data; }
|
||||
private:
|
||||
const std::string m_data;
|
||||
};
|
||||
|
||||
class ConfigGrouping
|
||||
{
|
||||
public:
|
||||
enum WidgetType
|
||||
{
|
||||
TYPE_TOGGLE,
|
||||
TYPE_SLIDER,
|
||||
};
|
||||
|
||||
ConfigGrouping(WidgetType type, const std::string& gui_name,
|
||||
const std::string& option_name, const std::string& parent,
|
||||
const PostProcessingShaderConfiguration::ConfigurationOption* config_option)
|
||||
: m_type(type), m_gui_name(gui_name),
|
||||
m_option(option_name), m_parent(parent),
|
||||
m_config_option(config_option) {}
|
||||
|
||||
void AddChild(ConfigGrouping* child) { m_children.push_back(child); }
|
||||
bool HasChildren() { return m_children.size() != 0; }
|
||||
std::vector<ConfigGrouping*>& GetChildren() { return m_children; }
|
||||
|
||||
// Gets the string that is shown in the UI for the option
|
||||
const std::string& GetGUIName() { return m_gui_name; }
|
||||
// Gets the option name for use in the shader
|
||||
// Also is a unique identifier for the option's configuration
|
||||
const std::string& GetOption() { return m_option; }
|
||||
// Gets the option name of the parent of this option
|
||||
const std::string& GetParent() { return m_parent; }
|
||||
|
||||
void GenerateUI(PostProcessingConfigDiag* dialog, wxWindow* parent, wxFlexGridSizer* sizer);
|
||||
|
||||
void EnableDependentChildren(bool enable);
|
||||
|
||||
int GetSliderValue(const int index) { return m_option_sliders[index]->GetValue(); }
|
||||
void SetSliderText(const int index, const std::string& text) { m_option_text_ctrls[index]->SetValue(text); }
|
||||
|
||||
private:
|
||||
const WidgetType m_type;
|
||||
const std::string m_gui_name;
|
||||
const std::string m_option;
|
||||
const std::string m_parent;
|
||||
const PostProcessingShaderConfiguration::ConfigurationOption* m_config_option;
|
||||
|
||||
// For TYPE_TOGGLE
|
||||
wxCheckBox* m_option_checkbox;
|
||||
|
||||
// For TYPE_SLIDER
|
||||
// Can have up to 4
|
||||
std::vector<wxSlider*> m_option_sliders;
|
||||
std::vector<wxTextCtrl*> m_option_text_ctrls;
|
||||
|
||||
std::vector<ConfigGrouping*> m_children;
|
||||
};
|
||||
|
||||
// WX UI things
|
||||
void Event_Close(wxCloseEvent&);
|
||||
void Event_ClickClose(wxCommandEvent&);
|
||||
void Event_Slider(wxCommandEvent &ev);
|
||||
void Event_CheckBox(wxCommandEvent &ev);
|
||||
|
||||
const std::string& m_shader;
|
||||
PostProcessingShaderConfiguration* m_post_processor;
|
||||
|
||||
std::map<std::string, ConfigGrouping*> m_config_map;
|
||||
std::vector<ConfigGrouping*> m_config_groups;
|
||||
};
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
@ -32,6 +36,7 @@
|
|||
#include "DolphinWX/VideoConfigDiag.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
#include "VideoBackends/OGL/main.h"
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
|
@ -401,10 +406,13 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
|||
// postproc shader
|
||||
if (vconfig.backend_info.PPShaders.size())
|
||||
{
|
||||
wxFlexGridSizer* const szr_pp = new wxFlexGridSizer(3, 5, 5);
|
||||
wxChoice *const choice_ppshader = new wxChoice(page_enh, -1);
|
||||
RegisterControl(choice_ppshader, wxGetTranslation(ppshader_desc));
|
||||
choice_ppshader->AppendString(_("(off)"));
|
||||
|
||||
button_config_pp = new wxButton(page_enh, wxID_ANY, _("Config"));
|
||||
|
||||
for (const std::string& shader : vconfig.backend_info.PPShaders)
|
||||
{
|
||||
choice_ppshader->AppendString(StrToWxStr(shader));
|
||||
|
@ -415,10 +423,18 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
|||
else
|
||||
choice_ppshader->SetStringSelection(StrToWxStr(vconfig.sPostProcessingShader));
|
||||
|
||||
// Should the configuration button be loaded by default?
|
||||
PostProcessingShaderConfiguration postprocessing_shader;
|
||||
postprocessing_shader.LoadShader(vconfig.sPostProcessingShader);
|
||||
button_config_pp->Enable(postprocessing_shader.HasOptions());
|
||||
|
||||
choice_ppshader->Bind(wxEVT_CHOICE, &VideoConfigDiag::Event_PPShader, this);
|
||||
button_config_pp->Bind(wxEVT_BUTTON, &VideoConfigDiag::Event_ConfigurePPShader, this);
|
||||
|
||||
szr_enh->Add(new wxStaticText(page_enh, -1, _("Post-Processing Effect:")), 1, wxALIGN_CENTER_VERTICAL, 0);
|
||||
szr_enh->Add(choice_ppshader);
|
||||
szr_pp->Add(choice_ppshader);
|
||||
szr_pp->Add(button_config_pp);
|
||||
szr_enh->Add(szr_pp);
|
||||
}
|
||||
|
||||
// Scaled copy, PL, Bilinear filter
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/defs.h>
|
||||
|
@ -22,7 +27,9 @@
|
|||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "DolphinWX/PostProcessingConfigDiag.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
|
@ -142,6 +149,19 @@ protected:
|
|||
else
|
||||
vconfig.sPostProcessingShader.clear();
|
||||
|
||||
// Should we enable the configuration button?
|
||||
PostProcessingShaderConfiguration postprocessing_shader;
|
||||
postprocessing_shader.LoadShader(vconfig.sPostProcessingShader);
|
||||
button_config_pp->Enable(postprocessing_shader.HasOptions());
|
||||
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void Event_ConfigurePPShader(wxCommandEvent &ev)
|
||||
{
|
||||
PostProcessingConfigDiag dialog(this, vconfig.sPostProcessingShader);
|
||||
dialog.ShowModal();
|
||||
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
|
@ -188,6 +208,8 @@ protected:
|
|||
wxStaticText* text_aamode;
|
||||
SettingChoice* choice_aamode;
|
||||
|
||||
wxButton* button_config_pp;
|
||||
|
||||
SettingCheckBox* borderless_fullscreen;
|
||||
|
||||
SettingRadioButton* efbcopy_texture;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "VideoBackends/OGL/FramebufferManager.h"
|
||||
#include "VideoBackends/OGL/GLUtil.h"
|
||||
|
@ -16,20 +17,6 @@
|
|||
namespace OGL
|
||||
{
|
||||
|
||||
namespace PostProcessing
|
||||
{
|
||||
|
||||
static std::string s_currentShader;
|
||||
static SHADER s_shader;
|
||||
static bool s_enable;
|
||||
|
||||
static u32 s_width;
|
||||
static u32 s_height;
|
||||
static GLuint s_fbo;
|
||||
static GLuint s_texture;
|
||||
|
||||
static GLuint s_uniform_resolution;
|
||||
|
||||
static char s_vertex_shader[] =
|
||||
"out vec2 uv0;\n"
|
||||
"void main(void) {\n"
|
||||
|
@ -38,119 +25,278 @@ static char s_vertex_shader[] =
|
|||
" uv0 = rawpos;\n"
|
||||
"}\n";
|
||||
|
||||
void Init()
|
||||
OpenGLPostProcessing::OpenGLPostProcessing()
|
||||
{
|
||||
s_currentShader = "";
|
||||
s_enable = 0;
|
||||
s_width = 0;
|
||||
s_height = 0;
|
||||
m_enable = false;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
|
||||
glGenFramebuffers(1, &s_fbo);
|
||||
glGenTextures(1, &s_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glGenTextures(1, &m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); // disable mipmaps
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, s_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_texture, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
|
||||
FramebufferManager::SetFramebuffer(0);
|
||||
|
||||
CreateHeader();
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
OpenGLPostProcessing::~OpenGLPostProcessing()
|
||||
{
|
||||
s_shader.Destroy();
|
||||
m_shader.Destroy();
|
||||
|
||||
glDeleteFramebuffers(1, &s_fbo);
|
||||
glDeleteTextures(1, &s_texture);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
glDeleteTextures(1, &m_texture);
|
||||
}
|
||||
|
||||
void ReloadShader()
|
||||
void OpenGLPostProcessing::BindTargetFramebuffer()
|
||||
{
|
||||
s_currentShader = "";
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_enable ? m_fbo : 0);
|
||||
}
|
||||
|
||||
void BindTargetFramebuffer ()
|
||||
void OpenGLPostProcessing::BlitToScreen()
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_enable ? s_fbo : 0);
|
||||
}
|
||||
|
||||
void BlitToScreen()
|
||||
{
|
||||
if (!s_enable) return;
|
||||
if (!m_enable) return;
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, s_width, s_height);
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
|
||||
s_shader.Bind();
|
||||
m_shader.Bind();
|
||||
|
||||
glUniform4f(s_uniform_resolution, (float)s_width, (float)s_height, 1.0f/(float)s_width, 1.0f/(float)s_height);
|
||||
glUniform4f(m_uniform_resolution, (float)m_width, (float)m_height, 1.0f/(float)m_width, 1.0f/(float)m_height);
|
||||
glUniform1ui(m_uniform_time, (GLuint)m_timer.GetTimeElapsed());
|
||||
|
||||
if (m_config.IsDirty())
|
||||
{
|
||||
for (auto& it : m_config.GetOptions())
|
||||
{
|
||||
if (it.second.m_dirty)
|
||||
{
|
||||
switch (it.second.m_type)
|
||||
{
|
||||
case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_BOOL:
|
||||
glUniform1i(m_uniform_bindings[it.first], it.second.m_bool_value);
|
||||
break;
|
||||
case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER:
|
||||
switch (it.second.m_integer_values.size())
|
||||
{
|
||||
case 1:
|
||||
glUniform1i(m_uniform_bindings[it.first], it.second.m_integer_values[0]);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2i(m_uniform_bindings[it.first],
|
||||
it.second.m_integer_values[0],
|
||||
it.second.m_integer_values[1]);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3i(m_uniform_bindings[it.first],
|
||||
it.second.m_integer_values[0],
|
||||
it.second.m_integer_values[1],
|
||||
it.second.m_integer_values[2]);
|
||||
break;
|
||||
case 4:
|
||||
glUniform4i(m_uniform_bindings[it.first],
|
||||
it.second.m_integer_values[0],
|
||||
it.second.m_integer_values[1],
|
||||
it.second.m_integer_values[2],
|
||||
it.second.m_integer_values[3]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT:
|
||||
switch (it.second.m_float_values.size())
|
||||
{
|
||||
case 1:
|
||||
glUniform1f(m_uniform_bindings[it.first], it.second.m_float_values[0]);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2f(m_uniform_bindings[it.first],
|
||||
it.second.m_float_values[0],
|
||||
it.second.m_float_values[1]);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3f(m_uniform_bindings[it.first],
|
||||
it.second.m_float_values[0],
|
||||
it.second.m_float_values[1],
|
||||
it.second.m_float_values[2]);
|
||||
break;
|
||||
case 4:
|
||||
glUniform4f(m_uniform_bindings[it.first],
|
||||
it.second.m_float_values[0],
|
||||
it.second.m_float_values[1],
|
||||
it.second.m_float_values[2],
|
||||
it.second.m_float_values[3]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
it.second.m_dirty = false;
|
||||
}
|
||||
}
|
||||
m_config.SetDirty(false);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0+9);
|
||||
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
/* glBindFramebuffer(GL_READ_FRAMEBUFFER, s_fbo);
|
||||
|
||||
glBlitFramebuffer(rc.left, rc.bottom, rc.right, rc.top,
|
||||
rc.left, rc.bottom, rc.right, rc.top,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);*/
|
||||
}
|
||||
|
||||
void Update ( u32 width, u32 height )
|
||||
void OpenGLPostProcessing::Update(u32 width, u32 height)
|
||||
{
|
||||
ApplyShader();
|
||||
|
||||
if (s_enable && (width != s_width || height != s_height)) {
|
||||
s_width = width;
|
||||
s_height = height;
|
||||
if (m_enable && (width != m_width || height != m_height))
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
// alloc texture for framebuffer
|
||||
glActiveTexture(GL_TEXTURE0+9);
|
||||
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyShader()
|
||||
void OpenGLPostProcessing::ApplyShader()
|
||||
{
|
||||
// shader didn't changed
|
||||
if (s_currentShader == g_ActiveConfig.sPostProcessingShader) return;
|
||||
s_currentShader = g_ActiveConfig.sPostProcessingShader;
|
||||
s_enable = false;
|
||||
s_shader.Destroy();
|
||||
if (m_config.GetShader() == g_ActiveConfig.sPostProcessingShader) return;
|
||||
|
||||
m_enable = false;
|
||||
m_shader.Destroy();
|
||||
m_uniform_bindings.clear();
|
||||
|
||||
// shader disabled
|
||||
if (g_ActiveConfig.sPostProcessingShader == "") return;
|
||||
|
||||
// so need to compile shader
|
||||
std::string code = m_config.LoadShader();
|
||||
|
||||
// loading shader code
|
||||
std::string code;
|
||||
std::string path = File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".glsl";
|
||||
if (!File::Exists(path))
|
||||
{
|
||||
// Fallback to shared user dir
|
||||
path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + g_ActiveConfig.sPostProcessingShader + ".glsl";
|
||||
}
|
||||
if (!File::ReadFileToString(path, code)) {
|
||||
ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
if (code == "") return;
|
||||
|
||||
code = LoadShaderOptions(code);
|
||||
|
||||
// and compile it
|
||||
if (!ProgramShaderCache::CompileShader(s_shader, s_vertex_shader, code.c_str())) {
|
||||
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
||||
if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str())) {
|
||||
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// read uniform locations
|
||||
s_uniform_resolution = glGetUniformLocation(s_shader.glprogid, "resolution");
|
||||
m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution");
|
||||
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
|
||||
|
||||
for (const auto& it : m_config.GetOptions())
|
||||
{
|
||||
std::string glsl_name = "option_" + it.first;
|
||||
m_uniform_bindings[it.first] = glGetUniformLocation(m_shader.glprogid, glsl_name.c_str());
|
||||
}
|
||||
|
||||
// successful
|
||||
s_enable = true;
|
||||
m_enable = true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
void OpenGLPostProcessing::CreateHeader()
|
||||
{
|
||||
m_glsl_header =
|
||||
// Required variables
|
||||
// Shouldn't be accessed directly by the PP shader
|
||||
// Texture sampler
|
||||
"SAMPLER_BINDING(8) uniform sampler2D samp8;\n"
|
||||
"SAMPLER_BINDING(9) uniform sampler2D samp9;\n"
|
||||
|
||||
// Output variable
|
||||
"out float4 ocol0;\n"
|
||||
// Input coordinates
|
||||
"in float2 uv0;\n"
|
||||
// Resolution
|
||||
"uniform float4 resolution;\n"
|
||||
// Time
|
||||
"uniform uint time;\n"
|
||||
|
||||
// Interfacing functions
|
||||
"float4 Sample()\n"
|
||||
"{\n"
|
||||
"\treturn texture(samp9, uv0);\n"
|
||||
"}\n"
|
||||
|
||||
"float4 SampleLocation(float2 location)\n"
|
||||
"{\n"
|
||||
"\treturn texture(samp9, location);\n"
|
||||
"}\n"
|
||||
|
||||
"#define SampleOffset(offset) textureOffset(samp9, uv0, offset)\n"
|
||||
|
||||
"float4 SampleFontLocation(float2 location)\n"
|
||||
"{\n"
|
||||
"\treturn texture(samp8, location);\n"
|
||||
"}\n"
|
||||
|
||||
"float2 GetResolution()\n"
|
||||
"{\n"
|
||||
"\treturn resolution.xy;\n"
|
||||
"}\n"
|
||||
|
||||
"float2 GetInvResolution()\n"
|
||||
"{\n"
|
||||
"\treturn resolution.zw;\n"
|
||||
"}\n"
|
||||
|
||||
"float2 GetCoordinates()\n"
|
||||
"{\n"
|
||||
"\treturn uv0;\n"
|
||||
"}\n"
|
||||
|
||||
"uint GetTime()\n"
|
||||
"{\n"
|
||||
"\treturn time;\n"
|
||||
"}\n"
|
||||
|
||||
"void SetOutput(float4 color)\n"
|
||||
"{\n"
|
||||
"\tocol0 = color;\n"
|
||||
"}\n"
|
||||
|
||||
"#define GetOption(x) (option_#x)\n"
|
||||
"#define OptionEnabled(x) (option_#x != 0)\n";
|
||||
}
|
||||
|
||||
std::string OpenGLPostProcessing::LoadShaderOptions(const std::string& code)
|
||||
{
|
||||
std::string glsl_options = "";
|
||||
m_uniform_bindings.clear();
|
||||
|
||||
for (const auto& it : m_config.GetOptions())
|
||||
{
|
||||
if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_BOOL)
|
||||
{
|
||||
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
|
||||
}
|
||||
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
{
|
||||
u32 count = it.second.m_integer_values.size();
|
||||
if (count == 1)
|
||||
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
|
||||
else
|
||||
glsl_options += StringFromFormat("uniform int%d option_%s;\n", count, it.first.c_str());
|
||||
}
|
||||
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT)
|
||||
{
|
||||
u32 count = it.second.m_float_values.size();
|
||||
if (count == 1)
|
||||
glsl_options += StringFromFormat("uniform float option_%s;\n", it.first.c_str());
|
||||
else
|
||||
glsl_options += StringFromFormat("uniform float%d option_%s;\n", count, it.first.c_str());
|
||||
}
|
||||
|
||||
m_uniform_bindings[it.first] = 0;
|
||||
}
|
||||
|
||||
return m_glsl_header + glsl_options + code;
|
||||
}
|
||||
|
||||
} // namespace OGL
|
||||
|
|
|
@ -4,26 +4,40 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "VideoBackends/OGL/GLUtil.h"
|
||||
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
|
||||
namespace PostProcessing
|
||||
class OpenGLPostProcessing : public PostProcessingShaderImplementation
|
||||
{
|
||||
public:
|
||||
OpenGLPostProcessing();
|
||||
~OpenGLPostProcessing();
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void BindTargetFramebuffer() override;
|
||||
void BlitToScreen() override;
|
||||
void Update(u32 width, u32 height) override;
|
||||
void ApplyShader() override;
|
||||
|
||||
void BindTargetFramebuffer();
|
||||
void BlitToScreen();
|
||||
void Update(u32 width, u32 height);
|
||||
private:
|
||||
GLuint m_fbo;
|
||||
GLuint m_texture;
|
||||
SHADER m_shader;
|
||||
GLuint m_uniform_resolution;
|
||||
GLuint m_uniform_time;
|
||||
std::string m_glsl_header;
|
||||
|
||||
void ReloadShader();
|
||||
std::unordered_map<std::string, GLuint> m_uniform_bindings;
|
||||
|
||||
void ApplyShader();
|
||||
|
||||
} // namespace
|
||||
void CreateHeader();
|
||||
std::string LoadShaderOptions(const std::string& code);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -641,6 +641,9 @@ void Renderer::Shutdown()
|
|||
delete s_pfont;
|
||||
s_pfont = nullptr;
|
||||
s_ShowEFBCopyRegions.Destroy();
|
||||
|
||||
delete m_post_processor;
|
||||
m_post_processor = nullptr;
|
||||
}
|
||||
|
||||
void Renderer::Init()
|
||||
|
@ -649,6 +652,8 @@ void Renderer::Init()
|
|||
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
||||
s_MSAASamples);
|
||||
|
||||
m_post_processor = new OpenGLPostProcessing();
|
||||
|
||||
s_pfont = new RasterFont();
|
||||
|
||||
ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions,
|
||||
|
@ -1331,7 +1336,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
|
||||
ResetAPIState();
|
||||
|
||||
PostProcessing::Update(s_backbuffer_width, s_backbuffer_height);
|
||||
m_post_processor->Update(s_backbuffer_width, s_backbuffer_height);
|
||||
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||
TargetRectangle flipped_trc = GetTargetRectangle();
|
||||
|
||||
|
@ -1354,7 +1359,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
// Render to the real/postprocessing buffer now.
|
||||
PostProcessing::BindTargetFramebuffer();
|
||||
m_post_processor->BindTargetFramebuffer();
|
||||
|
||||
// draw each xfb source
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
|
||||
|
@ -1413,7 +1418,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
FramebufferManager::ResolveAndGetRenderTarget(rc);
|
||||
|
||||
// Render to the real/postprocessing buffer now. (resolve have changed this in msaa mode)
|
||||
PostProcessing::BindTargetFramebuffer();
|
||||
m_post_processor->BindTargetFramebuffer();
|
||||
|
||||
// always the non-msaa fbo
|
||||
GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
|
||||
|
@ -1424,7 +1429,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
|||
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
}
|
||||
|
||||
PostProcessing::BlitToScreen();
|
||||
m_post_processor->BlitToScreen();
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
|
|
|
@ -210,7 +210,6 @@ void VideoBackend::Video_Prepare()
|
|||
VertexShaderManager::Init();
|
||||
PixelShaderManager::Init();
|
||||
ProgramShaderCache::Init();
|
||||
PostProcessing::Init();
|
||||
g_texture_cache = new TextureCache();
|
||||
g_sampler_cache = new SamplerCache();
|
||||
Renderer::Init();
|
||||
|
@ -250,7 +249,6 @@ void VideoBackend::Video_Cleanup() {
|
|||
g_sampler_cache = nullptr;
|
||||
delete g_texture_cache;
|
||||
g_texture_cache = nullptr;
|
||||
PostProcessing::Shutdown();
|
||||
ProgramShaderCache::Shutdown();
|
||||
VertexShaderManager::Shutdown();
|
||||
PixelShaderManager::Shutdown();
|
||||
|
|
|
@ -18,6 +18,7 @@ set(SRCS BPFunctions.cpp
|
|||
PixelEngine.cpp
|
||||
PixelShaderGen.cpp
|
||||
PixelShaderManager.cpp
|
||||
PostProcessing.cpp
|
||||
RenderBase.cpp
|
||||
Statistics.cpp
|
||||
TextureCacheBase.cpp
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
|
||||
PostProcessingShaderImplementation::PostProcessingShaderImplementation()
|
||||
{
|
||||
m_timer.Start();
|
||||
}
|
||||
|
||||
PostProcessingShaderImplementation::~PostProcessingShaderImplementation()
|
||||
{
|
||||
m_timer.Stop();
|
||||
}
|
||||
|
||||
std::string PostProcessingShaderConfiguration::LoadShader(std::string shader)
|
||||
{
|
||||
// Load the shader from the configuration if there isn't one sent to us.
|
||||
if (shader == "")
|
||||
shader = g_ActiveConfig.sPostProcessingShader;
|
||||
m_current_shader = shader;
|
||||
|
||||
// loading shader code
|
||||
std::string code;
|
||||
std::string path = File::GetUserPath(D_SHADERS_IDX) + shader + ".glsl";
|
||||
|
||||
if (!File::Exists(path))
|
||||
{
|
||||
// Fallback to shared user dir
|
||||
path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + shader + ".glsl";
|
||||
}
|
||||
|
||||
if (!File::ReadFileToString(path, code))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Post-processing shader not found: %s", path.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
LoadOptions(code);
|
||||
LoadOptionsConfiguration();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::LoadOptions(const std::string& code)
|
||||
{
|
||||
const std::string config_start_delimiter = "[configuration]";
|
||||
const std::string config_end_delimiter = "[/configuration]";
|
||||
size_t configuration_start = code.find(config_start_delimiter);
|
||||
size_t configuration_end = code.find(config_end_delimiter);
|
||||
|
||||
m_options.clear();
|
||||
m_any_options_dirty = true;
|
||||
|
||||
if (configuration_start == std::string::npos ||
|
||||
configuration_end == std::string::npos)
|
||||
{
|
||||
// Issue loading configuration or there isn't one.
|
||||
return;
|
||||
}
|
||||
|
||||
std::string configuration_string = code.substr(configuration_start + config_start_delimiter.size(),
|
||||
configuration_end - configuration_start - config_start_delimiter.size());
|
||||
|
||||
std::istringstream in(configuration_string);
|
||||
|
||||
struct GLSLStringOption
|
||||
{
|
||||
std::string m_type;
|
||||
std::vector<std::pair<std::string, std::string>> m_options;
|
||||
};
|
||||
|
||||
std::vector<GLSLStringOption> option_strings;
|
||||
GLSLStringOption* current_strings = nullptr;
|
||||
while (!in.eof())
|
||||
{
|
||||
std::string line;
|
||||
|
||||
if (std::getline(in, line))
|
||||
{
|
||||
#ifndef _WIN32
|
||||
// Check for CRLF eol and convert it to LF
|
||||
if (!line.empty() && line.at(line.size()-1) == '\r')
|
||||
{
|
||||
line.erase(line.size()-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (line.size() > 0)
|
||||
{
|
||||
if (line[0] == '[')
|
||||
{
|
||||
size_t endpos = line.find("]");
|
||||
|
||||
if (endpos != std::string::npos)
|
||||
{
|
||||
// New section!
|
||||
std::string sub = line.substr(1, endpos - 1);
|
||||
option_strings.push_back({ sub });
|
||||
current_strings = &option_strings.back();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_strings)
|
||||
{
|
||||
std::string key, value;
|
||||
IniFile::ParseLine(line, &key, &value);
|
||||
|
||||
if (!(key == "" && value == ""))
|
||||
current_strings->m_options.push_back(std::make_pair(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : option_strings)
|
||||
{
|
||||
ConfigurationOption option;
|
||||
option.m_dirty = true;
|
||||
|
||||
if (it.m_type == "OptionBool")
|
||||
option.m_type = ConfigurationOption::OptionType::OPTION_BOOL;
|
||||
else if (it.m_type == "OptionRangeFloat")
|
||||
option.m_type = ConfigurationOption::OptionType::OPTION_FLOAT;
|
||||
else if (it.m_type == "OptionRangeInteger")
|
||||
option.m_type = ConfigurationOption::OptionType::OPTION_INTEGER;
|
||||
|
||||
for (const auto& string_option : it.m_options)
|
||||
{
|
||||
if (string_option.first == "GUIName")
|
||||
{
|
||||
option.m_gui_name = string_option.second;
|
||||
}
|
||||
else if (string_option.first == "OptionName")
|
||||
{
|
||||
option.m_option_name = string_option.second;
|
||||
}
|
||||
else if (string_option.first == "DependentOption")
|
||||
{
|
||||
option.m_dependent_option = string_option.second;
|
||||
}
|
||||
else if (string_option.first == "MinValue" ||
|
||||
string_option.first == "MaxValue" ||
|
||||
string_option.first == "DefaultValue" ||
|
||||
string_option.first == "StepAmount")
|
||||
{
|
||||
std::vector<s32>* output_integer = nullptr;
|
||||
std::vector<float>* output_float = nullptr;
|
||||
|
||||
if (string_option.first == "MinValue")
|
||||
{
|
||||
output_integer = &option.m_integer_min_values;
|
||||
output_float = &option.m_float_min_values;
|
||||
}
|
||||
else if (string_option.first == "MaxValue")
|
||||
{
|
||||
output_integer = &option.m_integer_max_values;
|
||||
output_float = &option.m_float_max_values;
|
||||
}
|
||||
else if (string_option.first == "DefaultValue")
|
||||
{
|
||||
output_integer = &option.m_integer_values;
|
||||
output_float = &option.m_float_values;
|
||||
}
|
||||
else if (string_option.first == "StepAmount")
|
||||
{
|
||||
output_integer = &option.m_integer_step_values;
|
||||
output_float = &option.m_float_step_values;
|
||||
}
|
||||
|
||||
if (option.m_type == ConfigurationOption::OptionType::OPTION_BOOL)
|
||||
{
|
||||
TryParse(string_option.second, &option.m_bool_value);
|
||||
}
|
||||
else if (option.m_type == ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||
{
|
||||
TryParseVector(string_option.second, output_integer);
|
||||
if (output_integer->size() > 4)
|
||||
output_integer->erase(output_integer->begin() + 4, output_integer->end());
|
||||
}
|
||||
else if (option.m_type == ConfigurationOption::OptionType::OPTION_FLOAT)
|
||||
{
|
||||
TryParseVector(string_option.second, output_float);
|
||||
if (output_float->size() > 4)
|
||||
output_float->erase(output_float->begin() + 4, output_float->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
m_options[option.m_option_name] = option;
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::LoadOptionsConfiguration()
|
||||
{
|
||||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
std::string section = m_current_shader + "-options";
|
||||
|
||||
for (auto& it : m_options)
|
||||
{
|
||||
switch (it.second.m_type)
|
||||
{
|
||||
case ConfigurationOption::OptionType::OPTION_BOOL:
|
||||
ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &it.second.m_bool_value, it.second.m_bool_value);
|
||||
break;
|
||||
case ConfigurationOption::OptionType::OPTION_INTEGER:
|
||||
{
|
||||
std::string value;
|
||||
ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &value);
|
||||
if (value != "")
|
||||
TryParseVector(value, &it.second.m_integer_values);
|
||||
}
|
||||
break;
|
||||
case ConfigurationOption::OptionType::OPTION_FLOAT:
|
||||
{
|
||||
std::string value;
|
||||
ini.GetOrCreateSection(section)->Get(it.second.m_option_name, &value);
|
||||
if (value != "")
|
||||
TryParseVector(value, &it.second.m_float_values);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::SaveOptionsConfiguration()
|
||||
{
|
||||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
std::string section = m_current_shader + "-options";
|
||||
|
||||
for (auto& it : m_options)
|
||||
{
|
||||
switch (it.second.m_type)
|
||||
{
|
||||
case ConfigurationOption::OptionType::OPTION_BOOL:
|
||||
{
|
||||
ini.GetOrCreateSection(section)->Set(it.second.m_option_name, it.second.m_bool_value);
|
||||
}
|
||||
break;
|
||||
case ConfigurationOption::OptionType::OPTION_INTEGER:
|
||||
{
|
||||
std::string value = "";
|
||||
for (size_t i = 0; i < it.second.m_integer_values.size(); ++i)
|
||||
value += StringFromFormat("%d%s", it.second.m_integer_values[i], i == (it.second.m_integer_values.size() - 1) ? "": ", ");
|
||||
ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value);
|
||||
}
|
||||
break;
|
||||
case ConfigurationOption::OptionType::OPTION_FLOAT:
|
||||
{
|
||||
std::string value = "";
|
||||
for (size_t i = 0; i < it.second.m_float_values.size(); ++i)
|
||||
value += StringFromFormat("%f%s", it.second.m_float_values[i], i == (it.second.m_float_values.size() - 1) ? "": ", ");
|
||||
ini.GetOrCreateSection(section)->Set(it.second.m_option_name, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::ReloadShader()
|
||||
{
|
||||
m_current_shader = "";
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::SetOptionf(std::string option, int index, float value)
|
||||
{
|
||||
auto it = m_options.find(option);
|
||||
|
||||
it->second.m_float_values[index] = value;
|
||||
it->second.m_dirty = true;
|
||||
m_any_options_dirty = true;
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::SetOptioni(std::string option, int index, s32 value)
|
||||
{
|
||||
auto it = m_options.find(option);
|
||||
|
||||
it->second.m_integer_values[index] = value;
|
||||
it->second.m_dirty = true;
|
||||
m_any_options_dirty = true;
|
||||
}
|
||||
|
||||
void PostProcessingShaderConfiguration::SetOptionb(std::string option, bool value)
|
||||
{
|
||||
auto it = m_options.find(option);
|
||||
|
||||
it->second.m_bool_value = value;
|
||||
it->second.m_dirty = true;
|
||||
m_any_options_dirty = true;
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
class PostProcessingShaderConfiguration
|
||||
{
|
||||
public:
|
||||
struct ConfigurationOption
|
||||
{
|
||||
enum OptionType
|
||||
{
|
||||
OPTION_BOOL = 0,
|
||||
OPTION_FLOAT,
|
||||
OPTION_INTEGER,
|
||||
};
|
||||
|
||||
bool m_bool_value;
|
||||
|
||||
std::vector<float> m_float_values;
|
||||
std::vector<s32> m_integer_values;
|
||||
|
||||
std::vector<float> m_float_min_values;
|
||||
std::vector<s32> m_integer_min_values;
|
||||
|
||||
std::vector<float> m_float_max_values;
|
||||
std::vector<s32> m_integer_max_values;
|
||||
|
||||
std::vector<float> m_float_step_values;
|
||||
std::vector<s32> m_integer_step_values;
|
||||
|
||||
OptionType m_type;
|
||||
|
||||
std::string m_gui_name;
|
||||
std::string m_option_name;
|
||||
std::string m_dependent_option;
|
||||
bool m_dirty;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, ConfigurationOption> ConfigMap;
|
||||
|
||||
PostProcessingShaderConfiguration() : m_current_shader("") {}
|
||||
virtual ~PostProcessingShaderConfiguration() {}
|
||||
|
||||
// Loads the configuration with a shader
|
||||
// If the argument is "" the class will load the shader from the g_activeConfig option.
|
||||
// Returns the loaded shader source from file
|
||||
std::string LoadShader(std::string shader = "");
|
||||
void SaveOptionsConfiguration();
|
||||
void ReloadShader();
|
||||
std::string GetShader() { return m_current_shader; }
|
||||
|
||||
bool IsDirty() { return m_any_options_dirty; }
|
||||
void SetDirty(bool dirty) { m_any_options_dirty = dirty; }
|
||||
|
||||
bool HasOptions() { return m_options.size() > 0; }
|
||||
ConfigMap& GetOptions() { return m_options; }
|
||||
const ConfigurationOption& GetOption(const std::string& option) { return m_options[option]; }
|
||||
|
||||
// For updating option's values
|
||||
void SetOptionf(std::string option, int index, float value);
|
||||
void SetOptioni(std::string option, int index, s32 value);
|
||||
void SetOptionb(std::string option, bool value);
|
||||
|
||||
private:
|
||||
bool m_any_options_dirty;
|
||||
std::string m_current_shader;
|
||||
ConfigMap m_options;
|
||||
|
||||
void LoadOptions(const std::string& code);
|
||||
void LoadOptionsConfiguration();
|
||||
};
|
||||
|
||||
class PostProcessingShaderImplementation
|
||||
{
|
||||
public:
|
||||
PostProcessingShaderImplementation();
|
||||
virtual ~PostProcessingShaderImplementation();
|
||||
|
||||
PostProcessingShaderConfiguration* GetConfig() { return &m_config; }
|
||||
|
||||
// Should be implemented by the backends for backend specific code
|
||||
virtual void BindTargetFramebuffer() = 0;
|
||||
virtual void BlitToScreen() = 0;
|
||||
virtual void Update(u32 width, u32 height) = 0;
|
||||
virtual void ApplyShader() = 0;
|
||||
|
||||
protected:
|
||||
bool m_enable;
|
||||
u32 m_width;
|
||||
u32 m_height;
|
||||
// Timer for determining our time value
|
||||
Common::Timer m_timer;
|
||||
|
||||
PostProcessingShaderConfiguration m_config;
|
||||
};
|
|
@ -59,6 +59,8 @@ int Renderer::s_target_height;
|
|||
int Renderer::s_backbuffer_width;
|
||||
int Renderer::s_backbuffer_height;
|
||||
|
||||
PostProcessingShaderImplementation* Renderer::m_post_processor;
|
||||
|
||||
TargetRectangle Renderer::target_rc;
|
||||
|
||||
int Renderer::s_LastEFBScale;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "VideoCommon/NativeVertexFormat.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
class PostProcessingShaderImplementation;
|
||||
|
||||
// TODO: Move these out of here.
|
||||
extern int frameCount;
|
||||
extern int OSDChoice;
|
||||
|
@ -115,6 +117,8 @@ public:
|
|||
static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; }
|
||||
static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; }
|
||||
|
||||
PostProcessingShaderImplementation* GetPostProcessor() { return m_post_processor; }
|
||||
|
||||
protected:
|
||||
|
||||
static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
|
||||
|
@ -153,6 +157,8 @@ protected:
|
|||
|
||||
FPSCounter m_fps_counter;
|
||||
|
||||
static PostProcessingShaderImplementation* m_post_processor;
|
||||
|
||||
private:
|
||||
static PEControl::PixelFormat prev_efb_format;
|
||||
static unsigned int efb_scale_numeratorX;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<ClCompile Include="PixelEngine.cpp" />
|
||||
<ClCompile Include="PixelShaderGen.cpp" />
|
||||
<ClCompile Include="PixelShaderManager.cpp" />
|
||||
<ClCompile Include="PostProcessing.cpp" />
|
||||
<ClCompile Include="RenderBase.cpp" />
|
||||
<ClCompile Include="Statistics.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -105,6 +106,7 @@
|
|||
<ClInclude Include="PixelEngine.h" />
|
||||
<ClInclude Include="PixelShaderGen.h" />
|
||||
<ClInclude Include="PixelShaderManager.h" />
|
||||
<ClInclude Include="PostProcessing.h" />
|
||||
<ClInclude Include="RenderBase.h" />
|
||||
<ClInclude Include="ShaderGenCommon.h" />
|
||||
<ClInclude Include="Statistics.h" />
|
||||
|
@ -148,4 +150,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
<ClCompile Include="OnScreenDisplay.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PostProcessing.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Statistics.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
|
@ -234,6 +237,9 @@
|
|||
<ClInclude Include="OnScreenDisplay.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PostProcessing.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Statistics.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
|
@ -266,4 +272,4 @@
|
|||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue