Feature/model lighting (#670)

* Fix NH texture and add lighting options
* Add missing comma
* Light sources: work in progress.
* Add light sources
* Remove unused values
* Add types to documentation
* Add light sources to various missions
* Code cleanup based on review
This commit is contained in:
Emil Axelsson
2018-07-13 09:01:43 +02:00
committed by GitHub
parent 8a6dd14330
commit 6007f1d70d
23 changed files with 962 additions and 93 deletions
+167 -40
View File
@@ -33,6 +33,8 @@
#include <openspace/util/time.h>
#include <openspace/util/updatestructures.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/lightsource.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/misc/invariants.h>
@@ -52,6 +54,24 @@ namespace {
"rendered in this object."
};
constexpr openspace::properties::Property::PropertyInfo AmbientIntensityInfo = {
"AmbientIntensity",
"Ambient Intensity",
"A multiplier for ambient lighting."
};
constexpr openspace::properties::Property::PropertyInfo DiffuseIntensityInfo = {
"DiffuseIntensity",
"Diffuse Intensity",
"A multiplier for diffuse lighting."
};
constexpr openspace::properties::Property::PropertyInfo SpecularIntensityInfo = {
"SpecularIntensity",
"Specular Intensity",
"A multiplier for specular lighting."
};
constexpr openspace::properties::Property::PropertyInfo ShadingInfo = {
"PerformShading",
"Perform Shading",
@@ -65,6 +85,12 @@ namespace {
"This value specifies the model transform that is applied to the model before "
"all other transformations are applied."
};
constexpr openspace::properties::Property::PropertyInfo LightSourcesInfo = {
"LightSources",
"Light Sources",
"A list of light sources that this model should accept light from."
};
} // namespace
namespace openspace {
@@ -87,6 +113,24 @@ documentation::Documentation RenderableModel::Documentation() {
Optional::Yes,
TextureInfo.description
},
{
AmbientIntensityInfo.identifier,
new DoubleVerifier,
Optional::Yes,
AmbientIntensityInfo.description
},
{
DiffuseIntensityInfo.identifier,
new DoubleVerifier,
Optional::Yes,
DiffuseIntensityInfo.description
},
{
SpecularIntensityInfo.identifier,
new DoubleVerifier,
Optional::Yes,
SpecularIntensityInfo.description
},
{
ShadingInfo.identifier,
new BoolVerifier,
@@ -98,6 +142,18 @@ documentation::Documentation RenderableModel::Documentation() {
new DoubleMatrix3Verifier,
Optional::Yes,
ModelTransformInfo.description
},
{
LightSourcesInfo.identifier,
new TableVerifier({
{
"*",
new ReferencingVerifier("core_light_source"),
Optional::Yes
}
}),
Optional::Yes,
LightSourcesInfo.description
}
}
};
@@ -106,8 +162,12 @@ documentation::Documentation RenderableModel::Documentation() {
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath(TextureInfo)
, _ambientIntensity(AmbientIntensityInfo, 0.2, 0.0, 1.0)
, _diffuseIntensity(DiffuseIntensityInfo, 1.0, 0.0, 1.0)
, _specularIntensity(SpecularIntensityInfo, 1.0, 0.0, 1.0)
, _performShading(ShadingInfo, true)
, _modelTransform(ModelTransformInfo, glm::mat3(1.0))
, _lightSourcePropertyOwner({ "LightSources", "Light Sources" })
{
documentation::testSpecificationAndThrow(
Documentation(),
@@ -134,22 +194,58 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
_modelTransform = dictionary.value<glm::dmat3>(ModelTransformInfo.identifier);
}
if (dictionary.hasKey(AmbientIntensityInfo.identifier)) {
_ambientIntensity = dictionary.value<float>(AmbientIntensityInfo.identifier);
}
if (dictionary.hasKey(DiffuseIntensityInfo.identifier)) {
_diffuseIntensity = dictionary.value<float>(DiffuseIntensityInfo.identifier);
}
if (dictionary.hasKey(SpecularIntensityInfo.identifier)) {
_specularIntensity = dictionary.value<float>(SpecularIntensityInfo.identifier);
}
if (dictionary.hasKey(ShadingInfo.identifier)) {
_performShading = dictionary.value<bool>(ShadingInfo.identifier);
}
if (dictionary.hasKey(LightSourcesInfo.identifier)) {
const ghoul::Dictionary& lsDictionary =
dictionary.value<ghoul::Dictionary>(LightSourcesInfo.identifier);
for (const std::string& k : lsDictionary.keys()) {
std::unique_ptr<LightSource> lightSource = LightSource::createFromDictionary(
lsDictionary.value<ghoul::Dictionary>(k)
);
_lightSourcePropertyOwner.addPropertySubOwner(lightSource.get());
_lightSources.push_back(std::move(lightSource));
}
}
addPropertySubOwner(_lightSourcePropertyOwner);
addPropertySubOwner(_geometry.get());
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this));
addProperty(_ambientIntensity);
addProperty(_diffuseIntensity);
addProperty(_specularIntensity);
addProperty(_performShading);
}
RenderableModel::~RenderableModel() {}
bool RenderableModel::isReady() const {
return _programObject && _texture;
}
void RenderableModel::initialize() {
for (const std::unique_ptr<LightSource>& ls : _lightSources) {
ls->initialize();
}
}
void RenderableModel::initializeGL() {
_programObject = BaseModule::ProgramObjectManager.requestProgramObject(
ProgramName,
@@ -161,21 +257,7 @@ void RenderableModel::initializeGL() {
);
}
);
_uniformCache.opacity = _programObject->uniformLocation("opacity");
_uniformCache.directionToSunViewSpace = _programObject->uniformLocation(
"directionToSunViewSpace"
);
_uniformCache.modelViewTransform = _programObject->uniformLocation(
"modelViewTransform"
);
_uniformCache.projectionTransform = _programObject->uniformLocation(
"projectionTransform"
);
_uniformCache.performShading = _programObject->uniformLocation(
"performShading"
);
_uniformCache.texture = _programObject->uniformLocation("texture1");
updateUniformCache();
loadTexture();
@@ -213,15 +295,33 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() *
modelTransform;
const glm::vec3 directionToSun = glm::normalize(
_sunPos - data.modelTransform.translation
);
const glm::vec3 directionToSunViewSpace =
glm::normalize(glm::mat3(data.camera.combinedViewMatrix()) * directionToSun);
int nLightSources = 0;
_lightIntensitiesBuffer.resize(_lightSources.size());
_lightDirectionsViewSpaceBuffer.resize(_lightSources.size());
for (const std::unique_ptr<LightSource>& lightSource : _lightSources) {
if (!lightSource->isEnabled()) {
continue;
}
_lightIntensitiesBuffer[nLightSources] = lightSource->intensity();
_lightDirectionsViewSpaceBuffer[nLightSources] =
lightSource->directionViewSpace(data);
++nLightSources;
}
_programObject->setUniform(
_uniformCache.directionToSunViewSpace,
directionToSunViewSpace
_uniformCache.nLightSources,
nLightSources
);
_programObject->setUniform(
_uniformCache.lightIntensities,
_lightIntensitiesBuffer.data(),
nLightSources
);
_programObject->setUniform(
_uniformCache.lightDirectionsViewSpace,
_lightDirectionsViewSpaceBuffer.data(),
nLightSources
);
_programObject->setUniform(
_uniformCache.modelViewTransform,
@@ -231,6 +331,18 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
_uniformCache.projectionTransform,
data.camera.projectionMatrix()
);
_programObject->setUniform(
_uniformCache.ambientIntensity,
_ambientIntensity
);
_programObject->setUniform(
_uniformCache.diffuseIntensity,
_diffuseIntensity
);
_programObject->setUniform(
_uniformCache.specularIntensity,
_specularIntensity
);
_programObject->setUniform(
_uniformCache.performShading,
_performShading
@@ -252,26 +364,41 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
void RenderableModel::update(const UpdateData&) {
if (_programObject->isDirty()) {
_programObject->rebuildFromFile();
_uniformCache.opacity = _programObject->uniformLocation("opacity");
_uniformCache.directionToSunViewSpace = _programObject->uniformLocation(
"directionToSunViewSpace"
);
_uniformCache.modelViewTransform = _programObject->uniformLocation(
"modelViewTransform"
);
_uniformCache.projectionTransform = _programObject->uniformLocation(
"projectionTransform"
);
_uniformCache.performShading = _programObject->uniformLocation(
"performShading"
);
_uniformCache.texture = _programObject->uniformLocation("texture1");
updateUniformCache();
}
}
_sunPos = OsEng.renderEngine().scene()->sceneGraphNode(
"SolarSystemBarycenter"
)->worldPosition();
void RenderableModel::updateUniformCache() {
_uniformCache.opacity = _programObject->uniformLocation("opacity");
_uniformCache.nLightSources = _programObject->uniformLocation(
"nLightSources"
);
_uniformCache.lightDirectionsViewSpace = _programObject->uniformLocation(
"lightDirectionsViewSpace"
);
_uniformCache.lightIntensities = _programObject->uniformLocation(
"lightIntensities"
);
_uniformCache.modelViewTransform = _programObject->uniformLocation(
"modelViewTransform"
);
_uniformCache.projectionTransform = _programObject->uniformLocation(
"projectionTransform"
);
_uniformCache.performShading = _programObject->uniformLocation(
"performShading"
);
_uniformCache.ambientIntensity = _programObject->uniformLocation(
"ambientIntensity"
);
_uniformCache.diffuseIntensity = _programObject->uniformLocation(
"diffuseIntensity"
);
_uniformCache.specularIntensity = _programObject->uniformLocation(
"specularIntensity"
);
_uniformCache.texture = _programObject->uniformLocation("texture1");
}
void RenderableModel::loadTexture() {
+19 -3
View File
@@ -43,6 +43,7 @@ namespace openspace {
struct RenderData;
struct UpdateData;
class LightSource;
namespace documentation { struct Documentation; }
namespace modelgeometry { class ModelGeometry; }
@@ -50,7 +51,9 @@ namespace modelgeometry { class ModelGeometry; }
class RenderableModel : public Renderable {
public:
RenderableModel(const ghoul::Dictionary& dictionary);
~RenderableModel();
void initialize() override;
void initializeGL() override;
void deinitializeGL() override;
@@ -65,19 +68,32 @@ protected:
void loadTexture();
private:
void updateUniformCache();
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
properties::StringProperty _colorTexturePath;
properties::FloatProperty _ambientIntensity;
properties::FloatProperty _diffuseIntensity;
properties::FloatProperty _specularIntensity;
properties::BoolProperty _performShading;
properties::Mat3Property _modelTransform;
ghoul::opengl::ProgramObject* _programObject = nullptr;
UniformCache(opacity, directionToSunViewSpace, modelViewTransform,
projectionTransform, performShading, texture) _uniformCache;
UniformCache(opacity, nLightSources, lightDirectionsViewSpace, lightIntensities,
modelViewTransform, projectionTransform, performShading, texture,
ambientIntensity, diffuseIntensity, specularIntensity) _uniformCache;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::vector<std::unique_ptr<LightSource>> _lightSources;
glm::dvec3 _sunPos;
// Buffers for uniform uploading
std::vector<float> _lightIntensitiesBuffer;
std::vector<glm::vec3> _lightDirectionsViewSpaceBuffer;
properties::PropertyOwner _lightSourcePropertyOwner;
};
} // namespace openspace