Refactored opengl terrain rendering for future use of shaders
This commit is contained in:
parent
8098482d50
commit
ac5c0fd584
16 changed files with 465 additions and 458 deletions
|
@ -1,170 +0,0 @@
|
||||||
#include "BaseExplorerChunk.h"
|
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QGLWidget>
|
|
||||||
#include "ColorProfile.h"
|
|
||||||
|
|
||||||
#ifndef GL_CLAMP_TO_EDGE
|
|
||||||
#define GL_CLAMP_TO_EDGE 0x812F
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BaseExplorerChunk::BaseExplorerChunk(SoftwareRenderer* renderer)
|
|
||||||
{
|
|
||||||
_renderer = renderer;
|
|
||||||
_color_profile = new ColorProfile;
|
|
||||||
|
|
||||||
priority = 0.0;
|
|
||||||
_reset_needed = false;
|
|
||||||
|
|
||||||
_texture = new QImage(1, 1, QImage::Format_ARGB32);
|
|
||||||
_texture_id = 0;
|
|
||||||
_texture_changed = false;
|
|
||||||
_texture_current_size = 0;
|
|
||||||
_texture_max_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseExplorerChunk::~BaseExplorerChunk()
|
|
||||||
{
|
|
||||||
_lock_data.lock();
|
|
||||||
delete _color_profile;
|
|
||||||
delete _texture;
|
|
||||||
_lock_data.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseExplorerChunk::maintain()
|
|
||||||
{
|
|
||||||
bool subchanged;
|
|
||||||
|
|
||||||
_lock_data.lock();
|
|
||||||
if (_reset_needed)
|
|
||||||
{
|
|
||||||
_reset_needed = false;
|
|
||||||
_texture_current_size = 0;
|
|
||||||
onResetEvent();
|
|
||||||
}
|
|
||||||
_lock_data.unlock();
|
|
||||||
|
|
||||||
subchanged = onMaintainEvent();
|
|
||||||
|
|
||||||
// Improve texture resolution
|
|
||||||
if (_texture_current_size < _texture_max_size)
|
|
||||||
{
|
|
||||||
int new_texture_size = _texture_current_size ? _texture_current_size * 2 : 1;
|
|
||||||
QImage* new_image = new QImage(_texture->scaled(new_texture_size + 1, new_texture_size + 1, Qt::IgnoreAspectRatio, Qt::FastTransformation));
|
|
||||||
for (int j = 0; j <= new_texture_size; j++)
|
|
||||||
{
|
|
||||||
for (int i = 0; i <= new_texture_size; i++)
|
|
||||||
{
|
|
||||||
if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0)
|
|
||||||
{
|
|
||||||
Color color = getTextureColor((double)i / (double)new_texture_size, 1.0 - (double)j / (double)new_texture_size);
|
|
||||||
color = _color_profile->apply(color);
|
|
||||||
color.normalize();
|
|
||||||
new_image->setPixel(i, j, color.to32BitBGRA());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_lock_data.lock();
|
|
||||||
delete _texture;
|
|
||||||
_texture = new_image;
|
|
||||||
_texture_current_size = new_texture_size;
|
|
||||||
_texture_changed = true;
|
|
||||||
_lock_data.unlock();
|
|
||||||
|
|
||||||
/*if (_texture_current_size < 4 && _texture_current_size < _texture_max_size)
|
|
||||||
{
|
|
||||||
maintain();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return subchanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::updatePriority(CameraDefinition* camera)
|
|
||||||
{
|
|
||||||
if (_reset_needed || (_texture_max_size > 1 && _texture_current_size <= 1))
|
|
||||||
{
|
|
||||||
priority = 1000.0;
|
|
||||||
}
|
|
||||||
else if (_texture_current_size == _texture_max_size)
|
|
||||||
{
|
|
||||||
priority = -1000.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priority = getDisplayedSizeHint(camera) - _texture_current_size;
|
|
||||||
}
|
|
||||||
onCameraEvent(camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::render(QGLWidget* widget)
|
|
||||||
{
|
|
||||||
// Put texture in place
|
|
||||||
_lock_data.lock();
|
|
||||||
if (_texture_changed)
|
|
||||||
{
|
|
||||||
_texture_changed = false;
|
|
||||||
if (_texture_id)
|
|
||||||
{
|
|
||||||
widget->deleteTexture(_texture_id);
|
|
||||||
}
|
|
||||||
// TODO Only do the scale if not power-of-two textures are unsupported by GPU
|
|
||||||
_texture_id = widget->bindTexture(_texture->scaled(_texture_current_size, _texture_current_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
//_texture_id = widget->bindTexture(*_texture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, _texture_id);
|
|
||||||
}
|
|
||||||
_lock_data.unlock();
|
|
||||||
|
|
||||||
// Delegate poly rendering to subclass
|
|
||||||
if (!_reset_needed)
|
|
||||||
{
|
|
||||||
onRenderEvent(widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::askReset()
|
|
||||||
{
|
|
||||||
_reset_needed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::setMaxTextureSize(int size)
|
|
||||||
{
|
|
||||||
_texture_max_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::onCameraEvent(CameraDefinition*)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::onResetEvent()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseExplorerChunk::onMaintainEvent()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseExplorerChunk::onRenderEvent(QGLWidget*)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
double BaseExplorerChunk::getDisplayedSizeHint(CameraDefinition*)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color BaseExplorerChunk::getTextureColor(double, double)
|
|
||||||
{
|
|
||||||
return COLOR_TRANSPARENT;
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#ifndef BASEEXPLORERCHUNK_H
|
|
||||||
#define BASEEXPLORERCHUNK_H
|
|
||||||
|
|
||||||
#include "opengl_global.h"
|
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
#include "Color.h"
|
|
||||||
|
|
||||||
class QImage;
|
|
||||||
class QGLWidget;
|
|
||||||
|
|
||||||
namespace paysages {
|
|
||||||
namespace opengl {
|
|
||||||
|
|
||||||
class BaseExplorerChunk
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~BaseExplorerChunk();
|
|
||||||
|
|
||||||
bool maintain();
|
|
||||||
void updatePriority(CameraDefinition* camera);
|
|
||||||
void render(QGLWidget* widget);
|
|
||||||
|
|
||||||
double priority;
|
|
||||||
protected:
|
|
||||||
BaseExplorerChunk(SoftwareRenderer* renderer);
|
|
||||||
|
|
||||||
inline SoftwareRenderer* renderer() {return _renderer;}
|
|
||||||
|
|
||||||
void askReset();
|
|
||||||
void setMaxTextureSize(int size);
|
|
||||||
|
|
||||||
virtual void onCameraEvent(CameraDefinition* camera);
|
|
||||||
virtual void onResetEvent();
|
|
||||||
virtual bool onMaintainEvent();
|
|
||||||
virtual void onRenderEvent(QGLWidget* widget);
|
|
||||||
virtual double getDisplayedSizeHint(CameraDefinition* camera);
|
|
||||||
virtual Color getTextureColor(double x, double y);
|
|
||||||
|
|
||||||
QMutex _lock_data;
|
|
||||||
|
|
||||||
private:
|
|
||||||
SoftwareRenderer* _renderer;
|
|
||||||
ColorProfile* _color_profile;
|
|
||||||
|
|
||||||
bool _reset_needed;
|
|
||||||
|
|
||||||
QImage* _texture;
|
|
||||||
unsigned int _texture_id;
|
|
||||||
bool _texture_changed;
|
|
||||||
int _texture_current_size;
|
|
||||||
int _texture_max_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BASEEXPLORERCHUNK_H
|
|
|
@ -1,13 +1,28 @@
|
||||||
#include "ExplorerChunkTerrain.h"
|
#include "ExplorerChunkTerrain.h"
|
||||||
|
|
||||||
|
#include OPENGL_FUNCTIONS_INCLUDE
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <GL/gl.h>
|
#include <QImage>
|
||||||
|
#include <QOpenGLTexture>
|
||||||
|
#include "ColorProfile.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "TerrainRenderer.h"
|
#include "TerrainRenderer.h"
|
||||||
|
|
||||||
ExplorerChunkTerrain::ExplorerChunkTerrain(SoftwareRenderer* renderer, double x, double z, double size, int nbchunks, double water_height) : BaseExplorerChunk(renderer)
|
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
||||||
|
_renderer(renderer)
|
||||||
{
|
{
|
||||||
|
_color_profile = new ColorProfile;
|
||||||
|
|
||||||
|
priority = 0.0;
|
||||||
|
_reset_needed = false;
|
||||||
|
|
||||||
|
_texture = new QImage(1, 1, QImage::Format_ARGB32);
|
||||||
|
texture = new QOpenGLTexture(*_texture);
|
||||||
|
_texture_changed = false;
|
||||||
|
_texture_current_size = 0;
|
||||||
|
_texture_max_size = 0;
|
||||||
|
|
||||||
_startx = x;
|
_startx = x;
|
||||||
_startz = z;
|
_startz = z;
|
||||||
_size = size;
|
_size = size;
|
||||||
|
@ -31,20 +46,70 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(SoftwareRenderer* renderer, double x,
|
||||||
ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
||||||
{
|
{
|
||||||
_lock_data.lock();
|
_lock_data.lock();
|
||||||
|
delete _color_profile;
|
||||||
|
delete _texture;
|
||||||
|
delete texture;
|
||||||
delete [] _tessellation;
|
delete [] _tessellation;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExplorerChunkTerrain::onResetEvent()
|
bool ExplorerChunkTerrain::maintain()
|
||||||
{
|
{
|
||||||
|
bool subchanged;
|
||||||
|
|
||||||
|
_lock_data.lock();
|
||||||
|
if (_reset_needed)
|
||||||
|
{
|
||||||
|
_reset_needed = false;
|
||||||
|
_texture_current_size = 0;
|
||||||
_tessellation_current_size = 0;
|
_tessellation_current_size = 0;
|
||||||
_overwater = false;
|
_overwater = false;
|
||||||
|
}
|
||||||
|
_lock_data.unlock();
|
||||||
|
|
||||||
|
subchanged = onMaintainEvent();
|
||||||
|
|
||||||
|
// Improve texture resolution
|
||||||
|
if (_texture_current_size < _texture_max_size)
|
||||||
|
{
|
||||||
|
int new_texture_size = _texture_current_size ? _texture_current_size * 2 : 1;
|
||||||
|
QImage* new_image = new QImage(_texture->scaled(new_texture_size + 1, new_texture_size + 1, Qt::IgnoreAspectRatio, Qt::FastTransformation));
|
||||||
|
for (int j = 0; j <= new_texture_size; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= new_texture_size; i++)
|
||||||
|
{
|
||||||
|
if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0)
|
||||||
|
{
|
||||||
|
Color color = getTextureColor((double)i / (double)new_texture_size, (double)j / (double)new_texture_size);
|
||||||
|
color = _color_profile->apply(color);
|
||||||
|
color.normalize();
|
||||||
|
new_image->setPixel(i, j, color.to32BitBGRA());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lock_data.lock();
|
||||||
|
delete _texture;
|
||||||
|
_texture = new_image;
|
||||||
|
_texture_current_size = new_texture_size;
|
||||||
|
_texture_changed = true;
|
||||||
|
_lock_data.unlock();
|
||||||
|
|
||||||
|
/*if (_texture_current_size < 4 && _texture_current_size < _texture_max_size)
|
||||||
|
{
|
||||||
|
maintain();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return subchanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExplorerChunkTerrain::onMaintainEvent()
|
bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
{
|
{
|
||||||
SoftwareRenderer* renderer = this->renderer();
|
|
||||||
|
|
||||||
// Improve heightmap resolution
|
// Improve heightmap resolution
|
||||||
if (_tessellation_current_size < _tessellation_max_size)
|
if (_tessellation_current_size < _tessellation_max_size)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +122,7 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
{
|
{
|
||||||
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
||||||
{
|
{
|
||||||
double height = renderer->getTerrainRenderer()->getHeight(_startx + _tessellation_step * (double) i, _startz + _tessellation_step * (double) j, 1);
|
double height = _renderer->getTerrainRenderer()->getHeight(_startx + _tessellation_step * (double) i, _startz + _tessellation_step * (double) j, 1);
|
||||||
if (height >= _water_height)
|
if (height >= _water_height)
|
||||||
{
|
{
|
||||||
_overwater = true;
|
_overwater = true;
|
||||||
|
@ -84,8 +149,21 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExplorerChunkTerrain::onCameraEvent(CameraDefinition* camera)
|
void ExplorerChunkTerrain::updatePriority(CameraDefinition* camera)
|
||||||
{
|
{
|
||||||
|
if (_reset_needed || (_texture_max_size > 1 && _texture_current_size <= 1))
|
||||||
|
{
|
||||||
|
priority = 1000.0;
|
||||||
|
}
|
||||||
|
else if (_texture_current_size == _texture_max_size)
|
||||||
|
{
|
||||||
|
priority = -1000.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priority = getDisplayedSizeHint(camera) - _texture_current_size;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 camera_location = camera->getLocation();
|
Vector3 camera_location = camera->getLocation();
|
||||||
|
|
||||||
// Handle position
|
// Handle position
|
||||||
|
@ -116,8 +194,26 @@ void ExplorerChunkTerrain::onCameraEvent(CameraDefinition* camera)
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExplorerChunkTerrain::onRenderEvent(QGLWidget*)
|
void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
||||||
{
|
{
|
||||||
|
// Put texture in place
|
||||||
|
_lock_data.lock();
|
||||||
|
if (_texture_changed)
|
||||||
|
{
|
||||||
|
_texture_changed = false;
|
||||||
|
texture->destroy();
|
||||||
|
// TODO Only do the scale if not power-of-two textures are unsupported by GPU
|
||||||
|
texture->setData(_texture->scaled(_texture_current_size, _texture_current_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
//texture->setData(*_texture);
|
||||||
|
texture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);
|
||||||
|
texture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);
|
||||||
|
}
|
||||||
|
texture->bind();
|
||||||
|
_lock_data.unlock();
|
||||||
|
|
||||||
|
// Delegate poly rendering to subclass
|
||||||
|
if (!_reset_needed)
|
||||||
|
{
|
||||||
_lock_data.lock();
|
_lock_data.lock();
|
||||||
int tessellation_size = _tessellation_current_size;
|
int tessellation_size = _tessellation_current_size;
|
||||||
double tsize = 1.0 / (double) _tessellation_max_size;
|
double tsize = 1.0 / (double) _tessellation_max_size;
|
||||||
|
@ -131,16 +227,27 @@ void ExplorerChunkTerrain::onRenderEvent(QGLWidget*)
|
||||||
int tessellation_inc = _tessellation_max_size / (double) tessellation_size;
|
int tessellation_inc = _tessellation_max_size / (double) tessellation_size;
|
||||||
for (int j = 0; j < _tessellation_max_size; j += tessellation_inc)
|
for (int j = 0; j < _tessellation_max_size; j += tessellation_inc)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUAD_STRIP);
|
functions->glBegin(GL_QUAD_STRIP);
|
||||||
for (int i = 0; i <= _tessellation_max_size; i += tessellation_inc)
|
for (int i = 0; i <= _tessellation_max_size; i += tessellation_inc)
|
||||||
{
|
{
|
||||||
glTexCoord2d(tsize * (double) i, tsize * (double) j);
|
functions->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);
|
functions->glVertex3d(_startx + _tessellation_step * (double) i, _tessellation[j * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double) j);
|
||||||
glTexCoord2d(tsize * (double) i, tsize * (double) (j + tessellation_inc));
|
functions->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));
|
functions->glVertex3d(_startx + _tessellation_step * (double) i, _tessellation[(j + tessellation_inc) * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double) (j + tessellation_inc));
|
||||||
}
|
}
|
||||||
glEnd();
|
functions->glEnd();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExplorerChunkTerrain::askReset()
|
||||||
|
{
|
||||||
|
_reset_needed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExplorerChunkTerrain::setMaxTextureSize(int size)
|
||||||
|
{
|
||||||
|
_texture_max_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
|
double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
|
||||||
|
@ -170,7 +277,7 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
|
||||||
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
|
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
|
||||||
{
|
{
|
||||||
Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size};
|
Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size};
|
||||||
return renderer()->getTerrainRenderer()->getFinalColor(location, 0.01);
|
return _renderer->getTerrainRenderer()->getFinalColor(location, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 ExplorerChunkTerrain::getCenter()
|
Vector3 ExplorerChunkTerrain::getCenter()
|
||||||
|
|
|
@ -1,26 +1,34 @@
|
||||||
#ifndef EXPLORERCHUNKTERRAIN_H
|
#ifndef EXPLORERCHUNKTERRAIN_H
|
||||||
#define EXPLORERCHUNKTERRAIN_H
|
#define EXPLORERCHUNKTERRAIN_H
|
||||||
|
|
||||||
#include "BaseExplorerChunk.h"
|
#include "opengl_global.h"
|
||||||
|
|
||||||
#include "Vector3.h"
|
#include <QMutex>
|
||||||
|
class QImage;
|
||||||
|
class QOpenGLTexture;
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
class OPENGLSHARED_EXPORT ExplorerChunkTerrain:public BaseExplorerChunk
|
class OPENGLSHARED_EXPORT ExplorerChunkTerrain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplorerChunkTerrain(SoftwareRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
||||||
~ExplorerChunkTerrain();
|
~ExplorerChunkTerrain();
|
||||||
|
|
||||||
void onCameraEvent(CameraDefinition* camera);
|
bool maintain();
|
||||||
void onResetEvent();
|
void updatePriority(CameraDefinition* camera);
|
||||||
|
void render(OpenGLFunctions* functions);
|
||||||
|
|
||||||
|
void askReset();
|
||||||
|
void setMaxTextureSize(int size);
|
||||||
|
|
||||||
bool onMaintainEvent();
|
bool onMaintainEvent();
|
||||||
void onRenderEvent(QGLWidget* widget);
|
|
||||||
double getDisplayedSizeHint(CameraDefinition* camera);
|
double getDisplayedSizeHint(CameraDefinition* camera);
|
||||||
Color getTextureColor(double x, double y);
|
Color getTextureColor(double x, double y);
|
||||||
|
|
||||||
|
double priority;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3 getCenter();
|
Vector3 getCenter();
|
||||||
|
|
||||||
|
@ -38,6 +46,18 @@ private:
|
||||||
int _tessellation_current_size;
|
int _tessellation_current_size;
|
||||||
double _tessellation_step;
|
double _tessellation_step;
|
||||||
|
|
||||||
|
QMutex _lock_data;
|
||||||
|
|
||||||
|
OpenGLRenderer* _renderer;
|
||||||
|
ColorProfile* _color_profile;
|
||||||
|
|
||||||
|
bool _reset_needed;
|
||||||
|
|
||||||
|
QImage* _texture;
|
||||||
|
QOpenGLTexture* texture;
|
||||||
|
bool _texture_changed;
|
||||||
|
int _texture_current_size;
|
||||||
|
int _texture_max_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "OpenGLSharedState.h"
|
#include "OpenGLSharedState.h"
|
||||||
#include "OpenGLSkybox.h"
|
#include "OpenGLSkybox.h"
|
||||||
#include "OpenGLWater.h"
|
#include "OpenGLWater.h"
|
||||||
|
#include "OpenGLTerrain.h"
|
||||||
|
|
||||||
OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
|
OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
|
||||||
SoftwareRenderer(scenery)
|
SoftwareRenderer(scenery)
|
||||||
|
@ -16,12 +17,14 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
|
||||||
|
|
||||||
skybox = new OpenGLSkybox(this);
|
skybox = new OpenGLSkybox(this);
|
||||||
water = new OpenGLWater(this);
|
water = new OpenGLWater(this);
|
||||||
|
terrain = new OpenGLTerrain(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLRenderer::~OpenGLRenderer()
|
OpenGLRenderer::~OpenGLRenderer()
|
||||||
{
|
{
|
||||||
delete skybox;
|
delete skybox;
|
||||||
delete water;
|
delete water;
|
||||||
|
delete terrain;
|
||||||
|
|
||||||
delete functions;
|
delete functions;
|
||||||
delete shared_state;
|
delete shared_state;
|
||||||
|
@ -60,6 +63,9 @@ void OpenGLRenderer::initialize()
|
||||||
|
|
||||||
water->initialize();
|
water->initialize();
|
||||||
water->updateScenery();
|
water->updateScenery();
|
||||||
|
|
||||||
|
terrain->initialize();
|
||||||
|
terrain->updateScenery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +85,7 @@ void OpenGLRenderer::paint()
|
||||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
skybox->render();
|
skybox->render();
|
||||||
|
terrain->render();
|
||||||
water->render();
|
water->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ private:
|
||||||
|
|
||||||
OpenGLSkybox* skybox;
|
OpenGLSkybox* skybox;
|
||||||
OpenGLWater* water;
|
OpenGLWater* water;
|
||||||
|
OpenGLTerrain* terrain;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
144
src/render/opengl/OpenGLTerrain.cpp
Normal file
144
src/render/opengl/OpenGLTerrain.cpp
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
#include "OpenGLTerrain.h"
|
||||||
|
|
||||||
|
#include OPENGL_FUNCTIONS_INCLUDE
|
||||||
|
#include "OpenGLRenderer.h"
|
||||||
|
#include "OpenGLShaderProgram.h"
|
||||||
|
#include "ParallelPool.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "ExplorerChunkTerrain.h"
|
||||||
|
#include "WaterRenderer.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
#include "Scenery.h"
|
||||||
|
|
||||||
|
class ChunkMaintenanceThreads:public ParallelPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChunkMaintenanceThreads(OpenGLTerrain* terrain):
|
||||||
|
terrain(terrain)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void work() override
|
||||||
|
{
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
terrain->performChunksMaintenance();
|
||||||
|
Thread::timeSleepMs(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLTerrain* terrain;
|
||||||
|
};
|
||||||
|
|
||||||
|
OpenGLTerrain::OpenGLTerrain(OpenGLRenderer *renderer):
|
||||||
|
OpenGLPart(renderer)
|
||||||
|
{
|
||||||
|
work = new ChunkMaintenanceThreads(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLTerrain::~OpenGLTerrain()
|
||||||
|
{
|
||||||
|
delete work;
|
||||||
|
|
||||||
|
for (int i = 0; i < _chunks.count(); i++)
|
||||||
|
{
|
||||||
|
delete _chunks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLTerrain::initialize()
|
||||||
|
{
|
||||||
|
// Prepare shader programs
|
||||||
|
program = createShader("terrain");
|
||||||
|
program->addVertexSource("terrain");
|
||||||
|
program->addFragmentSource("bruneton");
|
||||||
|
program->addFragmentSource("tonemapping");
|
||||||
|
program->addFragmentSource("terrain");
|
||||||
|
|
||||||
|
// Add terrain chunks
|
||||||
|
int chunks = 20;
|
||||||
|
double size = 400.0;
|
||||||
|
double chunksize = size / (double) chunks;
|
||||||
|
double start = -size / 2.0;
|
||||||
|
double water_height = renderer->getWaterRenderer()->getHeightInfo().base_height;
|
||||||
|
for (int i = 0; i < chunks; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < chunks; j++)
|
||||||
|
{
|
||||||
|
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(renderer, start + chunksize * (double) i, start + chunksize * (double) j, chunksize, chunks, water_height);
|
||||||
|
_chunks.append(chunk);
|
||||||
|
_updateQueue.append(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start chunks maintenance
|
||||||
|
work->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLTerrain::update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMP
|
||||||
|
#include "GL/gl.h"
|
||||||
|
#include "GL/glu.h"
|
||||||
|
|
||||||
|
void OpenGLTerrain::render()
|
||||||
|
{
|
||||||
|
CameraDefinition* camera = renderer->getScenery()->getCamera();
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
CameraPerspective perspective = camera->getPerspective();
|
||||||
|
gluPerspective(perspective.yfov * 180.0 / M_PI, perspective.xratio, perspective.znear, perspective.zfar);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
Vector3 camera_location = camera->getLocation();
|
||||||
|
Vector3 camera_target = camera->getTarget();
|
||||||
|
Vector3 camera_up = camera->getUpVector();
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Render chunks
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
for (int i = 0; i < _chunks.count(); i++)
|
||||||
|
{
|
||||||
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
_chunks[i]->render(renderer->getOpenGlFunctions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _cmpChunks(const ExplorerChunkTerrain* c1, const ExplorerChunkTerrain* c2)
|
||||||
|
{
|
||||||
|
return c1->priority > c2->priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLTerrain::performChunksMaintenance()
|
||||||
|
{
|
||||||
|
CameraDefinition* camera = renderer->getScenery()->getCamera();
|
||||||
|
ExplorerChunkTerrain* chunk;
|
||||||
|
|
||||||
|
_lock_chunks.lock();
|
||||||
|
if (_updateQueue.count() > 0)
|
||||||
|
{
|
||||||
|
chunk = _updateQueue.takeFirst();
|
||||||
|
_lock_chunks.unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_lock_chunks.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk->maintain();
|
||||||
|
|
||||||
|
_lock_chunks.lock();
|
||||||
|
_updateQueue.append(chunk);
|
||||||
|
for (int i = 0; i < _chunks.count(); i++)
|
||||||
|
{
|
||||||
|
_chunks[i]->updatePriority(camera);
|
||||||
|
}
|
||||||
|
qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunks);
|
||||||
|
_lock_chunks.unlock();
|
||||||
|
}
|
40
src/render/opengl/OpenGLTerrain.h
Normal file
40
src/render/opengl/OpenGLTerrain.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef OPENGLTERRAIN_H
|
||||||
|
#define OPENGLTERRAIN_H
|
||||||
|
|
||||||
|
#include "opengl_global.h"
|
||||||
|
|
||||||
|
#include "OpenGLPart.h"
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
#include <QList>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace opengl {
|
||||||
|
|
||||||
|
class OPENGLSHARED_EXPORT OpenGLTerrain:public OpenGLPart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenGLTerrain(OpenGLRenderer* renderer);
|
||||||
|
virtual ~OpenGLTerrain();
|
||||||
|
|
||||||
|
virtual void initialize() override;
|
||||||
|
virtual void update() override;
|
||||||
|
virtual void render() override;
|
||||||
|
|
||||||
|
void performChunksMaintenance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenGLShaderProgram* program;
|
||||||
|
|
||||||
|
ParallelPool* work;
|
||||||
|
|
||||||
|
QVector<ExplorerChunkTerrain*> _chunks;
|
||||||
|
QList<ExplorerChunkTerrain*> _updateQueue;
|
||||||
|
QMutex _lock_chunks;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OPENGLTERRAIN_H
|
|
@ -17,44 +17,6 @@
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "LightingManager.h"
|
#include "LightingManager.h"
|
||||||
|
|
||||||
class ChunkMaintenanceThread : public QThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
ChunkMaintenanceThread(WidgetExplorer* wanderer)
|
|
||||||
{
|
|
||||||
_wanderer = wanderer;
|
|
||||||
_running = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void askStop()
|
|
||||||
{
|
|
||||||
_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void usleep(unsigned long us)
|
|
||||||
{
|
|
||||||
QThread::usleep(us);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
while (_running)
|
|
||||||
{
|
|
||||||
_wanderer->performChunksMaintenance();
|
|
||||||
QThread::usleep(10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _running;
|
|
||||||
WidgetExplorer* _wanderer;
|
|
||||||
};
|
|
||||||
|
|
||||||
static QVector<ChunkMaintenanceThread*> _threads;
|
|
||||||
|
|
||||||
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera, Scenery* scenery) :
|
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera, Scenery* scenery) :
|
||||||
QGLWidget(parent)
|
QGLWidget(parent)
|
||||||
{
|
{
|
||||||
|
@ -71,9 +33,6 @@ QGLWidget(parent)
|
||||||
_renderer->getLightingManager()->setSpecularity(false);
|
_renderer->getLightingManager()->setSpecularity(false);
|
||||||
_renderer->disableClouds();
|
_renderer->disableClouds();
|
||||||
|
|
||||||
_inited = false;
|
|
||||||
_updated = false;
|
|
||||||
|
|
||||||
_average_frame_time = 0.05;
|
_average_frame_time = 0.05;
|
||||||
_quality = 3;
|
_quality = 3;
|
||||||
_last_mouse_x = 0;
|
_last_mouse_x = 0;
|
||||||
|
@ -84,103 +43,10 @@ QGLWidget(parent)
|
||||||
|
|
||||||
WidgetExplorer::~WidgetExplorer()
|
WidgetExplorer::~WidgetExplorer()
|
||||||
{
|
{
|
||||||
stopRendering();
|
|
||||||
|
|
||||||
for (int i = 0; i < _chunks.count(); i++)
|
|
||||||
{
|
|
||||||
delete _chunks[i];
|
|
||||||
}
|
|
||||||
delete _current_camera;
|
delete _current_camera;
|
||||||
delete _renderer;
|
delete _renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetExplorer::startRendering()
|
|
||||||
{
|
|
||||||
// Add terrain
|
|
||||||
int chunks = 20;
|
|
||||||
double size = 400.0;
|
|
||||||
double chunksize = size / (double) chunks;
|
|
||||||
double start = -size / 2.0;
|
|
||||||
double water_height = _renderer->getWaterRenderer()->getHeightInfo().base_height;
|
|
||||||
for (int i = 0; i < chunks; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < chunks; j++)
|
|
||||||
{
|
|
||||||
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(_renderer, start + chunksize * (double) i, start + chunksize * (double) j, chunksize, chunks, water_height);
|
|
||||||
_chunks.append(chunk);
|
|
||||||
_updateQueue.append(chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start rendering workers
|
|
||||||
int nbcore;
|
|
||||||
_alive = true;
|
|
||||||
|
|
||||||
nbcore = QThread::idealThreadCount();
|
|
||||||
if (nbcore < 1)
|
|
||||||
{
|
|
||||||
nbcore = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < nbcore; i++)
|
|
||||||
{
|
|
||||||
_threads.append(new ChunkMaintenanceThread(this));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < _threads.count(); i++)
|
|
||||||
{
|
|
||||||
_threads[i]->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WidgetExplorer::stopRendering()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _threads.count(); i++)
|
|
||||||
{
|
|
||||||
_threads[i]->askStop();
|
|
||||||
}
|
|
||||||
_alive = false;
|
|
||||||
for (int i = 0; i < _threads.count(); i++)
|
|
||||||
{
|
|
||||||
_threads[i]->wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _cmpChunks(const BaseExplorerChunk* c1, const BaseExplorerChunk* c2)
|
|
||||||
{
|
|
||||||
return c1->priority > c2->priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WidgetExplorer::performChunksMaintenance()
|
|
||||||
{
|
|
||||||
BaseExplorerChunk* chunk;
|
|
||||||
|
|
||||||
_lock_chunks.lock();
|
|
||||||
if (_updateQueue.count() > 0)
|
|
||||||
{
|
|
||||||
chunk = _updateQueue.takeFirst();
|
|
||||||
_lock_chunks.unlock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_lock_chunks.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunk->maintain())
|
|
||||||
{
|
|
||||||
if (!_alive)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lock_chunks.lock();
|
|
||||||
_updateQueue.append(chunk);
|
|
||||||
_lock_chunks.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WidgetExplorer::resetCamera()
|
void WidgetExplorer::resetCamera()
|
||||||
{
|
{
|
||||||
_base_camera->copy(_current_camera);
|
_base_camera->copy(_current_camera);
|
||||||
|
@ -323,25 +189,7 @@ void WidgetExplorer::wheelEvent(QWheelEvent* event)
|
||||||
|
|
||||||
void WidgetExplorer::timerEvent(QTimerEvent*)
|
void WidgetExplorer::timerEvent(QTimerEvent*)
|
||||||
{
|
{
|
||||||
if (!_inited)
|
|
||||||
{
|
|
||||||
_inited = true;
|
|
||||||
startRendering();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_updated)
|
|
||||||
{
|
|
||||||
_updated = false;
|
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < _chunks.count(); i++)
|
|
||||||
{
|
|
||||||
_chunks[i]->updatePriority(_current_camera);
|
|
||||||
}
|
|
||||||
_lock_chunks.lock();
|
|
||||||
qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunks);
|
|
||||||
_lock_chunks.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetExplorer::initializeGL()
|
void WidgetExplorer::initializeGL()
|
||||||
|
@ -353,11 +201,6 @@ void WidgetExplorer::resizeGL(int w, int h)
|
||||||
{
|
{
|
||||||
_current_camera->setRenderSize(w, h);
|
_current_camera->setRenderSize(w, h);
|
||||||
_renderer->resize(w, h);
|
_renderer->resize(w, h);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
CameraPerspective perspective = _current_camera->getPerspective();
|
|
||||||
gluPerspective(perspective.yfov * 180.0 / M_PI, perspective.xratio, perspective.znear, perspective.zfar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetExplorer::paintGL()
|
void WidgetExplorer::paintGL()
|
||||||
|
@ -376,21 +219,6 @@ void WidgetExplorer::paintGL()
|
||||||
// Background
|
// Background
|
||||||
_renderer->paint();
|
_renderer->paint();
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
Vector3 camera_location = _current_camera->getLocation();
|
|
||||||
Vector3 camera_target = _current_camera->getTarget();
|
|
||||||
Vector3 camera_up = _current_camera->getUpVector();
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Render chunks
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
for (int i = 0; i < _chunks.count(); i++)
|
|
||||||
{
|
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
|
||||||
_chunks[i]->render(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_time = 0.001 * (double) start_time.msecsTo(QTime::currentTime());
|
frame_time = 0.001 * (double) start_time.msecsTo(QTime::currentTime());
|
||||||
|
|
||||||
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
||||||
|
@ -406,13 +234,13 @@ void WidgetExplorer::paintGL()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
if (!_inited)
|
/*if (!_inited)
|
||||||
{
|
{
|
||||||
glColor3f(0.0, 0.0, 0.0);
|
glColor3f(0.0, 0.0, 0.0);
|
||||||
renderText(6, height() - 10, tr("Please wait while loading scene..."));
|
renderText(6, height() - 10, tr("Please wait while loading scene..."));
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
renderText(5, height() - 9, tr("Please wait while loading scene..."));
|
renderText(5, height() - 9, tr("Please wait while loading scene..."));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
while ((error_code = glGetError()) != GL_NO_ERROR)
|
while ((error_code = glGetError()) != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
|
@ -17,8 +15,6 @@ public:
|
||||||
WidgetExplorer(QWidget* parent, CameraDefinition* camera, Scenery* scenery);
|
WidgetExplorer(QWidget* parent, CameraDefinition* camera, Scenery* scenery);
|
||||||
~WidgetExplorer();
|
~WidgetExplorer();
|
||||||
|
|
||||||
void performChunksMaintenance();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void resetCamera();
|
void resetCamera();
|
||||||
void validateCamera();
|
void validateCamera();
|
||||||
|
@ -35,20 +31,10 @@ protected:
|
||||||
void paintGL();
|
void paintGL();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startRendering();
|
|
||||||
void stopRendering();
|
|
||||||
|
|
||||||
CameraDefinition* _current_camera;
|
CameraDefinition* _current_camera;
|
||||||
CameraDefinition* _base_camera;
|
CameraDefinition* _base_camera;
|
||||||
|
|
||||||
OpenGLRenderer* _renderer;
|
OpenGLRenderer* _renderer;
|
||||||
bool _inited;
|
|
||||||
bool _updated;
|
|
||||||
|
|
||||||
QVector<BaseExplorerChunk*> _chunks;
|
|
||||||
QList<BaseExplorerChunk*> _updateQueue;
|
|
||||||
bool _alive;
|
|
||||||
QMutex _lock_chunks;
|
|
||||||
|
|
||||||
double _average_frame_time;
|
double _average_frame_time;
|
||||||
int _quality;
|
int _quality;
|
||||||
|
|
|
@ -15,7 +15,6 @@ include(../../common.pri)
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
OpenGLRenderer.cpp \
|
OpenGLRenderer.cpp \
|
||||||
BaseExplorerChunk.cpp \
|
|
||||||
ExplorerChunkTerrain.cpp \
|
ExplorerChunkTerrain.cpp \
|
||||||
WidgetExplorer.cpp \
|
WidgetExplorer.cpp \
|
||||||
OpenGLShaderProgram.cpp \
|
OpenGLShaderProgram.cpp \
|
||||||
|
@ -23,12 +22,12 @@ SOURCES += \
|
||||||
OpenGLSkybox.cpp \
|
OpenGLSkybox.cpp \
|
||||||
OpenGLWater.cpp \
|
OpenGLWater.cpp \
|
||||||
OpenGLSharedState.cpp \
|
OpenGLSharedState.cpp \
|
||||||
OpenGLVariable.cpp
|
OpenGLVariable.cpp \
|
||||||
|
OpenGLTerrain.cpp
|
||||||
|
|
||||||
HEADERS +=\
|
HEADERS +=\
|
||||||
opengl_global.h \
|
opengl_global.h \
|
||||||
OpenGLRenderer.h \
|
OpenGLRenderer.h \
|
||||||
BaseExplorerChunk.h \
|
|
||||||
ExplorerChunkTerrain.h \
|
ExplorerChunkTerrain.h \
|
||||||
WidgetExplorer.h \
|
WidgetExplorer.h \
|
||||||
OpenGLShaderProgram.h \
|
OpenGLShaderProgram.h \
|
||||||
|
@ -36,7 +35,8 @@ HEADERS +=\
|
||||||
OpenGLSkybox.h \
|
OpenGLSkybox.h \
|
||||||
OpenGLWater.h \
|
OpenGLWater.h \
|
||||||
OpenGLSharedState.h \
|
OpenGLSharedState.h \
|
||||||
OpenGLVariable.h
|
OpenGLVariable.h \
|
||||||
|
OpenGLTerrain.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -15,12 +15,13 @@ namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
class WidgetExplorer;
|
class WidgetExplorer;
|
||||||
class OpenGLRenderer;
|
class OpenGLRenderer;
|
||||||
class BaseExplorerChunk;
|
|
||||||
class OpenGLShaderProgram;
|
class OpenGLShaderProgram;
|
||||||
class OpenGLSharedState;
|
class OpenGLSharedState;
|
||||||
class OpenGLVariable;
|
class OpenGLVariable;
|
||||||
class OpenGLSkybox;
|
class OpenGLSkybox;
|
||||||
class OpenGLWater;
|
class OpenGLWater;
|
||||||
|
class OpenGLTerrain;
|
||||||
|
class ExplorerChunkTerrain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::opengl;
|
using namespace paysages::opengl;
|
||||||
|
|
55
src/system/ParallelPool.cpp
Normal file
55
src/system/ParallelPool.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include "ParallelPool.h"
|
||||||
|
|
||||||
|
#include "System.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
|
static void* _threadFunction(void* data)
|
||||||
|
{
|
||||||
|
ParallelPool* pool = (ParallelPool*)data;
|
||||||
|
pool->work();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelPool::ParallelPool()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelPool::~ParallelPool()
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
{
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
for (auto thread : threads)
|
||||||
|
{
|
||||||
|
thread->join();
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
threads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParallelPool::start(int thread_count)
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
{
|
||||||
|
qCritical("Starting an already started parallel pool !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
running = true;
|
||||||
|
if (thread_count < 0)
|
||||||
|
{
|
||||||
|
thread_count = System::getCoreCount();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < thread_count; i++)
|
||||||
|
{
|
||||||
|
Thread* thread = new Thread(_threadFunction);
|
||||||
|
thread->start(this);
|
||||||
|
threads.push_back(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParallelPool::interrupt()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
43
src/system/ParallelPool.h
Normal file
43
src/system/ParallelPool.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef PARALLELPOOL_H
|
||||||
|
#define PARALLELPOOL_H
|
||||||
|
|
||||||
|
#include "system_global.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Pool to handle a group of threads doing the same task.
|
||||||
|
*/
|
||||||
|
class ParallelPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParallelPool();
|
||||||
|
virtual ~ParallelPool();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Start the effective work.
|
||||||
|
*/
|
||||||
|
void start(int thread_count=-1);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Method called from each thread to do actual work.
|
||||||
|
*/
|
||||||
|
virtual void work() = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Method called once to interrupt all threads.
|
||||||
|
*/
|
||||||
|
virtual void interrupt();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Thread*> threads;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PARALLELPOOL_H
|
|
@ -24,7 +24,8 @@ SOURCES += \
|
||||||
ParallelQueue.cpp \
|
ParallelQueue.cpp \
|
||||||
CacheFile.cpp \
|
CacheFile.cpp \
|
||||||
PictureWriter.cpp \
|
PictureWriter.cpp \
|
||||||
Logs.cpp
|
Logs.cpp \
|
||||||
|
ParallelPool.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
system_global.h \
|
system_global.h \
|
||||||
|
@ -38,7 +39,8 @@ HEADERS += \
|
||||||
ParallelQueue.h \
|
ParallelQueue.h \
|
||||||
CacheFile.h \
|
CacheFile.h \
|
||||||
PictureWriter.h \
|
PictureWriter.h \
|
||||||
Logs.h
|
Logs.h \
|
||||||
|
ParallelPool.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace system {
|
||||||
class PackStream;
|
class PackStream;
|
||||||
class ParallelQueue;
|
class ParallelQueue;
|
||||||
class ParallelWork;
|
class ParallelWork;
|
||||||
|
class ParallelPool;
|
||||||
class Thread;
|
class Thread;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue