summaryrefslogtreecommitdiff
path: root/terrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'terrain.cpp')
-rw-r--r--terrain.cpp218
1 files changed, 65 insertions, 153 deletions
diff --git a/terrain.cpp b/terrain.cpp
index b9927b4..f606cc2 100644
--- a/terrain.cpp
+++ b/terrain.cpp
@@ -17,12 +17,10 @@ using namespace noise;
using std::min;
using std::max;
-Terrain::Node::Node(Chunk *chunk, float x, float y, float width, float height) {
+Terrain::Node::Node(Chunk *chunk, float x, float y) {
this->chunk = chunk;
this->x = x;
this->y = y;
- this->width = width;
- this->height = height;
fill();
}
@@ -31,8 +29,8 @@ Terrain::Node::~Node() {
}
float Terrain::Node::distance(float px, float pz) {
- bool in_width = px > x && px < x+width;
- bool in_height = pz > y && pz < y+height;
+ bool in_width = px > x && px < x+1;
+ bool in_height = pz > y && pz < y+1;
if(in_width && in_height)
return 0;
@@ -40,94 +38,48 @@ float Terrain::Node::distance(float px, float pz) {
Vector2 p(px, pz);
float a = (p - Vector2(x, y)).length();
- float b = (p - Vector2(x+width, y)).length();
- float c = (p - Vector2(x, y+height)).length();
- float d = (p - Vector2(x+width, y+height)).length();
+ float b = (p - Vector2(x+1, y)).length();
+ float c = (p - Vector2(x, y+1)).length();
+ float d = (p - Vector2(x+1, y+1)).length();
float dist = min(min(min(a, b), c), d);
if(in_width)
- dist = min(dist, (float)min(abs(y - pz), abs(y+height - pz)));
+ dist = min(dist, (float)min(abs(y - pz), abs(y+1 - pz)));
if(in_height)
- dist = min(dist, (float)min(abs(x - px), abs(x+width - px)));
+ dist = min(dist, (float)min(abs(x - px), abs(x+1 - px)));
return dist;
}
void Terrain::Node::fill() {
- vertex_array[0] = x + width / 2;
- vertex_array[1] = chunk->heights[(int)floorf((int)(x + width/2)*(chunk->height+1) + (int)(y + height/2))];
- vertex_array[2] = y + height / 2;
+ vertex_array[0] = x;
+ vertex_array[1] = chunk->heights[(int)floorf((x)*(chunk->height+1)+y)];
+ vertex_array[2] = y;
vertex_array[3] = x;
- vertex_array[4] = chunk->heights[(int)floorf((x)*(chunk->height+1)+y)];
- vertex_array[5] = y;
-
- vertex_array[6] = x;
- vertex_array[7] = chunk->heights[(int)floorf((x)*(chunk->height+1) + (y + height))];
- vertex_array[8] = y + height;
-
- vertex_array[9] = x + width;
- vertex_array[10] = chunk->heights[(int)floorf((x + width)*(chunk->height+1) + (y + height))];
- vertex_array[11] = y + height;
-
- vertex_array[12] = x + width;
- vertex_array[13] = chunk->heights[(int)floorf((x + width)*(chunk->height+1) + y)];
- vertex_array[14] = y;
+ vertex_array[4] = chunk->heights[(int)floorf((x)*(chunk->height+1) + (y + 1))];
+ vertex_array[5] = y + 1;
- /* midpoint is average of corner heights when width == 1 */
- if(width == 1) {
- vertex_array[1] = (vertex_array[4] + vertex_array[7] + vertex_array[10] + vertex_array[13])/4;
- }
-}
+ vertex_array[6] = x + 1;
+ vertex_array[7] = chunk->heights[(int)floorf((x + 1)*(chunk->height+1) + (y + 1))];
+ vertex_array[8] = y + 1;
-void Terrain::Node::draw() {
- float tex_coords[4][3][2] = {
- {{.5, .5}, {0, 0}, {0, 1}},
- {{.5, .5}, {0, 1}, {1, 1}},
- {{.5, .5}, {1, 1}, {1, 0}},
- {{.5, .5}, {1, 0}, {0, 0}}
- };
-
- glBegin(GL_TRIANGLES);
- for(int i = 0; i < 4; i++) {
- Vector3 a(vertex_array[0], vertex_array[1], vertex_array[2]);
- Vector3 b(vertex_array[i*3+3], vertex_array[i*3+4], vertex_array[i*3+5]);
- Vector3 c(vertex_array[i == 3 ? 3 : (i*3+6)], vertex_array[i == 3 ? 4 : (i*3+7)], vertex_array[i == 3 ? 5 : (i*3+8)]);
-
- Vector3 U(c.x-a.x, c.y-a.y, c.z-a.z);
- Vector3 V(b.x-a.x, b.y-a.y, b.z-a.z);
- Vector3 N(V.cross(U));
- glNormal3f(N.x, N.y, N.z);
-
- glTexCoord2f(tex_coords[i][0][0], tex_coords[i][0][1]);
- glVertex3f(a.x, a.y, a.z);
-
- glTexCoord2f(tex_coords[i][1][0], tex_coords[i][1][1]);
- glVertex3f(b.x, b.y, b.z);
-
- glTexCoord2f(tex_coords[i][2][0], tex_coords[i][2][1]);
- glVertex3f(c.x, c.y, c.z);
- }
- glEnd();
+ vertex_array[9] = x + 1;
+ vertex_array[10] = chunk->heights[(int)floorf((x + 1)*(chunk->height+1) + y)];
+ vertex_array[11] = y;
}
void Terrain::Node::draw_grid() {
glNormal3f(0, 1, 0);
- glBegin(GL_LINES);
- for(int i = 0; i < 4; i++) {
- Vector3 a(vertex_array[0], vertex_array[1], vertex_array[2]);
- Vector3 b(vertex_array[i*3+3], vertex_array[i*3+4], vertex_array[i*3+5]);
-
- glVertex3f(chunk->x + a.x, a.y, chunk->y + a.z);
- glVertex3f(chunk->x + b.x, b.y, chunk->y + b.z);
- }
- glEnd();
glBegin(GL_LINE_LOOP);
+ glVertex3f(chunk->x + vertex_array[0], vertex_array[1], chunk->y + vertex_array[2]);
glVertex3f(chunk->x + vertex_array[3], vertex_array[4], chunk->y + vertex_array[5]);
glVertex3f(chunk->x + vertex_array[6], vertex_array[7], chunk->y + vertex_array[8]);
glVertex3f(chunk->x + vertex_array[9], vertex_array[10], chunk->y + vertex_array[11]);
- glVertex3f(chunk->x + vertex_array[12], vertex_array[13], chunk->y + vertex_array[14]);
+
+ glVertex3f(chunk->x + vertex_array[0], vertex_array[1], chunk->y + vertex_array[2]);
+ glVertex3f(chunk->x + vertex_array[6], vertex_array[7], chunk->y + vertex_array[8]);
glEnd();
}
@@ -146,31 +98,11 @@ float Terrain::Node::get_height(float px, float py) {
px -= chunk->x;
py -= chunk->y;
bool left;
- bool top;
- top = px - x >= height - (py - y);
left = px - x >= py - y;
+ int ci = left ? 9 : 3;
Vector3 a(vertex_array[0], vertex_array[1], vertex_array[2]);
- Vector3 b, c;
- int bi, ci;
- if(left) {
- if(top) {
- bi = 3*3;
- ci = 4*3;
- } else {
- bi = 4*3;
- ci = 1*3;
- }
- } else {
- if(top) {
- bi = 2*3;
- ci = 3*3;
- } else {
- bi = 1*3;
- ci = 2*3;
- }
- }
- b = Vector3(vertex_array[bi], vertex_array[bi+1], vertex_array[bi+2]);
- c = Vector3(vertex_array[ci], vertex_array[ci+1], vertex_array[ci+2]);
+ Vector3 b = Vector3(vertex_array[6], vertex_array[7], vertex_array[8]);
+ Vector3 c = Vector3(vertex_array[ci], vertex_array[ci+1], vertex_array[ci+2]);
float det1 = (b.z - c.z) * (a.x - c.x) + (c.x - b.x) * (a.z - c.z);
float det2 = (c.z - a.z) * (b.x - c.x) + (a.x - c.x) * (b.z - c.z);
float l1 = ((b.z - c.z) * (px - c.x) + (c.x - b.x) * (py - c.z)) / det1;
@@ -198,7 +130,7 @@ Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float hei
nodes = new Node*[node_count];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
- nodes[j*(int)height + i] = new Node(this, j, i, 1, 1);
+ nodes[j*(int)height + i] = new Node(this, j, i);
}
}
make_vbo();
@@ -238,17 +170,17 @@ float Terrain::Chunk::distance(float px, float pz) {
void Terrain::Chunk::make_vbo() {
node_count = width*height;
- vertices = node_count*12;
+ vertices = node_count*6;
if(vbo_object)
glDeleteBuffers(1, &vbo_object);
glGenBuffers(1, &vbo_object);
glBindBuffer(GL_ARRAY_BUFFER, vbo_object);
- const size_t vertex_chunk_size = /*sizeof(float)*/3*12;
+ const size_t vertex_chunk_size = /*sizeof(float)*/3*6;
const size_t vertices_size = vertex_chunk_size*node_count;
const size_t normal_chunk_size = vertex_chunk_size;
const size_t normals_size = normal_chunk_size*node_count;
- const size_t tex_coord_chunk_size = /*sizeof(float)*/2*12;
+ const size_t tex_coord_chunk_size = /*sizeof(float)*/2*6;
const size_t tex_coords_size = tex_coord_chunk_size*node_count;
buf_size = sizeof(float)*(vertices_size + normals_size + tex_coords_size);
@@ -259,34 +191,27 @@ void Terrain::Chunk::make_vbo() {
for(unsigned int index = 0; index < node_count; index++) {
Terrain::Node *node = nodes[index];
- float tex_coords[4][4][3][2] = {
- {{{.25, .25}, {0, 0}, {0, .5}},
- {{.25, .25}, {0, .5}, {.5, .5}},
- {{.25, .25}, {.5, .5}, {.5, 0}},
- {{.25, .25}, {.5, 0}, {0, 0}}},
-
- {{{.75, .25}, {.5, 0}, {.5, .5}},
- {{.75, .25}, {.5, .5}, {1, .5}},
- {{.75, .25}, {1, .5}, {1, 0}},
- {{.75, .25}, {1, 0}, {.5, 0}}},
-
- {{{.25, .75}, {0, .5}, {0, 1}},
- {{.25, .75}, {0, 1}, {.5, 1}},
- {{.25, .75}, {.5, 1}, {.5, .5}},
- {{.25, .75}, {.5, .5}, {0, .5}}},
-
- {{{.75, .75}, {.5, .5}, {.5, 1}},
- {{.75, .75}, {.5, 1}, {1, 1}},
- {{.75, .75}, {1, 1}, {1, .5}},
- {{.75, .75}, {1, .5}, {.5, .5}}}
+ // quad-node, triangle, vertex, texcoord
+ float tex_coords[4][2][3][2] = {
+ {{{0, 0}, {0, .5}, {.5, .5}},
+ {{0, 0}, {.5, .5}, {.5, 0}}},
+
+ {{{.5, 0}, {.5, .5}, {1, .5}},
+ {{.5, 0}, {1, .5}, {1, 0}}},
+
+ {{{0, .5}, {0, 1}, {.5, 1}},
+ {{0, .5}, {.5, 1}, {.5, .5}}},
+
+ {{{.5, .5}, {.5, 1}, {1, 1}},
+ {{.5, .5}, {1, 1}, {1, .5}}}
};
- for(int i = 0; i < 4; i++) {
+ for(int i = 0; i < 2; i++) {
float *v = buffer + vertex_chunk_size*index + 3*3*i;
for(int j = 0; j < 3; j++) {
float *tc = buffer + vertices_size + normals_size + tex_coord_chunk_size*index + 6*i + 2*j;
- int k = (fmodf(node->x, 2) == 0 ? 1 : 0) + (fmodf(node->y, 2) == 0 ? 2 : 0);
- tc[0] = tex_coords[k][i][j][0]*node->width;
- tc[1] = tex_coords[k][i][j][1]*node->height;
+ int k = (fmodf(node->x, 2) == 0 ? 0 : 1) + (fmodf(node->y, 2) == 0 ? 0 : 2);
+ tc[0] = tex_coords[k][i][j][0];
+ tc[1] = tex_coords[k][i][j][1];
}
v[0] = node->vertex_array[0];
@@ -297,9 +222,9 @@ void Terrain::Chunk::make_vbo() {
v[4] = node->vertex_array[i*3+4];
v[5] = node->vertex_array[i*3+5];
- v[6] = node->vertex_array[i == 3 ? 3 : (i*3+6)];
- v[7] = node->vertex_array[i == 3 ? 4 : (i*3+7)];
- v[8] = node->vertex_array[i == 3 ? 5 : (i*3+8)];
+ v[6] = node->vertex_array[i*3+6];
+ v[7] = node->vertex_array[i*3+7];
+ v[8] = node->vertex_array[i*3+8];
}
float *n = buffer + vertices_size + normal_chunk_size*index;
@@ -309,34 +234,21 @@ void Terrain::Chunk::make_vbo() {
Vector3 tr = normals[(int)((node->x)*(height+1) + node->y+1)];
Vector3 tl = normals[(int)((node->x+1)*(height+1) + node->y+1)];
- n[24] = n[30] = bl.x;
- n[25] = n[31] = bl.y;
- n[26] = n[32] = bl.z;
-
- n[3] = n[33] = br.x;
- n[4] = n[34] = br.y;
- n[5] = n[35] = br.z;
-
- n[6] = n[12] = tr.x;
- n[7] = n[13] = tr.y;
- n[8] = n[14] = tr.z;
-
- n[15] = n[21] = tl.x;
- n[16] = n[22] = tl.y;
- n[17] = n[23] = tl.z;
-
- if(node->width == 1) {
- Vector3 v(bl + br + tr + tl);
- v /= v.length();
- n[0] = n[9] = n[18] = n[27] = v.x;
- n[1] = n[10] = n[19] = n[28] = v.y;
- n[2] = n[11] = n[20] = n[29] = v.z;
- } else {
- Vector3 v(normals[(int)((node->x+node->width/2)*(height+1) + node->y+node->height/2)]);
- n[0] = n[9] = n[18] = n[27] = v.x;
- n[1] = n[10] = n[19] = n[28] = v.y;
- n[2] = n[11] = n[20] = n[29] = v.z;
- }
+ n[0] = n[9] = br.x;
+ n[1] = n[10] = br.y;
+ n[2] = n[11] = br.z;
+
+ n[3] = tr.x;
+ n[4] = tr.y;
+ n[5] = tr.z;
+
+ n[6] = n[12] = tl.x;
+ n[7] = n[13] = tl.y;
+ n[8] = n[14] = tl.z;
+
+ n[15] = bl.x;
+ n[16] = bl.y;
+ n[17] = bl.z;
}
glUnmapBuffer(GL_ARRAY_BUFFER);