X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=demos%2Fdesertpillars.cpp;fp=demos%2Fdesertpillars.cpp;h=0000000000000000000000000000000000000000;hp=d741beea5390b0eb8307fdb78d401fb47c62b314;hb=8033bd7822b4f24d86be186c47ba7e6d69931eeb;hpb=57232117bfab90f5dd80131daa47d2f184de9ae2 diff --git a/demos/desertpillars.cpp b/demos/desertpillars.cpp deleted file mode 100644 index d741beea..00000000 --- a/demos/desertpillars.cpp +++ /dev/null @@ -1,921 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace Msp; - -/** -This application demonstrates a variety of features of the mspgl library, -including: -- Creating meshes from multiple parts -- Creating a mesh and then modifying it -- Shadow mapping -- Environment mapped reflections -- Skybox using a cube map texture -- Effects with nested sequences -- Complex multitexturing -- Shader-based deformations -- Creating a normalmapped texture through rendering - -To run the program in fullscreen mode, specify --fullscreen on the command -line. - -During execution the following keys are available: -esc exit -space stop camera movement -s stop cube rotation -f freeze cube shape -*/ -class DesertPillars: public RegisteredApplication -{ -private: - struct Options - { - Graphics::WindowOptions window_opts; - - Options(const Graphics::Display &, int, char **); - }; - - struct ObjectData - { - GL::Mesh *mesh; - GL::Object *object; - - ObjectData(); - ~ObjectData(); - }; - - class Cube: public GL::AnimatedObject - { - private: - GL::ProgramData shdata; - - public: - Cube(const GL::Object &); - - void set_spherify(float); - - virtual void setup_render(GL::Renderer &, const GL::Tag &) const; - }; - - Msp::Graphics::Display display; - Options options; - 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; - - const GL::Program &shadow_shprog; - - GL::Program ground_shprog; - GL::ProgramData ground_shdata; - GL::Texture2D tiles_texture; - 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; - - 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::BasicMaterial cube_material; - GL::Technique cube_tech; - ObjectData cube_data; - Cube *cube; - GL::EnvironmentMap *env_cube; - - GL::WindowView view; - GL::Sequence sequence; - GL::Camera camera; - GL::SimpleScene sky_scene; - GL::InstanceScene scene; - GL::Lighting lighting; - GL::Light light; - GL::ShadowMap shadow_scene; - GL::Bloom bloom; - GL::ColorCurve colorcurve; - - GL::Sequence env_sequence; - - Time::TimeStamp last_tick; - float camera_angle; - bool camera_stopped; - float cube_angle; - bool cube_stopped; - unsigned cube_shape; - float cube_phase; - bool cube_frozen; - - 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: - DesertPillars(int, char **); - ~DesertPillars(); - -private: - void setup_view(); - void create_sequence(); - void create_skybox(); - static void create_skybox_face(GL::TextureCube &, GL::TextureCubeFace); - void create_tiles_texture(); - void create_sand_texture(); - static void gaussian_blur(unsigned char *, unsigned, unsigned); - static void create_normalmap(const unsigned char *, unsigned char *, unsigned, unsigned, float); - void create_ground(); - static float ground_height(float, float); - void create_pillars(); - void create_cube(); - static void create_cube_face(GL::MeshBuilder &, const GL::Vector3 &, const GL::Vector3 &, const GL::Vector3 &, unsigned); - -public: - virtual int main(); -private: - virtual void tick(); - - void key_press(unsigned); -}; - -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" - " passthrough;\n" - "}\n" - "#pragma MSP stage(fragment)\n" - "layout(location=1) out vec4 frag_normal;\n" - "void main()\n" - "{\n" - " frag_color = color;\n" - " frag_normal = vec4(normal*0.5+0.5, 1.0);\n" - "}\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.xyz, 1.0);\n" - " passthrough;\n" - "}\n" - "#pragma MSP stage(fragment)\n" - "void main()\n" - "{\n" - " frag_color = texture(sky, vertex.xyz);\n" - "}\n"; - -const char DesertPillars::ground_src[] = - "import phong;\n" - "uniform sampler2D texture1;\n" - "uniform sampler2D normalmap1;\n" - "uniform sampler2D texture2;\n" - "uniform sampler2D normalmap2;\n" - "const bool use_normal_map = true;\n" - "const bool use_shadow_map = true;\n" - "#pragma MSP stage(vertex)\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() override\n" - "{\n" - " return mix(texture(texture1, texcoord.xy*3.0), texture(texture2, texcoord.xy), ground_type);\n" - "}\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"; - -const char DesertPillars::cube_src[] = - "import phong;\n" - "const bool use_specular = true;\n" - "const bool use_reflectivity = true;\n" - "uniform float spherify;\n" - "#pragma MSP stage(vertex)\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) override\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 }; - - -DesertPillars::Options::Options(const Graphics::Display &dpy, int argc, char **argv) -{ - GetOpt getopt; - getopt.add_option('f', "fullscreen", window_opts.fullscreen, GetOpt::NO_ARG).set_help("Run in fullscreen mode"); - getopt(argc, argv); - - if(window_opts.fullscreen) - { - const Graphics::VideoMode &mode = dpy.get_desktop_mode(); - window_opts.width = mode.width; - window_opts.height = mode.height; - } - else - { - window_opts.width = 800; - window_opts.height = 600; - } -} - - -DesertPillars::DesertPillars(int argc, char **argv): - options(display, argc, argv), - window(display, options.window_opts), - gl_context(window), - keyboard(window), - skybox_shprog(skybox_src), - 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), - 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), - cube_stopped(false), - cube_shape(0), - cube_phase(0), - cube_frozen(false) -{ - window.set_title("Desert Pillars"); - window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &DesertPillars::exit), 0)); - if(options.window_opts.fullscreen) - window.show_cursor(false); - keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false)); - - setup_view(); - create_sequence(); - create_skybox(); - create_ground(); - create_pillars(); - create_cube(); -} - -DesertPillars::~DesertPillars() -{ - delete env_cube; - delete cube; - for(vector::iterator i=pillars.begin(); i!=pillars.end(); ++i) - delete *i; -} - -void DesertPillars::setup_view() -{ - 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); - view.set_camera(&camera); - view.set_content(&sequence); -} - -void DesertPillars::create_sequence() -{ - 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 - 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.2)); - - // The skybox is rendered first - sequence.add_pass(0, sky_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); - 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(); - sequence.add_postprocessor(colorcurve); - - /* Initialize a second sequence to render the environment map. It has the - same renderables and passes, but no postprocessors or camera. */ - 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::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, &linear_clamped_sampler); - - // The shader will use the vertex coordinates to initialize texture coordinates as well - skybox_data.mesh = new GL::Mesh(GL::VERTEX3); - GL::BoxBuilder(10, 10, 10).build(*skybox_data.mesh); - skybox_data.object = new GL::Object(skybox_data.mesh, &skybox_tech); - - sky_scene.add(*skybox_data.object); -} - -void DesertPillars::create_skybox_face(GL::TextureCube &texture, GL::TextureCubeFace face) -{ - unsigned char *pixels = new unsigned char[128*128*3]; - for(int y=0; y<128; ++y) - for(int x=0; x<128; ++x) - { - unsigned i = (x+y*128)*3; - GL::Vector3 v = texture.get_texel_direction(face, x, y); - if(v.z>0) - { - float l = sqrt(v.x*v.x+v.y*v.y+v.z*v.z); - // Render a sky-like gradient, with deeper blue at the zenith - pixels[i] = 96-48*v.z/l; - pixels[i+1] = 168-84*v.z/l; - pixels[i+2] = 255; - } - else - { - // Fill with a desert-y color below horizon - pixels[i] = 240; - pixels[i+1] = 224; - pixels[i+2] = 160; - } - } - texture.image(face, 0, pixels); - delete[] pixels; -} - -void DesertPillars::create_tiles_texture() -{ - unsigned width = 256; - unsigned height = 256; - 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)); - - // Prepare some lookup tables for rendering the tiles - float split = 1.0f/3; - float spacing = split*0.02f; - float bevel = split*0.1f; - float coords[] = { 0.0f, spacing, spacing+bevel, split-bevel, split, split+spacing, split+spacing+bevel, 1.0f-bevel, 1.0f }; - unsigned order[] = { 4, 1, 3, 2, 1, 1, 2, 2, - 1, 4, 2, 3, 4, 4, 3, 3, - 1, 1, 2, 2, 1, 4, 2, 3, - 4, 4, 3, 3, 4, 1, 3, 2, - 2, 3, 2, 2, 3, 3, 3, 2 }; - - { - GL::MeshBuilder bld(tiles); - - // Create a dark background - bld.color(0.2f, 0.2f, 0.2f); - bld.normal(0.0f, 0.0f, 1.0f); - bld.begin(GL::TRIANGLE_STRIP); - bld.vertex(0.0f, 1.0f); - bld.vertex(0.0f, 0.0f); - bld.vertex(1.0f, 1.0f); - bld.vertex(1.0f, 0.0f); - bld.end(); - - // Create the four tiles - 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) - { - for(unsigned k=0; k<4; ++k) - { - bld.begin(GL::TRIANGLE_STRIP); - float facing = (k%2)*2-1.0f; - if(k<2) - bld.normal(0.0f, 0.7071f*facing, 0.7071f); - else - bld.normal(0.7071f*facing, 0.0f, 0.7071f); - for(unsigned l=0; l<4; ++l) - bld.vertex(coords[i*4+order[k*8+l*2]], coords[j*4+order[k*8+l*2+1]], (l%2 ? bevel : 0.0f)); - bld.end(); - } - - bld.begin(GL::TRIANGLE_STRIP); - bld.normal(0.0f, 0.0f, 1.0f); - for(unsigned l=0; l<4; ++l) - 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); - - // 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; - renderer.set_shader_program(&shprog, 0); - tiles.draw(renderer); -} - -void DesertPillars::create_sand_texture() -{ - unsigned width = 512; - unsigned height = 512; - - sand_texture.storage(GL::SRGB8, width/16, height/16); - sand_texture.set_auto_generate_mipmap(true); - 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]; - for(unsigned y=0; yset_shader_program(&ground_shprog, &ground_shdata); - 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::GENERIC1); - ground_data.mesh = new GL::Mesh(vfmt); - - // Create a base grid - GL::GridBuilder(80, 80, 200, 200).tbn().build(*ground_data.mesh); - - // And modify it with a heightmap - unsigned n_vertices = ground_data.mesh->get_n_vertices(); - unsigned pos = vfmt.offset(GL::VERTEX3); - unsigned nor = vfmt.offset(GL::NORMAL3); - unsigned tan = vfmt.offset(GL::TANGENT3); - unsigned bin = vfmt.offset(GL::BINORMAL3); - unsigned tex = vfmt.offset(GL::TEXCOORD2); - unsigned gt = vfmt.offset(GL::GENERIC1); - for(unsigned i=0; imodify_vertex(i); - v[pos+2] = ground_height(v[pos], v[pos+1]); - - float dz_x = (ground_height(v[pos]+0.01, v[pos+1])-ground_height(v[pos]-0.01, v[pos+1]))/0.02; - float dz_y = (ground_height(v[pos], v[pos+1]+0.01)-ground_height(v[pos], v[pos+1]-0.01))/0.02; - float l = sqrt(dz_x*dz_x+dz_y*dz_y+1); - v[nor] = -dz_x/l; - v[nor+1] = -dz_y/l; - v[nor+2] = 1/l; - - l = sqrt(dz_x*dz_x+1); - v[tan] = 1/l; - v[tan+2] = dz_x/l; - - l = sqrt(dz_y*dz_y+1); - v[bin+1] = 1/l; - v[bin+2] = dz_y/l; - - v[gt] = min(v[pos+2]*100, 1.0f); - - v[tex] *= 20; - v[tex+1] *= 20; - } - ground_data.object = new GL::Object(ground_data.mesh, &ground_tech); - - scene.add(*ground_data.object); -} - -float DesertPillars::ground_height(float x, float y) -{ - // Leave a flat area in the middle - float d = sqrt(x*x+y*y); - if(d<=6.0f) - return 0; - - // This results in concentric rings of low hills - int i = (d-6)/(M_PI*2); - float a = atan2(y, x); - a *= i*2+5; - a += M_PI*(i%3)/2; - float h = (i%2) ? 0.5 : 0.3; - return (d-6)*0.001f+(1-cos(d-6))*(1-cos(a))*h; -} - -void DesertPillars::create_pillars() -{ - // The pillars are a matt off-white - 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); - pass->set_material(&pillar_material, &resources); - - pass = &pillar_tech.add_pass("shadow"); - pass->set_shader_program(&shadow_shprog, 0); - - pillar_data.reserve(7); - for(unsigned i=3; i<=20; ++i) - { - unsigned height = 2; - for(unsigned j=2; jset_matrix(matrix); - - pillars.push_back(pillar); - scene.add(*pillar); - } -} - -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).to_linear()); - cube_material.set_specular(GL::Color(1.0)); - cube_material.set_shininess(120); - cube_material.set_reflectivity(0.5); - - GL::RenderPass *pass = &cube_tech.add_pass(0); - 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::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()); - create_cube_face(bld, GL::Vector3(-1, 1, -1), GL::Vector3(2, 0, 0), GL::Vector3(0, 0, 2), 16); - bld.offset(cube_data.mesh->get_n_vertices()); - 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()); - create_cube_face(bld, GL::Vector3(1, -1, -1), GL::Vector3(-2, 0, 0), GL::Vector3(0, 0, 2), 16); - bld.offset(cube_data.mesh->get_n_vertices()); - create_cube_face(bld, GL::Vector3(-1, -1, 1), GL::Vector3(0, 0, -2), GL::Vector3(0, 2, 0), 16); - bld.offset(cube_data.mesh->get_n_vertices()); - create_cube_face(bld, GL::Vector3(1, -1, -1), GL::Vector3(0, 0, 2), GL::Vector3(0, 2, 0), 16); - cube_data.object = new GL::Object(cube_data.mesh, &cube_tech); - - cube = new Cube(*cube_data.object); - env_cube = new GL::EnvironmentMap(resources, 512, *cube, env_sequence); - scene.add(*env_cube); -} - -void DesertPillars::create_cube_face(GL::MeshBuilder &bld, const GL::Vector3 &base, const GL::Vector3 &side1, const GL::Vector3 &side2, unsigned div) -{ - /* The sides follow the cube map convention where the cross product points - inwards. Since the normal has to point outwards, reverse the order. */ - GL::Vector3 n; - n.x = side2.y*side1.z-side2.z*side1.y; - n.y = side2.z*side1.x-side2.x*side1.z; - n.z = side2.x*side1.y-side2.y*side1.x; - float l = sqrt(n.x*n.x+n.y*n.y+n.z*n.z); - bld.normal(n.x/l, n.y/l, n.z/l); - - // Create vertices, with precomputed spherified coordinates - for(unsigned i=0; i<=div; ++i) - for(unsigned j=0; j<=div; ++j) - { - GL::Vector3 v; - v.x = base.x+side1.x*i/div+side2.x*j/div; - v.y = base.y+side1.y*i/div+side2.y*j/div; - v.z = base.z+side1.z*i/div+side2.z*j/div; - - l = sqrt(v.x*v.x+v.y*v.y+v.z*v.z); - l /= 1.732; - bld.generic(0, v.x/l, v.y/l, v.z/l); - - bld.vertex(v); - } - - for(unsigned i=0; iM_PI*4) - camera_angle -= M_PI*4; - float h = 3+(1-cos(camera_angle*1.5))*3; - float r = sqrt(225-h*h); - camera.set_position(GL::Vector3(cos(camera_angle)*r, sin(camera_angle)*r, 1.5+h)); - camera.look_at(GL::Vector3(0, 0, 2)); - } - - if(!cube_stopped) - { - cube_angle += (dt/Time::sec)*M_PI*2/20; - GL::Matrix cube_matrix; - cube_matrix.translate(0, 0, 2.5); - cube_matrix.rotate(cube_angle, 0, 0, 1); - cube_matrix.rotate(cube_angle*0.5, 1, 0, 0); - cube->set_matrix(cube_matrix); - } - - if(!cube_frozen) - { - cube_phase += (dt/Time::sec)/5; - if(cube_phase>1) - { - cube_phase -= 1; - ++cube_shape; - if(cube_shape>=4) - cube_shape -= 4; - } - if(cube_phase<0.2) - { - float x = cube_phase*5; - x = (3-2*x)*x*x; - cube->set_spherify((1-x)*cube_shapes[(cube_shape+3)%4]+x*cube_shapes[cube_shape]); - } - else - cube->set_spherify(cube_shapes[cube_shape]); - } - - display.tick(); - view.render(); -} - -void DesertPillars::key_press(unsigned key) -{ - if(key==Input::KEY_ESC) - exit(0); - else if(key==Input::KEY_SPACE) - camera_stopped = !camera_stopped; - else if(key==Input::KEY_F) - cube_frozen = !cube_frozen; - else if(key==Input::KEY_S) - cube_stopped = !cube_stopped; -} - - -DesertPillars::ObjectData::ObjectData(): - mesh(0), - object(0) -{ } - -DesertPillars::ObjectData::~ObjectData() -{ - delete object; - delete mesh; -} - - -DesertPillars::Cube::Cube(const GL::Object &obj): - GL::AnimatedObject(obj) -{ } - -void DesertPillars::Cube::set_spherify(float s) -{ - shdata.uniform("spherify", s); -} - -void DesertPillars::Cube::setup_render(GL::Renderer &renderer, const GL::Tag &tag) const -{ - AnimatedObject::setup_render(renderer, tag); - renderer.add_shader_data(shdata); -}