Merged async_streaming into nfb

--HG--
branch : nfb
This commit is contained in:
2013-11-16 16:19:18 -08:00
57 changed files with 1666 additions and 669 deletions

View File

@@ -73,6 +73,18 @@
E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; }; E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; };
E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (); }; }; E43B0AD815DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (); }; };
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; };
E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; };
E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; };
E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; };
E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; };
E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; };
E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; };
E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; };
E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; };
E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; };
E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; };
E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; };
E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; }; E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; };
E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; }; E44F38241683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (); }; };
E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; E44F38251683B23000399B5D /* KRRenderSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = E44F38231683B22C00399B5D /* KRRenderSettings.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -109,6 +121,10 @@
E461A176152E5C5600F2044A /* KRPointLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A157152E555400F2044A /* KRPointLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; E461A176152E5C5600F2044A /* KRPointLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A157152E555400F2044A /* KRPointLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
E461A177152E5C6600F2044A /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; }; E461A177152E5C6600F2044A /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; };
E461A17A152E5C9100F2044A /* KRMat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017713C99BDC0098455B /* KRMat4.cpp */; }; E461A17A152E5C9100F2044A /* KRMat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017713C99BDC0098455B /* KRMat4.cpp */; };
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; };
E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; };
E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; };
E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; };
E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; }; E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; };
E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; }; E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; };
E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; }; E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; };
@@ -419,6 +435,12 @@
E437849716C488360037FD43 /* hrtf_kemar.krbundle */ = {isa = PBXFileReference; lastKnownFileType = file; path = hrtf_kemar.krbundle; sourceTree = "<group>"; }; E437849716C488360037FD43 /* hrtf_kemar.krbundle */ = {isa = PBXFileReference; lastKnownFileType = file; path = hrtf_kemar.krbundle; sourceTree = "<group>"; };
E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRContextObject.cpp; sourceTree = "<group>"; }; E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRContextObject.cpp; sourceTree = "<group>"; };
E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; }; E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; };
E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = "<group>"; };
E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = "<group>"; };
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRTextureStreamer.mm; sourceTree = "<group>"; };
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = "<group>"; };
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRMeshStreamer.mm; sourceTree = "<group>"; };
E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = "<group>"; };
E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; }; E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; };
E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; }; E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; };
E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E450273716E0491D00FDEC5C /* KRReverbZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRReverbZone.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -438,6 +460,8 @@
E461A15E152E565700F2044A /* KRDirectionalLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRDirectionalLight.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E461A15E152E565700F2044A /* KRDirectionalLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRDirectionalLight.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E461A164152E56C000F2044A /* KRSpotLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSpotLight.cpp; sourceTree = "<group>"; }; E461A164152E56C000F2044A /* KRSpotLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSpotLight.cpp; sourceTree = "<group>"; };
E461A167152E570500F2044A /* KRSpotLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRSpotLight.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E461A167152E570500F2044A /* KRSpotLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRSpotLight.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E468447D17FFDF51001F1FA1 /* KRLocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLocator.cpp; sourceTree = "<group>"; };
E468447E17FFDF51001F1FA1 /* KRLocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLocator.h; sourceTree = "<group>"; };
E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = "<group>"; }; E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = "<group>"; };
E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = "<group>"; }; E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = "<group>"; };
E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = "<group>"; }; E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = "<group>"; };
@@ -878,6 +902,8 @@
E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */, E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */,
E460292516681CFE00261BB9 /* KRTextureAnimated.h */, E460292516681CFE00261BB9 /* KRTextureAnimated.h */,
E460292716681D1000261BB9 /* KRTextureAnimated.cpp */, E460292716681D1000261BB9 /* KRTextureAnimated.cpp */,
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */,
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */,
); );
name = Texture; name = Texture;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -893,6 +919,8 @@
E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */, E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */,
E4C454B1167BC04B003586CD /* KRMeshSphere.h */, E4C454B1167BC04B003586CD /* KRMeshSphere.h */,
E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */, E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */,
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */,
E43F70FE1824E73100136169 /* KRMeshStreamer.h */,
); );
name = Mesh; name = Mesh;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -971,6 +999,10 @@
E480BE6B1671C653004EC8AD /* KRBone.cpp */, E480BE6B1671C653004EC8AD /* KRBone.cpp */,
E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */, E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */,
E4AE635C1704FB0A00B460CD /* KRLODGroup.h */, E4AE635C1704FB0A00B460CD /* KRLODGroup.h */,
E468447D17FFDF51001F1FA1 /* KRLocator.cpp */,
E468447E17FFDF51001F1FA1 /* KRLocator.h */,
E43F70DA181B20E300136169 /* KRLODSet.cpp */,
E43F70DB181B20E400136169 /* KRLODSet.h */,
); );
name = "Scene Graph Nodes"; name = "Scene Graph Nodes";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1180,6 +1212,7 @@
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E43F70DE181B20E400136169 /* KRLODSet.h in Headers */,
E491019513C99BDC0098455B /* KRMaterial.h in Headers */, E491019513C99BDC0098455B /* KRMaterial.h in Headers */,
E491019C13C99BDC0098455B /* KRMaterialManager.h in Headers */, E491019C13C99BDC0098455B /* KRMaterialManager.h in Headers */,
E491019D13C99BDC0098455B /* KRTextureManager.h in Headers */, E491019D13C99BDC0098455B /* KRTextureManager.h in Headers */,
@@ -1198,6 +1231,8 @@
E461A152152E54B500F2044A /* KRLight.h in Headers */, E461A152152E54B500F2044A /* KRLight.h in Headers */,
E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */, E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */,
E461A168152E570700F2044A /* KRSpotLight.h in Headers */, E461A168152E570700F2044A /* KRSpotLight.h in Headers */,
E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */,
E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */,
E4F975321536220900FD60B2 /* KRNode.h in Headers */, E4F975321536220900FD60B2 /* KRNode.h in Headers */,
E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */, E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */,
E48C696F15374F5B00232E28 /* KRContext.h in Headers */, E48C696F15374F5B00232E28 /* KRContext.h in Headers */,
@@ -1246,6 +1281,7 @@
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */, E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */,
E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */, E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */,
E48CF944173453990005EBBB /* KRFloat.h in Headers */, E48CF944173453990005EBBB /* KRFloat.h in Headers */,
E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */,
E45134B81746A4A300443C21 /* KRBehavior.h in Headers */, E45134B81746A4A300443C21 /* KRBehavior.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -1257,6 +1293,7 @@
E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */, E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */,
E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */, E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */,
E461A177152E5C6600F2044A /* KRMat4.h in Headers */, E461A177152E5C6600F2044A /* KRMat4.h in Headers */,
E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */,
E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */, E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */,
E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */, E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */,
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */, E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */,
@@ -1272,7 +1309,9 @@
E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */, E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */,
E4F975501536333500FD60B2 /* KRMesh.h in Headers */, E4F975501536333500FD60B2 /* KRMesh.h in Headers */,
E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */, E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */,
E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */,
E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */, E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */,
E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */,
E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */, E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */,
E4D133661537685A0070068C /* KRShader.h in Headers */, E4D133661537685A0070068C /* KRShader.h in Headers */,
E461A153152E54B500F2044A /* KRLight.h in Headers */, E461A153152E54B500F2044A /* KRLight.h in Headers */,
@@ -1289,6 +1328,7 @@
E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */, E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */,
E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */, E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */,
E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */, E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */,
E43F70DF181B20E400136169 /* KRLODSet.h in Headers */,
E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */, E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */,
E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */, E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */,
E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */, E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */,
@@ -1536,14 +1576,17 @@
E491019A13C99BDC0098455B /* KRMeshManager.cpp in Sources */, E491019A13C99BDC0098455B /* KRMeshManager.cpp in Sources */,
E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */, E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */,
E47C25A913F4F6DD00FF4370 /* KRShader.cpp in Sources */, E47C25A913F4F6DD00FF4370 /* KRShader.cpp in Sources */,
E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */,
E414BAE51435558900A668C4 /* KRModel.cpp in Sources */, E414BAE51435558900A668C4 /* KRModel.cpp in Sources */,
E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */, E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */,
E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */, E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */,
E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */,
E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */,
E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */,
E461A156152E54F800F2044A /* KRLight.cpp in Sources */, E461A156152E54F800F2044A /* KRLight.cpp in Sources */,
E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */, E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */,
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */, E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */,
E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */, E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */,
E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */, E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */,
@@ -1566,6 +1609,7 @@
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */, E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */,
E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */, E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */,
E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */, E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */,
E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */, E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */,
E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */, E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */,
E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */, E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */,
@@ -1607,6 +1651,7 @@
E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */, E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */,
E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */, E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */,
E4BBBB8E1512A40300F43B5B /* krengine_osx.mm in Sources */, E4BBBB8E1512A40300F43B5B /* krengine_osx.mm in Sources */,
E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
E497B947151BA99500D3DC67 /* KRVector2.cpp in Sources */, E497B947151BA99500D3DC67 /* KRVector2.cpp in Sources */,
E497B94E151BCF2500D3DC67 /* KRResource.cpp in Sources */, E497B94E151BCF2500D3DC67 /* KRResource.cpp in Sources */,
E497B951151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */, E497B951151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
@@ -1636,6 +1681,8 @@
E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */, E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */,
E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */, E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */,
E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */, E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */,
E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */,
E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */,
E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */, E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */,
E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */, E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */,
E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */, E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */,
@@ -1651,6 +1698,7 @@
E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */, E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */,
E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */, E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */,
E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */, E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */,
E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */, E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */,
E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */, E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */,
E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */, E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */,
@@ -1701,21 +1749,22 @@
E491016913C99B9E0098455B /* Debug */ = { E491016913C99B9E0098455B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = c11;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42; GCC_UNROLL_LOOPS = YES;
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
/usr/local/include, /usr/local/include,
"$(SRCROOT)/3rdparty/**", "$(SRCROOT)/3rdparty/**",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; LLVM_VECTORIZE_LOOPS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6; MACOSX_DEPLOYMENT_TARGET = 10.6;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
@@ -1725,18 +1774,20 @@
E491016A13C99B9E0098455B /* Release */ = { E491016A13C99B9E0098455B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = c11;
GCC_VERSION = com.apple.compilers.llvmgcc42; GCC_OPTIMIZATION_LEVEL = fast;
GCC_UNROLL_LOOPS = YES;
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
/usr/local/include, /usr/local/include,
"$(SRCROOT)/3rdparty/**", "$(SRCROOT)/3rdparty/**",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; LLVM_VECTORIZE_LOOPS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6; MACOSX_DEPLOYMENT_TARGET = 10.6;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
@@ -1747,6 +1798,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES; ALWAYS_SEARCH_USER_PATHS = YES;
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
DSTROOT = /tmp/KREngine.dst; DSTROOT = /tmp/KREngine.dst;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -1754,7 +1806,7 @@
); );
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
@@ -1762,7 +1814,6 @@
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = kraken; PRODUCT_NAME = kraken;
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
@@ -1771,6 +1822,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES; ALWAYS_SEARCH_USER_PATHS = YES;
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
DSTROOT = /tmp/KREngine.dst; DSTROOT = /tmp/KREngine.dst;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -1778,7 +1830,7 @@
); );
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch"; GCC_PREFIX_HEADER = "kraken_ios/Kraken-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"", "\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
@@ -1786,7 +1838,6 @@
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = kraken; PRODUCT_NAME = kraken;
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders"; SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;

View File

@@ -85,9 +85,10 @@ bool KRAnimation::save(KRDataBlock &data) {
KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data) KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data)
{ {
data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely std::string xml_string = data->getString();
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
doc.Parse((char *)data->getStart()); doc.Parse(xml_string.c_str());
KRAnimation *new_animation = new KRAnimation(context, name); KRAnimation *new_animation = new KRAnimation(context, name);
tinyxml2::XMLElement *animation_node = doc.RootElement(); tinyxml2::XMLElement *animation_node = doc.RootElement();
@@ -296,3 +297,31 @@ void KRAnimation::deleteCurves()
} }
} }
void KRAnimation::_lockData()
{
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
KRAnimationAttribute *attribute = *attribute_itr;
KRAnimationCurve *curve = attribute->getCurve();
if(curve) {
curve->_lockData();
}
}
}
}
void KRAnimation::_unlockData()
{
for(unordered_map<std::string, KRAnimationLayer *>::iterator layer_itr = m_layers.begin(); layer_itr != m_layers.end(); layer_itr++) {
KRAnimationLayer *layer = (*layer_itr).second;
for(std::vector<KRAnimationAttribute *>::iterator attribute_itr = layer->getAttributes().begin(); attribute_itr != layer->getAttributes().end(); attribute_itr++) {
KRAnimationAttribute *attribute = *attribute_itr;
KRAnimationCurve *curve = attribute->getCurve();
if(curve) {
curve->_unlockData();
}
}
}
}

View File

@@ -71,6 +71,9 @@ public:
KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true); KRAnimation *split(const std::string &name, float start_time, float duration, bool strip_unchanging_attributes = true, bool clone_curves = true);
void deleteCurves(); void deleteCurves();
void _lockData();
void _unlockData();
private: private:
unordered_map<std::string, KRAnimationLayer *> m_layers; unordered_map<std::string, KRAnimationLayer *> m_layers;
bool m_auto_play; bool m_auto_play;

View File

@@ -37,11 +37,13 @@ KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name)
{ {
m_pData = new KRDataBlock(); m_pData = new KRDataBlock();
m_pData->expand(sizeof(animation_curve_header)); m_pData->expand(sizeof(animation_curve_header));
m_pData->lock();
animation_curve_header *header = (animation_curve_header *)m_pData->getStart(); animation_curve_header *header = (animation_curve_header *)m_pData->getStart();
strcpy(header->szTag, "KRCURVE1.0 "); strcpy(header->szTag, "KRCURVE1.0 ");
header->frame_rate = 30.0f; header->frame_rate = 30.0f;
header->frame_start = 0; header->frame_start = 0;
header->frame_count = 0; header->frame_count = 0;
m_pData->unlock();
} }
KRAnimationCurve::~KRAnimationCurve() KRAnimationCurve::~KRAnimationCurve()
@@ -84,11 +86,16 @@ KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &
int KRAnimationCurve::getFrameCount() int KRAnimationCurve::getFrameCount()
{ {
return ((animation_curve_header *)m_pData->getStart())->frame_count; m_pData->lock();
int frame_count = ((animation_curve_header *)m_pData->getStart())->frame_count;
m_pData->unlock();
return frame_count;
} }
void KRAnimationCurve::setFrameCount(int frame_count) void KRAnimationCurve::setFrameCount(int frame_count)
{ {
m_pData->lock();
int prev_frame_count = getFrameCount(); int prev_frame_count = getFrameCount();
if(frame_count != prev_frame_count) { if(frame_count != prev_frame_count) {
float fill_value = 0.0f; float fill_value = 0.0f;
@@ -102,30 +109,42 @@ void KRAnimationCurve::setFrameCount(int frame_count)
} }
((animation_curve_header *)m_pData->getStart())->frame_count = frame_count; ((animation_curve_header *)m_pData->getStart())->frame_count = frame_count;
} }
m_pData->unlock();
} }
float KRAnimationCurve::getFrameRate() float KRAnimationCurve::getFrameRate()
{ {
return ((animation_curve_header *)m_pData->getStart())->frame_rate; m_pData->lock();
float frame_rate =((animation_curve_header *)m_pData->getStart())->frame_rate;
m_pData->unlock();
return frame_rate;
} }
void KRAnimationCurve::setFrameRate(float frame_rate) void KRAnimationCurve::setFrameRate(float frame_rate)
{ {
m_pData->lock();
((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate; ((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate;
m_pData->unlock();
} }
int KRAnimationCurve::getFrameStart() int KRAnimationCurve::getFrameStart()
{ {
return ((animation_curve_header *)m_pData->getStart())->frame_start; m_pData->lock();
int frame_start = ((animation_curve_header *)m_pData->getStart())->frame_start;
m_pData->unlock();
return frame_start;
} }
void KRAnimationCurve::setFrameStart(int frame_number) void KRAnimationCurve::setFrameStart(int frame_number)
{ {
m_pData->lock();
((animation_curve_header *)m_pData->getStart())->frame_start = frame_number; ((animation_curve_header *)m_pData->getStart())->frame_start = frame_number;
m_pData->unlock();
} }
float KRAnimationCurve::getValue(int frame_number) float KRAnimationCurve::getValue(int frame_number)
{ {
m_pData->lock();
//printf("frame_number: %i\n", frame_number); //printf("frame_number: %i\n", frame_number);
int clamped_frame = frame_number - getFrameStart(); int clamped_frame = frame_number - getFrameStart();
if(clamped_frame < 0) { if(clamped_frame < 0) {
@@ -134,43 +153,56 @@ float KRAnimationCurve::getValue(int frame_number)
clamped_frame = getFrameCount()-1; clamped_frame = getFrameCount()-1;
} }
float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header));
return frame_data[clamped_frame]; float v = frame_data[clamped_frame];
m_pData->unlock();
return v;
} }
void KRAnimationCurve::setValue(int frame_number, float value) void KRAnimationCurve::setValue(int frame_number, float value)
{ {
m_pData->lock();
int clamped_frame = frame_number - getFrameStart(); int clamped_frame = frame_number - getFrameStart();
if(clamped_frame >= 0 && clamped_frame < getFrameCount()) { if(clamped_frame >= 0 && clamped_frame < getFrameCount()) {
float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header)); float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header));
frame_data[clamped_frame] = value; frame_data[clamped_frame] = value;
} }
m_pData->unlock();
} }
float KRAnimationCurve::getValue(float local_time) float KRAnimationCurve::getValue(float local_time)
{ {
// TODO - Need to add interpolation for time values between frames. // TODO - Need to add interpolation for time values between frames.
// Must consider looping animations when determining which two frames to interpolate between. // Must consider looping animations when determining which two frames to interpolate between.
return getValue((int)(local_time * getFrameRate())); m_pData->lock();
float v = getValue((int)(local_time * getFrameRate()));
m_pData->unlock();
return v;
} }
bool KRAnimationCurve::valueChanges(float start_time, float duration) bool KRAnimationCurve::valueChanges(float start_time, float duration)
{ {
return valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate())); m_pData->lock();
bool c = valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate()));
m_pData->unlock();
return c;
} }
bool KRAnimationCurve::valueChanges(int start_frame, int frame_count) bool KRAnimationCurve::valueChanges(int start_frame, int frame_count)
{ {
m_pData->lock();
float first_value = getValue(start_frame); float first_value = getValue(start_frame);
bool change_found = false;
// Range of frames is not inclusive of last frame // Range of frames is not inclusive of last frame
for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count; frame_number++) { for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count && !change_found; frame_number++) {
if(getValue(frame_number) != first_value) { if(getValue(frame_number) != first_value) {
return true; change_found = true;
} }
} }
return false; m_pData->unlock();
return change_found;
} }
KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration) KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration)
@@ -185,12 +217,24 @@ KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_fra
new_curve->setFrameRate(getFrameRate()); new_curve->setFrameRate(getFrameRate());
new_curve->setFrameStart(start_frame); new_curve->setFrameStart(start_frame);
new_curve->setFrameCount(frame_count); new_curve->setFrameCount(frame_count);
new_curve->m_pData->lock();
// Range of frames is not inclusive of last frame // Range of frames is not inclusive of last frame
for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) { for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) {
new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here? new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here?
} }
new_curve->m_pData->unlock();
getContext().getAnimationCurveManager()->addAnimationCurve(new_curve); getContext().getAnimationCurveManager()->addAnimationCurve(new_curve);
return new_curve; return new_curve;
} }
void KRAnimationCurve::_lockData()
{
m_pData->lock();
}
void KRAnimationCurve::_unlockData()
{
m_pData->unlock();
}

View File

@@ -67,6 +67,9 @@ public:
KRAnimationCurve *split(const std::string &name, float start_time, float duration); KRAnimationCurve *split(const std::string &name, float start_time, float duration);
KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count); KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count);
void _lockData();
void _unlockData();
private: private:
KRDataBlock *m_pData; KRDataBlock *m_pData;

View File

@@ -38,6 +38,11 @@ KRAnimationManager::KRAnimationManager(KRContext &context) : KRContextObject(con
} }
KRAnimationManager::~KRAnimationManager() { KRAnimationManager::~KRAnimationManager() {
for(std::set<KRAnimation *>::iterator itr = m_activeAnimations.begin(); itr != m_activeAnimations.end(); itr++) {
KRAnimation *animation = *itr;
animation->_unlockData();
}
for(unordered_map<std::string, KRAnimation *>::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){ for(unordered_map<std::string, KRAnimation *>::iterator itr = m_animations.begin(); itr != m_animations.end(); ++itr){
delete (*itr).second; delete (*itr).second;
} }
@@ -52,11 +57,13 @@ void KRAnimationManager::startFrame(float deltaTime)
// Add playing animations to the active animations list // Add playing animations to the active animations list
if(active_animations_itr == m_activeAnimations.end()) { if(active_animations_itr == m_activeAnimations.end()) {
m_activeAnimations.insert(animation); m_activeAnimations.insert(animation);
animation->_lockData();
} }
} else { } else {
// Remove stopped animations from the active animations list // Remove stopped animations from the active animations list
if(active_animations_itr != m_activeAnimations.end()) { if(active_animations_itr != m_activeAnimations.end()) {
m_activeAnimations.erase(active_animations_itr); m_activeAnimations.erase(active_animations_itr);
animation->_unlockData();
} }
} }
} }

View File

@@ -214,8 +214,8 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
uint64_t end_time = mach_absolute_time(); uint64_t end_time = mach_absolute_time();
uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds // uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds
uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100; // uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100;
// fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size()); // fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size());
} }
@@ -1364,14 +1364,14 @@ KRDataBlock *KRAudioManager::getBufferData(int size)
data = new KRDataBlock(); data = new KRDataBlock();
data->expand(size); data->expand(size);
} }
data->lock();
return data; return data;
} }
void KRAudioManager::recycleBufferData(KRDataBlock *data) void KRAudioManager::recycleBufferData(KRDataBlock *data)
{ {
if(data != NULL) { if(data != NULL) {
data->unlock();
if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) { if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) {
m_bufferPoolIdle.push_back(data); m_bufferPoolIdle.push_back(data);
} else { } else {

View File

@@ -198,7 +198,7 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc
KRAudioSample *sound = (KRAudioSample *)inClientData; KRAudioSample *sound = (KRAudioSample *)inClientData;
UInt32 max_count = sound->m_pData->getSize() - inPosition; UInt32 max_count = sound->m_pData->getSize() - inPosition;
*actualCount = requestCount < max_count ? requestCount : max_count; *actualCount = requestCount < max_count ? requestCount : max_count;
memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount); sound->m_pData->copy(buffer, inPosition, *actualCount);
return noErr; return noErr;
} }
@@ -231,6 +231,7 @@ void KRAudioSample::openFile()
{ {
// AudioFileInitializeWithCallbacks // AudioFileInitializeWithCallbacks
if(m_fileRef == NULL) { if(m_fileRef == NULL) {
// Temp variables // Temp variables
UInt32 propertySize; UInt32 propertySize;

View File

@@ -53,35 +53,18 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
{ {
m_pData = pData; m_pData = pData;
unsigned char *pFile = (unsigned char *)m_pData->getStart(); __int64_t file_pos = 0;
while(pFile < m_pData->getEnd() ) { while(file_pos < m_pData->getSize()) {
tar_header_type *file_header = (tar_header_type *)pFile; tar_header_type file_header;
size_t file_size = strtol(file_header->file_size, NULL, 8); m_pData->copy(&file_header, file_pos, sizeof(file_header));
pFile += 512; // Skip past the header to the file contents size_t file_size = strtol(file_header.file_size, NULL, 8);
file_pos += 512; // Skip past the header to the file contents
if(file_header->file_name[0] != '\0' && file_header->file_name[0] != '.') { if(file_header.file_name[0] != '\0' && file_header.file_name[0] != '.') {
// We ignore the last two records in the tar file, which are zero'ed out tar_header structures // We ignore the last two records in the tar file, which are zero'ed out tar_header structures
KRDataBlock *pFileData = new KRDataBlock(); KRDataBlock *pFileData = pData->getSubBlock(file_pos, file_size);
if(pFileData->load(pFile, file_size)) { context.loadResource(file_header.file_name, pFileData);
context.loadResource(file_header->file_name, pFileData);
} else {
delete pFileData;
assert(false);
} }
} file_pos += RoundUpSize(file_size);
// Advance past the end of the file
/*
if((file_size & 0x01ff) == 0) {
// file size is a multiple of 512 bytes, we can just add it
pFile += file_size;
} else {
// We would not be on a 512 byte boundary, round up to the next one
pFile += (file_size + 0x0200) - (file_size & 0x1ff);
}
*/
pFile += RoundUpSize(file_size);
} }
} }
@@ -90,7 +73,9 @@ KRBundle::KRBundle(KRContext &context, std::string name) : KRResource(context, n
// Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it. // Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it.
m_pData = new KRDataBlock(); m_pData = new KRDataBlock();
m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2); m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2);
m_pData->lock();
memset(m_pData->getStart(), 0, m_pData->getSize()); memset(m_pData->getStart(), 0, m_pData->getSize());
m_pData->unlock();
} }
size_t KRBundle::RoundUpSize(size_t s) size_t KRBundle::RoundUpSize(size_t s)
@@ -142,6 +127,8 @@ void KRBundle::append(KRResource &resource)
m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here
m_pData->lock();
// Get location of file header // Get location of file header
tar_header_type *file_header = (tar_header_type *)((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE); tar_header_type *file_header = (tar_header_type *)((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE);
@@ -149,7 +136,9 @@ void KRBundle::append(KRResource &resource)
memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE); memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE);
// Copy resource data // Copy resource data
resource_data.lock();
memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize()); memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize());
resource_data.unlock();
// Zero out alignment padding and terminating set of file header blocks // Zero out alignment padding and terminating set of file header blocks
memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size); memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size);
@@ -172,4 +161,6 @@ void KRBundle::append(KRResource &resource)
check_sum += byte_ptr[i]; check_sum += byte_ptr[i];
} }
sprintf(file_header->checksum, "%07o", check_sum); sprintf(file_header->checksum, "%07o", check_sum);
m_pData->unlock();
} }

View File

@@ -54,14 +54,9 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) {
volumetricLightAccumulationBuffer = 0; volumetricLightAccumulationBuffer = 0;
volumetricLightAccumulationTexture = 0; volumetricLightAccumulationTexture = 0;
m_frame_times_filled = 0; m_frame_times_filled = 0;
m_debug_text_vertices = NULL;
} }
KRCamera::~KRCamera() { KRCamera::~KRCamera() {
if(m_debug_text_vertices) {
delete m_debug_text_vertices;
}
destroyBuffers(); destroyBuffers();
} }
@@ -315,7 +310,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
// Render a full screen quad // Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
} }
@@ -472,7 +467,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, 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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true);
for(unordered_map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { for(unordered_map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
KRMat4 matModel = KRMat4(); KRMat4 matModel = KRMat4();
matModel.scale((*itr).first.size() * 0.5f); matModel.scale((*itr).first.size() * 0.5f);
@@ -704,7 +699,7 @@ void KRCamera::renderPost()
} }
// Update attribute values. // Update attribute values.
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -726,7 +721,7 @@ void KRCamera::renderPost()
// viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
// getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
// m_pContext->getTextureManager()->selectTexture(1, NULL); // m_pContext->getTextureManager()->selectTexture(1, NULL);
// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); // m_pContext->getModelManager()->bindVBO(KRENGINE_VBO_2D_SQUARE_INDICES, KRENGINE_VBO_2D_SQUARE_VERTEXES, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
// m_pContext->getTextureManager()->_setActiveTexture(0); // m_pContext->getTextureManager()->_setActiveTexture(0);
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
//#if GL_EXT_shadow_samplers //#if GL_EXT_shadow_samplers
@@ -745,7 +740,7 @@ void KRCamera::renderPost()
if(m_debug_text_vertices) { if(m_debug_text_vertices.getSize()) {
m_pContext->getModelManager()->releaseVBO(m_debug_text_vertices); m_pContext->getModelManager()->releaseVBO(m_debug_text_vertices);
} }
@@ -791,12 +786,13 @@ void KRCamera::renderPost()
const int DEBUG_TEXT_COLUMNS = 256; const int DEBUG_TEXT_COLUMNS = 256;
const int DEBUG_TEXT_ROWS = 128; const int DEBUG_TEXT_ROWS = 128;
if(m_debug_text_vertices == NULL) { if(m_debug_text_vertices.getSize() == 0) {
m_debug_text_vertices = new DebugTextVertexData[DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6]; m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6);
} }
int vertex_count = 0; int vertex_count = 0;
m_debug_text_vertices.lock();
DebugTextVertexData *vertex_data = (DebugTextVertexData *)m_debug_text_vertices.getStart();
pChar = szText; pChar = szText;
float dScaleX = 2.0 / (1024 / 16); float dScaleX = 2.0 / (1024 / 16);
@@ -824,47 +820,47 @@ void KRCamera::renderPost()
KRVector2 top_left_uv = KRVector2(dTexScale * iTexCol, dTexScale * iTexRow); KRVector2 top_left_uv = KRVector2(dTexScale * iTexCol, dTexScale * iTexRow);
KRVector2 bottom_right_uv = KRVector2(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale); KRVector2 bottom_right_uv = KRVector2(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale);
m_debug_text_vertices[vertex_count].x = top_left_pos.x; vertex_data[vertex_count].x = top_left_pos.x;
m_debug_text_vertices[vertex_count].y = top_left_pos.y; vertex_data[vertex_count].y = top_left_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = top_left_uv.x; vertex_data[vertex_count].u = top_left_uv.x;
m_debug_text_vertices[vertex_count].v = top_left_uv.y; vertex_data[vertex_count].v = top_left_uv.y;
vertex_count++; vertex_count++;
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; vertex_data[vertex_count].x = bottom_right_pos.x;
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; vertex_data[vertex_count].y = bottom_right_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; vertex_data[vertex_count].u = bottom_right_uv.x;
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; vertex_data[vertex_count].v = bottom_right_uv.y;
vertex_count++; vertex_count++;
m_debug_text_vertices[vertex_count].x = top_left_pos.x; vertex_data[vertex_count].x = top_left_pos.x;
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; vertex_data[vertex_count].y = bottom_right_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = top_left_uv.x; vertex_data[vertex_count].u = top_left_uv.x;
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; vertex_data[vertex_count].v = bottom_right_uv.y;
vertex_count++; vertex_count++;
m_debug_text_vertices[vertex_count].x = top_left_pos.x; vertex_data[vertex_count].x = top_left_pos.x;
m_debug_text_vertices[vertex_count].y = top_left_pos.y; vertex_data[vertex_count].y = top_left_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = top_left_uv.x; vertex_data[vertex_count].u = top_left_uv.x;
m_debug_text_vertices[vertex_count].v = top_left_uv.y; vertex_data[vertex_count].v = top_left_uv.y;
vertex_count++; vertex_count++;
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; vertex_data[vertex_count].x = bottom_right_pos.x;
m_debug_text_vertices[vertex_count].y = top_left_pos.y; vertex_data[vertex_count].y = top_left_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; vertex_data[vertex_count].u = bottom_right_uv.x;
m_debug_text_vertices[vertex_count].v = top_left_uv.y; vertex_data[vertex_count].v = top_left_uv.y;
vertex_count++; vertex_count++;
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; vertex_data[vertex_count].x = bottom_right_pos.x;
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; vertex_data[vertex_count].y = bottom_right_pos.y;
m_debug_text_vertices[vertex_count].z = 0.0f; vertex_data[vertex_count].z = 0.0f;
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; vertex_data[vertex_count].u = bottom_right_uv.x;
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; vertex_data[vertex_count].v = bottom_right_uv.y;
vertex_count++; vertex_count++;
} }
@@ -892,18 +888,20 @@ void KRCamera::renderPost()
m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"));
KRDataBlock index_data;
m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); //m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
m_pContext->getModelManager()->bindVBO(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count));
// Re-enable z-buffer write // Re-enable z-buffer write
GLDEBUG(glDepthMask(GL_TRUE)); GLDEBUG(glDepthMask(GL_TRUE));
m_debug_text_vertices.unlock();
} else { } else {
if(m_debug_text_vertices) { if(m_debug_text_vertices.getSize() > 0) {
delete m_debug_text_vertices; m_debug_text_vertices = KRDataBlock();
m_debug_text_vertices = NULL;
} }
} }
} }

View File

@@ -99,7 +99,7 @@ private:
GLfloat v; GLfloat v;
} DebugTextVertexData; } DebugTextVertexData;
DebugTextVertexData *m_debug_text_vertices; KRDataBlock m_debug_text_vertices;
// std::string getDebugText(); // std::string getDebugText();

View File

@@ -17,7 +17,6 @@ int KRContext::KRENGINE_MAX_SHADER_HANDLES;
int KRContext::KRENGINE_MAX_TEXTURE_HANDLES; int KRContext::KRENGINE_MAX_TEXTURE_HANDLES;
int KRContext::KRENGINE_MAX_TEXTURE_MEM; int KRContext::KRENGINE_MAX_TEXTURE_MEM;
int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX; int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX;
int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN;
int KRContext::KRENGINE_MAX_TEXTURE_DIM; int KRContext::KRENGINE_MAX_TEXTURE_DIM;
int KRContext::KRENGINE_MIN_TEXTURE_DIM; int KRContext::KRENGINE_MIN_TEXTURE_DIM;
int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT; int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT;
@@ -27,6 +26,7 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = {
}; };
KRContext::KRContext() { KRContext::KRContext() {
m_streamingEnabled = false;
mach_timebase_info(&m_timebase_info); mach_timebase_info(&m_timebase_info);
m_bDetectedExtensions = false; m_bDetectedExtensions = false;
@@ -43,7 +43,7 @@ KRContext::KRContext() {
m_pAnimationCurveManager = new KRAnimationCurveManager(*this); m_pAnimationCurveManager = new KRAnimationCurveManager(*this);
m_pSoundManager = new KRAudioManager(*this); m_pSoundManager = new KRAudioManager(*this);
m_pUnknownManager = new KRUnknownManager(*this); m_pUnknownManager = new KRUnknownManager(*this);
m_streamingEnabled = true;
} }
KRContext::~KRContext() { KRContext::~KRContext() {
@@ -271,3 +271,35 @@ long KRContext::getAbsoluteTimeMilliseconds()
return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow
} }
bool KRContext::getStreamingEnabled()
{
return m_streamingEnabled;
}
void KRContext::setStreamingEnabled(bool enable)
{
m_streamingEnabled = enable;
}
void KRContext::getMemoryStats(long &free_memory)
{
free_memory = 0;
#if TARGET_OS_IPHONE
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t pagesize = 0;
vm_statistics_data_t vm_stat;
int total_ram = 256 * 1024 * 1024;
if(host_page_size(host_port, &pagesize) != KERN_SUCCESS) {
fprintf(stderr, "ERROR: Could not get VM page size.\n");
} else if(host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
fprintf(stderr, "ERROR: Could not get VM stats.\n");
} else {
total_ram = (vm_stat.wire_count + vm_stat.active_count + vm_stat.inactive_count + vm_stat.free_count) * pagesize;
free_memory = vm_stat.free_count * pagesize;
}
#else
#error Unsupported Platform
#endif
}

View File

@@ -29,7 +29,6 @@ public:
static int KRENGINE_MAX_TEXTURE_HANDLES; static int KRENGINE_MAX_TEXTURE_HANDLES;
static int KRENGINE_MAX_TEXTURE_MEM; static int KRENGINE_MAX_TEXTURE_MEM;
static int KRENGINE_TARGET_TEXTURE_MEM_MAX; static int KRENGINE_TARGET_TEXTURE_MEM_MAX;
static int KRENGINE_TARGET_TEXTURE_MEM_MIN;
static int KRENGINE_MAX_TEXTURE_DIM; static int KRENGINE_MAX_TEXTURE_DIM;
static int KRENGINE_MIN_TEXTURE_DIM; static int KRENGINE_MIN_TEXTURE_DIM;
static int KRENGINE_MAX_TEXTURE_THROUGHPUT; static int KRENGINE_MAX_TEXTURE_THROUGHPUT;
@@ -73,6 +72,10 @@ public:
long getAbsoluteTimeMilliseconds(); long getAbsoluteTimeMilliseconds();
std::vector<KRResource *> getResources(); std::vector<KRResource *> getResources();
bool getStreamingEnabled();
void setStreamingEnabled(bool enable);
void getMemoryStats(long &free_memory);
private: private:
KRBundleManager *m_pBundleManager; KRBundleManager *m_pBundleManager;
@@ -93,6 +96,8 @@ private:
float m_absolute_time; float m_absolute_time;
mach_timebase_info_data_t m_timebase_info; mach_timebase_info_data_t m_timebase_info;
std::atomic<bool> m_streamingEnabled;
}; };
#endif #endif

View File

@@ -30,12 +30,40 @@
// //
#include "KRDataBlock.h" #include "KRDataBlock.h"
#include "KREngine-common.h"
#include "KRResource.h"
#include <errno.h>
int m_mapCount = 0;
size_t m_mapSize = 0;
size_t m_mapOverhead = 0;
KRDataBlock::KRDataBlock() { KRDataBlock::KRDataBlock() {
m_data = NULL; m_data = NULL;
m_data_size = 0; m_data_size = 0;
m_data_offset = 0;
m_fdPackFile = 0; m_fdPackFile = 0;
m_fileName = "";
m_mmapData = NULL;
m_fileOwnerDataBlock = NULL;
m_bMalloced = false; m_bMalloced = false;
m_lockCount = 0;
m_bReadOnly = false;
}
KRDataBlock::KRDataBlock(void *data, size_t size) {
m_data = NULL;
m_data_size = 0;
m_data_offset = 0;
m_fdPackFile = 0;
m_fileName = "";
m_mmapData = NULL;
m_fileOwnerDataBlock = NULL;
m_bMalloced = false;
m_lockCount = 0;
m_bReadOnly = false;
load(data, size);
} }
KRDataBlock::~KRDataBlock() { KRDataBlock::~KRDataBlock() {
@@ -45,10 +73,13 @@ KRDataBlock::~KRDataBlock() {
// Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use // Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use
void KRDataBlock::unload() void KRDataBlock::unload()
{ {
assert(m_lockCount == 0);
if(m_fdPackFile) { if(m_fdPackFile) {
// Memory mapped file // Memory mapped file
munmap(m_data, m_data_size); if(m_fileOwnerDataBlock == this) {
close(m_fdPackFile); close(m_fdPackFile);
}
} else if(m_data != NULL && m_bMalloced) { } else if(m_data != NULL && m_bMalloced) {
// Malloc'ed data // Malloc'ed data
free(m_data); free(m_data);
@@ -57,7 +88,12 @@ void KRDataBlock::unload()
m_bMalloced = false; m_bMalloced = false;
m_data = NULL; m_data = NULL;
m_data_size = 0; m_data_size = 0;
m_data_offset = 0;
m_fdPackFile = 0; m_fdPackFile = 0;
m_fileName = "";
m_mmapData = NULL;
m_fileOwnerDataBlock = NULL;
m_bReadOnly = false;
} }
// Encapsulate a pointer. Note - The pointer will not be free'ed // Encapsulate a pointer. Note - The pointer will not be free'ed
@@ -66,6 +102,8 @@ bool KRDataBlock::load(void *data, size_t size)
unload(); unload();
m_data = data; m_data = data;
m_data_size = size; m_data_size = size;
m_data_offset = 0;
m_bReadOnly = false;
return true; return true;
} }
@@ -76,16 +114,17 @@ bool KRDataBlock::load(const std::string &path)
unload(); unload();
struct stat statbuf; struct stat statbuf;
m_bReadOnly = true;
m_fdPackFile = open(path.c_str(), O_RDONLY); m_fdPackFile = open(path.c_str(), O_RDONLY);
if(m_fdPackFile >= 0) { if(m_fdPackFile >= 0) {
m_fileOwnerDataBlock = this;
m_fileName = KRResource::GetFileBase(path);
if(fstat(m_fdPackFile, &statbuf) >= 0) { if(fstat(m_fdPackFile, &statbuf) >= 0) {
if ((m_data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, m_fdPackFile, 0)) == (caddr_t) -1) {
} else {
m_data_size = statbuf.st_size; m_data_size = statbuf.st_size;
m_data_offset = 0;
success = true; success = true;
} }
} }
}
if(!success) { if(!success) {
// If anything failed, don't leave the object in an invalid state // If anything failed, don't leave the object in an invalid state
unload(); unload();
@@ -93,13 +132,33 @@ bool KRDataBlock::load(const std::string &path)
return success; return success;
} }
// Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object.
KRDataBlock *KRDataBlock::getSubBlock(int start, int length)
{
KRDataBlock *new_block = new KRDataBlock();
new_block->m_data_size = length;
if(m_fdPackFile) {
new_block->m_fdPackFile = m_fdPackFile;
new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock;
new_block->m_data_offset = start + m_data_offset;
} else if(m_bMalloced) {
new_block->m_data = (unsigned char *)m_data + start + m_data_offset;
}
new_block->m_bReadOnly = true;
return new_block;
}
// Return a pointer to the start of the data block // Return a pointer to the start of the data block
void *KRDataBlock::getStart() { void *KRDataBlock::getStart() {
assertLocked();
return m_data; return m_data;
} }
// Return a pointer to the byte after the end of the data block // Return a pointer to the byte after the end of the data block
void *KRDataBlock::getEnd() { void *KRDataBlock::getEnd() {
assertLocked();
return (unsigned char *)m_data + m_data_size; return (unsigned char *)m_data + m_data_size;
} }
@@ -111,28 +170,33 @@ size_t KRDataBlock::getSize() const {
// Expand the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed // Expand the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed
void KRDataBlock::expand(size_t size) void KRDataBlock::expand(size_t size)
{ {
if(m_data == NULL) { if(m_data == NULL && m_fdPackFile == 0) {
// Starting with an empty data block; allocate memory on the heap // Starting with an empty data block; allocate memory on the heap
m_data = malloc(size); m_data = malloc(size);
assert(m_data != NULL); assert(m_data != NULL);
m_data_size = size; m_data_size = size;
m_data_offset = 0;
m_bMalloced = true; m_bMalloced = true;
} else if(m_bMalloced) { } else if(m_bMalloced) {
// Starting with a malloc'ed data block; realloc it expand // Starting with a malloc'ed data block; realloc it expand
m_data = realloc(m_data, m_data_size + size); m_data = realloc(m_data, m_data_size + size);
m_data_size += size; m_data_size += size;
} else { } else {
// Starting with a mmap'ed data block; copy it to ram before expanding to avoid updating the original file until save() is called // Starting with a mmap'ed data block, an encapsulated pointer, or a sub-block; copy it to ram before expanding to avoid updating the original file until save() is called
// ... Or starting with a pointer reference, we must make our own copy and must not free the pointer // ... Or starting with a pointer reference, we must make our own copy and must not free the pointer
void *pNewData = malloc(m_data_size + size); void *pNewData = malloc(m_data_size + size);
assert(pNewData != NULL); assert(pNewData != NULL);
memcpy((unsigned char *)pNewData, m_data, m_data_size); // Copy exising data
// Copy exising data
copy(pNewData);
// Unload existing data allocation, which is now redundant // Unload existing data allocation, which is now redundant
size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it
unload(); unload();
m_bMalloced = true; m_bMalloced = true;
m_data = pNewData; m_data = pNewData;
m_data_size = new_size; m_data_size = new_size;
m_data_offset = 0;
} }
} }
@@ -142,12 +206,35 @@ void KRDataBlock::append(void *data, size_t size) {
expand(size); expand(size);
// Fill the new space with the data to append // Fill the new space with the data to append
lock();
memcpy((unsigned char *)m_data + m_data_size - size, data, size); memcpy((unsigned char *)m_data + m_data_size - size, data, size);
unlock();
}
// Copy the entire data block to the destination pointer
void KRDataBlock::copy(void *dest) {
copy(dest, 0, m_data_size);
}
// Copy a range of data to the destination pointer
void KRDataBlock::copy(void *dest, int start, int count) {
if(m_lockCount == 0 && m_fdPackFile != 0) {
// Optimization: If we haven't mmap'ed or malloced the data already, pread() it directly from the file into the buffer
ssize_t r = pread(m_fdPackFile, dest, count, start + m_data_offset);
assert(r != -1);
} else {
lock();
memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count);
unlock();
}
} }
// Append data to the end of the block, increasing the size of the block and making it read-write. // Append data to the end of the block, increasing the size of the block and making it read-write.
void KRDataBlock::append(KRDataBlock &data) { void KRDataBlock::append(KRDataBlock &data) {
data.lock();
append(data.getStart(), data.getSize()); append(data.getStart(), data.getSize());
data.unlock();
} }
// Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included // Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included
@@ -157,7 +244,7 @@ void KRDataBlock::append(const std::string &s)
append((void *)szText, strlen(szText)+1); append((void *)szText, strlen(szText)+1);
} }
// Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed // Save the data to a file.
bool KRDataBlock::save(const std::string& path) { bool KRDataBlock::save(const std::string& path) {
int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
if(fdNewFile == -1) { if(fdNewFile == -1) {
@@ -173,20 +260,16 @@ bool KRDataBlock::save(const std::string& path) {
close(fdNewFile); close(fdNewFile);
return false; return false;
} else if(m_data != NULL) { } else if(m_data != NULL) {
// Copy data to new file // Copy data to new file
memcpy(pNewData, m_data, m_data_size); copy(pNewData);
// Unload existing data allocation, which is now redundant // Unmap the new file
size_t new_size = m_data_size; // We need to store this, as unload() will reset it munmap(pNewData, m_data_size);
unload();
// Protect new mmap'ed memory // Close the new file
mprotect(pNewData, m_data_size, PROT_READ); close(fdNewFile);
// Switch pointer to use new mmap'ed memory
m_data_size = new_size;
m_fdPackFile = fdNewFile;
m_data = pNewData;
} }
return true; return true;
} }
@@ -198,5 +281,102 @@ std::string KRDataBlock::getString()
KRDataBlock b; KRDataBlock b;
b.append(*this); b.append(*this);
b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely
return std::string((char *)b.getStart()); b.lock();
std::string ret = std::string((char *)b.getStart());
b.unlock();
return ret;
}
// Lock the memory, forcing it to be loaded into a contiguous block of address space
void KRDataBlock::lock()
{
if(m_lockCount == 0) {
// Memory mapped file; ensure data is mapped to ram
if(m_fdPackFile) {
if(m_data_size < KRENGINE_MIN_MMAP) {
m_data = malloc(m_data_size);
assert(m_data != NULL);
copy(m_data);
} else {
//fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
// Round m_data_offset down to the next memory page, as required by mmap
size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1);
if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) {
int iError = errno;
switch(iError) {
case EACCES:
fprintf(stderr, "mmap failed with EACCES\n");
break;
case EBADF:
fprintf(stderr, "mmap failed with EBADF\n");
break;
case EMFILE:
fprintf(stderr, "mmap failed with EMFILE\n");
break;
case EINVAL:
fprintf(stderr, "mmap failed with EINVAL\n");
break;
case ENOMEM:
fprintf(stderr, "mmap failed with ENOMEM\n");
break;
case ENXIO:
fprintf(stderr, "mmap failed with ENXIO\n");
break;
case EOVERFLOW:
fprintf(stderr, "mmap failed with EOVERFLOW\n");
break;
default:
fprintf(stderr, "mmap failed with errno: %i\n", iError);
break;
}
assert(false); // mmap() failed.
}
m_mapCount++;
m_mapSize += m_data_size;
m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset;
fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead);
m_data = (unsigned char *)m_mmapData + alignment_offset;
}
}
}
m_lockCount++;
}
// Unlock the memory, releasing the address space for use by other allocations
void KRDataBlock::unlock()
{
// We expect that the data block was previously locked
assertLocked();
if(m_lockCount == 1) {
// Memory mapped file; ensure data is unmapped from ram
if(m_fdPackFile) {
if(m_data_size < KRENGINE_MIN_MMAP) {
free(m_data);
m_data = NULL;
} else {
//fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
munmap(m_mmapData, m_data_size);
m_data = NULL;
m_mmapData = NULL;
m_mapCount--;
m_mapSize -= m_data_size;
size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1);
m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset;
fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead);
}
}
}
m_lockCount--;
}
// Assert if not locked
void KRDataBlock::assertLocked()
{
assert(m_lockCount > 0);
} }

View File

@@ -34,9 +34,12 @@
#include "KREngine-common.h" #include "KREngine-common.h"
#define KRENGINE_MIN_MMAP 32768
class KRDataBlock { class KRDataBlock {
public: public:
KRDataBlock(); KRDataBlock();
KRDataBlock(void *data, size_t size);
~KRDataBlock(); ~KRDataBlock();
// Encapsulate a pointer. Note - The pointer will not be free'ed // Encapsulate a pointer. Note - The pointer will not be free'ed
@@ -45,9 +48,12 @@ public:
// Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called // Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called
bool load(const std::string &path); bool load(const std::string &path);
// Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed // Save the data to a file.
bool save(const std::string& path); bool save(const std::string& path);
// Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object.
KRDataBlock *getSubBlock(int start, int length);
// Append data to the end of the block, increasing the size of the block and making it read-write. // Append data to the end of the block, increasing the size of the block and making it read-write.
void append(void *data, size_t size); void append(void *data, size_t size);
@@ -74,15 +80,42 @@ public:
// Get the contents as a string // Get the contents as a string
std::string getString(); std::string getString();
// Copy the entire data block to the destination pointer
void copy(void *dest);
// Copy a range of data to the destination pointer
void copy(void *dest, int start, int count);
// Lock the memory, forcing it to be loaded into a contiguous block of address space
void lock();
// Unlock the memory, releasing the address space for use by other allocations
void unlock();
private: private:
void *m_data; void *m_data;
size_t m_data_size; size_t m_data_size;
size_t m_data_offset;
// For memory mapped objects: // For memory mapped objects:
int m_fdPackFile; int m_fdPackFile;
std::string m_fileName;
KRDataBlock *m_fileOwnerDataBlock;
void *m_mmapData;
// For malloc'ed objects: // For malloc'ed objects:
bool m_bMalloced; bool m_bMalloced;
// Lock refcount
int m_lockCount;
// Read-only allocation
bool m_bReadOnly;
// Assert if not locked
void assertLocked();
}; };
#endif #endif

