Continued refactoring for multiple light support in forward rendering

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40158
This commit is contained in:
kearwood
2012-11-16 02:58:23 +00:00
parent 3b352511dc
commit c30c9725e9
25 changed files with 256 additions and 175 deletions

View File

@@ -150,6 +150,12 @@ void KRCamera::setPosition(const KRVector3 &position) {
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
{
if(m_iFrame == 0) {
if(scene.getFirstLight() == NULL) {
scene.addDefaultLights();
}
}
GLint defaultFBO;
GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO));
@@ -160,13 +166,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
m_pContext->rotateBuffers(true);
KRDirectionalLight *firstDirectionalLight = scene.getFirstDirectionalLight();
KRVector3 lightDirection = KRVector3::Normalize(KRVector3(0.90, 0.70, 0.25));
if(firstDirectionalLight) {
lightDirection = firstDirectionalLight->getWorldLightDirection();
}
renderFrame(scene, lightDirection, deltaTime);
renderFrame(scene, deltaTime);
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO));
renderPost();
@@ -177,7 +177,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, float deltaTime)
void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float deltaTime) {
void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
@@ -340,7 +340,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
}
if(m_pSkyBoxTexture) {
getContext().getShaderManager()->selectShader("sky_box", this, std::stack<KRLight *>(), m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
getContext().getShaderManager()->selectShader("sky_box", this, std::vector<KRLight *>(), m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE);
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture, 2048);
@@ -456,7 +456,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
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);
KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector<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();
@@ -466,7 +466,7 @@ void KRCamera::renderFrame(KRScene &scene, KRVector3 &lightDirection, float delt
matModel.scale((*itr).size() / 2.0f);
matModel.translate((*itr).center());
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
if(getContext().getShaderManager()->selectShader(pVisShader, m_viewport, matModel, std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14));
}
}
@@ -662,8 +662,8 @@ void KRCamera::renderPost()
GLDEBUG(glDisable(GL_DEPTH_TEST));
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);
getContext().getShaderManager()->selectShader(postShader, m_viewport, KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
getContext().getShaderManager()->selectShader(postShader, m_viewport, KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
m_pContext->getTextureManager()->selectTexture(0, NULL, 0);
GLDEBUG(glActiveTexture(GL_TEXTURE0));
@@ -723,7 +723,7 @@ void KRCamera::renderPost()
const char *szText = m_debug_text.c_str();
if(*szText) {
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);
KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, std::vector<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);

View File

@@ -142,7 +142,7 @@ private:
void destroyBuffers();
void renderFrame(KRScene &scene, KRVector3 &lightDirection, float deltaTime);
void renderFrame(KRScene &scene, float deltaTime);

View File

@@ -50,7 +50,8 @@ KRVector3 KRDirectionalLight::getLocalLightDirection() {
int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewport) {
for(int iShadow=0; iShadow < 1; iShadow++) {
int cShadows = 1;
for(int iShadow=0; iShadow < cShadows; 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}};
@@ -69,37 +70,7 @@ int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewpor
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);
m_shadowViewports[iShadow] = KRViewport(KRVector2(KRENGINE_SHADOW_MAP_WIDTH, KRENGINE_SHADOW_MAP_HEIGHT), matShadowView, matShadowProjection);
}
return 1;
@@ -107,12 +78,15 @@ int KRDirectionalLight::configureShadowBufferViewports(const KRViewport &viewpor
#if TARGET_OS_IPHONE
void KRDirectionalLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass 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
std::vector<KRLight *> this_light;
this_light.push_back(this);
KRMat4 matModelViewInverseTranspose = viewport.getViewMatrix() * getModelMatrix();
matModelViewInverseTranspose.transpose();
@@ -122,8 +96,8 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights
light_direction_view_space = KRMat4::Dot(matModelViewInverseTranspose, light_direction_view_space);
light_direction_view_space.normalize();
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(getContext().getShaderManager()->selectShader(pShader, viewport, getModelMatrix(), lights, renderPass)) {
KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pShader, viewport, getModelMatrix(), this_light, 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]);

View File

@@ -25,7 +25,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
#endif
protected:

View File

@@ -75,7 +75,7 @@ void KRInstance::loadModel() {
#if TARGET_OS_IPHONE
void KRInstance::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
void KRInstance::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, lights, viewport, renderPass);

View File

