fixed terrain rendering - visualized normals
authorEleni Maria Stea <estea@igalia.com>
Sat, 19 Aug 2017 16:55:30 +0000 (19:55 +0300)
committerEleni Maria Stea <estea@igalia.com>
Sat, 19 Aug 2017 16:55:30 +0000 (19:55 +0300)
19 files changed:
gl_shaders/debug.f.glsl [new file with mode: 0644]
gl_shaders/debug.v.glsl [new file with mode: 0644]
gl_shaders/default.f.glsl
src/main.cc
src/mesh.h
src/meshgen.cc
src/opengl/mesh-gl.cc
src/opengl/mesh-gl.h
src/opengl/texture-gl.cc
src/opengl/texture-gl.h
src/renderer.cc
src/renderer.h
src/terrain.cc
src/terrain.h
src/texture.h
src/vulkan/mesh-vk.cc
src/vulkan/mesh-vk.h
src/vulkan/texture-vk.cc
src/vulkan/texture-vk.h

diff --git a/gl_shaders/debug.f.glsl b/gl_shaders/debug.f.glsl
new file mode 100644 (file)
index 0000000..79bdba6
--- /dev/null
@@ -0,0 +1,8 @@
+#version 450
+
+out vec4 color;
+
+void main()
+{
+       color = vec4(1.0, 0.0, 1.0, 1.0);
+}
diff --git a/gl_shaders/debug.v.glsl b/gl_shaders/debug.v.glsl
new file mode 100644 (file)
index 0000000..8ec32dd
--- /dev/null
@@ -0,0 +1,10 @@
+#version 450
+
+uniform mat4 mmviewproj;
+
+layout(location = 1) in vec3 attr_pos;
+
+void main()
+{
+       gl_Position = mmviewproj * vec4(attr_pos, 1.0);
+}
index 490efab..98cf032 100644 (file)
@@ -26,6 +26,7 @@ void main()
        float cspec = pow(max(dot(r, vdir), 0.0), shininess);
 
        vec4 texel = texture2D(tex, tex_coord);
-       color.xyz = diffuse.xyz * cdiff * texel.xyz + specular.xyz * cspec;
+       //color.xyz = diffuse.xyz * cdiff * texel.xyz + specular.xyz * cspec;
+       color.xyz = diffuse.xyz * cdiff + specular.xyz * cspec;
        color.w = 1.0;
 }
index 166b467..933bd62 100644 (file)
@@ -16,6 +16,7 @@
 #include "object.h"
 #include "renderer.h"
 #include "scene.h"
+#include "terrain.h"
 #include "texture.h"
 
 #include "opengl/opengl.h"
@@ -60,6 +61,10 @@ static Scene *scene_ground;
 static Renderer *rground; // default renderer
 static Texture *gskybox;
 
+static Renderer *tr;
+static Material tmat;
+static Terrain t;
+
 /* *** */
 
 int main(int argc, char **argv)
@@ -116,11 +121,24 @@ static bool init(Gfx_API api)
        camera = new OrbitCamera;
        camera->set_orbit_params(phi, theta, dist);
 
-       scene_ground = new Scene;
-       if(!scene_ground->load("data/ground.obj")) {
-               fprintf(stderr, "Failed to load scene: ground.obj.\n");
-               return false;
-       }
+       // scene_ground = new Scene;
+       // if(!scene_ground->load("data/ground.obj")) {
+       //      fprintf(stderr, "Failed to load scene: ground.obj.\n");
+       //      return false;
+       // }
+
+       // rground = new Renderer;
+       // rground->camera = camera;
+       // rground->scene = scene_ground;
+
+       // if(!rground->create()) {
+       //      fprintf(stderr, "Failed to create default renderer.\n");
+       //      return false;
+       // }
+
+       // gskybox = gfx_create_texture();
+       // gskybox->load("data/cubemap/cubemap.hdr");
+       // rground->set_sky_tex(gskybox);
 
        scene_cow = new Scene;
        if(!scene_cow->load("data/spot/spot.obj")) {
@@ -128,19 +146,6 @@ static bool init(Gfx_API api)
                return false;
        }
 
-       rground = new Renderer;
-       rground->camera = camera;
-       rground->scene = scene_ground;
-
-       if(!rground->create()) {
-               fprintf(stderr, "Failed to create default renderer.\n");
-               return false;
-       }
-
-       gskybox = gfx_create_texture();
-       gskybox->load("data/cubemap/cubemap.hdr");
-       rground->set_sky_tex(gskybox);
-
        rcow = new Renderer;
        rcow->camera = camera;
        rcow->scene = scene_cow;
@@ -150,14 +155,46 @@ static bool init(Gfx_API api)
                return false;
        }
 