View File

@@ -119,7 +119,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &
GLDEBUG(glDisable(GL_DEPTH_TEST)); GLDEBUG(glDisable(GL_DEPTH_TEST));
// Render a full screen quad // Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
} }
} }

View File

@@ -11,11 +11,10 @@
#ifndef KRENGINE_COMMON_H #ifndef KRENGINE_COMMON_H
#define KRENGINE_COMMON_H #define KRENGINE_COMMON_H
#define KRENGINE_MAX_TEXTURE_UNITS 8
float const PI = 3.141592653589793f; float const PI = 3.141592653589793f;
float const D2R = PI * 2 / 360; float const D2R = PI * 2 / 360;
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
#include <string> #include <string>
@@ -47,6 +46,9 @@ float const D2R = PI * 2 / 360;
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/signals2/mutex.hpp> #include <boost/signals2/mutex.hpp>
#include <atomic>
#include <thread>
#include "tinyxml2.h" #include "tinyxml2.h"
@@ -69,6 +71,12 @@ using std::queue;
#define KRAKEN_HAVE_BLAS 1 #define KRAKEN_HAVE_BLAS 1
#endif #endif
int KRAKEN_MEM_PAGE_SIZE = getpagesize();
#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1))
#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE)
#define KRENGINE_MAX_TEXTURE_UNITS 8
#if !defined(__i386__) && defined(__arm__) #if !defined(__i386__) && defined(__arm__)
#define KRAKEN_USE_ARM_NEON #define KRAKEN_USE_ARM_NEON

View File

@@ -101,7 +101,6 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_VBO_MEM = total_ram * 2 / 4; KRContext::KRENGINE_MAX_VBO_MEM = total_ram * 2 / 4;
KRContext::KRENGINE_MAX_TEXTURE_MEM = total_ram * 1 / 8; KRContext::KRENGINE_MAX_TEXTURE_MEM = total_ram * 1 / 8;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = KRContext::KRENGINE_MAX_TEXTURE_MEM * 3 / 4; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = KRContext::KRENGINE_MAX_TEXTURE_MEM * 3 / 4;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = KRContext::KRENGINE_MAX_TEXTURE_MEM / 2;
@@ -115,7 +114,6 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000 * 2; KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000 * 2;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000 * 2; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000 * 2;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 32000000 * 2;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000;
@@ -126,7 +124,6 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 64000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 32000000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 32000000;
@@ -139,7 +136,6 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000; KRContext::KRENGINE_MAX_TEXTURE_HANDLES = 10000;
KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000; KRContext::KRENGINE_MAX_TEXTURE_MEM = 512000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000; KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000;
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 256000000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048; KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64; KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000; KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000;
@@ -425,7 +421,7 @@ void kraken::set_debug_text(const std::string &print_text)
[self getAmbientIntensity], [self getAmbientIntensity],
[self getSunTemperature], [self getSunTemperature],
[self getSunIntensity], [self getSunIntensity],
_settings.dof_quality, static_cast<float>(_settings.dof_quality),
_settings.dof_depth, _settings.dof_depth,
_settings.dof_falloff, _settings.dof_falloff,
_settings.bEnableFlash ? 1.0f : 0.0f, _settings.bEnableFlash ? 1.0f : 0.0f,
@@ -445,26 +441,26 @@ void kraken::set_debug_text(const std::string &print_text)
_settings.bEnableDeferredLighting ? 1.0f : 0.0f, _settings.bEnableDeferredLighting ? 1.0f : 0.0f,
_settings.getPerspectiveNearZ(), _settings.getPerspectiveNearZ(),
_settings.getPerspectiveFarZ(), _settings.getPerspectiveFarZ(),
_settings.volumetric_environment_enable, static_cast<float>(_settings.volumetric_environment_enable),
5 - _settings.volumetric_environment_downsample, static_cast<float>(5 - _settings.volumetric_environment_downsample),
_settings.volumetric_environment_max_distance, _settings.volumetric_environment_max_distance,
_settings.volumetric_environment_quality, _settings.volumetric_environment_quality,
_settings.volumetric_environment_intensity, _settings.volumetric_environment_intensity,
_settings.fog_type, static_cast<float>(_settings.fog_type),
_settings.fog_near, _settings.fog_near,
_settings.fog_far, _settings.fog_far,
_settings.fog_density, _settings.fog_density,
_settings.fog_color.x, _settings.fog_color.x,
_settings.fog_color.y, _settings.fog_color.y,
_settings.fog_color.z, _settings.fog_color.z,
_settings.dust_particle_enable, static_cast<float>(_settings.dust_particle_enable),
_settings.dust_particle_intensity, _settings.dust_particle_intensity,
_settings.getLODBias(), _settings.getLODBias(),
_settings.getEnableRealtimeOcclusion(), static_cast<float>(_settings.getEnableRealtimeOcclusion()),
_settings.debug_display, _settings.debug_display,
_settings.siren_enable, static_cast<float>(_settings.siren_enable),
_settings.siren_enable_reverb, static_cast<float>(_settings.siren_enable_reverb),
_settings.siren_enable_hrtf, static_cast<float>(_settings.siren_enable_hrtf),
_settings.siren_reverb_max_length, _settings.siren_reverb_max_length,
_settings.max_anisotropy _settings.max_anisotropy
}; };

View File

@@ -11,7 +11,6 @@
#include "KRResource.h" #include "KRResource.h"
#include "KRNode.h" #include "KRNode.h"
#include "KRTexture.h"
class KRLODGroup : public KRNode { class KRLODGroup : public KRNode {
public: public:

View File

@@ -0,0 +1,35 @@
//
// KRLODSet.cpp
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#include "KRLODSet.h"
#include "KRContext.h"
KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name)
{
}
KRLODSet::~KRLODSet()
{
}
std::string KRLODSet::getElementName() {
return "lod_set";
}
tinyxml2::XMLElement *KRLODSet::saveXML( tinyxml2::XMLNode *parent)
{
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
return e;
}
void KRLODSet::loadXML(tinyxml2::XMLElement *e)
{
KRNode::loadXML(e);
}

View File

@@ -0,0 +1,26 @@
//
// KRLODSet
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#ifndef KRLODSET_H
#define KRLODSET_H
#include "KRResource.h"
#include "KRNode.h"
class KRLODSet : public KRNode {
public:
KRLODSet(KRScene &scene, std::string name);
virtual ~KRLODSet();
virtual std::string getElementName();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e);
};
#endif

View File

@@ -226,7 +226,8 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()));
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); KRDataBlock particle_index_data;
m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), particle_index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
} }
} }
@@ -266,7 +267,8 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing)); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing));
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f));
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); KRDataBlock index_data;
m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getVolumetricLightingVertexes(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
} }
@@ -333,7 +335,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize);
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
} }
} }

View File

@@ -0,0 +1,35 @@
//
// KRLocator.cpp
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#include "KRLocator.h"
#include "KRContext.h"
KRLocator::KRLocator(KRScene &scene, std::string name) : KRNode(scene, name)
{
}
KRLocator::~KRLocator()
{
}
std::string KRLocator::getElementName() {
return "locator";
}
tinyxml2::XMLElement *KRLocator::saveXML( tinyxml2::XMLNode *parent)
{
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
return e;
}
void KRLocator::loadXML(tinyxml2::XMLElement *e)
{
KRNode::loadXML(e);
}

View File

@@ -0,0 +1,27 @@
//
// KRLocator
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#ifndef KRLOCATOR_H
#define KRLOCATOR_H
#include "KRResource.h"
#include "KRNode.h"
#include "KRTexture.h"
class KRLocator : public KRNode {
public:
KRLocator(KRScene &scene, std::string name);
virtual ~KRLocator();
virtual std::string getElementName();
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e);
};
#endif

View File

@@ -87,7 +87,7 @@ float KRMat4::operator[](unsigned i) const {
} }
// Overload comparison operator // Overload comparison operator
bool KRMat4::operator==(const KRMat4 &m) { bool KRMat4::operator==(const KRMat4 &m) const {
return memcmp(c, m.c, sizeof(float) * 16) == 0; return memcmp(c, m.c, sizeof(float) * 16) == 0;
} }

View File

@@ -83,7 +83,7 @@ class KRMat4 {
KRMat4& operator=(const KRMat4 &m); KRMat4& operator=(const KRMat4 &m);
// Overload comparison operator // Overload comparison operator
bool operator==(const KRMat4 &m); bool operator==(const KRMat4 &m) const;
// Overload compound multiply operator // Overload compound multiply operator
KRMat4& operator*=(const KRMat4 &m); KRMat4& operator*=(const KRMat4 &m);

View File

@@ -100,7 +100,7 @@ void KRMaterialManager::add(KRMaterial *new_material) {
bool KRMaterialManager::load(const char *szName, KRDataBlock *data) { bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
KRMaterial *pMaterial = NULL; KRMaterial *pMaterial = NULL;
char szSymbol[16][256]; char szSymbol[16][256];
data->lock();
char *pScan = (char *)data->getStart(); char *pScan = (char *)data->getStart();
char *pEnd = (char *)data->getEnd(); char *pEnd = (char *)data->getEnd();
@@ -282,7 +282,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
} }
} }
data->unlock();
delete data; delete data;
return true; return true;
} }

View File

