WIP First attempt at a solution

This commit is contained in:
Malin E
2022-09-14 14:36:33 +02:00
parent 7946a93ee5
commit 77beb4c3af
7 changed files with 375 additions and 33 deletions

View File

@@ -28,6 +28,8 @@
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/rendering/helper.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/time.h>
#include <openspace/util/timeconversion.h>
@@ -39,11 +41,15 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/invariants.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/framebufferobject.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <filesystem>
#include <optional>
#include <iostream>
namespace {
constexpr std::string_view _loggerCat = "RenderableModel";
constexpr std::string_view ProgramName = "ModelProgram";
@@ -62,17 +68,30 @@ namespace {
{ "Color Adding", ColorAddingBlending }
};
constexpr glm::vec4 PosBufferClearVal = { 1e32, 1e32, 1e32, 1.f };
const GLenum ColorAttachmentArray[3] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2
};
constexpr openspace::properties::Property::PropertyInfo EnableAnimationInfo = {
"EnableAnimation",
"Enable Animation",
"Enable or disable the animation for the model if it has any"
};
constexpr std::array<const char*, 12> UniformNames = {
"opacity", "nLightSources", "lightDirectionsViewSpace", "lightIntensities",
constexpr std::array<const char*, 10> UniformNames = {
"nLightSources", "lightDirectionsViewSpace", "lightIntensities",
"modelViewTransform", "normalTransform", "projectionTransform",
"performShading", "ambientIntensity", "diffuseIntensity",
"specularIntensity", "opacityBlending"
"specularIntensity"
};
constexpr std::array<const char*, 6> UniformOpacityNames = {
"opacity", "opacityBlending", "colorTexture", "depthTexture", "positionTexture",
"normalTexture"
};
constexpr openspace::properties::Property::PropertyInfo AmbientIntensityInfo = {
@@ -486,7 +505,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
}
bool RenderableModel::isReady() const {
return _program;
return _program && _screenShader;
}
void RenderableModel::initialize() {
@@ -539,14 +558,198 @@ void RenderableModel::initializeGL() {
ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames);
_screenShader = BaseModule::ProgramObjectManager.request(
"ModelOpacityProgram",
[&]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
std::filesystem::path vs =
absPath("${MODULE_BASE}/shaders/modelOpacity_vs.glsl");
std::filesystem::path fs =
absPath("${MODULE_BASE}/shaders/modelOpacity_fs.glsl");
return global::renderEngine->buildRenderProgram("ModelOpacityProgram", vs, fs);
}
);
ghoul::opengl::updateUniformLocations(
*_screenShader,
_uniformOpacityCache,
UniformOpacityNames
);
// Screen quad VAO
const GLfloat quadVertices[] = {
// x y
-1.f, -1.f,
1.f, 1.f,
-1.f, 1.f,
-1.f, -1.f,
1.f, -1.f,
1.f, 1.f,
};
glGenVertexArrays(1, &_quadVao);
glBindVertexArray(_quadVao);
glGenBuffers(1, &_quadVbo);
glBindBuffer(GL_ARRAY_BUFFER, _quadVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(0);
createFramebuffers();
_geometry->initialize();
_geometry->calculateBoundingRadius();
}
void RenderableModel::createFramebuffers() {
glm::vec2 resolution = global::windowDelegate->currentDrawBufferResolution();
// Generate textures and the frame buffer
glGenTextures(1, &_colorTexture);
glGenTextures(1, &_positionTexture);
glGenTextures(1, &_normalTexture);
glGenTextures(1, &_depthTexture);
glGenFramebuffers(1, &_framebuffer);
// Create the textures
// Color
glBindTexture(GL_TEXTURE_2D, _colorTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA32F,
static_cast<GLsizei>(resolution.x),
static_cast<GLsizei>(resolution.y),
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (glbinding::Binding::ObjectLabel.isResolved()) {
glObjectLabel(GL_TEXTURE, _colorTexture, -1, "RenderableModel Color");
}
// Position
glBindTexture(GL_TEXTURE_2D, _positionTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA32F,
static_cast<GLsizei>(resolution.x),
static_cast<GLsizei>(resolution.y),
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (glbinding::Binding::ObjectLabel.isResolved()) {
glObjectLabel(GL_TEXTURE, _positionTexture, -1, "RenderableModel Position");
}
// Normal
glBindTexture(GL_TEXTURE_2D, _normalTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA32F,
static_cast<GLsizei>(resolution.x),
static_cast<GLsizei>(resolution.y),
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (glbinding::Binding::ObjectLabel.isResolved()) {
glObjectLabel(GL_TEXTURE, _normalTexture, -1, "RenderableModel Normal");
}
// Depth
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_DEPTH_COMPONENT32F,
static_cast<GLsizei>(resolution.x),
static_cast<GLsizei>(resolution.y),
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
nullptr
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (glbinding::Binding::ObjectLabel.isResolved()) {
glObjectLabel(GL_TEXTURE, _depthTexture, -1, "RenderableModel Depth");
}
// Create buffers
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glFramebufferTexture(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
_colorTexture,
0
);
glFramebufferTexture(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
_positionTexture,
0
);
glFramebufferTexture(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT2,
_normalTexture,
0
);
glFramebufferTexture(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
_depthTexture,
0
);
if (glbinding::Binding::ObjectLabel.isResolved()) {
glObjectLabel(GL_FRAMEBUFFER, _framebuffer, -1, "RenderableModel Opacity");
}
// Check status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Framebuffer is not complete!");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void RenderableModel::deinitializeGL() {
_geometry->deinitialize();
_geometry.reset();
glDeleteFramebuffers(1, &_framebuffer);
glDeleteTextures(1, &_colorTexture);
glDeleteTextures(1, &_depthTexture);
glDeleteTextures(1, &_positionTexture);
glDeleteTextures(1, &_normalTexture);
glDeleteBuffers(1, &_quadVbo);
glDeleteVertexArrays(1, &_quadVao);
std::string program = std::string(ProgramName);
if (!_vertexShaderPath.empty()) {
program += "|vs=" + _vertexShaderPath;
@@ -561,6 +764,8 @@ void RenderableModel::deinitializeGL() {
}
);
_program = nullptr;
_screenShader = nullptr;
ghoul::opengl::FramebufferObject::deactivate();
}
void RenderableModel::render(const RenderData& data, RendererTasks&) {
@@ -579,7 +784,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
if (distanceToCamera < maxDistance) {
_program->activate();
_program->setUniform(_uniformCache.opacity, opacity());
// Model transform and view transform needs to be in double precision
const glm::dmat4 modelTransform =
@@ -636,7 +841,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
_program->setUniform(_uniformCache.diffuseIntensity, _diffuseIntensity);
_program->setUniform(_uniformCache.specularIntensity, _specularIntensity);
_program->setUniform(_uniformCache.performShading, _performShading);
_program->setUniform(_uniformCache.opacityBlending, _enableOpacityBlending);
if (_disableFaceCulling) {
glDisable(GL_CULL_FACE);
@@ -665,18 +870,63 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
glDisable(GL_DEPTH_TEST);
}
// Frame buffer stuff
GLint defaultFBO = ghoul::opengl::FramebufferObject::getActiveObject();
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glDrawBuffers(3, ColorAttachmentArray);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearBufferfv(GL_COLOR, 1, glm::value_ptr(PosBufferClearVal));
// Render Pass 1
_geometry->render(*_program);
if (_disableFaceCulling) {
glEnable(GL_CULL_FACE);
}
global::renderEngine->openglStateCache().resetBlendState();
_program->deactivate();
if (_disableDepthTest) {
glEnable(GL_DEPTH_TEST);
}
_program->deactivate();
// Render pass 2
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
_screenShader->activate();
_program->setUniform(_uniformOpacityCache.opacity, opacity());
_program->setUniform(_uniformOpacityCache.opacityBlending, _enableOpacityBlending);
// Bind textures
ghoul::opengl::TextureUnit colorTextureUnit;
colorTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _colorTexture);
_program->setUniform(_uniformOpacityCache.modelColorTexture, colorTextureUnit);
/*
ghoul::opengl::TextureUnit positionTextureUnit;
positionTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _positionTexture);
_program->setUniform(_uniformOpacityCache.moedlPositionTexture, positionTextureUnit);
ghoul::opengl::TextureUnit normalTextureUnit;
normalTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _normalTexture);
_program->setUniform(_uniformOpacityCache.modelNormalTexture, normalTextureUnit);
ghoul::opengl::TextureUnit depthTextureUnit;
depthTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _depthTexture);
_program->setUniform(_uniformOpacityCache.modelDepthTexture, depthTextureUnit);
// Draw
glBindVertexArray(_quadVao);
glDrawArrays(GL_TRIANGLES, 0, 6);
_screenShader->deactivate();
*/
// End
global::renderEngine->openglStateCache().resetBlendState();
glEnable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
}
}

View File

@@ -40,6 +40,7 @@
#include <memory>
namespace ghoul::opengl {
class FramebufferObject;
class ProgramObject;
class Texture;
} // namespace ghoul::opengl
@@ -104,10 +105,10 @@ private:
std::string _vertexShaderPath;
std::string _fragmentShaderPath;
ghoul::opengl::ProgramObject* _program = nullptr;
UniformCache(opacity, nLightSources, lightDirectionsViewSpace, lightIntensities,
UniformCache(nLightSources, lightDirectionsViewSpace, lightIntensities,
modelViewTransform, normalTransform, projectionTransform,
performShading, ambientIntensity, diffuseIntensity,
specularIntensity, opacityBlending) _uniformCache;
specularIntensity) _uniformCache;
std::vector<std::unique_ptr<LightSource>> _lightSources;
@@ -116,6 +117,20 @@ private:
std::vector<glm::vec3> _lightDirectionsViewSpaceBuffer;
properties::PropertyOwner _lightSourcePropertyOwner;
// Frame buffer stuff
GLuint _framebuffer;
GLuint _colorTexture;
GLuint _depthTexture;
GLuint _positionTexture;
GLuint _normalTexture;
GLuint _quadVao;
GLuint _quadVbo;
void createFramebuffers();
ghoul::opengl::ProgramObject* _screenShader = nullptr;
UniformCache(opacity, opacityBlending, modelColorTexture, modelDepthTexture,
modelPositionTexture, modelNormalTexture) _uniformOpacityCache;
};
} // namespace openspace

View File

@@ -108,7 +108,7 @@ void ScreenSpaceFramebuffer::render() {
const glm::vec4& size = _size.value();
const float xratio = resolution.x / (size.z - size.x);
const float yratio = resolution.y / (size.w - size.y);;
const float yratio = resolution.y / (size.w - size.y);
if (!_renderFunctions.empty()) {
GLint viewport[4];

View File

@@ -0,0 +1,59 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include "fragment.glsl"
#include "floatoperations.glsl"
in vec2 vs_st;
uniform float opacity = 1.0;
uniform bool opacityBlending = false;
uniform sampler2D colorTexture;
uniform sampler2D depthTexture;
uniform sampler2D positionTexture;
uniform sampler2D normalTexture;
Fragment getFragment() {
Fragment frag;
if (opacity == 0.0) {
discard;
}
if (opacityBlending) {
// frag.color.a = opacity * (frag.color.r + frag.color.g + frag.color.b)/3.0;
frag.color.a = opacity * max(max(frag.color.r, frag.color.g), frag.color.b);
}
else {
frag.color.a = opacity;
}
frag.color.rgb = texture(colorTexture, vs_st).rgb;
frag.depth = denormalizeFloat(texture(depthTexture, vs_st).x);
frag.gPosition = texture(positionTexture, vs_st);
frag.gNormal = vec4(texture(normalTexture, vs_st).rgb, 0.0);
return frag;
}

View File

@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
void main() {
vs_st = in_st;
gl_Position = vec4(in_position.x, in_position.y, 0.0, 1.0);
}

View File

@@ -39,7 +39,6 @@ uniform bool has_texture_diffuse;
uniform bool has_texture_normal;
uniform bool has_texture_specular;
uniform bool has_color_specular;
uniform bool opacityBlending = false;
uniform sampler2D texture_diffuse;
uniform sampler2D texture_normal;
uniform sampler2D texture_specular;
@@ -48,7 +47,6 @@ uniform vec3 color_specular;
uniform int nLightSources;
uniform vec3 lightDirectionsViewSpace[8];
uniform float lightIntensities[8];
uniform float opacity = 1.0;
Fragment getFragment() {
@@ -63,7 +61,7 @@ Fragment getFragment() {
// Pink and complementary green in a chessboard pattern
frag.color.rgb = mix(vec3(1.0, 0.0, 0.8), vec3(0.0, 1.0, 0.2), chessboard);
frag.color.a = opacity;
frag.color.a = 1.0;
frag.depth = vs_screenSpaceDepth;
frag.gPosition = vs_positionCameraSpace;
frag.gNormal = vec4(vs_normalViewSpace, 0.0);
@@ -80,10 +78,6 @@ Fragment getFragment() {
diffuseAlbedo = color_diffuse;
}
if (opacity == 0.0) {
discard;
}
Fragment frag;
if (performShading) {
@@ -103,7 +97,7 @@ Fragment getFragment() {
// Some of these values could be passed in as uniforms
const vec3 lightColorAmbient = vec3(1.0);
const vec3 lightColor = vec3(1.0);
vec3 n;
if (has_texture_normal) {
vec3 normalAlbedo = texture(texture_normal, vs_st).rgb;
@@ -141,18 +135,7 @@ Fragment getFragment() {
frag.color.rgb = diffuseAlbedo;
}
if (opacityBlending) {
// frag.color.a = opacity * (frag.color.r + frag.color.g + frag.color.b)/3.0;
frag.color.a = opacity * max(max(frag.color.r, frag.color.g), frag.color.b);
}
else {
frag.color.a = opacity;
}
if (frag.color.a < 0.1) {
discard;
}
frag.color.a = 1.0;
frag.depth = vs_screenSpaceDepth;
frag.gPosition = vs_positionCameraSpace;
frag.gNormal = vec4(vs_normalViewSpace, 0.0);

View File

@@ -52,7 +52,7 @@ void main() {
gl_Position = positionScreenSpace;
vs_st = in_st;
vs_screenSpaceDepth = positionScreenSpace.w;
vs_normalViewSpace = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal));
// TBN matrix for normal mapping