-// TODO delete: debugging
-       for(size_t i=0; i<scene_ground->objects.size(); ++i) {
-               printf("object: %d\n", (int)i);
-               printf("mesh: %s\n", scene_ground->objects[i]->mesh->name.c_str());
-               printf("material: %s\n", scene_ground->objects[i]->material->name.c_str());
-               printf("transform:\n");
-               scene_ground->objects[i]->transform.print();
+       TerrainParams p;
+       p.xsz = 50;
+       p.ysz = 50;
+       p.max_height = 1;
+       p.xtiles = 1; //40;
+       p.ytiles = 1; // 40;
+       p.tile_usub = 8;
+       p.tile_vsub = 8;
+       p.num_octaves = 3;
+       p.noise_freq = 10;
+       p.coarse_heightmap = 0;
+
+       t.init();
+       t.generate(p);
+
+       tmat.diffuse = Vec3(1, 0, 0);
+       tmat.specular = Vec3(0.5, 0, 0);
+       tmat.shininess = 40;
+       tmat.dtex = 0;
+       tmat.name = "tt";
+
+       t.material = tmat;
+
+       tr = new Renderer;
+       tr->camera = camera;
+       tr->scene = t.get_visible(camera);
+       if(!tr->create()) {
+               fprintf(stderr, "terrain fail\n");
+               return false;
        }
+
+
+// TODO delete: debugging
+       // for(size_t i=0; i<scene_ground->objects.size(); ++i) {
+       //      printf("object: %d\n", (int)i);
+       //      printf("mesh: %s\n", scene_ground->objects[i]->mesh->name.c_str());
+       //      printf("material: %s\n", scene_ground->objects[i]->material->name.c_str());
+       //      printf("transform:\n");
+       //      scene_ground->objects[i]->transform.print();
+       // }
        return true;
 }
 
@@ -169,9 +206,11 @@ static void cleanup()
        delete scene_cow;
        delete rcow;
 
-       delete scene_ground;
-       delete rground;
+       // delete scene_ground;
+       // delete rground;
 
+//TODO
+       delete tr;
        gfx_cleanup();
 }
 
@@ -231,8 +270,10 @@ static void display()
 {
        camera->set_orbit_params(phi, theta, dist);
 
-       gfx_clear(0.76, 0.3, 0.43);
+       // gfx_clear(0.76, 0.3, 0.43);
+       gfx_clear(0.1, 0.1, 0.1);
 
-       rground->draw();
-       rcow->draw();
+       tr->draw();
+//     rground->draw();
+       // rcow->draw();
 }
\ No newline at end of file
index ed40f5d..82f5c48 100644 (file)
@@ -29,6 +29,7 @@ public:
        virtual ~Mesh() = 0;
 
        virtual void draw() const = 0;
+       virtual void draw_normals(float scale) const = 0;
        virtual void update_vertex_data() = 0;
 };
 
