mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 23:14:34 +02:00
Use deferred lighting for voxels as well as metavoxels.
This commit is contained in:
parent
c2b58c9781
commit
e6f37544fd
16 changed files with 114 additions and 206 deletions
|
@ -1,40 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// cascaded_shadow_map.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 5/29/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the shadow texture
|
|
||||||
uniform sampler2DShadow shadowMap;
|
|
||||||
|
|
||||||
// the distances to the cascade sections
|
|
||||||
uniform vec3 shadowDistances;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
|
||||||
|
|
||||||
// the color in shadow
|
|
||||||
varying vec4 shadowColor;
|
|
||||||
|
|
||||||
// the interpolated position
|
|
||||||
varying vec4 position;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
|
||||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
|
||||||
dot(gl_EyePlaneR[shadowIndex], position));
|
|
||||||
|
|
||||||
gl_FragColor = mix(shadowColor, gl_Color, 0.25 *
|
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r));
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// cascaded_shadow_map.vert
|
|
||||||
// vertex shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 5/29/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the color in shadow
|
|
||||||
varying vec4 shadowColor;
|
|
||||||
|
|
||||||
// the interpolated position
|
|
||||||
varying vec4 position;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// the shadow color includes only the ambient terms
|
|
||||||
shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
|
||||||
|
|
||||||
// the normal color includes diffuse
|
|
||||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
|
||||||
gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
|
||||||
|
|
||||||
// generate the shadow texture coordinates using the eye position
|
|
||||||
position = gl_ModelViewMatrix * gl_Vertex;
|
|
||||||
|
|
||||||
// use the fixed function transform
|
|
||||||
gl_Position = ftransform();
|
|
||||||
}
|
|
|
@ -26,6 +26,9 @@ const float amplitude = 0.5;
|
||||||
// the position in model space
|
// the position in model space
|
||||||
varying vec3 position;
|
varying vec3 position;
|
||||||
|
|
||||||
|
// the normal in view space
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
// gradient based on gradients from cube edge centers rather than random from texture lookup
|
// gradient based on gradients from cube edge centers rather than random from texture lookup
|
||||||
float randomEdgeGrad(int hash, vec3 position){
|
float randomEdgeGrad(int hash, vec3 position){
|
||||||
int h = int(mod(hash, 16));
|
int h = int(mod(hash, 16));
|
||||||
|
@ -114,7 +117,8 @@ void main(void) {
|
||||||
|
|
||||||
// apply vertex lighting
|
// apply vertex lighting
|
||||||
vec3 color = gl_Color.rgb * vec3(noise, noise, noise);
|
vec3 color = gl_Color.rgb * vec3(noise, noise, noise);
|
||||||
gl_FragColor = vec4(color, 1);
|
gl_FragData[0] = vec4(color, 1);
|
||||||
|
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,4 +160,4 @@ float perlin(vec3 location) {
|
||||||
mix(mix(ffcv, cfcv, params.x), mix(fccv, cccv, params.x), params.y),
|
mix(mix(ffcv, cfcv, params.x), mix(fccv, cccv, params.x), params.y),
|
||||||
params.z);
|
params.z);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,10 +14,12 @@
|
||||||
// the position in model space
|
// the position in model space
|
||||||
varying vec3 position;
|
varying vec3 position;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
position = gl_Vertex.xyz;
|
position = gl_Vertex.xyz;
|
||||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
normal = vec4(gl_NormalMatrix * gl_Normal, 0.0);
|
||||||
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
|
gl_FrontColor = gl_Color;
|
||||||
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
|
||||||
gl_Position = ftransform();
|
gl_Position = ftransform();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// shadow_map.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 11/21/13.
|
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
uniform sampler2DShadow shadowMap;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
|
||||||
|
|
||||||
// the color in shadow
|
|
||||||
varying vec4 shadowColor;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
gl_FragColor = mix(shadowColor, gl_Color, 0.25 *
|
|
||||||
(shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, shadowScale, 0.0)).r));
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// shadow_map.vert
|
|
||||||
// vertex shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 3/27/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the color in shadow
|
|
||||||
varying vec4 shadowColor;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// the shadow color includes only the ambient terms
|
|
||||||
shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
|
||||||
|
|
||||||
// the normal color includes diffuse
|
|
||||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
|
||||||
gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
|
||||||
|
|
||||||
// generate the shadow texture coordinates using the eye position
|
|
||||||
vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex;
|
|
||||||
gl_TexCoord[0] = vec4(dot(gl_EyePlaneS[0], eyePosition), dot(gl_EyePlaneT[0], eyePosition),
|
|
||||||
dot(gl_EyePlaneR[0], eyePosition), 1.0);
|
|
||||||
|
|
||||||
// use the fixed function transform
|
|
||||||
gl_Position = ftransform();
|
|
||||||
}
|
|
21
interface/resources/shaders/voxel.frag
Normal file
21
interface/resources/shaders/voxel.frag
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// voxel.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/11/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// store the color and normal directly
|
||||||
|
gl_FragData[0] = gl_Color;
|
||||||
|
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
|
}
|
26
interface/resources/shaders/voxel.vert
Normal file
26
interface/resources/shaders/voxel.vert
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// voxel.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/11/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// store the normal for interpolation
|
||||||
|
normal = vec4(gl_NormalMatrix * gl_Normal, 0.0);
|
||||||
|
|
||||||
|
// use the standard position
|
||||||
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
// store the color directly
|
||||||
|
gl_FrontColor = gl_Color;
|
||||||
|
}
|
|
@ -2842,8 +2842,10 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
_audioReflector.render();
|
_audioReflector.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw voxels
|
_deferredLightingEffect.prepare();
|
||||||
bool deferredLightingRequired = false;
|
bool deferredLightingRequired = false;
|
||||||
|
|
||||||
|
// Draw voxels
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||||
PerformanceTimer perfTimer("voxels");
|
PerformanceTimer perfTimer("voxels");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
|
|
|
@ -121,23 +121,13 @@ int RenderVisitor::visit(MetavoxelInfo& info) {
|
||||||
return STOP_RECURSION;
|
return STOP_RECURSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GLenum COLOR_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0 };
|
|
||||||
const GLenum NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT1 };
|
|
||||||
const GLenum COLOR_NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
|
||||||
|
|
||||||
void MetavoxelSystem::render() {
|
void MetavoxelSystem::render() {
|
||||||
// update the frustum
|
// update the frustum
|
||||||
ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum();
|
ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum();
|
||||||
_frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(),
|
_frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(),
|
||||||
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
|
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
|
||||||
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
|
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
|
||||||
|
|
||||||
// clear the normal buffer
|
|
||||||
glDrawBuffers(sizeof(NORMAL_DRAW_BUFFERS) / sizeof(NORMAL_DRAW_BUFFERS[0]), NORMAL_DRAW_BUFFERS);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
|
||||||
|
|
||||||
RenderVisitor renderVisitor(getLOD());
|
RenderVisitor renderVisitor(getLOD());
|
||||||
guideToAugmented(renderVisitor, true);
|
guideToAugmented(renderVisitor, true);
|
||||||
|
|
||||||
|
@ -834,7 +824,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
@ -907,7 +897,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||||
|
|
||||||
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
||||||
|
|
||||||
|
@ -936,7 +926,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
|
QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
|
||||||
|
|
||||||
void HeightfieldPreview::render(const glm::vec3& translation, float scale) const {
|
void HeightfieldPreview::render(const glm::vec3& translation, float scale) const {
|
||||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
@ -969,7 +959,7 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
|
VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
|
||||||
|
@ -1017,7 +1007,7 @@ void VoxelBuffer::render(bool cursor) {
|
||||||
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
if (!_materials.isEmpty()) {
|
if (!_materials.isEmpty()) {
|
||||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
@ -1087,7 +1077,7 @@ void VoxelBuffer::render(bool cursor) {
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||||
|
|
||||||
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materials);
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materials);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materialWeights);
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materialWeights);
|
||||||
|
@ -2132,7 +2122,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
|
|
||||||
_pointProgram.release();
|
_pointProgram.release();
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
@ -2175,7 +2165,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultMetavoxelRendererImplementation::loadSplatProgram(const char* type,
|
void DefaultMetavoxelRendererImplementation::loadSplatProgram(const char* type,
|
||||||
|
|
|
@ -26,6 +26,13 @@ void DeferredLightingEffect::init() {
|
||||||
_directionalLightCascadedShadowMapLocations);
|
_directionalLightCascadedShadowMapLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeferredLightingEffect::prepare() {
|
||||||
|
// clear the normal buffer
|
||||||
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::render() {
|
void DeferredLightingEffect::render() {
|
||||||
// perform deferred lighting, rendering to free fbo
|
// perform deferred lighting, rendering to free fbo
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -38,6 +45,7 @@ void DeferredLightingEffect::render() {
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
|
|
||||||
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
||||||
|
@ -133,6 +141,7 @@ void DeferredLightingEffect::render() {
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ class DeferredLightingEffect {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
void prepare();
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -242,6 +242,18 @@ GLuint TextureCache::getPrimaryNormalTextureID() {
|
||||||
return _primaryNormalTextureID;
|
return _primaryNormalTextureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureCache::setPrimaryDrawBuffers(bool color, bool normal) {
|
||||||
|
GLenum buffers[2];
|
||||||
|
int bufferCount = 0;
|
||||||
|
if (color) {
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||||
|
}
|
||||||
|
if (normal) {
|
||||||
|
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||||
|
}
|
||||||
|
glDrawBuffers(bufferCount, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
|
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
|
||||||
if (!_secondaryFramebufferObject) {
|
if (!_secondaryFramebufferObject) {
|
||||||
_secondaryFramebufferObject = createFramebufferObject();
|
_secondaryFramebufferObject = createFramebufferObject();
|
||||||
|
|
|
@ -64,6 +64,9 @@ public:
|
||||||
/// Returns the ID of the primary framebuffer object's normal texture.
|
/// Returns the ID of the primary framebuffer object's normal texture.
|
||||||
GLuint getPrimaryNormalTextureID();
|
GLuint getPrimaryNormalTextureID();
|
||||||
|
|
||||||
|
/// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound.
|
||||||
|
void setPrimaryDrawBuffers(bool color, bool normal);
|
||||||
|
|
||||||
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
|
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
|
||||||
/// screen effects.
|
/// screen effects.
|
||||||
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
|
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
|
||||||
|
|
|
@ -506,29 +506,13 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
_memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels);
|
_memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels);
|
||||||
|
|
||||||
// create our simple fragment shader if we're the first system to init
|
// create our simple fragment shader if we're the first system to init
|
||||||
if (!_shadowMapProgram.isLinked()) {
|
if (!_program.isLinked()) {
|
||||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
_program.addShaderFromSourceFile(QGLShader::Vertex,
|
||||||
Application::resourcesPath() + "shaders/shadow_map.vert");
|
Application::resourcesPath() + "shaders/voxel.vert");
|
||||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
_program.addShaderFromSourceFile(QGLShader::Fragment,
|
||||||
Application::resourcesPath() + "shaders/shadow_map.frag");
|
Application::resourcesPath() + "shaders/voxel.frag");
|
||||||
_shadowMapProgram.link();
|
_program.link();
|
||||||
|
|
||||||
_shadowMapProgram.bind();
|
|
||||||
_shadowMapProgram.setUniformValue("shadowMap", 0);
|
|
||||||
_shadowMapProgram.release();
|
|
||||||
|
|
||||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
|
||||||
Application::resourcesPath() + "shaders/cascaded_shadow_map.vert");
|
|
||||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
|
||||||
Application::resourcesPath() + "shaders/cascaded_shadow_map.frag");
|
|
||||||
_cascadedShadowMapProgram.link();
|
|
||||||
|
|
||||||
_cascadedShadowMapProgram.bind();
|
|
||||||
_cascadedShadowMapProgram.setUniformValue("shadowMap", 0);
|
|
||||||
_shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances");
|
|
||||||
_cascadedShadowMapProgram.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_renderer = new PrimitiveRenderer(_maxVoxels);
|
_renderer = new PrimitiveRenderer(_maxVoxels);
|
||||||
|
|
||||||
|
@ -1150,10 +1134,8 @@ glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float vo
|
||||||
return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale;
|
return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProgramObject VoxelSystem::_program;
|
||||||
ProgramObject VoxelSystem::_perlinModulateProgram;
|
ProgramObject VoxelSystem::_perlinModulateProgram;
|
||||||
ProgramObject VoxelSystem::_shadowMapProgram;
|
|
||||||
ProgramObject VoxelSystem::_cascadedShadowMapProgram;
|
|
||||||
int VoxelSystem::_shadowDistancesLocation;
|
|
||||||
|
|
||||||
void VoxelSystem::init() {
|
void VoxelSystem::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
|
@ -1478,41 +1460,31 @@ void VoxelSystem::render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::applyScaleAndBindProgram(bool texture) {
|
void VoxelSystem::applyScaleAndBindProgram(bool texture) {
|
||||||
|
if (texture) {
|
||||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
|
||||||
_cascadedShadowMapProgram.bind();
|
|
||||||
_cascadedShadowMapProgram.setUniform(_shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
|
||||||
} else {
|
|
||||||
_shadowMapProgram.bind();
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
|
||||||
|
|
||||||
} else if (texture) {
|
|
||||||
bindPerlinModulateProgram();
|
bindPerlinModulateProgram();
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
|
||||||
|
} else {
|
||||||
|
_program.bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glScalef(_treeScale, _treeScale, _treeScale);
|
glScalef(_treeScale, _treeScale, _treeScale);
|
||||||
|
|
||||||
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
||||||
// scale back down to 1 so heads aren't massive
|
// scale back down to 1 so heads aren't massive
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
if (texture) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
|
||||||
_cascadedShadowMapProgram.release();
|
|
||||||
} else {
|
|
||||||
_shadowMapProgram.release();
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
} else if (texture) {
|
|
||||||
_perlinModulateProgram.release();
|
_perlinModulateProgram.release();
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
} else {
|
||||||
|
_program.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelSystem::_nodeCount = 0;
|
int VoxelSystem::_nodeCount = 0;
|
||||||
|
|
|
@ -228,10 +228,8 @@ private:
|
||||||
|
|
||||||
bool _voxelsDirty;
|
bool _voxelsDirty;
|
||||||
|
|
||||||
|
static ProgramObject _program;
|
||||||
static ProgramObject _perlinModulateProgram;
|
static ProgramObject _perlinModulateProgram;
|
||||||
static ProgramObject _shadowMapProgram;
|
|
||||||
static ProgramObject _cascadedShadowMapProgram;
|
|
||||||
static int _shadowDistancesLocation;
|
|
||||||
|
|
||||||
static void bindPerlinModulateProgram();
|
static void bindPerlinModulateProgram();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue