]> git.tdb.fi Git - libs/gl.git/blobdiff - demos/desertpillars.cpp
Add functions for setting arrays of 2x2 and 3x3 matrix uniforms
[libs/gl.git] / demos / desertpillars.cpp
index 0f148f7de28ebc4335eff4bef2bea967de51ab5d..cb06cd000bc05f32f3cb446133c08a555362e4fb 100644 (file)
@@ -30,7 +30,7 @@
 #include <msp/input/keyboard.h>
 #include <msp/input/keys.h>
 #include <msp/time/timestamp.h>
-#include <msp/time/units.h>
+#include <msp/time/timedelta.h>
 #include <msp/time/utils.h>
 
 using namespace std;
@@ -43,7 +43,7 @@ including:
 - Creating a mesh and then modifying it
 - Shadow mapping
 - Environment mapped reflections
-- Skybox
+- Skybox using a cube map texture
 - Nested scenes and pipelines
 - Complex multitexturing
 - Shader-based deformations
@@ -118,7 +118,6 @@ private:
        std::vector<ObjectData> pillar_data;
        std::vector<GL::AnimatedObject *> pillars;
 
-       GL::VertexShader cube_transform;
        GL::Program cube_shprog;
        GL::Program cube_shadow_shprog;
        GL::Material cube_material;
@@ -151,9 +150,8 @@ private:
        static const char texture_fragment_src[];
        static const char skybox_vertex_src[];
        static const char skybox_fragment_src[];
-       static const char ground_transform_src[];
-       static const char ground_colorify_src[];
-       static const char cube_transform_src[];
+       static const char ground_variables[];
+       static const char cube_variables[];
        static const float cube_shapes[];
 
 public:
@@ -183,86 +181,72 @@ private:
 };
 
 const char DesertPillars::texture_vertex_src[] =
-       "varying vec3 v_normal;\n"
-       "varying vec3 v_color;\n"
+       "#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"
        "void main()\n"
        "{\n"
-       "       gl_Position = vec4(gl_Vertex.xy*2.0-1.0, -gl_Vertex.z*2.0, 1.0);\n"
-       "       v_normal = gl_Normal;\n"
-       "       v_color = gl_Color.rgb;\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[] =
-       "varying vec3 v_normal;\n"
-       "varying vec3 v_color;\n"
+       "#version 130\n"
+       "in vec3 v_normal;\n"
+       "in vec3 v_color;\n"
+       "out vec4 frag_color;\n"
+       "out vec4 frag_normal;\n"
        "void main()\n"
        "{\n"
-       "       gl_FragData[0] = vec4(v_color, 1.0);\n"
-       "       gl_FragData[1] = vec4(v_normal*0.5+0.5, 1.0);\n"
+       "       frag_color = vec4(v_color, 1.0);\n"
+       "       frag_normal = vec4(v_normal*0.5+0.5, 1.0);\n"
        "}\n";
 
 const char DesertPillars::skybox_vertex_src[] =
-       "#version 120\n"
-       "varying vec3 v_texcoord;\n"
+       "#version 130\n"
+       "uniform mat4 projection_matrix;\n"
+       "uniform mat4 eye_obj_matrix;\n"
+       "in vec3 vertex;\n"
+       "out vec3 v_texcoord;\n"
        "void main()\n"
        "{\n"
-       "       gl_Position = gl_ProjectionMatrix*vec4(mat3(gl_ModelViewMatrix)*gl_Vertex.xyz, 1.0);\n"
-       "       v_texcoord = gl_Vertex.xyz;\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"
-       "varying vec3 v_texcoord;\n"
+       "in vec3 v_texcoord;\n"
+       "out vec4 frag_color;\n"
        "void main()\n"
        "{\n"
-       "       gl_FragColor = textureCube(sky, v_texcoord);\n"
+       "       frag_color = textureCube(sky, v_texcoord);\n"
        "}";
 
-// This exists only to transfer the ground type to fragment shader
-const char DesertPillars::ground_transform_src[] =
-       "attribute float ground_type;\n"
-       "varying float v_ground_type;\n"
-       "vec4 transform_vertex(vec4 vertex)\n"
-       "{\n"
-       "       v_ground_type = ground_type;\n"
-       "       return gl_ModelViewMatrix*vertex;\n"
-       "}\n"
-       "vec3 transform_normal(vec3 normal)\n"
-       "{\n"
-       "       return gl_NormalMatrix*normal;\n"
-       "}\n";
-
-const char DesertPillars::ground_colorify_src[] =
+const char DesertPillars::ground_variables[] =
        "uniform sampler2D texture1;\n"
        "uniform sampler2D normalmap1;\n"
        "uniform sampler2D texture2;\n"
        "uniform sampler2D normalmap2;\n"