@@ -42,20 +42,23 @@
KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) { KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) {
m_hasTransparency = false;
m_materials.clear();
m_uniqueMaterials.clear();
m_pData = new KRDataBlock();
setName(name); setName(name);
m_hasTransparency = false;
m_pData = NULL;
m_pMetaData = NULL;
m_pIndexBaseData = NULL;
} }
KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRResource(context, name) { KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRResource(context, name) {
m_hasTransparency = false;
m_materials.clear();
m_uniqueMaterials.clear();
m_pData = new KRDataBlock();
setName(name); setName(name);
m_hasTransparency = false;
m_pData = NULL;
m_pMetaData = NULL;
m_pIndexBaseData = NULL;
loadPack(data); loadPack(data);
} }
@@ -103,8 +106,24 @@ int KRMesh::GetLODCoverage(const std::string &name)
KRMesh::~KRMesh() { KRMesh::~KRMesh() {
clearData(); releaseData();
if(m_pData) delete m_pData; }
void KRMesh::releaseData() {
if(m_pIndexBaseData) {
m_pIndexBaseData->unlock();
delete m_pIndexBaseData;
m_pIndexBaseData = NULL;
}
if(m_pMetaData) {
m_pMetaData->unlock();
delete m_pMetaData;
m_pMetaData = NULL;
}
if(m_pData) {
delete m_pData;
m_pData = NULL;
}
} }
std::string KRMesh::getExtension() { std::string KRMesh::getExtension() {
@@ -112,28 +131,36 @@ std::string KRMesh::getExtension() {
} }
bool KRMesh::save(const std::string& path) { bool KRMesh::save(const std::string& path) {
clearBuffers();
return m_pData->save(path); return m_pData->save(path);
} }
bool KRMesh::save(KRDataBlock &data) { bool KRMesh::save(KRDataBlock &data) {
clearBuffers();
data.append(*m_pData); data.append(*m_pData);
return true; return true;
} }
void KRMesh::loadPack(KRDataBlock *data) { void KRMesh::loadPack(KRDataBlock *data) {
clearData(); releaseData();
delete m_pData;
m_pData = data; m_pData = data;
pack_header ph;
m_pData->copy((void *)&ph, 0, sizeof(ph));
m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count);
m_pMetaData->lock();
m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8);
m_pIndexBaseData->lock();
m_minPoint = KRVector3(ph.minx, ph.miny, ph.minz);
m_maxPoint = KRVector3(ph.maxx, ph.maxy, ph.maxz);
updateAttributeOffsets(); updateAttributeOffsets();
pack_header *pHeader = getHeader();
m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz);
m_maxPoint = KRVector3(pHeader->maxx, pHeader->maxy, pHeader->maxz);
} }
void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) { void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_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_PARTICLE_OCCLUSION && 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) {
getSubmeshes(); getSubmeshes();
@@ -250,21 +277,21 @@ void KRMesh::getSubmeshes() {
} }
void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name) { void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name) {
//m_pData->lock();
getSubmeshes(); getSubmeshes();
Submesh *pSubmesh = m_submeshes[iSubmesh]; Submesh *pSubmesh = m_submeshes[iSubmesh];
int cVertexes = pSubmesh->vertex_count; int cVertexes = pSubmesh->vertex_count;
// fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes); // fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes);
unsigned char *pVertexData = getVertexData(); int vertex_data_offset = getVertexDataOffset();
int index_data_offset = getIndexDataOffset();
pack_header *pHeader = getHeader(); pack_header *pHeader = getHeader();
int32_t vertex_attrib_flags = pHeader->vertex_attrib_flags;
int32_t vertex_count = pHeader->vertex_count;
int vbo_index=0;
if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
__uint16_t *index_data = getIndexData();
int index_group = getSubmesh(iSubmesh)->index_group; int index_group = getSubmesh(iSubmesh)->index_group;
int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; int index_group_offset = getSubmesh(iSubmesh)->index_group_offset;
while(cVertexes > 0) { while(cVertexes > 0) {
@@ -272,7 +299,22 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st
int start_index_offset, start_vertex_offset, index_count, vertex_count; int start_index_offset, start_vertex_offset, index_count, vertex_count;
getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, pHeader->vertex_attrib_flags, true); KRDataBlock *vertex_data_block = NULL;
KRDataBlock *index_data_block = NULL;
if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) {
vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size);
index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2);
m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block);
m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block);
} else {
vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index];
index_data_block = m_submeshes[iSubmesh]->index_data_blocks[vbo_index];
}
vbo_index++;
//m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, vertex_attrib_flags, true);
m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true);
int vertex_draw_count = cVertexes; int vertex_draw_count = cVertexes;
if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset;
@@ -284,21 +326,27 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st
} }
} else { } else {
int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; int cBuffers = (vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
int iVertex = pSubmesh->start_vertex; int iVertex = pSubmesh->start_vertex;
int iBuffer = iVertex / MAX_VBO_SIZE; int iBuffer = iVertex / MAX_VBO_SIZE;
iVertex = iVertex % MAX_VBO_SIZE; iVertex = iVertex % MAX_VBO_SIZE;
while(cVertexes > 0) { while(cVertexes > 0) {
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE; GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE;
int vertex_size = m_vertex_size; int vertex_size = m_vertex_size;
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes; KRDataBlock *vertex_data_block = NULL;
void *buffer_end = m_pData->getEnd(); KRDataBlock *index_data_block = NULL;
assert(vbo_end <= buffer_end); if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) {
assert(cBufferVertexes <= 65535); vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes);
m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block);
} else {
vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index];
}
vbo_index++;
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, pHeader->vertex_attrib_flags, true); //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, vertex_attrib_flags, true);
m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true);
if(iVertex + cVertexes >= MAX_VBO_SIZE) { if(iVertex + cVertexes >= MAX_VBO_SIZE) {
@@ -344,13 +392,12 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st
} }
} }
// fprintf(stderr, "end object\n"); //m_pData->unlock();
} }
void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector<std::pair<int, int> > vertex_index_bases, std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<KRMat4> bone_bind_poses, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format, */const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { void KRMesh::LoadData(const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) {
clearData(); clearBuffers();
// TODO, FINDME - These values should be passed as a parameter and set by GUI flags // TODO, FINDME - These values should be passed as a parameter and set by GUI flags
bool use_short_vertexes = false; bool use_short_vertexes = false;
@@ -429,9 +476,10 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector<std:
size_t vertex_count = mi.vertices.size(); size_t vertex_count = mi.vertices.size();
size_t bone_count = mi.bone_names.size(); size_t bone_count = mi.bone_names.size();
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + KRALIGN(2 * index_count) + KRALIGN(8 * index_base_count) + vertex_size * vertex_count; size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + KRALIGN(2 * index_count) + KRALIGN(8 * index_base_count) + vertex_size * vertex_count;
m_pData = new KRDataBlock();
m_pMetaData = m_pData;
m_pData->expand(new_file_size); m_pData->expand(new_file_size);
m_pData->lock();
pack_header *pHeader = getHeader(); pack_header *pHeader = getHeader();
memset(pHeader, 0, sizeof(pack_header)); memset(pHeader, 0, sizeof(pack_header));
pHeader->vertex_attrib_flags = vertex_attrib_flags; pHeader->vertex_attrib_flags = vertex_attrib_flags;
@@ -573,6 +621,18 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector<std:
} }
} }
} }
m_pData->unlock();
// ----
pack_header ph;
m_pData->copy((void *)&ph, 0, sizeof(ph));
m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count);
m_pMetaData->lock();
m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8);
m_pIndexBaseData->lock();
// ----
optimize(); optimize();
} }
@@ -585,10 +645,6 @@ KRVector3 KRMesh::getMaxPoint() const {
return m_maxPoint; return m_maxPoint;
} }
void KRMesh::clearData() {
m_pData->unload();
}
void KRMesh::clearBuffers() { void KRMesh::clearBuffers() {
m_submeshes.clear(); m_submeshes.clear();
} }
@@ -620,34 +676,47 @@ bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attri
KRMesh::pack_header *KRMesh::getHeader() const KRMesh::pack_header *KRMesh::getHeader() const
{ {
return (pack_header *)m_pData->getStart(); return (pack_header *)m_pMetaData->getStart();
} }
KRMesh::pack_bone *KRMesh::getBone(int index) KRMesh::pack_bone *KRMesh::getBone(int index)
{ {
pack_header *header = getHeader(); pack_header *header = getHeader();
return (pack_bone *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); return (pack_bone *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index);
} }
unsigned char *KRMesh::getVertexData() const { unsigned char *KRMesh::getVertexData() const {
return ((unsigned char *)m_pData->getStart()) + getVertexDataOffset();
}
size_t KRMesh::getVertexDataOffset() const {
pack_header *pHeader = getHeader(); pack_header *pHeader = getHeader();
return ((unsigned char *)m_pData->getStart()) + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count);
} }
__uint16_t *KRMesh::getIndexData() const { __uint16_t *KRMesh::getIndexData() const {
return (__uint16_t *)((unsigned char *)m_pData->getStart() + getIndexDataOffset());
}
size_t KRMesh::getIndexDataOffset() const {
pack_header *pHeader = getHeader(); pack_header *pHeader = getHeader();
return (__uint16_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count); return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count;
} }
__uint32_t *KRMesh::getIndexBaseData() const { __uint32_t *KRMesh::getIndexBaseData() const {
if(m_pIndexBaseData == NULL) {
pack_header *pHeader = getHeader(); pack_header *pHeader = getHeader();
return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count));
} else {
return (__uint32_t *)m_pIndexBaseData->getStart();
}
} }
KRMesh::pack_material *KRMesh::getSubmesh(int mesh_index) const KRMesh::pack_material *KRMesh::getSubmesh(int mesh_index) const
{ {
return (pack_material *)((unsigned char *)m_pData->getStart() + sizeof(pack_header)) + mesh_index; return (pack_material *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header)) + mesh_index;
} }
unsigned char *KRMesh::getVertexData(int index) const unsigned char *KRMesh::getVertexData(int index) const
@@ -658,7 +727,8 @@ unsigned char *KRMesh::getVertexData(int index) const
int KRMesh::getSubmeshCount() const int KRMesh::getSubmeshCount() const
{ {
pack_header *header = getHeader(); pack_header *header = getHeader();
return header->submesh_count; int submesh_count = header->submesh_count;
return submesh_count;
} }
int KRMesh::getVertexCount(int submesh) const int KRMesh::getVertexCount(int submesh) const
@@ -893,7 +963,8 @@ size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_
int KRMesh::getBoneCount() int KRMesh::getBoneCount()
{ {
pack_header *header = getHeader(); pack_header *header = getHeader();
return header->bone_count; int bone_count = header->bone_count;
return bone_count;
} }
char *KRMesh::getBoneName(int bone_index) char *KRMesh::getBoneName(int bone_index)
@@ -908,7 +979,8 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index)
KRMesh::model_format_t KRMesh::getModelFormat() const KRMesh::model_format_t KRMesh::getModelFormat() const
{ {
return (model_format_t)getHeader()->model_format; model_format_t f = (model_format_t)getHeader()->model_format;
return f;
} }
bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo) bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo)
@@ -1000,6 +1072,7 @@ bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_ind
bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const
{ {
m_pData->lock();
bool hit_found = false; bool hit_found = false;
for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) {
// int vertex_start = getSubmesh(submesh_index)->start_vertex; // int vertex_start = getSubmesh(submesh_index)->start_vertex;
@@ -1036,26 +1109,30 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin
break; break;
} }
} }
m_pData->unlock();
return hit_found; return hit_found;
} }
bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const
{ {
m_pData->lock();
KRHitInfo new_hitinfo; KRHitInfo new_hitinfo;
KRVector3 dir = KRVector3::Normalize(v1 - v0); KRVector3 dir = KRVector3::Normalize(v1 - v0);
if(rayCast(v0, dir, new_hitinfo)) { if(rayCast(v0, dir, new_hitinfo)) {
if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) { if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) {
// The hit was between v1 and v2 // The hit was between v1 and v2
hitinfo = new_hitinfo; hitinfo = new_hitinfo;
m_pData->unlock();
return true; return true;
} }
} }
m_pData->unlock();
return false; // Either no hit, or the hit was beyond v1 return false; // Either no hit, or the hit was beyond v1
} }
void KRMesh::convertToIndexed() void KRMesh::convertToIndexed()
{ {
m_pData->lock();
char *szKey = new char[m_vertex_size * 2 + 1]; char *szKey = new char[m_vertex_size * 2 + 1];
// Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU // Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU
@@ -1230,6 +1307,8 @@ void KRMesh::convertToIndexed()
mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
m_pData->unlock();
LoadData(mi, false, false); LoadData(mi, false, false);
} }
@@ -1264,6 +1343,9 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
switch(getModelFormat()) { switch(getModelFormat()) {
case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
{ {
__uint16_t *index_data = getIndexData();
int start_index_offset, start_vertex_offset, index_count, vertex_count; int start_index_offset, start_vertex_offset, index_count, vertex_count;
int index_group = getSubmesh(submesh)->index_group; int index_group = getSubmesh(submesh)->index_group;
int index_group_offset = getSubmesh(submesh)->index_group_offset; int index_group_offset = getSubmesh(submesh)->index_group_offset;
@@ -1273,7 +1355,7 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
remaining_vertices -= index_count; remaining_vertices -= index_count;
getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
} }
return getIndexData()[start_index_offset + remaining_vertices] + start_vertex_offset; return index_data[start_index_offset + remaining_vertices] + start_vertex_offset;
} }
break; break;
default: default:
@@ -1284,7 +1366,8 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
void KRMesh::optimizeIndexes() void KRMesh::optimizeIndexes()
{ {
if(getModelFormat() != KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) return; m_pData->lock();
if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
__uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); __uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t));
__uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t)); __uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t));
@@ -1365,4 +1448,7 @@ void KRMesh::optimizeIndexes()
free(new_indices); free(new_indices);
free(vertex_mapping); free(vertex_mapping);
free(new_vertex_data); free(new_vertex_data);
} // if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES)
m_pData->unlock();
} }

View File

