summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-04-02 18:00:55 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-04-02 18:00:55 +0200
commit94c77b14469c9122d945eb1cf337507ff74c2fb6 (patch)
treefae6c6bf0bfc6fb0120559d210907ebf950f450e
parentfe2df4b280ecd8417cc267b8fc05ec050054ec4c (diff)
Moved select() into Scene, fixed rendering end of terrain.
-rw-r--r--main.cpp135
-rw-r--r--quadtree.cpp2
-rw-r--r--scene.cpp45
-rw-r--r--scene.h6
4 files changed, 66 insertions, 122 deletions
diff --git a/main.cpp b/main.cpp
index 1d634c2..f836cf3 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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);
diff --git a/scene.cpp b/scene.cpp
index 47b76bf..c477345 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -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;
+}
diff --git a/scene.h b/scene.h
index 7ae50b8..9e34e56 100644
--- a/scene.h
+++ b/scene.h
@@ -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