diff options
-rw-r--r-- | quadtree.cpp | 34 | ||||
-rw-r--r-- | scene.cpp | 37 | ||||
-rw-r--r-- | shaders/terrain_vertex.glsl | 3 |
3 files changed, 42 insertions, 32 deletions
diff --git a/quadtree.cpp b/quadtree.cpp index d591730..15759d9 100644 --- a/quadtree.cpp +++ b/quadtree.cpp @@ -48,23 +48,23 @@ float Quadtree::QuadNode::distance(float px, float pz) { void Quadtree::QuadNode::fill() { vertex_array[0] = x + width / 2; - vertex_array[1] = chunk->tree->heights[(int)floorf((int)(x + width/2)*chunk->tree->height + (int)(y + height/2))]; + vertex_array[1] = chunk->tree->heights[(int)floorf((int)(chunk->x + x + width/2)*chunk->tree->height + (int)(chunk->y + y + height/2))]; vertex_array[2] = y + height / 2; vertex_array[3] = x; - vertex_array[4] = chunk->tree->heights[(int)floorf(x*chunk->tree->height+y)]; + vertex_array[4] = chunk->tree->heights[(int)floorf((chunk->x + x)*chunk->tree->height+chunk->y + y)]; vertex_array[5] = y; vertex_array[6] = x; - vertex_array[7] = chunk->tree->heights[(int)floorf(x*chunk->tree->height + (y + height))]; + vertex_array[7] = chunk->tree->heights[(int)floorf((chunk->x + x)*chunk->tree->height + (chunk->y + y + height))]; vertex_array[8] = y + height; vertex_array[9] = x + width; - vertex_array[10] = chunk->tree->heights[(int)floorf((x + width)*chunk->tree->height + (y + height))]; + vertex_array[10] = chunk->tree->heights[(int)floorf((chunk->x + x + width)*chunk->tree->height + (chunk->y + y + height))]; vertex_array[11] = y + height; vertex_array[12] = x + width; - vertex_array[13] = chunk->tree->heights[(int)floorf((x + width)*chunk->tree->height + y)]; + vertex_array[13] = chunk->tree->heights[(int)floorf((chunk->x + x + width)*chunk->tree->height + chunk->y + y)]; vertex_array[14] = y; /* midpoint is average of corner heights when width == 1 */ @@ -111,19 +111,21 @@ void Quadtree::QuadNode::draw_grid() { 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(a.x, a.y, a.z); - glVertex3f(b.x, b.y, b.z); + 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(vertex_array[3], vertex_array[4], vertex_array[5]); - glVertex3f(vertex_array[6], vertex_array[7], vertex_array[8]); - glVertex3f(vertex_array[9], vertex_array[10], vertex_array[11]); - glVertex3f(vertex_array[12], vertex_array[13], vertex_array[14]); + 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]); glEnd(); } float Quadtree::QuadNode::get_height(float px, float py) { + px -= chunk->x; + py -= chunk->y; bool left; bool top; top = px - x >= height - (py - y); @@ -182,7 +184,7 @@ Quadtree::QuadChunk::QuadChunk(Quadtree *tree, float x, float y, float width, fl nodes = new QuadNode*[node_count]; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { - nodes[j*(int)height + i] = new QuadNode(this, x+j, y+i, 1, 1); + nodes[j*(int)height + i] = new QuadNode(this, j, i, 1, 1); } } } @@ -285,10 +287,10 @@ void Quadtree::QuadChunk::make_vbo() { float *n = buffer + vertices_size + normal_chunk_size*index; - Vector3 bl = tree->normals[(int)((node->x+1)*tree->height + node->y)]; - Vector3 br = tree->normals[(int)(node->x*tree->height + node->y)]; - Vector3 tr = tree->normals[(int)(node->x*tree->height + node->y+1)]; - Vector3 tl = tree->normals[(int)((node->x+1)*tree->height + node->y+1)]; + Vector3 bl = tree->normals[(int)((this->x+node->x+1)*tree->height + this->y+node->y)]; + Vector3 br = tree->normals[(int)((this->x+node->x)*tree->height + this->y+node->y)]; + Vector3 tr = tree->normals[(int)((this->x+node->x)*tree->height + this->y+node->y+1)]; + Vector3 tl = tree->normals[(int)((this->x+node->x+1)*tree->height + this->y+node->y+1)]; n[24] = n[30] = bl.x; n[25] = n[31] = bl.y; @@ -76,11 +76,9 @@ void Scene::lookat() { * z = sin Φ sin θ */ Vector3 center(sinf(pitch) * cosf(yaw), cosf(pitch), sinf(pitch) * sinf(yaw)); - center += pos; center.y += cam_height; - //Vector3 up(cosf(yaw) * cosf(pitch), sinf(pitch), sinf(yaw) * cosf(pitch)); Vector3 up(-cosf(pitch) * cosf(yaw), sinf(pitch), -cosf(pitch) * sinf(yaw)); - gluLookAt(pos.x, pos.y+cam_height, pos.z, + gluLookAt(0, cam_height, 0, center.x, center.y, center.z, up.x, up.y, up.z); } @@ -321,9 +319,11 @@ void Scene::render() { terrain_program.use(); GLint show_sel = glGetUniformLocation(terrain_program.get_program(), "show_sel"); glUniform1i(show_sel, show_selection ? 1 : 0); + GLint chunk_pos; if(show_selection) { GLint selpos = glGetUniformLocation(terrain_program.get_program(), "selpos"); glUniform3f(selpos, selected.x, selected.y, selected.z); + chunk_pos = glGetUniformLocation(terrain_program.get_program(), "chunk_pos"); } glEnable(GL_TEXTURE_2D); @@ -352,17 +352,24 @@ void Scene::render() { } else if(!chunk->vbo_object) continue; chunks_rendered++; - glBindBuffer(GL_ARRAY_BUFFER, chunk->vbo_object); - glVertexPointer(3, GL_FLOAT, 0, NULL); - glNormalPointer(GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float))); - glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float)*2)); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLES, 0, chunk->vertices); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glPushMatrix(); + glTranslatef(-pos.x + chunk->x, -pos.y, -pos.z + chunk->y); + if(show_selection) + glUniform2f(chunk_pos, chunk->x, chunk->y); + + glBindBuffer(GL_ARRAY_BUFFER, chunk->vbo_object); + glVertexPointer(3, GL_FLOAT, 0, NULL); + glNormalPointer(GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float))); + glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(chunk->vertices*3*sizeof(float)*2)); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDrawArrays(GL_TRIANGLES, 0, chunk->vertices); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glPopMatrix(); } glBindBuffer(GL_ARRAY_BUFFER, 0); glDisable(GL_TEXTURE_2D); @@ -396,7 +403,7 @@ void Scene::render() { float px, py, pz; if(do_select && select(sx, sy, px, py, pz)) { do_select = false; - selected = Vector3(px, py, pz); + selected = Vector3(pos.x + px, pos.y + py, pos.z + pz); show_selection = true; } diff --git a/shaders/terrain_vertex.glsl b/shaders/terrain_vertex.glsl index 5fcd17b..27da83f 100644 --- a/shaders/terrain_vertex.glsl +++ b/shaders/terrain_vertex.glsl @@ -1,11 +1,12 @@ #version 120 varying vec3 normal, light_pos, pos; +uniform vec2 chunk_pos; void main() { normal = gl_Normal; light_pos = vec3(0, 1, 0); - pos = gl_Vertex.xyz; + pos = gl_Vertex.xyz + vec3(chunk_pos.x, 0, chunk_pos.y); gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; |