X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=demos%2Fdesertpillars.cpp;h=242a9e73c0f1234732ff52006cb402a8cd0db643;hb=5e4204ecaf54f49b63587ef5cd669a1b3838e0e9;hp=bf62b7e32f6a9c37be256a6dcc07204f9c476df6;hpb=3e9eb612a32ebe05030b934e0afb059f19cbb320;p=libs%2Fgl.git diff --git a/demos/desertpillars.cpp b/demos/desertpillars.cpp index bf62b7e3..242a9e73 100644 --- a/demos/desertpillars.cpp +++ b/demos/desertpillars.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -18,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -96,13 +97,15 @@ private: Msp::Graphics::Window window; Msp::Graphics::GLContext gl_context; Msp::Input::Keyboard keyboard; + GL::Resources resources; GL::Program skybox_shprog; GL::Technique skybox_tech; GL::TextureCube skybox_tex; + GL::Sampler linear_clamped_sampler; ObjectData skybox_data; - GL::Program shadow_shprog; + const GL::Program &shadow_shprog; GL::Program ground_shprog; GL::ProgramData ground_shdata; @@ -110,6 +113,8 @@ private: GL::Texture2D tiles_normalmap; GL::Texture2D sand_texture; GL::Texture2D sand_normalmap; + GL::Sampler linear_sampler; + GL::Sampler mipmap_sampler; GL::Technique ground_tech; ObjectData ground_data; @@ -135,6 +140,7 @@ private: GL::Light light; GL::ShadowMap shadow_scene; GL::Bloom bloom; + GL::ColorCurve colorcurve; GL::Pipeline env_pipeline; @@ -227,7 +233,7 @@ const char DesertPillars::ground_src[] = "{\n" " return mix(texture(texture1, texcoord.xy*3.0), texture(texture2, texcoord.xy), ground_type);\n" "}\n" - "vec4 get_normal_sample()\n" + "vec4 get_fragment_normal()\n" "{\n" " return mix(texture(normalmap1, texcoord.xy*3.0).rgb, texture(normalmap2, texcoord.xy).rgb, ground_type);\n" "}\n"; @@ -284,14 +290,15 @@ DesertPillars::DesertPillars(int argc, char **argv): gl_context(window), keyboard(window), skybox_shprog(skybox_src), - shadow_shprog("occluder.glsl"), + shadow_shprog(resources.get("_occluder.glsl.shader")), ground_shprog(ground_src), cube_shprog(cube_src), cube_shadow_shprog(string(cube_src)+cube_shadow_src_tail), view(window, gl_context), pipeline(view), - shadow_scene(2048, scene, light), - bloom(window.get_width(), window.get_height()), + shadow_scene(resources, 2048, scene, light), + bloom(resources, window.get_width(), window.get_height()), + colorcurve(resources), env_pipeline(512, 512), camera_angle(0), camera_stopped(false), @@ -335,17 +342,20 @@ void DesertPillars::setup_view() void DesertPillars::create_pipeline() { pipeline.set_multisample(8); + pipeline.set_hdr(true); /* The shadow map is focused on the part of the scene that contains the pillars and the cube. Making the ground cast shadows as well would result either in a very low spatial resolution of the shadow map, or ugly artifacts as the ground crosses the shadow map boundary. */ shadow_scene.set_target(GL::Vector3(0, 0, 0), 10); + shadow_scene.set_darkness(1); // Put the sun pretty high in the sky + light.set_diffuse(GL::Color(2.0)); light.set_position(GL::Vector4(0.5, -2, 3, 0)); lighting.attach(0, light); - lighting.set_ambient(GL::Color(0.5)); + lighting.set_ambient(GL::Color(0.2)); // The skybox is rendered first pipeline.add_pass(0, sky_scene); @@ -359,6 +369,11 @@ void DesertPillars::create_pipeline() bloom.set_strength(0.3); pipeline.add_postprocessor(bloom); + /* Lighting calculations are best done in linear color space, so the final + image must be converted to srgb for display. */ + colorcurve.set_srgb(); + pipeline.add_postprocessor(colorcurve); + /* Initialize a second pipeline to render the environment map. It has the same renderables and passes, but no postprocessors or camera. */ env_pipeline.add_pass(0, sky_scene); @@ -369,15 +384,15 @@ void DesertPillars::create_pipeline() void DesertPillars::create_skybox() { - skybox_tex.storage(GL::RGB, 128); - skybox_tex.set_min_filter(GL::LINEAR); - skybox_tex.set_wrap(GL::CLAMP_TO_EDGE); + skybox_tex.storage(GL::SRGB8, 128, 1); + linear_clamped_sampler.set_min_filter(GL::LINEAR); + linear_clamped_sampler.set_wrap(GL::CLAMP_TO_EDGE); for(unsigned i=0; i<6; ++i) create_skybox_face(skybox_tex, skybox_tex.enumerate_faces(i)); GL::RenderPass &pass = skybox_tech.add_pass(0); pass.set_shader_program(&skybox_shprog, 0); - pass.set_texture(0, &skybox_tex); + pass.set_texture(0, &skybox_tex, &linear_clamped_sampler); // The shader will use the vertex coordinates to initialize texture coordinates as well skybox_data.mesh = new GL::Mesh(GL::VERTEX3); @@ -411,7 +426,7 @@ void DesertPillars::create_skybox_face(GL::TextureCube &texture, GL::TextureCube pixels[i+2] = 160; } } - texture.image(face, 0, GL::RGB, GL::UNSIGNED_BYTE, pixels); + texture.image(face, 0, pixels); delete[] pixels; } @@ -419,10 +434,9 @@ void DesertPillars::create_tiles_texture() { unsigned width = 256; unsigned height = 256; - tiles_texture.storage(GL::RGB, width, height); - tiles_texture.set_min_filter(GL::LINEAR); - tiles_normalmap.storage(GL::RGB, width, height); - tiles_normalmap.set_min_filter(GL::LINEAR); + tiles_texture.storage(GL::RGB8, width, height, 1); + tiles_normalmap.storage(GL::RGB8, width, height, 1); + linear_sampler.set_min_filter(GL::LINEAR); GL::Mesh tiles((GL::VERTEX3, GL::NORMAL3, GL::COLOR4_UBYTE)); @@ -437,6 +451,7 @@ void DesertPillars::create_tiles_texture() 4, 4, 3, 3, 4, 1, 3, 2, 2, 3, 2, 2, 3, 3, 3, 2 }; + { GL::MeshBuilder bld(tiles); // Create a dark background @@ -450,7 +465,7 @@ void DesertPillars::create_tiles_texture() bld.end(); // Create the four tiles - bld.color(0.95f, 0.8f, 0.65f); + bld.color(GL::Color(0.95f, 0.8f, 0.65f).to_linear()); for(unsigned i=0; i<2; ++i) for(unsigned j=0; j<2; ++j) { @@ -473,6 +488,7 @@ void DesertPillars::create_tiles_texture() bld.vertex(coords[i*4+order[32+l*2]], coords[j*4+order[32+l*2+1]], bevel); bld.end(); } + } GL::Program shprog(texture_src); @@ -491,14 +507,12 @@ void DesertPillars::create_sand_texture() unsigned width = 512; unsigned height = 512; - sand_texture.storage(GL::RGB, width/16, height/16); - sand_texture.set_min_filter(GL::LINEAR_MIPMAP_LINEAR); - sand_texture.set_max_anisotropy(4); + sand_texture.storage(GL::SRGB8, width/16, height/16); sand_texture.set_auto_generate_mipmap(true); - sand_normalmap.storage(GL::RGB, width, height); - sand_normalmap.set_min_filter(GL::LINEAR_MIPMAP_LINEAR); - sand_normalmap.set_max_anisotropy(4); + sand_normalmap.storage(GL::RGB8, width, height); sand_normalmap.set_auto_generate_mipmap(true); + mipmap_sampler.set_min_filter(GL::LINEAR_MIPMAP_LINEAR); + mipmap_sampler.set_max_anisotropy(4); unsigned char *pixels = new unsigned char[width*height*3]; unsigned char *bump = new unsigned char[width*height]; @@ -512,10 +526,10 @@ void DesertPillars::create_sand_texture() pixels[i+2] = 160; bump[x+y*width] = rand(); } - sand_texture.image(0, GL::RGB, GL::UNSIGNED_BYTE, pixels); + sand_texture.image(0, pixels); gaussian_blur(bump, width, height); create_normalmap(bump, pixels, width, height, 4); - sand_normalmap.image(0, GL::RGB, GL::UNSIGNED_BYTE, pixels); + sand_normalmap.image(0, pixels); delete[] pixels; delete[] bump; } @@ -587,10 +601,10 @@ void DesertPillars::create_ground() GL::RenderPass *pass = &ground_tech.add_pass(0); pass->set_shader_program(&ground_shprog, &ground_shdata); - pass->set_texture(0, &tiles_texture); - pass->set_texture(1, &tiles_normalmap); - pass->set_texture(2, &sand_texture); - pass->set_texture(3, &sand_normalmap); + pass->set_texture(0, &tiles_texture, &linear_sampler); + pass->set_texture(1, &tiles_normalmap, &linear_sampler); + pass->set_texture(2, &sand_texture, &mipmap_sampler); + pass->set_texture(3, &sand_normalmap, &mipmap_sampler); /* No shadow pass here; the ground only receives shadows, but doesn't cast them. */ @@ -658,7 +672,7 @@ float DesertPillars::ground_height(float x, float y) void DesertPillars::create_pillars() { // The pillars are a matt off-white - pillar_material.set_diffuse(GL::Color(0.9, 0.88, 0.8)); + pillar_material.set_diffuse(GL::Color(0.9, 0.89, 0.85).to_linear()); pillar_material.set_receive_shadows(true); GL::RenderPass *pass = &pillar_tech.add_pass(0); @@ -732,7 +746,7 @@ void DesertPillars::create_cube() { /* The cube is bluish-gray, with a hard specular reflection to produce a sun-like spot */ - cube_material.set_diffuse(GL::Color(0.5, 0.5, 0.55)); + cube_material.set_diffuse(GL::Color(0.5, 0.5, 0.55).to_linear()); cube_material.set_specular(GL::Color(1.0)); cube_material.set_shininess(120); cube_material.set_reflectivity(0.5); @@ -760,7 +774,7 @@ void DesertPillars::create_cube() cube_data.object = new GL::Object(cube_data.mesh, &cube_tech); cube = new Cube(*cube_data.object); - env_cube = new GL::EnvironmentMap(512, *cube, env_pipeline); + env_cube = new GL::EnvironmentMap(resources, 512, *cube, env_pipeline); scene.add(*env_cube); }