From f658c122374c09682d9029f0d0d76d1bfd67404b Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Thu, 31 Mar 2011 00:33:57 +0200 Subject: Simple terrain click-selection using gluUnProject(). --- main.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index b653427..36ddb10 100644 --- a/main.cpp +++ b/main.cpp @@ -33,7 +33,7 @@ struct hit_record { }; // TODO: reimplement -int select(Quadtree& qt, int x, int y) { +int _select(Quadtree& qt, int x, int y) { y = 600-y; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -95,9 +95,33 @@ int select(Quadtree& qt, int x, int y) { 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 = 800; - video::height = 600; + video::width = 1280; + video::height = 720; video::init(); font = new FTTextureFont("font.ttf"); @@ -150,6 +174,7 @@ int main(int argc, char **argv) { unsigned int last_time = SDL_GetTicks(); /*boost::timer t; double last_time = 0;*/ + Vector3 selected; while(running) { unsigned int time = SDL_GetTicks(); //double time = t.elapsed(); @@ -157,6 +182,8 @@ int main(int argc, char **argv) { unsigned int steps = time - last_time + 1; //double steps = (time - last_time) * 1000; last_time = time; + bool do_select = 0; + int sx, sy; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: @@ -173,6 +200,7 @@ int main(int argc, char **argv) { case SDLK_KP_PLUS: delete qt; qt = new Quadtree(hm->w, hm->h, heightmap, ++level); + level = qt->levels; break; case SDLK_KP_MINUS: if(level > 0) { @@ -190,6 +218,9 @@ int main(int argc, char **argv) { case SDL_MOUSEBUTTONUP: switch(event.button.button) { case SDL_BUTTON_LEFT: + sx = event.button.x; + sy = event.button.y; + do_select = true; // TODO: reimplement selection break; case SDL_BUTTON_WHEELUP: @@ -255,7 +286,7 @@ int main(int argc, char **argv) { scene.yvel -= 9.81 * steps / 85000; if(scene.yvel < -.5) scene.yvel = -.5; - scene.pos.y += scene.yvel; + scene.pos.y += scene.yvel * steps; if(scene.pos.y < y) { scene.pos.y = y; scene.yvel = 0; @@ -304,10 +335,24 @@ int main(int argc, char **argv) { glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); + float px, py, pz; + if(do_select && select(*qt, sx, sy, px, py, pz)) { + selected = Vector3(px, py, pz); + } + glColor3f(1, 0, 0); + glBegin(GL_TRIANGLE_FAN); + glVertex3f(selected.x, selected.y, selected.z); + glVertex3f(selected.x+.5, selected.y+1, selected.z-.5); + glVertex3f(selected.x+.5, selected.y+1, selected.z+.5); + glVertex3f(selected.x-.5, selected.y+1, selected.z+.5); + glVertex3f(selected.x-.5, selected.y+1, selected.z-.5); + glVertex3f(selected.x+.5, selected.y+1, selected.z-.5); + glEnd(); + video::ortho(); float height = font->LineHeight(); glColor3f(1, 1, 1); - glTranslatef(0, 600-height, 0); + 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()); //glTranslatef(0, height, 0); -- cgit v1.2.3