index ff7906d..9547cee 100644 (file)
@@ -129,7 +129,7 @@ static Vec3 hfield_vertex(float u, float v, float h, float xsz,
 {
        float x = u * xsz - xsz / 2.0;
        float y = h * height;
-       float z = v * ysz - ysz / 2.0;
+       float z = -(v * ysz - ysz / 2.0);
 
        return Vec3(x, y, z);
 }
@@ -202,7 +202,6 @@ void gen_heightfield(Mesh *mesh, float xsz, float ysz, float height, int usub,
                        int c = d + 1;
 
                        /* 1st triangle */
-
                        *iptr++ = a;
                        *iptr++ = b;
                        *iptr++ = c;
index 4707f11..f0956b4 100644 (file)
@@ -15,6 +15,9 @@ MeshGL::MeshGL()
 
        num_vertices = 0;
        num_indices = 0;
+
+       /* draw normals */
+       nvao = nvbo = 0;
 }
 
 MeshGL::MeshGL(const MeshGL &mesh)
@@ -30,6 +33,9 @@ MeshGL::MeshGL(const MeshGL &mesh)
        ibo = 0;
        vao = 0;
 
+       /* draw normals */
+       nvao = nvbo = 0;
+
        /*
         * if we set these to the actual
         * vertices.size() and indices.size()
@@ -76,6 +82,36 @@ void MeshGL::draw() const
        glBindVertexArray(0);
 }
 
+void MeshGL::draw_normals(float scale) const
+{
+       if(!nvao) {
+               glGenVertexArrays(1, &nvao);
+               glBindVertexArray(nvao);
+
+               glGenBuffers(1, &nvbo);
+               glBindBuffer(GL_ARRAY_BUFFER, nvbo);
+               
+               glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(Vec3) * 2, 0, GL_STATIC_DRAW);
+               Vec3 *data = (Vec3 *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+               for (size_t i = 0; i < normals.size(); i++)
+               {
+                       *data++ = vertices[i];
+                       *data++ = vertices[i] + normals[i] * scale;
+               }
+               glUnmapBuffer(GL_ARRAY_BUFFER);
+
+               glVertexAttribPointer(MESH_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
+               glEnableVertexAttribArray(MESH_VERTEX);
+               glBindBuffer(GL_ARRAY_BUFFER, 0);
+       } else {
+               glBindVertexArray(nvao);
+       }
+
+       glDrawArrays(GL_LINES, 0, normals.size() * 2);
+       glBindVertexArray(0);
+}
+
 void MeshGL::update_vertex_data()
 {
        update_vbo();
@@ -164,6 +200,12 @@ void MeshGL::destroy_vbo()
        if(vbo_tex_coords)
                glDeleteBuffers(1, &vbo_tex_coords);
        if(ibo)
-               if(vao)
-                       glDeleteVertexArrays(1, &vao);
+               glDeleteBuffers(1, &ibo);
+       if (vao)
+               glDeleteVertexArrays(1, &vao);
+
+       if(nvbo)
+               glDeleteBuffers(1, &nvbo);
+       if(nvao)
+               glDeleteVertexArrays(1, &nvao);
 }
\ No newline at end of file
index 78d415a..833e2db 100644 (file)
@@ -18,6 +18,10 @@ private:
 
        void update_vbo();
 
+       /* used by draw_normals to debug stuff: */
+       mutable unsigned int nvao;
+       mutable unsigned int nvbo;
+
 public:
        MeshGL();
        MeshGL(const MeshGL &mesh);
@@ -26,9 +30,10 @@ public:
        virtual ~MeshGL();
 
        virtual void draw() const override;
+       virtual void draw_normals(float scale) const override;
        virtual void update_vertex_data() override;
 
        void destroy_vbo();
 };
 
-#endif // MESH_GL_H_
+#endif // MESH_GL_H_
\ No newline at end of file
index 2fbd05e..157d0bb 100644 (file)
@@ -60,4 +60,10 @@ void TextureGL::bind()
 {
        unsigned int target = is_cubemap() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
        glBindTexture(target, tex);
+}
+
+void TextureGL::unbind()
+{
+       unsigned int target = is_cubemap() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+       glBindTexture(target, 0);
 }
\ No newline at end of file
index a08f159..aa2b3db 100644 (file)
@@ -14,6 +14,7 @@ public:
        virtual ~TextureGL();
 
        virtual void bind() override;
+       virtual void unbind() override;
 };
 
 #endif // TEXTURE_GL_H_
index e11b973..2f50d0b 100644 (file)
@@ -36,6 +36,11 @@ Renderer::~Renderer()
 
 bool Renderer::create()
 {
+       //debug
+       if(!(nprog = sdr_man->create_shader_program("debug.v.glsl", "debug.f.glsl"))) {
+               fprintf(stderr, "Failed to load debug shaders.\n");
+       }
+
        if(!(sprog = sdr_man->create_shader_program("default.v.glsl", "default.f.glsl"))) {
                return false;
        }
@@ -116,6 +121,19 @@ void Renderer::draw_object(Object *object) const
 
        object->mesh->update_vertex_data();
        object->mesh->draw();
+
+       /* debug */
+       if(nprog) {
+               int loc = nprog->get_uniform_location("mmviewproj");
+               if(loc != -1) {
+                       nprog->set_uniform_matrix(loc, mmviewproj);
+               }
+               nprog->use();
+               object->mesh->draw_normals(1.0);
+       }
+
+       // if(m->dtex)
+       //      m->dtex->unbind();
 }
 
 void Renderer::set_sky_tex(Texture *stex)
index a218dab..c3fb0bf 100644 (file)
@@ -16,6 +16,9 @@ protected:
 
        ShaderProgram *sprog;
 
+       /* debug shader to draw normals */
+       ShaderProgram *nprog;
+
        Texture *skytex, *dskytex;
 
        virtual void draw_object(Object *object) const;
index 6bfabe8..bdd787f 100644 (file)
@@ -1,39 +1,85 @@
+#include <gmath/gmath.h>
+
 #include "camera.h"
+#include "gfxapi.h"
 #include "image.h"
+#include "mesh.h"
+#include "meshgen.h"
+#include "object.h"
 #include "scene.h"
 #include "terrain.h"
 
-Terrain::Terrain() {}
+static float calc_height(float u, float v, void *ptr);
+
+Terrain::Terrain()
+{
+       vis_scene = 0;
+}
 
 Terrain::~Terrain()
 {
 }
 
