diff --git a/assets/shader1fragment.txt b/assets/shader1fragment.txt index 523790e..f8d773f 100755 --- a/assets/shader1fragment.txt +++ b/assets/shader1fragment.txt @@ -7,7 +7,7 @@ void main() { vec4 color = texture2D(Texture,texCoord).rgba; - gl_FragColor = vec4(color.rgb, color.a * Transparency); + gl_FragColor = vec4(color.rgb, 1.0); diff --git a/assets/smaa/blend_fragment.txt b/assets/smaa/blend_fragment.txt new file mode 100755 index 0000000..b832128 --- /dev/null +++ b/assets/smaa/blend_fragment.txt @@ -0,0 +1,422 @@ +#version 410 compatibility +#define SMAA_PIXEL_SIZE vec2(1.0 / 512.0, 1.0 / 512.0) + + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + + + + +//----------------------------------------------------------------------------- +// Diagonal Search Functions + +/** + * These functions allows to perform diagonal pattern searches. + */ +float SMAASearchDiag1(sampler2D edgesTex, vec2 texcoord, vec2 dir, float c) { + texcoord += dir * SMAA_PIXEL_SIZE; + vec2 e = vec2(0.0, 0.0); + float i; + for (i = 0.0; i < float(SMAA_MAX_SEARCH_STEPS_DIAG); i++) { + e.rg = textureLod(edgesTex, texcoord, 0.0).rg; + + //SMAA_FLATTEN + if (dot(e, vec2(1.0, 1.0)) < 1.9) break; + + texcoord += dir * SMAA_PIXEL_SIZE; + } + return i + float(e.g > 0.9) * c; +} + +float SMAASearchDiag2(sampler2D edgesTex, vec2 texcoord, vec2 dir, float c) { + texcoord += dir * SMAA_PIXEL_SIZE; + vec2 e = vec2(0.0, 0.0); + float i; + for (i = 0.0; i < float(SMAA_MAX_SEARCH_STEPS_DIAG); i++) { + e.g = textureLod(edgesTex, texcoord, 0.0).g; + e.r = textureLodOffset(edgesTex, texcoord, 0.0, ivec2(1, 0)).r; + + //SMAA_FLATTEN + if (dot(e, vec2(1.0, 1.0)) < 1.9) break; + + texcoord += dir * SMAA_PIXEL_SIZE; + } + return i + float(e.g > 0.9) * c; +} + +/** + * Similar to SMAAArea, this calculates the area corresponding to a certain + * diagonal distance and crossing edges 'e'. + */ +vec2 SMAAAreaDiag(sampler2D areaTex, vec2 dist, vec2 e, float offset) { + vec2 texcoord = float(SMAA_AREATEX_MAX_DISTANCE_DIAG) * e + dist; + + // We do a scale and bias for mapping to texel space: + texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + (0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Diagonal areas are on the second half of the texture: + texcoord.x += 0.5; + + // Move to proper place, according to the subpixel offset: + texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; + + + return textureLod(areaTex, texcoord, 0.0).rg; +} + +/** + * This searches for diagonal patterns and returns the corresponding weights. + */ +vec2 SMAACalculateDiagWeights(sampler2D edgesTex, sampler2D areaTex, vec2 texcoord, vec2 e, ivec4 subsampleIndices) { + vec2 weights = vec2(0.0, 0.0); + + vec2 d; + d.x = e.r > 0.0? SMAASearchDiag1(edgesTex, texcoord, vec2(-1.0, 1.0), 1.0) : 0.0; + d.y = SMAASearchDiag1(edgesTex, texcoord, vec2(1.0, -1.0), 0.0); + + //SMAA_BRANCH + if (d.r + d.g > 2.0) { // d.r + d.g + 1 > 3 + vec4 coords = fma(vec4(-d.r, d.r, d.g, -d.g), SMAA_PIXEL_SIZE.xyxy, texcoord.xyxy); + + vec4 c; + c.x = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2(-1, 0)).g; + c.y = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2( 0, 0)).r; + c.z = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2( 1, 0)).g; + c.w = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2( 1, -1)).r; + vec2 e = 2.0 * c.xz + c.yw; + float t = float(SMAA_MAX_SEARCH_STEPS_DIAG) - 1.0; + e *= step(d.rg, vec2(t, t)); + + weights += SMAAAreaDiag(areaTex, d, e, float(subsampleIndices.z)); + } + + d.x = SMAASearchDiag2(edgesTex, texcoord, vec2(-1.0, -1.0), 0.0); + float right = textureLodOffset(edgesTex, texcoord, 0.0, ivec2(1, 0)).r; + d.y = right > 0.0? SMAASearchDiag2(edgesTex, texcoord, vec2(1.0, 1.0), 1.0) : 0.0; + + //SMAA_BRANCH + if (d.r + d.g > 2.0) { // d.r + d.g + 1 > 3 + vec4 coords = fma(vec4(-d.r, -d.r, d.g, d.g), SMAA_PIXEL_SIZE.xyxy, texcoord.xyxy); + + vec4 c; + c.x = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2(-1, 0)).g; + c.y = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2( 0, -1)).r; + c.zw = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2( 1, 0)).gr; + vec2 e = 2.0 * c.xz + c.yw; + float t = float(SMAA_MAX_SEARCH_STEPS_DIAG) - 1.0; + e *= step(d.rg, vec2(t, t)); + + weights += SMAAAreaDiag(areaTex, d, e, float(subsampleIndices.w)).gr; + } + + return weights; +} + + +//----------------------------------------------------------------------------- +// Horizontal/Vertical Search Functions + +/** + * This allows to determine how much length should we add in the last step + * of the searches. It takes the bilinearly interpolated edge (see + * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and + * crossing edges are active. + */ +float SMAASearchLength(sampler2D searchTex, vec2 e, float bias, float scale) { + // Not required if searchTex accesses are set to point: + // vec2 SEARCH_TEX_PIXEL_SIZE = 1.0 / vec2(66.0, 33.0); + // e = vec2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE + + // e * vec2(scale, 1.0) * vec2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE; + e.r = bias + e.r * scale; + e.g = -e.g; + return 255.0 * textureLod(searchTex, e, 0.0).r; +} + +/** + * Horizontal/vertical search functions for the 2nd pass. + */ +float SMAASearchXLeft(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + /** + * @PSEUDO_GATHER4 + * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to + * sample between edge, thus fetching four edges in a row. + * Sampling with different offsets in each direction allows to disambiguate + * which edges are active from the four fetched ones. + */ + vec2 e = vec2(0.0, 1.0); + while (texcoord.x > end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord -= vec2(2.0, 0.0) * SMAA_PIXEL_SIZE; + } + + // We correct the previous (-0.25, -0.125) offset we applied: + texcoord.x += 0.25 * SMAA_PIXEL_SIZE.x; + + // The searches are bias by 1, so adjust the coords accordingly: + texcoord.x += SMAA_PIXEL_SIZE.x; + + // Disambiguate the length added by the last step: + texcoord.x += 2.0 * SMAA_PIXEL_SIZE.x; // Undo last step + texcoord.x -= SMAA_PIXEL_SIZE.x * SMAASearchLength(searchTex, e, 0.0, 0.5); + + return texcoord.x; +} + +float SMAASearchXRight(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(0.0, 1.0); + while (texcoord.x < end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord += vec2(2.0, 0.0) * SMAA_PIXEL_SIZE; + } + + texcoord.x -= 0.25 * SMAA_PIXEL_SIZE.x; + texcoord.x -= SMAA_PIXEL_SIZE.x; + texcoord.x -= 2.0 * SMAA_PIXEL_SIZE.x; + texcoord.x += SMAA_PIXEL_SIZE.x * SMAASearchLength(searchTex, e, 0.5, 0.5); + return texcoord.x; +} + +float SMAASearchYUp(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(1.0, 0.0); + while (texcoord.y > end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord -= vec2(0.0, 2.0) * SMAA_PIXEL_SIZE; + } + + texcoord.y += 0.25 * SMAA_PIXEL_SIZE.y; + texcoord.y += SMAA_PIXEL_SIZE.y; + texcoord.y += 2.0 * SMAA_PIXEL_SIZE.y; + texcoord.y -= SMAA_PIXEL_SIZE.y * SMAASearchLength(searchTex, e.gr, 0.0, 0.5); + return texcoord.y; +} + +float SMAASearchYDown(sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end) { + vec2 e = vec2(1.0, 0.0); + while (texcoord.y < end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = textureLod(edgesTex, texcoord, 0.0).rg; + texcoord += vec2(0.0, 2.0) * SMAA_PIXEL_SIZE; + } + + texcoord.y -= 0.25 * SMAA_PIXEL_SIZE.y; + texcoord.y -= SMAA_PIXEL_SIZE.y; + texcoord.y -= 2.0 * SMAA_PIXEL_SIZE.y; + texcoord.y += SMAA_PIXEL_SIZE.y * SMAASearchLength(searchTex, e.gr, 0.5, 0.5); + return texcoord.y; +} + +/** + * Ok, we have the distance and both crossing edges. So, what are the areas + * at each side of current edge? + */ +vec2 SMAAArea(sampler2D areaTex, vec2 dist, float e1, float e2, float offset) { + // Rounding prevents precision errors of bilinear filtering: + vec2 texcoord = float(SMAA_AREATEX_MAX_DISTANCE) * round(4.0 * vec2(e1, e2)) + dist; + + // We do a scale and bias for mapping to texel space: + texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + (0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Move to proper place, according to the subpixel offset: + texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; + + + return textureLod(areaTex, texcoord, 0.0).rg; + +} + +//----------------------------------------------------------------------------- +// Corner Detection Functions + +void SMAADetectHorizontalCornerPattern(sampler2D edgesTex, inout vec2 weights, vec2 texcoord, vec2 d) { + #if SMAA_CORNER_ROUNDING < 100 || SMAA_FORCE_CORNER_DETECTION == 1 + vec4 coords = fma(vec4(d.x, 0.0, d.y, 0.0), + SMAA_PIXEL_SIZE.xyxy, texcoord.xyxy); + vec2 e; + e.r = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2(0.0, 1.0)).r; + bool left = abs(d.x) < abs(d.y); + e.g = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2(0.0, -2.0)).r; + if (left) weights *= clamp(float(SMAA_CORNER_ROUNDING) / 100.0 + 1.0 - e, 0.0, 1.0); + + e.r = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2(1.0, 1.0)).r; + e.g = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2(1.0, -2.0)).r; + if (!left) weights *= clamp(float(SMAA_CORNER_ROUNDING) / 100.0 + 1.0 - e, 0.0, 1.0); + #endif +} + +void SMAADetectVerticalCornerPattern(sampler2D edgesTex, inout vec2 weights, vec2 texcoord, vec2 d) { + #if SMAA_CORNER_ROUNDING < 100 || SMAA_FORCE_CORNER_DETECTION == 1 + vec4 coords = fma(vec4(0.0, d.x, 0.0, d.y), + SMAA_PIXEL_SIZE.xyxy, texcoord.xyxy); + vec2 e; + e.r = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2( 1.0, 0.0)).g; + bool left = abs(d.x) < abs(d.y); + e.g = textureLodOffset(edgesTex, coords.xy, 0.0, ivec2(-2.0, 0.0)).g; + if (left) weights *= clamp(float(SMAA_CORNER_ROUNDING) / 100.0 + 1.0 - e, 0.0, 1.0); + + e.r = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2( 1.0, 1.0)).g; + e.g = textureLodOffset(edgesTex, coords.zw, 0.0, ivec2(-2.0, 1.0)).g; + if (!left) weights *= clamp(float(SMAA_CORNER_ROUNDING) / 100.0 + 1.0 - e, 0.0, 1.0); + #endif +} + +//----------------------------------------------------------------------------- +// Blending Weight Calculation Pixel Shader (Second Pass) + +vec4 SMAABlendingWeightCalculationPS(vec2 texcoord, + vec2 pixcoord, + vec4 offset[3], + sampler2D edgesTex, + sampler2D areaTex, + sampler2D searchTex, + ivec4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. + vec4 weights = vec4(0.0, 0.0, 0.0, 0.0); + + vec2 e = texture(edgesTex, texcoord).rg; + + //SMAA_BRANCH + if (e.g > 0.0) { // Edge at north + #if SMAA_MAX_SEARCH_STEPS_DIAG > 0 || SMAA_FORCE_DIAGONAL_DETECTION == 1 + // Diagonals have both north and west edges, so searching for them in + // one of the boundaries is enough. + weights.rg = SMAACalculateDiagWeights(edgesTex, areaTex, texcoord, e, subsampleIndices); + + // We give priority to diagonals, so if we find a diagonal we skip + // horizontal/vertical processing. + //SMAA_BRANCH + if (dot(weights.rg, vec2(1.0, 1.0)) == 0.0) { + #endif + + vec2 d; + + // Find the distance to the left: + vec2 coords; + coords.x = SMAASearchXLeft(edgesTex, searchTex, offset[0].xy, offset[2].x); + coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_PIXEL_SIZE.y (@CROSSING_OFFSET) + d.x = coords.x; + + // Now fetch the left crossing edges, two at a time using bilinear + // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to + // discern what value each edge has: + float e1 = textureLod(edgesTex, coords, 0.0).r; + + // Find the distance to the right: + coords.x = SMAASearchXRight(edgesTex, searchTex, offset[0].zw, offset[2].y); + d.y = coords.x; + + // We want the distances to be in pixel units (doing this here allow to + // better interleave arithmetic and memory accesses): + d = d / SMAA_PIXEL_SIZE.x - pixcoord.x; + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + vec2 sqrt_d = sqrt(abs(d)); + + // Fetch the right crossing edges: + float e2 = textureLodOffset(edgesTex, coords, 0.0, ivec2(1, 0)).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + weights.rg = SMAAArea(areaTex, sqrt_d, e1, e2, float(subsampleIndices.y)); + + // Fix corners: + SMAADetectHorizontalCornerPattern(edgesTex, weights.rg, texcoord, d); + + #if SMAA_MAX_SEARCH_STEPS_DIAG > 0 || SMAA_FORCE_DIAGONAL_DETECTION == 1 + } else + e.r = 0.0; // Skip vertical processing. + #endif + } + + //SMAA_BRANCH + if (e.r > 0.0) { // Edge at west + vec2 d; + + // Find the distance to the top: + vec2 coords; + coords.y = SMAASearchYUp(edgesTex, searchTex, offset[1].xy, offset[2].z); + coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_PIXEL_SIZE.x; + d.x = coords.y; + + // Fetch the top crossing edges: + float e1 = textureLod(edgesTex, coords, 0.0).g; + + // Find the distance to the bottom: + coords.y = SMAASearchYDown(edgesTex, searchTex, offset[1].zw, offset[2].w); + d.y = coords.y; + + // We want the distances to be in pixel units: + d = d / SMAA_PIXEL_SIZE.y - pixcoord.y; + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + vec2 sqrt_d = sqrt(abs(d)); + + // Fetch the bottom crossing edges: + float e2 = textureLodOffset(edgesTex, coords, 0.0, ivec2(0, 1)).g; + + // Get the area for this direction: + weights.ba = SMAAArea(areaTex, sqrt_d, e1, e2, float(subsampleIndices.x)); + + // Fix corners: + SMAADetectVerticalCornerPattern(edgesTex, weights.ba, texcoord, d); + + //return vec4(weights.ba, 0.0, 1.0); + } + + return weights; + + +} + + + +/* ------------- Header is over -------------- */ + + +uniform sampler2D edge_tex; +uniform sampler2D area_tex; +uniform sampler2D search_tex; +in vec2 texcoord; +in vec2 pixcoord; +in vec4 offset[3]; +in vec4 dummy2; +void main() +{ + gl_FragColor = SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, edge_tex, area_tex, search_tex, ivec4(0)); + +} \ No newline at end of file diff --git a/assets/smaa/blend_vertex.txt b/assets/smaa/blend_vertex.txt new file mode 100755 index 0000000..7746603 --- /dev/null +++ b/assets/smaa/blend_vertex.txt @@ -0,0 +1,74 @@ +#version 410 compatibility +#define SMAA_PIXEL_SIZE vec2(1.0 / 512.0, 1.0 / 512.0) + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + +/** + * Blend Weight Calculation Vertex Shader + */ +void SMAABlendingWeightCalculationVS(vec4 position, + out vec4 svPosition, + inout vec2 texcoord, + out vec2 pixcoord, + out vec4 offset[3]) { + svPosition = position; + + pixcoord = texcoord / SMAA_PIXEL_SIZE; + + // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): + offset[0] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4(-0.25, -0.125, 1.25, -0.125); + offset[1] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4(-0.125, -0.25, -0.125, 1.25); + + // And these for the searches, they indicate the ends of the loops: + offset[2] = vec4(offset[0].xz, offset[1].yw) + + vec4(-2.0, 2.0, -2.0, 2.0) * + SMAA_PIXEL_SIZE.xxyy * float(SMAA_MAX_SEARCH_STEPS); +} + +/* ------------- Header is over -------------- */ + +out vec2 texcoord; +out vec2 pixcoord; +out vec4 offset[3]; +out vec4 dummy2; + +attribute vec3 vPosition; +attribute vec2 vTexCoord; +uniform mat4 ProjectionMatrix; + + +void main() +{ + texcoord = vTexCoord; + vec4 dummy1 = vec4(0); + SMAABlendingWeightCalculationVS(dummy1, dummy2, texcoord, pixcoord, offset); + gl_Position = ProjectionMatrix * vec4(vPosition.xyz, 1.0); +} diff --git a/assets/smaa/edge_fragment.txt b/assets/smaa/edge_fragment.txt new file mode 100755 index 0000000..3d2de9a --- /dev/null +++ b/assets/smaa/edge_fragment.txt @@ -0,0 +1,105 @@ +#version 410 compatibility + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + +/** + * Color Edge Detection + * + * IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +vec4 SMAAColorEdgeDetectionPS(vec2 texcoord, + vec4 offset[3], + sampler2D colorTex + ) { + vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD); + + // Calculate color deltas: + vec4 delta; + vec3 C = texture(colorTex, texcoord).rgb; + + vec3 Cleft = texture(colorTex, offset[0].xy).rgb; + vec3 t = abs(C - Cleft); + delta.x = max(max(t.r, t.g), t.b); + + vec3 Ctop = texture(colorTex, offset[0].zw).rgb; + t = abs(C - Ctop); + delta.y = max(max(t.r, t.g), t.b); + + // We do the usual threshold: + vec2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, vec2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + vec3 Cright = texture(colorTex, offset[1].xy).rgb; + t = abs(C - Cright); + delta.z = max(max(t.r, t.g), t.b); + + vec3 Cbottom = texture(colorTex, offset[1].zw).rgb; + t = abs(C - Cbottom); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the maximum delta in the direct neighborhood: + float maxDelta = max(max(max(delta.x, delta.y), delta.z), delta.w); + + // Calculate left-left and top-top deltas: + vec3 Cleftleft = texture(colorTex, offset[2].xy).rgb; + t = abs(C - Cleftleft); + delta.z = max(max(t.r, t.g), t.b); + + vec3 Ctoptop = texture(colorTex, offset[2].zw).rgb; + t = abs(C - Ctoptop); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the final maximum delta: + maxDelta = max(max(maxDelta, delta.z), delta.w); + + // Local contrast adaptation in action: + edges.xy *= step(0.5 * maxDelta, delta.xy); + + return vec4(edges, 0.0, 0.0); + +} + + +/* ------------- Header is over -------------- */ + +uniform sampler2D albedo_tex; +in vec2 texcoord; +in vec4 offset[3]; +in vec4 dummy2; +void main() +{ + gl_FragColor = SMAAColorEdgeDetectionPS(texcoord, offset, albedo_tex); +} \ No newline at end of file diff --git a/assets/smaa/edge_vertex.txt b/assets/smaa/edge_vertex.txt new file mode 100755 index 0000000..f7edf16 --- /dev/null +++ b/assets/smaa/edge_vertex.txt @@ -0,0 +1,67 @@ +#version 410 compatibility +#define SMAA_PIXEL_SIZE vec2(1.0/512.0, 1.0/512.0) + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + +/** + * Edge Detection Vertex Shader + */ +void SMAAEdgeDetectionVS(vec4 position, + out vec4 svPosition, + inout vec2 texcoord, + out vec4 offset[3]) { + svPosition = position; + + offset[0] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, -1.0); + offset[1] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, 1.0); + offset[2] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4(-2.0, 0.0, 0.0, -2.0); +} + +/* ------------- Header is over -------------- */ + +out vec2 texcoord; +out vec4 offset[3]; +out vec4 dummy2; + + + +attribute vec3 vPosition; +attribute vec2 vTexCoord; +uniform mat4 ProjectionMatrix; + + +void main() +{ + texcoord = vTexCoord; + vec4 dummy1 = vec4(0); + SMAAEdgeDetectionVS(dummy1, dummy2, texcoord, offset); + gl_Position = ProjectionMatrix * vec4(vPosition.xyz, 1.0); +} \ No newline at end of file diff --git a/assets/smaa/neighborhood_fragment.txt b/assets/smaa/neighborhood_fragment.txt new file mode 100755 index 0000000..32470b0 --- /dev/null +++ b/assets/smaa/neighborhood_fragment.txt @@ -0,0 +1,102 @@ +#version 410 compatibility +#define SMAA_PIXEL_SIZE vec2(1.0 / 512.0, 1.0 / 512.0) + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + +vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, + vec4 offset[2], + sampler2D colorTex, + sampler2D blendTex) { + // Fetch the blending weights for current pixel: + vec4 a; + a.xz = texture(blendTex, texcoord).xz; + a.y = texture(blendTex, offset[1].zw).g; + a.w = texture(blendTex, offset[1].xy).a; + + // Is there any blending weight with a value greater than 0.0? + //SMAA_BRANCH + if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) + return textureLod(colorTex, texcoord, 0.0); + else { + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); + + // Up to 4 lines can be crossing a pixel (one through each edge). We + // favor blending by choosing the line with the maximum weight for each + // direction: + vec2 offset; + offset.x = a.a > a.b? a.a : -a.b; // left vs. right + offset.y = a.g > a.r? a.g : -a.r; // top vs. bottom + + // Then we go in the direction that has the maximum weight: + if (abs(offset.x) > abs(offset.y)) // horizontal vs. vertical + offset.y = 0.0; + else + offset.x = 0.0; + + #if SMAA_REPROJECTION == 1 + // Fetch the opposite color and lerp by hand: + vec4 C = textureLod(colorTex, texcoord, 0.0); + texcoord += sign(offset) * SMAA_PIXEL_SIZE; + vec4 Cop = textureLod(colorTex, texcoord, 0.0); + float s = abs(offset.x) > abs(offset.y)? abs(offset.x) : abs(offset.y); + + // Unpack the velocity values: + C.a *= C.a; + Cop.a *= Cop.a; + + // Lerp the colors: + vec4 Caa = mix(C, Cop, s); + + // Unpack velocity and return the resulting value: + Caa.a = sqrt(Caa.a); + return Caa; + #else + // Fetch the opposite color and lerp by hand: + vec4 C = textureLod(colorTex, texcoord, 0.0); + texcoord += sign(offset) * SMAA_PIXEL_SIZE; + vec4 Cop = textureLod(colorTex, texcoord, 0.0); + float s = abs(offset.x) > abs(offset.y)? abs(offset.x) : abs(offset.y); + return mix(C, Cop, s); + #endif + } +} + +/* ------------- Header is over -------------- */ + +uniform sampler2D albedo_tex; +uniform sampler2D blend_tex; +in vec2 texcoord; +in vec4 offset[2]; +in vec4 dummy2; +void main() +{ + gl_FragColor = SMAANeighborhoodBlendingPS(texcoord, offset, albedo_tex, blend_tex); +} \ No newline at end of file diff --git a/assets/smaa/neighborhood_vertex.txt b/assets/smaa/neighborhood_vertex.txt new file mode 100755 index 0000000..7df526e --- /dev/null +++ b/assets/smaa/neighborhood_vertex.txt @@ -0,0 +1,65 @@ +#version 410 compatibility +#define SMAA_PIXEL_SIZE vec2(1.0 / 512.0, 1.0 / 512.0) + +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 + + +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + + +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 + + +#ifndef SMAA_AREATEX_MAX_DISTANCE +#define SMAA_AREATEX_MAX_DISTANCE 16 +#endif +#ifndef SMAA_AREATEX_MAX_DISTANCE_DIAG +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#endif +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) + + +/* --- Define section is over ---- */ + +/** + * Neighborhood Blending Vertex Shader + */ +void SMAANeighborhoodBlendingVS(vec4 position, + out vec4 svPosition, + inout vec2 texcoord, + out vec4 offset[2]) { + svPosition = position; + + offset[0] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, -1.0); + offset[1] = texcoord.xyxy + SMAA_PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, 1.0); +} + +/* ------------- Header is over -------------- */ + + +out vec2 texcoord; +out vec4 offset[2]; +out vec4 dummy2; + +attribute vec3 vPosition; +attribute vec2 vTexCoord; +uniform mat4 ProjectionMatrix; + + +void main() +{ + texcoord = vTexCoord; + vec4 dummy1 = vec4(0); + SMAANeighborhoodBlendingVS(dummy1, dummy2, texcoord, offset); + gl_Position = ProjectionMatrix * vec4(vPosition.xyz, 1.0); +} \ No newline at end of file diff --git a/assets/smaa/smaa_area.raw b/assets/smaa/smaa_area.raw new file mode 100755 index 0000000..f5e8575 Binary files /dev/null and b/assets/smaa/smaa_area.raw differ diff --git a/assets/smaa/smaa_search.raw b/assets/smaa/smaa_search.raw new file mode 100755 index 0000000..714baa9 Binary files /dev/null and b/assets/smaa/smaa_search.raw differ diff --git a/game/main_code.cpp b/game/main_code.cpp index 3b10050..e01258a 100644 --- a/game/main_code.cpp +++ b/game/main_code.cpp @@ -12,6 +12,16 @@ TMyApplication* Application; +#define AREATEX_WIDTH 160 +#define AREATEX_HEIGHT 560 +#define SEARCHTEX_WIDTH 66 +#define SEARCHTEX_HEIGHT 33 + + +GLuint area_tex; +GLuint search_tex; + + void TMyApplication::InnerInit() { @@ -38,13 +48,20 @@ void TMyApplication::InnerInit() ResourceManager->ShaderManager.AddShader("DefaultShader", "shader1vertex.txt", "shader1fragment.txt"); ResourceManager->ShaderManager.AddShader("FrameShader", "frameshader_vertex.txt", "frameshader_fragment.txt"); ResourceManager->ShaderManager.AddShader("ColorShader", "color_vertex.txt", "color_fragment.txt"); - ResourceManager->ShaderManager.AddShader("SSAA_4X", "SSAA_4X.vertex", "SSAA_4X.frag"); + + + ResourceManager->ShaderManager.AddShader("SmaaEdge", "smaa/edge_vertex.txt", "smaa/edge_fragment.txt"); + ResourceManager->ShaderManager.AddShader("SmaaBlend", "smaa/blend_vertex.txt", "smaa/blend_fragment.txt"); + ResourceManager->ShaderManager.AddShader("SmaaNeighborhood", "smaa/neighborhood_vertex.txt", "smaa/neighborhood_fragment.txt"); + Renderer->PushShader("DefaultShader"); ResourceManager->TexList.AddTexture("console_bkg.bmp"); - ResourceManager->FrameManager.AddFrameRenderBuffer("LevelBuffer", 512, 512); - + ResourceManager->FrameManager.AddFrameRenderBuffer("AlbedoBuffer", 512, 512); + ResourceManager->FrameManager.AddFrameRenderBuffer("EdgeBuffer", 512, 512); + ResourceManager->FrameManager.AddFrameRenderBuffer("BlendBuffer", 512, 512); + pair.second.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(Vector3f(0, 0, 0)); pair.second.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(Vector3f(0, 512, 0)); pair.second.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(Vector3f(512, 512, 0)); @@ -53,13 +70,24 @@ void TMyApplication::InnerInit() pair.second.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(Vector3f(512, 0, 0)); + //Choose colored or black and white -- Vladislav Khorev vladislav.khorev@fishrungames.com +#if 1 pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(1, 0, 0, 1)); pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(1, 0, 0, 1)); pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 1, 0, 1)); pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 0, 1, 1)); pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 0, 1, 1)); pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 1, 0, 1)); +#else + + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(1, 1, 1, 1)); + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(1, 1, 1, 1)); + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(1, 1, 1, 1)); + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 0, 0, 1)); + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 0, 0, 1)); + pair.second.Data.Vec4CoordArr[CONST_STRING_COLOR_ATTRIB].push_back(Vector4f(0, 0, 0, 1)); +#endif pair.first.ShaderName = "ColorShader"; pair.second.RefreshBuffer(); @@ -87,11 +115,64 @@ void TMyApplication::InnerInit() Renderer->SetOrthoProjection(); Renderer->SetFullScreenViewport(); + + glDisable(GL_BLEND); //Don't forget to disable blending or whole thing will not work!!! -- Vladislav Khorev vladislav.khorev@fishrungames.com Inited = true; + + //This is stuff from original https://github.com/scrawl/smaa-opengl + //We must have these textures to be used for pattern matching or something -- Vladislav Khorev vladislav.khorev@fishrungames.com + + unsigned char* buffer = 0; + FILE* f = 0; + + buffer = new unsigned char[1024 * 1024]; + f = fopen((ST::PathToResources + "smaa/smaa_area.raw").c_str(), "rb"); //rb stands for "read binary file" + + if (!f) + { + std::cerr << "Couldn't open smaa_area.raw.\n"; + } + + fread(buffer, AREATEX_WIDTH * AREATEX_HEIGHT * 2, 1, f); + fclose(f); + + f = 0; + + glGenTextures(1, &area_tex); + glBindTexture(GL_TEXTURE_2D, area_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, (GLsizei)AREATEX_WIDTH, (GLsizei)AREATEX_HEIGHT, 0, GL_RG, GL_UNSIGNED_BYTE, buffer); + + f = fopen((ST::PathToResources + "smaa/smaa_search.raw").c_str(), "rb"); + + if (!f) + { + std::cerr << "Couldn't open smaa_search.raw.\n"; + } + + fread(buffer, SEARCHTEX_WIDTH * SEARCHTEX_HEIGHT, 1, f); + fclose(f); + + f = 0; + + glGenTextures(1, &search_tex); + glBindTexture(GL_TEXTURE_2D, search_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, (GLsizei)SEARCHTEX_WIDTH, (GLsizei)SEARCHTEX_HEIGHT, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); + + delete[] buffer; + + } void TMyApplication::InnerDeinit() @@ -103,6 +184,9 @@ void TMyApplication::InnerDeinit() *Console<<"APP DEINIT\n"; } + glDeleteTextures(1, &search_tex); + glDeleteTextures(1, &area_tex); + } void TMyApplication::InnerOnTapDown(Vector2f p) @@ -133,14 +217,17 @@ void TMyApplication::OnFling(Vector2f v) void TMyApplication::InnerDraw() { - Renderer->SwitchToFrameBuffer("LevelBuffer"); + //Render the frame + Renderer->SwitchToFrameBuffer("AlbedoBuffer"); Renderer->SetProjectionMatrix(512.f, 512.f); - glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); CheckGlError(""); { + //Render here all objects that you want to have -- Vladislav Khorev vladislav.khorev@fishrungames.com TRenderParamsSetter params(pair.first); Renderer->DrawTriangleList(pair.second); } @@ -148,47 +235,104 @@ void TMyApplication::InnerDraw() CheckGlError(""); - Renderer->SwitchToScreen(); - Renderer->SetFullScreenViewport(); + //------------------------- + //First pass - edge detection + + Renderer->PushShader("SmaaEdge"); - const float cos30 = sqrt(3) / 2; - const float sin30 = 0.5f; - const float sampleRadiusX = 0.75 / 512; - const float sampleRadiusY = 0.75 / 512; + Renderer->SwitchToFrameBuffer("EdgeBuffer"); + Renderer->SetProjectionMatrix(512.f, 512.f); - Matrix2f rotate30Matrix; - rotate30Matrix(0, 0) = cos30; - rotate30Matrix(0, 1) = sin30; - rotate30Matrix(1, 0) = -sin30; - rotate30Matrix(1, 1) = cos30; + RenderUniform1i("albedo_tex", 0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("AlbedoBuffer")); - Renderer->PushShader("SSAA_4X"); - - - std::array sampleVector = { - Vector2f(sampleRadiusX, sampleRadiusY), - Vector2f(-sampleRadiusX, sampleRadiusY), - Vector2f(-sampleRadiusX, -sampleRadiusY), - Vector2f(sampleRadiusX, -sampleRadiusY) - }; - - for (size_t i = 0; i < 4; i++) - { - sampleVector[i] = rotate30Matrix * sampleVector[i]; - - RenderUniform2fv("samplesOffset[" + boost::lexical_cast(i) + "]", &sampleVector[i][0]); - } - - - glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("LevelBuffer")); Renderer->DrawTriangleList(rect.second); Renderer->PopShader(); CheckGlError(""); + + //------------------------- + //Second pass - blend plus pattern matching + + Renderer->PushShader("SmaaBlend"); + + Renderer->SwitchToFrameBuffer("BlendBuffer"); + Renderer->SetProjectionMatrix(512.f, 512.f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + RenderUniform1i("edge_tex", 0); + RenderUniform1i("area_tex", 1); + RenderUniform1i("search_tex", 2); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("EdgeBuffer")); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, area_tex); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, search_tex); + + Renderer->DrawTriangleList(rect.second); + + Renderer->PopShader(); + + CheckGlError(""); + +#if 1 + //------------------------- + //Last pass - neightborhood + + Renderer->PushShader("SmaaNeighborhood"); + + Renderer->SwitchToScreen(); + Renderer->SetFullScreenViewport(); + Renderer->SetProjectionMatrix(512.f, 512.f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + RenderUniform1i("albedo_tex", 0); + RenderUniform1i("blend_tex", 1); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("BlendBuffer")); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("AlbedoBuffer")); + Renderer->DrawTriangleList(rect.second); + + Renderer->PopShader(); + + CheckGlError(""); +#else + + + //... or just render intermediate buffers to see what is going on + Renderer->PushShader("DefaultShader"); + Renderer->SwitchToScreen(); + Renderer->SetFullScreenViewport(); + Renderer->SetProjectionMatrix(512.f, 512.f); + + + glActiveTexture(GL_TEXTURE0); + + //Choose any to render for debug: + //glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("AlbedoBuffer")); + //glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("EdgeBuffer")); + glBindTexture(GL_TEXTURE_2D, ResourceManager->FrameManager.GetFrameTexture("BlendBuffer")); + + Renderer->DrawTriangleList(rect.second); + + Renderer->PopShader(); + + CheckGlError(""); +#endif + }