@@ -133,11 +133,24 @@ public:
typedef struct { class Submesh {
public:
Submesh() {};
~Submesh() {
for(std::vector<KRDataBlock *>::iterator itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) {
delete (*itr);
}
for(std::vector<KRDataBlock *>::iterator itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) {
delete (*itr);
}
};
GLint start_vertex; GLint start_vertex;
GLsizei vertex_count; GLsizei vertex_count;
char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
} Submesh; vector<KRDataBlock *> vertex_data_blocks;
vector<KRDataBlock *> index_data_blocks;
};
typedef struct { typedef struct {
union { union {
@@ -198,6 +211,10 @@ public:
static int GetLODCoverage(const std::string &name); static int GetLODCoverage(const std::string &name);
private: private:
KRDataBlock *m_pData;
KRDataBlock *m_pMetaData;
KRDataBlock *m_pIndexBaseData;
void getSubmeshes(); void getSubmeshes();
// bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const; // bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const;
@@ -212,7 +229,6 @@ private:
KRVector3 m_minPoint, m_maxPoint; KRVector3 m_minPoint, m_maxPoint;
KRDataBlock *m_pData;
@@ -235,7 +251,6 @@ private:
void updateAttributeOffsets(); void updateAttributeOffsets();
void clearData();
void clearBuffers(); void clearBuffers();
void setName(const std::string name); void setName(const std::string name);
@@ -244,14 +259,19 @@ private:
pack_material *getSubmesh(int mesh_index) const; pack_material *getSubmesh(int mesh_index) const;
unsigned char *getVertexData() const; unsigned char *getVertexData() const;
size_t getVertexDataOffset() const;
unsigned char *getVertexData(int index) const; unsigned char *getVertexData(int index) const;
__uint16_t *getIndexData() const; __uint16_t *getIndexData() const;
size_t getIndexDataOffset() const;
__uint32_t *getIndexBaseData() const; __uint32_t *getIndexBaseData() const;
pack_header *getHeader() const; pack_header *getHeader() const;
pack_bone *getBone(int index); pack_bone *getBone(int index);
void getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const; void getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const;
void releaseData();
}; };

View File

@@ -37,14 +37,12 @@
#include "KRMeshCube.h" #include "KRMeshCube.h"
#include "KRMeshSphere.h" #include "KRMeshSphere.h"
KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context) { KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_streamer(context) {
m_currentVBO.vbo_handle = -1; m_currentVBO.vbo_handle = -1;
m_currentVBO.vbo_handle_indexes = -1; m_currentVBO.vbo_handle_indexes = -1;
m_currentVBO.vao_handle = -1; m_currentVBO.vao_handle = -1;
m_currentVBO.data = NULL; m_currentVBO.data = NULL;
m_vboMemUsed = 0; m_vboMemUsed = 0;
m_randomParticleVertexData = NULL;
m_volumetricLightingVertexData = NULL;
m_memoryTransferredThisFrame = 0; m_memoryTransferredThisFrame = 0;
// addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults // addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults
@@ -52,6 +50,45 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context) {
addModel(new KRMeshSphere(context)); addModel(new KRMeshSphere(context));
m_draw_call_logging_enabled = false; m_draw_call_logging_enabled = false;
m_draw_call_log_used = false; m_draw_call_log_used = false;
// ---- Initialize stock models ----
static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = {
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
1.0,-1.0, 1.0,
-1.0,-1.0, 1.0,
-1.0,-1.0,-1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0,-1.0,
1.0, 1.0, 1.0,
1.0, 1.0,-1.0,
1.0,-1.0, 1.0,
1.0,-1.0,-1.0,
-1.0,-1.0,-1.0,
1.0, 1.0,-1.0,
-1.0, 1.0,-1.0
};
KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX);
KRENGINE_VBO_3D_CUBE_VERTICES.expand(sizeof(GLfloat) * 3 * 14);
KRENGINE_VBO_3D_CUBE_VERTICES.lock();
memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14);
KRENGINE_VBO_3D_CUBE_VERTICES.unlock();
static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA);
KRENGINE_VBO_2D_SQUARE_VERTICES.expand(sizeof(GLfloat) * 5 * 4);
KRENGINE_VBO_2D_SQUARE_VERTICES.lock();
memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4);
KRENGINE_VBO_2D_SQUARE_VERTICES.unlock();
} }
KRMeshManager::~KRMeshManager() { KRMeshManager::~KRMeshManager() {
@@ -59,8 +96,6 @@ KRMeshManager::~KRMeshManager() {
delete (*itr).second; delete (*itr).second;
} }
m_models.empty(); m_models.empty();
if(m_randomParticleVertexData != NULL) delete m_randomParticleVertexData;
if(m_volumetricLightingVertexData != NULL) delete m_volumetricLightingVertexData;
} }
KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) { KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) {
@@ -115,24 +150,24 @@ void KRMeshManager::unbindVBO() {
} }
} }
void KRMeshManager::releaseVBO(GLvoid *data) void KRMeshManager::releaseVBO(KRDataBlock &data)
{ {
if(m_currentVBO.data == data) { if(m_currentVBO.data == &data) {
unbindVBO(); unbindVBO();
} }
vbo_info_type vbo_to_release; vbo_info_type vbo_to_release;
if(m_vbosActive.find(data) != m_vbosActive.end()) { if(m_vbosActive.find(&data) != m_vbosActive.end()) {
fprintf(stderr, "glFinish called due to releasing a VBO that is active in the current frame.\n"); fprintf(stderr, "glFinish called due to releasing a VBO that is active in the current frame.\n");
GLDEBUG(glFinish()); GLDEBUG(glFinish());
// The VBO is active // The VBO is active
vbo_to_release = m_vbosActive[data]; vbo_to_release = m_vbosActive[&data];
m_vbosActive.erase(data); m_vbosActive.erase(&data);
} else { } else {
// The VBO is inactive // The VBO is inactive
vbo_to_release = m_vbosPool[data]; vbo_to_release = m_vbosPool[&data];
m_vbosPool.erase(data); m_vbosPool.erase(&data);
} }
m_vboMemUsed -= vbo_to_release.size; m_vboMemUsed -= vbo_to_release.size;
@@ -146,12 +181,12 @@ void KRMeshManager::releaseVBO(GLvoid *data)
} }
} }
void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo) { void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo) {
if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) { if(m_currentVBO.data != &data) {
if(m_vbosActive.find(data) != m_vbosActive.end()) { if(m_vbosActive.find(&data) != m_vbosActive.end()) {
m_currentVBO = m_vbosActive[data]; m_currentVBO = m_vbosActive[&data];
#if GL_OES_vertex_array_object #if GL_OES_vertex_array_object
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
#else #else
@@ -163,10 +198,10 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes));
} }
#endif #endif
} else if(m_vbosPool.find(data) != m_vbosPool.end()) { } else if(m_vbosPool.find(&data) != m_vbosPool.end()) {
m_currentVBO = m_vbosPool[data]; m_currentVBO = m_vbosPool[&data];
m_vbosPool.erase(data); m_vbosPool.erase(&data);
m_vbosActive[data] = m_currentVBO; m_vbosActive[&data] = m_currentVBO;
#if GL_OES_vertex_array_object #if GL_OES_vertex_array_object
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
#else #else
@@ -181,12 +216,12 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
} else { } else {
while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + size + index_data_size >= KRContext::KRENGINE_MAX_VBO_MEM) { while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + data.getSize() + index_data.getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) {
if(m_vbosPool.empty()) { if(m_vbosPool.empty()) {
fprintf(stderr, "flushBuffers due to VBO exhaustion...\n"); fprintf(stderr, "flushBuffers due to VBO exhaustion...\n");
m_pContext->rotateBuffers(false); m_pContext->rotateBuffers(false);
} }
unordered_map<GLvoid *, vbo_info_type>::iterator first_itr = m_vbosPool.begin(); unordered_map<KRDataBlock *, vbo_info_type>::iterator first_itr = m_vbosPool.begin();
vbo_info_type firstVBO = first_itr->second; vbo_info_type firstVBO = first_itr->second;
#if GL_OES_vertex_array_object #if GL_OES_vertex_array_object
GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle)); GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle));
@@ -204,7 +239,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
m_currentVBO.vbo_handle = -1; m_currentVBO.vbo_handle = -1;
m_currentVBO.vbo_handle_indexes = -1; m_currentVBO.vbo_handle_indexes = -1;
GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle)); GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle));
if(index_data != NULL) { if(index_data.getSize() > 0) {
GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes)); GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes));
} }
@@ -214,25 +249,49 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
#endif #endif
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); #if GL_OES_mapbuffer
m_memoryTransferredThisFrame += size;
m_vboMemUsed += size; GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES));
data.copy(map_ptr);
//memcpy(map_ptr, data, size);
GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER));
#else
data.lock();
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
data.unlock();
#endif
m_memoryTransferredThisFrame += data.getSize();
m_vboMemUsed += data.getSize();
configureAttribs(vertex_attrib_flags); configureAttribs(vertex_attrib_flags);
m_currentVBO.size = size; m_currentVBO.size = data.getSize();
m_currentVBO.data = data; m_currentVBO.data = &data;
if(index_data == NULL) { if(index_data.getSize() == 0) {
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else { } else {
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes));
GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, index_data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
m_memoryTransferredThisFrame += index_data_size; #if GL_OES_mapbuffer
m_vboMemUsed += index_data_size;
m_currentVBO.size += index_data_size; GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES));
index_data.copy(map_ptr);
//memcpy(map_ptr, index_data, index_data.getSize());
GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER));
#else
index_data.lock();
GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), index_data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
index_data.unlock();
#endif
m_memoryTransferredThisFrame += index_data.getSize();
m_vboMemUsed += index_data.getSize();
m_currentVBO.size += index_data.getSize();
} }
m_vbosActive[data] = m_currentVBO; m_vbosActive[&data] = m_currentVBO;
} }
} }
} }
@@ -314,7 +373,7 @@ long KRMeshManager::getMemUsed()
long KRMeshManager::getMemActive() long KRMeshManager::getMemActive()
{ {
long mem_active = 0; long mem_active = 0;
for(unordered_map<GLvoid *, vbo_info_type>::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { for(unordered_map<KRDataBlock *, vbo_info_type>::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) {
mem_active += (*itr).second.size; mem_active += (*itr).second.size;
} }
return mem_active; return mem_active;
@@ -332,56 +391,56 @@ void KRMeshManager::rotateBuffers(bool new_frame)
} }
KRMeshManager::VolumetricLightingVertexData *KRMeshManager::getVolumetricLightingVertexes() KRDataBlock &KRMeshManager::getVolumetricLightingVertexes()
{ {
if(m_volumetricLightingVertexData == NULL) { if(m_volumetricLightingVertexData.getSize() == 0) {
m_volumetricLightingVertexData = (VolumetricLightingVertexData *)malloc(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6);
m_volumetricLightingVertexData.lock();
VolumetricLightingVertexData * vertex_data = (VolumetricLightingVertexData *)m_volumetricLightingVertexData.getStart();
int iVertex=0; int iVertex=0;
for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) { for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) {
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; vertex_data[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; vertex_data[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; vertex_data[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; vertex_data[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; vertex_data[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; vertex_data[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; vertex_data[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; vertex_data[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; vertex_data[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; vertex_data[iVertex].vertex.x = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; vertex_data[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; vertex_data[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; vertex_data[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; vertex_data[iVertex].vertex.y = -1.0f;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; vertex_data[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
vertex_data[iVertex].vertex.x = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; vertex_data[iVertex].vertex.y = 1.0f;
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; vertex_data[iVertex].vertex.z = iPlane;
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
iVertex++; iVertex++;
// -1.0f, -1.0f,
// 1.0f, -1.0f,
// -1.0f, 1.0f,
// 1.0f, 1.0f,
} }
m_volumetricLightingVertexData.unlock();
} }
return m_volumetricLightingVertexData; return m_volumetricLightingVertexData;
} }
KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles() KRDataBlock &KRMeshManager::getRandomParticles()
{ {
if(m_randomParticleVertexData == NULL) { if(m_randomParticleVertexData.getSize() == 0) {
m_randomParticleVertexData = (RandomParticleVertexData *)malloc(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); m_randomParticleVertexData.expand(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3);
m_randomParticleVertexData.lock();
RandomParticleVertexData *vertex_data = (RandomParticleVertexData *)m_randomParticleVertexData.getStart();
// Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill // Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill
@@ -390,27 +449,28 @@ KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles()
int iVertex=0; int iVertex=0;
for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) { for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) {
m_randomParticleVertexData[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; vertex_data[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
m_randomParticleVertexData[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; vertex_data[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
m_randomParticleVertexData[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; vertex_data[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
m_randomParticleVertexData[iVertex].uva.u = -0.5f; vertex_data[iVertex].uva.u = -0.5f;
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; vertex_data[iVertex].uva.v = -inscribed_circle_radius;
iVertex++; iVertex++;
m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x;
m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y;
m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z;
m_randomParticleVertexData[iVertex].uva.u = 0.5f; vertex_data[iVertex].uva.u = 0.5f;
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; vertex_data[iVertex].uva.v = -inscribed_circle_radius;
iVertex++; iVertex++;
m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x;
m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y;
m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z;
m_randomParticleVertexData[iVertex].uva.u = 0.0f; vertex_data[iVertex].uva.u = 0.0f;
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height; vertex_data[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height;
iVertex++; iVertex++;
} }
m_randomParticleVertexData.unlock();
} }
return m_randomParticleVertexData; return m_randomParticleVertexData;
} }

View File

@@ -37,6 +37,8 @@
#include "KRDataBlock.h" #include "KRDataBlock.h"
#include "KRNode.h" #include "KRNode.h"
#include "KRMeshStreamer.h"
class KRContext; class KRContext;
class KRMesh; class KRMesh;
@@ -59,8 +61,8 @@ public:
std::vector<std::string> getModelNames(); std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh *> &getModels(); unordered_multimap<std::string, KRMesh *> &getModels();
void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo); void bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo);
void releaseVBO(GLvoid *data); void releaseVBO(KRDataBlock &data);
void unbindVBO(); void unbindVBO();
long getMemUsed(); long getMemUsed();
long getMemActive(); long getMemActive();
@@ -88,10 +90,8 @@ public:
} VolumetricLightingVertexData; } VolumetricLightingVertexData;
KRDataBlock &getRandomParticles();
KRDataBlock &getVolumetricLightingVertexes();
RandomParticleVertexData *getRandomParticles();
VolumetricLightingVertexData *getVolumetricLightingVertexes();
long getMemoryTransferedThisFrame(); long getMemoryTransferedThisFrame();
@@ -110,6 +110,12 @@ public:
std::vector<draw_call_info> getDrawCalls(); std::vector<draw_call_info> getDrawCalls();
KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES;
__int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS;
KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES;
__int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS;
private: private:
unordered_multimap<std::string, KRMesh *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model unordered_multimap<std::string, KRMesh *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model
@@ -118,17 +124,17 @@ private:
GLuint vbo_handle_indexes; GLuint vbo_handle_indexes;
GLuint vao_handle; GLuint vao_handle;
GLsizeiptr size; GLsizeiptr size;
GLvoid *data; KRDataBlock *data;
} vbo_info_type; } vbo_info_type;
long m_vboMemUsed; long m_vboMemUsed;
vbo_info_type m_currentVBO; vbo_info_type m_currentVBO;
unordered_map<GLvoid *, vbo_info_type> m_vbosActive; unordered_map<KRDataBlock *, vbo_info_type> m_vbosActive;
unordered_map<GLvoid *, vbo_info_type> m_vbosPool; unordered_map<KRDataBlock *, vbo_info_type> m_vbosPool;
RandomParticleVertexData *m_randomParticleVertexData; KRDataBlock m_randomParticleVertexData;
VolumetricLightingVertexData *m_volumetricLightingVertexData; KRDataBlock m_volumetricLightingVertexData;
long m_memoryTransferredThisFrame; long m_memoryTransferredThisFrame;
@@ -136,6 +142,8 @@ private:
bool m_draw_call_logging_enabled; bool m_draw_call_logging_enabled;
bool m_draw_call_log_used; bool m_draw_call_log_used;
KRMeshStreamer m_streamer;
}; };
#endif #endif

View File

@@ -0,0 +1,57 @@
//
// KRMeshManager.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 KRMESHSTREAMER_H
#define KRMESHSTREAMER_H
#include "KREngine-common.h"
#include <thread>
#include <atomic>
class KRContext;
class KRMeshStreamer
{
public:
KRMeshStreamer(KRContext &context);
~KRMeshStreamer();
private:
KRContext &m_context;
std::thread m_thread;
std::atomic<bool> m_stop;
void run();
};
#endif /* defined(KRMESHSTREAMER_H) */

View File

@@ -0,0 +1,47 @@
//
// KRMeshStreamer.cpp
// Kraken
//
// Created by Kearwood Gilbert on 11/1/2013.
// Copyright (c) 2013 Kearwood Software. All rights reserved.
//
#include "KRMeshStreamer.h"
#include "KREngine-common.h"
#include "KRContext.h"
#include <chrono>
EAGLContext *gMeshStreamerContext;
KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context)
{
gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup];
m_stop = false;
m_thread = std::thread(&KRMeshStreamer::run, this);
}
KRMeshStreamer::~KRMeshStreamer()
{
m_stop = true;
m_thread.join();
[gMeshStreamerContext release];
}
void KRMeshStreamer::run()
{
pthread_setname_np("Kraken - Mesh Streamer");
std::chrono::microseconds sleep_duration( 100 );
[EAGLContext setCurrentContext: gMeshStreamerContext];
while(!m_stop)
{
if(m_context.getStreamingEnabled()) {
}
std::this_thread::sleep_for( sleep_duration );
}
}

View File

@@ -43,6 +43,23 @@ KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_na
m_min_lod_coverage = lod_min_coverage; m_min_lod_coverage = lod_min_coverage;
m_receivesShadow = receives_shadow; m_receivesShadow = receives_shadow;
m_faces_camera = faces_camera; m_faces_camera = faces_camera;
m_boundsCachedMat.c[0] = -1.0f;
m_boundsCachedMat.c[1] = -1.0f;
m_boundsCachedMat.c[2] = -1.0f;
m_boundsCachedMat.c[3] = -1.0f;
m_boundsCachedMat.c[4] = -1.0f;
m_boundsCachedMat.c[5] = -1.0f;
m_boundsCachedMat.c[6] = -1.0f;
m_boundsCachedMat.c[7] = -1.0f;
m_boundsCachedMat.c[8] = -1.0f;
m_boundsCachedMat.c[9] = -1.0f;
m_boundsCachedMat.c[10] = -1.0f;
m_boundsCachedMat.c[11] = -1.0f;
m_boundsCachedMat.c[12] = -1.0f;
m_boundsCachedMat.c[13] = -1.0f;
m_boundsCachedMat.c[14] = -1.0f;
m_boundsCachedMat.c[15] = -1.0f;
} }
KRModel::~KRModel() { KRModel::~KRModel() {
@@ -155,7 +172,12 @@ KRAABB KRModel::getBounds() {
float max_dimension = normal_bounds.longest_radius(); float max_dimension = normal_bounds.longest_radius();
return KRAABB(normal_bounds.center()-KRVector3(max_dimension), normal_bounds.center() + KRVector3(max_dimension)); return KRAABB(normal_bounds.center()-KRVector3(max_dimension), normal_bounds.center() + KRVector3(max_dimension));
} else { } else {
return KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix());
if(!(m_boundsCachedMat == getModelMatrix())) {
m_boundsCachedMat = getModelMatrix();
m_boundsCached = KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix());
}
return m_boundsCached;
} }
} else { } else {
return KRAABB::Infinite(); return KRAABB::Infinite();

View File

@@ -74,6 +74,10 @@ private:
bool m_receivesShadow; bool m_receivesShadow;
bool m_faces_camera; bool m_faces_camera;
KRMat4 m_boundsCachedMat;
KRAABB m_boundsCached;
}; };

View File

@@ -20,6 +20,7 @@
#include "KRAABB.h" #include "KRAABB.h"
#include "KRQuaternion.h" #include "KRQuaternion.h"
#include "KRBone.h" #include "KRBone.h"
#include "KRLocator.h"
#include "KRAudioSource.h" #include "KRAudioSource.h"
#include "KRAmbientZone.h" #include "KRAmbientZone.h"
#include "KRReverbZone.h" #include "KRReverbZone.h"
@@ -421,6 +422,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f); new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f);
} else if(strcmp(szElementName, "bone") == 0) { } else if(strcmp(szElementName, "bone") == 0) {
new_node = new KRBone(scene, szName); new_node = new KRBone(scene, szName);
} else if(strcmp(szElementName, "locator") == 0) {
new_node = new KRLocator(scene, szName);
} else if(strcmp(szElementName, "audio_source") == 0) { } else if(strcmp(szElementName, "audio_source") == 0) {
new_node = new KRAudioSource(scene, szName); new_node = new KRAudioSource(scene, szName);
} else if(strcmp(szElementName, "ambient_zone") == 0) { } else if(strcmp(szElementName, "ambient_zone") == 0) {

View File

@@ -77,7 +77,9 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); //m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false);
KRDataBlock index_data;
m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
} }
} }

View File

@@ -96,7 +96,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_
GLDEBUG(glDisable(GL_DEPTH_TEST)); GLDEBUG(glDisable(GL_DEPTH_TEST));
// Render a full screen quad // Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
} else { } else {
#if GL_OES_vertex_array_object #if GL_OES_vertex_array_object

View File

@@ -15,7 +15,7 @@ KRRenderSettings::KRRenderSettings()
siren_enable_hrtf = true; siren_enable_hrtf = true;
siren_reverb_max_length = 2.0f; siren_reverb_max_length = 2.0f;
m_enable_realtime_occlusion = true; m_enable_realtime_occlusion = false;
bShowShadowBuffer = false; bShowShadowBuffer = false;
bShowOctree = false; bShowOctree = false;
bShowDeferred = false; bShowDeferred = false;

View File

@@ -23,6 +23,7 @@
#include "KRScene.h" #include "KRScene.h"
#include "KRQuaternion.h" #include "KRQuaternion.h"
#include "KRBone.h" #include "KRBone.h"
#include "KRLocator.h"
#include "KRBundle.h" #include "KRBundle.h"
#include "KRModel.h" #include "KRModel.h"
#include "KRLODGroup.h" #include "KRLODGroup.h"
@@ -46,6 +47,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG
KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode);
KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode); KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode);
KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode);
KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode); KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode);
std::string GetFbxObjectName(FbxObject *obj); std::string GetFbxObjectName(FbxObject *obj);
@@ -54,9 +56,25 @@ const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be c
std::string GetFbxObjectName(FbxObject *obj) std::string GetFbxObjectName(FbxObject *obj)
{ {
bool is_locator = false;
KFbxNode *node = FbxCast<KFbxNode>(obj);
if(node) {
KFbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType());
if(attribute_type == KFbxNodeAttribute::eNull) {
KFbxNull* pSourceNull = (KFbxNull*) node->GetNodeAttribute();
if(pSourceNull->Look.Get() == KFbxNull::eCross ) {
is_locator = true;
}
}
}
// Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique // Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique
// TODO - This should be updated to only add a prefix or suffix if needed to make the name unique // TODO - This should be updated to only add a prefix or suffix if needed to make the name unique
if(strcmp(obj->GetName(), "default_camera") == 0) { if(is_locator) {
// We do not rename locators
return std::string(obj->GetName());
} else if(strcmp(obj->GetName(), "default_camera") == 0) {
// There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera // There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera
return "default_camera"; return "default_camera";
} else { } else {
@@ -955,37 +973,27 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
case KFbxNodeAttribute::eSkeleton: case KFbxNodeAttribute::eSkeleton:
new_node = LoadSkeleton(parent_node, pFbxScene, pNode); new_node = LoadSkeleton(parent_node, pFbxScene, pNode);
break; break;
case KFbxNodeAttribute::eCamera: case KFbxNodeAttribute::eCamera:
new_node = LoadCamera(parent_node, pNode); new_node = LoadCamera(parent_node, pNode);
break; break;
default: default:
{ {
bool is_locator = false;
if(attribute_type == KFbxNodeAttribute::eNull) {
KFbxNull* pSourceNull = (KFbxNull*) pNode->GetNodeAttribute();
if(pSourceNull->Look.Get() == KFbxNull::eCross ) {
is_locator = true;
}
}
if(is_locator) {
new_node = LoadLocator(parent_node, pFbxScene, pNode);
} else {
if(pNode->GetChildCount() > 0) { if(pNode->GetChildCount() > 0) {
// Create an empty node, for inheritence of transforms // Create an empty node, for inheritence of transforms
std::string name = GetFbxObjectName(pNode); std::string name = GetFbxObjectName(pNode);
float min_distance = 0.0f;
float max_distance = 0.0f;
typedef boost::tokenizer<boost::char_separator<char> > char_tokenizer;
int step = 0;
char_tokenizer name_components(name, boost::char_separator<char>("_"));
for(char_tokenizer::iterator itr=name_components.begin(); itr != name_components.end(); itr++) {
std::string component = *itr;
std::transform(component.begin(), component.end(),
component.begin(), ::tolower);
if(component.compare("lod") == 0) {
step = 1;
} else if(step == 1) {
min_distance = boost::lexical_cast<float>(component);
step++;
} else if(step == 2) {
max_distance = boost::lexical_cast<float>(component);
step++;
}
}
/* /*
if(min_distance == 0.0f && max_distance == 0.0f) { if(min_distance == 0.0f && max_distance == 0.0f) {
@@ -995,14 +1003,10 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
*/ */
// LOD Enabled group node // LOD Enabled group node
KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name); KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name);
lod_group->setMinDistance(min_distance); lod_group->setMinDistance(0.0f);
lod_group->setMaxDistance(max_distance); lod_group->setMaxDistance(0.0f);
new_node = lod_group; new_node = lod_group;
/*
} }
*/
} }
} }
break; break;
@@ -1526,6 +1530,21 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode)
return new_bone; return new_bone;
} }
KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) {
std::string name = GetFbxObjectName(pNode);
KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str());
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<int>& pIndex);
// PoseList pose_list;
// FbxArray<int> pose_indices;
// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) {
// fprintf(stderr, "Found bind pose(s)!\n");
// }
return new_locator;
}
KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) { KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) {
FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute(); FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute();
const char *szName = pNode->GetName(); const char *szName = pNode->GetName();

View File

@@ -272,7 +272,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &visi
KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix(); KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); getContext().getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true);
// Enable additive blending // Enable additive blending
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
@@ -404,9 +404,10 @@ bool KRScene::save(KRDataBlock &data) {
KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock *data) KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock *data)
{ {
data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely std::string xml_string = data->getString();
delete data;
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
doc.Parse((char *)data->getStart()); doc.Parse(xml_string.c_str());
KRScene *new_scene = new KRScene(context, name); KRScene *new_scene = new KRScene(context, name);
tinyxml2::XMLElement *scene_element = doc.RootElement(); tinyxml2::XMLElement *scene_element = doc.RootElement();
@@ -418,7 +419,7 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock
new_scene->getRootNode()->addChild(n); new_scene->getRootNode()->addChild(n);
} }
delete data;
return new_scene; return new_scene;
} }

