diff options
-rw-r--r-- | scene.cpp | 4 | ||||
-rw-r--r-- | terrain.cpp | 218 | ||||
-rw-r--r-- | terrain.h | 7 |
3 files changed, 70 insertions, 159 deletions
@@ -298,8 +298,8 @@ void Scene::render() { yvel = 0; } } - move_str = (boost::format("%s n: %.2f,%.2f %.2fx%.2f c: %d,%d %dx%d") - % pos.str() % node->x % node->y % node->width % node->height + move_str = (boost::format("%s n: %.2f,%.2f c: %d,%d %dx%d") + % pos.str() % node->x % node->y % node->chunk->x % node->chunk->y % node->chunk->width % node->chunk->height).str(); if(last_node != node) { 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); @@ -15,15 +15,14 @@ class Terrain { struct Node { Chunk *chunk; - float x, y, width, height; - float vertex_array[15]; + float x, y; + float vertex_array[12]; - Node(Chunk *chunk, float x, float y, float width, float height); + Node(Chunk *chunk, float x, float y); virtual ~Node(); float distance(float px, float pz); void fill(); - void draw(); void draw_grid(); void draw_normal(); float get_height(float px, float py); |