diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 571b6ce..6ddf2ea 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -33,6 +33,8 @@ E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; }; E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; }; E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = E460292516681CFE00261BB9 /* KRTextureAnimated.h */; }; + E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E460292716681D1000261BB9 /* KRTextureAnimated.cpp */; }; E461A152152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; }; E461A153152E54B500F2044A /* KRLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A151152E54B500F2044A /* KRLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; E461A156152E54F800F2044A /* KRLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E461A155152E54F700F2044A /* KRLight.cpp */; }; @@ -237,6 +239,8 @@ E45AC0411641DE6D00DC3C3B /* debug_font.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = debug_font.fsh; path = Shaders/debug_font.fsh; sourceTree = ""; }; E45AC0461643451200DC3C3B /* dust_particle.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = dust_particle.fsh; path = Shaders/dust_particle.fsh; sourceTree = ""; }; E45AC0491643452000DC3C3B /* dust_particle.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = dust_particle.vsh; path = Shaders/dust_particle.vsh; sourceTree = ""; }; + E460292516681CFE00261BB9 /* KRTextureAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRTextureAnimated.h; path = Classes/KRTextureAnimated.h; sourceTree = ""; }; + E460292716681D1000261BB9 /* KRTextureAnimated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KRTextureAnimated.cpp; path = Classes/KRTextureAnimated.cpp; sourceTree = ""; }; E461A151152E54B500F2044A /* KRLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KRLight.h; path = Classes/KRLight.h; sourceTree = ""; }; E461A155152E54F700F2044A /* KRLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRLight.cpp; path = Classes/KRLight.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E461A157152E555400F2044A /* KRPointLight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRPointLight.h; path = Classes/KRPointLight.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; @@ -526,6 +530,8 @@ E4CA10E81637BD2B005D9400 /* KRTexturePVR.cpp */, E4CA10EB1637BD47005D9400 /* KRTextureTGA.h */, E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */, + E460292516681CFE00261BB9 /* KRTextureAnimated.h */, + E460292716681D1000261BB9 /* KRTextureAnimated.cpp */, ); name = Texture; sourceTree = ""; @@ -754,6 +760,7 @@ E4CA11741639CBD6005D9400 /* KRViewport.h in Headers */, E4324BA416444C0D0043185B /* KRParticleSystem.h in Headers */, E4324BAB16444DEF0043185B /* KRParticleSystemNewtonian.h in Headers */, + E460292616681CFF00261BB9 /* KRTextureAnimated.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -933,6 +940,7 @@ E4CA11781639CC90005D9400 /* KRViewport.cpp in Sources */, E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, + E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index a89e876..a7e6c01 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -87,12 +87,16 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) { e->QueryFloatAttribute("rotate_z", &z); m_localRotation = KRVector3(x,y,z) / 180.0 * M_PI; // Convert degrees to radians + m_modelMatrixValid = false; + for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { KRNode *child_node = KRNode::LoadXML(getScene(), child_element); if(child_node) { addChild(child_node); } } + + } void KRNode::setLocalTranslation(const KRVector3 &v) { @@ -224,7 +228,7 @@ const KRMat4 &KRNode::getModelMatrix() // if(m_parentNode) { // m_modelMatrix *= m_parentNode->getModelMatrix(); // } - +// m_modelMatrixValid = true; } diff --git a/KREngine/KREngine/Classes/KRShaderManager.cpp b/KREngine/KREngine/Classes/KRShaderManager.cpp index 36a56c6..4808ad2 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.cpp +++ b/KREngine/KREngine/Classes/KRShaderManager.cpp @@ -180,7 +180,7 @@ bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, co { if(pShader) { bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; - if(!bSameShader) { + if(!bSameShader || true) { // FINDME, HACK. Need to update logic to detect appropriate times to bind a new shader strcpy(m_szCurrentShaderKey, pShader->getKey()); #if TARGET_OS_IPHONE return pShader->bind(camera, viewport, matModel, lights, renderPass); diff --git a/KREngine/KREngine/Classes/KRTexture.cpp b/KREngine/KREngine/Classes/KRTexture.cpp index 8162776..c3ec1e7 100644 --- a/KREngine/KREngine/Classes/KRTexture.cpp +++ b/KREngine/KREngine/Classes/KRTexture.cpp @@ -38,6 +38,11 @@ long KRTexture::getMemSize() { return m_textureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory } +long KRTexture::getReferencedMemSize() { + // Return the amount of memory used by other textures referenced by this texture (for cube maps and animated textures) + return 0; +} + void KRTexture::resize(int max_dim) { if(max_dim == 0) { @@ -46,7 +51,7 @@ void KRTexture::resize(int max_dim) int target_dim = max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim); - int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize(); + int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize(); if(requiredMemoryDelta) { // Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory) @@ -103,7 +108,7 @@ long KRTexture::getThroughputRequiredForResize(int max_dim) if(target_dim != m_current_lod_max_dim) { int requiredMemory = getMemRequiredForSize(target_dim); - int requiredMemoryDelta = requiredMemory - getMemSize(); + int requiredMemoryDelta = requiredMemory - getMemSize() - getReferencedMemSize(); if(requiredMemoryDelta == 0) { // Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory) @@ -121,4 +126,9 @@ long KRTexture::getLastFrameUsed() return m_last_frame_used; } +bool KRTexture::isAnimated() +{ + return false; +} + diff --git a/KREngine/KREngine/Classes/KRTexture.h b/KREngine/KREngine/Classes/KRTexture.h index 9acd3df..130bbd1 100644 --- a/KREngine/KREngine/Classes/KRTexture.h +++ b/KREngine/KREngine/Classes/KRTexture.h @@ -48,6 +48,7 @@ public: virtual void bind() = 0; void releaseHandle(); long getMemSize(); + virtual long getReferencedMemSize(); virtual long getMemRequiredForSize(int max_dim) = 0; virtual long getThroughputRequiredForResize(int max_dim); @@ -56,6 +57,7 @@ public: long getLastFrameUsed(); virtual void resetPoolExpiry(); + virtual bool isAnimated(); protected: virtual bool createGLTexture(int lod_max_dim) = 0; diff --git a/KREngine/KREngine/Classes/KRTexture2D.cpp b/KREngine/KREngine/Classes/KRTexture2D.cpp index 849547e..1c0edda 100644 --- a/KREngine/KREngine/Classes/KRTexture2D.cpp +++ b/KREngine/KREngine/Classes/KRTexture2D.cpp @@ -75,7 +75,7 @@ bool KRTexture2D::createGLTexture(int lod_max_dim) { return true; } -void KRTexture2D::bind() { +void KRTexture2D::bind() { GLuint handle = getHandle(); GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle)); diff --git a/KREngine/KREngine/Classes/KRTextureAnimated.cpp b/KREngine/KREngine/Classes/KRTextureAnimated.cpp new file mode 100644 index 0000000..3308e3b --- /dev/null +++ b/KREngine/KREngine/Classes/KRTextureAnimated.cpp @@ -0,0 +1,140 @@ +// +// KRTextureAnimated.cpp +// 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. +// + +#import +#include "KRTextureAnimated.h" +#include "KRTexture2D.h" +#include "KRContext.h" + +KRTextureAnimated::KRTextureAnimated(KRContext &context, std::string name) : KRTexture(context) +{ + // Format of name: + // animate:texturebasename,xx,yy + // Where - texturebasename is a prefix for the other textures + // - xx is the number of frames + // - yy is the framerate + + // TODO - Add error handling for mal-formatted animated texture formats + int first_comma_pos = name.find(","); + int second_comma_pos = name.find(",", first_comma_pos + 1); + + + m_texture_base_name = name.substr(8, first_comma_pos - 9); + m_frame_count = atoi(name.substr(first_comma_pos+1, second_comma_pos - first_comma_pos -1).c_str()); + m_frame_rate = atof(name.substr(second_comma_pos+1).c_str()); + + m_max_lod_max_dim = 2048; + m_min_lod_max_dim = 64; + + for(int i=0; igetMaxMipMap() < m_max_lod_max_dim) m_max_lod_max_dim = frame_texture->getMaxMipMap(); + if(frame_texture->getMinMipMap() > m_min_lod_max_dim) m_min_lod_max_dim = frame_texture->getMinMipMap(); + } + } +} + +std::string KRTextureAnimated::textureNameForFrame(int frame) +{ + char szFrameNumber[10]; + sprintf(szFrameNumber, "%i", frame); + return m_texture_base_name + szFrameNumber; +} + +KRTexture2D *KRTextureAnimated::textureForFrame(int frame) +{ + return (KRTexture2D *)getContext().getTextureManager()->getTexture(textureNameForFrame(frame).c_str()); +} + +KRTextureAnimated::~KRTextureAnimated() +{ + +} + +bool KRTextureAnimated::createGLTexture(int lod_max_dim) +{ + return true; +} + +long KRTextureAnimated::getMemRequiredForSize(int max_dim) +{ + int target_dim = max_dim; + if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; + + long memoryRequired = 0; + for(int i=0; igetMemRequiredForSize(target_dim); + } + } + return memoryRequired; +} + + +void KRTextureAnimated::resetPoolExpiry() +{ + KRTexture::resetPoolExpiry(); + for(int i=0; iresetPoolExpiry(); // Ensure that frames of animated textures do not expire from the texture pool prematurely, as they are referenced indirectly + } + } +} + +void KRTextureAnimated::bind() +{ + int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); + KRTexture2D *frame_texture = textureForFrame(frame_number); + if(frame_texture) { + frame_texture->bind(); + } +} + +long KRTextureAnimated::getReferencedMemSize() +{ + long referenced_mem = 0; + for(int i=0; igetMemSize(); + } + } + return referenced_mem; +} + +bool KRTextureAnimated::isAnimated() +{ + return true; +} + diff --git a/KREngine/KREngine/Classes/KRTextureAnimated.h b/KREngine/KREngine/Classes/KRTextureAnimated.h new file mode 100644 index 0000000..0eca8ce --- /dev/null +++ b/KREngine/KREngine/Classes/KRTextureAnimated.h @@ -0,0 +1,63 @@ +// +// KRTextureAnimated.h +// 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. +// + +#ifndef KRTEXTUREANIMATED_H +#define KRTEXTUREANIMATED_H + +#include "KRTexture.h" +#include "KRTexture2D.h" + +class KRTextureAnimated : public KRTexture { +public: + KRTextureAnimated(KRContext &context, std::string name); + virtual ~KRTextureAnimated(); + + virtual void bind(); + virtual long getMemRequiredForSize(int max_dim); + virtual void resetPoolExpiry(); + + virtual long getReferencedMemSize(); + + virtual bool isAnimated(); + +private: + virtual bool createGLTexture(int lod_max_dim); + + float m_frame_rate; + int m_frame_count; + + std::string m_texture_base_name; + std::string textureNameForFrame(int frame); + KRTexture2D *textureForFrame(int frame); +}; + + +#endif /* defined(KRTEXTURECUBE_H) */ diff --git a/KREngine/KREngine/Classes/KRTextureManager.cpp b/KREngine/KREngine/Classes/KRTextureManager.cpp index 7e3ace2..23bc21d 100644 --- a/KREngine/KREngine/Classes/KRTextureManager.cpp +++ b/KREngine/KREngine/Classes/KRTextureManager.cpp @@ -35,6 +35,7 @@ #include "KRTexturePVR.h" #include "KRTextureTGA.h" #include "KRTextureCube.h" +#include "KRTextureAnimated.h" #include "KRContext.h" #include @@ -99,18 +100,28 @@ KRTexture *KRTextureManager::getTexture(const char *szName) { map::iterator itr = m_textures.find(lowerName); if(itr == m_textures.end()) { - // Not found - //fprintf(stderr, "ERROR: Texture not found: %s\n", szName); - return NULL; + if(lowerName.substr(8).compare("animate:") == 0) { + // This is an animated texture, create KRTextureAnimated's on-demand + KRTextureAnimated *pTexture = new KRTextureAnimated(getContext(), lowerName); + m_textures[lowerName] = pTexture; + return pTexture; + } else { + // Not found + //fprintf(stderr, "ERROR: Texture not found: %s\n", szName); + return NULL; + } } else { return (*itr).second; } - } void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { - - if(m_boundTextures[iTextureUnit] != pTexture) { + bool is_animated = false; + if(pTexture) { + if(pTexture->isAnimated()) is_animated = true; + } + + if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { GLDEBUG(glActiveTexture(GL_TEXTURE0 + iTextureUnit)); if(pTexture != NULL) { m_poolTextures.erase(pTexture);