Merge branch 'master' into vegetation
Conflicts: src/interface/commandline/tests.cpp src/render/opengl/OpenGLPart.h src/render/opengl/OpenGLRenderer.cpp src/render/opengl/OpenGLRenderer.h src/render/opengl/OpenGLShaderProgram.h src/render/opengl/OpenGLSharedState.h src/render/software/SoftwareCanvasRenderer.h
This commit is contained in:
commit
4a710c0977
118 changed files with 640 additions and 457 deletions
|
@ -35,7 +35,7 @@ class BASICSSHARED_EXPORT NoiseState {
|
||||||
void setLevelCount(int level_count);
|
void setLevelCount(int level_count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<NoiseOffset> level_offsets;
|
vector<NoiseOffset> level_offsets;
|
||||||
|
|
||||||
friend class NoiseGenerator;
|
friend class NoiseGenerator;
|
||||||
friend class FractalNoise;
|
friend class FractalNoise;
|
||||||
|
|
|
@ -152,7 +152,7 @@ class Texture2DWriter : public PictureWriter {
|
||||||
const Texture2D *tex;
|
const Texture2D *tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Texture2D::saveToFile(const std::string &filepath) const {
|
void Texture2D::saveToFile(const string &filepath) const {
|
||||||
Texture2DWriter writer(this);
|
Texture2DWriter writer(this);
|
||||||
writer.save(filepath, xsize, ysize);
|
writer.save(filepath, xsize, ysize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class BASICSSHARED_EXPORT Texture2D {
|
||||||
void add(Texture2D *other);
|
void add(Texture2D *other);
|
||||||
void save(PackStream *stream) const;
|
void save(PackStream *stream) const;
|
||||||
void load(PackStream *stream);
|
void load(PackStream *stream);
|
||||||
void saveToFile(const std::string &filepath) const;
|
void saveToFile(const string &filepath) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int xsize;
|
int xsize;
|
||||||
|
|
|
@ -187,7 +187,7 @@ class Texture3DWriter : public PictureWriter {
|
||||||
const Texture3D *tex;
|
const Texture3D *tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Texture3D::saveToFile(const std::string &filepath) const {
|
void Texture3D::saveToFile(const string &filepath) const {
|
||||||
Texture3DWriter writer(this);
|
Texture3DWriter writer(this);
|
||||||
writer.save(filepath, xsize, ysize * zsize);
|
writer.save(filepath, xsize, ysize * zsize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class BASICSSHARED_EXPORT Texture3D {
|
||||||
void add(Texture3D *other);
|
void add(Texture3D *other);
|
||||||
void save(PackStream *stream) const;
|
void save(PackStream *stream) const;
|
||||||
void load(PackStream *stream);
|
void load(PackStream *stream);
|
||||||
void saveToFile(const std::string &filepath) const;
|
void saveToFile(const string &filepath) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int xsize;
|
int xsize;
|
||||||
|
|
|
@ -230,7 +230,7 @@ class Texture4DWriter : public PictureWriter {
|
||||||
const Texture4D *tex;
|
const Texture4D *tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Texture4D::saveToFile(const std::string &filepath) const {
|
void Texture4D::saveToFile(const string &filepath) const {
|
||||||
Texture4DWriter writer(this);
|
Texture4DWriter writer(this);
|
||||||
writer.save(filepath, xsize * wsize, ysize * zsize);
|
writer.save(filepath, xsize * wsize, ysize * zsize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class BASICSSHARED_EXPORT Texture4D {
|
||||||
void add(Texture4D *other);
|
void add(Texture4D *other);
|
||||||
void save(PackStream *stream) const;
|
void save(PackStream *stream) const;
|
||||||
void load(PackStream *stream);
|
void load(PackStream *stream);
|
||||||
void saveToFile(const std::string &filepath) const;
|
void saveToFile(const string &filepath) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int xsize;
|
int xsize;
|
||||||
|
|
|
@ -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,8 +153,7 @@ 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--;
|
||||||
|
|
|
@ -77,7 +77,7 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
||||||
double moon_theta;
|
double moon_theta;
|
||||||
double moon_phi;
|
double moon_phi;
|
||||||
|
|
||||||
std::vector<Star> stars;
|
vector<Star> stars;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GodRaysDefinition *godrays;
|
GodRaysDefinition *godrays;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
|
|
||||||
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent, const std::string &name)
|
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent, const string &name)
|
||||||
: DefinitionNode(parent, name, "cloudlayer") {
|
: DefinitionNode(parent, name, "cloudlayer") {
|
||||||
type = CIRRUS;
|
type = CIRRUS;
|
||||||
altitude = 0.5;
|
altitude = 0.5;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace definition {
|
||||||
|
|
||||||
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode {
|
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
CloudLayerDefinition(DefinitionNode *parent, const std::string &name);
|
CloudLayerDefinition(DefinitionNode *parent, const string &name);
|
||||||
virtual ~CloudLayerDefinition();
|
virtual ~CloudLayerDefinition();
|
||||||
|
|
||||||
inline const NoiseState &getNoiseState() const {
|
inline const NoiseState &getNoiseState() const {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "CloudLayerDefinition.h"
|
#include "CloudLayerDefinition.h"
|
||||||
|
|
||||||
static DefinitionNode *_layerConstructor(Layers *parent, const std::string &name) {
|
static DefinitionNode *_layerConstructor(Layers *parent, const string &name) {
|
||||||
return new CloudLayerDefinition(parent, name);
|
return new CloudLayerDefinition(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,16 @@ class DEFINITIONSHARED_EXPORT DefinitionDiff {
|
||||||
DefinitionDiff(const DefinitionNode *node);
|
DefinitionDiff(const DefinitionNode *node);
|
||||||
virtual ~DefinitionDiff();
|
virtual ~DefinitionDiff();
|
||||||
|
|
||||||
inline const std::string &getTypeName() const {
|
inline const string &getTypeName() const {
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
inline const std::string &getPath() const {
|
inline const string &getPath() const {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string type_name;
|
string type_name;
|
||||||
std::string path;
|
string path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
DefinitionNode::DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name)
|
DefinitionNode::DefinitionNode(DefinitionNode *parent, const string &name, const string &type_name)
|
||||||
: parent(parent), type_name(type_name), name(name) {
|
: parent(parent), type_name(type_name), name(name) {
|
||||||
if (parent) {
|
if (parent) {
|
||||||
root = parent->root;
|
root = parent->root;
|
||||||
|
@ -33,7 +33,7 @@ DefinitionNode::~DefinitionNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
|
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
|
||||||
std::vector<DefinitionNode *> children_copy = children;
|
vector<DefinitionNode *> children_copy = children;
|
||||||
for (auto child : children_copy) {
|
for (auto child : children_copy) {
|
||||||
if (child->getParent() == this) {
|
if (child->getParent() == this) {
|
||||||
delete child;
|
delete child;
|
||||||
|
@ -41,7 +41,7 @@ DefinitionNode::~DefinitionNode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::setName(const std::string &name) {
|
void DefinitionNode::setName(const string &name) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ const Scenery *DefinitionNode::getScenery() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefinitionNode::toString(int indent) const {
|
string DefinitionNode::toString(int indent) const {
|
||||||
std::string result;
|
string result;
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
result += " ";
|
result += " ";
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ std::string DefinitionNode::toString(int indent) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefinitionNode::getPath() const {
|
string DefinitionNode::getPath() const {
|
||||||
if (parent == root) {
|
if (parent == root) {
|
||||||
return parent->getPath() + name;
|
return parent->getPath() + name;
|
||||||
} else if (parent) {
|
} else if (parent) {
|
||||||
|
@ -77,7 +77,7 @@ std::string DefinitionNode::getPath() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const {
|
DefinitionNode *DefinitionNode::findByPath(const string &path) const {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (path[0] == '/') {
|
} else if (path[0] == '/') {
|
||||||
|
@ -90,11 +90,11 @@ DefinitionNode *DefinitionNode::findByPath(const std::string &path) const {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t seppos = path.find("/");
|
size_t seppos = path.find("/");
|
||||||
std::string child_name = (seppos == std::string::npos) ? path : path.substr(0, seppos);
|
string child_name = (seppos == string::npos) ? path : path.substr(0, seppos);
|
||||||
DefinitionNode *child =
|
DefinitionNode *child =
|
||||||
((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
|
((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
|
||||||
if (child) {
|
if (child) {
|
||||||
if (seppos == std::string::npos) {
|
if (seppos == string::npos) {
|
||||||
return child;
|
return child;
|
||||||
} else {
|
} else {
|
||||||
return child->findByPath(path.substr(seppos + 1));
|
return child->findByPath(path.substr(seppos + 1));
|
||||||
|
@ -111,18 +111,18 @@ bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[Definition] Can't apply " << diff->getTypeName() << " diff to " << getName() << " "
|
Logs::error() << "[Definition] Can't apply " << diff->getTypeName() << " diff to " << getName() << " "
|
||||||
<< type_name << " node" << std::endl;
|
<< type_name << " node" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const {
|
void DefinitionNode::generateInitDiffs(vector<const DefinitionDiff *> *) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff) {
|
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff) {
|
||||||
if (root && root->diffs) {
|
if (root && root->diffs) {
|
||||||
if (init_diff) {
|
if (init_diff) {
|
||||||
std::vector<const DefinitionDiff *> diffs;
|
vector<const DefinitionDiff *> diffs;
|
||||||
generateInitDiffs(&diffs);
|
generateInitDiffs(&diffs);
|
||||||
|
|
||||||
for (auto diff : diffs) {
|
for (auto diff : diffs) {
|
||||||
|
@ -156,7 +156,7 @@ void DefinitionNode::save(PackStream *stream) const {
|
||||||
} else {
|
} else {
|
||||||
// Child size not known, write it to a temporary stream to know it
|
// Child size not known, write it to a temporary stream to know it
|
||||||
Logs::debug() << "[Definition] Unknown size for child " << child->name
|
Logs::debug() << "[Definition] Unknown size for child " << child->name
|
||||||
<< ", unefficient writing to temporary stream" << std::endl;
|
<< ", unefficient writing to temporary stream" << endl;
|
||||||
PackStream substream;
|
PackStream substream;
|
||||||
child->save(&substream);
|
child->save(&substream);
|
||||||
stream->writeFromBuffer(substream, true);
|
stream->writeFromBuffer(substream, true);
|
||||||
|
@ -170,7 +170,7 @@ void DefinitionNode::load(PackStream *stream) {
|
||||||
stream->read(&children_count);
|
stream->read(&children_count);
|
||||||
|
|
||||||
for (int i = 0; i < children_count; i++) {
|
for (int i = 0; i < children_count; i++) {
|
||||||
std::string child_name = stream->readString();
|
string child_name = stream->readString();
|
||||||
|
|
||||||
int child_size;
|
int child_size;
|
||||||
stream->read(&child_size);
|
stream->read(&child_size);
|
||||||
|
@ -183,7 +183,7 @@ void DefinitionNode::load(PackStream *stream) {
|
||||||
// TODO Ask subclass if it can instanciate a child
|
// TODO Ask subclass if it can instanciate a child
|
||||||
// Else skip length of unknown child
|
// Else skip length of unknown child
|
||||||
stream->skipBytes(child_size);
|
stream->skipBytes(child_size);
|
||||||
Logs::warning() << "[Definition] Skipped unknown child '" << child_name << "'" << std::endl;
|
Logs::warning() << "[Definition] Skipped unknown child '" << child_name << "'" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,12 +197,12 @@ void DefinitionNode::copy(DefinitionNode *destination) const {
|
||||||
child->copy(dest_child);
|
child->copy(dest_child);
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "[Definition] Can't copy to child " << child->name << " of "
|
Logs::warning() << "[Definition] Can't copy to child " << child->name << " of "
|
||||||
<< destination->getTypeName() << std::endl;
|
<< destination->getTypeName() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName()
|
Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName()
|
||||||
<< std::endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ void DefinitionNode::validate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::addChild(DefinitionNode *child) {
|
void DefinitionNode::addChild(DefinitionNode *child) {
|
||||||
if (std::find(children.begin(), children.end(), child) == children.end()) {
|
if (find(children.begin(), children.end(), child) == children.end()) {
|
||||||
children.push_back(child);
|
children.push_back(child);
|
||||||
child->parent = this;
|
child->parent = this;
|
||||||
child->root = this->root;
|
child->root = this->root;
|
||||||
|
@ -221,17 +221,17 @@ void DefinitionNode::addChild(DefinitionNode *child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::removeChild(DefinitionNode *child) {
|
void DefinitionNode::removeChild(DefinitionNode *child) {
|
||||||
std::vector<DefinitionNode *>::iterator it = std::find(children.begin(), children.end(), child);
|
vector<DefinitionNode *>::iterator it = find(children.begin(), children.end(), child);
|
||||||
if (it != children.end()) {
|
if (it != children.end()) {
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
children.erase(it);
|
children.erase(it);
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "[Definition] Trying to remove not found child '" << child->name << "' from '" << name << "'"
|
Logs::warning() << "[Definition] Trying to remove not found child '" << child->name << "' from '" << name << "'"
|
||||||
<< std::endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinitionNode *DefinitionNode::findChildByName(const std::string name) {
|
DefinitionNode *DefinitionNode::findChildByName(const string name) {
|
||||||
for (auto child : children) {
|
for (auto child : children) {
|
||||||
if (child->name == name) {
|
if (child->name == name) {
|
||||||
return child;
|
return child;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace definition {
|
||||||
*/
|
*/
|
||||||
class DEFINITIONSHARED_EXPORT DefinitionNode {
|
class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
public:
|
public:
|
||||||
DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name = "");
|
DefinitionNode(DefinitionNode *parent, const string &name, const string &type_name = "");
|
||||||
virtual ~DefinitionNode();
|
virtual ~DefinitionNode();
|
||||||
|
|
||||||
virtual void save(PackStream *stream) const;
|
virtual void save(PackStream *stream) const;
|
||||||
|
@ -22,12 +22,12 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
virtual void copy(DefinitionNode *destination) const;
|
virtual void copy(DefinitionNode *destination) const;
|
||||||
virtual void validate();
|
virtual void validate();
|
||||||
|
|
||||||
inline const std::string &getName() const {
|
inline const string &getName() const {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
virtual void setName(const std::string &name);
|
virtual void setName(const string &name);
|
||||||
|
|
||||||
inline const std::string &getTypeName() const {
|
inline const string &getTypeName() const {
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,19 +49,19 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
/**
|
/**
|
||||||
* Return a string representation of the tree (mainly for debugging purposes).
|
* Return a string representation of the tree (mainly for debugging purposes).
|
||||||
*/
|
*/
|
||||||
virtual std::string toString(int indent = 0) const;
|
virtual string toString(int indent = 0) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the path to this node, using '/' delimited syntax, with the first '/' being the root node.
|
* Return the path to this node, using '/' delimited syntax, with the first '/' being the root node.
|
||||||
*/
|
*/
|
||||||
std::string getPath() const;
|
string getPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a node in this tree, by its path (as returned by getPath).
|
* Find a node in this tree, by its path (as returned by getPath).
|
||||||
*
|
*
|
||||||
* Return NULL if the path does not exists.
|
* Return NULL if the path does not exists.
|
||||||
*/
|
*/
|
||||||
DefinitionNode *findByPath(const std::string &path) const;
|
DefinitionNode *findByPath(const string &path) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a diff to the internal value of this node.
|
* Apply a diff to the internal value of this node.
|
||||||
|
@ -79,7 +79,7 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
*
|
*
|
||||||
* This method should be overridden by subclasses.
|
* This method should be overridden by subclasses.
|
||||||
*/
|
*/
|
||||||
virtual void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
virtual void generateInitDiffs(vector<const DefinitionDiff *> *diffs) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a watcher over this node.
|
* Add a watcher over this node.
|
||||||
|
@ -98,7 +98,7 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
protected:
|
protected:
|
||||||
void addChild(DefinitionNode *child);
|
void addChild(DefinitionNode *child);
|
||||||
void removeChild(DefinitionNode *child);
|
void removeChild(DefinitionNode *child);
|
||||||
virtual DefinitionNode *findChildByName(const std::string name);
|
virtual DefinitionNode *findChildByName(const string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size in bytes this child will consume when serialized to a stream.
|
* Get the size in bytes this child will consume when serialized to a stream.
|
||||||
|
@ -121,9 +121,9 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||||
DefinitionNode *parent;
|
DefinitionNode *parent;
|
||||||
DefinitionNode *root;
|
DefinitionNode *root;
|
||||||
DiffManager *diffs;
|
DiffManager *diffs;
|
||||||
std::string type_name;
|
string type_name;
|
||||||
std::string name;
|
string name;
|
||||||
std::vector<DefinitionNode *> children;
|
vector<DefinitionNode *> children;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
#include "DefinitionWatcher.h"
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
|
#include "DefinitionNode.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
DefinitionWatcher::DefinitionWatcher() {
|
DefinitionWatcher::DefinitionWatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefinitionWatcher::startWatching(const DefinitionNode *root, const string &path, bool init_diff) {
|
||||||
|
DefinitionNode *node = root->findByPath(path);
|
||||||
|
if (node) {
|
||||||
|
node->addWatcher(this, init_diff);
|
||||||
|
} else {
|
||||||
|
Logs::warning() << "[Definition] Node not found for watching : " << path << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@ class DEFINITIONSHARED_EXPORT DefinitionWatcher {
|
||||||
* Abstract method called when a node changed.
|
* Abstract method called when a node changed.
|
||||||
*/
|
*/
|
||||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Start watching a path in a definition tree.
|
||||||
|
*/
|
||||||
|
void startWatching(const DefinitionNode *root, const string &path, bool init_diff = true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ DiffManager::~DiffManager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher) {
|
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher) {
|
||||||
if (std::find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end()) {
|
if (find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end()) {
|
||||||
watchers[node].push_back(watcher);
|
watchers[node].push_back(watcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ void DiffManager::undo() {
|
||||||
watcher->nodeChanged(node, diff);
|
watcher->nodeChanged(node, diff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't find node to undo diff : " << diff->getPath() << std::endl;
|
Logs::error() << "Can't find node to undo diff : " << diff->getPath() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ void DiffManager::redo() {
|
||||||
watcher->nodeChanged(node, diff);
|
watcher->nodeChanged(node, diff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't find node to redo diff : " << diff->getPath() << std::endl;
|
Logs::error() << "Can't find node to redo diff : " << diff->getPath() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@ class DEFINITIONSHARED_EXPORT DiffManager {
|
||||||
private:
|
private:
|
||||||
DefinitionNode *tree;
|
DefinitionNode *tree;
|
||||||
int undone;
|
int undone;
|
||||||
std::vector<const DefinitionDiff *> diffs;
|
vector<const DefinitionDiff *> diffs;
|
||||||
std::map<const DefinitionNode *, std::vector<DefinitionWatcher *>> watchers;
|
map<const DefinitionNode *, vector<DefinitionWatcher *>> watchers;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
FloatNode::FloatNode(DefinitionNode *parent, const std::string &name, double value)
|
FloatNode::FloatNode(DefinitionNode *parent, const string &name, double value)
|
||||||
: DefinitionNode(parent, name, "float"), value(value) {
|
: DefinitionNode(parent, name, "float"), value(value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FloatNode::toString(int indent) const {
|
string FloatNode::toString(int indent) const {
|
||||||
std::ostringstream stream;
|
ostringstream stream;
|
||||||
|
|
||||||
stream << DefinitionNode::toString(indent) << " " << value;
|
stream << DefinitionNode::toString(indent) << " " << value;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ void FloatNode::copy(DefinitionNode *destination) const {
|
||||||
if (destination->getTypeName() == getTypeName()) {
|
if (destination->getTypeName() == getTypeName()) {
|
||||||
((FloatNode *)destination)->value = value;
|
((FloatNode *)destination)->value = value;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ const FloatDiff *FloatNode::produceDiff(double new_value) const {
|
||||||
return new FloatDiff(this, value, new_value);
|
return new FloatDiff(this, value, new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
void FloatNode::generateInitDiffs(vector<const DefinitionDiff *> *diffs) const {
|
||||||
diffs->push_back(produceDiff(value));
|
diffs->push_back(produceDiff(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||||
value = next;
|
value = next;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't apply float diff " << previous << " => " << next << " to " << getName() << std::endl;
|
Logs::error() << "Can't apply float diff " << previous << " => " << next << " to " << getName() << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ namespace definition {
|
||||||
*/
|
*/
|
||||||
class DEFINITIONSHARED_EXPORT FloatNode : public DefinitionNode {
|
class DEFINITIONSHARED_EXPORT FloatNode : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
FloatNode(DefinitionNode *parent, const std::string &name, double value = 0.0);
|
FloatNode(DefinitionNode *parent, const string &name, double value = 0.0);
|
||||||
|
|
||||||
inline double getValue() const {
|
inline double getValue() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString(int indent) const override;
|
virtual string toString(int indent) const override;
|
||||||
virtual void save(PackStream *stream) const override;
|
virtual void save(PackStream *stream) const override;
|
||||||
virtual void load(PackStream *stream) override;
|
virtual void load(PackStream *stream) override;
|
||||||
virtual void copy(DefinitionNode *destination) const override;
|
virtual void copy(DefinitionNode *destination) const override;
|
||||||
|
@ -31,7 +31,7 @@ class DEFINITIONSHARED_EXPORT FloatNode : public DefinitionNode {
|
||||||
*/
|
*/
|
||||||
void setValue(double new_value);
|
void setValue(double new_value);
|
||||||
const FloatDiff *produceDiff(double new_value) const;
|
const FloatDiff *produceDiff(double new_value) const;
|
||||||
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
void generateInitDiffs(vector<const DefinitionDiff *> *diffs) const;
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||||
|
|
||||||
void addValue(double added);
|
void addValue(double added);
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
IntNode::IntNode(DefinitionNode *parent, const std::string &name, int value)
|
IntNode::IntNode(DefinitionNode *parent, const string &name, int value)
|
||||||
: DefinitionNode(parent, name, "int"), value(value) {
|
: DefinitionNode(parent, name, "int"), value(value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IntNode::toString(int indent) const {
|
string IntNode::toString(int indent) const {
|
||||||
std::ostringstream stream;
|
ostringstream stream;
|
||||||
|
|
||||||
stream << DefinitionNode::toString(indent) << " " << value;
|
stream << DefinitionNode::toString(indent) << " " << value;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ void IntNode::copy(DefinitionNode *destination) const {
|
||||||
if (destination->getTypeName() == getTypeName()) {
|
if (destination->getTypeName() == getTypeName()) {
|
||||||
((IntNode *)destination)->value = value;
|
((IntNode *)destination)->value = value;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ const IntDiff *IntNode::produceDiff(int new_value) const {
|
||||||
return new IntDiff(this, value, new_value);
|
return new IntDiff(this, value, new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
void IntNode::generateInitDiffs(vector<const DefinitionDiff *> *diffs) const {
|
||||||
diffs->push_back(produceDiff(value));
|
diffs->push_back(produceDiff(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||||
value = next;
|
value = next;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't apply int diff " << previous << " => " << next << " to " << getName() << std::endl;
|
Logs::error() << "Can't apply int diff " << previous << " => " << next << " to " << getName() << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ namespace definition {
|
||||||
*/
|
*/
|
||||||
class DEFINITIONSHARED_EXPORT IntNode : public DefinitionNode {
|
class DEFINITIONSHARED_EXPORT IntNode : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
IntNode(DefinitionNode *parent, const std::string &name, int value = 0);
|
IntNode(DefinitionNode *parent, const string &name, int value = 0);
|
||||||
|
|
||||||
inline int getValue() const {
|
inline int getValue() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString(int indent) const override;
|
virtual string toString(int indent) const override;
|
||||||
virtual void save(PackStream *stream) const override;
|
virtual void save(PackStream *stream) const override;
|
||||||
virtual void load(PackStream *stream) override;
|
virtual void load(PackStream *stream) override;
|
||||||
virtual void copy(DefinitionNode *destination) const override;
|
virtual void copy(DefinitionNode *destination) const override;
|
||||||
|
@ -31,7 +31,7 @@ class DEFINITIONSHARED_EXPORT IntNode : public DefinitionNode {
|
||||||
*/
|
*/
|
||||||
void setValue(int new_value);
|
void setValue(int new_value);
|
||||||
const IntDiff *produceDiff(int new_value) const;
|
const IntDiff *produceDiff(int new_value) const;
|
||||||
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
void generateInitDiffs(vector<const DefinitionDiff *> *diffs) const;
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "LayersDiff.h"
|
#include "LayersDiff.h"
|
||||||
|
|
||||||
Layers::Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor)
|
Layers::Layers(DefinitionNode *parent, const string &name, LayerConstructor layer_constructor)
|
||||||
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
|
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
|
||||||
max_layer_count = 100;
|
max_layer_count = 100;
|
||||||
null_layer = layer_constructor(this, "#NULL#");
|
null_layer = layer_constructor(this, "#NULL#");
|
||||||
|
@ -69,7 +69,7 @@ DefinitionNode *Layers::getLayer(int position) const {
|
||||||
return layers[position];
|
return layers[position];
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size()
|
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size()
|
||||||
<< std::endl;
|
<< endl;
|
||||||
return null_layer;
|
return null_layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,12 +81,12 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||||
|
|
||||||
if ((not backward and op == LayersDiff::LAYER_ADDED) or (backward and op == LayersDiff::LAYER_REMOVED)) {
|
if ((not backward and op == LayersDiff::LAYER_ADDED) or (backward and op == LayersDiff::LAYER_REMOVED)) {
|
||||||
if (layer_count >= max_layer_count) {
|
if (layer_count >= max_layer_count) {
|
||||||
Logs::warning() << "Add layer ignored because limit of " << max_layer_count << " reached" << std::endl;
|
Logs::warning() << "Add layer ignored because limit of " << max_layer_count << " reached" << endl;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
int position = layer_diff->getLayer1();
|
int position = layer_diff->getLayer1();
|
||||||
if (position < 0 or position > layer_count) {
|
if (position < 0 or position > layer_count) {
|
||||||
Logs::error() << "Add layer ignored because requested position was incorrect" << std::endl;
|
Logs::error() << "Add layer ignored because requested position was incorrect" << endl;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
DefinitionNode *layer = layer_constructor(this, "temp");
|
DefinitionNode *layer = layer_constructor(this, "temp");
|
||||||
|
@ -104,7 +104,7 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||||
int position = layer_diff->getLayer1();
|
int position = layer_diff->getLayer1();
|
||||||
if (position < 0 or position >= layer_count) {
|
if (position < 0 or position >= layer_count) {
|
||||||
Logs::warning() << "Removing unknown layer " << position << " on " << layer_count << " from '" << getName()
|
Logs::warning() << "Removing unknown layer " << position << " on " << layer_count << " from '" << getName()
|
||||||
<< "'" << std::endl;
|
<< "'" << endl;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
DefinitionNode *removed = layers[position];
|
DefinitionNode *removed = layers[position];
|
||||||
|
@ -117,7 +117,7 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layers::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
void Layers::generateInitDiffs(vector<const DefinitionDiff *> *diffs) const {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto layer : layers) {
|
for (auto layer : layers) {
|
||||||
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, i++);
|
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, i++);
|
||||||
|
@ -132,7 +132,7 @@ void Layers::addLayer(const DefinitionNode &tocopy) {
|
||||||
addDiff(diff);
|
addDiff(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layers::addLayer(const std::string &name) {
|
void Layers::addLayer(const string &name) {
|
||||||
auto layer = layer_constructor(this, name);
|
auto layer = layer_constructor(this, name);
|
||||||
addLayer(*layer);
|
addLayer(*layer);
|
||||||
delete layer;
|
delete layer;
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace definition {
|
namespace definition {
|
||||||
|
|
||||||
typedef DefinitionNode *(*LayerConstructor)(Layers *parent, const std::string &name);
|
typedef DefinitionNode *(*LayerConstructor)(Layers *parent, const string &name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Layers of definitions, ideally all of the same type.
|
* @brief Layers of definitions, ideally all of the same type.
|
||||||
*/
|
*/
|
||||||
class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor);
|
Layers(DefinitionNode *parent, const string &name, LayerConstructor layer_constructor);
|
||||||
virtual ~Layers();
|
virtual ~Layers();
|
||||||
|
|
||||||
virtual void save(PackStream *stream) const override;
|
virtual void save(PackStream *stream) const override;
|
||||||
|
@ -23,7 +23,7 @@ class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
||||||
virtual void copy(DefinitionNode *destination) const override;
|
virtual void copy(DefinitionNode *destination) const override;
|
||||||
|
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||||
virtual void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const override;
|
virtual void generateInitDiffs(vector<const DefinitionDiff *> *diffs) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the maximal layer count allowed.
|
* Set the maximal layer count allowed.
|
||||||
|
@ -43,12 +43,12 @@ class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
||||||
/**
|
/**
|
||||||
* Retrieve a layer by its name.
|
* Retrieve a layer by its name.
|
||||||
*/
|
*/
|
||||||
DefinitionNode *getLayer(const std::string &name) const;
|
DefinitionNode *getLayer(const string &name) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new empty layer.
|
* Add a new empty layer.
|
||||||
*/
|
*/
|
||||||
void addLayer(const std::string &name);
|
void addLayer(const string &name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new layer, copying another node into it.
|
* Add a new layer, copying another node into it.
|
||||||
|
@ -68,7 +68,7 @@ class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
LayerConstructor layer_constructor;
|
LayerConstructor layer_constructor;
|
||||||
int max_layer_count;
|
int max_layer_count;
|
||||||
std::vector<DefinitionNode *> layers;
|
vector<DefinitionNode *> layers;
|
||||||
DefinitionNode *null_layer;
|
DefinitionNode *null_layer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ void NoiseNode::copy(DefinitionNode *destination) const {
|
||||||
if (destination->getTypeName() == getTypeName()) {
|
if (destination->getTypeName() == getTypeName()) {
|
||||||
noise->copy(((NoiseNode *)destination)->noise);
|
noise->copy(((NoiseNode *)destination)->noise);
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ void Scenery::validate() {
|
||||||
keepCameraAboveGround(camera);
|
keepCameraAboveGround(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const {
|
Scenery::FileOperationResult Scenery::saveGlobal(const string &filepath) const {
|
||||||
PackStream stream;
|
PackStream stream;
|
||||||
double app_header = (double)APP_HEADER;
|
double app_header = (double)APP_HEADER;
|
||||||
double version_header = (double)DATA_VERSION;
|
double version_header = (double)DATA_VERSION;
|
||||||
|
@ -49,11 +49,11 @@ Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) co
|
||||||
stream.write(&version_header);
|
stream.write(&version_header);
|
||||||
stream.write(&app_header);
|
stream.write(&app_header);
|
||||||
|
|
||||||
Logs::debug() << "[Definition] Scenery saved to file: " << filepath << std::endl;
|
Logs::debug() << "[Definition] Scenery saved to file: " << filepath << endl;
|
||||||
return FILE_OPERATION_OK;
|
return FILE_OPERATION_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) {
|
Scenery::FileOperationResult Scenery::loadGlobal(const string &filepath) {
|
||||||
PackStream stream;
|
PackStream stream;
|
||||||
double app_header, version_header;
|
double app_header, version_header;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) {
|
||||||
return FILE_OPERATION_APP_MISMATCH;
|
return FILE_OPERATION_APP_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logs::debug() << "[Definition] Scenery loaded from file: " << filepath << std::endl;
|
Logs::debug() << "[Definition] Scenery loaded from file: " << filepath << endl;
|
||||||
return FILE_OPERATION_OK;
|
return FILE_OPERATION_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,11 +108,10 @@ void Scenery::autoPreset(RandomGenerator &random) {
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
|
|
||||||
Logs::debug() << "[Definition] New scenery generated from seed " << random.getSeed() << std::endl;
|
Logs::debug() << "[Definition] New scenery generated from seed " << random.getSeed() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scenery::autoPreset(unsigned int seed)
|
void Scenery::autoPreset(unsigned int seed) {
|
||||||
{
|
|
||||||
RandomGenerator random(seed);
|
RandomGenerator random(seed);
|
||||||
autoPreset(random);
|
autoPreset(random);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
|
||||||
|
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
FileOperationResult saveGlobal(const std::string &filepath) const;
|
FileOperationResult saveGlobal(const string &filepath) const;
|
||||||
FileOperationResult loadGlobal(const std::string &filepath);
|
FileOperationResult loadGlobal(const string &filepath);
|
||||||
|
|
||||||
virtual const Scenery *getScenery() const override;
|
virtual const Scenery *getScenery() const override;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "TerrainDefinition.h"
|
#include "TerrainDefinition.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
|
||||||
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent, const std::string &name)
|
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent, const string &name)
|
||||||
: DefinitionNode(parent, name, "texturelayer") {
|
: DefinitionNode(parent, name, "texturelayer") {
|
||||||
terrain_zone = new Zone;
|
terrain_zone = new Zone;
|
||||||
_displacement_noise = new NoiseGenerator;
|
_displacement_noise = new NoiseGenerator;
|
||||||
|
|
|
@ -20,7 +20,7 @@ class DEFINITIONSHARED_EXPORT TextureLayerDefinition : public DefinitionNode {
|
||||||
} TextureLayerPreset;
|
} TextureLayerPreset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureLayerDefinition(DefinitionNode *parent, const std::string &name);
|
TextureLayerDefinition(DefinitionNode *parent, const string &name);
|
||||||
virtual ~TextureLayerDefinition();
|
virtual ~TextureLayerDefinition();
|
||||||
|
|
||||||
virtual void save(PackStream *stream) const override;
|
virtual void save(PackStream *stream) const override;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "TextureLayerDefinition.h"
|
#include "TextureLayerDefinition.h"
|
||||||
|
|
||||||
static DefinitionNode *_layer_constructor(Layers *parent, const std::string &name) {
|
static DefinitionNode *_layer_constructor(Layers *parent, const string &name) {
|
||||||
return new TextureLayerDefinition(parent, name);
|
return new TextureLayerDefinition(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "VegetationLayerDefinition.h"
|
#include "VegetationLayerDefinition.h"
|
||||||
#include "VegetationModelDefinition.h"
|
#include "VegetationModelDefinition.h"
|
||||||
|
|
||||||
static DefinitionNode *_layer_constructor(Layers *parent, const std::string &name) {
|
static DefinitionNode *_layer_constructor(Layers *parent, const string &name) {
|
||||||
return new VegetationLayerDefinition(parent, name);
|
return new VegetationLayerDefinition(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "VegetationModelDefinition.h"
|
#include "VegetationModelDefinition.h"
|
||||||
#include "VegetationPresenceDefinition.h"
|
#include "VegetationPresenceDefinition.h"
|
||||||
|
|
||||||
VegetationLayerDefinition::VegetationLayerDefinition(DefinitionNode *parent, const std::string &name)
|
VegetationLayerDefinition::VegetationLayerDefinition(DefinitionNode *parent, const string &name)
|
||||||
: DefinitionNode(parent, name, "vegetationlayer") {
|
: DefinitionNode(parent, name, "vegetationlayer") {
|
||||||
model = new VegetationModelDefinition(this);
|
model = new VegetationModelDefinition(this);
|
||||||
presence = new VegetationPresenceDefinition(this);
|
presence = new VegetationPresenceDefinition(this);
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace definition {
|
||||||
*/
|
*/
|
||||||
class DEFINITIONSHARED_EXPORT VegetationLayerDefinition : public DefinitionNode {
|
class DEFINITIONSHARED_EXPORT VegetationLayerDefinition : public DefinitionNode {
|
||||||
public:
|
public:
|
||||||
VegetationLayerDefinition(DefinitionNode *parent, const std::string &name);
|
VegetationLayerDefinition(DefinitionNode *parent, const string &name);
|
||||||
|
|
||||||
inline const VegetationPresenceDefinition *getPresence() const {
|
inline const VegetationPresenceDefinition *getPresence() const {
|
||||||
return presence;
|
return presence;
|
||||||
|
|
|
@ -105,7 +105,7 @@ static inline double randomizeValue(RandomGenerator &random, double base, double
|
||||||
return base * (min_factor + random.genDouble() * (max_factor - min_factor));
|
return base * (min_factor + random.genDouble() * (max_factor - min_factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addBranchRecurse(RandomGenerator &random, std::vector<CappedCylinder> &branches, const Vector3 &base,
|
static void addBranchRecurse(RandomGenerator &random, vector<CappedCylinder> &branches, const Vector3 &base,
|
||||||
const Vector3 &direction, double radius, double length) {
|
const Vector3 &direction, double radius, double length) {
|
||||||
branches.push_back(CappedCylinder(base, direction, radius, length));
|
branches.push_back(CappedCylinder(base, direction, radius, length));
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,13 @@ class DEFINITIONSHARED_EXPORT VegetationModelDefinition : public DefinitionNode
|
||||||
return *foliage_material;
|
return *foliage_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::vector<CappedCylinder> &getSolidVolumes() const {
|
inline const vector<CappedCylinder> &getSolidVolumes() const {
|
||||||
return solid_volumes;
|
return solid_volumes;
|
||||||
}
|
}
|
||||||
inline const std::vector<Sphere> &getFoliageGroups() const {
|
inline const vector<Sphere> &getFoliageGroups() const {
|
||||||
return foliage_groups;
|
return foliage_groups;
|
||||||
}
|
}
|
||||||
inline const std::vector<Disk> &getFoliageItems() const {
|
inline const vector<Disk> &getFoliageItems() const {
|
||||||
return foliage_items;
|
return foliage_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ class DEFINITIONSHARED_EXPORT VegetationModelDefinition : public DefinitionNode
|
||||||
private:
|
private:
|
||||||
SurfaceMaterial *solid_material;
|
SurfaceMaterial *solid_material;
|
||||||
SurfaceMaterial *foliage_material;
|
SurfaceMaterial *foliage_material;
|
||||||
std::vector<CappedCylinder> solid_volumes;
|
vector<CappedCylinder> solid_volumes;
|
||||||
std::vector<Sphere> foliage_groups;
|
vector<Sphere> foliage_groups;
|
||||||
std::vector<Disk> foliage_items;
|
vector<Disk> foliage_items;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ VegetationPresenceDefinition::VegetationPresenceDefinition(VegetationLayerDefini
|
||||||
interval = new FloatNode(this, "interval", 0.1);
|
interval = new FloatNode(this, "interval", 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstance> *result,
|
bool VegetationPresenceDefinition::collectInstances(vector<VegetationInstance> *result,
|
||||||
const VegetationModelDefinition &model, double xmin, double zmin,
|
const VegetationModelDefinition &model, double xmin, double zmin,
|
||||||
double xmax, double zmax, bool outcomers) const {
|
double xmax, double zmax, bool outcomers) const {
|
||||||
if (outcomers) {
|
if (outcomers) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class DEFINITIONSHARED_EXPORT VegetationPresenceDefinition : public DefinitionNo
|
||||||
* The location vector set in collected instances is based on raw terrain height, without displacement.
|
* The location vector set in collected instances is based on raw terrain height, without displacement.
|
||||||
* It's the renderer role to apply the correct displacement.
|
* It's the renderer role to apply the correct displacement.
|
||||||
*/
|
*/
|
||||||
bool collectInstances(std::vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin,
|
bool collectInstances(vector<VegetationInstance> *result, const VegetationModelDefinition &model, double xmin,
|
||||||
double zmin, double xmax, double zmax, bool outcomers = true) const;
|
double zmin, double xmax, double zmax, bool outcomers = true) const;
|
||||||
|
|
||||||
double getMaxHeight() const;
|
double getMaxHeight() const;
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
|
|
||||||
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath);
|
void startRender(SoftwareCanvasRenderer *renderer, const char *outputpath);
|
||||||
|
|
||||||
static std::string getFileName(const std::string &name, int iteration = -1) {
|
static string getFileName(const string &name, int iteration = -1) {
|
||||||
std::ostringstream stream;
|
ostringstream stream;
|
||||||
|
|
||||||
stream << "pic_test_" << name;
|
stream << "pic_test_" << name;
|
||||||
if (iteration >= 0) {
|
if (iteration >= 0) {
|
||||||
|
@ -47,7 +47,7 @@ static std::string getFileName(const std::string &name, int iteration = -1) {
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void startTestRender(SoftwareCanvasRenderer *renderer, const std::string &name, int iteration = -1) {
|
static void startTestRender(SoftwareCanvasRenderer *renderer, const string &name, int iteration = -1) {
|
||||||
startRender(renderer, getFileName(name, iteration).data());
|
startRender(renderer, getFileName(name, iteration).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,8 +298,8 @@ static void testVegetationModels() {
|
||||||
|
|
||||||
static void testOpenGLVegetationImpostor() {
|
static void testOpenGLVegetationImpostor() {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
std::string filename = getFileName("opengl_vegetation_impostor", i);
|
string filename = getFileName("opengl_vegetation_impostor", i);
|
||||||
std::cout << "Rendering " << filename << "..." << std::endl;
|
cout << "Rendering " << filename << "..." << endl;
|
||||||
|
|
||||||
Scenery scenery;
|
Scenery scenery;
|
||||||
scenery.autoPreset(i);
|
scenery.autoPreset(i);
|
||||||
|
|
|
@ -15,7 +15,7 @@ FloatPropertyBind::FloatPropertyBind(MainModelerWindow *window, const QString &o
|
||||||
connect(item, SIGNAL(changed(double)), this, SLOT(propertyChanged(double)));
|
connect(item, SIGNAL(changed(double)), this, SLOT(propertyChanged(double)));
|
||||||
} else {
|
} else {
|
||||||
item = NULL;
|
item = NULL;
|
||||||
Logs::error() << "Can't find object :" << object_name.toStdString() << std::endl;
|
Logs::error() << "Can't find object :" << object_name.toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ IntPropertyBind::IntPropertyBind(MainModelerWindow *window, const QString &objec
|
||||||
connect(item, SIGNAL(changed(int)), this, SLOT(propertyChanged(int)));
|
connect(item, SIGNAL(changed(int)), this, SLOT(propertyChanged(int)));
|
||||||
} else {
|
} else {
|
||||||
item = NULL;
|
item = NULL;
|
||||||
Logs::error() << "Can't find object :" << object_name.toStdString() << std::endl;
|
Logs::error() << "Can't find object :" << object_name.toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
@ -86,7 +74,7 @@ void MainModelerWindow::setQmlProperty(const QString &objectName, const QString
|
||||||
if (item) {
|
if (item) {
|
||||||
item->setProperty(propertyName.toLocal8Bit(), value);
|
item->setProperty(propertyName.toLocal8Bit(), value);
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "QML object not found :" << objectName.toStdString() << std::endl;
|
Logs::error() << "QML object not found :" << objectName.toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +84,7 @@ void MainModelerWindow::connectQmlSignal(const QString &objectName, const char *
|
||||||
if (item) {
|
if (item) {
|
||||||
connect(item, signal, receiver, method);
|
connect(item, signal, receiver, method);
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "QML object not found :" << objectName.toStdString() << std::endl;
|
Logs::error() << "QML object not found :" << objectName.toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -149,8 +137,8 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) {
|
||||||
} else if (event->key() == Qt::Key_F6) {
|
} else if (event->key() == Qt::Key_F6) {
|
||||||
render_process->showPreviousRender();
|
render_process->showPreviousRender();
|
||||||
} else if (event->key() == Qt::Key_F12) {
|
} else if (event->key() == Qt::Key_F12) {
|
||||||
Logs::warning() << "Current scenery dump:" << std::endl
|
Logs::warning() << "Current scenery dump:" << endl
|
||||||
<< scenery->toString() << std::endl;
|
<< scenery->toString() << endl;
|
||||||
} else if (event->key() == Qt::Key_N) {
|
} else if (event->key() == Qt::Key_N) {
|
||||||
if (event->modifiers() & Qt::ControlModifier) {
|
if (event->modifiers() & Qt::ControlModifier) {
|
||||||
newFile();
|
newFile();
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -4,22 +4,39 @@
|
||||||
#include "OpenGLShaderProgram.h"
|
#include "OpenGLShaderProgram.h"
|
||||||
#include "OpenGLVertexArray.h"
|
#include "OpenGLVertexArray.h"
|
||||||
|
|
||||||
OpenGLPart::OpenGLPart(OpenGLRenderer *renderer) : renderer(renderer) {
|
OpenGLPart::OpenGLPart(OpenGLRenderer *renderer, const string &name) : renderer(renderer), name(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLShaderProgram *OpenGLPart::createShader(const std::string &name) {
|
void OpenGLPart::pause() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLPart::resume() {
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLShaderProgram *OpenGLPart::createShader(const string &name) {
|
||||||
OpenGLShaderProgram *program = new OpenGLShaderProgram(name, renderer);
|
OpenGLShaderProgram *program = new OpenGLShaderProgram(name, renderer);
|
||||||
|
|
||||||
if (shaders.find(name) == shaders.end()) {
|
if (shaders.find(name) == shaders.end()) {
|
||||||
|
@ -30,13 +47,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) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace opengl {
|
||||||
*/
|
*/
|
||||||
class OPENGLSHARED_EXPORT OpenGLPart {
|
class OPENGLSHARED_EXPORT OpenGLPart {
|
||||||
public:
|
public:
|
||||||
OpenGLPart(OpenGLRenderer *renderer);
|
OpenGLPart(OpenGLRenderer *renderer, const string &name);
|
||||||
virtual ~OpenGLPart();
|
virtual ~OpenGLPart();
|
||||||
|
|
||||||
// Initialize the part rendering (create shaders, prepare static textures...)
|
// Initialize the part rendering (create shaders, prepare static textures...)
|
||||||
|
@ -26,9 +26,18 @@ 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();
|
||||||
|
|
||||||
|
// Temporarily pause the background working
|
||||||
|
virtual void pause();
|
||||||
|
|
||||||
|
// Resume the background working
|
||||||
|
virtual void resume();
|
||||||
|
|
||||||
void updateScenery(bool onlyCommon = false);
|
void updateScenery(bool onlyCommon = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,13 +50,17 @@ class OPENGLSHARED_EXPORT OpenGLPart {
|
||||||
*/
|
*/
|
||||||
OpenGLFunctions *getOpenGlFunctions() const;
|
OpenGLFunctions *getOpenGlFunctions() const;
|
||||||
|
|
||||||
|
inline const string &getName() const {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Create a shader program.
|
* Create a shader program.
|
||||||
*
|
*
|
||||||
* The returned shader's ownership remains in this object. It will taks care of the destruction.
|
* The returned shader's ownership remains in this object. It will taks care of the destruction.
|
||||||
*/
|
*/
|
||||||
OpenGLShaderProgram *createShader(const std::string &name);
|
OpenGLShaderProgram *createShader(const string &name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a vertex array.
|
* Create a vertex array.
|
||||||
|
@ -56,12 +69,15 @@ 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;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, OpenGLShaderProgram *> shaders;
|
string name;
|
||||||
std::vector<OpenGLVertexArray *> arrays;
|
map<string, OpenGLShaderProgram *> shaders;
|
||||||
|
vector<OpenGLVertexArray *> arrays;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,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;
|
||||||
|
|
||||||
|
@ -38,26 +40,23 @@ OpenGLRenderer::OpenGLRenderer(Scenery *scenery) : SoftwareRenderer(scenery) {
|
||||||
shared_state->set("viewDistance", 300.0);
|
shared_state->set("viewDistance", 300.0);
|
||||||
shared_state->set("exposure", 1.2);
|
shared_state->set("exposure", 1.2);
|
||||||
|
|
||||||
skybox = new OpenGLSkybox(this);
|
parts.push_back(skybox = new OpenGLSkybox(this));
|
||||||
water = new OpenGLWater(this);
|
parts.push_back(water = new OpenGLWater(this));
|
||||||
terrain = new OpenGLTerrain(this);
|
parts.push_back(terrain = new OpenGLTerrain(this));
|
||||||
vegetation = new OpenGLVegetation(this);
|
parts.push_back(vegetation = new OpenGLVegetation(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLRenderer::~OpenGLRenderer() {
|
OpenGLRenderer::~OpenGLRenderer() {
|
||||||
vegetation->interrupt();
|
for (auto part : parts) {
|
||||||
terrain->interrupt();
|
part->interrupt();
|
||||||
water->interrupt();
|
}
|
||||||
skybox->interrupt();
|
|
||||||
|
|
||||||
delete mouse_projected;
|
delete mouse_projected;
|
||||||
|
|
||||||
delete view_matrix;
|
delete view_matrix;
|
||||||
|
|
||||||
delete skybox;
|
for (auto part : parts) {
|
||||||
delete water;
|
delete part;
|
||||||
delete terrain;
|
}
|
||||||
delete vegetation;
|
|
||||||
|
|
||||||
delete functions;
|
delete functions;
|
||||||
delete shared_state;
|
delete shared_state;
|
||||||
|
@ -72,42 +71,45 @@ void OpenGLRenderer::prepare() {
|
||||||
getVegetationRenderer()->setEnabled(false);
|
getVegetationRenderer()->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::checkForErrors(const std::string &domain) {
|
void OpenGLRenderer::checkForErrors(const string &domain) {
|
||||||
int error_code;
|
int error_code;
|
||||||
while ((error_code = functions->glGetError()) != GL_NO_ERROR) {
|
while ((error_code = functions->glGetError()) != GL_NO_ERROR) {
|
||||||
Logs::warning() << "[OpenGL] Error in " << domain << " : " << error_code << std::endl;
|
Logs::warning() << "[OpenGL] Error in " << domain << " : " << error_code << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::destroy() {
|
||||||
|
shared_state->destroy(functions);
|
||||||
|
|
||||||
|
for (auto part : parts) {
|
||||||
|
part->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkForErrors("destroy");
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::initialize() {
|
void OpenGLRenderer::initialize() {
|
||||||
bool init = functions->initializeOpenGLFunctions();
|
bool init = functions->initializeOpenGLFunctions();
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
Logs::debug() << "[OpenGL] renderer started (version " << functions->glGetString(GL_VERSION)
|
Logs::debug() << "[OpenGL] renderer started (version " << functions->glGetString(GL_VERSION)
|
||||||
<< ", glsl version " << functions->glGetString(GL_SHADING_LANGUAGE_VERSION) << ")" << std::endl;
|
<< ", glsl version " << functions->glGetString(GL_SHADING_LANGUAGE_VERSION) << ")" << endl;
|
||||||
|
|
||||||
prepareOpenGLState();
|
prepareOpenGLState();
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
skybox->initialize();
|
for (auto part : parts) {
|
||||||
skybox->updateScenery();
|
part->initialize();
|
||||||
|
part->updateScenery();
|
||||||
water->initialize();
|
}
|
||||||
water->updateScenery();
|
|
||||||
|
|
||||||
terrain->initialize();
|
|
||||||
terrain->updateScenery();
|
|
||||||
|
|
||||||
vegetation->initialize();
|
|
||||||
vegetation->updateScenery();
|
|
||||||
|
|
||||||
cameraChangeEvent(render_camera);
|
cameraChangeEvent(render_camera);
|
||||||
|
|
||||||
checkForErrors("initialize");
|
checkForErrors("initialize");
|
||||||
ready = true;
|
ready = true;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[OpenGL] Failed to initialize api bindings" << std::endl;
|
Logs::error() << "[OpenGL] Failed to initialize api bindings" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,23 +161,21 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
skybox->render();
|
for (auto part : parts) {
|
||||||
checkForErrors("skybox");
|
part->render();
|
||||||
|
checkForErrors(part->getName());
|
||||||
terrain->render();
|
}
|
||||||
checkForErrors("terrain");
|
|
||||||
|
|
||||||
water->render();
|
|
||||||
checkForErrors("water");
|
|
||||||
|
|
||||||
vegetation->render();
|
|
||||||
checkForErrors("vegetation");
|
|
||||||
|
|
||||||
if (mouse_tracking) {
|
if (mouse_tracking) {
|
||||||
updateMouseProjection();
|
updateMouseProjection();
|
||||||
|
@ -186,25 +186,37 @@ void OpenGLRenderer::paint(bool clear) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLRenderer::stop() {
|
||||||
|
stopping = true;
|
||||||
|
return stopped;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::reset() {
|
void OpenGLRenderer::reset() {
|
||||||
if (ready) {
|
if (ready) {
|
||||||
skybox->updateScenery();
|
for (auto part : parts) {
|
||||||
water->updateScenery();
|
part->updateScenery();
|
||||||
terrain->updateScenery();
|
}
|
||||||
vegetation->updateScenery();
|
|
||||||
|
|
||||||
cameraChangeEvent(render_camera);
|
cameraChangeEvent(render_camera);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::pause() {
|
void OpenGLRenderer::pause() {
|
||||||
|
if (not paused) {
|
||||||
paused = true;
|
paused = true;
|
||||||
terrain->pause();
|
for (auto part : parts) {
|
||||||
|
part->pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::resume() {
|
void OpenGLRenderer::resume() {
|
||||||
|
if (paused) {
|
||||||
|
for (auto part : parts) {
|
||||||
|
part->resume();
|
||||||
|
}
|
||||||
paused = false;
|
paused = false;
|
||||||
terrain->resume();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::setMouseLocation(int x, int y) {
|
void OpenGLRenderer::setMouseLocation(int x, int y) {
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
|
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class QMatrix4x4;
|
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:
|
||||||
|
@ -33,6 +35,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;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void prepare() override;
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
@ -41,12 +49,28 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
*
|
*
|
||||||
* Will write the error on standard error output, with the *domain* specified.
|
* Will write the error on standard error output, with the *domain* specified.
|
||||||
*/
|
*/
|
||||||
void checkForErrors(const std::string &domain);
|
void checkForErrors(const 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).
|
||||||
|
@ -100,6 +124,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;
|
||||||
|
|
||||||
|
@ -117,6 +143,8 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer {
|
||||||
OpenGLWater *water;
|
OpenGLWater *water;
|
||||||
OpenGLTerrain *terrain;
|
OpenGLTerrain *terrain;
|
||||||
OpenGLVegetation *vegetation;
|
OpenGLVegetation *vegetation;
|
||||||
|
|
||||||
|
vector<OpenGLPart *> parts;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
|
||||||
OpenGLShaderProgram::OpenGLShaderProgram(const std::string &name, OpenGLRenderer *renderer)
|
OpenGLShaderProgram::OpenGLShaderProgram(const string &name, OpenGLRenderer *renderer)
|
||||||
: renderer(renderer), name(name) {
|
: renderer(renderer), name(name) {
|
||||||
program = new QOpenGLShaderProgram();
|
program = new QOpenGLShaderProgram();
|
||||||
functions = renderer->getOpenGlFunctions();
|
functions = renderer->getOpenGlFunctions();
|
||||||
|
@ -25,26 +25,30 @@ OpenGLShaderProgram::~OpenGLShaderProgram() {
|
||||||
delete state;
|
delete state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLShaderProgram::addVertexSource(const std::string &path) {
|
void OpenGLShaderProgram::addVertexSource(const string &path) {
|
||||||
QFile file(QString(":/shaders/%1.vert").arg(QString::fromStdString(path)));
|
QFile file(QString(":/shaders/%1.vert").arg(QString::fromStdString(path)));
|
||||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
source_vertex += QString(file.readAll()).toStdString();
|
source_vertex += QString(file.readAll()).toStdString();
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[OpenGL] Can't open vertex file " << file.fileName().toStdString() << std::endl;
|
Logs::error() << "[OpenGL] Can't open vertex file " << file.fileName().toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLShaderProgram::addFragmentSource(const std::string &path) {
|
void OpenGLShaderProgram::addFragmentSource(const string &path) {
|
||||||
QFile file(QString(":/shaders/%1.frag").arg(QString::fromStdString(path)));
|
QFile file(QString(":/shaders/%1.frag").arg(QString::fromStdString(path)));
|
||||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
source_fragment += QString(file.readAll()).toStdString();
|
source_fragment += QString(file.readAll()).toStdString();
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[OpenGL] Can't open fragment file " << file.fileName().toStdString() << std::endl;
|
Logs::error() << "[OpenGL] Can't open fragment file " << file.fileName().toStdString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLShaderProgram::destroy(OpenGLFunctions *) {
|
||||||
|
program->removeAllShaders();
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLShaderProgram::compile() {
|
void OpenGLShaderProgram::compile() {
|
||||||
std::string prefix = std::string("#version ") + OPENGL_GLSL_VERSION + "\n\n";
|
string prefix = string("#version ") + OPENGL_GLSL_VERSION + "\n\n";
|
||||||
|
|
||||||
program->addShaderFromSourceCode(QOpenGLShader::Vertex, QString::fromStdString(prefix + source_vertex));
|
program->addShaderFromSourceCode(QOpenGLShader::Vertex, QString::fromStdString(prefix + source_vertex));
|
||||||
program->addShaderFromSourceCode(QOpenGLShader::Fragment, QString::fromStdString(prefix + source_fragment));
|
program->addShaderFromSourceCode(QOpenGLShader::Fragment, QString::fromStdString(prefix + source_fragment));
|
||||||
|
@ -53,13 +57,13 @@ void OpenGLShaderProgram::compile() {
|
||||||
program->bindAttributeLocation("uv", 1);
|
program->bindAttributeLocation("uv", 1);
|
||||||
|
|
||||||
if (not program->link()) {
|
if (not program->link()) {
|
||||||
Logs::warning() << "[OpenGL] Error while compiling shader " << name << std::endl
|
Logs::warning() << "[OpenGL] Error while compiling shader " << name << endl
|
||||||
<< program->log().toStdString() << std::endl;
|
<< program->log().toStdString() << endl;
|
||||||
} else if (program->log().length() > 0) {
|
} else if (program->log().length() > 0) {
|
||||||
Logs::debug() << "[OpenGL] Shader " << name << " compilation output:" << std::endl
|
Logs::debug() << "[OpenGL] Shader " << name << " compilation output:" << endl
|
||||||
<< program->log().toStdString() << std::endl;
|
<< program->log().toStdString() << endl;
|
||||||
} else {
|
} else {
|
||||||
Logs::debug() << "[OpenGL] Shader " << name << " compiled" << std::endl;
|
Logs::debug() << "[OpenGL] Shader " << name << " compiled" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,18 @@ namespace opengl {
|
||||||
|
|
||||||
class OPENGLSHARED_EXPORT OpenGLShaderProgram {
|
class OPENGLSHARED_EXPORT OpenGLShaderProgram {
|
||||||
public:
|
public:
|
||||||
OpenGLShaderProgram(const std::string &name, OpenGLRenderer *renderer);
|
OpenGLShaderProgram(const string &name, OpenGLRenderer *renderer);
|
||||||
~OpenGLShaderProgram();
|
~OpenGLShaderProgram();
|
||||||
|
|
||||||
void addVertexSource(const std::string &path);
|
void addVertexSource(const string &path);
|
||||||
void addFragmentSource(const std::string &path);
|
void addFragmentSource(const 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.
|
||||||
|
@ -51,14 +58,14 @@ class OPENGLSHARED_EXPORT OpenGLShaderProgram {
|
||||||
|
|
||||||
OpenGLRenderer *renderer;
|
OpenGLRenderer *renderer;
|
||||||
|
|
||||||
std::string name;
|
string name;
|
||||||
QOpenGLShaderProgram *program;
|
QOpenGLShaderProgram *program;
|
||||||
OpenGLFunctions *functions;
|
OpenGLFunctions *functions;
|
||||||
|
|
||||||
OpenGLSharedState *state;
|
OpenGLSharedState *state;
|
||||||
|
|
||||||
std::string source_vertex;
|
string source_vertex;
|
||||||
std::string source_fragment;
|
string source_fragment;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,13 @@ void OpenGLSharedState::apply(OpenGLShaderProgram *program, int &texture_unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLVariable *OpenGLSharedState::get(const std::string &name) {
|
void OpenGLSharedState::destroy(OpenGLFunctions *functions) {
|
||||||
|
for (const auto &pair : variables) {
|
||||||
|
pair.second->destroy(functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLVariable *OpenGLSharedState::get(const string &name) {
|
||||||
OpenGLVariable *&var = variables[name];
|
OpenGLVariable *&var = variables[name];
|
||||||
if (var == NULL) {
|
if (var == NULL) {
|
||||||
var = new OpenGLVariable(name);
|
var = new OpenGLVariable(name);
|
||||||
|
|
|
@ -11,61 +11,68 @@ 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.
|
||||||
*/
|
*/
|
||||||
OpenGLVariable *get(const std::string &name);
|
void destroy(OpenGLFunctions *functions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create a variable in the state.
|
||||||
|
*/
|
||||||
|
OpenGLVariable *get(const string &name);
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
inline void setInt(const std::string &name, int value) {
|
inline void setInt(const string &name, int value) {
|
||||||
get(name)->set(value);
|
get(name)->set(value);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, float value) {
|
inline void set(const string &name, float value) {
|
||||||
get(name)->set(value);
|
get(name)->set(value);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Texture2D *texture, bool repeat = false, bool color = true) {
|
inline void set(const string &name, const Texture2D *texture, bool repeat = false, bool color = true) {
|
||||||
get(name)->set(texture, repeat, color);
|
get(name)->set(texture, repeat, color);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const QImage &texture, bool repeat = false, bool color = true) {
|
inline void set(const string &name, const QImage &texture, bool repeat = false, bool color = true) {
|
||||||
get(name)->set(texture, repeat, color);
|
get(name)->set(texture, repeat, color);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Texture3D *texture, bool repeat = false, bool color = true) {
|
inline void set(const string &name, const Texture3D *texture, bool repeat = false, bool color = true) {
|
||||||
get(name)->set(texture, repeat, color);
|
get(name)->set(texture, repeat, color);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Texture4D *texture, bool repeat = false, bool color = true) {
|
inline void set(const string &name, const Texture4D *texture, bool repeat = false, bool color = true) {
|
||||||
get(name)->set(texture, repeat, color);
|
get(name)->set(texture, repeat, color);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Vector3 &vector) {
|
inline void set(const string &name, const Vector3 &vector) {
|
||||||
get(name)->set(vector);
|
get(name)->set(vector);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const QVector3D &vector) {
|
inline void set(const string &name, const QVector3D &vector) {
|
||||||
get(name)->set(vector);
|
get(name)->set(vector);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Matrix4 &matrix) {
|
inline void set(const string &name, const Matrix4 &matrix) {
|
||||||
get(name)->set(matrix);
|
get(name)->set(matrix);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const QMatrix4x4 &matrix) {
|
inline void set(const string &name, const QMatrix4x4 &matrix) {
|
||||||
get(name)->set(matrix);
|
get(name)->set(matrix);
|
||||||
}
|
}
|
||||||
inline void set(const std::string &name, const Color &color) {
|
inline void set(const string &name, const Color &color) {
|
||||||
get(name)->set(color);
|
get(name)->set(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, OpenGLVariable *> variables;
|
map<string, OpenGLVariable *> variables;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,13 @@
|
||||||
#include "AtmosphereRenderer.h"
|
#include "AtmosphereRenderer.h"
|
||||||
#include "AtmosphereModelBruneton.h"
|
#include "AtmosphereModelBruneton.h"
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
OpenGLSkybox::OpenGLSkybox(OpenGLRenderer *renderer) : OpenGLPart(renderer) {
|
static const string path_daytime = "/atmosphere/daytime";
|
||||||
|
static const string path_humidity = "/atmosphere/humidity";
|
||||||
|
static const string path_sun_radius = "/atmosphere/sun_radius";
|
||||||
|
|
||||||
|
OpenGLSkybox::OpenGLSkybox(OpenGLRenderer *renderer) : OpenGLPart(renderer, "skybox") {
|
||||||
program = createShader("skybox");
|
program = createShader("skybox");
|
||||||
program->addVertexSource("skybox");
|
program->addVertexSource("skybox");
|
||||||
program->addFragmentSource("atmosphere");
|
program->addFragmentSource("atmosphere");
|
||||||
|
@ -50,12 +55,15 @@ OpenGLSkybox::~OpenGLSkybox() {
|
||||||
|
|
||||||
void OpenGLSkybox::initialize() {
|
void OpenGLSkybox::initialize() {
|
||||||
// Watch for definition changes
|
// Watch for definition changes
|
||||||
renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true);
|
Scenery *scenery = renderer->getScenery();
|
||||||
renderer->getScenery()->getAtmosphere()->propHumidity()->addWatcher(this, true);
|
startWatching(scenery, path_daytime);
|
||||||
renderer->getScenery()->getAtmosphere()->propSunRadius()->addWatcher(this, true);
|
startWatching(scenery, path_humidity);
|
||||||
|
startWatching(scenery, path_sun_radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLSkybox::update() {
|
void OpenGLSkybox::update() {
|
||||||
|
Logs::debug() << "[OpenGL] Updating atmosphere textures" << endl;
|
||||||
|
|
||||||
SoftwareBrunetonAtmosphereRenderer *bruneton =
|
SoftwareBrunetonAtmosphereRenderer *bruneton =
|
||||||
(SoftwareBrunetonAtmosphereRenderer *)renderer->getAtmosphereRenderer();
|
(SoftwareBrunetonAtmosphereRenderer *)renderer->getAtmosphereRenderer();
|
||||||
renderer->getSharedState()->set("transmittanceTexture", bruneton->getModel()->getTextureTransmittance());
|
renderer->getSharedState()->set("transmittanceTexture", bruneton->getModel()->getTextureTransmittance());
|
||||||
|
@ -67,19 +75,20 @@ void OpenGLSkybox::render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||||
if (node->getPath() == "/atmosphere/daytime") {
|
OpenGLSharedState *state = renderer->getSharedState();
|
||||||
|
AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere();
|
||||||
|
|
||||||
|
if (node->getPath() == path_daytime) {
|
||||||
Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(false);
|
Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(false);
|
||||||
renderer->getSharedState()->set("sunDirection", sun_direction);
|
state->set("sunDirection", sun_direction);
|
||||||
|
|
||||||
Color sun_color = renderer->getScenery()->getAtmosphere()->sun_color;
|
Color sun_color = newdef->sun_color;
|
||||||
renderer->getSharedState()->set("sunColor", sun_color);
|
state->set("sunColor", sun_color);
|
||||||
|
|
||||||
renderer->getSharedState()->set("dayTime", renderer->getScenery()->getAtmosphere()->propDayTime()->getValue());
|
state->set("dayTime", newdef->propDayTime()->getValue());
|
||||||
} else if (node->getPath() == "/atmosphere/humidity") {
|
} else if (node->getPath() == path_humidity) {
|
||||||
renderer->getSharedState()->set("atmosphereHumidity",
|
state->set("atmosphereHumidity", newdef->propHumidity()->getValue());
|
||||||
renderer->getScenery()->getAtmosphere()->propHumidity()->getValue());
|
} else if (node->getPath() == path_sun_radius) {
|
||||||
} else if (node->getPath() == "/atmosphere/sun_radius") {
|
state->set("sunRadius", newdef->propSunRadius()->getValue());
|
||||||
renderer->getSharedState()->set("sunRadius",
|
|
||||||
renderer->getScenery()->getAtmosphere()->propSunRadius()->getValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ class ChunkMaintenanceThreads : public ParallelPool {
|
||||||
OpenGLTerrain *terrain;
|
OpenGLTerrain *terrain;
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenGLTerrain::OpenGLTerrain(OpenGLRenderer *renderer) : OpenGLPart(renderer) {
|
OpenGLTerrain::OpenGLTerrain(OpenGLRenderer *renderer) : OpenGLPart(renderer, "terrain") {
|
||||||
work = new ChunkMaintenanceThreads(this);
|
work = new ChunkMaintenanceThreads(this);
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
|
@ -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,9 +22,10 @@ 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();
|
virtual void pause() override;
|
||||||
void resume();
|
virtual void resume() override;
|
||||||
inline bool isPaused() const {
|
inline bool isPaused() const {
|
||||||
return paused;
|
return paused;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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*.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "Texture3D.h"
|
#include "Texture3D.h"
|
||||||
#include "Texture4D.h"
|
#include "Texture4D.h"
|
||||||
|
|
||||||
OpenGLVariable::OpenGLVariable(const std::string &name) : name(name) {
|
OpenGLVariable::OpenGLVariable(const string &name) : name(name) {
|
||||||
type = TYPE_NONE;
|
type = TYPE_NONE;
|
||||||
texture_toupload = false;
|
texture_toupload = false;
|
||||||
texture_id = 0;
|
texture_id = 0;
|
||||||
|
@ -35,7 +35,7 @@ OpenGLVariable::~OpenGLVariable() {
|
||||||
delete[] value_texture_data;
|
delete[] value_texture_data;
|
||||||
|
|
||||||
if (texture_id) {
|
if (texture_id) {
|
||||||
Logs::warning() << "[OpenGL] Texture ID not freed " << texture_id << std::endl;
|
Logs::warning() << "[OpenGL] Texture ID not freed " << texture_id << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,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);
|
||||||
|
|
||||||
|
@ -114,8 +121,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;
|
||||||
|
@ -282,8 +288,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,18 @@ class OpenGLVariable {
|
||||||
} OpenGLVariableType;
|
} OpenGLVariableType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenGLVariable(const std::string &name);
|
OpenGLVariable(const string &name);
|
||||||
~OpenGLVariable();
|
~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);
|
||||||
|
@ -50,7 +57,7 @@ class OpenGLVariable {
|
||||||
void uploadTexture(OpenGLRenderer *renderer);
|
void uploadTexture(OpenGLRenderer *renderer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name;
|
string name;
|
||||||
OpenGLVariableType type;
|
OpenGLVariableType type;
|
||||||
|
|
||||||
int value_int;
|
int value_int;
|
||||||
|
|
|
@ -25,7 +25,7 @@ class paysages::opengl::VegetationUpdater : public Thread {
|
||||||
protected:
|
protected:
|
||||||
virtual void run() override {
|
virtual void run() override {
|
||||||
while (not interrupted) {
|
while (not interrupted) {
|
||||||
std::vector<OpenGLVegetationLayer *> layers;
|
vector<OpenGLVegetationLayer *> layers;
|
||||||
vegetation->acquireLayers(layers);
|
vegetation->acquireLayers(layers);
|
||||||
for (auto layer : layers) {
|
for (auto layer : layers) {
|
||||||
layer->threadedUpdate();
|
layer->threadedUpdate();
|
||||||
|
@ -40,7 +40,7 @@ class paysages::opengl::VegetationUpdater : public Thread {
|
||||||
OpenGLVegetation *vegetation;
|
OpenGLVegetation *vegetation;
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenGLVegetation::OpenGLVegetation(OpenGLRenderer *renderer) : OpenGLPart(renderer) {
|
OpenGLVegetation::OpenGLVegetation(OpenGLRenderer *renderer) : OpenGLPart(renderer, "vegetation") {
|
||||||
layers_lock = new Mutex();
|
layers_lock = new Mutex();
|
||||||
updater = new VegetationUpdater(this);
|
updater = new VegetationUpdater(this);
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
@ -79,7 +79,7 @@ void OpenGLVegetation::update() {
|
||||||
|
|
||||||
void OpenGLVegetation::render() {
|
void OpenGLVegetation::render() {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
std::vector<OpenGLVegetationLayer *> layers;
|
vector<OpenGLVegetationLayer *> layers;
|
||||||
acquireLayers(layers);
|
acquireLayers(layers);
|
||||||
for (auto layer : layers) {
|
for (auto layer : layers) {
|
||||||
layer->render();
|
layer->render();
|
||||||
|
@ -99,7 +99,7 @@ Scenery *OpenGLVegetation::getScenery() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetation::cameraChanged(const CameraDefinition *camera) {
|
void OpenGLVegetation::cameraChanged(const CameraDefinition *camera) {
|
||||||
std::vector<OpenGLVegetationLayer *> layers;
|
vector<OpenGLVegetationLayer *> layers;
|
||||||
acquireLayers(layers);
|
acquireLayers(layers);
|
||||||
for (auto layer : layers) {
|
for (auto layer : layers) {
|
||||||
layer->setCamera(camera);
|
layer->setCamera(camera);
|
||||||
|
@ -107,7 +107,7 @@ void OpenGLVegetation::cameraChanged(const CameraDefinition *camera) {
|
||||||
releaseLayers(layers);
|
releaseLayers(layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetation::acquireLayers(std::vector<OpenGLVegetationLayer *> &layers) {
|
void OpenGLVegetation::acquireLayers(vector<OpenGLVegetationLayer *> &layers) {
|
||||||
layers_lock->acquire();
|
layers_lock->acquire();
|
||||||
|
|
||||||
for (auto layer : this->layers) {
|
for (auto layer : this->layers) {
|
||||||
|
@ -118,7 +118,7 @@ void OpenGLVegetation::acquireLayers(std::vector<OpenGLVegetationLayer *> &layer
|
||||||
layers_lock->release();
|
layers_lock->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetation::releaseLayers(const std::vector<OpenGLVegetationLayer *> &layers) {
|
void OpenGLVegetation::releaseLayers(const vector<OpenGLVegetationLayer *> &layers) {
|
||||||
// TODO Reference count
|
// TODO Reference count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,12 @@ class OPENGLSHARED_EXPORT OpenGLVegetation : public OpenGLPart, public Definitio
|
||||||
*
|
*
|
||||||
* This will not hold a lock on them, but increment a reference counter to not delete them while in use.
|
* This will not hold a lock on them, but increment a reference counter to not delete them while in use.
|
||||||
*/
|
*/
|
||||||
void acquireLayers(std::vector<OpenGLVegetationLayer *> &layers);
|
void acquireLayers(vector<OpenGLVegetationLayer *> &layers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release the layers acquired by acquireLayers.
|
* Release the layers acquired by acquireLayers.
|
||||||
*/
|
*/
|
||||||
void releaseLayers(const std::vector<OpenGLVegetationLayer *> &layers);
|
void releaseLayers(const vector<OpenGLVegetationLayer *> &layers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a rendering layer, by the matching definition layer.
|
* Find a rendering layer, by the matching definition layer.
|
||||||
|
@ -79,7 +79,7 @@ class OPENGLSHARED_EXPORT OpenGLVegetation : public OpenGLPart, public Definitio
|
||||||
private:
|
private:
|
||||||
OpenGLShaderProgram *program;
|
OpenGLShaderProgram *program;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
std::vector<OpenGLVegetationLayer *> layers;
|
vector<OpenGLVegetationLayer *> layers;
|
||||||
Mutex *layers_lock;
|
Mutex *layers_lock;
|
||||||
VegetationUpdater *updater;
|
VegetationUpdater *updater;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,8 +29,8 @@ OpenGLVegetationLayer::~OpenGLVegetationLayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetationLayer::produceInstancesInArea(double xmin, double xmax, double zmin, double zmax,
|
void OpenGLVegetationLayer::produceInstancesInArea(double xmin, double xmax, double zmin, double zmax,
|
||||||
std::vector<OpenGLVegetationInstance *> *instances) const {
|
vector<OpenGLVegetationInstance *> *instances) const {
|
||||||
std::vector<VegetationInstance> result;
|
vector<VegetationInstance> result;
|
||||||
definition->getPresence()->collectInstances(&result, *definition->getModel(), xmin, zmin, xmax, zmax, false);
|
definition->getPresence()->collectInstances(&result, *definition->getModel(), xmin, zmin, xmax, zmax, false);
|
||||||
for (auto raw_instance : result) {
|
for (auto raw_instance : result) {
|
||||||
instances->push_back(new OpenGLVegetationInstance(raw_instance));
|
instances->push_back(new OpenGLVegetationInstance(raw_instance));
|
||||||
|
@ -46,7 +46,7 @@ static bool compareInstances(OpenGLVegetationInstance *instance1, OpenGLVegetati
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetationLayer::removeInstancesOutsideArea(double xmin, double xmax, double zmin, double zmax,
|
void OpenGLVegetationLayer::removeInstancesOutsideArea(double xmin, double xmax, double zmin, double zmax,
|
||||||
std::vector<OpenGLVegetationInstance *> *instances) const {
|
vector<OpenGLVegetationInstance *> *instances) const {
|
||||||
for (auto &instance : *instances) {
|
for (auto &instance : *instances) {
|
||||||
Vector3 base = instance->getBase();
|
Vector3 base = instance->getBase();
|
||||||
if (base.x < xmin or base.x >= xmax or base.z < zmin or base.z >= zmax) {
|
if (base.x < xmin or base.x >= xmax or base.z < zmin or base.z >= zmax) {
|
||||||
|
@ -56,7 +56,7 @@ void OpenGLVegetationLayer::removeInstancesOutsideArea(double xmin, double xmax,
|
||||||
instance = NULL;
|
instance = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instances->erase(std::remove_if(instances->begin(), instances->end(), isNull), instances->end());
|
instances->erase(remove_if(instances->begin(), instances->end(), isNull), instances->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLVegetationLayer::threadedUpdate() {
|
void OpenGLVegetationLayer::threadedUpdate() {
|
||||||
|
@ -71,7 +71,7 @@ void OpenGLVegetationLayer::threadedUpdate() {
|
||||||
newzmax = camera_location->z + range;
|
newzmax = camera_location->z + range;
|
||||||
|
|
||||||
// Prepare instances where area grew
|
// Prepare instances where area grew
|
||||||
std::vector<OpenGLVegetationInstance *> new_instances;
|
vector<OpenGLVegetationInstance *> new_instances;
|
||||||
if (newxmin < xmin) {
|
if (newxmin < xmin) {
|
||||||
produceInstancesInArea(newxmin, xmin, newzmin, newzmax, &new_instances);
|
produceInstancesInArea(newxmin, xmin, newzmin, newzmax, &new_instances);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ void OpenGLVegetationLayer::threadedUpdate() {
|
||||||
for (auto instance : instances) {
|
for (auto instance : instances) {
|
||||||
instance->setDistance(instance->getBase().sub(*camera_location).getNorm());
|
instance->setDistance(instance->getBase().sub(*camera_location).getNorm());
|
||||||
}
|
}
|
||||||
std::sort(instances.begin(), instances.end(), compareInstances);
|
sort(instances.begin(), instances.end(), compareInstances);
|
||||||
lock_instances->release();
|
lock_instances->release();
|
||||||
|
|
||||||
// Update impostor texture
|
// Update impostor texture
|
||||||
|
|
|
@ -26,13 +26,13 @@ class OPENGLSHARED_EXPORT OpenGLVegetationLayer {
|
||||||
* The array is not checked for already present instances.
|
* The array is not checked for already present instances.
|
||||||
*/
|
*/
|
||||||
virtual void produceInstancesInArea(double xmin, double xmax, double zmin, double zmax,
|
virtual void produceInstancesInArea(double xmin, double xmax, double zmin, double zmax,
|
||||||
std::vector<OpenGLVegetationInstance *> *instances) const;
|
vector<OpenGLVegetationInstance *> *instances) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove instances outside of a given area.
|
* Remove instances outside of a given area.
|
||||||
*/
|
*/
|
||||||
virtual void removeInstancesOutsideArea(double xmin, double xmax, double zmin, double zmax,
|
virtual void removeInstancesOutsideArea(double xmin, double xmax, double zmin, double zmax,
|
||||||
std::vector<OpenGLVegetationInstance *> *instances) const;
|
vector<OpenGLVegetationInstance *> *instances) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform maintenance tasks that can be perform in a thread.
|
* Perform maintenance tasks that can be perform in a thread.
|
||||||
|
@ -70,7 +70,7 @@ class OPENGLSHARED_EXPORT OpenGLVegetationLayer {
|
||||||
double zmax;
|
double zmax;
|
||||||
double range;
|
double range;
|
||||||
bool own_instances;
|
bool own_instances;
|
||||||
std::vector<OpenGLVegetationInstance *> instances;
|
vector<OpenGLVegetationInstance *> instances;
|
||||||
Mutex *lock_instances;
|
Mutex *lock_instances;
|
||||||
OpenGLVegetationImpostor *impostor;
|
OpenGLVegetationImpostor *impostor;
|
||||||
Vector3 *camera_location;
|
Vector3 *camera_location;
|
||||||
|
|
|
@ -23,15 +23,26 @@ OpenGLVertexArray::OpenGLVertexArray(bool has_uv, bool strip) : has_uv(has_uv) {
|
||||||
|
|
||||||
OpenGLVertexArray::~OpenGLVertexArray() {
|
OpenGLVertexArray::~OpenGLVertexArray() {
|
||||||
if (vao || vbo_vertex || vbo_uv) {
|
if (vao || vbo_vertex || vbo_uv) {
|
||||||
Logs::warning() << "[OpenGL] VertexArray not freed in OpenGL state before destructor called" << std::endl;
|
Logs::warning() << "[OpenGL] VertexArray not freed in OpenGL state before destructor called" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(array_vertex);
|
free(array_vertex);
|
||||||
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, int start, int count) {
|
void OpenGLVertexArray::render(OpenGLFunctions *functions, int start, int count) {
|
||||||
|
@ -68,12 +79,11 @@ void OpenGLVertexArray::set(int index, const Vector3 &location, double u, double
|
||||||
array_uv[index * 2 + 1] = v;
|
array_uv[index * 2 + 1] = v;
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[OpenGL] Setting vertex data outside of array bounds" << std::endl;
|
Logs::error() << "[OpenGL] Setting vertex data outside of array bounds" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -81,12 +91,11 @@ void OpenGLVertexArray::get(int index, Vector3 *location, double *u, double *v)
|
||||||
*u = array_uv[index * 2];
|
*u = array_uv[index * 2];
|
||||||
*v = array_uv[index * 2 + 1];
|
*v = array_uv[index * 2 + 1];
|
||||||
} else {
|
} else {
|
||||||
Logs::error() << "[OpenGL] Getting vertex data outside of array bounds" << std::endl;
|
Logs::error() << "[OpenGL] Getting vertex data outside of array bounds" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
||||||
|
|
|
@ -12,8 +12,13 @@
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
#include "FloatDiff.h"
|
#include "FloatDiff.h"
|
||||||
#include "IntNode.h"
|
#include "IntNode.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
OpenGLWater::OpenGLWater(OpenGLRenderer *renderer) : OpenGLPart(renderer) {
|
static const string path_height = "/terrain/water_height";
|
||||||
|
static const string path_reflection = "/water/reflection";
|
||||||
|
static const string path_model = "/water/model";
|
||||||
|
|
||||||
|
OpenGLWater::OpenGLWater(OpenGLRenderer *renderer) : OpenGLPart(renderer, "water") {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
program = createShader("water");
|
program = createShader("water");
|
||||||
|
@ -38,19 +43,23 @@ OpenGLWater::~OpenGLWater() {
|
||||||
|
|
||||||
void OpenGLWater::initialize() {
|
void OpenGLWater::initialize() {
|
||||||
// Watch for definition changes
|
// Watch for definition changes
|
||||||
renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this, true);
|
Scenery *scenery = renderer->getScenery();
|
||||||
renderer->getScenery()->getWater()->propReflection()->addWatcher(this, true);
|
startWatching(scenery, path_height);
|
||||||
renderer->getScenery()->getWater()->propModel()->addWatcher(this, false);
|
startWatching(scenery, path_reflection);
|
||||||
|
startWatching(scenery, path_model, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLWater::update() {
|
void OpenGLWater::update() {
|
||||||
WaterDefinition *water = renderer->getScenery()->getWater();
|
OpenGLSharedState *state = renderer->getSharedState();
|
||||||
renderer->getSharedState()->set("waterMaterialColor", *water->material->base);
|
|
||||||
renderer->getSharedState()->set("waterMaterialReflection", water->material->reflection);
|
|
||||||
renderer->getSharedState()->set("waterMaterialShininess", water->material->shininess);
|
|
||||||
renderer->getSharedState()->set("waterMaterialHardness", water->material->hardness);
|
|
||||||
|
|
||||||
renderer->getSharedState()->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
|
WaterDefinition *water = renderer->getScenery()->getWater();
|
||||||
|
state->set("waterMaterialColor", *water->material->base);
|
||||||
|
state->set("waterMaterialReflection", water->material->reflection);
|
||||||
|
state->set("waterMaterialShininess", water->material->shininess);
|
||||||
|
state->set("waterMaterialHardness", water->material->hardness);
|
||||||
|
|
||||||
|
Logs::debug() << "[OpenGL] Updating simplex texture" << endl;
|
||||||
|
state->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLWater::render() {
|
void OpenGLWater::render() {
|
||||||
|
@ -60,12 +69,13 @@ void OpenGLWater::render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLWater::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
void OpenGLWater::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||||
if (node->getPath() == "/terrain/water_height") {
|
OpenGLSharedState *state = renderer->getSharedState();
|
||||||
renderer->getSharedState()->set("waterOffset", renderer->getScenery()->getTerrain()->getWaterOffset());
|
|
||||||
} else if (node->getPath() == "/water/reflection") {
|
if (node->getPath() == path_height) {
|
||||||
renderer->getSharedState()->set("waterReflection",
|
state->set("waterOffset", renderer->getScenery()->getTerrain()->getWaterOffset());
|
||||||
renderer->getScenery()->getWater()->propReflection()->getValue());
|
} else if (node->getPath() == path_reflection) {
|
||||||
} else if (node->getPath() == "/water/model") {
|
state->set("waterReflection", renderer->getScenery()->getWater()->propReflection()->getValue());
|
||||||
|
} else if (node->getPath() == path_model) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
class WidgetExplorer;
|
|
||||||
class OpenGLRenderer;
|
class OpenGLRenderer;
|
||||||
|
class OpenGLPart;
|
||||||
class OpenGLShaderProgram;
|
class OpenGLShaderProgram;
|
||||||
class OpenGLSharedState;
|
class OpenGLSharedState;
|
||||||
class OpenGLVariable;
|
class OpenGLVariable;
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AtmosphereModelBruneton::getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const {
|
bool AtmosphereModelBruneton::getLightsAt(vector<LightComponent> &result, const Vector3 &location) const {
|
||||||
LightComponent sun, irradiance;
|
LightComponent sun, irradiance;
|
||||||
double muS;
|
double muS;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SOFTWARESHARED_EXPORT AtmosphereModelBruneton : public LightSource {
|
||||||
|
|
||||||
AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
|
AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
|
||||||
AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base);
|
AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base);
|
||||||
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||||
|
|
||||||
/* Functions to get access to internal textures (for opengl shaders) */
|
/* Functions to get access to internal textures (for opengl shaders) */
|
||||||
Texture2D *getTextureTransmittance() const;
|
Texture2D *getTextureTransmittance() const;
|
||||||
|
|
|
@ -92,7 +92,7 @@ Vector3 BaseAtmosphereRenderer::getSunDirection(bool) const {
|
||||||
return Vector3(cos(sun_angle), sin(sun_angle), 0.0);
|
return Vector3(cos(sun_angle), sin(sun_angle), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseAtmosphereRenderer::getLightsAt(std::vector<LightComponent> &, const Vector3 &) const {
|
bool BaseAtmosphereRenderer::getLightsAt(vector<LightComponent> &, const Vector3 &) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +195,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoftwareBrunetonAtmosphereRenderer::getLightsAt(std::vector<LightComponent> &result,
|
bool SoftwareBrunetonAtmosphereRenderer::getLightsAt(vector<LightComponent> &result, const Vector3 &location) const {
|
||||||
const Vector3 &location) const {
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
changed |= model->getLightsAt(result, location);
|
changed |= model->getLightsAt(result, location);
|
||||||
changed |= parent->getNightSky()->getLightsAt(result, location);
|
changed |= parent->getNightSky()->getLightsAt(result, location);
|
||||||
|
|
|
@ -18,7 +18,7 @@ class BaseAtmosphereRenderer : public LightSource {
|
||||||
virtual AtmosphereResult getSkyColor(const Vector3 &direction);
|
virtual AtmosphereResult getSkyColor(const Vector3 &direction);
|
||||||
virtual Vector3 getSunDirection(bool cache = true) const;
|
virtual Vector3 getSunDirection(bool cache = true) const;
|
||||||
|
|
||||||
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AtmosphereDefinition *getDefinition() const;
|
virtual AtmosphereDefinition *getDefinition() const;
|
||||||
|
@ -33,7 +33,7 @@ class SoftwareBrunetonAtmosphereRenderer : public BaseAtmosphereRenderer {
|
||||||
virtual AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base) override;
|
virtual AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base) override;
|
||||||
virtual AtmosphereResult getSkyColor(const Vector3 &direction) override;
|
virtual AtmosphereResult getSkyColor(const Vector3 &direction) override;
|
||||||
|
|
||||||
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||||
|
|
||||||
inline const AtmosphereModelBruneton *getModel() const {
|
inline const AtmosphereModelBruneton *getModel() const {
|
||||||
return model;
|
return model;
|
||||||
|
|
|
@ -99,7 +99,7 @@ CanvasPortion *Canvas::atPixel(int x, int y) const {
|
||||||
return at(px, py);
|
return at(px, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const {
|
bool Canvas::saveToDisk(const string &filepath, const ColorProfile &profile, int antialias) const {
|
||||||
assert(antialias >= 1);
|
assert(antialias >= 1);
|
||||||
|
|
||||||
CanvasPictureWriter writer(this);
|
CanvasPictureWriter writer(this);
|
||||||
|
|
|
@ -46,10 +46,10 @@ class SOFTWARESHARED_EXPORT Canvas {
|
||||||
*
|
*
|
||||||
* Returns true if the save was successful.
|
* Returns true if the save was successful.
|
||||||
*/
|
*/
|
||||||
bool saveToDisk(const std::string &filepath, const ColorProfile &profile, int antialias) const;
|
bool saveToDisk(const string &filepath, const ColorProfile &profile, int antialias) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CanvasPortion *> portions;
|
vector<CanvasPortion *> portions;
|
||||||
int horizontal_portion_count;
|
int horizontal_portion_count;
|
||||||
int vertical_portion_count;
|
int vertical_portion_count;
|
||||||
int width;
|
int width;
|
||||||
|
|
|
@ -37,7 +37,7 @@ void CanvasPictureWriter::setColorProfile(const ColorProfile &profile) {
|
||||||
profile.copy(this->profile);
|
profile.copy(this->profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanvasPictureWriter::saveCanvas(const std::string &filepath) {
|
bool CanvasPictureWriter::saveCanvas(const string &filepath) {
|
||||||
return save(filepath, width, height);
|
return save(filepath, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class SOFTWARESHARED_EXPORT CanvasPictureWriter : public PictureWriter {
|
||||||
*
|
*
|
||||||
* Returns true if saving was successful.
|
* Returns true if saving was successful.
|
||||||
*/
|
*/
|
||||||
bool saveCanvas(const std::string &filepath);
|
bool saveCanvas(const string &filepath);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual unsigned int getPixel(int x, int y) override;
|
virtual unsigned int getPixel(int x, int y) override;
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
assert(pixels != NULL)
|
assert(pixels != NULL)
|
||||||
|
|
||||||
// Keep track of created files to erase them at program exit
|
// Keep track of created files to erase them at program exit
|
||||||
static std::vector<std::string> _files;
|
static vector<string> _files;
|
||||||
static void clean_all_files() {
|
static void clean_all_files() {
|
||||||
for (auto &filepath : _files) {
|
for (auto &filepath : _files) {
|
||||||
FileSystem::removeFile(filepath);
|
FileSystem::removeFile(filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int _atexit = std::atexit(clean_all_files);
|
static int _atexit = atexit(clean_all_files);
|
||||||
|
|
||||||
CanvasPortion::CanvasPortion(int index, CanvasPreview *preview) : index(index), preview(preview) {
|
CanvasPortion::CanvasPortion(int index, CanvasPreview *preview) : index(index), preview(preview) {
|
||||||
width = 1;
|
width = 1;
|
||||||
|
@ -86,8 +86,7 @@ void CanvasPortion::discardPixels(bool save) {
|
||||||
void CanvasPortion::saveToDisk() {
|
void CanvasPortion::saveToDisk() {
|
||||||
if (pixels) {
|
if (pixels) {
|
||||||
auto pid = System::getProcessId();
|
auto pid = System::getProcessId();
|
||||||
filepath =
|
filepath = FileSystem::getTempFile("paysages_portion_" + to_string(index) + "_" + to_string(pid) + ".dat");
|
||||||
FileSystem::getTempFile("paysages_portion_" + std::to_string(index) + "_" + std::to_string(pid) + ".dat");
|
|
||||||
PackStream stream;
|
PackStream stream;
|
||||||
stream.bindToFile(filepath, true);
|
stream.bindToFile(filepath, true);
|
||||||
stream.write(&width);
|
stream.write(&width);
|
||||||
|
|
|
@ -89,7 +89,7 @@ class SOFTWARESHARED_EXPORT CanvasPortion {
|
||||||
int yoffset;
|
int yoffset;
|
||||||
CanvasPixel *pixels;
|
CanvasPixel *pixels;
|
||||||
CanvasPreview *preview;
|
CanvasPreview *preview;
|
||||||
std::string filepath;
|
string filepath;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ BaseCloudLayerRenderer *CloudsRenderer::getLayerRenderer(unsigned int layer) {
|
||||||
if (layer < layer_renderers.size()) {
|
if (layer < layer_renderers.size()) {
|
||||||
return layer_renderers[layer];
|
return layer_renderers[layer];
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "Asked for unknown layer renderer " << layer << std::endl;
|
Logs::warning() << "Asked for unknown layer renderer " << layer << endl;
|
||||||
return fake_renderer;
|
return fake_renderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ BaseCloudsModel *CloudsRenderer::getLayerModel(unsigned int layer) {
|
||||||
if (layer < layer_models.size()) {
|
if (layer < layer_models.size()) {
|
||||||
return layer_models[layer];
|
return layer_models[layer];
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "Asked for unknown layer model" << layer << std::endl;
|
Logs::warning() << "Asked for unknown layer model" << layer << endl;
|
||||||
return fake_model;
|
return fake_model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ void CloudsRenderer::setLayerModel(unsigned int layer, BaseCloudsModel *model, b
|
||||||
}
|
}
|
||||||
layer_models[layer] = model;
|
layer_models[layer] = model;
|
||||||
} else {
|
} else {
|
||||||
Logs::warning() << "Asked to set an unknown layer model" << layer << std::endl;
|
Logs::warning() << "Asked to set an unknown layer model" << layer << endl;
|
||||||
delete model;
|
delete model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,10 @@ class SOFTWARESHARED_EXPORT CloudsRenderer : public LightFilter {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
SoftwareRenderer *parent;
|
SoftwareRenderer *parent;
|
||||||
|
|
||||||
std::vector<BaseCloudLayerRenderer *> layer_renderers;
|
vector<BaseCloudLayerRenderer *> layer_renderers;
|
||||||
BaseCloudLayerRenderer *fake_renderer;
|
BaseCloudLayerRenderer *fake_renderer;
|
||||||
|
|
||||||
std::vector<BaseCloudsModel *> layer_models;
|
vector<BaseCloudsModel *> layer_models;
|
||||||
BaseCloudsModel *fake_model;
|
BaseCloudsModel *fake_model;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class SOFTWARESHARED_EXPORT FluidMediumManager {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SoftwareRenderer *renderer;
|
SoftwareRenderer *renderer;
|
||||||
std::vector<FluidMediumInterface *> media;
|
vector<FluidMediumInterface *> media;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class SOFTWARESHARED_EXPORT LightSource {
|
||||||
*
|
*
|
||||||
* Returns true if lights were added to *result*.
|
* Returns true if lights were added to *result*.
|
||||||
*/
|
*/
|
||||||
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const = 0;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ class SOFTWARESHARED_EXPORT LightStatus {
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
Vector3 eye;
|
Vector3 eye;
|
||||||
bool filtered;
|
bool filtered;
|
||||||
std::vector<LightComponent> components;
|
vector<LightComponent> components;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,14 @@ void LightingManager::clearSources() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightingManager::registerSource(LightSource *source) {
|
void LightingManager::registerSource(LightSource *source) {
|
||||||
if (std::find(sources.begin(), sources.end(), source) == sources.end()) {
|
if (find(sources.begin(), sources.end(), source) == sources.end()) {
|
||||||
sources.push_back(source);
|
sources.push_back(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightingManager::unregisterSource(LightSource *source) {
|
void LightingManager::unregisterSource(LightSource *source) {
|
||||||
if (std::find(sources.begin(), sources.end(), source) != sources.end()) {
|
if (find(sources.begin(), sources.end(), source) != sources.end()) {
|
||||||
sources.erase(std::find(sources.begin(), sources.end(), source));
|
sources.erase(find(sources.begin(), sources.end(), source));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ void LightingManager::clearFilters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightingManager::registerFilter(LightFilter *filter) {
|
void LightingManager::registerFilter(LightFilter *filter) {
|
||||||
if (std::find(filters.begin(), filters.end(), filter) == filters.end()) {
|
if (find(filters.begin(), filters.end(), filter) == filters.end()) {
|
||||||
filters.push_back(filter);
|
filters.push_back(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightingManager::unregisterFilter(LightFilter *filter) {
|
void LightingManager::unregisterFilter(LightFilter *filter) {
|
||||||
if (std::find(filters.begin(), filters.end(), filter) != filters.end()) {
|
if (find(filters.begin(), filters.end(), filter) != filters.end()) {
|
||||||
filters.erase(std::find(filters.begin(), filters.end(), filter));
|
filters.erase(find(filters.begin(), filters.end(), filter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ void LightingManager::fillStatus(LightStatus &status, const Vector3 &location) c
|
||||||
status.pushComponent(light);
|
status.pushComponent(light);
|
||||||
}
|
}
|
||||||
for (auto source : sources) {
|
for (auto source : sources) {
|
||||||
std::vector<LightComponent> lights;
|
vector<LightComponent> lights;
|
||||||
if (source->getLightsAt(lights, location)) {
|
if (source->getLightsAt(lights, location)) {
|
||||||
for (auto &light : lights) {
|
for (auto &light : lights) {
|
||||||
status.pushComponent(light);
|
status.pushComponent(light);
|
||||||
|
|
|
@ -102,9 +102,9 @@ class SOFTWARESHARED_EXPORT LightingManager {
|
||||||
private:
|
private:
|
||||||
bool specularity;
|
bool specularity;
|
||||||
bool filtering;
|
bool filtering;
|
||||||
std::vector<LightComponent> static_lights;
|
vector<LightComponent> static_lights;
|
||||||
std::vector<LightFilter *> filters;
|
vector<LightFilter *> filters;
|
||||||
std::vector<LightSource *> sources;
|
vector<LightSource *> sources;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NightSky::getLightsAt(std::vector<LightComponent> &result, const Vector3 &) const {
|
bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &) const {
|
||||||
LightComponent moon, sky;
|
LightComponent moon, sky;
|
||||||
|
|
||||||
AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere();
|
AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere();
|
||||||
|
|
|
@ -27,7 +27,7 @@ class SOFTWARESHARED_EXPORT NightSky : public LightSource {
|
||||||
*/
|
*/
|
||||||
virtual const Color getColor(double altitude, const Vector3 &direction);
|
virtual const Color getColor(double altitude, const Vector3 &direction);
|
||||||
|
|
||||||
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
|
virtual bool getLightsAt(vector<LightComponent> &result, const Vector3 &location) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SoftwareRenderer *renderer;
|
SoftwareRenderer *renderer;
|
||||||
|
|
|
@ -72,7 +72,7 @@ void RenderProgress::exitSub() {
|
||||||
|
|
||||||
void RenderProgress::end() {
|
void RenderProgress::end() {
|
||||||
if (subs.size() > 0) {
|
if (subs.size() > 0) {
|
||||||
Logs::error() << subs.size() << " progress subs remaining at the end of render" << std::endl;
|
Logs::error() << subs.size() << " progress subs remaining at the end of render" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
end_time = Time::getRelativeTimeMs();
|
end_time = Time::getRelativeTimeMs();
|
||||||
|
|
|
@ -58,7 +58,7 @@ class SOFTWARESHARED_EXPORT RenderProgress {
|
||||||
double prev_est_done;
|
double prev_est_done;
|
||||||
double prev_est_speed;
|
double prev_est_speed;
|
||||||
|
|
||||||
std::stack<RenderSub> subs;
|
stack<RenderSub> subs;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ const Rasterizer &SoftwareCanvasRenderer::getRasterizer(int client_id) const {
|
||||||
return *(rasterizers[client_id]);
|
return *(rasterizers[client_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoftwareCanvasRenderer::saveToDisk(const std::string &filepath) const {
|
bool SoftwareCanvasRenderer::saveToDisk(const string &filepath) const {
|
||||||
return getCanvas()->saveToDisk(filepath, *getCanvas()->getPreview()->getToneMapping(), samples);
|
return getCanvas()->saveToDisk(filepath, *getCanvas()->getPreview()->getToneMapping(), samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class SOFTWARESHARED_EXPORT SoftwareCanvasRenderer : public SoftwareRenderer {
|
||||||
*
|
*
|
||||||
* Returns true if the save was successful.
|
* Returns true if the save was successful.
|
||||||
*/
|
*/
|
||||||
bool saveToDisk(const std::string &filepath) const;
|
bool saveToDisk(const string &filepath) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +114,7 @@ class SOFTWARESHARED_EXPORT SoftwareCanvasRenderer : public SoftwareRenderer {
|
||||||
Canvas *canvas;
|
Canvas *canvas;
|
||||||
int samples;
|
int samples;
|
||||||
|
|
||||||
std::vector<Rasterizer *> rasterizers;
|
vector<Rasterizer *> rasterizers;
|
||||||
Rasterizer *rasterizer_sky;
|
Rasterizer *rasterizer_sky;
|
||||||
Rasterizer *rasterizer_water;
|
Rasterizer *rasterizer_water;
|
||||||
Rasterizer *rasterizer_terrain;
|
Rasterizer *rasterizer_terrain;
|
||||||
|
|
|
@ -196,7 +196,7 @@ void TerrainRenderer::estimateMinMaxHeight(double x1, double z1, double x2, doub
|
||||||
// TODO Apply max slope
|
// TODO Apply max slope
|
||||||
// TODO Estimate displacement
|
// TODO Estimate displacement
|
||||||
|
|
||||||
std::pair<double, double> minmax = std::minmax(y1, y2);
|
pair<double, double> limits = minmax(y1, y2);
|
||||||
*ymin = minmax.first;
|
*ymin = limits.first;
|
||||||
*ymax = minmax.second;
|
*ymax = limits.second;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ RayCastingResult VegetationRenderer::getBoundResult(const SpaceSegment &segment,
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
VegetationLayerDefinition *layer = vegetation->getVegetationLayer(i);
|
VegetationLayerDefinition *layer = vegetation->getVegetationLayer(i);
|
||||||
|
|
||||||
std::vector<VegetationInstance> instances;
|
vector<VegetationInstance> instances;
|
||||||
layer->getPresence()->collectInstances(&instances, *layer->getModel(), x, z, x + xsize, z + zsize);
|
layer->getPresence()->collectInstances(&instances, *layer->getModel(), x, z, x + xsize, z + zsize);
|
||||||
|
|
||||||
for (auto &instance : instances) {
|
for (auto &instance : instances) {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "DataFile.h"
|
#include "DataFile.h"
|
||||||
|
|
||||||
CacheFile::CacheFile(const std::string &module, const std::string &ext, const std::string &tag1, int tag2, int tag3,
|
CacheFile::CacheFile(const string &module, const string &ext, const string &tag1, int tag2, int tag3, int tag4,
|
||||||
int tag4, int tag5, int tag6) {
|
int tag5, int tag6) {
|
||||||
filepath = QString("cache/%1-%2-%3-%4-%5-%6-%7.%8")
|
filepath = QString("cache/%1-%2-%3-%4-%5-%6-%7.%8")
|
||||||
.arg(QString::fromStdString(module))
|
.arg(QString::fromStdString(module))
|
||||||
.arg(QString::fromStdString(tag1))
|
.arg(QString::fromStdString(tag1))
|
||||||
|
@ -23,7 +23,7 @@ bool CacheFile::isReadable() {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
std::string datapath = DataFile::findFile(filepath);
|
string datapath = DataFile::findFile(filepath);
|
||||||
if (datapath.empty()) {
|
if (datapath.empty()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,8 +48,8 @@ bool CacheFile::isWritable() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CacheFile::getPath() {
|
string CacheFile::getPath() {
|
||||||
std::string datapath = DataFile::findFile(filepath);
|
string datapath = DataFile::findFile(filepath);
|
||||||
if (datapath.empty()) {
|
if (datapath.empty()) {
|
||||||
return filepath;
|
return filepath;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,15 +8,15 @@ namespace system {
|
||||||
|
|
||||||
class SYSTEMSHARED_EXPORT CacheFile {
|
class SYSTEMSHARED_EXPORT CacheFile {
|
||||||
public:
|
public:
|
||||||
CacheFile(const std::string &module, const std::string &ext, const std::string &tag1, int tag2, int tag3, int tag4,
|
CacheFile(const string &module, const string &ext, const string &tag1, int tag2, int tag3, int tag4, int tag5,
|
||||||
int tag5, int tag6);
|
int tag6);
|
||||||
|
|
||||||
bool isReadable();
|
bool isReadable();
|
||||||
bool isWritable();
|
bool isWritable();
|
||||||
std::string getPath();
|
string getPath();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filepath;
|
string filepath;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
std::string DataFile::findFile(const std::string &relpath) {
|
string DataFile::findFile(const string &relpath) {
|
||||||
if (dataDir.empty()) {
|
if (dataDir.empty()) {
|
||||||
dataDir = initDataDir();
|
dataDir = initDataDir();
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,16 @@ std::string DataFile::findFile(const std::string &relpath) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataFile::findDir(const std::string &relpath) {
|
string DataFile::findDir(const string &relpath) {
|
||||||
return findFile(relpath);
|
return findFile(relpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataFile::tryDataDir(const QDir &dir) {
|
bool DataFile::tryDataDir(const QDir &dir) {
|
||||||
Logs::debug() << "[System] Try data dir " << dir.absolutePath().toStdString() << std::endl;
|
Logs::debug() << "[System] Try data dir " << dir.absolutePath().toStdString() << endl;
|
||||||
return dir.exists("data/.paysages_data");
|
return dir.exists("data/.paysages_data");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataFile::locateDataDir() {
|
string DataFile::locateDataDir() {
|
||||||
QDir dir = QDir::current();
|
QDir dir = QDir::current();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -47,16 +47,16 @@ std::string DataFile::locateDataDir() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataFile::initDataDir() {
|
string DataFile::initDataDir() {
|
||||||
std::string parent = locateDataDir();
|
string parent = locateDataDir();
|
||||||
if (parent.empty()) {
|
if (parent.empty()) {
|
||||||
Logs::warning() << "[System] Data files not found" << std::endl;
|
Logs::warning() << "[System] Data files not found" << endl;
|
||||||
return parent;
|
return parent;
|
||||||
} else {
|
} else {
|
||||||
std::string result = QDir(QString::fromStdString(parent)).absoluteFilePath("data").toStdString();
|
string result = QDir(QString::fromStdString(parent)).absoluteFilePath("data").toStdString();
|
||||||
Logs::debug() << "[System] Data files found : " << result << std::endl;
|
Logs::debug() << "[System] Data files found : " << result << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataFile::dataDir;
|
string DataFile::dataDir;
|
||||||
|
|
|
@ -18,20 +18,20 @@ class SYSTEMSHARED_EXPORT DataFile {
|
||||||
*
|
*
|
||||||
* Return the absolute data path, or an empty string if not found.
|
* Return the absolute data path, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
static std::string findFile(const std::string &relpath);
|
static string findFile(const string &relpath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a data directory.
|
* Find a data directory.
|
||||||
*
|
*
|
||||||
* Return the absolute data path, or an empty string if not found.
|
* Return the absolute data path, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
static std::string findDir(const std::string &relpath);
|
static string findDir(const string &relpath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool tryDataDir(const QDir &dir);
|
static bool tryDataDir(const QDir &dir);
|
||||||
static std::string locateDataDir();
|
static string locateDataDir();
|
||||||
static std::string initDataDir();
|
static string initDataDir();
|
||||||
static std::string dataDir;
|
static string dataDir;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
std::string FileSystem::getTempFile(const std::string &filename) {
|
string FileSystem::getTempFile(const string &filename) {
|
||||||
return QDir::temp().filePath(QString::fromStdString(filename)).toStdString();
|
return QDir::temp().filePath(QString::fromStdString(filename)).toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::isFile(const std::string &filepath) {
|
bool FileSystem::isFile(const string &filepath) {
|
||||||
return QFileInfo(QString::fromStdString(filepath)).exists();
|
return QFileInfo(QString::fromStdString(filepath)).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::removeFile(const std::string &filepath) {
|
bool FileSystem::removeFile(const string &filepath) {
|
||||||
if (FileSystem::isFile(filepath)) {
|
if (FileSystem::isFile(filepath)) {
|
||||||
remove(filepath.c_str());
|
remove(filepath.c_str());
|
||||||
return true;
|
return true;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue