diff options
-rw-r--r-- | main.cpp | 135 | ||||
-rw-r--r-- | quadtree.cpp | 2 | ||||
-rw-r--r-- | scene.cpp | 45 | ||||
-rw-r--r-- | scene.h | 6 |
4 files changed, 66 insertions, 122 deletions
@@ -24,106 +24,13 @@ FTFont *font; -Scene scene; - -struct hit_record { - uint32_t hits; - int32_t min_z; - int32_t max_z; - uint32_t name; -}; - -// TODO: reimplement -int _select(Quadtree& qt, int x, int y) { - y = 600-y; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - GLuint buf[64] = {0}; - GLint hits, view[4] = {0}; - uint32_t id = 0; - glSelectBuffer(64, buf); - glGetIntegerv(GL_VIEWPORT, view); - glRenderMode(GL_SELECT); - glInitNames(); - - //glPushName(0); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPickMatrix(x, y, 1, 1, view); - gluPerspective(45, (float)view[2] / (float)view[3], 1, 10000); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - scene.lookat(); - - std::vector<Quadtree::QuadNode*> nodes; - uint32_t index = 0; - std::queue<Quadtree::QuadNode*> q; - q.push(qt.root); - while(!q.empty()) { - Quadtree::QuadNode *node = q.front(); - q.pop(); - if(node->vertex_array) { - glPushName(++index); - /*glBegin(GL_QUADS); - glVertex3f(node->x - node->width/2, - glEnd();*/ - glPopName(); - node->draw(); - } else - for(int i = 0; i < 4; i++) - q.push(node->children[i]); - } - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - //glMatrixMode(GL_MODELVIEW); - //glFlush(); - hits = glRenderMode(GL_RENDER); - //std::cout << "hits: " << hits << std::endl; - for(int i = 0; i < hits; i++) { - struct hit_record *hit = (struct hit_record*)(buf + i*sizeof(hit_record)); - //std::cout << " hits: " << hit->hits << " min_z: " << hit->min_z << " max_z: " << hit->max_z << std::endl; - if(hit->hits == 1 && hit->name > 0) - id = hit->name; - } - glMatrixMode(GL_MODELVIEW); - //std::cout << "id: " << id << std::endl; - if(id > 0) { - //return map[vectors[id-1]]; - } - //return Vector3::p(); - //return id; - return 0; -} - -bool select(Quadtree& qt, int x, int y, float& px, float& py, float& pz) { - GLint view[4] = {0}; - GLdouble mvmatrix[16] = {0}, projmatrix[16] = {0}; - glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); - glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); - glGetIntegerv(GL_VIEWPORT, view); - - y = view[3] - y - 1; - - float z; - glReadBuffer(GL_BACK); - glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); - - GLdouble _px, _py, _pz; - if(gluUnProject(x, y, z, mvmatrix, projmatrix, view, &_px, &_py, &_pz) == GLU_TRUE) { - px = _px; - py = _py; - pz = _pz; - return true; - } - - return false; -} - int main(int argc, char **argv) { video::width = 1280; video::height = 720; video::init(); + + Scene scene; + GLShaderProgram program; GLVertexShader terrain_vertex("terrain_vertex.glsl"); GLFragmentShader terrain_fragment("terrain_fragment.glsl"); @@ -134,19 +41,6 @@ int main(int argc, char **argv) { font = new FTTextureFont("font.ttf"); font->FaceSize(10); - SDL_Surface *hm = IMG_Load("heightmap6.png"); - unsigned char *pixels = (unsigned char*)hm->pixels; - float *heightmap = new float[hm->w * hm->h]; - for(int x = 0; x < hm->w; x++) { - for(int y = 0; y < hm->h; y++) { - heightmap[y*hm->w + x] = ((float)(pixels[y*hm->w + x]) / 256) * 20; - } - } - int level = 3; - Quadtree *qt = new Quadtree(hm->w, hm->h, heightmap, level); - //Quadtree qt(qt_size, qt_size, (int)ceil(sqrt(qt_size))); - - GLuint grass_texture; { SDL_Surface *surface = IMG_Load("Grass0073_3_S.jpg"); @@ -208,13 +102,12 @@ int main(int argc, char **argv) { break; case SDLK_KP_PLUS: case SDLK_PLUS: - qt->create_nodes(++level); - level = qt->levels; + scene.qt->create_nodes(scene.qt->levels+1); break; case SDLK_KP_MINUS: case SDLK_MINUS: - if(level > 1) { - qt->create_nodes(--level); + if(scene.qt->levels > 1) { + scene.qt->create_nodes(scene.qt->levels-1); } break; case SDLK_SPACE: @@ -290,7 +183,7 @@ int main(int argc, char **argv) { scene.move(forward, right, steps*(keystate[SDLK_LSHIFT]?10:1)); std::string move_str; - Quadtree::QuadNode *node = qt->find(scene.pos.x, scene.pos.z); + Quadtree::QuadNode *node = scene.qt->find(scene.pos.x, scene.pos.z); if(node) { if(gravity) { float y = node->get_height(scene.pos.x, scene.pos.z); @@ -318,14 +211,14 @@ int main(int argc, char **argv) { program.use(); glBindTexture(GL_TEXTURE_2D, grass_texture); glEnable(GL_TEXTURE_2D); - glBindBuffer(GL_ARRAY_BUFFER, qt->vbo_object); + glBindBuffer(GL_ARRAY_BUFFER, scene.qt->vbo_object); glVertexPointer(3, GL_FLOAT, 0, NULL); - glNormalPointer(GL_FLOAT, 0, (GLvoid*)(qt->vertices*3*sizeof(float))); - glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(qt->vertices*3*sizeof(float)*2)); + glNormalPointer(GL_FLOAT, 0, (GLvoid*)(scene.qt->vertices*3*sizeof(float))); + glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(scene.qt->vertices*3*sizeof(float)*2)); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLES, 0, qt->vertices); + glDrawArrays(GL_TRIANGLES, 0, scene.qt->vertices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -333,7 +226,7 @@ int main(int argc, char **argv) { glUseProgram(0); } else { std::queue<Quadtree::QuadNode*> q; - q.push(qt->root); + q.push(scene.qt->root); while(!q.empty()) { Quadtree::QuadNode *node = q.front(); q.pop(); @@ -348,7 +241,7 @@ int main(int argc, char **argv) { glDisable(GL_LIGHTING); float px, py, pz; - if(do_select && select(*qt, sx, sy, px, py, pz)) { + if(do_select && scene.select(sx, sy, px, py, pz)) { selected = Vector3(px, py, pz); } glColor3f(1, 0, 0); @@ -366,7 +259,7 @@ int main(int argc, char **argv) { glColor3f(1, 1, 1); glTranslatef(0, video::height-height, 0); font->Render((boost::format("%dx%d %d levels %d nodes tree creation time: %f steps: %d") - % qt->width % qt->height % qt->levels % qt->nodes % qt->init_time % steps).str().c_str()); + % scene.qt->width % scene.qt->height % scene.qt->levels % scene.qt->nodes % scene.qt->init_time % steps).str().c_str()); //glTranslatef(0, height, 0); //font->Render((boost::format("selected: %x") % selected).str().c_str()); glTranslatef(0, -height, 0); diff --git a/quadtree.cpp b/quadtree.cpp index f109f63..ab08e3e 100644 --- a/quadtree.cpp +++ b/quadtree.cpp @@ -241,7 +241,7 @@ void Quadtree::create_nodes(int levels) { this->levels = levels; boost::timer t; - root = new QuadNode(this, NULL, 0, 0, width, height, 1, levels == 0); + root = new QuadNode(this, NULL, 0, 0, width-1, height-1, 1, levels == 0); std::queue<Quadtree::QuadNode*> q; if(levels > 0) q.push(root); @@ -1,11 +1,32 @@ #include "scene.h" +#include <SDL_image.h> #include <SDL_opengl.h> #include <cmath> #define inrange(a, b, c) ((a) >= (b) && (a) <= (c)) +Scene::Scene() { + SDL_Surface *hm = IMG_Load("heightmap10.png"); + float *heightmap = new float[hm->w * hm->h]; + for(int x = 0; x < hm->w; x++) { + for(int y = 0; y < hm->h; y++) { + Uint8 *p = (Uint8*)hm->pixels + y * hm->pitch + x * hm->format->BytesPerPixel; + heightmap[y*hm->w + x] = ((float)(*p) / 256) * 20; + } + } + int w = hm->w; + int h = hm->h; + SDL_FreeSurface(hm); + qt = new Quadtree(w, h, heightmap, 3); +} + +Scene::~Scene() { + if(qt) + delete qt; +} + void Scene::lookat() { /* calculate cartesian coordinates for the center vector where yaw is Φ and pitch is θ * x = cos Φ sin θ @@ -44,3 +65,27 @@ void Scene::move(float forward, float right, int steps) { //pos.x += dir.x; //pos.z += dir.y; } + +bool Scene::select(int x, int y, float& px, float& py, float& pz) { + GLint view[4] = {0}; + GLdouble mvmatrix[16] = {0}, projmatrix[16] = {0}; + glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); + glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); + glGetIntegerv(GL_VIEWPORT, view); + + y = view[3] - y - 1; + + float z; + glReadBuffer(GL_BACK); + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); + + GLdouble _px, _py, _pz; + if(gluUnProject(x, y, z, mvmatrix, projmatrix, view, &_px, &_py, &_pz) == GLU_TRUE) { + px = _px; + py = _py; + pz = _pz; + return true; + } + + return false; +} @@ -2,15 +2,21 @@ #define SCENE_H #include "vector.h" +#include "quadtree.h" class Scene { public: float pitch, yaw; Vector3 pos; float yvel; + Quadtree *qt; + + Scene(); + ~Scene(); void lookat(); void move(float forward, float right, int steps); + bool select(int x, int y, float& px, float& py, float& pz); }; #endif |