Added opengl resources deleting at exit (textures, arrays...)
This commit is contained in:
parent
bc9db69564
commit
479dcb03ac
27 changed files with 203 additions and 65 deletions
|
@ -117,7 +117,7 @@ Vector3 Vector3::midPointTo(const Vector3 &other) const {
|
||||||
Vector3 Vector3::randomInSphere(double radius, bool only_surface, RandomGenerator &random) {
|
Vector3 Vector3::randomInSphere(double radius, bool only_surface, RandomGenerator &random) {
|
||||||
// TODO More uniform spatial repartition
|
// TODO More uniform spatial repartition
|
||||||
// The current randomization clusters result near the center and at the poles
|
// The current randomization clusters result near the center and at the poles
|
||||||
VectorSpherical vec = {only_surface ? radius : random.genDouble() * radius,
|
VectorSpherical vec = {only_surface ? radius : random.genDouble() * radius, (random.genDouble() - 0.5) * M_PI,
|
||||||
(random.genDouble() - 0.5) * M_PI, random.genDouble() * M_2PI};
|
random.genDouble() * M_2PI};
|
||||||
return Vector3(vec);
|
return Vector3(vec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@ class BASICSSHARED_EXPORT Vector3 {
|
||||||
*
|
*
|
||||||
* If *only_surface* is true, produce a vector with *radius* as length.
|
* If *only_surface* is true, produce a vector with *radius* as length.
|
||||||
*/
|
*/
|
||||||
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false, RandomGenerator &random = RandomGeneratorDefault);
|
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false,
|
||||||
|
RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO Make private
|
// TODO Make private
|
||||||
|
|
|
@ -153,9 +153,8 @@ void AtmosphereDefinition::generateStars(int count, RandomGenerator &random) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
Star star;
|
Star star;
|
||||||
|
|
||||||
star.location =
|
star.location = Vector3((random.genDouble() - 0.5) * 100000.0, (random.genDouble() * 0.5) * 100000.0,
|
||||||
Vector3((random.genDouble() - 0.5) * 100000.0, (random.genDouble() * 0.5) * 100000.0,
|
(random.genDouble() - 0.5) * 100000.0);
|
||||||
(random.genDouble() - 0.5) * 100000.0);
|
|
||||||
if (star.location.getNorm() < 30000.0) {
|
if (star.location.getNorm() < 30000.0) {
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -108,8 +108,7 @@ void Scenery::autoPreset(RandomGenerator &random) {
|
||||||
Logs::debug() << "[Definition] New scenery generated from seed " << random.getSeed() << std::endl;
|
Logs::debug() << "[Definition] New scenery generated from seed " << random.getSeed() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scenery::autoPreset(unsigned int seed)
|
void Scenery::autoPreset(unsigned int seed) {
|
||||||
{
|
|
||||||
RandomGenerator random(seed);
|
RandomGenerator random(seed);
|
||||||
autoPreset(random);
|
autoPreset(random);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,23 +42,11 @@ MainModelerWindow::MainModelerWindow() {
|
||||||
|
|
||||||
render_process = new RenderProcess(this, render_preview_provider);
|
render_process = new RenderProcess(this, render_preview_provider);
|
||||||
|
|
||||||
// Bind file buttons
|
connectQmlSignal("tool_file_new", SIGNAL(clicked()), this, SLOT(newFile()));
|
||||||
QObject *button_new = findQmlObject("tool_file_new");
|
connectQmlSignal("tool_file_save", SIGNAL(clicked()), this, SLOT(saveFile()));
|
||||||
if (button_new) {
|
connectQmlSignal("tool_file_load", SIGNAL(clicked()), this, SLOT(loadFile()));
|
||||||
connect(button_new, SIGNAL(clicked()), this, SLOT(newFile()));
|
connectQmlSignal("tool_file_exit", SIGNAL(clicked()), this, SLOT(exit()));
|
||||||
}
|
connectQmlSignal("root", SIGNAL(stopped()), this, SLOT(effectiveExit()));
|
||||||
QObject *button_save = findQmlObject("tool_file_save");
|
|
||||||
if (button_save) {
|
|
||||||
connect(button_save, SIGNAL(clicked()), this, SLOT(saveFile()));
|
|
||||||
}
|
|
||||||
QObject *button_load = findQmlObject("tool_file_load");
|
|
||||||
if (button_load) {
|
|
||||||
connect(button_load, SIGNAL(clicked()), this, SLOT(loadFile()));
|
|
||||||
}
|
|
||||||
QObject *button_exit = findQmlObject("tool_file_exit");
|
|
||||||
if (button_exit) {
|
|
||||||
connect(button_exit, SIGNAL(clicked()), this, SLOT(exit()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainModelerWindow::~MainModelerWindow() {
|
MainModelerWindow::~MainModelerWindow() {
|
||||||
|
@ -126,7 +114,7 @@ void MainModelerWindow::loadFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainModelerWindow::exit() {
|
void MainModelerWindow::exit() {
|
||||||
close();
|
renderer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) {
|
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) {
|
||||||
|
@ -178,3 +166,7 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainModelerWindow::effectiveExit() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
|
@ -40,6 +40,9 @@ class MainModelerWindow : public QQuickView {
|
||||||
protected:
|
protected:
|
||||||
virtual void keyReleaseEvent(QKeyEvent *event) override;
|
virtual void keyReleaseEvent(QKeyEvent *event) override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void effectiveExit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scenery *scenery;
|
Scenery *scenery;
|
||||||
OpenGLRenderer *renderer;
|
OpenGLRenderer *renderer;
|
||||||
|
|
|
@ -41,6 +41,11 @@ void OpenGLView::paint() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (renderer->isStopped()) {
|
||||||
|
emit stopped();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (not initialized or not renderer) {
|
if (not initialized or not renderer) {
|
||||||
renderer->initialize();
|
renderer->initialize();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
|
@ -19,6 +19,9 @@ class OpenGLView : public QQuickItem {
|
||||||
void handleResize();
|
void handleResize();
|
||||||
void handleSceneGraphReady();
|
void handleSceneGraphReady();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void stopped();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void wheelEvent(QWheelEvent *event) override;
|
virtual void wheelEvent(QWheelEvent *event) override;
|
||||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "OpenGLPart.h"
|
#include "OpenGLPart.h"
|
||||||
|
|
||||||
|
#include "OpenGLRenderer.h"
|
||||||
#include "OpenGLShaderProgram.h"
|
#include "OpenGLShaderProgram.h"
|
||||||
#include "OpenGLVertexArray.h"
|
#include "OpenGLVertexArray.h"
|
||||||
|
|
||||||
|
@ -7,14 +8,25 @@ OpenGLPart::OpenGLPart(OpenGLRenderer *renderer) : renderer(renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLPart::~OpenGLPart() {
|
OpenGLPart::~OpenGLPart() {
|
||||||
for (auto &pair: shaders) {
|
for (auto pair : shaders) {
|
||||||
delete pair.second;
|
delete pair.second;
|
||||||
}
|
}
|
||||||
for (auto &array: arrays) {
|
for (auto array : arrays) {
|
||||||
delete array;
|
delete array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLPart::destroy() {
|
||||||
|
OpenGLFunctions *functions = getFunctions();
|
||||||
|
|
||||||
|
for (auto shader : shaders) {
|
||||||
|
shader.second->destroy(functions);
|
||||||
|
}
|
||||||
|
for (auto array : arrays) {
|
||||||
|
array->destroy(functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLPart::interrupt() {
|
void OpenGLPart::interrupt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +41,16 @@ OpenGLShaderProgram *OpenGLPart::createShader(const std::string &name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLVertexArray *OpenGLPart::createVertexArray(bool has_uv, bool strip)
|
OpenGLVertexArray *OpenGLPart::createVertexArray(bool has_uv, bool strip) {
|
||||||
{
|
|
||||||
OpenGLVertexArray *result = new OpenGLVertexArray(has_uv, strip);
|
OpenGLVertexArray *result = new OpenGLVertexArray(has_uv, strip);
|
||||||
arrays.push_back(result);
|
arrays.push_back(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenGLFunctions *OpenGLPart::getFunctions() {
|
||||||
|
return renderer->getOpenGlFunctions();
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLPart::updateScenery(bool onlyCommon) {
|
void OpenGLPart::updateScenery(bool onlyCommon) {
|
||||||
// Let subclass do its own collecting
|
// Let subclass do its own collecting
|
||||||
if (not onlyCommon) {
|
if (not onlyCommon) {
|
||||||
|
|
|
@ -26,6 +26,9 @@ class OPENGLSHARED_EXPORT OpenGLPart {
|
||||||
// Do the rendering
|
// Do the rendering
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
|
||||||
|
// Free opengl resources generated in context (like textures...)
|
||||||
|
virtual void destroy();
|
||||||
|
|
||||||
// Interrupt the rendering
|
// Interrupt the rendering
|
||||||
virtual void interrupt();
|
virtual void interrupt();
|
||||||
|
|
||||||
|
@ -46,6 +49,8 @@ class OPENGLSHARED_EXPORT OpenGLPart {
|
||||||
*/
|
*/
|
||||||
OpenGLVertexArray *createVertexArray(bool has_uv, bool strip);
|
OpenGLVertexArray *createVertexArray(bool has_uv, bool strip);
|
||||||
|
|
||||||
|
OpenGLFunctions *getFunctions();
|
||||||
|
|
||||||
// Access to the main scenery renderer
|
// Access to the main scenery renderer
|
||||||
OpenGLRenderer *renderer;
|
OpenGLRenderer *renderer;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ OpenGLRenderer::OpenGLRenderer(Scenery *scenery) : SoftwareRenderer(scenery) {
|
||||||
ready = false;
|
ready = false;
|
||||||
paused = false;
|
paused = false;
|
||||||
displayed = false;
|
displayed = false;
|
||||||
|
stopping = false;
|
||||||
|
stopped = false;
|
||||||
vp_width = 1;
|
vp_width = 1;
|
||||||
vp_height = 1;
|
vp_height = 1;
|
||||||
|
|
||||||
|
@ -65,6 +67,16 @@ void OpenGLRenderer::checkForErrors(const std::string &domain) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::destroy() {
|
||||||
|
shared_state->destroy(functions);
|
||||||
|
|
||||||
|
skybox->destroy();
|
||||||
|
terrain->destroy();
|
||||||
|
water->destroy();
|
||||||
|
|
||||||
|
checkForErrors("stopping");
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::initialize() {
|
void OpenGLRenderer::initialize() {
|
||||||
ready = functions->initializeOpenGLFunctions();
|
ready = functions->initializeOpenGLFunctions();
|
||||||
|
|
||||||
|
@ -145,7 +157,12 @@ void OpenGLRenderer::resize(int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::paint(bool clear) {
|
void OpenGLRenderer::paint(bool clear) {
|
||||||
if (ready and not paused) {
|
if (stopping) {
|
||||||
|
if (not stopped) {
|
||||||
|
destroy();
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
} else if (ready and not paused) {
|
||||||
checkForErrors("before_paint");
|
checkForErrors("before_paint");
|
||||||
if (clear) {
|
if (clear) {
|
||||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
@ -169,6 +186,11 @@ void OpenGLRenderer::paint(bool clear) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLRenderer::stop() {
|
||||||
|
stopping = true;
|
||||||
|
return stopped;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::reset() {
|
void OpenGLRenderer::reset() {
|
||||||
if (ready) {
|
if (ready) {
|
||||||
skybox->updateScenery();
|
skybox->updateScenery();
|
||||||
|
|
|
@ -10,8 +10,8 @@ class QMatrix4x4;
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
* \brief Scenery renderer in an OpenGL context.
|
* Scenery renderer in an OpenGL context.
|
||||||
*/
|
*/
|
||||||
class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
public:
|
public:
|
||||||
|
@ -30,6 +30,12 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
inline bool isDisplayed() const {
|
inline bool isDisplayed() const {
|
||||||
return displayed;
|
return displayed;
|
||||||
}
|
}
|
||||||
|
inline bool isStopping() const {
|
||||||
|
return stopping;
|
||||||
|
}
|
||||||
|
inline bool isStopped() const {
|
||||||
|
return stopped;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for errors in OpenGL context.
|
* Check for errors in OpenGL context.
|
||||||
|
@ -38,10 +44,26 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
*/
|
*/
|
||||||
void checkForErrors(const std::string &domain);
|
void checkForErrors(const std::string &domain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any allocated resource in the opengl context.
|
||||||
|
*
|
||||||
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
|
*/
|
||||||
|
void destroy();
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void prepareOpenGLState(bool clear=true);
|
void prepareOpenGLState(bool clear = true);
|
||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
void paint(bool clear=true);
|
void paint(bool clear = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask for the rendering to stop gracefully.
|
||||||
|
*
|
||||||
|
* Returns true if the rendering is stopped and resources freed.
|
||||||
|
*
|
||||||
|
* This should be called in an idle loop, while it returns false.
|
||||||
|
*/
|
||||||
|
bool stop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the whole state (when the scenery has been massively updated).
|
* Reset the whole state (when the scenery has been massively updated).
|
||||||
|
@ -95,6 +117,8 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
bool ready;
|
bool ready;
|
||||||
bool paused;
|
bool paused;
|
||||||
bool displayed;
|
bool displayed;
|
||||||
|
bool stopping;
|
||||||
|
bool stopped;
|
||||||
int vp_width;
|
int vp_width;
|
||||||
int vp_height;
|
int vp_height;
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,10 @@ void OpenGLShaderProgram::addFragmentSource(const std::string &path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLShaderProgram::destroy(OpenGLFunctions *functions) {
|
||||||
|
program->removeAllShaders();
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLShaderProgram::compile() {
|
void OpenGLShaderProgram::compile() {
|
||||||
std::string prefix = std::string("#version ") + OPENGL_GLSL_VERSION + "\n\n";
|
std::string prefix = std::string("#version ") + OPENGL_GLSL_VERSION + "\n\n";
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,13 @@ class OPENGLSHARED_EXPORT OpenGLShaderProgram {
|
||||||
void addVertexSource(const std::string &path);
|
void addVertexSource(const std::string &path);
|
||||||
void addFragmentSource(const std::string &path);
|
void addFragmentSource(const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any allocated resource in the opengl context.
|
||||||
|
*
|
||||||
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
|
*/
|
||||||
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a VertexArray object.
|
* Draw a VertexArray object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,6 +15,12 @@ void OpenGLSharedState::apply(OpenGLShaderProgram *program, int &texture_unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLSharedState::destroy(OpenGLFunctions *functions) {
|
||||||
|
for (const auto &pair : variables) {
|
||||||
|
pair.second->destroy(functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OpenGLVariable *OpenGLSharedState::get(const std::string &name) {
|
OpenGLVariable *OpenGLSharedState::get(const std::string &name) {
|
||||||
OpenGLVariable *&var = variables[name];
|
OpenGLVariable *&var = variables[name];
|
||||||
if (var == NULL) {
|
if (var == NULL) {
|
||||||
|
|
|
@ -11,21 +11,28 @@ class QImage;
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
* \brief OpenGL variables that can be shared between shaders.
|
* OpenGL variables that can be shared between shaders.
|
||||||
*/
|
*/
|
||||||
class OPENGLSHARED_EXPORT OpenGLSharedState {
|
class OPENGLSHARED_EXPORT OpenGLSharedState {
|
||||||
public:
|
public:
|
||||||
OpenGLSharedState();
|
OpenGLSharedState();
|
||||||
~OpenGLSharedState();
|
~OpenGLSharedState();
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
* \brief Apply the stored variables to the bound program.
|
* Apply the stored variables to the bound program.
|
||||||
*/
|
*/
|
||||||
void apply(OpenGLShaderProgram *program, int &texture_unit);
|
void apply(OpenGLShaderProgram *program, int &texture_unit);
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
* \brief Get or create a variable in the state.
|
* Release any allocated resource in the opengl context.
|
||||||
|
*
|
||||||
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
|
*/
|
||||||
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create a variable in the state.
|
||||||
*/
|
*/
|
||||||
OpenGLVariable *get(const std::string &name);
|
OpenGLVariable *get(const std::string &name);
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ void OpenGLTerrain::initialize() {
|
||||||
for (int i = 0; i < chunks; i++) {
|
for (int i = 0; i < chunks; i++) {
|
||||||
for (int j = 0; j < chunks; j++) {
|
for (int j = 0; j < chunks; j++) {
|
||||||
OpenGLTerrainChunk *chunk = new OpenGLTerrainChunk(renderer, start + chunksize * (double)i,
|
OpenGLTerrainChunk *chunk = new OpenGLTerrainChunk(renderer, start + chunksize * (double)i,
|
||||||
start + chunksize * (double)j, chunksize, chunks);
|
start + chunksize * (double)j, chunksize, chunks);
|
||||||
_chunks.append(chunk);
|
_chunks.append(chunk);
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,13 @@ void OpenGLTerrain::interrupt() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLTerrain::destroy() {
|
||||||
|
OpenGLFunctions *functions = getFunctions();
|
||||||
|
for (auto &chunk : _chunks) {
|
||||||
|
chunk->destroy(functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLTerrain::pause() {
|
void OpenGLTerrain::pause() {
|
||||||
paused = true;
|
paused = true;
|
||||||
interrupt();
|
interrupt();
|
||||||
|
|
|
@ -22,6 +22,7 @@ class OPENGLSHARED_EXPORT OpenGLTerrain : public OpenGLPart, public DefinitionWa
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void render() override;
|
virtual void render() override;
|
||||||
virtual void interrupt() override;
|
virtual void interrupt() override;
|
||||||
|
virtual void destroy() override;
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
|
|
|
@ -146,14 +146,14 @@ void OpenGLTerrainChunk::updatePriority(CameraDefinition *camera) {
|
||||||
_lock_data->release();
|
_lock_data->release();
|
||||||
|
|
||||||
// Update wanted LOD
|
// Update wanted LOD
|
||||||
if (distance_to_camera < 60.0) {
|
if (distance_to_camera < 100.0) {
|
||||||
_texture_wanted_size = _texture_max_size;
|
_texture_wanted_size = _texture_max_size;
|
||||||
} else if (distance_to_camera < 140.0) {
|
} else if (distance_to_camera < 200.0) {
|
||||||
_texture_wanted_size = _texture_max_size / 4;
|
_texture_wanted_size = _texture_max_size / 4;
|
||||||
} else if (distance_to_camera < 300.0) {
|
} else if (distance_to_camera < 400.0) {
|
||||||
_texture_wanted_size = _texture_max_size / 8;
|
_texture_wanted_size = _texture_max_size / 8;
|
||||||
} else {
|
} else {
|
||||||
_texture_wanted_size = 8;
|
_texture_wanted_size = _texture_max_size / 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update priority
|
// Update priority
|
||||||
|
@ -195,6 +195,11 @@ void OpenGLTerrainChunk::askResume() {
|
||||||
interrupt = false;
|
interrupt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLTerrainChunk::destroy(OpenGLFunctions *functions) {
|
||||||
|
vertices->destroy(functions);
|
||||||
|
glstate->destroy(functions);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLTerrainChunk::setFirstStepVertices() {
|
void OpenGLTerrainChunk::setFirstStepVertices() {
|
||||||
OpenGLVertexArray next(true);
|
OpenGLVertexArray next(true);
|
||||||
next.setVertexCount(6);
|
next.setVertexCount(6);
|
||||||
|
@ -210,6 +215,9 @@ void OpenGLTerrainChunk::augmentVertices() {
|
||||||
// TODO Re-use existing vertices from previous level when possible
|
// TODO Re-use existing vertices from previous level when possible
|
||||||
double quad_size = _size / (double)next_vertices_level;
|
double quad_size = _size / (double)next_vertices_level;
|
||||||
for (int iz = 0; iz < next_vertices_level; iz++) {
|
for (int iz = 0; iz < next_vertices_level; iz++) {
|
||||||
|
if (interrupt or _reset_topology) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (int ix = 0; ix < next_vertices_level; ix++) {
|
for (int ix = 0; ix < next_vertices_level; ix++) {
|
||||||
fillVerticesFromSquare(&next, (iz * next_vertices_level + ix) * 6, _startx + quad_size * (double)ix,
|
fillVerticesFromSquare(&next, (iz * next_vertices_level + ix) * 6, _startx + quad_size * (double)ix,
|
||||||
_startz + quad_size * (double)iz, quad_size);
|
_startz + quad_size * (double)iz, quad_size);
|
||||||
|
|
|
@ -28,6 +28,13 @@ class OPENGLSHARED_EXPORT OpenGLTerrainChunk {
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any allocated resource in the opengl context.
|
||||||
|
*
|
||||||
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
|
*/
|
||||||
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill *vertices* with a quick initial set of vertices, that can be augmented later using *augmentVertices*.
|
* Fill *vertices* with a quick initial set of vertices, that can be augmented later using *augmentVertices*.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -79,6 +79,13 @@ void OpenGLVariable::apply(OpenGLShaderProgram *program, int &texture_unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLVariable::destroy(OpenGLFunctions *functions) {
|
||||||
|
if (texture_id) {
|
||||||
|
functions->glDeleteTextures(1, &texture_id);
|
||||||
|
texture_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLVariable::set(const Texture2D *texture, bool repeat, bool color) {
|
void OpenGLVariable::set(const Texture2D *texture, bool repeat, bool color) {
|
||||||
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
||||||
|
|
||||||
|
@ -111,8 +118,7 @@ void OpenGLVariable::set(const Texture2D *texture, bool repeat, bool color) {
|
||||||
texture_color = color;
|
texture_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVariable::set(const QImage &texture, bool repeat, bool color)
|
void OpenGLVariable::set(const QImage &texture, bool repeat, bool color) {
|
||||||
{
|
|
||||||
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
assert(type == TYPE_NONE or type == TYPE_TEXTURE_2D);
|
||||||
|
|
||||||
type = TYPE_TEXTURE_2D;
|
type = TYPE_TEXTURE_2D;
|
||||||
|
@ -272,8 +278,10 @@ void OpenGLVariable::uploadTexture(OpenGLRenderer *renderer) {
|
||||||
int dest_format = texture_color ? GL_RGBA : GL_RED;
|
int dest_format = texture_color ? GL_RGBA : GL_RED;
|
||||||
|
|
||||||
if (type == TYPE_TEXTURE_2D) {
|
if (type == TYPE_TEXTURE_2D) {
|
||||||
functions->glTexImage2D(GL_TEXTURE_2D, 0, dest_format, texture_size_x, texture_size_y, 0, GL_RGBA, GL_FLOAT, value_texture_data);
|
functions->glTexImage2D(GL_TEXTURE_2D, 0, dest_format, texture_size_x, texture_size_y, 0, GL_RGBA, GL_FLOAT,
|
||||||
|
value_texture_data);
|
||||||
} else {
|
} else {
|
||||||
functions->glTexImage3D(GL_TEXTURE_3D, 0, dest_format, texture_size_x, texture_size_y, texture_size_z, 0, GL_RGBA, GL_FLOAT, value_texture_data);
|
functions->glTexImage3D(GL_TEXTURE_3D, 0, dest_format, texture_size_x, texture_size_y, texture_size_z, 0,
|
||||||
|
GL_RGBA, GL_FLOAT, value_texture_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,13 @@ class OpenGLVariable {
|
||||||
|
|
||||||
void apply(OpenGLShaderProgram *program, int &texture_unit);
|
void apply(OpenGLShaderProgram *program, int &texture_unit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release any allocated resource in the opengl context.
|
||||||
|
*
|
||||||
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
|
*/
|
||||||
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
void set(const Texture2D *texture, bool repeat = false, bool color = true);
|
void set(const Texture2D *texture, bool repeat = false, bool color = true);
|
||||||
void set(const QImage &texture, bool repeat = false, bool color = true);
|
void set(const QImage &texture, bool repeat = false, bool color = true);
|
||||||
void set(const Texture3D *texture, bool repeat = false, bool color = true);
|
void set(const Texture3D *texture, bool repeat = false, bool color = true);
|
||||||
|
|
|
@ -30,8 +30,19 @@ OpenGLVertexArray::~OpenGLVertexArray() {
|
||||||
free(array_uv);
|
free(array_uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVertexArray::destroy() {
|
void OpenGLVertexArray::destroy(OpenGLFunctions *functions) {
|
||||||
// TODO
|
if (vbo_vertex) {
|
||||||
|
functions->glDeleteBuffers(1, &vbo_vertex);
|
||||||
|
vbo_vertex = 0;
|
||||||
|
}
|
||||||
|
if (vbo_uv) {
|
||||||
|
functions->glDeleteBuffers(1, &vbo_uv);
|
||||||
|
vbo_uv = 0;
|
||||||
|
}
|
||||||
|
if (vao) {
|
||||||
|
functions->glDeleteVertexArrays(1, &vao);
|
||||||
|
vao = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVertexArray::render(OpenGLFunctions *functions) {
|
void OpenGLVertexArray::render(OpenGLFunctions *functions) {
|
||||||
|
@ -72,8 +83,7 @@ void OpenGLVertexArray::set(int index, const Vector3 &location, double u, double
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVertexArray::get(int index, Vector3 *location, double *u, double *v) const
|
void OpenGLVertexArray::get(int index, Vector3 *location, double *u, double *v) const {
|
||||||
{
|
|
||||||
if (index >= 0 and index < vertexcount) {
|
if (index >= 0 and index < vertexcount) {
|
||||||
location->x = array_vertex[index * 3];
|
location->x = array_vertex[index * 3];
|
||||||
location->y = array_vertex[index * 3 + 1];
|
location->y = array_vertex[index * 3 + 1];
|
||||||
|
@ -85,8 +95,7 @@ void OpenGLVertexArray::get(int index, Vector3 *location, double *u, double *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVertexArray::copyTo(OpenGLVertexArray *destination) const
|
void OpenGLVertexArray::copyTo(OpenGLVertexArray *destination) const {
|
||||||
{
|
|
||||||
destination->setVertexCount(vertexcount);
|
destination->setVertexCount(vertexcount);
|
||||||
if (vertexcount) {
|
if (vertexcount) {
|
||||||
memcpy(destination->array_vertex, array_vertex, sizeof(float) * vertexcount * 3);
|
memcpy(destination->array_vertex, array_vertex, sizeof(float) * vertexcount * 3);
|
||||||
|
|
|
@ -25,7 +25,7 @@ class OpenGLVertexArray {
|
||||||
*
|
*
|
||||||
* Must be called in the opengl rendering thread, and before the destructor is called.
|
* Must be called in the opengl rendering thread, and before the destructor is called.
|
||||||
*/
|
*/
|
||||||
void destroy();
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render this array in current opengl context.
|
* Render this array in current opengl context.
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
static RandomGenerator _RandomGeneratorDefault;
|
static RandomGenerator _RandomGeneratorDefault;
|
||||||
RandomGenerator& paysages::system::RandomGeneratorDefault = _RandomGeneratorDefault;
|
RandomGenerator &paysages::system::RandomGeneratorDefault = _RandomGeneratorDefault;
|
||||||
|
|
||||||
class RandomGenerator::RandomGeneratorPrivate {
|
class RandomGenerator::RandomGeneratorPrivate {
|
||||||
public:
|
public:
|
||||||
RandomGeneratorPrivate(unsigned int seed): generator(seed) {
|
RandomGeneratorPrivate(unsigned int seed) : generator(seed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::default_random_engine generator;
|
std::default_random_engine generator;
|
||||||
|
@ -27,12 +27,10 @@ RandomGenerator::RandomGenerator(RandomGenerator::Seed seed) {
|
||||||
data = new RandomGeneratorPrivate(seed);
|
data = new RandomGeneratorPrivate(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomGenerator::~RandomGenerator()
|
RandomGenerator::~RandomGenerator() {
|
||||||
{
|
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
double RandomGenerator::genDouble()
|
double RandomGenerator::genDouble() {
|
||||||
{
|
|
||||||
return data->distribution_double(data->generator);
|
return data->distribution_double(data->generator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ class PictureWriter;
|
||||||
class Time;
|
class Time;
|
||||||
class RandomGenerator;
|
class RandomGenerator;
|
||||||
|
|
||||||
extern RandomGenerator& RandomGeneratorDefault;
|
extern RandomGenerator &RandomGeneratorDefault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::system;
|
using namespace paysages::system;
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
#include "OpenGLVertexArray.h"
|
#include "OpenGLVertexArray.h"
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
static void checkVertex(const OpenGLVertexArray *array, int index, const Vector3 &expected_location, double expected_u, double expected_v) {
|
static void checkVertex(const OpenGLVertexArray *array, int index, const Vector3 &expected_location, double expected_u,
|
||||||
|
double expected_v) {
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
double u, v;
|
double u, v;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue