diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 08d8a53..30853e2 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -296,6 +296,7 @@ E4BBBB961512A46700F43B5B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; E4BBBB981512A47500F43B5B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; }; E4BBBB9A1512A48200F43B5B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + E4CE184815FEEDA200F80870 /* font.pvr */ = {isa = PBXFileReference; lastKnownFileType = file; name = font.pvr; path = Shaders/font.pvr; sourceTree = ""; }; E4D133B91538F7480070068C /* light_directional.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.fsh; path = Shaders/light_directional.fsh; sourceTree = ""; }; E4D133BB1538F7560070068C /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.vsh; path = Shaders/light_directional.vsh; sourceTree = ""; }; E4F711A41512BB56007EE923 /* libfbxsdk-2012.2-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfbxsdk-2012.2-static.a"; path = "../../../../../../../../Applications/Autodesk/FBXSDK20122/lib/gcc4/ub/libfbxsdk-2012.2-static.a"; sourceTree = ""; }; @@ -547,12 +548,12 @@ E491016613C99B9E0098455B /* KREngine */ = { isa = PBXGroup; children = ( + E4CE184615FEED6800F80870 /* Standard Assets */, E491016E13C99BAE0098455B /* Classes */, E4924C2415EE95E700B965C6 /* KROctree.cpp */, E4924C2515EE95E800B965C6 /* KROctree.h */, E4924C2915EE96AA00B965C6 /* KROctreeNode.cpp */, E4924C2A15EE96AA00B965C6 /* KROctreeNode.h */, - E45772E313C99F160037BEEA /* Shaders */, E491016713C99B9E0098455B /* Supporting Files */, ); path = KREngine; @@ -627,6 +628,15 @@ name = "OSX Frameworks"; sourceTree = ""; }; + E4CE184615FEED6800F80870 /* Standard Assets */ = { + isa = PBXGroup; + children = ( + E4CE184815FEEDA200F80870 /* font.pvr */, + E45772E313C99F160037BEEA /* Shaders */, + ); + name = "Standard Assets"; + sourceTree = ""; + }; E4F9753815362A5200FD60B2 /* 3rdparty */ = { isa = PBXGroup; children = ( diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index 9cc8288..6957a20 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -416,6 +416,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD glDepthMask(GL_TRUE); + fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i Kbyte\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024); } diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index 873c1b6..3af9c1c 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -122,7 +122,7 @@ double const PI = 3.141592653589793f; NSFileManager* fileManager = [NSFileManager defaultManager]; NSString *bundle_directory = [[NSBundle mainBundle] bundlePath]; for (NSString* fileName in [fileManager contentsOfDirectoryAtPath: bundle_directory error:nil]) { - if([fileName hasSuffix: @".vsh"] || [fileName hasSuffix: @".fsh"]) { + if([fileName hasSuffix: @".vsh"] || [fileName hasSuffix: @".fsh"] || [fileName isEqualToString:@"font.pvr"]) { NSString* path = [NSString stringWithFormat:@"%@/%@", bundle_directory, fileName]; _context->loadResource([path UTF8String]); } diff --git a/KREngine/KREngine/Classes/KRModelManager.cpp b/KREngine/KREngine/Classes/KRModelManager.cpp index 2346db4..b9731ee 100644 --- a/KREngine/KREngine/Classes/KRModelManager.cpp +++ b/KREngine/KREngine/Classes/KRModelManager.cpp @@ -36,6 +36,7 @@ KRModelManager::KRModelManager(KRContext &context) : KRContextObject(context) { m_currentVBO.handle = 0; m_currentVBO.data = NULL; + m_vboMemUsed = 0; } KRModelManager::~KRModelManager() { @@ -74,20 +75,23 @@ void KRModelManager::bindVBO(const GLvoid *data, GLsizeiptr size) { assert(m_currentVBO.size == size); glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.handle); } else { + m_vboMemUsed += size; - while(m_vbos.size() >= KRENGINE_MAX_VBO_HANDLES) { + while(m_vbos.size() >= KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed >= KRENGINE_MAX_VBO_MEM) { // TODO - This should maintain a max size limit for VBO's rather than a limit on the number of VBO's. As meshes are split to multiple small VBO's, this is not too bad, but still not optimial. std::map::iterator first_itr = m_vbos.begin(); vbo_info_type firstVBO = first_itr->second; glDeleteBuffers(1, &firstVBO.handle); + m_vboMemUsed -= firstVBO.size; m_vbos.erase(first_itr); - fprintf(stderr, "VBO Swapping..."); + fprintf(stderr, "VBO Swapping...\n"); } m_currentVBO.handle = -1; glGenBuffers(1, &m_currentVBO.handle); glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.handle); glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + m_currentVBO.size = size; m_currentVBO.data = data; @@ -96,3 +100,7 @@ void KRModelManager::bindVBO(const GLvoid *data, GLsizeiptr size) { } } +long KRModelManager::getMemUsed() +{ + return m_vboMemUsed; +} diff --git a/KREngine/KREngine/Classes/KRModelManager.h b/KREngine/KREngine/Classes/KRModelManager.h index 8eaeb59..b7aa9cd 100644 --- a/KREngine/KREngine/Classes/KRModelManager.h +++ b/KREngine/KREngine/Classes/KRModelManager.h @@ -32,7 +32,8 @@ #ifndef KRMODELMANAGER_H #define KRMODELMANAGER_H -#define KRENGINE_MAX_VBO_HANDLES 50 +#define KRENGINE_MAX_VBO_HANDLES 1000 +#define KRENGINE_MAX_VBO_MEM 100000000 #import "KREngine-common.h" #import "KRContextObject.h" @@ -59,6 +60,7 @@ public: void bindVBO(const GLvoid *data, GLsizeiptr size); + long getMemUsed(); private: std::map m_models; @@ -69,6 +71,7 @@ private: const GLvoid *data; } vbo_info_type; + long m_vboMemUsed; vbo_info_type m_currentVBO; std::map m_vbos; diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index 5ae3dc3..59bb531 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -274,7 +274,6 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock { data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely tinyxml2::XMLDocument doc; - fprintf(stderr, "Scene Content: %s\n", data->getStart()); doc.Parse((char *)data->getStart()); KRScene *new_scene = new KRScene(context, name); diff --git a/KREngine/KREngine/Classes/KRTexture.cpp b/KREngine/KREngine/Classes/KRTexture.cpp index ff3c64b..4658750 100644 --- a/KREngine/KREngine/Classes/KRTexture.cpp +++ b/KREngine/KREngine/Classes/KRTexture.cpp @@ -77,7 +77,8 @@ KRTexture::KRTexture(KRDataBlock *data, KRTextureManager *manager) { } KRTexture::~KRTexture() { - releaseHandle(); + long textureMemFreed = 0; + releaseHandle(textureMemFreed); delete m_pData; } @@ -205,10 +206,14 @@ bool KRTexture::createGLTexture() { return true; } -GLuint KRTexture::getHandle() { +GLuint KRTexture::getHandle(long &textureMemUsed) { if(m_iName == 0) { if(!createGLTexture()) { - createGLTexture(); // FINDME - HACK! The first texture fails with 0x501 return code but loads on second try + if(createGLTexture()) { // FINDME - HACK! The first texture fails with 0x501 return code but loads on second try + textureMemUsed += getMemSize(); + } + } else { + textureMemUsed += getMemSize(); } createGLTexture(); @@ -216,9 +221,14 @@ GLuint KRTexture::getHandle() { return m_iName; } -void KRTexture::releaseHandle() { +void KRTexture::releaseHandle(long &textureMemUsed) { if(m_iName != 0) { + textureMemUsed -= getMemSize(); glDeleteTextures(1, &m_iName); m_iName = 0; } } + +long KRTexture::getMemSize() { + return m_pData->getSize(); // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory +} diff --git a/KREngine/KREngine/Classes/KRTexture.h b/KREngine/KREngine/Classes/KRTexture.h index 16e1e03..21e69ae 100644 --- a/KREngine/KREngine/Classes/KRTexture.h +++ b/KREngine/KREngine/Classes/KRTexture.h @@ -49,8 +49,10 @@ public: ~KRTexture(); bool createGLTexture(); - GLuint getHandle(); - void releaseHandle(); + GLuint getHandle(long &textureMemUsed); + void releaseHandle(long &textureMemUsed); + + long getMemSize(); private: @@ -72,6 +74,7 @@ private: bool load(); KRTextureManager *m_pManager; + }; #endif diff --git a/KREngine/KREngine/Classes/KRTextureManager.cpp b/KREngine/KREngine/Classes/KRTextureManager.cpp index ba7f9cb..9782302 100644 --- a/KREngine/KREngine/Classes/KRTextureManager.cpp +++ b/KREngine/KREngine/Classes/KRTextureManager.cpp @@ -33,6 +33,7 @@ #include KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) { + m_textureMemUsed = 0; for(int iTexture=0; iTexturegetHandle()); + glBindTexture(GL_TEXTURE_2D, pTexture->getHandle(m_textureMemUsed)); // TODO - These texture parameters should be assigned by the material or texture parameters glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -91,6 +92,7 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { } if(m_activeTextures[iTextureUnit] != NULL) { KRTexture *unloadedTexture = m_activeTextures[iTextureUnit]; + m_activeTextures[iTextureUnit] = NULL; bool bActive = false; for(int iTexture=0; iTexture < KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { if(m_activeTextures[iTexture] == unloadedTexture) { @@ -101,10 +103,10 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { // Only return a texture to the cache when the last texture unit referencing it is re-assigned to a different texture if(m_textureCache.find(unloadedTexture) == m_textureCache.end()) { m_textureCache.insert(unloadedTexture); - while(m_textureCache.size() > KRENGINE_MAX_TEXTURE_HANDLES) { + while(m_textureCache.size() > KRENGINE_MAX_TEXTURE_HANDLES || m_textureMemUsed > KRENGINE_MAX_TEXTURE_MEM) { // Keep texture size within limits KRTexture *droppedTexture = (*m_textureCache.begin()); - droppedTexture->releaseHandle(); + droppedTexture->releaseHandle(m_textureMemUsed); m_textureCache.erase(droppedTexture); fprintf(stderr, "Texture Swapping...\n"); } @@ -115,3 +117,7 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture) { } } +long KRTextureManager::getMemUsed() { + return m_textureMemUsed; +} + diff --git a/KREngine/KREngine/Classes/KRTextureManager.h b/KREngine/KREngine/Classes/KRTextureManager.h index 0f929e0..be5c593 100644 --- a/KREngine/KREngine/Classes/KRTextureManager.h +++ b/KREngine/KREngine/Classes/KRTextureManager.h @@ -30,7 +30,8 @@ // #define KRENGINE_MAX_TEXTURE_UNITS 8 -#define KRENGINE_MAX_TEXTURE_HANDLES 20 +#define KRENGINE_MAX_TEXTURE_HANDLES 1000 +#define KRENGINE_MAX_TEXTURE_MEM 100000000 #ifndef KRTEXTUREMANAGER_H #define KRTEXTUREMANAGER_H @@ -58,11 +59,15 @@ public: KRTexture *getTexture(const char *szFile); + long getMemUsed(); + private: std::map m_textures; KRTexture *m_activeTextures[KRENGINE_MAX_TEXTURE_UNITS]; std::set m_textureCache; + + long m_textureMemUsed; }; #endif diff --git a/KREngine/KREngine/Shaders/font.pvr b/KREngine/KREngine/Shaders/font.pvr new file mode 100644 index 0000000..7d91f4e Binary files /dev/null and b/KREngine/KREngine/Shaders/font.pvr differ diff --git a/objview/KRObjView.xcodeproj/project.pbxproj b/objview/KRObjView.xcodeproj/project.pbxproj index befdd65..5d9cc3c 100644 --- a/objview/KRObjView.xcodeproj/project.pbxproj +++ b/objview/KRObjView.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */; }; E4A9DEC715412923009DF363 /* light_point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC2154128F0009DF363 /* light_point.fsh */; }; E4A9DEC815412923009DF363 /* light_point.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; }; + E4CE184A15FEEE8500F80870 /* font.pvr in Resources */ = {isa = PBXBuildFile; fileRef = E4CE184915FEEE8500F80870 /* font.pvr */; }; E4FF48C51538FBF8002053FC /* light_directional.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4FF48C01538FBF0002053FC /* light_directional.fsh */; }; E4FF48C61538FBFC002053FC /* light_directional.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4FF48C11538FBF0002053FC /* light_directional.vsh */; }; /* End PBXBuildFile section */ @@ -84,6 +85,7 @@ 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 = ""; }; + E4CE184915FEEE8500F80870 /* font.pvr */ = {isa = PBXFileReference; lastKnownFileType = file; name = font.pvr; path = ../KREngine/KREngine/Shaders/font.pvr; sourceTree = ""; }; E4FF48C01538FBF0002053FC /* light_directional.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.fsh; path = ../KREngine/KREngine/Shaders/light_directional.fsh; sourceTree = ""; }; E4FF48C11538FBF0002053FC /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.vsh; path = ../KREngine/KREngine/Shaders/light_directional.vsh; sourceTree = ""; }; /* End PBXFileReference section */ @@ -180,6 +182,7 @@ E400687C1373AB6400B3D28B /* Assets */ = { isa = PBXGroup; children = ( + E4CE184915FEEE8500F80870 /* font.pvr */, E46FED2013C9A472009F5814 /* Shaders */, ); name = Assets; @@ -308,6 +311,7 @@ E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */, E40611D714E4E98B0065996A /* README.txt in Resources */, E40611D814E4E98B0065996A /* release_notes.txt in Resources */, + E4CE184A15FEEE8500F80870 /* font.pvr in Resources */, ); runOnlyForDeploymentPostprocessing = 0; };