From 243eb502c5dc70e586a9e81815234069bf623480 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Sat, 19 Aug 2017 19:55:30 +0300 Subject: [PATCH] fixed terrain rendering - visualized normals --- gl_shaders/debug.f.glsl | 8 ++++ gl_shaders/debug.v.glsl | 10 +++++ gl_shaders/default.f.glsl | 3 +- src/main.cc | 101 +++++++++++++++++++++++++++++++-------------- src/mesh.h | 1 + src/meshgen.cc | 3 +- src/opengl/mesh-gl.cc | 46 ++++++++++++++++++++- src/opengl/mesh-gl.h | 7 +++- src/opengl/texture-gl.cc | 6 +++ src/opengl/texture-gl.h | 1 + src/renderer.cc | 18 ++++++++ src/renderer.h | 3 ++ src/terrain.cc | 78 +++++++++++++++++++++++++++------- src/terrain.h | 7 ++++ src/texture.h | 1 + src/vulkan/mesh-vk.cc | 4 ++ src/vulkan/mesh-vk.h | 1 + src/vulkan/texture-vk.cc | 4 ++ src/vulkan/texture-vk.h | 1 + 19 files changed, 251 insertions(+), 52 deletions(-) create mode 100644 gl_shaders/debug.f.glsl create mode 100644 gl_shaders/debug.v.glsl diff --git a/gl_shaders/debug.f.glsl b/gl_shaders/debug.f.glsl new file mode 100644 index 0000000..79bdba6 --- /dev/null +++ b/gl_shaders/debug.f.glsl @@ -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 index 0000000..8ec32dd --- /dev/null +++ b/gl_shaders/debug.v.glsl @@ -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); +} diff --git a/gl_shaders/default.f.glsl b/gl_shaders/default.f.glsl index 490efab..98cf032 100644 --- a/gl_shaders/default.f.glsl +++ b/gl_shaders/default.f.glsl @@ -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; } diff --git a/src/main.cc b/src/main.cc index 166b467..933bd62 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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; iobjects.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; iobjects.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 diff --git a/src/mesh.h b/src/mesh.h index ed40f5d..82f5c48 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -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; }; diff --git a/src/meshgen.cc b/src/meshgen.cc index ff7906d..9547cee 100644 --- a/src/meshgen.cc +++ b/src/meshgen.cc @@ -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; diff --git a/src/opengl/mesh-gl.cc b/src/opengl/mesh-gl.cc index 4707f11..f0956b4 100644 --- a/src/opengl/mesh-gl.cc +++ b/src/opengl/mesh-gl.cc @@ -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 diff --git a/src/opengl/mesh-gl.h b/src/opengl/mesh-gl.h index 78d415a..833e2db 100644 --- a/src/opengl/mesh-gl.h +++ b/src/opengl/mesh-gl.h @@ -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 diff --git a/src/opengl/texture-gl.cc b/src/opengl/texture-gl.cc index 2fbd05e..157d0bb 100644 --- a/src/opengl/texture-gl.cc +++ b/src/opengl/texture-gl.cc @@ -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 diff --git a/src/opengl/texture-gl.h b/src/opengl/texture-gl.h index a08f159..aa2b3db 100644 --- a/src/opengl/texture-gl.h +++ b/src/opengl/texture-gl.h @@ -14,6 +14,7 @@ public: virtual ~TextureGL(); virtual void bind() override; + virtual void unbind() override; }; #endif // TEXTURE_GL_H_ diff --git a/src/renderer.cc b/src/renderer.cc index e11b973..2f50d0b 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -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) diff --git a/src/renderer.h b/src/renderer.h index a218dab..c3fb0bf 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -16,6 +16,9 @@ protected: ShaderProgram *sprog; + /* debug shader to draw normals */ + ShaderProgram *nprog; + Texture *skytex, *dskytex; virtual void draw_object(Object *object) const; diff --git a/src/terrain.cc b/src/terrain.cc index 6bfabe8..bdd787f 100644 --- a/src/terrain.cc +++ b/src/terrain.cc @@ -1,39 +1,85 @@ +#include + #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 ¶ms) { - // 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; iupdate_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 diff --git a/src/terrain.h b/src/terrain.h index f2ecd69..bf9df09 100644 --- a/src/terrain.h +++ b/src/terrain.h @@ -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 tiles; public: + Material material; + Terrain(); ~Terrain(); + bool init(); + void destroy(); + bool generate(const TerrainParams ¶ms); Scene *get_visible(const Camera *camera) const; }; diff --git a/src/texture.h b/src/texture.h index 4fcdbf5..3a850f1 100644 --- a/src/texture.h +++ b/src/texture.h @@ -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 diff --git a/src/vulkan/mesh-vk.cc b/src/vulkan/mesh-vk.cc index 4bd4791..89594f2 100644 --- a/src/vulkan/mesh-vk.cc +++ b/src/vulkan/mesh-vk.cc @@ -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 diff --git a/src/vulkan/mesh-vk.h b/src/vulkan/mesh-vk.h index 30593e9..8c8a39c 100644 --- a/src/vulkan/mesh-vk.h +++ b/src/vulkan/mesh-vk.h @@ -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 diff --git a/src/vulkan/texture-vk.cc b/src/vulkan/texture-vk.cc index af67c82..3c56ebd 100644 --- a/src/vulkan/texture-vk.cc +++ b/src/vulkan/texture-vk.cc @@ -14,4 +14,8 @@ void TextureVK::update() void TextureVK::bind() { +} + +void TextureVK::unbind() +{ } \ No newline at end of file diff --git a/src/vulkan/texture-vk.h b/src/vulkan/texture-vk.h index bc99c83..56da38d 100644 --- a/src/vulkan/texture-vk.h +++ b/src/vulkan/texture-vk.h @@ -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 -- 1.7.10.4