View File

@@ -254,12 +254,12 @@ bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KR
} }
void KRShaderManager::loadFragmentShader(const std::string &name, KRDataBlock *data) { void KRShaderManager::loadFragmentShader(const std::string &name, KRDataBlock *data) {
m_fragShaderSource[name] = string((char *)data->getStart(), data->getSize()); m_fragShaderSource[name] = data->getString();
delete data; delete data;
} }
void KRShaderManager::loadVertexShader(const std::string &name, KRDataBlock *data) { void KRShaderManager::loadVertexShader(const std::string &name, KRDataBlock *data) {
m_vertShaderSource[name] = string((char *)data->getStart(), data->getSize()); m_vertShaderSource[name] = data->getString();
delete data; delete data;
} }

View File

@@ -10,8 +10,9 @@
#define KRSTOCKGEOMETRY_H #define KRSTOCKGEOMETRY_H
#include "KRMesh.h" #include "KRMesh.h"
#include "KRDataBlock.h"
static const GLfloat KRENGINE_VBO_3D_CUBE[] = { /*
static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = {
1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
1.0,-1.0, 1.0, 1.0,-1.0, 1.0,
@@ -28,32 +29,20 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
-1.0, 1.0,-1.0 -1.0, 1.0,-1.0
}; };
static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14; static KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES;
KRENGINE_VBO_3D_CUBE_VERTICES.load((void *)_KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14);
static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX);
static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = { static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat KRENGINE_VERTICES_2D_SQUARE_UV[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat KRENGINE_VBO_2D_SQUARE[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f 1.0f, 1.0f, 0.0f, 1.0f, 1.0f
}; };
static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4; static KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES;
KRENGINE_VBO_2D_SQUARE_VERTICES.load((void *)_KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4);
static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA);
*/
#endif #endif

View File

@@ -15,26 +15,42 @@
KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name) KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name)
{ {
m_iHandle = 0; m_iHandle = 0;
m_iNewHandle = 0;
m_textureMemUsed = 0; m_textureMemUsed = 0;
m_newTextureMemUsed = 0;
m_last_frame_used = 0; m_last_frame_used = 0;
m_last_frame_bound = 0;
m_handle_lock.clear();
} }
KRTexture::~KRTexture() KRTexture::~KRTexture()
{ {
releaseHandle(); releaseHandles();
} }
void KRTexture::releaseHandle() { void KRTexture::releaseHandles() {
long mem_size = getMemSize();
while(m_handle_lock.test_and_set()); // Spin lock
if(m_iNewHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iNewHandle));
m_iNewHandle = 0;
m_newTextureMemUsed = 0;
}
if(m_iHandle != 0) { if(m_iHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iHandle)); GLDEBUG(glDeleteTextures(1, &m_iHandle));
getContext().getTextureManager()->memoryChanged(-getMemSize());
m_iHandle = 0; m_iHandle = 0;
m_textureMemUsed = 0; m_textureMemUsed = 0;
} }
m_handle_lock.clear();
getContext().getTextureManager()->memoryChanged(-mem_size);
} }
long KRTexture::getMemSize() { long KRTexture::getMemSize() {
return m_textureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory return m_textureMemUsed + m_newTextureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory
} }
long KRTexture::getReferencedMemSize() { long KRTexture::getReferencedMemSize() {
@@ -44,42 +60,36 @@ long KRTexture::getReferencedMemSize() {
void KRTexture::resize(int max_dim) void KRTexture::resize(int max_dim)
{ {
if(!m_handle_lock.test_and_set())
{
if(m_iHandle == m_iNewHandle) {
if(max_dim == 0) { if(max_dim == 0) {
releaseHandle(); m_iNewHandle = 0;
} else { } else {
int target_dim = max_dim; int target_dim = max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_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() - getReferencedMemSize();
if(requiredMemoryDelta) { if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 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) assert(m_newTextureMemUsed == 0);
m_newTextureMemUsed = getMemRequiredForSize(target_dim);
if(getContext().getTextureManager()->getMemoryTransferedThisFrame() + requiredMemoryTransfer > getContext().KRENGINE_MAX_TEXTURE_THROUGHPUT) { getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed);
// Exceeding per-frame transfer throughput; can't resize now getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed);
return;
}
if(getContext().getTextureManager()->getMemUsed() + requiredMemoryDelta > getContext().KRENGINE_MAX_TEXTURE_MEM) {
// Exceeding total memory allocated to textures; can't resize now
return;
}
if(m_current_lod_max_dim != target_dim || m_iHandle == 0) {
if(!createGLTexture(target_dim)) { if(!createGLTexture(target_dim)) {
getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed);
m_newTextureMemUsed = 0;
assert(false); assert(false);
} }
} }
} }
} }
m_handle_lock.clear();
}
} }
GLuint KRTexture::getHandle() { GLuint KRTexture::getHandle() {
if(m_iHandle == 0) {
//resize(getContext().KRENGINE_MIN_TEXTURE_DIM);
resize(m_min_lod_max_dim);
}
resetPoolExpiry(); resetPoolExpiry();
return m_iHandle; return m_iHandle;
} }
@@ -89,34 +99,6 @@ void KRTexture::resetPoolExpiry()
m_last_frame_used = getContext().getCurrentFrame(); m_last_frame_used = getContext().getCurrentFrame();
} }
long KRTexture::getThroughputRequiredForResize(int max_dim)
{
// Calculate the throughput required for GPU texture upload if the texture is resized to max_dim.
// This default behaviour assumes that the texture will need to be deleted and regenerated to change the maximum mip-map level.
// If an OpenGL extension is present that allows a texture to be resized incrementally, then this method should be overridden
if(max_dim == 0) {
return 0;
} else {
int target_dim = max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = target_dim;
if(target_dim != m_current_lod_max_dim) {
int requiredMemory = getMemRequiredForSize(target_dim);
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)
return 0;
}
return requiredMemory;
} else {
return 0;
}
}
}
long KRTexture::getLastFrameUsed() long KRTexture::getLastFrameUsed()
{ {
return m_last_frame_used; return m_last_frame_used;
@@ -147,3 +129,28 @@ int KRTexture::getMinMipMap() {
bool KRTexture::hasMipmaps() { bool KRTexture::hasMipmaps() {
return m_max_lod_max_dim != m_min_lod_max_dim; return m_max_lod_max_dim != m_min_lod_max_dim;
} }
void KRTexture::bind(GLuint texture_unit) {
m_last_frame_bound = getContext().getCurrentFrame();
}
bool KRTexture::canStreamOut() const {
return (m_last_frame_bound + 2 > getContext().getCurrentFrame());
}
void KRTexture::_swapHandles()
{
if(!m_handle_lock.test_and_set()) {
if(m_iHandle != m_iNewHandle) {
if(m_iHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iHandle));
getContext().getTextureManager()->memoryChanged(-m_textureMemUsed);
}
m_textureMemUsed = (long)m_newTextureMemUsed;
m_newTextureMemUsed = 0;
m_iHandle = m_iNewHandle;
}
m_handle_lock.clear();
}
}

View File

@@ -46,13 +46,12 @@ public:
KRTexture(KRContext &context, std::string name); KRTexture(KRContext &context, std::string name);
virtual ~KRTexture(); virtual ~KRTexture();
virtual void bind(GLuint texture_unit) = 0; virtual void bind(GLuint texture_unit);
void releaseHandle(); void releaseHandles();
long getMemSize(); long getMemSize();
virtual long getReferencedMemSize(); virtual long getReferencedMemSize();
virtual long getMemRequiredForSize(int max_dim) = 0; virtual long getMemRequiredForSize(int max_dim) = 0;
virtual long getThroughputRequiredForResize(int max_dim);
virtual void resize(int max_dim); virtual void resize(int max_dim);
long getLastFrameUsed(); long getLastFrameUsed();
@@ -66,13 +65,17 @@ public:
int getMinMipMap(); int getMinMipMap();
bool hasMipmaps(); bool hasMipmaps();
bool canStreamOut() const;
void _swapHandles();
protected: protected:
virtual bool createGLTexture(int lod_max_dim) = 0; virtual bool createGLTexture(int lod_max_dim) = 0;
GLuint getHandle(); GLuint getHandle();
GLuint m_iHandle; GLuint m_iHandle;
long m_textureMemUsed; GLuint m_iNewHandle;
std::atomic_flag m_handle_lock;
int m_current_lod_max_dim; int m_current_lod_max_dim;
@@ -80,6 +83,11 @@ protected:
uint32_t m_min_lod_max_dim; uint32_t m_min_lod_max_dim;
long m_last_frame_used; long m_last_frame_used;
long m_last_frame_bound;
private:
std::atomic<long> m_textureMemUsed;
std::atomic<long> m_newTextureMemUsed;
}; };

View File

@@ -43,54 +43,47 @@ KRTexture2D::~KRTexture2D() {
} }
bool KRTexture2D::createGLTexture(int lod_max_dim) { bool KRTexture2D::createGLTexture(int lod_max_dim) {
if(m_iHandle != m_iNewHandle) {
return true;
}
bool success = true; bool success = true;
GLuint prev_handle = 0;
int prev_lod_max_dim = 0; int prev_lod_max_dim = 0;
long prev_mem_size = 0;
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
if(m_iHandle != 0) { if(m_iHandle != 0) {
prev_handle = m_iHandle;
prev_mem_size = getMemSize();
m_iHandle = 0;
m_textureMemUsed = 0;
prev_lod_max_dim = m_current_lod_max_dim; prev_lod_max_dim = m_current_lod_max_dim;
} }
#else
releaseHandle();
#endif #endif
m_iNewHandle = 0;
m_current_lod_max_dim = 0; m_current_lod_max_dim = 0;
GLDEBUG(glGenTextures(1, &m_iHandle)); GLDEBUG(glGenTextures(1, &m_iNewHandle));
if(m_iHandle == 0) { if(m_iNewHandle == 0) {
success = false; success = false;
} else { } else {
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iHandle)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iNewHandle));
if (hasMipmaps()) { if (hasMipmaps()) {
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
} else { } else {
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
} }
if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle)) { if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim)) {
GLDEBUG(glDeleteTextures(1, &m_iHandle)); GLDEBUG(glDeleteTextures(1, &m_iNewHandle));
m_iHandle = 0; m_iNewHandle = m_iHandle;
m_current_lod_max_dim = 0; m_current_lod_max_dim = prev_lod_max_dim;
success = false; success = false;
} }
} }
if(prev_handle != 0) {
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
GLDEBUG(glDeleteTextures(1, &prev_handle));
}
return success; return success;
} }
void KRTexture2D::bind(GLuint texture_unit) { void KRTexture2D::bind(GLuint texture_unit) {
KRTexture::bind(texture_unit);
GLuint handle = getHandle(); GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle)); GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle));
@@ -101,7 +94,6 @@ void KRTexture2D::bind(GLuint texture_unit) {
} }
} }
bool KRTexture2D::save(const std::string& path) bool KRTexture2D::save(const std::string& path)
{ {
if(m_pData) { if(m_pData) {

View File

@@ -46,7 +46,7 @@ public:
virtual bool save(const std::string& path); virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data); virtual bool save(KRDataBlock &data);
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0; virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim) = 0;
virtual void bind(GLuint texture_unit); virtual void bind(GLuint texture_unit);
protected: protected:

View File

@@ -114,6 +114,7 @@ void KRTextureAnimated::resetPoolExpiry()
void KRTextureAnimated::bind(GLuint texture_unit) void KRTextureAnimated::bind(GLuint texture_unit)
{ {
KRTexture::bind(texture_unit);
int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count)); int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count));
KRTexture2D *frame_texture = textureForFrame(frame_number); KRTexture2D *frame_texture = textureForFrame(frame_number);
if(frame_texture) { if(frame_texture) {

View File

@@ -55,32 +55,25 @@ KRTextureCube::~KRTextureCube()
bool KRTextureCube::createGLTexture(int lod_max_dim) bool KRTextureCube::createGLTexture(int lod_max_dim)
{ {
assert(m_iNewHandle == m_iHandle); // Only allow one resize per frame
bool success = true; bool success = true;
GLuint prev_handle = 0;
int prev_lod_max_dim = 0; int prev_lod_max_dim = 0;
long prev_mem_size = 0;
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage #if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
if(m_iHandle != 0) { if(m_iHandle != 0) {
prev_handle = m_iHandle;
prev_mem_size = getMemSize();
m_iHandle = 0;
m_textureMemUsed = 0;
prev_lod_max_dim = m_current_lod_max_dim; prev_lod_max_dim = m_current_lod_max_dim;
} }
#else
releaseHandle();
#endif #endif
m_current_lod_max_dim = 0; m_iNewHandle = 0;
GLDEBUG(glGenTextures(1, &m_iHandle)); GLDEBUG(glGenTextures(1, &m_iNewHandle));
if(m_iHandle == 0) { assert(m_iNewHandle != 0);
success = false;
} else {
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iHandle)); m_current_lod_max_dim = 0;
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle));
bool bMipMaps = false; bool bMipMaps = false;
@@ -89,7 +82,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName); KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName);
if(faceTexture) { if(faceTexture) {
if(faceTexture->hasMipmaps()) bMipMaps = true; if(faceTexture->hasMipmaps()) bMipMaps = true;
faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle); faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim);
} }
} }
@@ -100,12 +93,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP)); GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
} }
}
if(prev_handle != 0) {
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
GLDEBUG(glDeleteTextures(1, &prev_handle));
}
return success; return success;
} }
@@ -141,6 +129,7 @@ void KRTextureCube::resetPoolExpiry()
void KRTextureCube::bind(GLuint texture_unit) void KRTextureCube::bind(GLuint texture_unit)
{ {
KRTexture::bind(texture_unit);
GLuint handle = getHandle(); GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle)); GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle));
if(handle) { if(handle) {

View File

@@ -39,7 +39,7 @@
#include "KRTextureAnimated.h" #include "KRTextureAnimated.h"
#include "KRContext.h" #include "KRContext.h"
KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) { KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context), m_streamer(context) {
m_textureMemUsed = 0; m_textureMemUsed = 0;
for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
@@ -215,9 +215,20 @@ long KRTextureManager::getMemActive() {
void KRTextureManager::startFrame(float deltaTime) void KRTextureManager::startFrame(float deltaTime)
{ {
m_streamer.startStreamer();
_clearGLState(); _clearGLState();
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) {
KRTexture *activeTexture = *itr;
activeTexture->_swapHandles();
}
// TODO - Implement proper double-buffering to reduce copy operations
m_streamerFenceMutex.lock();
m_activeTextures_streamer_copy = m_activeTextures;
m_poolTextures_streamer_copy = m_poolTextures;
m_streamerFenceMutex.unlock();
m_memoryTransferredThisFrame = 0; m_memoryTransferredThisFrame = 0;
balanceTextureMemory();
rotateBuffers(); rotateBuffers();
} }
@@ -230,6 +241,17 @@ void KRTextureManager::endFrame(float deltaTime)
} }
} }
void KRTextureManager::doStreaming()
{
// TODO - Implement proper double-buffering to reduce copy operations
m_streamerFenceMutex.lock();
m_activeTextures_streamer = m_activeTextures_streamer_copy;
m_poolTextures_streamer = m_poolTextures_streamer_copy;
m_streamerFenceMutex.unlock();
balanceTextureMemory();
}
void KRTextureManager::balanceTextureMemory() void KRTextureManager::balanceTextureMemory()
{ {
// Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures
@@ -237,14 +259,14 @@ void KRTextureManager::balanceTextureMemory()
// Determine the additional amount of memory required in order to resize all active textures to the maximum size // Determine the additional amount of memory required in order to resize all active textures to the maximum size
long wantedTextureMem = 0; long wantedTextureMem = 0;
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize(); wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize();
} }
// Determine how much memory we need to free up // Determine how much memory we need to free up
long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_MAX_TEXTURE_MEM - getMemUsed()); long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed());
// Determine how many mip map levels we need to strip off of inactive textures to free the memory we need // Determine how many mip map levels we need to strip off of inactive textures to free the memory we need
@@ -254,7 +276,7 @@ void KRTextureManager::balanceTextureMemory()
maxDimInactive = maxDimInactive >> 1; maxDimInactive = maxDimInactive >> 1;
potentialMemorySaving = 0; potentialMemorySaving = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr; KRTexture *poolTexture = *itr;
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) { if(potentialMemoryDelta < 0) {
@@ -265,12 +287,19 @@ void KRTextureManager::balanceTextureMemory()
// Strip off mipmap levels of inactive textures to free up memory // Strip off mipmap levels of inactive textures to free up memory
long inactive_texture_mem_used_target = 0; long inactive_texture_mem_used_target = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr; KRTexture *poolTexture = *itr;
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); long mem_required = poolTexture->getMemRequiredForSize(maxDimInactive);
long potentialMemoryDelta = mem_required - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) { if(potentialMemoryDelta < 0) {
if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) {
long mem_free;
m_pContext->getMemoryStats(mem_free);
if(mem_required * 2 < mem_free - 10000000) {
poolTexture->resize(maxDimInactive); poolTexture->resize(maxDimInactive);
inactive_texture_mem_used_target += poolTexture->getMemRequiredForSize(maxDimInactive); }
}
inactive_texture_mem_used_target += mem_required;
} else { } else {
inactive_texture_mem_used_target += poolTexture->getMemSize(); inactive_texture_mem_used_target += poolTexture->getMemSize();
} }
@@ -280,8 +309,8 @@ void KRTextureManager::balanceTextureMemory()
long memory_available = 0; long memory_available = 0;
long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM; long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM;
while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) { while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) {
memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target; memory_available = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - inactive_texture_mem_used_target;
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
memory_available -= activeTexture->getMemRequiredForSize(maxDimActive); memory_available -= activeTexture->getMemRequiredForSize(maxDimActive);
} }
@@ -292,10 +321,17 @@ void KRTextureManager::balanceTextureMemory()
} }
// Resize active textures to balance the memory usage and mipmap levels // Resize active textures to balance the memory usage and mipmap levels
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
long mem_required = activeTexture->getMemRequiredForSize(maxDimActive);
if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) {
long mem_free;
m_pContext->getMemoryStats(mem_free);
if(mem_required * 2 < mem_free - 10000000) {
activeTexture->resize(maxDimActive); activeTexture->resize(maxDimActive);
} }
}
}
//fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive); //fprintf(stderr, "Active mipmap size: %i Inactive mapmap size: %i\n", (int)maxDimActive, (int)maxDimInactive);
} }
@@ -310,7 +346,7 @@ void KRTextureManager::rotateBuffers()
KRTexture *poolTexture = *itr; KRTexture *poolTexture = *itr;
if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) { if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) {
expiredTextures.insert(poolTexture); expiredTextures.insert(poolTexture);
poolTexture->releaseHandle(); poolTexture->releaseHandles();
} }
} }
for(std::set<KRTexture *>::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) {
@@ -318,6 +354,7 @@ void KRTextureManager::rotateBuffers()
} }
// ----====---- Swap the buffers ----====---- // ----====---- Swap the buffers ----====----
m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end()); m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end());
m_activeTextures.clear(); m_activeTextures.clear();
} }
@@ -335,6 +372,7 @@ void KRTextureManager::addMemoryTransferredThisFrame(long memoryTransferred)
void KRTextureManager::memoryChanged(long memoryDelta) void KRTextureManager::memoryChanged(long memoryDelta)
{ {
m_textureMemUsed += memoryDelta; m_textureMemUsed += memoryDelta;
//fprintf(stderr, "Texture Memory: %ld / %i\n", (long)m_textureMemUsed, KRContext::KRENGINE_MAX_TEXTURE_MEM);
} }
unordered_map<std::string, KRTexture *> &KRTextureManager::getTextures() unordered_map<std::string, KRTexture *> &KRTextureManager::getTextures()

