File base/glsl/fxaa.frag deleted (index e2d4891..0000000) |
1 |
|
uniform sampler2D u_texture; |
|
2 |
|
in vec2 v_UV; |
|
3 |
|
out vec4 fragColor; |
|
4 |
|
|
|
5 |
|
const float FXAA_SUBPIX_SHIFT = 1.0 / 4.0; |
|
6 |
|
const float FXAA_REDUCE_MIN = 1.0 / 128.0; |
|
7 |
|
const float FXAA_SPAN_MAX = 8.0; |
|
8 |
|
const float FXAA_REDUCE_MUL = 1.0 / 8.0; |
|
9 |
|
|
|
10 |
|
void main(){ |
|
11 |
|
vec2 rcpFrame = v_UV / gl_FragCoord.xy; |
|
12 |
|
vec2 tc = v_UV - rcpFrame * ( 0.5 + FXAA_SUBPIX_SHIFT ); |
|
13 |
|
vec3 rgbNW = textureLod(u_texture, tc, 0.0).xyz; |
|
14 |
|
vec3 rgbNE = textureLodOffset(u_texture, tc, 0.0, ivec2(1,0)).xyz; |
|
15 |
|
vec3 rgbSW = textureLodOffset(u_texture, tc, 0.0, ivec2(0,1)).xyz; |
|
16 |
|
vec3 rgbSE = textureLodOffset(u_texture, tc, 0.0, ivec2(1,1)).xyz; |
|
17 |
|
vec3 rgbM = textureLod(u_texture, v_UV, 0.0).xyz; |
|
18 |
|
|
|
19 |
|
vec3 luma = vec3(0.2126729, 0.7151522, 0.072175); // Linear weights. |
|
20 |
|
float lumaNW = dot(rgbNW, luma); |
|
21 |
|
float lumaNE = dot(rgbNE, luma); |
|
22 |
|
float lumaSW = dot(rgbSW, luma); |
|
23 |
|
float lumaSE = dot(rgbSE, luma); |
|
24 |
|
float lumaM = dot(rgbM, luma); |
|
25 |
|
|
|
26 |
|
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); |
|
27 |
|
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); |
|
28 |
|
|
|
29 |
|
vec2 dir = vec2( |
|
30 |
|
-((lumaNW + lumaNE) - (lumaSW + lumaSE)), |
|
31 |
|
((lumaNW + lumaSW) - (lumaNE + lumaSE)) |
|
32 |
|
); |
|
33 |
|
|
|
34 |
|
float dirReduce = max( |
|
35 |
|
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), |
|
36 |
|
FXAA_REDUCE_MIN); |
|
37 |
|
|
|
38 |
|
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); |
|
39 |
|
|
|
40 |
|
dir = min( |
|
41 |
|
vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), |
|
42 |
|
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin) |
|
43 |
|
) * rcpFrame.xy; |
|
44 |
|
|
|
45 |
|
vec3 rgbA = (1.0 / 2.0) * ( |
|
46 |
|
textureLod(u_texture, v_UV + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + |
|
47 |
|
textureLod(u_texture, v_UV + dir * (2.0 / 3.0 - 0.5), 0.0).xyz); |
|
48 |
|
vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * ( |
|
49 |
|
textureLod(u_texture, v_UV + dir * (0.0 / 3.0 - 0.5), 0.0).xyz + |
|
50 |
|
textureLod(u_texture, v_UV + dir * (3.0 / 3.0 - 0.5), 0.0).xyz); |
|
51 |
|
float lumaB = dot(rgbB, luma); |
|
52 |
|
fragColor = vec4((lumaB < lumaMin) || (lumaB > lumaMax) ? rgbA : rgbB, 1.0); |
|
53 |
|
} |
|
File base/glsl/postfx.frag added (mode: 100644) (index 0000000..d4e95df) |
|
1 |
|
uniform sampler2D u_texture; |
|
2 |
|
in vec2 v_UV; |
|
3 |
|
out vec4 fragColor; |
|
4 |
|
|
|
5 |
|
// Perform antialiasing step? |
|
6 |
|
uniform int u_AA; |
|
7 |
|
|
|
8 |
|
// RGB control points. |
|
9 |
|
uniform vec3 u_shadow; |
|
10 |
|
uniform vec3 u_midtone; |
|
11 |
|
uniform vec3 u_highlight; |
|
12 |
|
|
|
13 |
|
const float FXAA_SUBPIX_SHIFT = 1.0 / 4.0; |
|
14 |
|
const float FXAA_REDUCE_MIN = 1.0 / 128.0; |
|
15 |
|
const float FXAA_SPAN_MAX = 8.0; |
|
16 |
|
const float FXAA_REDUCE_MUL = 1.0 / 8.0; |
|
17 |
|
|
|
18 |
|
// Bezier-like tone curve function for a single channel. |
|
19 |
|
float ToneCurve(float x, float a, float b, float c){ |
|
20 |
|
return (1.0 - x) * (1.0 - x) * a + 2.0 * (1.0 - x) * x * b + x * x * c; |
|
21 |
|
} |
|
22 |
|
|
|
23 |
|
void main(){ |
|
24 |
|
vec3 color; |
|
25 |
|
if(u_AA == 0){ |
|
26 |
|
color = textureLod(u_texture, v_UV, 0.0).xyz; |
|
27 |
|
}else{ |
|
28 |
|
vec2 rcpFrame = v_UV / gl_FragCoord.xy; |
|
29 |
|
vec2 tc = v_UV - rcpFrame * ( 0.5 + FXAA_SUBPIX_SHIFT ); |
|
30 |
|
vec3 rgbNW = textureLod(u_texture, tc, 0.0).xyz; |
|
31 |
|
vec3 rgbNE = textureLodOffset(u_texture, tc, 0.0, ivec2(1,0)).xyz; |
|
32 |
|
vec3 rgbSW = textureLodOffset(u_texture, tc, 0.0, ivec2(0,1)).xyz; |
|
33 |
|
vec3 rgbSE = textureLodOffset(u_texture, tc, 0.0, ivec2(1,1)).xyz; |
|
34 |
|
vec3 rgbM = textureLod(u_texture, v_UV, 0.0).xyz; |
|
35 |
|
|
|
36 |
|
vec3 luma = vec3(0.2126729, 0.7151522, 0.072175); // Linear weights. |
|
37 |
|
float lumaNW = dot(rgbNW, luma); |
|
38 |
|
float lumaNE = dot(rgbNE, luma); |
|
39 |
|
float lumaSW = dot(rgbSW, luma); |
|
40 |
|
float lumaSE = dot(rgbSE, luma); |
|
41 |
|
float lumaM = dot(rgbM, luma); |
|
42 |
|
|
|
43 |
|
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); |
|
44 |
|
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); |
|
45 |
|
|
|
46 |
|
vec2 dir = vec2( |
|
47 |
|
-((lumaNW + lumaNE) - (lumaSW + lumaSE)), |
|
48 |
|
((lumaNW + lumaSW) - (lumaNE + lumaSE)) |
|
49 |
|
); |
|
50 |
|
|
|
51 |
|
float dirReduce = max( |
|
52 |
|
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), |
|
53 |
|
FXAA_REDUCE_MIN); |
|
54 |
|
|
|
55 |
|
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); |
|
56 |
|
|
|
57 |
|
dir = min( |
|
58 |
|
vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), |
|
59 |
|
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin) |
|
60 |
|
) * rcpFrame.xy; |
|
61 |
|
|
|
62 |
|
vec3 rgbA = (1.0 / 2.0) * ( |
|
63 |
|
textureLod(u_texture, v_UV + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + |
|
64 |
|
textureLod(u_texture, v_UV + dir * (2.0 / 3.0 - 0.5), 0.0).xyz); |
|
65 |
|
vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * ( |
|
66 |
|
textureLod(u_texture, v_UV + dir * (0.0 / 3.0 - 0.5), 0.0).xyz + |
|
67 |
|
textureLod(u_texture, v_UV + dir * (3.0 / 3.0 - 0.5), 0.0).xyz); |
|
68 |
|
float lumaB = dot(rgbB, luma); |
|
69 |
|
color = (lumaB < lumaMin) || (lumaB > lumaMax) ? rgbA : rgbB; |
|
70 |
|
} |
|
71 |
|
// Apply tone curve to each channel independently. |
|
72 |
|
color.r = ToneCurve(color.r, u_shadow.r, u_midtone.r, u_highlight.r); |
|
73 |
|
color.g = ToneCurve(color.g, u_shadow.g, u_midtone.g, u_highlight.g); |
|
74 |
|
color.b = ToneCurve(color.b, u_shadow.b, u_midtone.b, u_highlight.b); |
|
75 |
|
|
|
76 |
|
fragColor = vec4(color, 1.0); |
|
77 |
|
} |
File include/fg3/fg3.h changed (mode: 100644) (index 9928925..a5a3477) |
... |
... |
Framebuffer createFramebuffer( GLsizei width, GLsizei height, bool cubemap = fal |
260 |
260 |
void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei multisample = 0 ); |
void resizeFramebuffer( Framebuffer &fb, GLsizei width, GLsizei height, GLsizei multisample = 0 ); |
261 |
261 |
Texture getFramebufferTexture( Framebuffer &fb ); |
Texture getFramebufferTexture( Framebuffer &fb ); |
262 |
262 |
void setFramebuffer( Framebuffer fb = newFramebuffer, float viewScale = 1.0f ); |
void setFramebuffer( Framebuffer fb = newFramebuffer, float viewScale = 1.0f ); |
|
263 |
|
void drawQuadToRegion( double x, double y, double width, double height ); |
263 |
264 |
void drawFramebuffer( Framebuffer &fb, bool draw_z = false, float viewScale = 1.0f ); |
void drawFramebuffer( Framebuffer &fb, bool draw_z = false, float viewScale = 1.0f ); |
264 |
265 |
Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb = newFramebuffer ); |
Framebuffer getIrradianceFramebuffer( Texture in_cubemap, Framebuffer fb = newFramebuffer ); |
265 |
266 |
void drawSkybox( Texture &tex, linalg::mat<double,4,4> view, linalg::mat<double,4,4> proj, Color tint = newColor ); |
void drawSkybox( Texture &tex, linalg::mat<double,4,4> view, linalg::mat<double,4,4> proj, Color tint = newColor ); |
|
... |
... |
void setFramebuffer( Framebuffer fb, float viewScale ){ |
1815 |
1816 |
} |
} |
1816 |
1817 |
} |
} |
1817 |
1818 |
|
|
|
1819 |
|
// Draw a plane using the provided pixel coordinates. |
|
1820 |
|
void drawQuadToRegion(double x, double y, double width, double height){ |
|
1821 |
|
double screenWidth = getDisplayWidth(), screenHeight = getDisplayHeight(); |
|
1822 |
|
|
|
1823 |
|
double normalizedX = (x / screenWidth) * 2.0 - 1.0; |
|
1824 |
|
double normalizedY = (y / screenHeight) * -2.0 + 1.0; |
|
1825 |
|
double normalizedWidth = (width / screenWidth) * 2.0; |
|
1826 |
|
double normalizedHeight = (height / screenHeight) * -2.0; |
|
1827 |
|
|
|
1828 |
|
linalg::vec<double,3> scaleVec = {normalizedWidth, normalizedHeight, 0.0}; |
|
1829 |
|
linalg::vec<double,3> translateVec = {normalizedX, normalizedY, 0.0}; |
|
1830 |
|
|
|
1831 |
|
linalg::mat<double,4,4> modelMat = linalg::mul( |
|
1832 |
|
linalg::translation_matrix(translateVec), |
|
1833 |
|
linalg::scaling_matrix(scaleVec) |
|
1834 |
|
); |
|
1835 |
|
|
|
1836 |
|
drawMesh( |
|
1837 |
|
planeMesh, |
|
1838 |
|
modelMat, |
|
1839 |
|
linalg::identity, |
|
1840 |
|
linalg::identity |
|
1841 |
|
); |
|
1842 |
|
} |
|
1843 |
|
|
1818 |
1844 |
void drawFramebuffer( Framebuffer &fb, bool draw_z, float viewScale ){ |
void drawFramebuffer( Framebuffer &fb, bool draw_z, float viewScale ){ |
1819 |
1845 |
if( !fb.success ) return; |
if( !fb.success ) return; |
1820 |
1846 |
if( fb.multisample > 0 ){ |
if( fb.multisample > 0 ){ |
File src/rsod.cpp changed (mode: 100644) (index f65ceb1..0f88a0b) |
... |
... |
std::vector<std::string> mod_paths = { "game" }; |
242 |
242 |
|
|
243 |
243 |
fgl::Framebuffer fb_left, fb_right, fb_resolved, fb_bloom_multisample, fb_bloom, fb_bloom_temp, fb_minimap; |
fgl::Framebuffer fb_left, fb_right, fb_resolved, fb_bloom_multisample, fb_bloom, fb_bloom_temp, fb_minimap; |
244 |
244 |
|
|
245 |
|
fgl::Pipeline fxaaPipeline, anaglyphPipeline, bloomBlurPipeline; |
|
|
245 |
|
fgl::Pipeline postfxPipeline, anaglyphPipeline, bloomBlurPipeline; |
246 |
246 |
|
|
247 |
247 |
linalg::vec<double,3> player_angle_init{}; |
linalg::vec<double,3> player_angle_init{}; |
248 |
248 |
|
|
|
... |
... |
fgl::Color ambient_colors[] = { |
261 |
261 |
|
|
262 |
262 |
fgl::Color ambient_light = { 1.0f, 1.0f, 1.0f, 1.0f }; |
fgl::Color ambient_light = { 1.0f, 1.0f, 1.0f, 1.0f }; |
263 |
263 |
|
|
|
264 |
|
std::map<std::string,std::vector<fgl::Color>> tonemaps; |
|
265 |
|
std::string current_tonemap = "default"; |
|
266 |
|
|
264 |
267 |
double fadeLevel = 0.0; |
double fadeLevel = 0.0; |
265 |
268 |
std::string fade_to = ""; |
std::string fade_to = ""; |
266 |
269 |
|
|
|
... |
... |
int main( int argc, char* argv[] ){ |
718 |
721 |
// Load the trinkets. |
// Load the trinkets. |
719 |
722 |
dungeon.appendTrinkets( data_path + "/trinkets", data_path + "/trinkets/unique_trinkets.json" ); |
dungeon.appendTrinkets( data_path + "/trinkets", data_path + "/trinkets/unique_trinkets.json" ); |
720 |
723 |
|
|
721 |
|
fxaaPipeline = dungeon.loadShaders( data_path + "/glsl/fxaa.vert", data_path + "/glsl/fxaa.frag", { "u_texture" } ); |
|
|
724 |
|
postfxPipeline = dungeon.loadShaders( data_path + "/glsl/postfx.vert", data_path + "/glsl/postfx.frag", { "u_texture" } ); |
722 |
725 |
anaglyphPipeline = dungeon.loadShaders( data_path + "/glsl/anaglyph.vert", data_path + "/glsl/anaglyph.frag", { "u_texture" } ); |
anaglyphPipeline = dungeon.loadShaders( data_path + "/glsl/anaglyph.vert", data_path + "/glsl/anaglyph.frag", { "u_texture" } ); |
723 |
726 |
bloomBlurPipeline = dungeon.loadShaders( data_path + "/glsl/bloom_blur.vert", data_path + "/glsl/bloom_blur.frag", { "u_texture" } ); |
bloomBlurPipeline = dungeon.loadShaders( data_path + "/glsl/bloom_blur.vert", data_path + "/glsl/bloom_blur.frag", { "u_texture" } ); |
724 |
727 |
|
|
|
... |
... |
void InitEngine( std::string file_name ){ |
1224 |
1227 |
fprintf( stderr, "Warning: ambientColors must include 6 RGB triplets.\n" ); |
fprintf( stderr, "Warning: ambientColors must include 6 RGB triplets.\n" ); |
1225 |
1228 |
} |
} |
1226 |
1229 |
} |
} |
|
1230 |
|
// Map assignments must happen at runtime. |
|
1231 |
|
std::vector<fgl::Color> tonemap_colors(3); |
|
1232 |
|
tonemap_colors[0] = { 0.0f, 0.0f, 0.0f, 1.0f }; // Shadows. |
|
1233 |
|
tonemap_colors[1] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Midtones. |
|
1234 |
|
tonemap_colors[2] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Highlights. |
|
1235 |
|
tonemaps["default"] = tonemap_colors; |
|
1236 |
|
if( info["tonemaps"] ){ |
|
1237 |
|
for( auto &o : info["tonemaps"].getObject() ){ |
|
1238 |
|
auto tc = o.value.getArray(); |
|
1239 |
|
if( tc.size() >= 3 ){ |
|
1240 |
|
for( size_t i = 0; i < 3; i++ ){ |
|
1241 |
|
auto c = tc[i].getArray(); |
|
1242 |
|
if( c.size() >= 3 ){ |
|
1243 |
|
tonemap_colors[i] = |
|
1244 |
|
{ c[0].getFloat(), c[1].getFloat(), c[2].getFloat(), 1.0f }; |
|
1245 |
|
} |
|
1246 |
|
} |
|
1247 |
|
tonemaps[viewToString( o.name )] = tonemap_colors; |
|
1248 |
|
}else{ |
|
1249 |
|
fprintf( stderr, |
|
1250 |
|
"Warning: Each tonemap must include 3 RGB triplets (shadows, midtones, highlights).\n" ); |
|
1251 |
|
} |
|
1252 |
|
} |
|
1253 |
|
} |
1227 |
1254 |
|
|
1228 |
1255 |
jsonFreeDocument( &allocatedDocument ); |
jsonFreeDocument( &allocatedDocument ); |
1229 |
1256 |
} |
} |
|
... |
... |
void LoadMap( std::string file_path ){ |
1948 |
1975 |
cs_stop_all_sounds( csctx ); |
cs_stop_all_sounds( csctx ); |
1949 |
1976 |
return; |
return; |
1950 |
1977 |
} |
} |
|
1978 |
|
// Set the tonemap. |
|
1979 |
|
if( file_path.length() >= 9 |
|
1980 |
|
&& file_path.substr( 0, 8 ) == "TONEMAP " ){ |
|
1981 |
|
current_tonemap = file_path.substr( 8 ); |
|
1982 |
|
return; |
|
1983 |
|
} |
1951 |
1984 |
// Shake the camera for a specified amount of time. |
// Shake the camera for a specified amount of time. |
1952 |
1985 |
if( file_path.length() >= 7 && file_path.substr(0, 6) == "SHAKE " ){ |
if( file_path.length() >= 7 && file_path.substr(0, 6) == "SHAKE " ){ |
1953 |
1986 |
char* p; |
char* p; |
|
... |
... |
void LoadMap( std::string file_path ){ |
2255 |
2288 |
} |
} |
2256 |
2289 |
// Stop the playlist. |
// Stop the playlist. |
2257 |
2290 |
StopPlaylist(); |
StopPlaylist(); |
|
2291 |
|
// Reset the tonemap. |
|
2292 |
|
current_tonemap = "default"; |
2258 |
2293 |
// Clear the fade_to string so Warp callbacks can trigger. |
// Clear the fade_to string so Warp callbacks can trigger. |
2259 |
2294 |
fade_to = ""; |
fade_to = ""; |
2260 |
2295 |
// Display a loading screen. |
// Display a loading screen. |
|
... |
... |
void OpenMap(){ // TODO: DRY |
2350 |
2385 |
fclose( file ); |
fclose( file ); |
2351 |
2386 |
// Stop the playlist. |
// Stop the playlist. |
2352 |
2387 |
StopPlaylist(); |
StopPlaylist(); |
|
2388 |
|
// Reset the tonemap. |
|
2389 |
|
current_tonemap = "default"; |
2353 |
2390 |
// Reset playtime. |
// Reset playtime. |
2354 |
2391 |
playtime = 0.0; |
playtime = 0.0; |
2355 |
2392 |
// Reset "map" variables along with map state so that they |
// Reset "map" variables along with map state so that they |
|
... |
... |
void Render(){ |
2888 |
2925 |
playtime += d; |
playtime += d; |
2889 |
2926 |
} |
} |
2890 |
2927 |
|
|
2891 |
|
// Resolve the eye framebuffer(s). Use FXAA if applicable. |
|
2892 |
|
if( msaa == 0 ) |
|
2893 |
|
fgl::setPipeline( dungeon.pbr ? fxaaPipeline : fgl::unlitPipeline ); |
|
|
2928 |
|
// Resolve the eye framebuffer(s). Use post effects if PBR is enabled. |
|
2929 |
|
if(dungeon.pbr){ |
|
2930 |
|
fgl::setPipeline(postfxPipeline); |
|
2931 |
|
auto postprog = postfxPipeline.programObject; |
|
2932 |
|
// Enable or disable FXAA. |
|
2933 |
|
GLint u_AA = glGetUniformLocation(postprog, "u_AA"); |
|
2934 |
|
glUniform1i(u_AA, msaa == 0 ? 1 : 0); |
|
2935 |
|
// Set tone curves. |
|
2936 |
|
std::vector<fgl::Color> &tonemap_colors = tonemaps[current_tonemap]; |
|
2937 |
|
if(tonemap_colors.size() >= 3){ |
|
2938 |
|
glUniform3f(glGetUniformLocation(postprog, "u_shadow"), |
|
2939 |
|
tonemap_colors[0].r, tonemap_colors[0].g, tonemap_colors[0].b); |
|
2940 |
|
glUniform3f(glGetUniformLocation(postprog, "u_midtone"), |
|
2941 |
|
tonemap_colors[1].r, tonemap_colors[1].g, tonemap_colors[1].b); |
|
2942 |
|
glUniform3f(glGetUniformLocation(postprog, "u_highlight"), |
|
2943 |
|
tonemap_colors[2].r, tonemap_colors[2].g, tonemap_colors[2].b); |
|
2944 |
|
} |
|
2945 |
|
}else{ |
|
2946 |
|
fgl::setPipeline(fgl::unlitPipeline); |
|
2947 |
|
} |
2894 |
2948 |
fgl::setFog({0.0f, 0.0f, 0.0f, 0.0f}); |
fgl::setFog({0.0f, 0.0f, 0.0f, 0.0f}); |
2895 |
2949 |
glDisable(GL_BLEND); |
glDisable(GL_BLEND); |
2896 |
2950 |
for(int i = 0; i < (use_stereogram ? 2 : 1); i++){ |
for(int i = 0; i < (use_stereogram ? 2 : 1); i++){ |
|
... |
... |
void Render(){ |
2902 |
2956 |
// Blit and rely on OpenGL to resolve samples. |
// Blit and rely on OpenGL to resolve samples. |
2903 |
2957 |
// There must be zero scaling of the framebuffer |
// There must be zero scaling of the framebuffer |
2904 |
2958 |
// when resolving multisampling samples. |
// when resolving multisampling samples. |
2905 |
|
// TODO: Anaglyph FXAA. |
|
|
2959 |
|
// TODO: Anaglyph postfx. |
2906 |
2960 |
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.fbo); |
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.fbo); |
2907 |
2961 |
glBlitFramebuffer( |
glBlitFramebuffer( |
2908 |
2962 |
0, 0, fb.width, fb.height, // source |
0, 0, fb.width, fb.height, // source |
|
... |
... |
void Render(){ |
2920 |
2974 |
fgl::drawFramebuffer(fb_resolved, false, dungeon.frameBufScale); |
fgl::drawFramebuffer(fb_resolved, false, dungeon.frameBufScale); |
2921 |
2975 |
} |
} |
2922 |
2976 |
}else{ |
}else{ |
2923 |
|
// Draw the appropriate eye framebuffer. |
|
2924 |
|
fgl::drawFramebuffer(fb); |
|
|
2977 |
|
// ************************************************************** |
|
2978 |
|
// * * |
|
2979 |
|
// * /\_/\ * |
|
2980 |
|
// * ( o.o ) < This code draws framebuffers with shaders. * |
|
2981 |
|
// * > ^ < * |
|
2982 |
|
// * * |
|
2983 |
|
// ************************************************************** |
|
2984 |
|
if(msaa == 0){ |
|
2985 |
|
// No MSAA, so draw the appropriate eye framebuffer. |
|
2986 |
|
fgl::drawFramebuffer(fb); |
|
2987 |
|
}else{ |
|
2988 |
|
// Resolve the multisampled framebuffer into fb_resolved. |
|
2989 |
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.fbo); |
|
2990 |
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_resolved.fbo); |
|
2991 |
|
glBlitFramebuffer( |
|
2992 |
|
0, 0, fb.width, fb.height, |
|
2993 |
|
0, 0, fb_resolved.width, fb_resolved.height, |
|
2994 |
|
GL_COLOR_BUFFER_BIT, |
|
2995 |
|
GL_NEAREST |
|
2996 |
|
); |
|
2997 |
|
// Draw the resolved framebuffer with post effects. |
|
2998 |
|
fgl::drawFramebuffer(fb_resolved); |
|
2999 |
|
} |
2925 |
3000 |
// Draw the resolved framebuffer to the screen. |
// Draw the resolved framebuffer to the screen. |
2926 |
3001 |
fgl::setFramebuffer(); |
fgl::setFramebuffer(); |
|
3002 |
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_resolved.fbo); |
2927 |
3003 |
// Blit the framebuffers left-right. |
// Blit the framebuffers left-right. |
2928 |
3004 |
int x = i * fb_resolved.width; |
int x = i * fb_resolved.width; |
2929 |
|
glBindFramebuffer( GL_READ_FRAMEBUFFER, fb_resolved.fbo ); |
|
2930 |
3005 |
glBlitFramebuffer( |
glBlitFramebuffer( |
2931 |
3006 |
0, 0, fb_resolved.width * dungeon.frameBufScale, fb_resolved.height * dungeon.frameBufScale, // source |
0, 0, fb_resolved.width * dungeon.frameBufScale, fb_resolved.height * dungeon.frameBufScale, // source |
2932 |
3007 |
x, 0, x + fb_resolved.width + 1, fb_resolved.height + 1, // destination |
x, 0, x + fb_resolved.width + 1, fb_resolved.height + 1, // destination |
|
... |
... |
void Render(){ |
2936 |
3011 |
} |
} |
2937 |
3012 |
} |
} |
2938 |
3013 |
fgl::setPipeline(fgl::unlitPipeline); |
fgl::setPipeline(fgl::unlitPipeline); |
2939 |
|
|
|
2940 |
|
// Draw the bloom framebuffer to the screen. |
|
2941 |
|
if(bloomBlurPipeline.success && !use_stereogram){ |
|
2942 |
|
glEnable( GL_BLEND ); |
|
2943 |
|
glBlendFunc( GL_ONE, GL_ONE ); |
|
2944 |
|
fgl::drawFramebuffer( fb_bloom ); |
|
2945 |
|
//if( fgl::charKey('z') ){ |
|
2946 |
|
// glDisable( GL_BLEND ); |
|
2947 |
|
// fgl::drawFramebuffer( dungeon.shadowBuf ); |
|
2948 |
|
//} |
|
2949 |
|
} |
|
2950 |
3014 |
} |
} |
2951 |
3015 |
|
|
2952 |
3016 |
Prepare2D(); |
Prepare2D(); |
|
... |
... |
void FirstPersonLoop( double d ){ |
4040 |
4104 |
fgl::drawFramebuffer( fb_bloom_temp ); // from --> |
fgl::drawFramebuffer( fb_bloom_temp ); // from --> |
4041 |
4105 |
} |
} |
4042 |
4106 |
|
|
|
4107 |
|
// Draw the bloom framebuffer to the viewport framebuffer. |
|
4108 |
|
if(bloomBlurPipeline.success && !use_stereogram){ |
|
4109 |
|
fgl::setFramebuffer( fb_left ); |
|
4110 |
|
// Clear only the depth buffer. |
|
4111 |
|
//glClear( GL_DEPTH_BUFFER_BIT ); |
|
4112 |
|
glEnable( GL_BLEND ); |
|
4113 |
|
glBlendFunc( GL_ONE, GL_ONE ); |
|
4114 |
|
fgl::drawFramebuffer( fb_bloom, false, 1.0f / dungeon.frameBufScale ); |
|
4115 |
|
glDisable( GL_BLEND ); |
|
4116 |
|
} |
|
4117 |
|
|
4043 |
4118 |
// Restore dungeon.playerZoom. |
// Restore dungeon.playerZoom. |
4044 |
4119 |
if(use_stereogram && !use_anaglyph) dungeon.playerZoom = zoom_copy; |
if(use_stereogram && !use_anaglyph) dungeon.playerZoom = zoom_copy; |
4045 |
4120 |
} |
} |