From 3e9eb612a32ebe05030b934e0afb059f19cbb320 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 11 Jun 2020 18:07:38 +0300 Subject: [PATCH] Modernize the demo and tool programs --- demos/desertpillars.cpp | 225 +++++++++++++++++----------------------- tools/viewer.cpp | 25 +++-- 2 files changed, 112 insertions(+), 138 deletions(-) diff --git a/demos/desertpillars.cpp b/demos/desertpillars.cpp index cb06cd00..bf62b7e3 100644 --- a/demos/desertpillars.cpp +++ b/demos/desertpillars.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ including: - Shadow mapping - Environment mapped reflections - Skybox using a cube map texture -- Nested scenes and pipelines +- Effects with nested pipelines - Complex multitexturing - Shader-based deformations - Creating a normalmapped texture through rendering @@ -112,20 +113,20 @@ private: GL::Technique ground_tech; ObjectData ground_data; - GL::Program pillar_shprog; - GL::Material pillar_material; + GL::BasicMaterial pillar_material; GL::Technique pillar_tech; std::vector pillar_data; std::vector pillars; GL::Program cube_shprog; GL::Program cube_shadow_shprog; - GL::Material cube_material; + GL::BasicMaterial cube_material; GL::Technique cube_tech; ObjectData cube_data; Cube *cube; GL::EnvironmentMap *env_cube; + GL::WindowView view; GL::Pipeline pipeline; GL::Camera camera; GL::SimpleScene sky_scene; @@ -146,12 +147,11 @@ private: float cube_phase; bool cube_frozen; - static const char texture_vertex_src[]; - static const char texture_fragment_src[]; - static const char skybox_vertex_src[]; - static const char skybox_fragment_src[]; - static const char ground_variables[]; - static const char cube_variables[]; + static const char texture_src[]; + static const char skybox_src[]; + static const char ground_src[]; + static const char cube_src[]; + static const char cube_shadow_src_tail[]; static const float cube_shapes[]; public: @@ -159,6 +159,7 @@ public: ~DesertPillars(); private: + void setup_view(); void create_pipeline(); void create_skybox(); static void create_skybox_face(GL::TextureCube &, GL::TextureCubeFace); @@ -180,68 +181,79 @@ private: void key_press(unsigned); }; -const char DesertPillars::texture_vertex_src[] = - "#version 130\n" - "in vec3 vertex;\n" - "in vec3 normal;\n" - "in vec3 color;\n" - "out vec3 v_normal;\n" - "out vec3 v_color;\n" +const char DesertPillars::texture_src[] = + "import msp_interface;\n" + "#pragma MSP stage(vertex)\n" "void main()\n" "{\n" " gl_Position = vec4(vertex.xy*2.0-1.0, -vertex.z*2.0, 1.0);\n" - " v_normal = normal;\n" - " v_color = color.rgb;\n" - "}\n"; - -const char DesertPillars::texture_fragment_src[] = - "#version 130\n" - "in vec3 v_normal;\n" - "in vec3 v_color;\n" - "out vec4 frag_color;\n" - "out vec4 frag_normal;\n" + " passthrough;\n" + "}\n" + "#pragma MSP stage(fragment)\n" + "layout(location=1) out vec4 frag_normal;\n" "void main()\n" "{\n" - " frag_color = vec4(v_color, 1.0);\n" - " frag_normal = vec4(v_normal*0.5+0.5, 1.0);\n" + " frag_color = color;\n" + " frag_normal = vec4(normal*0.5+0.5, 1.0);\n" "}\n"; -const char DesertPillars::skybox_vertex_src[] = - "#version 130\n" - "uniform mat4 projection_matrix;\n" - "uniform mat4 eye_obj_matrix;\n" - "in vec3 vertex;\n" - "out vec3 v_texcoord;\n" +const char DesertPillars::skybox_src[] = + "import msp_interface;\n" + "uniform samplerCube sky;\n" + "#pragma MSP stage(vertex)\n" "void main()\n" "{\n" - " gl_Position = projection_matrix*vec4(mat3(eye_obj_matrix)*vertex, 1.0);\n" - " v_texcoord = vertex;\n" - "}"; - -const char DesertPillars::skybox_fragment_src[] = - "#version 130\n" - "uniform samplerCube sky;\n" - "in vec3 v_texcoord;\n" - "out vec4 frag_color;\n" + " gl_Position = projection_matrix*vec4(mat3(eye_obj_matrix)*vertex.xyz, 1.0);\n" + " passthrough;\n" + "}\n" + "#pragma MSP stage(fragment)\n" "void main()\n" "{\n" - " frag_color = textureCube(sky, v_texcoord);\n" - "}"; + " frag_color = texture(sky, vertex.xyz);\n" + "}\n"; -const char DesertPillars::ground_variables[] = +const char DesertPillars::ground_src[] = + "import phong;\n" "uniform sampler2D texture1;\n" "uniform sampler2D normalmap1;\n" "uniform sampler2D texture2;\n" "uniform sampler2D normalmap2;\n" - "attribute float ground_type;\n" - "fragment vec4 diffuse_sample = mix(texture2D(texture1, texture_coord*3.0), texture2D(texture2, texture_coord), ground_type);\n" - "fragment vec3 normal_sample = mix(texture2D(normalmap1, texture_coord*3.0).rgb, texture2D(normalmap2, texture_coord).rgb, ground_type);\n"; + "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" + "#pragma MSP stage(fragment)\n" + "vec4 get_diffuse_color()\n" + "{\n" + " return mix(texture(texture1, texcoord.xy*3.0), texture(texture2, texcoord.xy), ground_type);\n" + "}\n" + "vec4 get_normal_sample()\n" + "{\n" + " return mix(texture(normalmap1, texcoord.xy*3.0).rgb, texture(normalmap2, texcoord.xy).rgb, ground_type);\n" + "}\n"; -const char DesertPillars::cube_variables[] = +const char DesertPillars::cube_src[] = + "import phong;\n" + "const bool use_specular = true;\n" + "const bool use_reflectivity = true;\n" "uniform float spherify;\n" - "attribute vec3 sphere_coord;\n" - "vertex vec3 eye_normal = eye_obj_normal_matrix*normalize(mix(normal, normalize(sphere_coord), spherify));\n" - "vertex vec4 eye_vertex = eye_obj_matrix*vec4(mix(vertex.xyz, sphere_coord, spherify), 1.0);\n"; + "#pragma MSP stage(vertex)\n" + "layout(location=7) in vec3 sphere_coord;\n" + "vec4 transform_position(vec4 pos)\n" + "{\n" + " return eye_obj_matrix*vec4(mix(vertex.xyz, sphere_coord, spherify), 1.0);\n" + "}\n" + "vec3 transform_normal(vec3 pos)\n" + "{\n" + " return eye_obj_normal_matrix*normalize(mix(normal, normalize(sphere_coord), spherify));\n" + "}\n"; + +const char DesertPillars::cube_shadow_src_tail[] = + "#pragma MSP stage(fragment)\n" + "void main()\n" + "{\n" + " frag_color = vec4(1.0);\n" + "}\n"; const float DesertPillars::cube_shapes[] = { -0.4, 0.5, 1.0, 0.3 }; @@ -271,8 +283,13 @@ DesertPillars::DesertPillars(int argc, char **argv): window(display, options.window_opts), gl_context(window), keyboard(window), - shadow_shprog(GL::ProgramBuilder::StandardFeatures()), - pipeline(window.get_width(), window.get_height()), + skybox_shprog(skybox_src), + shadow_shprog("occluder.glsl"), + 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), @@ -290,6 +307,7 @@ DesertPillars::DesertPillars(int argc, char **argv): window.show_cursor(false); keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false)); + setup_view(); create_pipeline(); create_skybox(); create_ground(); @@ -305,22 +323,24 @@ DesertPillars::~DesertPillars() delete *i; } -void DesertPillars::create_pipeline() +void DesertPillars::setup_view() { - pipeline.set_multisample(8); - - camera.set_aspect(float(window.get_width())/window.get_height()); + camera.set_aspect_ratio(float(window.get_width())/window.get_height()); camera.set_up_direction(GL::Vector3(0, 0, 1)); camera.set_depth_clip(1, 50); - pipeline.set_camera(&camera); + view.set_camera(&camera); + view.set_content(&pipeline); +} + +void DesertPillars::create_pipeline() +{ + pipeline.set_multisample(8); /* 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); - sky_scene.add(shadow_scene); - pipeline.add_renderable(sky_scene); // Put the sun pretty high in the sky light.set_position(GL::Vector4(0.5, -2, 3, 0)); @@ -328,9 +348,9 @@ void DesertPillars::create_pipeline() lighting.set_ambient(GL::Color(0.5)); // The skybox is rendered first - pipeline.add_pass("sky"); + pipeline.add_pass(0, sky_scene); - GL::Pipeline::Pass *pass = &pipeline.add_pass(0); + GL::Pipeline::Pass *pass = &pipeline.add_pass(0, shadow_scene); pass->set_lighting(&lighting); pass->set_depth_test(&GL::DepthTest::lequal()); @@ -341,9 +361,8 @@ void DesertPillars::create_pipeline() /* Initialize a second pipeline to render the environment map. It has the same renderables and passes, but no postprocessors or camera. */ - env_pipeline.add_renderable(sky_scene); - env_pipeline.add_pass("sky"); - pass = &env_pipeline.add_pass(0); + env_pipeline.add_pass(0, sky_scene); + pass = &env_pipeline.add_pass(0, shadow_scene); pass->set_lighting(&lighting); pass->set_depth_test(&GL::DepthTest::lequal()); } @@ -356,13 +375,7 @@ void DesertPillars::create_skybox() for(unsigned i=0; i<6; ++i) create_skybox_face(skybox_tex, skybox_tex.enumerate_faces(i)); - skybox_shprog.attach_shader_owned(new GL::VertexShader(skybox_vertex_src)); - skybox_shprog.attach_shader_owned(new GL::FragmentShader(skybox_fragment_src)); - skybox_shprog.bind_attribute(GL::VERTEX3, "vertex"); - skybox_shprog.bind_fragment_data(0, "frag_color"); - skybox_shprog.link(); - - GL::RenderPass &pass = skybox_tech.add_pass("sky"); + GL::RenderPass &pass = skybox_tech.add_pass(0); pass.set_shader_program(&skybox_shprog, 0); pass.set_texture(0, &skybox_tex); @@ -461,20 +474,14 @@ void DesertPillars::create_tiles_texture() bld.end(); } - GL::Program shprog(texture_vertex_src, texture_fragment_src); - shprog.bind_attribute(GL::VERTEX3, "vertex"); - shprog.bind_attribute(GL::NORMAL3, "normal"); - shprog.bind_attribute(GL::COLOR4_UBYTE, "color"); - shprog.bind_fragment_data(0, "frag_color"); - shprog.bind_fragment_data(1, "frag_normal"); - shprog.link(); + GL::Program shprog(texture_src); // Use an FBO to turn the geometry into a normalmapped texture GL::Framebuffer fbo; fbo.attach(GL::COLOR_ATTACHMENT0, tiles_texture); fbo.attach(GL::COLOR_ATTACHMENT1, tiles_normalmap); GL::Bind bind_fbo(fbo); - GL::Renderer renderer(0); + GL::Renderer renderer; renderer.set_shader_program(&shprog, 0); tiles.draw(renderer); } @@ -487,11 +494,11 @@ void DesertPillars::create_sand_texture() 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.set_generate_mipmap(true); + 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.set_generate_mipmap(true); + sand_normalmap.set_auto_generate_mipmap(true); unsigned char *pixels = new unsigned char[width*height*3]; unsigned char *bump = new unsigned char[width*height]; @@ -573,16 +580,6 @@ void DesertPillars::create_ground() create_tiles_texture(); create_sand_texture(); - GL::ProgramBuilder::StandardFeatures features; - features.lighting = true; - features.shadow = true; - features.texture = true; - features.normal_map = true; - features.custom = ground_variables; - GL::ProgramBuilder(features).add_shaders(ground_shprog); - ground_shprog.bind_attribute(7, "ground_type"); - ground_shprog.link(); - ground_shdata.uniform("texture1", 0); ground_shdata.uniform("normalmap1", 1); ground_shdata.uniform("texture2", 2); @@ -662,18 +659,10 @@ 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_ambient(GL::Color(0.9, 0.88, 0.8)); - - GL::ProgramBuilder::StandardFeatures features; - features.lighting = true; - features.material = true; - features.shadow = true; - GL::ProgramBuilder(features).add_shaders(pillar_shprog); - pillar_shprog.link(); + pillar_material.set_receive_shadows(true); GL::RenderPass *pass = &pillar_tech.add_pass(0); pass->set_material(&pillar_material); - pass->set_shader_program(&pillar_shprog, 0); pass = &pillar_tech.add_pass("shadow"); pass->set_shader_program(&shadow_shprog, 0); @@ -719,9 +708,9 @@ void DesertPillars::create_pillars() } // Create a square plinth and capitel - bld.matrix() = GL::Matrix::translation(0, 0, 0.3); + bld.set_matrix(GL::Matrix::translation(0, 0, 0.3)); GL::BoxBuilder(1.0, 1.0, 0.6).build(bld); - bld.matrix() = GL::Matrix::translation(0, 0, height+0.8); + bld.set_matrix(GL::Matrix::translation(0, 0, height+0.8)); GL::BoxBuilder(1.0, 1.0, 0.4).build(bld); pd.object = new GL::Object(pd.mesh, &pillar_tech); @@ -744,28 +733,10 @@ 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_ambient(GL::Color(0.5, 0.5, 0.55)); cube_material.set_specular(GL::Color(1.0)); cube_material.set_shininess(120); cube_material.set_reflectivity(0.5); - // First create a simplified shader for rendering the shadow map - GL::ProgramBuilder::StandardFeatures features; - features.custom = cube_variables; - GL::ProgramBuilder(features).add_shaders(cube_shadow_shprog); - cube_shadow_shprog.bind_attribute(7, "sphere_coord"); - cube_shadow_shprog.link(); - - // Then add the rest of the features for normal rendering - features.lighting = true; - features.specular = true; - features.material = true; - features.shadow = true; - features.reflection = true; - GL::ProgramBuilder(features).add_shaders(cube_shprog); - cube_shprog.bind_attribute(7, "sphere_coord"); - cube_shprog.link(); - GL::RenderPass *pass = &cube_tech.add_pass(0); pass->set_material(&cube_material); pass->set_shader_program(&cube_shprog, 0); @@ -888,9 +859,7 @@ void DesertPillars::tick() } display.tick(); - GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT); - pipeline.render(); - gl_context.swap_buffers(); + view.render(); } void DesertPillars::key_press(unsigned key) diff --git a/tools/viewer.cpp b/tools/viewer.cpp index d2a384f4..a1853e92 100644 --- a/tools/viewer.cpp +++ b/tools/viewer.cpp @@ -16,11 +16,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -48,6 +50,8 @@ private: Graphics::SimpleGLWindow window; Input::Mouse mouse; Resources resources; + GL::WindowView view; + GL::Pipeline pipeline; GL::Renderable *renderable; GL::AnimatedObject *anim_object; GL::AnimationPlayer *anim_player; @@ -86,6 +90,8 @@ private: Viewer::Viewer(int argc, char **argv): window(1024, 768, false), mouse(window), + view(window, window.get_gl_context()), + pipeline(view), renderable(0), anim_object(0), anim_player(0), @@ -177,6 +183,14 @@ Viewer::Viewer(int argc, char **argv): camera.set_up_direction(GL::Vector3(0, 0, 1)); update_camera(); + + GL::Pipeline::Pass &pass = pipeline.add_pass(0, *renderable); + pass.set_lighting(&lighting); + pass.set_depth_test(&GL::DepthTest::lequal()); + pass.set_blend(&GL::Blend::alpha()); + + view.set_content(&pipeline); + view.set_camera(&camera); } template @@ -219,16 +233,7 @@ void Viewer::tick() } window.tick(); - - GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT); - - GL::Bind bind_depth(GL::DepthTest::lequal()); - GL::Bind bind_blend(GL::Blend::alpha()); - GL::Renderer renderer(&camera); - renderer.set_lighting(&lighting); - renderable->render(renderer); - - window.swap_buffers(); + view.render(); } void Viewer::button_press(unsigned btn) -- 2.45.2