Flares now disappear behind objects.
This commit is contained in:
@@ -266,6 +266,29 @@ void KRCamera::renderFrame(float deltaTime)
|
|||||||
// Render all transparent geometry
|
// Render all transparent geometry
|
||||||
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, false);
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, false);
|
||||||
|
|
||||||
|
// ----====---- Particle Occlusion Tests ----====----
|
||||||
|
|
||||||
|
// Set render target
|
||||||
|
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
|
||||||
|
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0));
|
||||||
|
|
||||||
|
// Disable backface culling
|
||||||
|
GLDEBUG(glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
|
// Disable z-buffer write
|
||||||
|
GLDEBUG(glDepthMask(GL_FALSE));
|
||||||
|
|
||||||
|
// Enable z-buffer test
|
||||||
|
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||||
|
GLDEBUG(glDepthFunc(GL_LEQUAL));
|
||||||
|
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||||
|
|
||||||
|
// Enable additive blending
|
||||||
|
GLDEBUG(glEnable(GL_BLEND));
|
||||||
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||||
|
|
||||||
|
// ----====---- Perform Occlusion Tests ----====----
|
||||||
|
scene.render(this, m_viewport.getVisibleBounds(), m_viewport, RENDER_PASS_PARTICLE_OCCLUSION, false);
|
||||||
|
|
||||||
// ----====---- Flares ----====----
|
// ----====---- Flares ----====----
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ KRLight::KRLight(KRScene &scene, std::string name) : KRNode(scene, name)
|
|||||||
m_flareTexture = "";
|
m_flareTexture = "";
|
||||||
m_pFlareTexture = NULL;
|
m_pFlareTexture = NULL;
|
||||||
m_flareSize = 0.0;
|
m_flareSize = 0.0;
|
||||||
|
m_flareOcclusionSize = 0.05;
|
||||||
m_casts_shadow = true;
|
m_casts_shadow = true;
|
||||||
m_light_shafts = true;
|
m_light_shafts = true;
|
||||||
m_dust_particle_density = 0.1f;
|
m_dust_particle_density = 0.1f;
|
||||||
m_dust_particle_size = 1.0f;
|
m_dust_particle_size = 1.0f;
|
||||||
|
m_occlusionQuery = 0;
|
||||||
|
|
||||||
// Initialize shadow buffers
|
// Initialize shadow buffers
|
||||||
m_cShadowBuffers = 0;
|
m_cShadowBuffers = 0;
|
||||||
@@ -45,6 +47,10 @@ KRLight::KRLight(KRScene &scene, std::string name) : KRNode(scene, name)
|
|||||||
|
|
||||||
KRLight::~KRLight()
|
KRLight::~KRLight()
|
||||||
{
|
{
|
||||||
|
if(m_occlusionQuery) {
|
||||||
|
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
||||||
|
m_occlusionQuery = 0;
|
||||||
|
}
|
||||||
allocateShadowBuffers(0);
|
allocateShadowBuffers(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +63,7 @@ tinyxml2::XMLElement *KRLight::saveXML( tinyxml2::XMLNode *parent)
|
|||||||
e->SetAttribute("color_b", m_color.z);
|
e->SetAttribute("color_b", m_color.z);
|
||||||
e->SetAttribute("decay_start", m_decayStart);
|
e->SetAttribute("decay_start", m_decayStart);
|
||||||
e->SetAttribute("flare_size", m_flareSize);
|
e->SetAttribute("flare_size", m_flareSize);
|
||||||
|
e->SetAttribute("flare_occlusion_size", m_flareOcclusionSize);
|
||||||
e->SetAttribute("flare_texture", m_flareTexture.c_str());
|
e->SetAttribute("flare_texture", m_flareTexture.c_str());
|
||||||
e->SetAttribute("casts_shadow", m_casts_shadow ? "true" : "false");
|
e->SetAttribute("casts_shadow", m_casts_shadow ? "true" : "false");
|
||||||
e->SetAttribute("light_shafts", m_light_shafts ? "true" : "false");
|
e->SetAttribute("light_shafts", m_light_shafts ? "true" : "false");
|
||||||
@@ -92,6 +99,10 @@ void KRLight::loadXML(tinyxml2::XMLElement *e) {
|
|||||||
m_flareSize = 0.0;
|
m_flareSize = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(e->QueryFloatAttribute("flare_occlusion_size", &m_flareOcclusionSize) != tinyxml2::XML_SUCCESS) {
|
||||||
|
m_flareOcclusionSize = 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
if(e->QueryBoolAttribute("casts_shadow", &m_casts_shadow) != tinyxml2::XML_SUCCESS) {
|
if(e->QueryBoolAttribute("casts_shadow", &m_casts_shadow) != tinyxml2::XML_SUCCESS) {
|
||||||
m_casts_shadow = true;
|
m_casts_shadow = true;
|
||||||
}
|
}
|
||||||
@@ -133,6 +144,10 @@ void KRLight::setFlareSize(float flare_size) {
|
|||||||
m_flareSize = flare_size;
|
m_flareSize = flare_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRLight::setOcclusionSize(float occlusion_size) {
|
||||||
|
m_flareOcclusionSize;
|
||||||
|
}
|
||||||
|
|
||||||
void KRLight::setIntensity(float intensity) {
|
void KRLight::setIntensity(float intensity) {
|
||||||
m_intensity = intensity;
|
m_intensity = intensity;
|
||||||
}
|
}
|
||||||
@@ -230,27 +245,66 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
if(renderPass == KRNode::RENDER_PASS_PARTICLE_OCCLUSION) {
|
||||||
if(m_flareTexture.size() && m_flareSize > 0.0f) {
|
if(m_flareTexture.size() && m_flareSize > 0.0f) {
|
||||||
if(!m_pFlareTexture && m_flareTexture.size()) {
|
|
||||||
m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture.c_str());
|
|
||||||
|
KRMat4 occlusion_test_sphere_matrix = KRMat4();
|
||||||
|
occlusion_test_sphere_matrix.scale(m_localScale * m_flareOcclusionSize);
|
||||||
|
occlusion_test_sphere_matrix.translate(m_localTranslation);
|
||||||
|
if(m_parentNode) {
|
||||||
|
occlusion_test_sphere_matrix *= m_parentNode->getModelMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_pFlareTexture) {
|
if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, lights, 0, viewport, occlusion_test_sphere_matrix, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass)) {
|
||||||
// Disable z-buffer test
|
|
||||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
|
||||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
|
||||||
|
|
||||||
// Render light flare on transparency pass
|
GLDEBUG(glGenQueriesEXT(1, &m_occlusionQuery));
|
||||||
KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
GLDEBUG(glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, m_occlusionQuery));
|
||||||
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), lights, 0, renderPass)) {
|
|
||||||
GLDEBUG(glUniform1f(
|
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
|
||||||
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
|
if(sphereModels.size()) {
|
||||||
m_flareSize
|
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
|
||||||
));
|
sphereModels[0]->renderSubmesh(i);
|
||||||
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
}
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
|
}
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
|
||||||
|
GLDEBUG(glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
|
||||||
|
if(m_flareTexture.size() && m_flareSize > 0.0f) {
|
||||||
|
|
||||||
|
if(m_occlusionQuery) {
|
||||||
|
GLuint params = 0;
|
||||||
|
GLDEBUG(glGetQueryObjectuivEXT(m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
||||||
|
GLDEBUG(glDeleteQueriesEXT(1, &m_occlusionQuery));
|
||||||
|
|
||||||
|
if(params) {
|
||||||
|
|
||||||
|
if(!m_pFlareTexture && m_flareTexture.size()) {
|
||||||
|
m_pFlareTexture = getContext().getTextureManager()->getTexture(m_flareTexture.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_pFlareTexture) {
|
||||||
|
// Disable z-buffer test
|
||||||
|
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||||
|
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||||
|
|
||||||
|
// Render light flare on transparency pass
|
||||||
|
KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||||
|
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), lights, 0, renderPass)) {
|
||||||
|
GLDEBUG(glUniform1f(
|
||||||
|
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
|
||||||
|
m_flareSize
|
||||||
|
));
|
||||||
|
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
||||||
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
|
||||||
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public:
|
|||||||
|
|
||||||
void setFlareTexture(std::string flare_texture);
|
void setFlareTexture(std::string flare_texture);
|
||||||
void setFlareSize(float flare_size);
|
void setFlareSize(float flare_size);
|
||||||
|
void setOcclusionSize(float occlusion_size);
|
||||||
void deleteBuffers();
|
void deleteBuffers();
|
||||||
|
|
||||||
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
virtual void render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||||
@@ -58,6 +59,7 @@ protected:
|
|||||||
std::string m_flareTexture;
|
std::string m_flareTexture;
|
||||||
KRTexture *m_pFlareTexture;
|
KRTexture *m_pFlareTexture;
|
||||||
float m_flareSize;
|
float m_flareSize;
|
||||||
|
float m_flareOcclusionSize;
|
||||||
|
|
||||||
bool m_casts_shadow;
|
bool m_casts_shadow;
|
||||||
bool m_light_shafts;
|
bool m_light_shafts;
|
||||||
@@ -65,6 +67,8 @@ protected:
|
|||||||
float m_dust_particle_size;
|
float m_dust_particle_size;
|
||||||
float m_dust_particle_intensity;
|
float m_dust_particle_intensity;
|
||||||
|
|
||||||
|
GLuint m_occlusionQuery; // Occlusion query for attenuating occluded flares
|
||||||
|
|
||||||
|
|
||||||
// Shadow Maps
|
// Shadow Maps
|
||||||
int m_cShadowBuffers;
|
int m_cShadowBuffers;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ void KRMesh::loadPack(KRDataBlock *data) {
|
|||||||
void KRMesh::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) {
|
void KRMesh::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) {
|
||||||
|
|
||||||
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
|
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
|
||||||
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||||
|
|
||||||
if(m_materials.size() == 0) {
|
if(m_materials.size() == 0) {
|
||||||
vector<KRMesh::Submesh *> submeshes = getSubmeshes();
|
vector<KRMesh::Submesh *> submeshes = getSubmeshes();
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
|
|||||||
|
|
||||||
KRNode::render(pCamera, lights, viewport, 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 && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
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_PARTICLE_OCCLUSION && 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
|
// Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied
|
||||||
|
|
||||||
loadModel();
|
loadModel();
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public:
|
|||||||
RENDER_PASS_DEFERRED_LIGHTS,
|
RENDER_PASS_DEFERRED_LIGHTS,
|
||||||
RENDER_PASS_DEFERRED_OPAQUE,
|
RENDER_PASS_DEFERRED_OPAQUE,
|
||||||
RENDER_PASS_FORWARD_TRANSPARENT,
|
RENDER_PASS_FORWARD_TRANSPARENT,
|
||||||
|
RENDER_PASS_PARTICLE_OCCLUSION,
|
||||||
RENDER_PASS_ADDITIVE_PARTICLES,
|
RENDER_PASS_ADDITIVE_PARTICLES,
|
||||||
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE,
|
||||||
RENDER_PASS_GENERATE_SHADOWMAPS,
|
RENDER_PASS_GENERATE_SHADOWMAPS,
|
||||||
@@ -109,6 +110,8 @@ protected:
|
|||||||
KRVector3 m_initialLocalScale;
|
KRVector3 m_initialLocalScale;
|
||||||
KRVector3 m_initialLocalRotation;
|
KRVector3 m_initialLocalRotation;
|
||||||
|
|
||||||
|
KRNode *m_parentNode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void invalidateModelMatrix();
|
void invalidateModelMatrix();
|
||||||
void invalidateBindPoseMatrix();
|
void invalidateBindPoseMatrix();
|
||||||
@@ -124,7 +127,6 @@ private:
|
|||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
std::vector<KRNode *> m_childNodes;
|
std::vector<KRNode *> m_childNodes;
|
||||||
KRNode *m_parentNode;
|
|
||||||
|
|
||||||
KRScene *m_pScene;
|
KRScene *m_pScene;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user