diff --git a/ChangeLog b/ChangeLog index 8f6dc08..c4d537b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,7 @@ * New texture model (perpendicular displacement and thickness). * Added clouds hardness to light. * Version management in saved files. -* Added ground texture and sun location in 3D explorer. +* Added ground texture and skybox in 3D explorer. * 3D explorer now takes advantage of multiple CPU cores. * Added sun halo control. diff --git a/TODO b/TODO index 9e49618..f8dad19 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,7 @@ Technology Preview 2 : - Compute shadows only once for all textures at a same location. => Add an intermediary light status (two pass lighting). - Add layer sorting/naming. +- Disable specular lighting in explorer (and everything camera dependent). - Add logarithmic sliders for some float values. - Save GUI config (views, render params). - Add an OSD ability on previews and use it for camera location and user landmarks. diff --git a/gui_qt/baseexplorerchunk.cpp b/gui_qt/baseexplorerchunk.cpp index d217452..02dbc3d 100644 --- a/gui_qt/baseexplorerchunk.cpp +++ b/gui_qt/baseexplorerchunk.cpp @@ -47,7 +47,7 @@ bool BaseExplorerChunk::maintain() { if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0) { - Color color = getTextureColor((double)i / (double)(new_texture_size + 1), (double)j / (double)(new_texture_size + 1)); + Color color = getTextureColor((double)i / (double)new_texture_size, 1.0 - (double)j / (double)new_texture_size); new_image->setPixel(i, j, colorTo32BitBGRA(&color)); } } diff --git a/gui_qt/explorerchunksky.cpp b/gui_qt/explorerchunksky.cpp new file mode 100644 index 0000000..07c1e98 --- /dev/null +++ b/gui_qt/explorerchunksky.cpp @@ -0,0 +1,135 @@ +#include "explorerchunksky.h" + +#include +#include "baseexplorerchunk.h" +#include "../lib_paysages/camera.h" + +ExplorerChunkSky::ExplorerChunkSky(Renderer* renderer, SkyDefinition* sky, double size, SkyboxOrientation orientation) : BaseExplorerChunk(renderer) +{ + _sky = sky; + _box_size = size; + _orientation = orientation; + + setMaxTextureSize(256); + maintain(); +} + +void ExplorerChunkSky::onRenderEvent(QGLWidget* widget) +{ + double size = _box_size; + Vector3 camera = renderer()->camera_location; + + glBegin(GL_QUADS); + switch(_orientation) + { + case SKYBOX_NORTH: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x - size, camera.y + size, camera.z - size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x - size, camera.y - size, camera.z - size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x + size, camera.y - size, camera.z - size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x + size, camera.y + size, camera.z - size); + break; + case SKYBOX_SOUTH: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x + size, camera.y + size, camera.z + size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x + size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x - size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x - size, camera.y + size, camera.z + size); + break; + case SKYBOX_EAST: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x + size, camera.y + size, camera.z - size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x + size, camera.y - size, camera.z - size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x + size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x + size, camera.y + size, camera.z + size); + break; + case SKYBOX_WEST: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x - size, camera.y + size, camera.z + size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x - size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x - size, camera.y - size, camera.z - size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x - size, camera.y + size, camera.z - size); + break; + case SKYBOX_TOP: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x - size, camera.y + size, camera.z + size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x - size, camera.y + size, camera.z - size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x + size, camera.y + size, camera.z - size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x + size, camera.y + size, camera.z + size); + break; + case SKYBOX_BOTTOM: + glTexCoord2d(0.0, 0.0); + glVertex3d(camera.x - size, camera.y - size, camera.z - size); + glTexCoord2d(0.0, 1.0); + glVertex3d(camera.x - size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 1.0); + glVertex3d(camera.x + size, camera.y - size, camera.z + size); + glTexCoord2d(1.0, 0.0); + glVertex3d(camera.x + size, camera.y - size, camera.z - size); + break; + } + glEnd(); +} + +double ExplorerChunkSky::getDisplayedSizeHint(CameraDefinition* camera) +{ + return 1000.0; +} + +Color ExplorerChunkSky::getTextureColor(double x, double y) +{ + Vector3 location; + + x -= 0.5; + y -= 0.5; + + switch(_orientation) + { + case SKYBOX_NORTH: + location.x = x; + location.y = -y; + location.z = -0.5; + break; + case SKYBOX_SOUTH: + location.x = -x; + location.y = -y; + location.z = 0.5; + break; + case SKYBOX_EAST: + location.x = 0.5; + location.y = -y; + location.z = x; + break; + case SKYBOX_WEST: + location.x = -0.5; + location.y = -y; + location.z = -x; + break; + case SKYBOX_TOP: + location.x = x; + location.y = 0.5; + location.z = -y; + break; + case SKYBOX_BOTTOM: + location.x = x; + location.y = -0.5; + location.z = y; + break; + } + return skyGetColor(_sky, renderer(), VECTOR_ZERO, v3Normalize(location)); +} diff --git a/gui_qt/explorerchunksky.h b/gui_qt/explorerchunksky.h new file mode 100644 index 0000000..838acf7 --- /dev/null +++ b/gui_qt/explorerchunksky.h @@ -0,0 +1,35 @@ +#ifndef _PAYSAGES_QT_EXPLORERCHUNKSKY_H_ +#define _PAYSAGES_QT_EXPLORERCHUNKSKY_H_ + +#include "baseexplorerchunk.h" +#include "../lib_paysages/renderer.h" +#include "../lib_paysages/euclid.h" +#include "../lib_paysages/sky.h" + +enum SkyboxOrientation +{ + SKYBOX_NORTH, + SKYBOX_SOUTH, + SKYBOX_WEST, + SKYBOX_EAST, + SKYBOX_TOP, + SKYBOX_BOTTOM +}; + +class ExplorerChunkSky:public BaseExplorerChunk +{ +public: + ExplorerChunkSky(Renderer* renderer, SkyDefinition* sky, double size, SkyboxOrientation orientation); + + void onRenderEvent(QGLWidget* widget); + double getDisplayedSizeHint(CameraDefinition* camera); + Color getTextureColor(double x, double y); + +private: + SkyDefinition* _sky; + SkyboxOrientation _orientation; + double _box_size; + +}; + +#endif diff --git a/gui_qt/explorerchunkterrain.cpp b/gui_qt/explorerchunkterrain.cpp index 62e1ff8..25af52c 100644 --- a/gui_qt/explorerchunkterrain.cpp +++ b/gui_qt/explorerchunkterrain.cpp @@ -112,9 +112,9 @@ void ExplorerChunkTerrain::onRenderEvent(QGLWidget* widget) glBegin(GL_QUAD_STRIP); for (int i = 0; i <= _tessellation_max_size; i += tessellation_inc) { - glTexCoord2d(tsize * (double)i, 1.0 - tsize * (double)j); + glTexCoord2d(tsize * (double)i, tsize * (double)j); glVertex3d(_startx + _tessellation_step * (double)i, _tessellation[j * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double)j); - glTexCoord2d(tsize * (double)i, 1.0 - tsize * (double)(j + tessellation_inc)); + glTexCoord2d(tsize * (double)i, tsize * (double)(j + tessellation_inc)); glVertex3d(_startx + _tessellation_step * (double)i, _tessellation[(j + tessellation_inc) * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double)(j + tessellation_inc)); } glEnd(); diff --git a/gui_qt/widgetexplorer.cpp b/gui_qt/widgetexplorer.cpp index cda9f58..e9db5cf 100644 --- a/gui_qt/widgetexplorer.cpp +++ b/gui_qt/widgetexplorer.cpp @@ -9,6 +9,8 @@ #include "../lib_paysages/scenery.h" #include "../lib_paysages/euclid.h" #include "explorerchunkterrain.h" +#include "explorerchunksky.h" +#include "tools.h" class ChunkMaintenanceThread:public QThread { @@ -99,6 +101,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): _updated = false; + // Add terrain int chunks = 20; double size = 200.0; double chunksize = size / (double)chunks; @@ -112,6 +115,14 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): _updateQueue.append(chunk); } } + + // Add skybox + for (int orientation = 0; orientation < 6; orientation++) + { + ExplorerChunkSky* chunk = new ExplorerChunkSky(&_renderer, &_sky, 500.0, (SkyboxOrientation)orientation); + _chunks.append(chunk); + _updateQueue.append(chunk); + } startThreads(); startTimer(500); @@ -400,6 +411,7 @@ void WidgetExplorer::resizeGL(int w, int h) void WidgetExplorer::paintGL() { + GLenum error_code; QTime start_time; double frame_time; @@ -409,6 +421,7 @@ void WidgetExplorer::paintGL() } cameraValidateDefinition(&_current_camera, 1); + _renderer.camera_location = _current_camera.location; start_time = QTime::currentTime(); @@ -421,20 +434,7 @@ void WidgetExplorer::paintGL() glClearColor(zenith_color.r, zenith_color.g, zenith_color.b, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Render sun - Vector3 sun_location = v3Add(_current_camera.location, v3Scale(skyGetSunDirection(&_sky), 500.0)); - Color sun_color = skyGetSunColor(&_sky); - glDisable(GL_TEXTURE); - glDisable(GL_TEXTURE_2D); - glColor3f(sun_color.r, sun_color.g, sun_color.b); - glPointSize(15.0 * _sky.sun_radius / 0.02); - glEnable(GL_POINT_SMOOTH); - glBegin(GL_POINTS); - glVertex3f(sun_location.x, sun_location.y, sun_location.z); - glEnd(); - // Render water - glDisable(GL_TEXTURE); glDisable(GL_TEXTURE_2D); glColor3f(_water.material.base.r, _water.material.base.g, _water.material.base.b); glBegin(GL_QUADS); @@ -444,8 +444,7 @@ void WidgetExplorer::paintGL() glVertex3f(_current_camera.location.x + 500.0, _water.height, _current_camera.location.z - 500.0); glEnd(); - // Render terrain chunks - glEnable(GL_TEXTURE); + // Render chunks glEnable(GL_TEXTURE_2D); for (int i = 0; i < _chunks.count(); i++) { @@ -466,4 +465,9 @@ void WidgetExplorer::paintGL() { _quality++; } + + while ((error_code = glGetError()) != GL_NO_ERROR) + { + logDebug(QString("[OpenGL] ERROR : ") + (const char*)gluErrorString(error_code)); + } } diff --git a/i18n/paysages_fr.ts b/i18n/paysages_fr.ts index 6de9da6..44bb748 100644 --- a/i18n/paysages_fr.ts +++ b/i18n/paysages_fr.ts @@ -121,6 +121,46 @@ Right click on a point to delete it. + + DialogExplorer + + + Paysages 3D - Explore + Paysages 3D - Exploration + + + + COMMANDS + +Left click : Look around +Right click : Pan (adjust framing) +Wheel : Move forward/backward +Hold SHIFT : Faster +Hold CTRL : Slower + COMMANDES + +Clic gauche : Regarder autour +Clic droit : Déplacer le cadrage +Molette : Avancer/reculer +Maintenir Maj : Plus rapide +Maintenir Ctrl : Plus lent + + + + Reset camera + Revenir au point de vue initial + + + + Validate as render camera + Choisir comme caméra de rendu + + + + Close + Fermer + + DialogMaterial @@ -218,12 +258,10 @@ Right click on a point to delete it. DialogWanderer - Paysages 3D - Explore - Paysages 3D - Exploration + Paysages 3D - Exploration - COMMANDS Left click : Look around @@ -231,7 +269,7 @@ Right click : Pan (adjust framing) Wheel : Move forward/backward Hold SHIFT : Faster Hold CTRL : Slower - COMMANDES + COMMANDES Clic gauche : Regarder autour Clic droit : Déplacer le cadrage @@ -256,19 +294,16 @@ Maintenir MAJ : Plus lent Maintenir Ctrl : Plus rapide - Reset camera - Revenir au point de vue initial + Revenir au point de vue initial - Validate as render camera - Choisir comme caméra de rendu + Choisir comme caméra de rendu - Close - Fermer + Fermer