paysages: Wanderer LOD + yaw.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@243 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
c57adf47f2
commit
d484e0271a
5 changed files with 108 additions and 41 deletions
1
TODO
1
TODO
|
@ -3,3 +3,4 @@
|
|||
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*).
|
||||
- Remove all global variables (render_quality, render_width...), it should all be set in Renderer.
|
||||
- Implement scaling and scrolling on previews.
|
||||
- Water and terrain LOD moves with the camera, fix it like in the wanderer.
|
||||
|
|
|
@ -11,6 +11,8 @@ DialogWanderer::DialogWanderer(QWidget* parent, CameraDefinition* camera):
|
|||
setLayout(new QVBoxLayout());
|
||||
|
||||
layout()->addWidget(new WidgetWanderer(this, camera));
|
||||
|
||||
resize(700, 530);
|
||||
}
|
||||
|
||||
DialogWanderer::~DialogWanderer()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QGLWidget>
|
||||
#include <QKeyEvent>
|
||||
#include <math.h>
|
||||
#include "../lib_paysages/scenery.h"
|
||||
|
||||
WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera):
|
||||
|
@ -38,6 +39,7 @@ void WidgetWanderer::keyPressEvent(QKeyEvent* event)
|
|||
{
|
||||
factor = 1.0;
|
||||
}
|
||||
factor *= 3.0;
|
||||
|
||||
if (event->key() == Qt::Key_Up)
|
||||
{
|
||||
|
@ -108,6 +110,12 @@ void WidgetWanderer::mouseMoveEvent(QMouseEvent* event)
|
|||
updateGL();
|
||||
event->accept();
|
||||
}
|
||||
else if (event->buttons() & Qt::RightButton)
|
||||
{
|
||||
cameraRotateYaw(&camera, (double)(event->x() - last_mouse_x) * factor * 0.1);
|
||||
updateGL();
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
|
@ -133,7 +141,7 @@ void WidgetWanderer::wheelEvent(QWheelEvent* event)
|
|||
{
|
||||
factor = 0.1;
|
||||
}
|
||||
factor *= 0.1;
|
||||
factor *= 0.03;
|
||||
|
||||
if (event->orientation() == Qt::Vertical)
|
||||
{
|
||||
|
@ -147,6 +155,21 @@ void WidgetWanderer::wheelEvent(QWheelEvent* event)
|
|||
void WidgetWanderer::initializeGL()
|
||||
{
|
||||
glClearColor(0.4, 0.7, 0.8, 0.0);
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE);
|
||||
|
||||
glFrontFace(GL_CCW);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.0);
|
||||
}
|
||||
|
||||
void WidgetWanderer::resizeGL(int w, int h)
|
||||
|
@ -160,31 +183,82 @@ void WidgetWanderer::resizeGL(int w, int h)
|
|||
glFrustum(-2.5, 2.5, -2.5 * ratio, 2.5 * ratio, 2.0, 1000.0);
|
||||
}
|
||||
|
||||
static inline void _pushTerrainVertex(TerrainDefinition* terrain, double x, double z)
|
||||
static inline void _renderTerrainQuad(TerrainDefinition* terrain, double x, double z, double size)
|
||||
{
|
||||
glVertex3f(x, terrainGetHeight(terrain, x, z), z);
|
||||
double y1, y2, y3, y4;
|
||||
|
||||
y1 = terrainGetHeight(terrain, x, z);
|
||||
y2 = terrainGetHeight(terrain, x, z + size);
|
||||
y3 = terrainGetHeight(terrain, x + size, z + size);
|
||||
y4 = terrainGetHeight(terrain, x + size, z);
|
||||
|
||||
glColor3f(0.0, 0.5, 0.0);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(x, y1, z);
|
||||
glVertex3f(x, y2, z + size);
|
||||
glVertex3f(x + size, y3, z + size);
|
||||
glVertex3f(x + size, y4, z);
|
||||
glEnd();
|
||||
|
||||
glColor3f(0.0, 1.0, 0.0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x, y1, z);
|
||||
glVertex3f(x, y2, z + size);
|
||||
glVertex3f(x + size, y3, z + size);
|
||||
glVertex3f(x + size, y4, z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void _renderTerrain(TerrainDefinition* terrain, CameraDefinition* camera, int quality)
|
||||
{
|
||||
int chunk_factor, chunk_count, i;
|
||||
double min_chunk_size, visible_chunk_size;
|
||||
double radius_int, radius_ext, chunk_size;
|
||||
double cx, cz;
|
||||
|
||||
min_chunk_size = 1.0 / (double)quality;
|
||||
visible_chunk_size = 1.0 / (double)quality;
|
||||
|
||||
cx = camera->location.x - fmod(camera->location.x, min_chunk_size * 16.0);
|
||||
cz = camera->location.z - fmod(camera->location.z, min_chunk_size * 16.0);
|
||||
|
||||
chunk_factor = 1;
|
||||
chunk_count = 2;
|
||||
radius_int = 0.0;
|
||||
radius_ext = min_chunk_size;
|
||||
chunk_size = min_chunk_size;
|
||||
|
||||
while (radius_ext < 100.0)
|
||||
{
|
||||
for (i = 0; i < chunk_count - 1; i++)
|
||||
{
|
||||
_renderTerrainQuad(terrain, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size);
|
||||
_renderTerrainQuad(terrain, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size);
|
||||
_renderTerrainQuad(terrain, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size);
|
||||
_renderTerrainQuad(terrain, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size);
|
||||
}
|
||||
|
||||
if (chunk_count % 32 == 0 && chunk_size / radius_int < visible_chunk_size)
|
||||
{
|
||||
chunk_count /= 2;
|
||||
chunk_factor *= 2;
|
||||
/* TODO Fill in gaps with triangles */
|
||||
}
|
||||
chunk_count += 2;
|
||||
chunk_size = min_chunk_size * chunk_factor;
|
||||
radius_int = radius_ext;
|
||||
radius_ext += chunk_size;
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetWanderer::paintGL()
|
||||
{
|
||||
double x, z, step;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(camera.location.x, camera.location.y, camera.location.z, camera.target.x, camera.target.y, camera.target.z, camera.up.x, camera.up.y, camera.up.z);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glFrontFace(GL_CCW);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glLineWidth(1.0);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glColor3f(0.0, 0.0, 1.0);
|
||||
glBegin(GL_QUADS);
|
||||
|
@ -194,30 +268,5 @@ void WidgetWanderer::paintGL()
|
|||
glVertex3f(500.0, water.height, -500.0);
|
||||
glEnd();
|
||||
|
||||
step = 2.0;
|
||||
for (x = -50.0; x < 50.0; x += step)
|
||||
{
|
||||
for (z = -50.0; z < 50.0; z += step)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glColor3f(0.0, 0.5, 0.0);
|
||||
glBegin(GL_QUADS);
|
||||
_pushTerrainVertex(&terrain, x, z);
|
||||
_pushTerrainVertex(&terrain, x, z + step);
|
||||
_pushTerrainVertex(&terrain, x + step, z + step);
|
||||
_pushTerrainVertex(&terrain, x + step, z);
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glColor3f(0.0, 1.0, 0.0);
|
||||
glBegin(GL_QUADS);
|
||||
_pushTerrainVertex(&terrain, x, z);
|
||||
_pushTerrainVertex(&terrain, x, z + step);
|
||||
_pushTerrainVertex(&terrain, x + step, z + step);
|
||||
_pushTerrainVertex(&terrain, x + step, z);
|
||||
glEnd();
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
}
|
||||
_renderTerrain(&terrain, &camera, 3);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,20 @@ void cameraStrafeUp(CameraDefinition* camera, double value)
|
|||
cameraValidateDefinition(camera);
|
||||
}
|
||||
|
||||
void cameraRotateYaw(CameraDefinition* camera, double value)
|
||||
{
|
||||
Matrix4 m;
|
||||
Vector3 v;
|
||||
|
||||
v = v3Sub(camera->target, camera->location);
|
||||
m = m4NewRotateAxis(value, camera->up);
|
||||
v = m4MultPoint(m, v);
|
||||
|
||||
camera->target = v3Add(camera->location, v);
|
||||
|
||||
cameraValidateDefinition(camera);
|
||||
}
|
||||
|
||||
Vector3 cameraProject(CameraDefinition* camera, Vector3 point)
|
||||
{
|
||||
point = m4Transform(camera->project, v3Sub(point, camera->location));
|
||||
|
|
|
@ -33,6 +33,7 @@ void cameraSetAngle(CameraDefinition* camera, double angle);
|
|||
void cameraStrafeForward(CameraDefinition* camera, double value);
|
||||
void cameraStrafeRight(CameraDefinition* camera, double value);
|
||||
void cameraStrafeUp(CameraDefinition* camera, double value);
|
||||
void cameraRotateYaw(CameraDefinition* camera, double value);
|
||||
|
||||
Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
|
||||
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
|
||||
|
|
Loading…
Reference in a new issue