added function that procedurally generates heightfield
authorEleni Maria Stea <estea@igalia.com>
Wed, 16 Aug 2017 13:25:47 +0000 (16:25 +0300)
committerEleni Maria Stea <estea@igalia.com>
Wed, 16 Aug 2017 13:25:47 +0000 (16:25 +0300)
replaced jpg images with hdr

external/gph-math
external/libimago
src/main.cc
src/meshgen.cc
src/meshgen.h
src/terrain.cc
src/terrain.h

index 4c82eda..54ac4cb 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4c82eda2dcba00a4998cfd60a13330dc793b16ca
+Subproject commit 54ac4cbc3b08744e570a53e7f1a8ba862ea87b80
index d7e3914..843ac48 160000 (submodule)
@@ -1 +1 @@
-Subproject commit d7e3914d568a9e397b1bcd11b3722a84e7f4334e
+Subproject commit 843ac48c7cd58166bb9dc0d49097c1b0ae7e2029
index 7061bb6..166b467 100644 (file)
@@ -138,7 +138,7 @@ static bool init(Gfx_API api)
        }
 
        gskybox = gfx_create_texture();
-       gskybox->load("data/cubemap/cubemap.jpg");
+       gskybox->load("data/cubemap/cubemap.hdr");
        rground->set_sky_tex(gskybox);
 
        rcow = new Renderer;
index fb4fae2..ff7906d 100644 (file)
@@ -120,4 +120,99 @@ void gen_geosphere(Mesh *mesh, float rad, int subdiv, bool hemi)
                mesh->indices[i] = i;
        }
        mesh->update_vertex_data();
-}
\ No newline at end of file
+}
+
+// ------ heightfield ------
+
+static Vec3 hfield_vertex(float u, float v, float h, float xsz,
+               float ysz, float height)
+{
+       float x = u * xsz - xsz / 2.0;
+       float y = h * height;
+       float z = v * ysz - ysz / 2.0;
+
+       return Vec3(x, y, z);
+}
+
+void gen_heightfield(Mesh *mesh, float xsz, float ysz, float height, int usub,
+               int vsub, float (*calc_height)(float u, float v, void *ptr), void *ptr)
+{
+       /* 
+       usub and vsub is the number of subdivision at each axis
+       (heightfield = grid) 
+       */
+       if(usub < 1)
+               usub = 1;
+
+       if(vsub < 1)
+               vsub = 1;
+
+       int num_uvertices = usub + 1;
+       int num_vvertices = vsub + 1;
+
+       int num_quads = usub * vsub;
+       int num_triangles = num_quads * 2;
+
+       int num_vertices = num_uvertices * num_vvertices;
+
+       mesh->vertices.resize(num_vertices);
+       mesh->normals.resize(num_vertices);
+       mesh->tex_coords.resize(num_vertices);
+       mesh->indices.resize(num_triangles * 3);
+
+       int vidx = 0;
+       float du = 1.0 / (float)num_uvertices;
+       float dv = 1.0 / (float)num_vvertices;
+
+       for(int i=0; i<num_vvertices; i++) {
+               float v = (float)i / (float)num_vvertices;
+               for(int j=0; j<num_uvertices; j++) {
+                       float u = (float)j / (float)num_uvertices;
+                       Vec3 vtx = hfield_vertex(u, v, calc_height(u, v, ptr), xsz, ysz, height);
+
+                       /* calculating normal with forward differences:
+                       slopes in x, z, axis */
+
+                       Vec3 tangent = hfield_vertex(u + du, v, calc_height(u + du, v, ptr),
+                                       xsz, ysz, height) - vtx;
+
+                       Vec3 bitangent = hfield_vertex(u, v + dv, calc_height(u, v + dv, ptr),
+                                       xsz, ysz, height) - vtx;
+
+                       Vec3 normal = normalize(cross(tangent, bitangent));
+
+                       mesh->vertices[vidx] = vtx;
+                       mesh->normals[vidx] = normal;
+                       mesh->tex_coords[vidx] = Vec2(u, v);
+
+                       vidx++;
+               }
+       }
+
+       /*
+               indices: 
+       */
+       uint16_t *iptr = &mesh->indices[0];
+
+       for(int i=0; i<vsub; i++) {
+               for(int j=0; j<usub; j++) {
+                       int a = num_vvertices * i + j;
+                       int b = a + 1;
+                       int d = num_vvertices * (i + 1) + j;
+                       int c = d + 1;
+
+                       /* 1st triangle */
+
+                       *iptr++ = a;
+                       *iptr++ = b;
+                       *iptr++ = c;
+
+                       /* 2nd triangle */
+
+                       *iptr++ = c;
+                       *iptr++ = d;
+                       *iptr++ = a;
+               }
+       }
+       mesh->update_vertex_data();
+}
index bcd09ae..81880f6 100644 (file)
@@ -7,5 +7,7 @@ class Mesh;
 
 /* generates geodesic sphere: if hemi is true we only gen the hemisphere */
 void gen_geosphere(Mesh *mesh, float rad, int subdiv, bool hemi = false);
+void gen_heightfield(Mesh *mesh, float xsz, float ysz, float height, int usub,
+               int vsub, float (*calc_height)(float u, float v, void *ptr), void *ptr);
 
 #endif // MESHGEN_H_
index e69de29..6bfabe8 100644 (file)
@@ -0,0 +1,39 @@
+#include "camera.h"
+#include "image.h"
+#include "scene.h"
+#include "terrain.h"
+
+Terrain::Terrain() {}
+
+Terrain::~Terrain()
+{
+}
+
+bool Terrain::generate(const TerrainParams &params)
+{
+       // if(xsz <= 0 || ysz <=0) {
+       //      fprintf(stderr, "Invalid terrain size.\n");
+       //      return false;
+       // }
+
+       // if(xtiles <= 0 || ytiles <= 0) {
+       //      fprintf(stderr, "Invalid number of terrain tiles.\n");
+       //      return false;
+       // }
+
+       // if(tiles)
+       //      tiles.clear();
+
+       // int tsz = xtiles * ytiles;
+       // tiles.resize(tsz);
+
+       // for(int i=0; i<tsz; i++) {
+
+       // }
+       return true;
+}
+
+Scene *Terrain::get_visible(const Camera *camera) const
+{
+       return 0;
+}
index d6f4844..f2ecd69 100644 (file)
@@ -1,6 +1,44 @@
 #ifndef TERRAIN_H_
 #define TERRAIN_H_
 
+class Camera;
+class Image;
+class Scene;
 
+// terrain 8a ftiaxnei skini k taisma renderer
+class TerrainTile {
+private:
+       Mesh *mesh;
+
+};
+
+/* parameters needed in terrain generation */
+
+struct TerrainParams {
+       float xsz; /* terrain size in x axis */
+       float ysz; /* terrain size in y axis */
+       float max_height; /* max height of the heightfield */
+       int xtiles; /* number of tiles in x axis */
+       int ytiles; /* number of tiles in y axis */
+       int tile_usub;
+       int tile_vsub;
+       int num_octaves; /* Perlin noise sums */
+       Image *coarse_heightmap; /* mask for low detail heightmap */
+};
+
+class Terrain {
+private:
+       TerrainParams params;
+       mutable Scene *vis_scene; /* set of visible tiles returned by get_visible */
+
+       std::vector<TerrainTile> tiles;
+       
+public:
+       Terrain();
+       ~Terrain();
+
+       bool generate(const TerrainParams &params);
+       Scene *get_visible(const Camera *camera) const;
+};
 
 #endif // TERRAIN_H_
\ No newline at end of file