Refactoring to enable multiple lights in forward rendering in progress
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40156
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other materials
|
||||
// provided with the distribution.
|
||||
//
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#import <assert.h>
|
||||
#include <stack.h>
|
||||
|
||||
#import "KRVector2.h"
|
||||
#import "KRCamera.h"
|
||||
@@ -107,8 +108,7 @@ KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
|
||||
volumetricLightAccumulationTexture = 0;
|
||||
|
||||
|
||||
memset(shadowFramebuffer, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
memset(shadowDepthTexture, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
|
||||
|
||||
m_iFrame = 0;
|
||||
|
||||
@@ -121,8 +121,6 @@ KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
|
||||
volumetric_environment_max_distance = 1000.0f;
|
||||
volumetric_environment_quality = (50 - 5.0) / 495.0f;
|
||||
volumetric_environment_intensity = 1.0f;
|
||||
|
||||
invalidateShadowBuffers();
|
||||
}
|
||||
|
||||
KRCamera::~KRCamera() {
|
||||
@@ -168,61 +166,6 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
|
||||
if(firstDirectionalLight) {
|
||||
lightDirection = firstDirectionalLight->getWorldLightDirection();
|
||||
}
|
||||
|
||||
allocateShadowBuffers(m_cShadowBuffers);
|
||||
for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
|
||||
GLfloat shadowMinDepths[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.05, 0.3}};
|
||||
GLfloat shadowMaxDepths[3][3] = {{0.0, 0.0, 1.0},{0.1, 0.0, 0.0},{0.1, 0.3, 1.0}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
KRVector3 shadowLook = -KRVector3::Normalize(lightDirection);
|
||||
|
||||
KRVector3 shadowUp(0.0, 1.0, 0.0);
|
||||
if(KRVector3::Dot(shadowUp, shadowLook) > 0.99f) shadowUp = KRVector3(0.0, 0.0, 1.0); // Ensure shadow look direction is not parallel with the shadowUp direction
|
||||
|
||||
KRMat4 matShadowView = KRMat4::LookAt(m_viewport.getCameraPosition() - shadowLook, m_viewport.getCameraPosition(), shadowUp);
|
||||
|
||||
|
||||
KRMat4 matShadowProjection = KRMat4();
|
||||
matShadowProjection.scale(0.001, 0.001, 0.001);
|
||||
|
||||
KRMat4 matBias;
|
||||
matBias.bias();
|
||||
matShadowProjection *= matBias;
|
||||
|
||||
|
||||
|
||||
|
||||
// KRAABB frustrumWorldBounds = KRAABB(KRVector3(-1.0, -1.0, 0.0), KRVector3(1.0, 1.0, 1.0), m_viewport.getInverseProjectionMatrix() * m_viewport.getInverseViewMatrix());
|
||||
// matShadowProjection.translate(KRVector3(0.0, 0.0, -frustrumWorldBounds.size().z));
|
||||
// matShadowProjection.scale(2.0 / frustrumWorldBounds.size().x, 2.0 / frustrumWorldBounds.size().y, 2.0 / frustrumWorldBounds.size().z);
|
||||
// matShadowView.translate(-m_viewport.getCameraPosition());
|
||||
|
||||
//matShadowProjection *= matBias;
|
||||
|
||||
m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection);
|
||||
|
||||
// KRMat4 newShadowMVP;
|
||||
// if(shadowMaxDepths[m_cShadowBuffers - 1][iShadow] == 0.0) {
|
||||
// KRBoundingVolume ext = KRBoundingVolume(-KRVector3::One(), KRVector3::One(), KRMat4()); // HACK - Temporary workaround to compile until this logic is updated to use information from the Octree
|
||||
//
|
||||
// newShadowMVP = ext.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
// } else {
|
||||
// KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
|
||||
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
// }
|
||||
|
||||
// KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
|
||||
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
//
|
||||
// m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), KRMat4(), newShadowMVP);
|
||||
//
|
||||
renderShadowBuffer(scene, iShadow);
|
||||
|
||||
}
|
||||
|
||||
renderFrame(scene, lightDirection, deltaTime);
|
||||
|
||||
@@ -241,6 +184,10 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
|
||||
std::set<KRAABB> newVisibleBounds;
|
||||
|
||||
// GLuint shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
// KRViewport shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
// int cShadows = 0;
|
||||
|
||||
if(bEnableDeferredLighting) {
|
||||
// ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====----
|
||||
|
||||
@@ -265,7 +212,11 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glDisable(GL_BLEND));
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_GBUFFER, newVisibleBounds);
|
||||
|
||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||
|
||||
// ----====---- Opaque Geometry, Deferred rendering Pass 2 ----====----
|
||||
// Set render target
|
||||
@@ -291,7 +242,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, 0, KRNode::RENDER_PASS_DEFERRED_LIGHTS, newVisibleBounds);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
||||
|
||||
// ----====---- Opaque Geometry, Deferred rendering Pass 3 ----====----
|
||||
// Set render target
|
||||
@@ -323,7 +274,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
|
||||
// Render the geometry
|
||||
std::set<KRAABB> emptyBoundsSet; // At this point, we only render octree nodes that produced fragments during the 1st pass into the GBuffer
|
||||
scene.render(this, emptyBoundsSet, m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
|
||||
scene.render(this, emptyBoundsSet, m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, newVisibleBounds);
|
||||
|
||||
// Deactivate source buffer texture units
|
||||
m_pContext->getTextureManager()->selectTexture(6, NULL, 0);
|
||||
@@ -333,6 +284,10 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE7));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
} else {
|
||||
// ----====---- Generate Shadowmaps for Lights ----====----
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_GENERATE_SHADOWMAPS, newVisibleBounds);
|
||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||
|
||||
// ----====---- Opaque Geometry, Forward Rendering ----====----
|
||||
|
||||
// Set render target
|
||||
@@ -361,7 +316,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
|
||||
|
||||
// Render the geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_OPAQUE, newVisibleBounds);
|
||||
}
|
||||
|
||||
// ----====---- Sky Box ----====----
|
||||
@@ -386,8 +341,8 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
}
|
||||
|
||||
if(m_pSkyBoxTexture) {
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader("sky_box", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||
pShader->bind(m_viewport, m_shadowViewports, KRMat4(), lightDirection, NULL, 0, KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader("sky_box", this, std::stack<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||
pShader->bind(m_viewport, KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_OPAQUE);
|
||||
|
||||
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 2048);
|
||||
|
||||
@@ -421,7 +376,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
// Render all transparent geometry
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, newVisibleBounds);
|
||||
|
||||
|
||||
// ----====---- Flares ----====----
|
||||
@@ -445,11 +400,12 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||
|
||||
// Render all flares
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_pContext, m_viewport, m_shadowViewports, lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds);
|
||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_ADDITIVE_PARTICLES, newVisibleBounds);
|
||||
|
||||
// ----====---- Volumetric Lighting ----====----
|
||||
|
||||
if(m_cShadowBuffers >= 1 && volumetric_environment_enable) {
|
||||
if(volumetric_environment_enable) {
|
||||
KRViewport volumetricLightingViewport = KRViewport(KRVector2(volumetricBufferWidth, volumetricBufferHeight), m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix());
|
||||
|
||||
if(volumetric_environment_downsample != 0) {
|
||||
// Set render target
|
||||
@@ -463,6 +419,8 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
|
||||
|
||||
glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y);
|
||||
} else {
|
||||
// Enable z-buffer test
|
||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||
@@ -470,28 +428,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||
}
|
||||
|
||||
std::string shader_name = volumetric_environment_downsample != 0 ? "volumetric_fog_downsampled" : "volumetric_fog";
|
||||
|
||||
KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
|
||||
|
||||
KRViewport volumetricLightingViewport = KRViewport(KRVector2(volumetricBufferWidth, volumetricBufferHeight), m_viewport.getViewMatrix(), m_viewport.getProjectionMatrix());
|
||||
glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y);
|
||||
if(pFogShader->bind(volumetricLightingViewport, m_shadowViewports, KRMat4(), lightDirection, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
|
||||
|
||||
|
||||
|
||||
int slice_count = (int)(volumetric_environment_quality * 495.0) + 5;
|
||||
|
||||
float slice_near = -getPerspectiveNearZ();
|
||||
float slice_far = -volumetric_environment_max_distance;
|
||||
float slice_spacing = (slice_far - slice_near) / slice_count;
|
||||
|
||||
KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]);
|
||||
(KRVector3::One() * volumetric_environment_intensity * -slice_spacing / 1000.0f).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);
|
||||
|
||||
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRModelManager::MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRModelManager::VolumetricLightingVertexData), true, false, false, false, false);
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
|
||||
}
|
||||
scene.render(this, m_viewport.getVisibleBounds(), volumetricLightingViewport, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE, newVisibleBounds);
|
||||
|
||||
if(volumetric_environment_downsample != 0) {
|
||||
// Set render target
|
||||
@@ -521,7 +458,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||
|
||||
|
||||
KRShader *pVisShader = m_pContext->getShaderManager()->getShader("visualize_overlay", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::stack<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
KRMat4 projectionMatrix = getProjectionMatrix();
|
||||
|
||||
@@ -530,7 +467,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
|
||||
KRMat4 matModel = KRMat4();
|
||||
matModel.scale((*itr).size() / 2.0f);
|
||||
matModel.translate((*itr).center());
|
||||
if(pVisShader->bind(m_viewport, m_shadowViewports, matModel, lightDirection, shadowDepthTexture, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||
if(pVisShader->bind(m_viewport, matModel, std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
||||
}
|
||||
}
|
||||
@@ -660,55 +597,10 @@ void KRCamera::createBuffers() {
|
||||
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, volumetricLightAccumulationTexture, 0));
|
||||
}
|
||||
}
|
||||
allocateShadowBuffers(m_cShadowBuffers);
|
||||
}
|
||||
|
||||
void KRCamera::allocateShadowBuffers(int cBuffers) {
|
||||
// First deallocate buffers no longer needed
|
||||
for(int iShadow = cBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) {
|
||||
if (shadowDepthTexture[iShadow]) {
|
||||
GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow));
|
||||
shadowDepthTexture[iShadow] = 0;
|
||||
}
|
||||
|
||||
if (shadowFramebuffer[iShadow]) {
|
||||
GLDEBUG(glDeleteFramebuffers(1, shadowFramebuffer + iShadow));
|
||||
shadowFramebuffer[iShadow] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate newly required buffers
|
||||
for(int iShadow = 0; iShadow < cBuffers; iShadow++) {
|
||||
if(!shadowDepthTexture[iShadow]) {
|
||||
shadowValid[iShadow] = false;
|
||||
|
||||
GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow));
|
||||
GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow));
|
||||
// ===== Create offscreen shadow framebuffer object =====
|
||||
|
||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
|
||||
|
||||
// ----- Create Depth Texture for shadowFramebuffer -----
|
||||
GLDEBUG( glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#if GL_EXT_shadow_samplers
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_EXT, GL_LEQUAL)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
#endif
|
||||
GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
|
||||
|
||||
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRCamera::destroyBuffers()
|
||||
{
|
||||
allocateShadowBuffers(0);
|
||||
|
||||
if (compositeDepthTexture) {
|
||||
GLDEBUG(glDeleteTextures(1, &compositeDepthTexture));
|
||||
compositeDepthTexture = 0;
|
||||
@@ -745,70 +637,6 @@ void KRCamera::destroyBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KRCamera::renderShadowBuffer(KRScene &scene, int iShadow)
|
||||
{
|
||||
|
||||
glViewport(0, 0, m_shadowViewports[iShadow].getSize().x, m_shadowViewports[iShadow].getSize().y);
|
||||
|
||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
|
||||
GLDEBUG(glClearDepthf(1.0f));
|
||||
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
|
||||
|
||||
glViewport(1, 1, m_shadowViewports[iShadow].getSize().x - 2, m_shadowViewports[iShadow].getSize().y - 2);
|
||||
|
||||
GLDEBUG(glDisable(GL_DITHER));
|
||||
|
||||
GLDEBUG(glCullFace(GL_BACK)); // Enable frontface culling, which eliminates some self-cast shadow artifacts
|
||||
GLDEBUG(glEnable(GL_CULL_FACE));
|
||||
|
||||
// Enable z-buffer test
|
||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||
GLDEBUG(glDepthFunc(GL_LESS));
|
||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||
|
||||
// Disable alpha blending as we are using alpha channel for packed depth info
|
||||
GLDEBUG(glDisable(GL_BLEND));
|
||||
|
||||
// Use shader program
|
||||
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
shadowShader->bind(m_shadowViewports[iShadow], m_shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_SHADOWMAP);
|
||||
|
||||
// // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
|
||||
// shadowmvpmatrix[iShadow].setUniform(shadowShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SHADOWMVP1]);
|
||||
|
||||
// // Calculate the bounding volume of the light map
|
||||
// KRMat4 matInvShadow = shadowmvpmatrix[iShadow];
|
||||
// matInvShadow.invert();
|
||||
//
|
||||
// KRVector3 vertices[8];
|
||||
// vertices[0] = KRVector3(-1.0, -1.0, 0.0);
|
||||
// vertices[1] = KRVector3(1.0, -1.0, 0.0);
|
||||
// vertices[2] = KRVector3(1.0, 1.0, 0.0);
|
||||
// vertices[3] = KRVector3(-1.0, 1.0, 0.0);
|
||||
// vertices[4] = KRVector3(-1.0, -1.0, 1.0);
|
||||
// vertices[5] = KRVector3(1.0, -1.0, 1.0);
|
||||
// vertices[6] = KRVector3(1.0, 1.0, 1.0);
|
||||
// vertices[7] = KRVector3(-1.0, 1.0, 1.0);
|
||||
//
|
||||
// for(int iVertex=0; iVertex < 8; iVertex++) {
|
||||
// vertices[iVertex] = KRMat4::Dot(matInvShadow, vertices[iVertex]);
|
||||
// }
|
||||
//
|
||||
// KRVector3 cameraPosition;
|
||||
// KRVector3 lightDirection;
|
||||
// KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
|
||||
|
||||
|
||||
KRVector3 temp = KRVector3();
|
||||
std::set<KRAABB> newVisibleBounds;
|
||||
scene.render(this, m_shadowViewports[iShadow].getVisibleBounds(), m_pContext, m_shadowViewports[iShadow], m_shadowViewports, temp, NULL, m_cShadowBuffers, KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
|
||||
|
||||
m_shadowViewports[iShadow].setVisibleBounds(newVisibleBounds);
|
||||
GLDEBUG(glViewport(0, 0, m_viewport.getSize().x, m_viewport.getSize().y));
|
||||
}
|
||||
|
||||
void KRCamera::renderPost()
|
||||
{
|
||||
// Disable alpha blending
|
||||
@@ -836,8 +664,8 @@ void KRCamera::renderPost()
|
||||
|
||||
|
||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||
KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
postShader->bind(m_viewport, m_shadowViewports, KRMat4(), KRVector3(), shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::stack<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
postShader->bind(m_viewport, KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
@@ -867,37 +695,37 @@ void KRCamera::renderPost()
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
|
||||
if(bShowShadowBuffer) {
|
||||
KRShader *blitShader = m_pContext->getShaderManager()->getShader("simple_blit", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
|
||||
KRMat4 viewMatrix = KRMat4();
|
||||
viewMatrix.scale(0.20, 0.20, 0.20);
|
||||
viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
|
||||
blitShader->bind(KRViewport(getViewportSize(), viewMatrix, KRMat4()), m_shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
#if GL_EXT_shadow_samplers
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_NONE)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
#endif
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
#if GL_EXT_shadow_samplers
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
#endif
|
||||
}
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
}
|
||||
// if(bShowShadowBuffer) {
|
||||
// KRShader *blitShader = m_pContext->getShaderManager()->getShader("simple_blit", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
//
|
||||
// for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
|
||||
// KRMat4 viewMatrix = KRMat4();
|
||||
// viewMatrix.scale(0.20, 0.20, 0.20);
|
||||
// viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
|
||||
// blitShader->bind(KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
// m_pContext->getTextureManager()->selectTexture(1, NULL, 0);
|
||||
// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
|
||||
// GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
//#if GL_EXT_shadow_samplers
|
||||
// GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_NONE)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
//#endif
|
||||
// GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
//#if GL_EXT_shadow_samplers
|
||||
// GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
//#endif
|
||||
// }
|
||||
//
|
||||
// m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
|
||||
// GLDEBUG(glActiveTexture(GL_TEXTURE0));
|
||||
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
// }
|
||||
|
||||
|
||||
|
||||
const char *szText = m_debug_text.c_str();
|
||||
if(*szText) {
|
||||
KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, std::stack<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"), 2048);
|
||||
|
||||
@@ -942,12 +770,6 @@ void KRCamera::renderPost()
|
||||
|
||||
}
|
||||
|
||||
void KRCamera::invalidateShadowBuffers() {
|
||||
for(int i=0; i < m_cShadowBuffers; i++) {
|
||||
shadowValid[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void KRCamera::setSkyBox(const std::string &skyBoxName) {
|
||||
m_pSkyBoxTexture = NULL;
|
||||
m_skyBoxName = skyBoxName;
|
||||
@@ -965,13 +787,11 @@ void KRCamera::setPerspectiveNear(float v)
|
||||
{
|
||||
if(perspective_nearz != v) {
|
||||
perspective_nearz = v;
|
||||
invalidateShadowBuffers();
|
||||
}
|
||||
}
|
||||
void KRCamera::setPerpsectiveFarZ(float v)
|
||||
{
|
||||
if(perspective_farz != v) {
|
||||
perspective_farz = v;
|
||||
invalidateShadowBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,6 @@
|
||||
#import "KRContext.h"
|
||||
#import "KRViewport.h"
|
||||
|
||||
#define KRENGINE_MAX_SHADOW_BUFFERS 3
|
||||
#define KRENGINE_SHADOW_MAP_WIDTH 4096
|
||||
#define KRENGINE_SHADOW_MAP_HEIGHT 4096
|
||||
|
||||
class KRInstance;
|
||||
class KRScene;
|
||||
class KRViewport;
|
||||
@@ -130,9 +126,6 @@ public:
|
||||
private:
|
||||
KRVector3 m_position;
|
||||
|
||||
void renderShadowBuffer(KRScene &scene, int iShadow);
|
||||
void invalidateShadowBuffers();
|
||||
void allocateShadowBuffers(int cBuffers);
|
||||
void createBuffers();
|
||||
|
||||
float perspective_nearz;
|
||||
@@ -145,12 +138,6 @@ private:
|
||||
|
||||
GLuint volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture;
|
||||
|
||||
|
||||
GLuint shadowFramebuffer[KRENGINE_MAX_SHADOW_BUFFERS], shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
|
||||
KRViewport m_shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
|
||||
void renderPost();
|
||||
|
||||
void destroyBuffers();
|
||||
|
||||
@@ -48,11 +48,68 @@ KRVector3 KRDirectionalLight::getLocalLightDirection() {
|
||||
return KRVector3(0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewport) {
|
||||
for(int iShadow=0; iShadow < 1; iShadow++) {
|
||||
GLfloat shadowMinDepths[3][3] = {{0.0, 0.0, 0.0},{0.0, 0.0, 0.0},{0.0, 0.05, 0.3}};
|
||||
GLfloat shadowMaxDepths[3][3] = {{0.0, 0.0, 1.0},{0.1, 0.0, 0.0},{0.1, 0.3, 1.0}};
|
||||
|
||||
KRVector3 shadowLook = -KRVector3::Normalize(getWorldLightDirection());
|
||||
|
||||
KRVector3 shadowUp(0.0, 1.0, 0.0);
|
||||
if(KRVector3::Dot(shadowUp, shadowLook) > 0.99f) shadowUp = KRVector3(0.0, 0.0, 1.0); // Ensure shadow look direction is not parallel with the shadowUp direction
|
||||
|
||||
KRMat4 matShadowView = KRMat4::LookAt(viewport.getCameraPosition() - shadowLook, viewport.getCameraPosition(), shadowUp);
|
||||
|
||||
|
||||
KRMat4 matShadowProjection = KRMat4();
|
||||
matShadowProjection.scale(0.001, 0.001, 0.001);
|
||||
|
||||
KRMat4 matBias;
|
||||
matBias.bias();
|
||||
matShadowProjection *= matBias;
|
||||
|
||||
|
||||
|
||||
|
||||
// KRAABB frustrumWorldBounds = KRAABB(KRVector3(-1.0, -1.0, 0.0), KRVector3(1.0, 1.0, 1.0), m_viewport.getInverseProjectionMatrix() * m_viewport.getInverseViewMatrix());
|
||||
// matShadowProjection.translate(KRVector3(0.0, 0.0, -frustrumWorldBounds.size().z));
|
||||
// matShadowProjection.scale(2.0 / frustrumWorldBounds.size().x, 2.0 / frustrumWorldBounds.size().y, 2.0 / frustrumWorldBounds.size().z);
|
||||
// matShadowView.translate(-m_viewport.getCameraPosition());
|
||||
|
||||
//matShadowProjection *= matBias;
|
||||
|
||||
m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection);
|
||||
|
||||
// KRMat4 newShadowMVP;
|
||||
// if(shadowMaxDepths[m_cShadowBuffers - 1][iShadow] == 0.0) {
|
||||
// KRBoundingVolume ext = KRBoundingVolume(-KRVector3::One(), KRVector3::One(), KRMat4()); // HACK - Temporary workaround to compile until this logic is updated to use information from the Octree
|
||||
//
|
||||
// newShadowMVP = ext.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
// } else {
|
||||
// KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
|
||||
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
// }
|
||||
|
||||
// KRBoundingVolume frustrumSliceVolume = KRBoundingVolume(viewMatrix, perspective_fov, getViewportSize().x / getViewportSize().y, perspective_nearz + (perspective_farz - perspective_nearz) * shadowMinDepths[m_cShadowBuffers - 1][iShadow], perspective_nearz + (perspective_farz - perspective_nearz) * shadowMaxDepths[m_cShadowBuffers - 1][iShadow]);
|
||||
// newShadowMVP = frustrumSliceVolume.calcShadowProj(&scene, m_pContext, scene.sun_yaw, scene.sun_pitch);
|
||||
//
|
||||
// m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), KRMat4(), newShadowMVP);
|
||||
//
|
||||
|
||||
|
||||
// renderShadowBuffer(scene, iShadow);
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
|
||||
void KRDirectionalLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||
|
||||
KRLight::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRLight::render(pCamera, lights, viewport, renderPass);
|
||||
|
||||
if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {
|
||||
// Lights are rendered on the second pass of the deferred renderer
|
||||
@@ -65,8 +122,8 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KR
|
||||
light_direction_view_space = KRMat4::Dot(matModelViewInverseTranspose, light_direction_view_space);
|
||||
light_direction_view_space.normalize();
|
||||
|
||||
KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, 0, renderPass)) {
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, getModelMatrix(), lights, renderPass)) {
|
||||
|
||||
light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]);
|
||||
m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);
|
||||
|
||||
@@ -25,9 +25,13 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
virtual int configureShadowBufferViewports(const KRViewport &viewport);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -75,12 +75,12 @@ void KRInstance::loadModel() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
|
||||
void KRInstance::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||
|
||||
|
||||
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRNode::render(pCamera, lights, viewport, renderPass);
|
||||
|
||||
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && (renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT || this->hasTransparency()) && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && (renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT || this->hasTransparency()) && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
|
||||
|
||||
loadModel();
|
||||
@@ -103,14 +103,14 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport
|
||||
}
|
||||
|
||||
if(m_pLightMap == NULL && m_lightMap.size()) {
|
||||
m_pLightMap = pContext->getTextureManager()->getTexture(m_lightMap.c_str());
|
||||
m_pLightMap = getContext().getTextureManager()->getTexture(m_lightMap.c_str());
|
||||
}
|
||||
|
||||
if(m_pLightMap && pCamera->bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP) {
|
||||
if(m_pLightMap && pCamera->bEnableLightMap && renderPass != RENDER_PASS_SHADOWMAP && renderPass != RENDER_PASS_GENERATE_SHADOWMAPS) {
|
||||
m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, 2048);
|
||||
}
|
||||
|
||||
pModel->render(pCamera, pContext, viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, m_receivesShadow ? cShadowBuffers : 0, m_pLightMap, renderPass);
|
||||
pModel->render(pCamera, lights, viewport, getModelMatrix(), m_pLightMap, renderPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
#endif
|
||||
|
||||
bool hasTransparency();
|
||||
|
||||
@@ -29,11 +29,17 @@ KRLight::KRLight(KRScene &scene, std::string name) : KRNode(scene, name)
|
||||
m_flareTexture = "";
|
||||
m_pFlareTexture = NULL;
|
||||
m_flareSize = 0.0;
|
||||
|
||||
// Initialize shadow buffers
|
||||
m_cShadowBuffers = 0;
|
||||
memset(shadowFramebuffer, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
memset(shadowDepthTexture, sizeof(GLuint) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
memset(shadowValid, sizeof(bool) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
}
|
||||
|
||||
KRLight::~KRLight()
|
||||
{
|
||||
|
||||
allocateShadowBuffers(0);
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement *KRLight::saveXML( tinyxml2::XMLNode *parent)
|
||||
@@ -118,14 +124,44 @@ float KRLight::getDecayStart() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
|
||||
void KRLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||
|
||||
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRNode::render(pCamera, lights, viewport, renderPass);
|
||||
|
||||
if(renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
|
||||
allocateShadowBuffers(configureShadowBufferViewports(viewport));
|
||||
renderShadowBuffers(pCamera);
|
||||
}
|
||||
|
||||
if(renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
std::string shader_name = pCamera->volumetric_environment_downsample != 0 ? "volumetric_fog_downsampled" : "volumetric_fog";
|
||||
|
||||
std::stack<KRLight *> this_light;
|
||||
this_light.push(this);
|
||||
|
||||
KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
|
||||
|
||||
|
||||
if(pFogShader->bind(viewport, KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) {
|
||||
int slice_count = (int)(pCamera->volumetric_environment_quality * 495.0) + 5;
|
||||
|
||||
float slice_near = -pCamera->getPerspectiveNearZ();
|
||||
float slice_far = -pCamera->volumetric_environment_max_distance;
|
||||
float slice_spacing = (slice_far - slice_near) / slice_count;
|
||||
|
||||
KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]);
|
||||
(KRVector3::One() * pCamera->volumetric_environment_intensity * -slice_spacing / 1000.0f).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);
|
||||
|
||||
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRModelManager::MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRModelManager::VolumetricLightingVertexData), true, false, false, false, false);
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
if(m_flareTexture.size() && m_flareSize > 0.0f) {
|
||||
if(!m_pFlareTexture && m_flareTexture.size()) {
|
||||
m_pFlareTexture = pContext->getTextureManager()->getTexture(m_flareTexture.c_str());
|
||||
m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture.c_str());
|
||||
}
|
||||
|
||||
if(m_pFlareTexture) {
|
||||
@@ -134,8 +170,8 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
|
||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||
|
||||
// Render light flare on transparency pass
|
||||
KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, 0, renderPass)) {
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, getModelMatrix(), lights, renderPass)) {
|
||||
GLDEBUG(glUniform1f(
|
||||
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
|
||||
m_flareSize
|
||||
@@ -150,4 +186,132 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KRLight::allocateShadowBuffers(int cBuffers) {
|
||||
// First deallocate buffers no longer needed
|
||||
for(int iShadow = cBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) {
|
||||
if (shadowDepthTexture[iShadow]) {
|
||||
GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow));
|
||||
shadowDepthTexture[iShadow] = 0;
|
||||
}
|
||||
|
||||
if (shadowFramebuffer[iShadow]) {
|
||||
GLDEBUG(glDeleteFramebuffers(1, shadowFramebuffer + iShadow));
|
||||
shadowFramebuffer[iShadow] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate newly required buffers
|
||||
for(int iShadow = 0; iShadow < cBuffers; iShadow++) {
|
||||
KRVector2 viewportSize = m_shadowViewports[iShadow].getSize();
|
||||
|
||||
if(!shadowDepthTexture[iShadow]) {
|
||||
shadowValid[iShadow] = false;
|
||||
|
||||
GLDEBUG(glGenFramebuffers(1, shadowFramebuffer + iShadow));
|
||||
GLDEBUG(glGenTextures(1, shadowDepthTexture + iShadow));
|
||||
// ===== Create offscreen shadow framebuffer object =====
|
||||
|
||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
|
||||
|
||||
// ----- Create Depth Texture for shadowFramebuffer -----
|
||||
GLDEBUG( glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#if GL_EXT_shadow_samplers
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_EXT, GL_COMPARE_REF_TO_TEXTURE_EXT)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_EXT, GL_LEQUAL)); // TODO - Detect GL_EXT_shadow_samplers and only activate if available
|
||||
#endif
|
||||
GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, viewportSize.x, viewportSize.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
|
||||
|
||||
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowDepthTexture[iShadow], 0));
|
||||
}
|
||||
}
|
||||
|
||||
m_cShadowBuffers = cBuffers;
|
||||
}
|
||||
|
||||
|
||||
void KRLight::deleteBuffers()
|
||||
{
|
||||
// Called when this light wasn't used in the last frame, so we can free the resources for use by other lights
|
||||
allocateShadowBuffers(0);
|
||||
}
|
||||
|
||||
void KRLight::invalidateShadowBuffers()
|
||||
{
|
||||
memset(shadowValid, sizeof(bool) * KRENGINE_MAX_SHADOW_BUFFERS, 0);
|
||||
}
|
||||
|
||||
int KRLight::configureShadowBufferViewports(const KRViewport &viewport)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KRLight::renderShadowBuffers(KRCamera *pCamera)
|
||||
{
|
||||
for(int iShadow=0; iShadow < m_cShadowBuffers; iShadow++) {
|
||||
glViewport(0, 0, m_shadowViewports[iShadow].getSize().x, m_shadowViewports[iShadow].getSize().y);
|
||||
|
||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer[iShadow]));
|
||||
GLDEBUG(glClearDepthf(1.0f));
|
||||
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
|
||||
|
||||
glViewport(1, 1, m_shadowViewports[iShadow].getSize().x - 2, m_shadowViewports[iShadow].getSize().y - 2);
|
||||
|
||||
GLDEBUG(glDisable(GL_DITHER));
|
||||
|
||||
GLDEBUG(glCullFace(GL_BACK)); // Enable frontface culling, which eliminates some self-cast shadow artifacts
|
||||
GLDEBUG(glEnable(GL_CULL_FACE));
|
||||
|
||||
// Enable z-buffer test
|
||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||
GLDEBUG(glDepthFunc(GL_LESS));
|
||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||
|
||||
// Disable alpha blending as we are using alpha channel for packed depth info
|
||||
GLDEBUG(glDisable(GL_BLEND));
|
||||
|
||||
// Use shader program
|
||||
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::stack<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
shadowShader->bind(m_shadowViewports[iShadow], KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
|
||||
|
||||
// // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram
|
||||
// shadowmvpmatrix[iShadow].setUniform(shadowShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SHADOWMVP1]);
|
||||
|
||||
// // Calculate the bounding volume of the light map
|
||||
// KRMat4 matInvShadow = shadowmvpmatrix[iShadow];
|
||||
// matInvShadow.invert();
|
||||
//
|
||||
// KRVector3 vertices[8];
|
||||
// vertices[0] = KRVector3(-1.0, -1.0, 0.0);
|
||||
// vertices[1] = KRVector3(1.0, -1.0, 0.0);
|
||||
// vertices[2] = KRVector3(1.0, 1.0, 0.0);
|
||||
// vertices[3] = KRVector3(-1.0, 1.0, 0.0);
|
||||
// vertices[4] = KRVector3(-1.0, -1.0, 1.0);
|
||||
// vertices[5] = KRVector3(1.0, -1.0, 1.0);
|
||||
// vertices[6] = KRVector3(1.0, 1.0, 1.0);
|
||||
// vertices[7] = KRVector3(-1.0, 1.0, 1.0);
|
||||
//
|
||||
// for(int iVertex=0; iVertex < 8; iVertex++) {
|
||||
// vertices[iVertex] = KRMat4::Dot(matInvShadow, vertices[iVertex]);
|
||||
// }
|
||||
//
|
||||
// KRVector3 cameraPosition;
|
||||
// KRVector3 lightDirection;
|
||||
// KRBoundingVolume shadowVolume = KRBoundingVolume(vertices);
|
||||
|
||||
|
||||
std::set<KRAABB> newVisibleBounds;
|
||||
|
||||
getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, newVisibleBounds);
|
||||
|
||||
m_shadowViewports[iShadow].setVisibleBounds(newVisibleBounds);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
|
||||
static const float KRLIGHT_MIN_INFLUENCE = 0.15f; // 0.05f
|
||||
|
||||
// KRENGINE_MAX_SHADOW_BUFFERS must be at least 6 to allow omni-directional lights to render cube maps
|
||||
|
||||
#define KRENGINE_MAX_SHADOW_BUFFERS 6
|
||||
#define KRENGINE_SHADOW_MAP_WIDTH 4096
|
||||
#define KRENGINE_SHADOW_MAP_HEIGHT 4096
|
||||
|
||||
class KRLight : public KRNode {
|
||||
public:
|
||||
|
||||
@@ -33,10 +39,11 @@ public:
|
||||
|
||||
void setFlareTexture(std::string flare_texture);
|
||||
void setFlareSize(float flare_size);
|
||||
void deleteBuffers();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +57,19 @@ protected:
|
||||
std::string m_flareTexture;
|
||||
KRTexture *m_pFlareTexture;
|
||||
float m_flareSize;
|
||||
|
||||
|
||||
// Shadow Maps
|
||||
int m_cShadowBuffers;
|
||||
GLuint shadowFramebuffer[KRENGINE_MAX_SHADOW_BUFFERS], shadowDepthTexture[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
bool shadowValid[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
KRViewport m_shadowViewports[KRENGINE_MAX_SHADOW_BUFFERS];
|
||||
|
||||
void allocateShadowBuffers(int cBuffers);
|
||||
void invalidateShadowBuffers();
|
||||
|
||||
virtual int configureShadowBufferViewports(const KRViewport &viewport);
|
||||
void renderShadowBuffers(KRCamera *pCamera);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -201,27 +201,27 @@ bool KRMaterial::isTransparent() {
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
|
||||
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
|
||||
bool bSameMaterial = *prevBoundMaterial == this;
|
||||
bool bLightMap = pLightMap && pCamera->bEnableLightMap;
|
||||
|
||||
if(!m_pAmbientMap && m_ambientMap.size()) {
|
||||
m_pAmbientMap = pContext->getTextureManager()->getTexture(m_ambientMap.c_str());
|
||||
m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap.c_str());
|
||||
}
|
||||
if(!m_pDiffuseMap && m_diffuseMap.size()) {
|
||||
m_pDiffuseMap = pContext->getTextureManager()->getTexture(m_diffuseMap.c_str());
|
||||
m_pDiffuseMap = getContext().getTextureManager()->getTexture(m_diffuseMap.c_str());
|
||||
}
|
||||
if(!m_pNormalMap && m_normalMap.size()) {
|
||||
m_pNormalMap = pContext->getTextureManager()->getTexture(m_normalMap.c_str());
|
||||
m_pNormalMap = getContext().getTextureManager()->getTexture(m_normalMap.c_str());
|
||||
}
|
||||
if(!m_pSpecularMap && m_specularMap.size()) {
|
||||
m_pSpecularMap = pContext->getTextureManager()->getTexture(m_specularMap.c_str());
|
||||
m_pSpecularMap = getContext().getTextureManager()->getTexture(m_specularMap.c_str());
|
||||
}
|
||||
if(!m_pReflectionMap && m_reflectionMap.size()) {
|
||||
m_pReflectionMap = pContext->getTextureManager()->getTexture(m_reflectionMap.c_str());
|
||||
m_pReflectionMap = getContext().getTextureManager()->getTexture(m_reflectionMap.c_str());
|
||||
}
|
||||
if(!m_pReflectionCube && m_reflectionCube.size()) {
|
||||
m_pReflectionCube = pContext->getTextureManager()->getTextureCube(m_reflectionCube.c_str());
|
||||
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
|
||||
}
|
||||
|
||||
if(!bSameMaterial) {
|
||||
@@ -238,11 +238,11 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, con
|
||||
bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE);
|
||||
|
||||
|
||||
KRShader *pShader = pContext->getShaderManager()->getShader("ObjectShader", pCamera, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, cShadowBuffers, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass);
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass);
|
||||
|
||||
bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0;
|
||||
if(!bSameShader) {
|
||||
if(!pShader->bind(viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass)) {
|
||||
if(!pShader->bind(viewport, matModel, lights, renderPass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
char *getName();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass);
|
||||
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -111,17 +111,17 @@ void KRModel::loadPack(KRDataBlock *data) {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
|
||||
void KRModel::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
|
||||
|
||||
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
|
||||
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
|
||||
if(m_materials.size() == 0) {
|
||||
vector<KRModel::Submesh *> submeshes = getSubmeshes();
|
||||
|
||||
for(std::vector<KRModel::Submesh *>::iterator itr = submeshes.begin(); itr != submeshes.end(); itr++) {
|
||||
const char *szMaterialName = (*itr)->szMaterialName;
|
||||
KRMaterial *pMaterial = pContext->getMaterialManager()->getMaterial(szMaterialName);
|
||||
KRMaterial *pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName);
|
||||
m_materials.push_back(pMaterial);
|
||||
if(pMaterial) {
|
||||
m_uniqueMaterials.insert(pMaterial);
|
||||
@@ -164,7 +164,7 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
|
||||
|
||||
if(pMaterial != NULL && pMaterial == (*mat_itr)) {
|
||||
if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||
if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass)) {
|
||||
if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, lights, viewport, matModel, pLightMap, renderPass)) {
|
||||
|
||||
switch(pMaterial->getAlphaMode()) {
|
||||
case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass);
|
||||
void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -168,7 +168,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRNode::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass) {
|
||||
void KRNode::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "KRVector3.h"
|
||||
#import "KRViewport.h"
|
||||
#import "tinyxml2.h"
|
||||
#import <stack.h>
|
||||
|
||||
class KRCamera;
|
||||
class KRShaderManager;
|
||||
@@ -34,6 +35,8 @@ public:
|
||||
RENDER_PASS_DEFERRED_OPAQUE,
|
||||
RENDER_PASS_FORWARD_TRANSPARENT,
|
||||
RENDER_PASS_ADDITIVE_PARTICLES,
|
||||
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
||||
RENDER_PASS_GENERATE_SHADOWMAPS,
|
||||
RENDER_PASS_SHADOWMAP
|
||||
};
|
||||
|
||||
@@ -68,7 +71,7 @@ public:
|
||||
KRScene &getScene();
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) = 0;
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -52,10 +52,10 @@ void KRParticleSystemBrownian::physicsUpdate(float deltaTime)
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRParticleSystemBrownian::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
|
||||
void KRParticleSystemBrownian::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
|
||||
|
||||
|
||||
KRNode::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRNode::render(pCamera, lights, viewport, renderPass);
|
||||
|
||||
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
|
||||
@@ -69,11 +69,11 @@ void KRParticleSystemBrownian::render(KRCamera *pCamera, KRContext *pContext, co
|
||||
KRTexture *pParticleTexture = m_pContext->getTextureManager()->getTexture("flare");
|
||||
m_pContext->getTextureManager()->selectTexture(0, pParticleTexture, 2048);
|
||||
|
||||
KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("particle", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES);
|
||||
KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("particle", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
|
||||
int particle_count = 10000;
|
||||
|
||||
if(pParticleShader->bind(viewport, pShadowViewports, getModelMatrix(), lightDirection, shadowDepthTextures, cShadowBuffers, KRNode::RENDER_PASS_ADDITIVE_PARTICLES)) {
|
||||
if(pParticleShader->bind(viewport, getModelMatrix(), lights, renderPass)) {
|
||||
GLDEBUG(glUniform1f(
|
||||
pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
|
||||
1.0f
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -43,9 +43,10 @@ KRAABB KRPointLight::getBounds() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
|
||||
void KRPointLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
|
||||
{
|
||||
|
||||
KRLight::render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRLight::render(pCamera, lights, viewport, renderPass);
|
||||
|
||||
bool bVisualize = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && pCamera->bShowDeferred;
|
||||
|
||||
@@ -68,8 +69,8 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewpo
|
||||
|
||||
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ());
|
||||
|
||||
KRShader *pShader = pContext->getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, pShadowViewports, sphereModelMatrix, lightDirection, shadowDepthTextures, 0, renderPass)) {
|
||||
KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||
if(pShader->bind(viewport, sphereModelMatrix, lights, renderPass)) {
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
|
||||
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -42,12 +42,9 @@
|
||||
#import "KRStockGeometry.h"
|
||||
|
||||
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
|
||||
m_pContext = &context;
|
||||
m_pFirstDirectionalLight = NULL;
|
||||
m_pRootNode = new KRNode(*this, "scene_root");
|
||||
|
||||
sun_yaw = 4.333; // TODO - Remove temporary testing code
|
||||
sun_pitch = 0.55;
|
||||
m_skyBoxName = "";
|
||||
}
|
||||
KRScene::~KRScene() {
|
||||
@@ -57,52 +54,29 @@ KRScene::~KRScene() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
|
||||
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
|
||||
|
||||
std::stack<KRLight *> lights;
|
||||
|
||||
updateOctree();
|
||||
pCamera->setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph
|
||||
|
||||
if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) {
|
||||
|
||||
if(cShadowBuffers > 0) {
|
||||
m_pContext->getTextureManager()->selectTexture(3, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE3));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[0]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
}
|
||||
|
||||
if(cShadowBuffers > 1) {
|
||||
m_pContext->getTextureManager()->selectTexture(4, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE4));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[1]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
}
|
||||
|
||||
if(cShadowBuffers > 2) {
|
||||
m_pContext->getTextureManager()->selectTexture(5, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE5));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[2]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
std::set<KRNode *> outerNodes = std::set<KRNode *>(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future.
|
||||
|
||||
// Get lights from outer nodes (directional lights, which have no bounds)
|
||||
for(std::set<KRNode *>::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) {
|
||||
KRNode *node = (*itr);
|
||||
KRLight *light = dynamic_cast<KRLight *>(node);
|
||||
if(light) {
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
|
||||
KRVector3 forward_render_light_direction = lightDirection;
|
||||
KRDirectionalLight *directional_light = getFirstDirectionalLight();
|
||||
if(directional_light) {
|
||||
forward_render_light_direction = directional_light->getWorldLightDirection();
|
||||
KRVector3 sun_color = directional_light->getColor() * (directional_light->getIntensity() / 100.0f);
|
||||
pCamera->dSunR = sun_color.x;
|
||||
pCamera->dSunG = sun_color.y;
|
||||
pCamera->dSunB = sun_color.z;
|
||||
|
||||
// Render outer nodes
|
||||
for(std::set<KRNode *>::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) {
|
||||
KRNode *node = (*itr);
|
||||
node->render(pCamera, lights, viewport, renderPass);
|
||||
}
|
||||
|
||||
std::vector<KROctreeNode *> remainingOctrees;
|
||||
@@ -118,10 +92,10 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, K
|
||||
newRemainingOctrees.clear();
|
||||
newRemainingOctreesTestResults.clear();
|
||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
|
||||
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
||||
}
|
||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
|
||||
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
|
||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, false);
|
||||
}
|
||||
remainingOctrees = newRemainingOctrees;
|
||||
remainingOctreesTestResults = newRemainingOctreesTestResults;
|
||||
@@ -130,16 +104,11 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, K
|
||||
newRemainingOctrees.clear();
|
||||
newRemainingOctreesTestResults.clear();
|
||||
for(std::vector<KROctreeNode *>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
|
||||
render(*octree_itr, visibleBounds, pCamera, pContext, viewport, pShadowViewports, forward_render_light_direction, shadowDepthTextures, cShadowBuffers, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
|
||||
}
|
||||
|
||||
std::set<KRNode *> outerNodes = std::set<KRNode *>(m_nodeTree.getOuterSceneNodes()); // HACK - Copying the std::set as it is potentially modified as KRNode's update their bounds during the iteration. This is very expensive and will be eliminated in the future.
|
||||
for(std::set<KRNode *>::iterator itr=outerNodes.begin(); itr != outerNodes.end(); itr++) {
|
||||
(*itr)->render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
render(*octree_itr, visibleBounds, pCamera, lights, viewport, renderPass, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::stack<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
|
||||
{
|
||||
if(pOctreeNode) {
|
||||
|
||||
@@ -215,16 +184,16 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
||||
if(bNeedOcclusionTest) {
|
||||
pOctreeNode->beginOcclusionQuery();
|
||||
|
||||
KRShader *pVisShader = m_pContext->getShaderManager()->getShader("occlusion_test", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
KRShader *pVisShader = getContext().getShaderManager()->getShader("occlusion_test", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||
|
||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
|
||||
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
|
||||
KRMat4 matModel = KRMat4();
|
||||
matModel.scale(octreeBounds.size() / 2.0f);
|
||||
matModel.translate(octreeBounds.center());
|
||||
KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
|
||||
|
||||
// Enable additive blending
|
||||
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
GLDEBUG(glEnable(GL_BLEND));
|
||||
}
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||
@@ -239,7 +208,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
||||
GLDEBUG(glDepthMask(GL_FALSE));
|
||||
}
|
||||
|
||||
if(pVisShader->bind(viewport, pShadowViewports, matModel, lightDirection, shadowDepthTextures, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||
if(pVisShader->bind(viewport, matModel, std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
|
||||
}
|
||||
|
||||
@@ -254,12 +223,12 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
||||
|
||||
pOctreeNode->endOcclusionQuery();
|
||||
|
||||
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
GLDEBUG(glDisable(GL_BLEND));
|
||||
} else if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT) {
|
||||
GLDEBUG(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
} else {
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); // RENDER_PASS_FORWARD_TRANSPARENT and RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE
|
||||
}
|
||||
|
||||
|
||||
@@ -274,15 +243,33 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
|
||||
|
||||
if(bVisible) {
|
||||
|
||||
// Add lights that influence this octree level and its children to the stack
|
||||
int light_count = 0;
|
||||
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
|
||||
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
|
||||
(*itr)->render(pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass);
|
||||
KRNode *node = (*itr);
|
||||
KRLight *light = dynamic_cast<KRLight *>(node);
|
||||
if(light) {
|
||||
lights.push(light);
|
||||
light_count++;
|
||||
}
|
||||
}
|
||||
|
||||
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
|
||||
// Render objects that are at this octree level
|
||||
for(std::set<KRNode *>::iterator itr=pOctreeNode->getSceneNodes().begin(); itr != pOctreeNode->getSceneNodes().end(); itr++) {
|
||||
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
|
||||
(*itr)->render(pCamera, lights, viewport, renderPass);
|
||||
}
|
||||
|
||||
// Render child octrees
|
||||
const int *childOctreeOrder = renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES || renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? viewport.getBackToFrontOrder() : viewport.getFrontToBackOrder();
|
||||
|
||||
for(int i=0; i<8; i++) {
|
||||
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, pContext, viewport, pShadowViewports, lightDirection, shadowDepthTextures, cShadowBuffers, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
||||
render(pOctreeNode->getChildren()[childOctreeOrder[i]], visibleBounds, pCamera, lights, viewport, renderPass, remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, newVisibleBounds, false, false);
|
||||
}
|
||||
|
||||
// Remove lights added at this octree level from the stack
|
||||
while(light_count--) {
|
||||
lights.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,14 +62,12 @@ public:
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
void render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
|
||||
void render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds);
|
||||
|
||||
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRViewport *pShadowViewports, KRVector3 &lightDirection, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::stack<KRLight *> lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, std::set<KRAABB> &newVisibleBounds, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
|
||||
|
||||
#endif
|
||||
|
||||
float sun_pitch, sun_yaw;
|
||||
|
||||
|
||||
void notify_sceneGraphCreate(KRNode *pNode);
|
||||
void notify_sceneGraphDelete(KRNode *pNode);
|
||||
@@ -78,7 +76,6 @@ public:
|
||||
void physicsUpdate(float deltaTime);
|
||||
|
||||
private:
|
||||
KRContext *m_pContext;
|
||||
KRDirectionalLight *findFirstDirectionalLight(KRNode &node);
|
||||
|
||||
KRNode *m_pRootNode;
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
#include "KRShader.h"
|
||||
#import "assert.h"
|
||||
|
||||
KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) {
|
||||
KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) : KRContextObject(context)
|
||||
{
|
||||
strcpy(m_szKey, szKey);
|
||||
m_iProgram = 0;
|
||||
GLuint vertexShader = 0, fragShader = 0;
|
||||
@@ -205,11 +206,48 @@ KRShader::~KRShader() {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
bool KRShader::bind(const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass) {
|
||||
bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass) {
|
||||
if(m_iProgram == 0) {
|
||||
return false;
|
||||
}
|
||||
GLDEBUG(glUseProgram(m_iProgram));
|
||||
|
||||
// FINDME - HACK - Temporary placeholder code
|
||||
KRViewport *pShadowViewports = NULL;
|
||||
KRVector3 lightDirection = KRVector3::Normalize(KRVector3(0.90, 0.70, 0.25));
|
||||
GLuint *shadowDepthTextures = NULL;
|
||||
int cShadowBuffers = 0;
|
||||
|
||||
GLDEBUG(glUseProgram(m_iProgram));
|
||||
|
||||
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) {
|
||||
m_pContext->getTextureManager()->selectTexture(3, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE3));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[0]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
}
|
||||
|
||||
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1) {
|
||||
m_pContext->getTextureManager()->selectTexture(4, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE4));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[1]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
}
|
||||
|
||||
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2) {
|
||||
m_pContext->getTextureManager()->selectTexture(5, NULL, 0);
|
||||
GLDEBUG(glActiveTexture(GL_TEXTURE5));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[2]));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
}
|
||||
|
||||
if(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1 || m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) {
|
||||
KRMat4 inverseModelMatrix = matModel;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#import <stdint.h>
|
||||
#import <vector>
|
||||
#import <string>
|
||||
#import <stack>
|
||||
|
||||
#import "KREngine-common.h"
|
||||
|
||||
@@ -47,16 +48,16 @@ using std::vector;
|
||||
#import "KRNode.h"
|
||||
#import "KRViewport.h"
|
||||
|
||||
class KRShader {
|
||||
class KRShader : public KRContextObject {
|
||||
public:
|
||||
KRShader(char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource);
|
||||
~KRShader();
|
||||
KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource);
|
||||
virtual ~KRShader();
|
||||
GLuint getProgram();
|
||||
char *getKey();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
bool bind(const KRViewport &viewport, const KRViewport *pShadowViewports, const KRMat4 &matModel, const KRVector3 &lightDirection, const GLuint *shadowDepthTextures, const int &cShadowBuffers, const KRNode::RenderPass &renderPass);
|
||||
bool bind(const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -45,8 +45,11 @@ KRShaderManager::~KRShaderManager() {
|
||||
}
|
||||
|
||||
|
||||
KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) {
|
||||
KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, const std::stack<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) {
|
||||
|
||||
int iShadowQuality = 0; // FINDME - HACK - Placeholder code, need to iterate through lights and dynamically build shader
|
||||
|
||||
|
||||
char szKey[256];
|
||||
sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", pCamera->bEnablePerPixel, bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset,pCamera->volumetric_environment_enable, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff);
|
||||
|
||||
@@ -130,7 +133,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
|
||||
stream << "\n";
|
||||
std::string options = stream.str();
|
||||
|
||||
pShader = new KRShader(szKey, options, m_vertShaderSource[shader_name], m_fragShaderSource[shader_name]);
|
||||
pShader = new KRShader(getContext(), szKey, options, m_vertShaderSource[shader_name], m_fragShaderSource[shader_name]);
|
||||
|
||||
m_shaders[szKey] = pShader;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
const std::string &getVertShaderSource(const std::string &name);
|
||||
|
||||
|
||||
KRShader *getShader(const std::string &shader_name, const KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
|
||||
KRShader *getShader(const std::string &shader_name, const KRCamera *pCamera, const std::stack<KRLight *> &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
|
||||
|
||||
long getShaderHandlesUsed();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "KRVector2.h"
|
||||
#include "KRMat4.h"
|
||||
#include "KRViewport.h"
|
||||
#include "KRLight.h"
|
||||
|
||||
|
||||
KRViewport::KRViewport()
|
||||
@@ -163,3 +164,4 @@ void KRViewport::setVisibleBounds(const std::set<KRAABB> visibleBounds)
|
||||
m_visibleBounds = visibleBounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "KRMat4.h"
|
||||
#include "KRAABB.h"
|
||||
|
||||
class KRLight;
|
||||
|
||||
class KRViewport {
|
||||
public:
|
||||
KRViewport();
|
||||
@@ -39,6 +41,9 @@ public:
|
||||
const std::set<KRAABB> &getVisibleBounds();
|
||||
void setVisibleBounds(const std::set<KRAABB> visibleBounds);
|
||||
|
||||
const std::set<KRLight *> &getVisibleLights();
|
||||
void setVisibleLights(const std::set<KRLight *> visibleLights);
|
||||
|
||||
private:
|
||||
KRVector2 m_size;
|
||||
KRMat4 m_matView;
|
||||
|
||||
Reference in New Issue
Block a user