+bool Terrain::init()
+{
+       vis_scene = new Scene;
+
+       return true;
+}
+
+void Terrain::destroy()
+{
+       delete vis_scene;
+}
+
 bool Terrain::generate(const TerrainParams &params)
 {
-       // if(xsz <= 0 || ysz <=0) {
-       //      fprintf(stderr, "Invalid terrain size.\n");
-       //      return false;
-       // }
+       tiles.clear();
 
-       // if(xtiles <= 0 || ytiles <= 0) {
-       //      fprintf(stderr, "Invalid number of terrain tiles.\n");
-       //      return false;
-       // }
+       float txsz = params.xsz / params.xtiles;
+       float tysz = params.ysz / params.ytiles;
 
-       // if(tiles)
-       //      tiles.clear();
+       for(int i=0; i<params.ytiles; i++) {
+               for(int j=0; j<params.xtiles; j++) {
+                       TerrainTile tile;
+                       tile.mesh = gfx_create_mesh();
 
-       // int tsz = xtiles * ytiles;
-       // tiles.resize(tsz);
+                       gen_heightfield(tile.mesh, txsz, tysz, params.max_height,
+                                       params.tile_usub, params.tile_vsub, calc_height,
+                                       (void*)&params);
 
-       // for(int i=0; i<tsz; i++) {
+                       tile.mesh->update_vertex_data();
+                       tiles.push_back(tile);
 
-       // }
+/*
+       the terrain scene stores objects only
+       no need to fill the mat, mesh std::vectors
+*/
+                       Object *o = new Object;
+                       o->mesh = tile.mesh;
+                       o->material = &material;
+                       o->transform = Mat4::identity;
+
+                       vis_scene->objects.push_back(o);
+               }
+       }
        return true;
 }
 
 Scene *Terrain::get_visible(const Camera *camera) const
 {
-       return 0;
+       return vis_scene;
 }
+
+static float calc_height(float u, float v, void *ptr)
+{
+       if(!ptr) {
+               fprintf(stderr, "Terrain parameters not found.\n");
+               return 0;
+       }
+
+       TerrainParams *tp = (TerrainParams*)ptr;
+       float sn = gph::fbm(u * tp->noise_freq, v * tp->noise_freq, tp->num_octaves);
+       /* todo use the image later */
+       return sn;
+}
\ No newline at end of file
index f2ecd69..bf9df09 100644 (file)
@@ -10,6 +10,7 @@ class TerrainTile {
 private:
        Mesh *mesh;
 
+       friend class Terrain;
 };
 
 /* parameters needed in terrain generation */
@@ -23,6 +24,7 @@ struct TerrainParams {
        int tile_usub;
        int tile_vsub;
        int num_octaves; /* Perlin noise sums */
+       float noise_freq; /* Perlin noise scaling factor */
        Image *coarse_heightmap; /* mask for low detail heightmap */
 };
 
@@ -34,9 +36,14 @@ private:
        std::vector<TerrainTile> tiles;
        
 public:
+       Material material;
+
        Terrain();
        ~Terrain();
 
+       bool init();
+       void destroy();
+
        bool generate(const TerrainParams &params);
        Scene *get_visible(const Camera *camera) const;
 };
index 4fcdbf5..3a850f1 100644 (file)
@@ -25,6 +25,7 @@ public:
        virtual bool is_cubemap() const;
 
        virtual void bind() = 0;
+       virtual void unbind() = 0;
 };
 
 #endif // TEXTURE_H_
\ No newline at end of file
index 4bd4791..89594f2 100644 (file)
@@ -33,4 +33,8 @@ void MeshVK::update_vertex_data()
 
 void MeshVK::draw() const
 {
+}
+
+void MeshVK::draw_normals(float scale) const
+{
 }
\ No newline at end of file
index 30593e9..8c8a39c 100644 (file)
@@ -13,6 +13,7 @@ public:
 
        virtual ~MeshVK();
        virtual void draw() const override;
+       virtual void draw_normals(float scale) const override;
 };
 
 #endif // MESH_VK_H_
\ No newline at end of file
index af67c82..3c56ebd 100644 (file)
@@ -14,4 +14,8 @@ void TextureVK::update()
 
 void TextureVK::bind()
 {
+}
+
+void TextureVK::unbind()
+{
 }
\ No newline at end of file
index bc99c83..56da38d 100644 (file)
@@ -12,6 +12,7 @@ public:
        virtual ~TextureVK();
 
        virtual void bind() override;
+       virtual void unbind() override;
 };
 
 #endif // TEXTURE_VK_H_
\ No newline at end of file