mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-28 06:59:46 -06:00
Merged master into atmosphere's branch.
This commit is contained in:
@@ -23,10 +23,11 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/performance/performancemeasurement.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
@@ -35,23 +36,19 @@
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/performance/performancemeasurement.h>
|
||||
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "ABufferRenderer";
|
||||
const std::string BoundsFragmentShaderPath = "${SHADERS}/abuffer/boundsabuffer.frag";
|
||||
const std::string RenderFragmentShaderPath = "${SHADERS}/abuffer/renderabuffer.frag";
|
||||
const char* _loggerCat = "ABufferRenderer";
|
||||
const char* BoundsFragmentShaderPath = "${SHADERS}/abuffer/boundsabuffer.frag";
|
||||
const char* RenderFragmentShaderPath = "${SHADERS}/abuffer/renderabuffer.frag";
|
||||
const int MaxRaycasters = 32;
|
||||
const int MaxLayers = 32;
|
||||
const int MaxAverageLayers = 8;
|
||||
@@ -93,7 +90,14 @@ void ABufferRenderer::initialize() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast<void*>(0));
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(GLfloat) * 4,
|
||||
reinterpret_cast<void*>(0)
|
||||
);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glGenTextures(1, &_anchorPointerTexture);
|
||||
@@ -111,16 +115,26 @@ void ABufferRenderer::initialize() {
|
||||
GLint defaultFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
|
||||
|
||||
|
||||
|
||||
updateResolution();
|
||||
updateRendererData();
|
||||
updateRaycastData();
|
||||
updateResolveDictionary();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture, 0);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_mainColorTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_mainDepthTexture,
|
||||
0
|
||||
);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
@@ -129,18 +143,19 @@ void ABufferRenderer::initialize() {
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
|
||||
|
||||
|
||||
try {
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("resolveData", _resolveDictionary);
|
||||
dict.setValue("rendererData", _rendererData);
|
||||
|
||||
_resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve",
|
||||
_resolveProgram = ghoul::opengl::ProgramObject::Build(
|
||||
"ABuffer Resolve",
|
||||
"${SHADERS}/abuffer/resolveabuffer.vert",
|
||||
"${SHADERS}/abuffer/resolveabuffer.frag",
|
||||
dict);
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
dict
|
||||
);
|
||||
} catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC(e.component, e.message);
|
||||
}
|
||||
|
||||
OsEng.renderEngine().raycasterManager().addListener(*this);
|
||||
@@ -161,9 +176,7 @@ void ABufferRenderer::deinitialize() {
|
||||
OsEng.renderEngine().raycasterManager().removeListener(*this);
|
||||
}
|
||||
|
||||
void ABufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool attached) {
|
||||
(void) raycaster;
|
||||
(void) attached;
|
||||
void ABufferRenderer::raycastersChanged(VolumeRaycaster&, bool) {
|
||||
_dirtyRaycastData = true;
|
||||
}
|
||||
|
||||
@@ -206,8 +219,8 @@ void ABufferRenderer::update() {
|
||||
if (_resolveProgram->isDirty()) {
|
||||
try {
|
||||
_resolveProgram->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError& error) {
|
||||
LERROR(error.message);
|
||||
} catch (const ghoul::RuntimeError& error) {
|
||||
LERRORC(error.component, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,23 +228,19 @@ void ABufferRenderer::update() {
|
||||
if (program.second->isDirty()) {
|
||||
try {
|
||||
program.second->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
} catch (const ghoul::RuntimeError e) {
|
||||
LERRORC(e.component, e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) {
|
||||
PerfMeasure("ABufferRenderer::render");
|
||||
|
||||
|
||||
if (_scene == nullptr)
|
||||
return;
|
||||
if (_camera == nullptr)
|
||||
if (!_scene || !_camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
_mainColorTextureUnit = std::make_unique<ghoul::opengl::TextureUnit>();
|
||||
_mainColorTextureUnit->activate();
|
||||
@@ -292,22 +301,25 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Step 3: Resolve the buffer
|
||||
_resolveProgram->activate();
|
||||
|
||||
// TEMPORARY GAMMA CORRECTION.
|
||||
|
||||
float gamma = 1.0;
|
||||
glm::vec3 cameraPos = data.camera.position().vec3();
|
||||
float maxComponent = std::max(std::max(std::abs(cameraPos.x), std::abs(cameraPos.y)), std::abs(cameraPos.z));
|
||||
float logDistance = std::log(glm::length(cameraPos / maxComponent) * maxComponent) / std::log(10.f);
|
||||
float maxComponent = std::max(
|
||||
std::max(std::abs(cameraPos.x), std::abs(cameraPos.y)), std::abs(cameraPos.z)
|
||||
);
|
||||
float logDistance = std::log(glm::length(cameraPos / maxComponent) * maxComponent)
|
||||
/ std::log(10.f);
|
||||
|
||||
float minLogDist = 15;
|
||||
float maxLogDist = 20;
|
||||
const float minLogDist = 15;
|
||||
const float maxLogDist = 20;
|
||||
|
||||
float t = (logDistance - minLogDist) / (maxLogDist - minLogDist);
|
||||
t = glm::clamp(t, 0.0f, 1.0f);
|
||||
gamma = 1.f * (1.f - t) + 2.2f * t;
|
||||
const float gamma = 1.f * (1.f - t) + 2.2f * t;
|
||||
|
||||
_resolveProgram->setUniform("gamma", gamma);
|
||||
|
||||
@@ -390,14 +402,23 @@ void ABufferRenderer::clear() {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer);
|
||||
glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _resolution.x, _resolution.y, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_R32UI,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RED_INTEGER,
|
||||
GL_UNSIGNED_INT,
|
||||
nullptr
|
||||
);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
static const GLuint zero = 1;
|
||||
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer);
|
||||
glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero);
|
||||
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
void ABufferRenderer::updateResolution() {
|
||||
@@ -405,21 +426,43 @@ void ABufferRenderer::updateResolution() {
|
||||
|
||||
int totalPixels = _resolution.x * _resolution.y;
|
||||
glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _resolution.x, _resolution.y, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_R32UI,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RED_INTEGER,
|
||||
GL_UNSIGNED_INT,
|
||||
nullptr
|
||||
);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW);
|
||||
glBufferData(
|
||||
GL_PIXEL_UNPACK_BUFFER,
|
||||
totalPixels * sizeof(GLuint),
|
||||
nullptr,
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
GLuint* data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||
GLuint* data = reinterpret_cast<GLuint*>(
|
||||
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)
|
||||
);
|
||||
memset(data, 0x00, totalPixels * sizeof(GLuint));
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, MaxAverageLayers*totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY);
|
||||
glBufferData(
|
||||
GL_TEXTURE_BUFFER,
|
||||
MaxAverageLayers*totalPixels * sizeof(GLuint) * 4,
|
||||
nullptr,
|
||||
GL_DYNAMIC_COPY
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer);
|
||||
@@ -435,7 +478,8 @@ void ABufferRenderer::updateResolution() {
|
||||
GL_RGBA,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
true);
|
||||
true
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture);
|
||||
glTexImage2DMultisample(
|
||||
@@ -444,9 +488,9 @@ void ABufferRenderer::updateResolution() {
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
true);
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
_dirtyResolution = false;
|
||||
}
|
||||
|
||||
@@ -454,10 +498,9 @@ void ABufferRenderer::updateResolution() {
|
||||
|
||||
void ABufferRenderer::updateResolveDictionary() {
|
||||
ghoul::Dictionary dict;
|
||||
|
||||
ghoul::Dictionary raycastersDict;
|
||||
|
||||
for (const auto &raycastPair : _raycastData) {
|
||||
for (const auto& raycastPair : _raycastData) {
|
||||
ghoul::Dictionary innerDict;
|
||||
int id = raycastPair.second.id;
|
||||
std::string namespaceName = raycastPair.second.namespaceName;
|
||||
@@ -474,7 +517,7 @@ void ABufferRenderer::updateResolveDictionary() {
|
||||
dict.setValue("raycasters", raycastersDict);
|
||||
|
||||
ghoul::Dictionary helperPathsDict;
|
||||
for (int i = 0; i < _helperPaths.size(); i++) {
|
||||
for (int i = 0; i < _helperPaths.size(); ++i) {
|
||||
helperPathsDict.setValue(std::to_string(i), _helperPaths[i]);
|
||||
}
|
||||
|
||||
@@ -497,7 +540,8 @@ void ABufferRenderer::updateRaycastData() {
|
||||
_boundsPrograms.clear();
|
||||
_helperPaths.clear();
|
||||
|
||||
const std::vector<VolumeRaycaster*>& raycasters = OsEng.renderEngine().raycasterManager().raycasters();
|
||||
const std::vector<VolumeRaycaster*>& raycasters =
|
||||
OsEng.renderEngine().raycasterManager().raycasters();
|
||||
|
||||
std::map<std::string, int> namespaceIndices;
|
||||
int nextId = 0; // raycaster ids are positive integers starting at 0. (for raycasters, fragment type is id+1)
|
||||
@@ -506,7 +550,10 @@ void ABufferRenderer::updateRaycastData() {
|
||||
for (auto &raycaster : raycasters) {
|
||||
if (nextId > MaxRaycasters) {
|
||||
int nIgnored = MaxRaycasters - static_cast<int>(raycasters.size());
|
||||
LWARNING("ABufferRenderer does not support more than 32 raycasters. Ignoring " << nIgnored << " raycasters");
|
||||
LWARNING(
|
||||
"ABufferRenderer does not support more than 32 raycasters. " <<
|
||||
"Ignoring " << nIgnored << " raycasters"
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -546,19 +593,22 @@ void ABufferRenderer::updateRaycastData() {
|
||||
dict.setValue("fragmentPath", fsPath);
|
||||
dict.setValue("fragmentType", data.id + 1);
|
||||
try {
|
||||
_boundsPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " bounds", vsPath, BoundsFragmentShaderPath, dict);
|
||||
_boundsPrograms[raycaster] = ghoul::opengl::ProgramObject::Build(
|
||||
"Volume " + std::to_string(data.id) + " bounds",
|
||||
vsPath,
|
||||
BoundsFragmentShaderPath,
|
||||
dict
|
||||
);
|
||||
}
|
||||
catch (ghoul::RuntimeError& error) {
|
||||
LERROR(error.message);
|
||||
LERRORC(error.component, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
_dirtyRaycastData = false;
|
||||
_dirtyResolveDictionary = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ABufferRenderer::updateRendererData() {
|
||||
PerfMeasure("ABufferRenderer::updateRendererData");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user