diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 80e2248..79d2d82 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -57,6 +57,8 @@ E46F4A0E155E003000CCF8B8 /* KRDataBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46F4A0D155E003000CCF8B8 /* KRDataBlock.cpp */; }; E46F4A0F155E003000CCF8B8 /* KRDataBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46F4A0D155E003000CCF8B8 /* KRDataBlock.cpp */; }; E46F4A10155E004100CCF8B8 /* KRDataBlock.cpp in Headers */ = {isa = PBXBuildFile; fileRef = E46F4A0D155E003000CCF8B8 /* KRDataBlock.cpp */; settings = {ATTRIBUTES = (Public, ); }; }; + E4769DED158A78B6004B83AC /* flare.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E4769DEC158A78B6004B83AC /* flare.fsh */; }; + E4769DF0158A78C6004B83AC /* flare.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4769DEF158A78C6004B83AC /* flare.vsh */; }; E47C25A213F4F65A00FF4370 /* KRShaderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C25A113F4F65A00FF4370 /* KRShaderManager.h */; }; E47C25A513F4F66F00FF4370 /* KRShader.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C25A413F4F66F00FF4370 /* KRShader.h */; }; E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47C25A613F4F6AB00FF4370 /* KRShaderManager.cpp */; }; @@ -190,6 +192,8 @@ E46F4A03155DF47C00CCF8B8 /* KRWorld.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRWorld.cpp; path = Classes/KRWorld.cpp; sourceTree = ""; }; E46F4A0A155E002100CCF8B8 /* KRDataBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRDataBlock.h; path = Classes/KRDataBlock.h; sourceTree = ""; }; E46F4A0D155E003000CCF8B8 /* KRDataBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRDataBlock.cpp; path = Classes/KRDataBlock.cpp; sourceTree = ""; }; + E4769DEC158A78B6004B83AC /* flare.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = flare.fsh; path = Shaders/flare.fsh; sourceTree = ""; }; + E4769DEF158A78C6004B83AC /* flare.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = flare.vsh; path = Shaders/flare.vsh; sourceTree = ""; }; E47C25A113F4F65A00FF4370 /* KRShaderManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRShaderManager.h; path = Classes/KRShaderManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E47C25A413F4F66F00FF4370 /* KRShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRShader.h; path = Classes/KRShader.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E47C25A613F4F6AB00FF4370 /* KRShaderManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRShaderManager.cpp; path = Classes/KRShaderManager.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -290,6 +294,8 @@ E4D133BB1538F7560070068C /* light_directional.vsh */, E4A9DEBD154120C4009DF363 /* light_point.fsh */, E4A9DEC0154120E8009DF363 /* light_point.vsh */, + E4769DEC158A78B6004B83AC /* flare.fsh */, + E4769DEF158A78C6004B83AC /* flare.vsh */, ); name = Shaders; sourceTree = ""; @@ -702,6 +708,8 @@ E46F4A04155DF47C00CCF8B8 /* KRWorld.cpp in Sources */, E46F4A0E155E003000CCF8B8 /* KRDataBlock.cpp in Sources */, E42CB1F0158446AB0066E0D8 /* KRQuaternion.cpp in Sources */, + E4769DED158A78B6004B83AC /* flare.fsh in Sources */, + E4769DF0158A78C6004B83AC /* flare.vsh in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index e820d3e..bd9febf 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -97,4 +97,11 @@ const KRVector2 &KRCamera::getViewportSize() { void KRCamera::setViewportSize(const KRVector2 &size) { m_viewportSize = size; +} + +KRVector3 KRCamera::getPosition() const { + return m_position; +} +void KRCamera::setPosition(const KRVector3 &position) { + m_position = position; } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRCamera.h b/KREngine/KREngine/Classes/KRCamera.h index e07c21a..76cc46d 100644 --- a/KREngine/KREngine/Classes/KRCamera.h +++ b/KREngine/KREngine/Classes/KRCamera.h @@ -42,6 +42,9 @@ public: KRCamera(); ~KRCamera(); + KRVector3 getPosition() const; + void setPosition(const KRVector3 &position); + KRMat4 getProjectionMatrix(); const KRVector2 &getViewportSize(); void setViewportSize(const KRVector2 &size); @@ -82,6 +85,9 @@ public: double vignette_falloff; KRVector2 m_viewportSize; + +private: + KRVector3 m_position; }; #endif diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index d1ad2c0..4a3a4d9 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -50,6 +50,9 @@ KRVector3 KRDirectionalLight::getLocalLightDirection() { void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { + KRLight::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); + + if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { // Lights are rendered on the second pass of the deferred renderer @@ -106,8 +109,6 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundi glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - - KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); } #endif \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KREngine.h b/KREngine/KREngine/Classes/KREngine.h index 82f22ff..4553e25 100644 --- a/KREngine/KREngine/Classes/KREngine.h +++ b/KREngine/KREngine/Classes/KREngine.h @@ -73,6 +73,7 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F KRENGINE_UNIFORM_LIGHT_DECAY_START, KRENGINE_UNIFORM_LIGHT_CUTOFF, KRENGINE_UNIFORM_LIGHT_INTENSITY, + KRENGINE_UNIFORM_FLARE_SIZE, KRENGINE_UNIFORM_MVP, KRENGINE_UNIFORM_INVP, KRENGINE_UNIFORM_MN2V, diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index 54d5494..32d7637 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -487,13 +487,13 @@ double const PI = 3.141592653589793f; // Set render target glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0); - // Enable backface culling - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); + // Disable backface culling + glDisable(GL_CULL_FACE); - // Enable z-buffer write - glDepthMask(GL_TRUE); + // Disable z-buffer write + glDepthMask(GL_FALSE); // Enable z-buffer test glEnable(GL_DEPTH_TEST); @@ -503,9 +503,36 @@ double const PI = 3.141592653589793f; // Enable alpha blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // TODO: Need to perform a forward render of all transparent geometry here... + + // Render all transparent geometry pScene->render(&m_camera, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + + // ----====---- Flares ----====---- + + // Set render target + glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0); + + // Disable backface culling + glDisable(GL_CULL_FACE); + + // Disable z-buffer write + glDepthMask(GL_FALSE); + + // Disable z-buffer test + glDisable(GL_DEPTH_TEST); + glDepthRangef(0.0, 1.0); + + // Enable additive blending + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + // Render all transparent geometry + pScene->render(&m_camera, m_pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, KRNode::RENDER_PASS_FLARES); + + + // Re-enable z-buffer write + glDepthMask(GL_TRUE); } - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file withOptions: (NSString *)options diff --git a/KREngine/KREngine/Classes/KRInstance.cpp b/KREngine/KREngine/Classes/KRInstance.cpp index da4f424..830282e 100644 --- a/KREngine/KREngine/Classes/KRInstance.cpp +++ b/KREngine/KREngine/Classes/KRInstance.cpp @@ -66,8 +66,10 @@ KRMat4 &KRInstance::getModelMatrix() { #if TARGET_OS_IPHONE void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { + + KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); - if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) { + if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_FLARES) { // Don't render meshes on second pass of the deferred lighting renderer, as only lights will be applied @@ -112,7 +114,6 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume } - KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); } #endif diff --git a/KREngine/KREngine/Classes/KRLight.cpp b/KREngine/KREngine/Classes/KRLight.cpp index 2294e6f..ea5d889 100644 --- a/KREngine/KREngine/Classes/KRLight.cpp +++ b/KREngine/KREngine/Classes/KRLight.cpp @@ -8,11 +8,26 @@ #include + + #import "KRLight.h" +#import "KRNode.h" +#import "KRMat4.h" +#import "KRVector3.h" +#import "KRCamera.h" +#import "KRContext.h" + +#import "KRBoundingVolume.h" +#import "KRShaderManager.h" +#import "KRShader.h" + KRLight::KRLight(std::string name) : KRNode(name) { m_intensity = 1.0f; + m_flareTexture = ""; + m_pFlareTexture = NULL; + m_flareSize = 0.0; } KRLight::~KRLight() @@ -28,19 +43,53 @@ tinyxml2::XMLElement *KRLight::saveXML( tinyxml2::XMLNode *parent) e->SetAttribute("color_g", m_color.y); e->SetAttribute("color_b", m_color.z); e->SetAttribute("decay_start", m_decayStart); + e->SetAttribute("flare_size", m_flareSize); + e->SetAttribute("flare_texture", m_flareTexture.c_str()); return e; } void KRLight::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); float x,y,z; - e->QueryFloatAttribute("color_r", &x); - e->QueryFloatAttribute("color_g", &y); - e->QueryFloatAttribute("color_b", &z); + if(e->QueryFloatAttribute("color_r", &x) != tinyxml2::XML_SUCCESS) { + x = 1.0; + } + if(e->QueryFloatAttribute("color_g", &y) != tinyxml2::XML_SUCCESS) { + y = 1.0; + } + if(e->QueryFloatAttribute("color_b", &z) != tinyxml2::XML_SUCCESS) { + z = 1.0; + } m_color = KRVector3(x,y,z); - e->QueryFloatAttribute("intensity", &m_intensity); - e->QueryFloatAttribute("decay_start", &m_decayStart); + if(e->QueryFloatAttribute("intensity", &m_intensity) != tinyxml2::XML_SUCCESS) { + m_intensity = 100.0; + } + + if(e->QueryFloatAttribute("decay_start", &m_decayStart) != tinyxml2::XML_SUCCESS) { + m_decayStart = 0.0; + } + + if(e->QueryFloatAttribute("flare_size", &m_flareSize) != tinyxml2::XML_SUCCESS) { + m_flareSize = 0.0; + } + + const char *szFlareTexture = e->Attribute("flare_texture"); + if(szFlareTexture) { + m_flareTexture = szFlareTexture; + } else { + m_flareTexture = ""; + } + m_pFlareTexture = NULL; +} + +void KRLight::setFlareTexture(std::string flare_texture) { + m_flareTexture = flare_texture; + m_pFlareTexture = NULL; +} + +void KRLight::setFlareSize(float flare_size) { + m_flareSize = flare_size; } void KRLight::setIntensity(float intensity) { @@ -65,3 +114,61 @@ void KRLight::setDecayStart(float decayStart) { float KRLight::getDecayStart() { return m_decayStart; } + +#if TARGET_OS_IPHONE + +void KRLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { + + KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); + + if(renderPass == KRNode::RENDER_PASS_FLARES) { + if(m_flareTexture.size() && m_flareSize > 0.0f) { + if(!m_pFlareTexture && m_flareTexture.size()) { + m_pFlareTexture = pContext->getTextureManager()->getTexture(m_flareTexture.c_str()); + } + + if(m_pFlareTexture) { + + KRMat4 projectionMatrix = pCamera->getProjectionMatrix(); + KRVector3 light_position = getLocalTranslation(); + + KRMat4 m_modelMatrix = KRMat4(); + m_modelMatrix.translate(light_position.x, light_position.y, light_position.z); + + + KRMat4 mvpmatrix = m_modelMatrix * viewMatrix * projectionMatrix; + KRMat4 matModelToView = viewMatrix * m_modelMatrix; + matModelToView.transpose(); + matModelToView.invert(); + + + + // Render light flare on transparency pass + KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, renderPass); + pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_pFlareTexture->getName()); + + static const GLfloat squareVertices[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, + }; + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, squareVertices); + + glUniform1f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], + m_flareSize + ); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + } + + } +} + +#endif diff --git a/KREngine/KREngine/Classes/KRLight.h b/KREngine/KREngine/Classes/KRLight.h index 893ae91..04ca4ac 100644 --- a/KREngine/KREngine/Classes/KRLight.h +++ b/KREngine/KREngine/Classes/KRLight.h @@ -11,6 +11,7 @@ #import "KRResource.h" #import "KRNode.h" +#import "KRTexture.h" static const float KRLIGHT_MIN_INFLUENCE = 0.05f; @@ -30,12 +31,25 @@ public: const KRVector3 &getColor(); void setColor(const KRVector3 &color); + void setFlareTexture(std::string flare_texture); + void setFlareSize(float flare_size); + +#if TARGET_OS_IPHONE + + virtual void render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass); + +#endif + protected: KRLight(std::string name); float m_intensity; float m_decayStart; KRVector3 m_color; + + std::string m_flareTexture; + KRTexture *m_pFlareTexture; + float m_flareSize; }; #endif diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index e178141..c436479 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -69,48 +69,53 @@ KRModel::~KRModel() { void KRModel::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &matModelToView, KRMat4 &mvpMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) { - if(m_materials.size() == 0) { - vector submeshes = m_pMesh->getSubmeshes(); - - for(std::vector::iterator itr = submeshes.begin(); itr != submeshes.end(); itr++) { - KRMaterial *pMaterial = pContext->getMaterialManager()->getMaterial((*itr)->szMaterialName); - m_materials.push_back(pMaterial); - m_uniqueMaterials.insert(pMaterial); - } - } + if(renderPass != KRNode::RENDER_PASS_FLARES) { - KRMaterial *pPrevBoundMaterial = NULL; - int iPrevBuffer = -1; - char szPrevShaderKey[128]; - szPrevShaderKey[0] = '\0'; - int cSubmeshes = m_pMesh->getSubmeshes().size(); - if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { - for(int iSubmesh=0; iSubmesh submeshes = m_pMesh->getSubmeshes(); - if(pMaterial != NULL) { - - if(!pMaterial->isTransparent()) { - // Exclude transparent and semi-transparent meshes from shadow maps - m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); - } + for(std::vector::iterator itr = submeshes.begin(); itr != submeshes.end(); itr++) { + KRMaterial *pMaterial = pContext->getMaterialManager()->getMaterial((*itr)->szMaterialName); + m_materials.push_back(pMaterial); + m_uniqueMaterials.insert(pMaterial); } - } - } else { - // Apply submeshes in per-material batches to reduce number of state changes - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + + KRMaterial *pPrevBoundMaterial = NULL; + int iPrevBuffer = -1; + char szPrevShaderKey[128]; + szPrevShaderKey[0] = '\0'; + int cSubmeshes = m_pMesh->getSubmeshes().size(); + if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { for(int iSubmesh=0; iSubmeshbind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, matModelToView, mvpMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass); - m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + if(pMaterial != NULL) { + + if(!pMaterial->isTransparent()) { + // Exclude transparent and semi-transparent meshes from shadow maps + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + } + } + + } + } else { + // Apply submeshes in per-material batches to reduce number of state changes + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + for(int iSubmesh=0; iSubmeshisTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, matModelToView, mvpMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass); + m_pMesh->renderSubmesh(iSubmesh, &iPrevBuffer); + } + } } } } + glBindBuffer(GL_ARRAY_BUFFER, 0); } - glBindBuffer(GL_ARRAY_BUFFER, 0); } #endif diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index f6acb4c..1e42f49 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -31,6 +31,7 @@ public: RENDER_PASS_DEFERRED_LIGHTS, RENDER_PASS_DEFERRED_OPAQUE, RENDER_PASS_FORWARD_TRANSPARENT, + RENDER_PASS_FLARES, RENDER_PASS_SHADOWMAP }; diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index 67750f0..1c79428 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -38,12 +38,12 @@ std::string KRPointLight::getElementName() { void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { - if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT) { - // Render light flare on transparency pass - } + KRLight::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); + + if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { // Lights are rendered on the second pass of the deferred renderer - + KRMat4 projectionMatrix = pCamera->getProjectionMatrix(); KRVector3 light_position = getLocalTranslation(); @@ -58,6 +58,7 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolu KRMat4 matModelToView = viewMatrix * m_modelMatrix; matModelToView.transpose(); matModelToView.invert(); + KRMat4 matModelToView2 = KRMat4() * m_modelMatrix * viewMatrix; @@ -140,7 +141,6 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolu } } - KRNode::render(pCamera, pContext, frustrumVolume, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); } void KRPointLight::generateMesh() { diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index d404dd6..1f91aa4 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -52,33 +52,36 @@ KRScene::~KRScene() { void KRScene::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { - if(cShadowBuffers > 0 && renderPass != KRNode::RENDER_PASS_SHADOWMAP) { - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } + if(renderPass != KRNode::RENDER_PASS_SHADOWMAP) { - if(cShadowBuffers > 1 && renderPass != KRNode::RENDER_PASS_SHADOWMAP) { - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if(cShadowBuffers > 0) { + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + if(cShadowBuffers > 1) { + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + if(cShadowBuffers > 2) { + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } } - - if(cShadowBuffers > 2 && renderPass != KRNode::RENDER_PASS_SHADOWMAP) { - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, shadowDepthTextures[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - + KRVector3 forward_render_light_direction = lightDirection; KRDirectionalLight *directional_light = getFirstDirectionalLight(); if(directional_light) { diff --git a/KREngine/KREngine/Classes/KRShader.cpp b/KREngine/KREngine/Classes/KRShader.cpp index eaa4b10..34e4395 100644 --- a/KREngine/KREngine/Classes/KRShader.cpp +++ b/KREngine/KREngine/Classes/KRShader.cpp @@ -113,6 +113,7 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc m_uniforms[KRENGINE_UNIFORM_LIGHT_INTENSITY] = glGetUniformLocation(m_iProgram, "light_intensity"); m_uniforms[KRENGINE_UNIFORM_LIGHT_DECAY_START] = glGetUniformLocation(m_iProgram, "light_decay_start"); m_uniforms[KRENGINE_UNIFORM_LIGHT_CUTOFF] = glGetUniformLocation(m_iProgram, "light_cutoff"); + m_uniforms[KRENGINE_UNIFORM_FLARE_SIZE] = glGetUniformLocation(m_iProgram, "flare_size"); diff --git a/KREngine/KREngine/Classes/KRShader.h b/KREngine/KREngine/Classes/KRShader.h index 71119c6..0ccace8 100644 --- a/KREngine/KREngine/Classes/KRShader.h +++ b/KREngine/KREngine/Classes/KRShader.h @@ -84,6 +84,7 @@ public: KRENGINE_UNIFORM_LIGHT_DECAY_START, KRENGINE_UNIFORM_LIGHT_CUTOFF, KRENGINE_UNIFORM_LIGHT_INTENSITY, + KRENGINE_UNIFORM_FLARE_SIZE, KRENGINE_UNIFORM_MVP, diff --git a/KREngine/KREngine/Shaders/flare.fsh b/KREngine/KREngine/Shaders/flare.fsh new file mode 100644 index 0000000..aa8d43b --- /dev/null +++ b/KREngine/KREngine/Shaders/flare.fsh @@ -0,0 +1,37 @@ +// +// flare.fsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 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 +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +varying mediump vec2 texCoord; +uniform sampler2D diffuseTexture; + +void main() { + gl_FragColor = vec4(vec3(texture2D(diffuseTexture, texCoord)), 1.0); +} \ No newline at end of file diff --git a/KREngine/KREngine/Shaders/flare.vsh b/KREngine/KREngine/Shaders/flare.vsh new file mode 100644 index 0000000..785bf5e --- /dev/null +++ b/KREngine/KREngine/Shaders/flare.vsh @@ -0,0 +1,42 @@ +// +// flare.vsh +// KREngine +// +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 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 +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +attribute mediump vec2 vertex_uv; +uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices +uniform mediump vec4 viewport; +uniform mediump float flare_size; + +varying mediump vec2 texCoord; + +void main() { + texCoord = vertex_uv; + gl_Position = mvp_matrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(vertex_uv.x * viewport.w / viewport.z * 2.0 - 1.0, vertex_uv.y * 2.0 - 1.0, 0.0, 0.0) * flare_size; +} diff --git a/objview/KRObjView.xcodeproj/project.pbxproj b/objview/KRObjView.xcodeproj/project.pbxproj index b12a3ac..4ff3e82 100644 --- a/objview/KRObjView.xcodeproj/project.pbxproj +++ b/objview/KRObjView.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ E46FED3013C9A49F009F5814 /* ObjectShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2413C9A488009F5814 /* ObjectShader.fsh */; }; E46FED3113C9A49F009F5814 /* ObjectShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2513C9A488009F5814 /* ObjectShader.vsh */; }; E46FED3213C9A49F009F5814 /* PostShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2613C9A488009F5814 /* PostShader.vsh */; }; + E4769DF3158A7915004B83AC /* flare.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF1158A7915004B83AC /* flare.fsh */; }; + E4769DF4158A7915004B83AC /* flare.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4769DF2158A7915004B83AC /* flare.vsh */; }; E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */; }; E4A9DEC615412906009DF363 /* light_point.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; }; E4A9DEC715412923009DF363 /* light_point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC2154128F0009DF363 /* light_point.fsh */; }; @@ -69,6 +71,8 @@ E46FED2413C9A488009F5814 /* ObjectShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = ObjectShader.fsh; path = ../KREngine/KREngine/Shaders/ObjectShader.fsh; sourceTree = ""; }; E46FED2513C9A488009F5814 /* ObjectShader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; lineEnding = 0; name = ObjectShader.vsh; path = ../KREngine/KREngine/Shaders/ObjectShader.vsh; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.glsl; }; E46FED2613C9A488009F5814 /* PostShader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = PostShader.vsh; path = ../KREngine/KREngine/Shaders/PostShader.vsh; sourceTree = ""; }; + E4769DF1158A7915004B83AC /* flare.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = flare.fsh; path = ../KREngine/KREngine/Shaders/flare.fsh; sourceTree = ""; }; + E4769DF2158A7915004B83AC /* flare.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = flare.vsh; path = ../KREngine/KREngine/Shaders/flare.vsh; sourceTree = ""; }; E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "iPad/MainWindow-iPad.xib"; sourceTree = ""; }; E4A9DEC2154128F0009DF363 /* light_point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.fsh; path = ../KREngine/KREngine/Shaders/light_point.fsh; sourceTree = ""; }; E4A9DEC515412906009DF363 /* light_point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.vsh; path = ../KREngine/KREngine/Shaders/light_point.vsh; sourceTree = ""; }; @@ -187,6 +191,8 @@ E46FED2013C9A472009F5814 /* Shaders */ = { isa = PBXGroup; children = ( + E4769DF1158A7915004B83AC /* flare.fsh */, + E4769DF2158A7915004B83AC /* flare.vsh */, E4A9DEC2154128F0009DF363 /* light_point.fsh */, E4A9DEC515412906009DF363 /* light_point.vsh */, E4FF48C01538FBF0002053FC /* light_directional.fsh */, @@ -270,6 +276,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + E4769DF3158A7915004B83AC /* flare.fsh in Resources */, + E4769DF4158A7915004B83AC /* flare.vsh in Resources */, E4A9DEC715412923009DF363 /* light_point.fsh in Resources */, E4A9DEC815412923009DF363 /* light_point.vsh in Resources */, E46FED2D13C9A49F009F5814 /* ShadowShader.vsh in Resources */,