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*, ...*).
|
- 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.
|
- Remove all global variables (render_quality, render_width...), it should all be set in Renderer.
|
||||||
- Implement scaling and scrolling on previews.
|
- 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());
|
setLayout(new QVBoxLayout());
|
||||||
|
|
||||||
layout()->addWidget(new WidgetWanderer(this, camera));
|
layout()->addWidget(new WidgetWanderer(this, camera));
|
||||||
|
|
||||||
|
resize(700, 530);
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogWanderer::~DialogWanderer()
|
DialogWanderer::~DialogWanderer()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <math.h>
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
|
|
||||||
WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera):
|
WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera):
|
||||||
|
@ -38,6 +39,7 @@ void WidgetWanderer::keyPressEvent(QKeyEvent* event)
|
||||||
{
|
{
|
||||||
factor = 1.0;
|
factor = 1.0;
|
||||||
}
|
}
|
||||||
|
factor *= 3.0;
|
||||||
|
|
||||||
if (event->key() == Qt::Key_Up)
|
if (event->key() == Qt::Key_Up)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +110,12 @@ void WidgetWanderer::mouseMoveEvent(QMouseEvent* event)
|
||||||
updateGL();
|
updateGL();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
else if (event->buttons() & Qt::RightButton)
|
||||||
|
{
|
||||||
|
cameraRotateYaw(&camera, (double)(event->x() - last_mouse_x) * factor * 0.1);
|
||||||
|
updateGL();
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
@ -133,7 +141,7 @@ void WidgetWanderer::wheelEvent(QWheelEvent* event)
|
||||||
{
|
{
|
||||||
factor = 0.1;
|
factor = 0.1;
|
||||||
}
|
}
|
||||||
factor *= 0.1;
|
factor *= 0.03;
|
||||||
|
|
||||||
if (event->orientation() == Qt::Vertical)
|
if (event->orientation() == Qt::Vertical)
|
||||||
{
|
{
|
||||||
|
@ -147,6 +155,21 @@ void WidgetWanderer::wheelEvent(QWheelEvent* event)
|
||||||
void WidgetWanderer::initializeGL()
|
void WidgetWanderer::initializeGL()
|
||||||
{
|
{
|
||||||
glClearColor(0.4, 0.7, 0.8, 0.0);
|
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)
|
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);
|
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()
|
void WidgetWanderer::paintGL()
|
||||||
{
|
{
|
||||||
double x, z, step;
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
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);
|
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);
|
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);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glColor3f(0.0, 0.0, 1.0);
|
glColor3f(0.0, 0.0, 1.0);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
@ -194,30 +268,5 @@ void WidgetWanderer::paintGL()
|
||||||
glVertex3f(500.0, water.height, -500.0);
|
glVertex3f(500.0, water.height, -500.0);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
step = 2.0;
|
_renderTerrain(&terrain, &camera, 3);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,20 @@ void cameraStrafeUp(CameraDefinition* camera, double value)
|
||||||
cameraValidateDefinition(camera);
|
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)
|
Vector3 cameraProject(CameraDefinition* camera, Vector3 point)
|
||||||
{
|
{
|
||||||
point = m4Transform(camera->project, v3Sub(point, camera->location));
|
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 cameraStrafeForward(CameraDefinition* camera, double value);
|
||||||
void cameraStrafeRight(CameraDefinition* camera, double value);
|
void cameraStrafeRight(CameraDefinition* camera, double value);
|
||||||
void cameraStrafeUp(CameraDefinition* camera, double value);
|
void cameraStrafeUp(CameraDefinition* camera, double value);
|
||||||
|
void cameraRotateYaw(CameraDefinition* camera, double value);
|
||||||
|
|
||||||
Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
|
Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
|
||||||
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
|
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
|
||||||
|
|
Loading…
Reference in a new issue