OrbitCamera::~OrbitCamera() {}
-void OrbitCamera::set_orbit_params(float phi, float theta, float distance)
+void OrbitCamera::set_orbit_params(float theta, float phi, float distance)
{
this->phi = phi;
this->theta = theta;
class Camera {
public:
Camera();
- Camera(float phi, float theta, float distance, float fov);
virtual ~Camera();
virtual Mat4 get_view_matrix() const = 0;
public:
OrbitCamera();
- OrbitCamera(float theta, float phi, float distance);
virtual ~OrbitCamera();
virtual Mat4 get_view_matrix() const override;
- void set_orbit_params(float phi, float theta, float distance);
+ void set_orbit_params(float theta, float phi, float distance);
};
Mat4 calc_projection_matrix(float fov_deg, float aspect, float n, float f);
float phi = 25;
float theta = 0;
-float dist = 4;
+float dist = 16;
ShaderManager *sdr_man;
sdr_man = new ShaderManager;
camera = new OrbitCamera;
- camera->set_orbit_params(phi, theta, dist);
// scene_ground = new Scene;
// if(!scene_ground->load("data/ground.obj")) {
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.max_height = 2;
+ p.xtiles = 20;
+ p.ytiles = 20;
+ p.tile_usub = 10;
+ p.tile_vsub = 10;
p.num_octaves = 3;
p.noise_freq = 10;
p.coarse_heightmap = 0;
prev_y = y;
if(button[0]) {
- theta += dx;
- phi += dy;
+ theta += dx * 0.5;
+ phi += dy * 0.5;
- if(phi < -90)
- phi = -90;
+ if(phi < 0)
+ phi = 0;
if(phi > 90)
phi = 90;
}
static void display()
{
- camera->set_orbit_params(phi, theta, dist);
+ camera->set_orbit_params(theta, phi, dist);
// gfx_clear(0.76, 0.3, 0.43);
gfx_clear(0.1, 0.1, 0.1);
#include "mesh.h"
-Mesh::Mesh() {}
+Mesh::Mesh()
+{
+ vdata_valid = false;
+}
Mesh::~Mesh()
{
indices.clear();
vertices.clear();
normals.clear();
+}
+
+void Mesh::transform(const Mat4 &mat)
+{
+ Mat4 normal_mat = mat.upper3x3();
+ for(size_t i=0; i<vertices.size(); i++) {
+ vertices[i] = mat * vertices[i];
+ normals[i] = normal_mat * normals[i];
+ }
+ invalidate();
+}
+
+void Mesh::invalidate()
+{
+ vdata_valid = false;
}
\ No newline at end of file
};
class Mesh {
+protected:
+ bool vdata_valid;
+
public:
std::vector<uint16_t> indices;
std::vector<Vec3> vertices;
std::vector<Vec2> tex_coords;
std::string name;
- unsigned int mat_idx;
-
Mesh();
virtual ~Mesh() = 0;
virtual void draw() const = 0;
virtual void draw_normals(float scale) const = 0;
virtual void update_vertex_data() = 0;
+ virtual void transform(const Mat4 &mat);
+ virtual void invalidate();
};
#endif // MESH_H_
\ No newline at end of file
for(int i=0; i<num_verts; i++) {
mesh->indices[i] = i;
}
- mesh->update_vertex_data();
+ mesh->invalidate();
}
// ------ heightfield ------
{
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);
}
float dv = 1.0 / (float)num_vvertices;
for(int i=0; i<num_vvertices; i++) {
- float v = (float)i / (float)num_vvertices;
+ float v = 1 - (float)i / (float)(num_vvertices - 1);
for(int j=0; j<num_uvertices; j++) {
- float u = (float)j / (float)num_uvertices;
+ float u = (float)j / (float)(num_uvertices - 1);
Vec3 vtx = hfield_vertex(u, v, calc_height(u, v, ptr), xsz, ysz, height);
/* calculating normal with forward differences:
*iptr++ = a;
}
}
- mesh->update_vertex_data();
+ mesh->invalidate();
}
void MeshGL::draw() const
{
+ if(!vdata_valid) {
+ ((MeshGL*)this)->update_vertex_data();
+ }
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
Mat4 mview = object->transform * camera->get_view_matrix();
sprog->set_uniform_matrix(mview_loc, mview);
- object->mesh->update_vertex_data();
object->mesh->draw();
- /* debug */
+ /* debug
if(nprog) {
int loc = nprog->get_uniform_location("mmviewproj");
if(loc != -1) {
}
nprog->use();
object->mesh->draw_normals(1.0);
- }
+ }*/
// if(m->dtex)
// m->dtex->unbind();
else
fprintf(stderr, "No faces found.\n");
- mesh->mat_idx = amesh->mMaterialIndex;
return mesh;
}
delete vis_scene;
}
+struct GenData {
+ const TerrainParams *tp;
+ float xoffs;
+ float yoffs;
+};
+
bool Terrain::generate(const TerrainParams ¶ms)
{
tiles.clear();
TerrainTile tile;
tile.mesh = gfx_create_mesh();
+ GenData data;
+ data.tp = ¶ms;
+ data.xoffs = (float)j / (float)params.xtiles;
+ data.yoffs = (float)i / (float)params.ytiles;
+
gen_heightfield(tile.mesh, txsz, tysz, params.max_height,
params.tile_usub, params.tile_vsub, calc_height,
- (void*)¶ms);
+ (void*)&data);
+
+ float xoffs = j * txsz - params.xsz / 2.0 + txsz / 2.0;
+ float yoffs = i * tysz - params.ysz / 2.0 + tysz / 2.0;
+
+ Mat4 offmat;
+ offmat.translation(xoffs, 0, yoffs);
+ tile.mesh->transform(offmat);
- tile.mesh->update_vertex_data();
tiles.push_back(tile);
/*
return 0;
}
- TerrainParams *tp = (TerrainParams*)ptr;
+ GenData *data = (GenData*)ptr;
+ const TerrainParams *tp = data->tp;
+
+ // float ufreq = tp->noise_freq / tp->xtiles;
+ // float vfreq = tp->noise_freq / tp->ytiles;
+
+ u = u / tp->xtiles + data->xoffs;
+ v = v / tp->ytiles + data->yoffs;
+
float sn = gph::fbm(u * tp->noise_freq, v * tp->noise_freq, tp->num_octaves);
/* todo use the image later */
return sn;