@@ -58,7 +58,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
#endif
bool hasTransparency();

View File

@@ -29,12 +29,16 @@ KRLight::KRLight(KRScene &scene, std::string name) : KRNode(scene, name)
m_flareTexture = "";
m_pFlareTexture = NULL;
m_flareSize = 0.0;
m_casts_shadow = true;
m_light_shafts = true;
// 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);
for(int iBuffer=0; iBuffer < KRENGINE_MAX_SHADOW_BUFFERS; iBuffer++) {
shadowFramebuffer[iBuffer] = 0;
shadowDepthTexture[iBuffer] = 0;
shadowValid[iBuffer] = false;
}
}
KRLight::~KRLight()
@@ -52,6 +56,8 @@ tinyxml2::XMLElement *KRLight::saveXML( tinyxml2::XMLNode *parent)
e->SetAttribute("decay_start", m_decayStart);
e->SetAttribute("flare_size", m_flareSize);
e->SetAttribute("flare_texture", m_flareTexture.c_str());
e->SetAttribute("casts_shadow", m_casts_shadow ? "true" : "false");
e->SetAttribute("light_shafts", m_light_shafts ? "true" : "false");
return e;
}
@@ -81,6 +87,14 @@ void KRLight::loadXML(tinyxml2::XMLElement *e) {
m_flareSize = 0.0;
}
if(e->QueryBoolAttribute("casts_shadow", &m_casts_shadow) != tinyxml2::XML_SUCCESS) {
m_casts_shadow = true;
}
if(e->QueryBoolAttribute("light_shafts", &m_light_shafts) != tinyxml2::XML_SUCCESS) {
m_light_shafts = true;
}
const char *szFlareTexture = e->Attribute("flare_texture");
if(szFlareTexture) {
m_flareTexture = szFlareTexture;
@@ -124,25 +138,25 @@ float KRLight::getDecayStart() {
#if TARGET_OS_IPHONE
void KRLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, lights, viewport, renderPass);
if(renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) {
if(renderPass == KRNode::RENDER_PASS_GENERATE_SHADOWMAPS && (pCamera->volumetric_environment_enable || (pCamera->m_cShadowBuffers > 0 && m_casts_shadow))) {
allocateShadowBuffers(configureShadowBufferViewports(viewport));
renderShadowBuffers(pCamera);
}
if(renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
if(renderPass == KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE && pCamera->volumetric_environment_enable && m_light_shafts) {
std::string shader_name = pCamera->volumetric_environment_downsample != 0 ? "volumetric_fog_downsampled" : "volumetric_fog";
std::stack<KRLight *> this_light;
this_light.push(this);
std::vector<KRLight *> this_light;
this_light.push_back(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(getContext().getShaderManager()->selectShader(pFogShader, viewport, KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) {
if(getContext().getShaderManager()->selectShader(pFogShader, viewport, KRMat4(), this_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) {
int slice_count = (int)(pCamera->volumetric_environment_quality * 495.0) + 5;
float slice_near = -pCamera->getPerspectiveNearZ();
@@ -275,9 +289,9 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
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);
KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::vector<KRLight *>(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::stack<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
getContext().getShaderManager()->selectShader(shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector<KRLight *>(), KRNode::RENDER_PASS_SHADOWMAP);
std::set<KRAABB> newVisibleBounds;
@@ -288,3 +302,18 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera)
}
#endif
int KRLight::getShadowBufferCount()
{
return m_cShadowBuffers;
}
GLuint *KRLight::getShadowTextures()
{
return shadowDepthTexture;
}
KRViewport *KRLight::getShadowViewports()
{
return m_shadowViewports;
}

View File

@@ -18,8 +18,8 @@ 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
#define KRENGINE_SHADOW_MAP_WIDTH 2048
#define KRENGINE_SHADOW_MAP_HEIGHT 2048
class KRLight : public KRNode {
public:
@@ -43,10 +43,15 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
#endif
int getShadowBufferCount();
GLuint *getShadowTextures();
KRViewport *getShadowViewports();
protected:
KRLight(KRScene &scene, std::string name);
@@ -58,6 +63,9 @@ protected:
KRTexture *m_pFlareTexture;
float m_flareSize;
bool m_casts_shadow;
bool m_light_shafts;
// Shadow Maps
int m_cShadowBuffers;

View File

@@ -201,7 +201,7 @@ bool KRMaterial::isTransparent() {
}
#if TARGET_OS_IPHONE
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 KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool bSameMaterial = *prevBoundMaterial == this;
bool bLightMap = pLightMap && pCamera->bEnableLightMap;

View File

@@ -89,7 +89,7 @@ public:
char *getName();
#if TARGET_OS_IPHONE
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif

View File

@@ -111,7 +111,7 @@ void KRModel::loadPack(KRDataBlock *data) {
#if TARGET_OS_IPHONE
void KRModel::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
void KRModel::render(KRCamera *pCamera, std::vector<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 && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {

View File

@@ -69,7 +69,7 @@ public:
#if TARGET_OS_IPHONE
void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif

View File

@@ -150,7 +150,7 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
} else if(strcmp(szElementName, "mesh") == 0) {
float lod_min_coverage = 0.0f;
if(e->QueryFloatAttribute("lod_min_coverage", &lod_min_coverage) != tinyxml2::XML_SUCCESS) {
lod_min_coverage = 0.0f; //1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size
lod_min_coverage = 0.0f;
}
bool receives_shadow = true;
if(e->QueryBoolAttribute("receives_shadow", &receives_shadow) != tinyxml2::XML_SUCCESS) {
@@ -168,7 +168,7 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
#if TARGET_OS_IPHONE
void KRNode::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass)
void KRNode::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass)
{
}

View File

@@ -71,7 +71,7 @@ public:
KRScene &getScene();
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, RenderPass renderPass);
#endif

View File

@@ -23,7 +23,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) = 0;
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) = 0;
#endif
protected:

View File

@@ -52,7 +52,7 @@ void KRParticleSystemBrownian::physicsUpdate(float deltaTime)
#if TARGET_OS_IPHONE
void KRParticleSystemBrownian::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
void KRParticleSystemBrownian::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass) {
KRNode::render(pCamera, lights, viewport, renderPass);

View File

@@ -26,7 +26,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
#endif

View File

@@ -42,7 +42,7 @@ KRAABB KRPointLight::getBounds() {
#if TARGET_OS_IPHONE
void KRPointLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
void KRPointLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
{
KRLight::render(pCamera, lights, viewport, renderPass);
@@ -51,6 +51,9 @@ void KRPointLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, cons
if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS || bVisualize) {
// Lights are rendered on the second pass of the deferred renderer
std::vector<KRLight *> this_light;
this_light.push_back(this);
KRVector3 light_position = getLocalTranslation();
@@ -68,9 +71,9 @@ void KRPointLight::render(KRCamera *pCamera, std::stack<KRLight *> &lights, cons
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ());
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);
KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(getContext().getShaderManager()->selectShader(pShader, viewport, sphereModelMatrix, lights, renderPass)) {
if(getContext().getShaderManager()->selectShader(pShader, viewport, sphereModelMatrix, this_light, renderPass)) {

View File

@@ -24,7 +24,7 @@ public:
#if TARGET_OS_IPHONE
virtual void render(KRCamera *pCamera, std::stack<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
#endif
private:

View File

@@ -35,14 +35,18 @@
#import "KRMat4.h"
#import "tinyxml2.h"
#import "KRDirectionalLight.h"
#import "KRLight.h"
#import "KRScene.h"
#import "KRNode.h"
#import "KRStockGeometry.h"
#import "KRDirectionalLight.h"
#import "KRSpotLight.h"
#import "KRPointLight.h"
#import "KRQuaternion.h"
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
m_pFirstDirectionalLight = NULL;
m_pFirstLight = NULL;
m_pRootNode = new KRNode(*this, "scene_root");
m_skyBoxName = "";
@@ -56,7 +60,7 @@ KRScene::~KRScene() {
void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, std::set<KRAABB> &newVisibleBounds) {
std::stack<KRLight *> lights;
std::vector<KRLight *> lights;
updateOctree();
pCamera->setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph
@@ -69,7 +73,7 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
KRNode *node = (*itr);
KRLight *light = dynamic_cast<KRLight *>(node);
if(light) {
lights.push(light);
lights.push_back(light);
}
}
@@ -108,7 +112,7 @@ void KRScene::render(KRCamera *pCamera, const std::set<KRAABB> &visibleBounds, c
}
}
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)
void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<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) {
@@ -134,7 +138,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
}
} else {
float min_coverage = 0.0f; // 1.0f / 1024.0f / 768.0f; // FINDME - HACK - Need to dynamically select the absolute minimum based on the render buffer size
float min_coverage = 0.0f;
float lod_coverage = pOctreeNode->getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > min_coverage) {
@@ -251,7 +255,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
KRNode *node = (*itr);
KRLight *light = dynamic_cast<KRLight *>(node);
if(light) {
lights.push(light);
lights.push_back(light);
light_count++;
}
}
@@ -271,7 +275,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleB
// Remove lights added at this octree level from the stack
while(light_count--) {
lights.pop();
lights.pop_back();
}
}
}
@@ -302,14 +306,14 @@ bool KRScene::save(const std::string& path) {
}
KRDirectionalLight *KRScene::findFirstDirectionalLight(KRNode &node) {
KRDirectionalLight *pLight = dynamic_cast<KRDirectionalLight *>(&node);
KRLight *KRScene::findFirstLight(KRNode &node) {
KRLight *pLight = dynamic_cast<KRLight *>(&node);
if(pLight) {
return pLight;
} else {
const std::vector<KRNode *> children = node.getChildren();
for(std::vector<KRNode *>::const_iterator itr=children.begin(); itr < children.end(); ++itr) {
pLight = findFirstDirectionalLight(*(*itr));
pLight = findFirstLight(*(*itr));
if(pLight) {
return pLight;
}
@@ -338,12 +342,12 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock
return new_scene;
}
KRDirectionalLight *KRScene::getFirstDirectionalLight()
KRLight *KRScene::getFirstLight()
{
if(m_pFirstDirectionalLight == NULL) {
m_pFirstDirectionalLight = findFirstDirectionalLight(*m_pRootNode);
if(m_pFirstLight == NULL) {
m_pFirstLight = findFirstLight(*m_pRootNode);
}
return m_pFirstDirectionalLight;
return m_pFirstLight;
}
void KRScene::notify_sceneGraphCreate(KRNode *pNode)
@@ -391,6 +395,10 @@ void KRScene::physicsUpdate(float deltaTime)
}
}
#if TARGET_OS_IPHONE
#endif
void KRScene::addDefaultLights()
{
KRDirectionalLight *light1 = new KRDirectionalLight(*this, "default_light1");
light1->setLocalRotation((KRQuaternion(KRVector3(0.0, M_PI * 0.25, 0.0)) * KRQuaternion(KRVector3(0.0, 0.0, -M_PI * 0.25))).euler());
m_pRootNode->addChild(light1);
}

View File

@@ -43,7 +43,7 @@
#import "KRNode.h"
#import "KROctree.h"
class KRInstance;
class KRDirectionalLight;
class KRLight;
using std::vector;
@@ -58,13 +58,13 @@ public:
static KRScene *Load(KRContext &context, const std::string &name, KRDataBlock *data);
KRNode *getRootNode();
KRDirectionalLight *getFirstDirectionalLight();
KRLight *getFirstLight();
#if TARGET_OS_IPHONE
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, 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);
void render(KROctreeNode *pOctreeNode, const std::set<KRAABB> &visibleBounds, KRCamera *pCamera, std::vector<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
@@ -74,12 +74,13 @@ public:
void notify_sceneGraphModify(KRNode *pNode);
void physicsUpdate(float deltaTime);
void addDefaultLights();
private:
KRDirectionalLight *findFirstDirectionalLight(KRNode &node);
KRLight *findFirstLight(KRNode &node);
KRNode *m_pRootNode;
KRDirectionalLight *m_pFirstDirectionalLight;
KRLight *m_pFirstLight;
std::set<KRNode *> m_newNodes;
std::set<KRNode *> m_modifiedNodes;

View File

@@ -31,6 +31,10 @@
#include "KRShader.h"
#import "assert.h"
#include "KRLight.h"
#include "KRDirectionalLight.h"
#include "KRSpotLight.h"
#include "KRPointLight.h"
KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) : KRContextObject(context)
{
@@ -115,19 +119,27 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st
} else {
// Get uniform locations
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_AMBIENT] = glGetUniformLocation(m_iProgram, "material_ambient"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_DIFFUSE] = glGetUniformLocation(m_iProgram, "material_diffuse"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_SPECULAR] = glGetUniformLocation(m_iProgram, "material_specular"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_REFLECTION] = glGetUniformLocation(m_iProgram, "material_reflection"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_ALPHA] = glGetUniformLocation(m_iProgram, "material_alpha"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_SHININESS] = glGetUniformLocation(m_iProgram, "material_shininess"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_POSITION] = glGetUniformLocation(m_iProgram, "light_position"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "view_space_model_origin"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_COLOR] = glGetUniformLocation(m_iProgram, "light_color"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_INTENSITY] = glGetUniformLocation(m_iProgram, "light_intensity"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DECAY_START] = glGetUniformLocation(m_iProgram, "light_decay_start"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_CUTOFF] = glGetUniformLocation(m_iProgram, "light_cutoff"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_model_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_view_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_FLARE_SIZE] = glGetUniformLocation(m_iProgram, "flare_size"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_ALPHA] = glGetUniformLocation(m_iProgram, "material_alpha"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MATERIAL_SHININESS] = glGetUniformLocation(m_iProgram, "material_shininess"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] = glGetUniformLocation(m_iProgram, "view_space_model_origin"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_MVP] = glGetUniformLocation(m_iProgram, "mvp_matrix"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_INVMVP] = glGetUniformLocation(m_iProgram, "inv_mvp_matrix"));
@@ -142,8 +154,7 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_iProgram, "shadow_mvp1"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP2] = glGetUniformLocation(m_iProgram, "shadow_mvp2"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP3] = glGetUniformLocation(m_iProgram, "shadow_mvp3"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_model_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_view_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] = glGetUniformLocation(m_iProgram, "camera_position_model_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] = glGetUniformLocation(m_iProgram, "viewport"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE] = glGetUniformLocation(m_iProgram, "diffuseTexture"));
@@ -206,60 +217,91 @@ KRShader::~KRShader() {
#if TARGET_OS_IPHONE
bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass) const {
bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const {
if(m_iProgram == 0) {
return false;
}
// 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));
int light_directional_count = 0;
int light_point_count = 0;
int light_spot_count = 0;
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
for(std::vector<KRLight *>::const_iterator light_itr=lights.begin(); light_itr != lights.end(); light_itr++) {
KRLight *light = (*light_itr);
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(light);
KRPointLight *point_light = dynamic_cast<KRPointLight *>(light);
KRSpotLight *spot_light = dynamic_cast<KRSpotLight *>(light);
if(directional_light) {
if(light_directional_count == 0) {
int cShadowBuffers = directional_light->getShadowBufferCount();
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, directional_light->getShadowTextures()[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, directional_light->getShadowTextures()[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, directional_light->getShadowTextures()[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));
}
KRMat4 matBias;
matBias.translate(1.0, 1.0, 1.0);
matBias.scale(0.5);
for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) {
(matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias).setUniform(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow]);
}
if(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1) {
KRMat4 inverseModelMatrix = matModel;
inverseModelMatrix.invert();
// Bind the light direction vector
KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection());
lightDirObject.normalize();
lightDirObject.setUniform(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE]);
}
}
light_directional_count++;
}
if(point_light) {
light_point_count++;
}
if(spot_light) {
light_spot_count++;
}
}
}
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) {
if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) {
KRMat4 inverseModelMatrix = matModel;
inverseModelMatrix.invert();
if(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1) {
// Bind the light direction vector
KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, lightDirection);
lightDirObject.normalize();
lightDirObject.setUniform(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE]);
}
if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) {
// Transform location of camera to object space for calculation of specular halfVec
KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, viewport.getCameraPosition());
@@ -277,14 +319,14 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const st
}
}
if(m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW] != -1) {
if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW] != -1) {
KRMat4 matModelView = matModel * viewport.getViewMatrix();
matModelView.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW]);
if(m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] != -1) {
if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1) {
KRVector3 view_space_model_origin = KRMat4::Dot(matModelView, KRVector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required
view_space_model_origin.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE]);
view_space_model_origin.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN]);
}
if(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) {
@@ -336,13 +378,6 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const st
));
}
// Bind the shadowmap space matrices
for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) {
KRMat4 matBias;
matBias.translate(1.0, 1.0, 1.0);
matBias.scale(0.5);
(matModel * pShadowViewports[iShadow].getViewProjectionMatrix() * matBias).setUniform(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow]);
}
// Sets the diffuseTexture variable to the first texture unit
GLDEBUG(glUniform1i(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE], 0));
@@ -395,10 +430,6 @@ bool KRShader::bind(const KRViewport &viewport, const KRMat4 &matModel, const st
#endif
GLuint KRShader::getProgram() const {
return m_iProgram;
}
const char *KRShader::getKey() const {
return m_szKey;
}

View File

@@ -52,12 +52,11 @@ class KRShader : public KRContextObject {
public:
KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource);
virtual ~KRShader();
GLuint getProgram() const;
const char *getKey() const;
#if TARGET_OS_IPHONE
bool bind(const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass) const;
bool bind(const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass) const;
#endif
@@ -79,15 +78,16 @@ public:
KRENGINE_UNIFORM_MATERIAL_SHININESS,
KRENGINE_UNIFORM_LIGHT_POSITION,
KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE,
KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE,
KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE,
KRENGINE_UNIFORM_LIGHT_COLOR,
KRENGINE_UNIFORM_LIGHT_DECAY_START,
KRENGINE_UNIFORM_LIGHT_CUTOFF,
KRENGINE_UNIFORM_LIGHT_INTENSITY,
KRENGINE_UNIFORM_FLARE_SIZE,
KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN,
KRENGINE_UNIFORM_MVP,
KRENGINE_UNIFORM_INVP,

View File

@@ -34,6 +34,11 @@
#include <sstream>
#include <fstream>
#include "KRLight.h"
#include "KRDirectionalLight.h"
#include "KRSpotLight.h"
#include "KRPointLight.h"
using namespace std;
KRShaderManager::KRShaderManager(KRContext &context) : KRContextObject(context) {
@@ -45,13 +50,32 @@ KRShaderManager::~KRShaderManager() {
}
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) {
KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<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
int light_directional_count = 0;
int light_point_count = 0;
int light_spot_count = 0;
if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE) {
for(std::vector<KRLight *>::const_iterator light_itr=lights.begin(); light_itr != lights.end(); light_itr++) {
KRLight *light = (*light_itr);
KRDirectionalLight *directional_light = dynamic_cast<KRDirectionalLight *>(light);
KRPointLight *point_light = dynamic_cast<KRPointLight *>(light);
KRSpotLight *spot_light = dynamic_cast<KRSpotLight *>(light);
if(directional_light) {
iShadowQuality = directional_light->getShadowBufferCount();
light_directional_count++;
}
if(point_light) light_point_count++;
if(spot_light) light_spot_count++;
}
}
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 && pCamera->volumetric_environment_downsample != 0, 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);
sprintf(szKey, "%i_%i_%i_%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", light_directional_count, light_point_count, light_spot_count, 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 && pCamera->volumetric_environment_downsample != 0, 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);
KRShader *pShader = m_shaders[szKey];
@@ -66,8 +90,11 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
stringstream stream;
stream.precision(std::numeric_limits<long double>::digits10);
stream << "\n#define LIGHT_DIRECTIONAL_COUNT " << light_directional_count;
stream << "#define LIGHT_POINT_COUNT " << light_point_count;
stream << "#define LIGHT_SPOT_COUNT " << light_spot_count;
stream << "#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0");
stream << "\n#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0");
stream << "\n#define HAS_DIFFUSE_MAP_SCALE " << (bDiffuseMapScale ? "1" : "0");
stream << "\n#define HAS_DIFFUSE_MAP_OFFSET " << (bDiffuseMapOffset ? "1" : "0");
@@ -140,13 +167,13 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCam
return pShader;
}
bool KRShaderManager::selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, 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)
bool KRShaderManager::selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, 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)
{
KRShader *pShader = getShader(shader_name, pCamera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass);
return selectShader(pShader, viewport, matModel, lights, renderPass);
}
bool KRShaderManager::selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass)
bool KRShaderManager::selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass)
{
if(pShader) {
bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0;

View File

@@ -59,11 +59,11 @@ public:
const std::string &getVertShaderSource(const std::string &name);
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);
KRShader *getShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<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);
bool selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::stack<KRLight *> &lights, const KRNode::RenderPass &renderPass);
bool selectShader(const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRLight *> &lights, const KRNode::RenderPass &renderPass);
bool selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::stack<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, 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);
bool selectShader(const std::string &shader_name, const KRCamera *pCamera, const std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, 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();