View File

@@ -39,6 +39,7 @@
#include "KREngine-common.h" #include "KREngine-common.h"
#include "KRDataBlock.h" #include "KRDataBlock.h"
#include "KRContext.h" #include "KRContext.h"
#include "KRTextureStreamer.h"
class KRTextureManager : public KRContextObject { class KRTextureManager : public KRContextObject {
public: public:
@@ -77,6 +78,8 @@ public:
void _clearGLState(); void _clearGLState();
void setMaxAnisotropy(float max_anisotropy); void setMaxAnisotropy(float max_anisotropy);
void doStreaming();
private: private:
int m_iActiveTexture; int m_iActiveTexture;
@@ -88,13 +91,24 @@ private:
GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS];
GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS];
float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS]; float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS];
std::set<KRTexture *> m_activeTextures; std::set<KRTexture *> m_activeTextures;
std::set<KRTexture *> m_poolTextures; std::set<KRTexture *> m_poolTextures;
long m_textureMemUsed; std::set<KRTexture *> m_activeTextures_streamer;
std::set<KRTexture *> m_poolTextures_streamer;
std::set<KRTexture *> m_activeTextures_streamer_copy;
std::set<KRTexture *> m_poolTextures_streamer_copy;
std::atomic<long> m_textureMemUsed;
void rotateBuffers(); void rotateBuffers();
void balanceTextureMemory(); void balanceTextureMemory();
KRTextureStreamer m_streamer;
std::mutex m_streamerFenceMutex;
}; };
#endif #endif

View File

@@ -64,8 +64,11 @@ typedef struct _PVRTexHeader
KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) { KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart();
uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK; PVRTexHeader header;
m_pData->copy(&header, 0, sizeof(PVRTexHeader));
uint32_t formatFlags = header.flags & PVR_TEXTURE_FLAG_TYPE_MASK;
if (formatFlags == kPVRTextureFlagTypePVRTC_4) { if (formatFlags == kPVRTextureFlagTypePVRTC_4) {
m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
} else if(formatFlags == kPVRTextureFlagTypePVRTC_2) { } else if(formatFlags == kPVRTextureFlagTypePVRTC_2) {
@@ -74,7 +77,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
assert(false); assert(false);
} }
uint32_t pvrTag = header->pvrTag; uint32_t pvrTag = header.pvrTag;
if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) || if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) || gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) || gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
@@ -82,12 +85,12 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
assert(false); assert(false);
} }
m_iWidth = header->width; // Note: call __builtin_bswap32 when needed to switch endianness m_iWidth = header.width; // Note: call __builtin_bswap32 when needed to switch endianness
m_iHeight = header->height; m_iHeight = header.height;
m_bHasAlpha = header->bitmaskAlpha; m_bHasAlpha = header.bitmaskAlpha;
uint8_t *bytes = ((uint8_t *)m_pData->getStart()) + sizeof(PVRTexHeader); uint32_t dataStart = sizeof(PVRTexHeader);
uint32_t dataLength = header->dataLength, dataOffset = 0, dataSize = 0; uint32_t dataLength = header.dataLength, dataOffset = 0, dataSize = 0;
uint32_t width = m_iWidth, height = m_iHeight, bpp = 4; uint32_t width = m_iWidth, height = m_iHeight, bpp = 4;
uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0; uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0;
@@ -114,11 +117,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
} }
dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8); dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
dataBlockStruct newBlock; m_blocks.push_back(m_pData->getSubBlock(dataStart + dataOffset, dataSize));
newBlock.start = bytes+dataOffset;
newBlock.length = dataSize;
m_blocks.push_back(newBlock);
dataOffset += dataSize; dataOffset += dataSize;
@@ -134,12 +133,15 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight; m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight;
m_min_lod_max_dim = width > height ? width : height; m_min_lod_max_dim = width > height ? width : height;
#endif #endif
} }
KRTexturePVR::~KRTexturePVR() { KRTexturePVR::~KRTexturePVR() {
for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
KRDataBlock *block = *itr;
delete block;
}
m_blocks.clear();
} }
long KRTexturePVR::getMemRequiredForSize(int max_dim) long KRTexturePVR::getMemRequiredForSize(int max_dim)
@@ -152,10 +154,10 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
int height = m_iHeight; int height = m_iHeight;
long memoryRequired = 0; long memoryRequired = 0;
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
dataBlockStruct block = *itr; KRDataBlock *block = *itr;
if(width <= target_dim && height <= target_dim) { if(width <= target_dim && height <= target_dim) {
memoryRequired += block.length; memoryRequired += block->getSize();
} }
width = width >> 1; width = width >> 1;
@@ -171,13 +173,11 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
return memoryRequired; return memoryRequired;
} }
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim)
{ {
int target_dim = lod_max_dim; int target_dim = lod_max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
GLenum err;
if(m_blocks.size() == 0) { if(m_blocks.size() == 0) {
return false; return false;
} }
@@ -196,7 +196,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
int level_count=0; int level_count=0;
int max_lod_width=0; int max_lod_width=0;
int max_lod_height=0; int max_lod_height=0;
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
if(width <= target_dim && height <= target_dim) { if(width <= target_dim && height <= target_dim) {
if(max_lod_width == 0) { if(max_lod_width == 0) {
max_lod_width = width; max_lod_width = width;
@@ -229,8 +229,8 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
// Upload texture data // Upload texture data
int destination_level=0; int destination_level=0;
int source_level = 0; int source_level = 0;
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) { for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
dataBlockStruct block = *itr; KRDataBlock *block = *itr;
if(width <= target_dim && height <= target_dim) { if(width <= target_dim && height <= target_dim) {
if(width > current_lod_max_dim) { if(width > current_lod_max_dim) {
@@ -243,22 +243,25 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) { if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) {
//GLDEBUG(glCompressedTexImage2D(target, i, m_internalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy //GLDEBUG(glCompressedTexImage2D(target, i, m_internalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy
// GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL)); // GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
GLDEBUG(glCopyTextureLevelsAPPLE(m_iHandle, prev_handle, source_level, 1)); GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1));
} else { } else {
// glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); block->lock();
GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, block.start)); GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, (GLsizei)block->getSize(), block->getStart()));
// GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start)); block->unlock();
memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE
memoryTransferred += block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE
} }
#else #else
block->lock();
#if GL_EXT_texture_storage #if GL_EXT_texture_storage
GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, block.start)); GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block->getSize(), block->getStart()));
#else #else
GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start)); GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block->getSize(), block->getStart()));
#endif #endif
memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE block->unlock();
memoryTransferred += block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE
#endif #endif
memoryRequired += block.length; memoryRequired += block->getSize();
// //
// err = glGetError(); // err = glGetError();
// if (err != GL_NO_ERROR) { // if (err != GL_NO_ERROR) {
@@ -284,10 +287,6 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
} }
} }
textureMemUsed += memoryRequired;
getContext().getTextureManager()->memoryChanged(memoryTransferred);
getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred);
return true; return true;
} }

View File

@@ -18,7 +18,7 @@ public:
virtual ~KRTexturePVR(); virtual ~KRTexturePVR();
virtual std::string getExtension(); virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle); bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim);
virtual long getMemRequiredForSize(int max_dim); virtual long getMemRequiredForSize(int max_dim);
@@ -29,12 +29,7 @@ protected:
GLenum m_internalFormat; GLenum m_internalFormat;
bool m_bHasAlpha; bool m_bHasAlpha;
struct dataBlockStruct { std::list<KRDataBlock *> m_blocks;
void *start;
uint32_t length;
};
std::list<dataBlockStruct> m_blocks;
}; };
#endif #endif

View File

@@ -0,0 +1,61 @@
//
// KRTextureManager.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 KRTEXTURESTREAMER_H
#define KRTEXTURESTREAMER_H
#include "KREngine-common.h"
#include <thread>
#include <atomic>
class KRContext;
class KRTextureStreamer
{
public:
KRTextureStreamer(KRContext &context);
~KRTextureStreamer();
void startStreamer();
private:
KRContext &m_context;
std::thread m_thread;
std::atomic<bool> m_stop;
std::atomic<bool> m_running;
void run();
};
#endif /* defined(KRTEXTURESTREAMER_H) */

View File

@@ -0,0 +1,57 @@
//
// KRTextureStreamer.cpp
// Kraken
//
// Created by Kearwood Gilbert on 11/1/2013.
// Copyright (c) 2013 Kearwood Software. All rights reserved.
//
#include "KREngine-common.h"
#include "KRTextureStreamer.h"
#include "KRContext.h"
#include <chrono>
EAGLContext *gTextureStreamerContext = nil;
KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context)
{
m_running = false;
m_stop = false;
}
void KRTextureStreamer::startStreamer()
{
if(!m_running) {
m_running = true;
gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup];
m_thread = std::thread(&KRTextureStreamer::run, this);
}
}
KRTextureStreamer::~KRTextureStreamer()
{
m_stop = true;
m_thread.join();
[gTextureStreamerContext release];
}
void KRTextureStreamer::run()
{
pthread_setname_np("Kraken - Texture Streamer");
std::chrono::microseconds sleep_duration( 100 );
[EAGLContext setCurrentContext: gTextureStreamerContext];
while(!m_stop)
{
if(m_context.getStreamingEnabled()) {
m_context.getTextureManager()->doStreaming();
}
std::this_thread::sleep_for( sleep_duration );
}
m_running = false;
}

View File

@@ -28,10 +28,40 @@ typedef struct {
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
{ {
data->lock();
TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart(); TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart();
m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height; m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height;
m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images
switch(pHeader->imagetype) {
case 2: // rgb
switch(pHeader->bitsperpixel) {
case 24:
{
m_imageSize = pHeader->width * pHeader->height * 4;
}
break;
case 32:
{
m_imageSize = pHeader->width * pHeader->height * 4;
}
break;
default:
{
assert(false);
}
break;
}
break;
default:
{
assert(false);
break;
}
}
data->unlock();
} }
KRTextureTGA::~KRTextureTGA() KRTextureTGA::~KRTextureTGA()
@@ -39,12 +69,14 @@ KRTextureTGA::~KRTextureTGA()
} }
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim)
{ {
m_pData->lock();
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();
unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER); unsigned char *pData = (unsigned char *)pHeader + (long)pHeader->idlength + (long)pHeader->colourmaplength * (long)pHeader->colourmaptype + sizeof(TGA_HEADER);
if(pHeader->colourmaptype != 0) { if(pHeader->colourmaptype != 0) {
m_pData->unlock();
return false; // Mapped colors not supported return false; // Mapped colors not supported
} }
@@ -73,15 +105,12 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
} }
//#endif //#endif
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image); glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image);
delete converted_image; free(converted_image);
err = glGetError(); err = glGetError();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
m_pData->unlock();
return false; return false;
} }
int memAllocated = pHeader->width * pHeader->height * 4;
textureMemUsed += memAllocated;
getContext().getTextureManager()->memoryChanged(memAllocated);
getContext().getTextureManager()->addMemoryTransferredThisFrame(memAllocated);
current_lod_max_dim = m_max_lod_max_dim; current_lod_max_dim = m_max_lod_max_dim;
} }
break; break;
@@ -90,47 +119,29 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData); glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData);
err = glGetError(); err = glGetError();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
m_pData->unlock();
return false; return false;
} }
int memAllocated = pHeader->width * pHeader->height * 4;
textureMemUsed += memAllocated;
getContext().getTextureManager()->memoryChanged(memAllocated);
getContext().getTextureManager()->addMemoryTransferredThisFrame(memAllocated);
current_lod_max_dim = m_max_lod_max_dim; current_lod_max_dim = m_max_lod_max_dim;
} }
break; break;
default: default:
m_pData->unlock();
return false; // 16-bit images not yet supported return false; // 16-bit images not yet supported
} }
break; break;
default: default:
m_pData->unlock();
return false; // Image type not yet supported return false; // Image type not yet supported
} }
m_pData->unlock();
return true; return true;
} }
long KRTextureTGA::getMemRequiredForSize(int max_dim) long KRTextureTGA::getMemRequiredForSize(int max_dim)
{ {
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart(); return m_imageSize;
switch(pHeader->imagetype) {
case 2: // rgb
switch(pHeader->bitsperpixel) {
case 24:
{
return pHeader->width * pHeader->height * 4;
}
break;
case 32:
{
return pHeader->width * pHeader->height * 4;
}
break;
}
break;
}
return 0;
} }
std::string KRTextureTGA::getExtension() std::string KRTextureTGA::getExtension()

View File

@@ -18,9 +18,11 @@ public:
virtual ~KRTextureTGA(); virtual ~KRTextureTGA();
virtual std::string getExtension(); virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle); bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim);
virtual long getMemRequiredForSize(int max_dim); virtual long getMemRequiredForSize(int max_dim);
private:
long m_imageSize;
}; };
#endif #endif