X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=demos%2Fdesertpillars.cpp;h=d741beea5390b0eb8307fdb78d401fb47c62b314;hp=758f5eb12ef8bbce7eed1c55e7ed9d87f801fbba;hb=dff7004fa078d55911664c0f513b5dc6c9449420;hpb=9e3e811d54906e73d97e2a14ee785f2fe6c0fae7 diff --git a/demos/desertpillars.cpp b/demos/desertpillars.cpp index 758f5eb1..d741beea 100644 --- a/demos/desertpillars.cpp +++ b/demos/desertpillars.cpp @@ -17,10 +17,10 @@ #include #include #include -#include +#include #include -#include #include +#include #include #include #include @@ -46,7 +46,7 @@ including: - Shadow mapping - Environment mapped reflections - Skybox using a cube map texture -- Effects with nested pipelines +- Effects with nested sequences - Complex multitexturing - Shader-based deformations - Creating a normalmapped texture through rendering @@ -97,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; @@ -111,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; @@ -128,7 +132,7 @@ private: GL::EnvironmentMap *env_cube; GL::WindowView view; - GL::Pipeline pipeline; + GL::Sequence sequence; GL::Camera camera; GL::SimpleScene sky_scene; GL::InstanceScene scene; @@ -138,7 +142,7 @@ private: GL::Bloom bloom; GL::ColorCurve colorcurve; - GL::Pipeline env_pipeline; + GL::Sequence env_sequence; Time::TimeStamp last_tick; float camera_angle; @@ -162,7 +166,7 @@ public: private: void setup_view(); - void create_pipeline(); + void create_sequence(); void create_skybox(); static void create_skybox_face(GL::TextureCube &, GL::TextureCubeFace); void create_tiles_texture(); @@ -223,13 +227,17 @@ const char DesertPillars::ground_src[] = "const bool use_normal_map = true;\n" "const bool use_shadow_map = true;\n" "#pragma MSP stage(vertex)\n" - "layout(location=7) in float ground_type;\n" + "layout(location=11) in float ground_type;\n" + "void custom_transform() override\n" + "{\n" + " passthrough;\n" + "}\n" "#pragma MSP stage(fragment)\n" - "vec4 get_diffuse_color()\n" + "vec4 get_diffuse_color() override\n" "{\n" " return mix(texture(texture1, texcoord.xy*3.0), texture(texture2, texcoord.xy), ground_type);\n" "}\n" - "vec4 get_normal_sample()\n" + "vec3 get_fragment_normal() override\n" "{\n" " return mix(texture(normalmap1, texcoord.xy*3.0).rgb, texture(normalmap2, texcoord.xy).rgb, ground_type);\n" "}\n"; @@ -240,12 +248,12 @@ const char DesertPillars::cube_src[] = "const bool use_reflectivity = true;\n" "uniform float spherify;\n" "#pragma MSP stage(vertex)\n" - "layout(location=7) in vec3 sphere_coord;\n" - "vec4 transform_position(vec4 pos)\n" + "layout(location=11) in vec3 sphere_coord;\n" + "vec4 transform_position(vec4 pos) override\n" "{\n" " return eye_obj_matrix*vec4(mix(vertex.xyz, sphere_coord, spherify), 1.0);\n" "}\n" - "vec3 transform_normal(vec3 pos)\n" + "vec3 transform_normal(vec3 pos) override\n" "{\n" " return eye_obj_normal_matrix*normalize(mix(normal, normalize(sphere_coord), spherify));\n" "}\n"; @@ -286,15 +294,16 @@ 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()), - env_pipeline(512, 512), + sequence(view), + shadow_scene(resources, 2048, scene, light), + bloom(resources, window.get_width(), window.get_height()), + colorcurve(resources), + env_sequence(512, 512), camera_angle(0), camera_stopped(false), cube_angle(0), @@ -310,7 +319,7 @@ DesertPillars::DesertPillars(int argc, char **argv): keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false)); setup_view(); - create_pipeline(); + create_sequence(); create_skybox(); create_ground(); create_pillars(); @@ -331,13 +340,13 @@ void DesertPillars::setup_view() camera.set_up_direction(GL::Vector3(0, 0, 1)); camera.set_depth_clip(1, 50); view.set_camera(&camera); - view.set_content(&pipeline); + view.set_content(&sequence); } -void DesertPillars::create_pipeline() +void DesertPillars::create_sequence() { - pipeline.set_multisample(8); - pipeline.set_hdr(true); + sequence.set_multisample(8); + sequence.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 @@ -353,41 +362,41 @@ void DesertPillars::create_pipeline() lighting.set_ambient(GL::Color(0.2)); // The skybox is rendered first - pipeline.add_pass(0, sky_scene); + sequence.add_pass(0, sky_scene); - GL::Pipeline::Pass *pass = &pipeline.add_pass(0, shadow_scene); + GL::Sequence::Pass *pass = &sequence.add_pass(0, shadow_scene); pass->set_lighting(&lighting); pass->set_depth_test(&GL::DepthTest::lequal()); /* A bloom filter enhances the realism of bright surfaces, even if there isn't anything really glowy in the scene. */ bloom.set_strength(0.3); - pipeline.add_postprocessor(bloom); + sequence.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); + sequence.add_postprocessor(colorcurve); - /* Initialize a second pipeline to render the environment map. It has the + /* Initialize a second sequence to render the environment map. It has the same renderables and passes, but no postprocessors or camera. */ - env_pipeline.add_pass(0, sky_scene); - pass = &env_pipeline.add_pass(0, shadow_scene); + env_sequence.add_pass(0, sky_scene); + pass = &env_sequence.add_pass(0, shadow_scene); pass->set_lighting(&lighting); pass->set_depth_test(&GL::DepthTest::lequal()); } void DesertPillars::create_skybox() { - skybox_tex.storage(GL::SRGB, 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); @@ -421,7 +430,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; } @@ -429,10 +438,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)); @@ -447,6 +455,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 @@ -483,6 +492,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); @@ -501,14 +511,12 @@ void DesertPillars::create_sand_texture() unsigned width = 512; unsigned height = 512; - sand_texture.storage(GL::SRGB, 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]; @@ -522,10 +530,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; } @@ -597,15 +605,15 @@ 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. */ - GL::VertexFormat vfmt = (GL::VERTEX3, GL::NORMAL3, GL::TANGENT3, GL::BINORMAL3, GL::TEXCOORD2, GL::ATTRIB1,7); + GL::VertexFormat vfmt = (GL::VERTEX3, GL::NORMAL3, GL::TANGENT3, GL::BINORMAL3, GL::TEXCOORD2, GL::GENERIC1); ground_data.mesh = new GL::Mesh(vfmt); // Create a base grid @@ -618,7 +626,7 @@ void DesertPillars::create_ground() unsigned tan = vfmt.offset(GL::TANGENT3); unsigned bin = vfmt.offset(GL::BINORMAL3); unsigned tex = vfmt.offset(GL::TEXCOORD2); - unsigned gt = vfmt.offset(GL::make_indexed_component(GL::ATTRIB1, 7)); + unsigned gt = vfmt.offset(GL::GENERIC1); for(unsigned i=0; imodify_vertex(i); @@ -672,7 +680,7 @@ void DesertPillars::create_pillars() pillar_material.set_receive_shadows(true); GL::RenderPass *pass = &pillar_tech.add_pass(0); - pass->set_material(&pillar_material); + pass->set_material(&pillar_material, &resources); pass = &pillar_tech.add_pass("shadow"); pass->set_shader_program(&shadow_shprog, 0); @@ -748,13 +756,13 @@ void DesertPillars::create_cube() cube_material.set_reflectivity(0.5); GL::RenderPass *pass = &cube_tech.add_pass(0); - pass->set_material(&cube_material); + pass->set_material(&cube_material, &resources); pass->set_shader_program(&cube_shprog, 0); pass = &cube_tech.add_pass("shadow"); pass->set_shader_program(&cube_shadow_shprog, 0); - cube_data.mesh = new GL::Mesh((GL::VERTEX3, GL::NORMAL3, GL::ATTRIB3,7)); + cube_data.mesh = new GL::Mesh((GL::VERTEX3, GL::NORMAL3, GL::GENERIC3)); GL::MeshBuilder bld(*cube_data.mesh); create_cube_face(bld, GL::Vector3(-1, -1, -1), GL::Vector3(2, 0, 0), GL::Vector3(0, 2, 0), 16); bld.offset(cube_data.mesh->get_n_vertices()); @@ -770,7 +778,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_sequence); scene.add(*env_cube); } @@ -796,7 +804,7 @@ void DesertPillars::create_cube_face(GL::MeshBuilder &bld, const GL::Vector3 &ba l = sqrt(v.x*v.x+v.y*v.y+v.z*v.z); l /= 1.732; - bld.attrib(7, v.x/l, v.y/l, v.z/l); + bld.generic(0, v.x/l, v.y/l, v.z/l); bld.vertex(v); }