-       "varying float v_ground_type;\n"
-       "vec4 sample_texture(vec2 coord)\n"
-       "{\n"
-       "       return mix(texture2D(texture1, coord*3.0), texture2D(texture2, coord), v_ground_type);\n"
-       "}\n"
-       "vec3 sample_normalmap(vec2 coord)\n"
-       "{\n"
-       "       return mix(texture2D(normalmap1, coord*3.0).rgb, texture2D(normalmap2, coord).rgb, v_ground_type);\n"
-       "}\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 char DesertPillars::cube_transform_src[] =
+const char DesertPillars::cube_variables[] =
        "uniform float spherify;\n"
        "attribute vec3 sphere_coord;\n"
-       "vec4 transform_vertex(vec4 vertex)\n"
-       "{\n"
-       "       return gl_ModelViewMatrix*vec4(mix(vertex.xyz, sphere_coord, spherify), 1.0);\n"
-       "}\n"
-       "vec3 transform_normal(vec3 normal)\n"
-       "{\n"
-       "       return gl_NormalMatrix*normalize(mix(normal, normalize(sphere_coord), spherify));\n"
-       "}\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";
 
 const float DesertPillars::cube_shapes[] = { -0.4, 0.5, 1.0, 0.3 };
 
 
-DesertPillars::Options::Options(const Graphics::Display &display, int argc, char **argv)
+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");
@@ -270,7 +254,7 @@ DesertPillars::Options::Options(const Graphics::Display &display, int argc, char
 
        if(window_opts.fullscreen)
        {
-               const Graphics::VideoMode &mode = display.get_desktop_mode();
+               const Graphics::VideoMode &mode = dpy.get_desktop_mode();
                window_opts.width = mode.width;
                window_opts.height = mode.height;
        }
@@ -304,7 +288,7 @@ DesertPillars::DesertPillars(int argc, char **argv):
        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::mem_fun(this, &DesertPillars::key_press));
+       keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false));
 
        create_pipeline();
        create_skybox();
@@ -335,7 +319,6 @@ void DesertPillars::create_pipeline()
        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_texture_unit(5);
        sky_scene.add(shadow_scene);
        pipeline.add_renderable(sky_scene);
 
@@ -375,6 +358,8 @@ void DesertPillars::create_skybox()
 
        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");
@@ -477,6 +462,12 @@ void DesertPillars::create_tiles_texture()
                }
 
        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();
 
        // Use an FBO to turn the geometry into a normalmapped texture
        GL::Framebuffer fbo;
@@ -586,12 +577,9 @@ void DesertPillars::create_ground()
        features.lighting = true;
        features.shadow = true;
        features.texture = true;
-       features.normalmap = true;
-       features.transform = true;
-       features.colorify = true;
+       features.normal_map = true;
+       features.custom = ground_variables;
        GL::ProgramBuilder(features).add_shaders(ground_shprog);
-       ground_shprog.attach_shader_owned(new GL::VertexShader(ground_transform_src));
-       ground_shprog.attach_shader_owned(new GL::FragmentShader(ground_colorify_src));
        ground_shprog.bind_attribute(7, "ground_type");
        ground_shprog.link();
 
@@ -758,16 +746,13 @@ void DesertPillars::create_cube()
        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(150);
-
-       cube_transform.source(cube_transform_src);
-       cube_transform.compile();
+       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.transform = true;
+       features.custom = cube_variables;
        GL::ProgramBuilder(features).add_shaders(cube_shadow_shprog);
-       cube_shadow_shprog.attach_shader(cube_transform);
        cube_shadow_shprog.bind_attribute(7, "sphere_coord");
        cube_shadow_shprog.link();
 
@@ -778,7 +763,6 @@ void DesertPillars::create_cube()
        features.shadow = true;
        features.reflection = true;
        GL::ProgramBuilder(features).add_shaders(cube_shprog);
-       cube_shprog.attach_shader(cube_transform);
        cube_shprog.bind_attribute(7, "sphere_coord");
        cube_shprog.link();
 
@@ -936,9 +920,7 @@ DesertPillars::ObjectData::~ObjectData()
 
 DesertPillars::Cube::Cube(const GL::Object &obj):
        GL::AnimatedObject(obj)
-{
-       shdata.uniform("reflectivity", 0.5f);
-}
+{ }
 
 void DesertPillars::Cube::set_spherify(float s)
 {