Merged async_streaming branch into default.
This commit is contained in:
@@ -73,6 +73,18 @@
|
||||
E43B0AD715DDCA0F00A5CB9F /* KRContextObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43B0AD415DDCA0C00A5CB9F /* KRContextObject.cpp */; };
|
||||
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, ); }; };
|
||||
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 */; };
|
||||
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, ); }; };
|
||||
@@ -109,6 +121,10 @@
|
||||
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, ); }; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
@@ -419,6 +435,12 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
@@ -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; };
|
||||
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; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@@ -878,6 +902,8 @@
|
||||
E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */,
|
||||
E460292516681CFE00261BB9 /* KRTextureAnimated.h */,
|
||||
E460292716681D1000261BB9 /* KRTextureAnimated.cpp */,
|
||||
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */,
|
||||
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */,
|
||||
);
|
||||
name = Texture;
|
||||
sourceTree = "<group>";
|
||||
@@ -893,6 +919,8 @@
|
||||
E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */,
|
||||
E4C454B1167BC04B003586CD /* KRMeshSphere.h */,
|
||||
E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */,
|
||||
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */,
|
||||
E43F70FE1824E73100136169 /* KRMeshStreamer.h */,
|
||||
);
|
||||
name = Mesh;
|
||||
sourceTree = "<group>";
|
||||
@@ -971,6 +999,10 @@
|
||||
E480BE6B1671C653004EC8AD /* KRBone.cpp */,
|
||||
E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */,
|
||||
E4AE635C1704FB0A00B460CD /* KRLODGroup.h */,
|
||||
E468447D17FFDF51001F1FA1 /* KRLocator.cpp */,
|
||||
E468447E17FFDF51001F1FA1 /* KRLocator.h */,
|
||||
E43F70DA181B20E300136169 /* KRLODSet.cpp */,
|
||||
E43F70DB181B20E400136169 /* KRLODSet.h */,
|
||||
);
|
||||
name = "Scene Graph Nodes";
|
||||
sourceTree = "<group>";
|
||||
@@ -1180,6 +1212,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E43F70DE181B20E400136169 /* KRLODSet.h in Headers */,
|
||||
E491019513C99BDC0098455B /* KRMaterial.h in Headers */,
|
||||
E491019C13C99BDC0098455B /* KRMaterialManager.h in Headers */,
|
||||
E491019D13C99BDC0098455B /* KRTextureManager.h in Headers */,
|
||||
@@ -1198,6 +1231,8 @@
|
||||
E461A152152E54B500F2044A /* KRLight.h in Headers */,
|
||||
E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */,
|
||||
E461A168152E570700F2044A /* KRSpotLight.h in Headers */,
|
||||
E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */,
|
||||
E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */,
|
||||
E4F975321536220900FD60B2 /* KRNode.h in Headers */,
|
||||
E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */,
|
||||
E48C696F15374F5B00232E28 /* KRContext.h in Headers */,
|
||||
@@ -1246,6 +1281,7 @@
|
||||
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */,
|
||||
E4EC73C31720B1FF0065299F /* KRVector4.h in Headers */,
|
||||
E48CF944173453990005EBBB /* KRFloat.h in Headers */,
|
||||
E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */,
|
||||
E45134B81746A4A300443C21 /* KRBehavior.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1257,6 +1293,7 @@
|
||||
E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */,
|
||||
E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */,
|
||||
E461A177152E5C6600F2044A /* KRMat4.h in Headers */,
|
||||
E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */,
|
||||
E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */,
|
||||
E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */,
|
||||
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */,
|
||||
@@ -1272,7 +1309,9 @@
|
||||
E4F9754C153632F000FD60B2 /* KRCamera.h in Headers */,
|
||||
E4F975501536333500FD60B2 /* KRMesh.h in Headers */,
|
||||
E488399F15F92BE000BD66D5 /* KRBundleManager.h in Headers */,
|
||||
E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */,
|
||||
E4AFC6BC15F7C95D00DDB4C8 /* KRSceneManager.h in Headers */,
|
||||
E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */,
|
||||
E428C2F31669610500A16EDF /* KRAnimationManager.h in Headers */,
|
||||
E4D133661537685A0070068C /* KRShader.h in Headers */,
|
||||
E461A153152E54B500F2044A /* KRLight.h in Headers */,
|
||||
@@ -1289,6 +1328,7 @@
|
||||
E428C312166971FF00A16EDF /* KRAnimationLayer.h in Headers */,
|
||||
E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */,
|
||||
E428C3171669A24B00A16EDF /* KRAnimationAttribute.h in Headers */,
|
||||
E43F70DF181B20E400136169 /* KRLODSet.h in Headers */,
|
||||
E4AFC6BE15F7C9E600DDB4C8 /* KROctreeNode.h in Headers */,
|
||||
E4AFC6BD15F7C9DA00DDB4C8 /* KROctree.h in Headers */,
|
||||
E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */,
|
||||
@@ -1536,14 +1576,17 @@
|
||||
E491019A13C99BDC0098455B /* KRMeshManager.cpp in Sources */,
|
||||
E47C25A713F4F6AB00FF4370 /* KRShaderManager.cpp in Sources */,
|
||||
E47C25A913F4F6DD00FF4370 /* KRShader.cpp in Sources */,
|
||||
E43F70DC181B20E400136169 /* KRLODSet.cpp in Sources */,
|
||||
E414BAE51435558900A668C4 /* KRModel.cpp in Sources */,
|
||||
E414BAE91435585A00A668C4 /* KRScene.cpp in Sources */,
|
||||
E48B3CC014393E30000C50E2 /* KRCamera.cpp in Sources */,
|
||||
E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */,
|
||||
E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */,
|
||||
E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
|
||||
E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */,
|
||||
E461A156152E54F800F2044A /* KRLight.cpp in Sources */,
|
||||
E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */,
|
||||
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
|
||||
E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */,
|
||||
E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */,
|
||||
E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */,
|
||||
@@ -1566,6 +1609,7 @@
|
||||
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */,
|
||||
E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */,
|
||||
E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */,
|
||||
E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
|
||||
E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */,
|
||||
E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */,
|
||||
E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */,
|
||||
@@ -1607,6 +1651,7 @@
|
||||
E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */,
|
||||
E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */,
|
||||
E4BBBB8E1512A40300F43B5B /* krengine_osx.mm in Sources */,
|
||||
E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
|
||||
E497B947151BA99500D3DC67 /* KRVector2.cpp in Sources */,
|
||||
E497B94E151BCF2500D3DC67 /* KRResource.cpp in Sources */,
|
||||
E497B951151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
|
||||
@@ -1636,6 +1681,8 @@
|
||||
E40BA45515EFF79500D7C3DD /* KRAABB.cpp in Sources */,
|
||||
E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */,
|
||||
E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */,
|
||||
E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */,
|
||||
E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */,
|
||||
E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */,
|
||||
E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */,
|
||||
E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */,
|
||||
@@ -1651,6 +1698,7 @@
|
||||
E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */,
|
||||
E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */,
|
||||
E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */,
|
||||
E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
|
||||
E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */,
|
||||
E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */,
|
||||
E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */,
|
||||
@@ -1701,21 +1749,22 @@
|
||||
E491016913C99B9E0098455B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||
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_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
"$(SRCROOT)/3rdparty/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
|
||||
LLVM_VECTORIZE_LOOPS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -1725,18 +1774,20 @@
|
||||
E491016A13C99B9E0098455B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_UNROLL_LOOPS = YES;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
"$(SRCROOT)/3rdparty/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
|
||||
LLVM_VECTORIZE_LOOPS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -1747,6 +1798,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/KREngine.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1754,7 +1806,7 @@
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
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 = (
|
||||
"$(inherited)",
|
||||
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
|
||||
@@ -1762,7 +1814,6 @@
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = kraken;
|
||||
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1771,6 +1822,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/KREngine.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1778,7 +1830,7 @@
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
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 = (
|
||||
"$(inherited)",
|
||||
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
|
||||
@@ -1786,7 +1838,6 @@
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = kraken;
|
||||
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders";
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -85,9 +85,10 @@ bool KRAnimation::save(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;
|
||||
doc.Parse((char *)data->getStart());
|
||||
doc.Parse(xml_string.c_str());
|
||||
KRAnimation *new_animation = new KRAnimation(context, name);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
void deleteCurves();
|
||||
|
||||
void _lockData();
|
||||
void _unlockData();
|
||||
|
||||
private:
|
||||
unordered_map<std::string, KRAnimationLayer *> m_layers;
|
||||
bool m_auto_play;
|
||||
|
||||
@@ -37,11 +37,13 @@ KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name)
|
||||
{
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->expand(sizeof(animation_curve_header));
|
||||
m_pData->lock();
|
||||
animation_curve_header *header = (animation_curve_header *)m_pData->getStart();
|
||||
strcpy(header->szTag, "KRCURVE1.0 ");
|
||||
header->frame_rate = 30.0f;
|
||||
header->frame_start = 0;
|
||||
header->frame_count = 0;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
KRAnimationCurve::~KRAnimationCurve()
|
||||
@@ -84,11 +86,16 @@ KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &
|
||||
|
||||
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)
|
||||
{
|
||||
m_pData->lock();
|
||||
int prev_frame_count = getFrameCount();
|
||||
if(frame_count != prev_frame_count) {
|
||||
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;
|
||||
}
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_pData->lock();
|
||||
((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_pData->lock();
|
||||
((animation_curve_header *)m_pData->getStart())->frame_start = frame_number;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
float KRAnimationCurve::getValue(int frame_number)
|
||||
{
|
||||
m_pData->lock();
|
||||
//printf("frame_number: %i\n", frame_number);
|
||||
int clamped_frame = frame_number - getFrameStart();
|
||||
if(clamped_frame < 0) {
|
||||
@@ -134,43 +153,56 @@ float KRAnimationCurve::getValue(int frame_number)
|
||||
clamped_frame = getFrameCount()-1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
m_pData->lock();
|
||||
int clamped_frame = frame_number - getFrameStart();
|
||||
if(clamped_frame >= 0 && clamped_frame < getFrameCount()) {
|
||||
float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header));
|
||||
frame_data[clamped_frame] = value;
|
||||
}
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
float KRAnimationCurve::getValue(float local_time)
|
||||
{
|
||||
// TODO - Need to add interpolation for time values between frames.
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
m_pData->lock();
|
||||
float first_value = getValue(start_frame);
|
||||
|
||||
bool change_found = false;
|
||||
|
||||
// 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) {
|
||||
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)
|
||||
@@ -185,12 +217,24 @@ KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_fra
|
||||
new_curve->setFrameRate(getFrameRate());
|
||||
new_curve->setFrameStart(start_frame);
|
||||
new_curve->setFrameCount(frame_count);
|
||||
new_curve->m_pData->lock();
|
||||
|
||||
// Range of frames is not inclusive of last frame
|
||||
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->m_pData->unlock();
|
||||
|
||||
getContext().getAnimationCurveManager()->addAnimationCurve(new_curve);
|
||||
return new_curve;
|
||||
}
|
||||
|
||||
void KRAnimationCurve::_lockData()
|
||||
{
|
||||
m_pData->lock();
|
||||
}
|
||||
|
||||
void KRAnimationCurve::_unlockData()
|
||||
{
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ public:
|
||||
KRAnimationCurve *split(const std::string &name, float start_time, float duration);
|
||||
KRAnimationCurve *split(const std::string &name, int start_frame, int frame_count);
|
||||
|
||||
void _lockData();
|
||||
void _unlockData();
|
||||
|
||||
private:
|
||||
KRDataBlock *m_pData;
|
||||
|
||||
|
||||
@@ -38,6 +38,11 @@ KRAnimationManager::KRAnimationManager(KRContext &context) : KRContextObject(con
|
||||
}
|
||||
|
||||
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){
|
||||
delete (*itr).second;
|
||||
}
|
||||
@@ -52,11 +57,13 @@ void KRAnimationManager::startFrame(float deltaTime)
|
||||
// Add playing animations to the active animations list
|
||||
if(active_animations_itr == m_activeAnimations.end()) {
|
||||
m_activeAnimations.insert(animation);
|
||||
animation->_lockData();
|
||||
}
|
||||
} else {
|
||||
// Remove stopped animations from the active animations list
|
||||
if(active_animations_itr != m_activeAnimations.end()) {
|
||||
m_activeAnimations.erase(active_animations_itr);
|
||||
animation->_unlockData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,8 +214,8 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
|
||||
|
||||
|
||||
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 max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100;
|
||||
// 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;
|
||||
// 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->expand(size);
|
||||
}
|
||||
|
||||
data->lock();
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
void KRAudioManager::recycleBufferData(KRDataBlock *data)
|
||||
{
|
||||
if(data != NULL) {
|
||||
data->unlock();
|
||||
if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) {
|
||||
m_bufferPoolIdle.push_back(data);
|
||||
} else {
|
||||
|
||||
@@ -198,7 +198,7 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc
|
||||
KRAudioSample *sound = (KRAudioSample *)inClientData;
|
||||
UInt32 max_count = sound->m_pData->getSize() - inPosition;
|
||||
*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;
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ void KRAudioSample::openFile()
|
||||
{
|
||||
// AudioFileInitializeWithCallbacks
|
||||
if(m_fileRef == NULL) {
|
||||
|
||||
// Temp variables
|
||||
UInt32 propertySize;
|
||||
|
||||
|
||||
@@ -53,35 +53,18 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
|
||||
{
|
||||
m_pData = pData;
|
||||
|
||||
unsigned char *pFile = (unsigned char *)m_pData->getStart();
|
||||
while(pFile < m_pData->getEnd() ) {
|
||||
tar_header_type *file_header = (tar_header_type *)pFile;
|
||||
size_t file_size = strtol(file_header->file_size, NULL, 8);
|
||||
pFile += 512; // Skip past the header to the file contents
|
||||
|
||||
if(file_header->file_name[0] != '\0' && file_header->file_name[0] != '.') {
|
||||
__int64_t file_pos = 0;
|
||||
while(file_pos < m_pData->getSize()) {
|
||||
tar_header_type file_header;
|
||||
m_pData->copy(&file_header, file_pos, sizeof(file_header));
|
||||
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] != '.') {
|
||||
// We ignore the last two records in the tar file, which are zero'ed out tar_header structures
|
||||
KRDataBlock *pFileData = new KRDataBlock();
|
||||
if(pFileData->load(pFile, file_size)) {
|
||||
context.loadResource(file_header->file_name, pFileData);
|
||||
} else {
|
||||
delete pFileData;
|
||||
assert(false);
|
||||
KRDataBlock *pFileData = pData->getSubBlock(file_pos, file_size);
|
||||
context.loadResource(file_header.file_name, pFileData);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
file_pos += 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.
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2);
|
||||
m_pData->lock();
|
||||
memset(m_pData->getStart(), 0, m_pData->getSize());
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
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->lock();
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -149,7 +136,9 @@ void KRBundle::append(KRResource &resource)
|
||||
memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE);
|
||||
|
||||
// Copy resource data
|
||||
resource_data.lock();
|
||||
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
|
||||
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];
|
||||
}
|
||||
sprintf(file_header->checksum, "%07o", check_sum);
|
||||
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
@@ -54,14 +54,9 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) {
|
||||
volumetricLightAccumulationBuffer = 0;
|
||||
volumetricLightAccumulationTexture = 0;
|
||||
m_frame_times_filled = 0;
|
||||
|
||||
m_debug_text_vertices = NULL;
|
||||
}
|
||||
|
||||
KRCamera::~KRCamera() {
|
||||
if(m_debug_text_vertices) {
|
||||
delete m_debug_text_vertices;
|
||||
}
|
||||
destroyBuffers();
|
||||
}
|
||||
|
||||
@@ -315,7 +310,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
||||
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
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++) {
|
||||
KRMat4 matModel = KRMat4();
|
||||
matModel.scale((*itr).first.size() * 0.5f);
|
||||
@@ -704,7 +699,7 @@ void KRCamera::renderPost()
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
@@ -726,7 +721,7 @@ void KRCamera::renderPost()
|
||||
// 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);
|
||||
// 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);
|
||||
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||
//#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);
|
||||
}
|
||||
|
||||
@@ -791,12 +786,13 @@ void KRCamera::renderPost()
|
||||
const int DEBUG_TEXT_COLUMNS = 256;
|
||||
const int DEBUG_TEXT_ROWS = 128;
|
||||
|
||||
if(m_debug_text_vertices == NULL) {
|
||||
m_debug_text_vertices = new DebugTextVertexData[DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6];
|
||||
if(m_debug_text_vertices.getSize() == 0) {
|
||||
m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6);
|
||||
}
|
||||
int vertex_count = 0;
|
||||
|
||||
|
||||
m_debug_text_vertices.lock();
|
||||
DebugTextVertexData *vertex_data = (DebugTextVertexData *)m_debug_text_vertices.getStart();
|
||||
|
||||
pChar = szText;
|
||||
float dScaleX = 2.0 / (1024 / 16);
|
||||
@@ -824,47 +820,47 @@ void KRCamera::renderPost()
|
||||
KRVector2 top_left_uv = KRVector2(dTexScale * iTexCol, dTexScale * iTexRow);
|
||||
KRVector2 bottom_right_uv = KRVector2(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale);
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = top_left_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = top_left_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = top_left_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = top_left_uv.y;
|
||||
vertex_data[vertex_count].x = top_left_pos.x;
|
||||
vertex_data[vertex_count].y = top_left_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = top_left_uv.x;
|
||||
vertex_data[vertex_count].v = top_left_uv.y;
|
||||
vertex_count++;
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_data[vertex_count].x = bottom_right_pos.x;
|
||||
vertex_data[vertex_count].y = bottom_right_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = bottom_right_uv.x;
|
||||
vertex_data[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_count++;
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = top_left_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = top_left_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_data[vertex_count].x = top_left_pos.x;
|
||||
vertex_data[vertex_count].y = bottom_right_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = top_left_uv.x;
|
||||
vertex_data[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_count++;
|
||||
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = top_left_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = top_left_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = top_left_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = top_left_uv.y;
|
||||
vertex_data[vertex_count].x = top_left_pos.x;
|
||||
vertex_data[vertex_count].y = top_left_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = top_left_uv.x;
|
||||
vertex_data[vertex_count].v = top_left_uv.y;
|
||||
vertex_count++;
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = top_left_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = top_left_uv.y;
|
||||
vertex_data[vertex_count].x = bottom_right_pos.x;
|
||||
vertex_data[vertex_count].y = top_left_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = bottom_right_uv.x;
|
||||
vertex_data[vertex_count].v = top_left_uv.y;
|
||||
vertex_count++;
|
||||
|
||||
m_debug_text_vertices[vertex_count].x = bottom_right_pos.x;
|
||||
m_debug_text_vertices[vertex_count].y = bottom_right_pos.y;
|
||||
m_debug_text_vertices[vertex_count].z = 0.0f;
|
||||
m_debug_text_vertices[vertex_count].u = bottom_right_uv.x;
|
||||
m_debug_text_vertices[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_data[vertex_count].x = bottom_right_pos.x;
|
||||
vertex_data[vertex_count].y = bottom_right_pos.y;
|
||||
vertex_data[vertex_count].z = 0.0f;
|
||||
vertex_data[vertex_count].u = bottom_right_uv.x;
|
||||
vertex_data[vertex_count].v = bottom_right_uv.y;
|
||||
vertex_count++;
|
||||
}
|
||||
|
||||
@@ -892,18 +888,20 @@ void KRCamera::renderPost()
|
||||
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"));
|
||||
|
||||
|
||||
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);
|
||||
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(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
|
||||
|
||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count));
|
||||
|
||||
// Re-enable z-buffer write
|
||||
GLDEBUG(glDepthMask(GL_TRUE));
|
||||
|
||||
m_debug_text_vertices.unlock();
|
||||
|
||||
} else {
|
||||
if(m_debug_text_vertices) {
|
||||
delete m_debug_text_vertices;
|
||||
m_debug_text_vertices = NULL;
|
||||
if(m_debug_text_vertices.getSize() > 0) {
|
||||
m_debug_text_vertices = KRDataBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
GLfloat v;
|
||||
} DebugTextVertexData;
|
||||
|
||||
DebugTextVertexData *m_debug_text_vertices;
|
||||
KRDataBlock m_debug_text_vertices;
|
||||
|
||||
// std::string getDebugText();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ int KRContext::KRENGINE_MAX_SHADER_HANDLES;
|
||||
int KRContext::KRENGINE_MAX_TEXTURE_HANDLES;
|
||||
int KRContext::KRENGINE_MAX_TEXTURE_MEM;
|
||||
int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX;
|
||||
int KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN;
|
||||
int KRContext::KRENGINE_MAX_TEXTURE_DIM;
|
||||
int KRContext::KRENGINE_MIN_TEXTURE_DIM;
|
||||
int KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT;
|
||||
@@ -27,6 +26,7 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = {
|
||||
};
|
||||
|
||||
KRContext::KRContext() {
|
||||
m_streamingEnabled = false;
|
||||
mach_timebase_info(&m_timebase_info);
|
||||
|
||||
m_bDetectedExtensions = false;
|
||||
@@ -43,7 +43,7 @@ KRContext::KRContext() {
|
||||
m_pAnimationCurveManager = new KRAnimationCurveManager(*this);
|
||||
m_pSoundManager = new KRAudioManager(*this);
|
||||
m_pUnknownManager = new KRUnknownManager(*this);
|
||||
|
||||
m_streamingEnabled = true;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ public:
|
||||
static int KRENGINE_MAX_TEXTURE_HANDLES;
|
||||
static int KRENGINE_MAX_TEXTURE_MEM;
|
||||
static int KRENGINE_TARGET_TEXTURE_MEM_MAX;
|
||||
static int KRENGINE_TARGET_TEXTURE_MEM_MIN;
|
||||
static int KRENGINE_MAX_TEXTURE_DIM;
|
||||
static int KRENGINE_MIN_TEXTURE_DIM;
|
||||
static int KRENGINE_MAX_TEXTURE_THROUGHPUT;
|
||||
@@ -73,6 +72,10 @@ public:
|
||||
long getAbsoluteTimeMilliseconds();
|
||||
|
||||
std::vector<KRResource *> getResources();
|
||||
bool getStreamingEnabled();
|
||||
void setStreamingEnabled(bool enable);
|
||||
|
||||
void getMemoryStats(long &free_memory);
|
||||
|
||||
private:
|
||||
KRBundleManager *m_pBundleManager;
|
||||
@@ -93,6 +96,8 @@ private:
|
||||
float m_absolute_time;
|
||||
|
||||
mach_timebase_info_data_t m_timebase_info;
|
||||
|
||||
std::atomic<bool> m_streamingEnabled;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,12 +30,40 @@
|
||||
//
|
||||
|
||||
#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() {
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -45,10 +73,13 @@ KRDataBlock::~KRDataBlock() {
|
||||
// Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use
|
||||
void KRDataBlock::unload()
|
||||
{
|
||||
assert(m_lockCount == 0);
|
||||
|
||||
if(m_fdPackFile) {
|
||||
// Memory mapped file
|
||||
munmap(m_data, m_data_size);
|
||||
if(m_fileOwnerDataBlock == this) {
|
||||
close(m_fdPackFile);
|
||||
}
|
||||
} else if(m_data != NULL && m_bMalloced) {
|
||||
// Malloc'ed data
|
||||
free(m_data);
|
||||
@@ -57,7 +88,12 @@ void KRDataBlock::unload()
|
||||
m_bMalloced = false;
|
||||
m_data = NULL;
|
||||
m_data_size = 0;
|
||||
m_data_offset = 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
|
||||
@@ -66,6 +102,8 @@ bool KRDataBlock::load(void *data, size_t size)
|
||||
unload();
|
||||
m_data = data;
|
||||
m_data_size = size;
|
||||
m_data_offset = 0;
|
||||
m_bReadOnly = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,16 +114,17 @@ bool KRDataBlock::load(const std::string &path)
|
||||
unload();
|
||||
|
||||
struct stat statbuf;
|
||||
m_bReadOnly = true;
|
||||
m_fdPackFile = open(path.c_str(), O_RDONLY);
|
||||
if(m_fdPackFile >= 0) {
|
||||
m_fileOwnerDataBlock = this;
|
||||
m_fileName = KRResource::GetFileBase(path);
|
||||
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_offset = 0;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!success) {
|
||||
// If anything failed, don't leave the object in an invalid state
|
||||
unload();
|
||||
@@ -93,13 +132,33 @@ bool KRDataBlock::load(const std::string &path)
|
||||
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
|
||||
void *KRDataBlock::getStart() {
|
||||
assertLocked();
|
||||
return m_data;
|
||||
}
|
||||
|
||||
// Return a pointer to the byte after the end of the data block
|
||||
void *KRDataBlock::getEnd() {
|
||||
assertLocked();
|
||||
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
|
||||
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
|
||||
m_data = malloc(size);
|
||||
assert(m_data != NULL);
|
||||
m_data_size = size;
|
||||
m_data_offset = 0;
|
||||
m_bMalloced = true;
|
||||
} else if(m_bMalloced) {
|
||||
// Starting with a malloc'ed data block; realloc it expand
|
||||
m_data = realloc(m_data, m_data_size + size);
|
||||
m_data_size += size;
|
||||
} 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
|
||||
void *pNewData = malloc(m_data_size + size);
|
||||
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
|
||||
size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it
|
||||
unload();
|
||||
m_bMalloced = true;
|
||||
m_data = pNewData;
|
||||
m_data_size = new_size;
|
||||
m_data_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,12 +206,35 @@ void KRDataBlock::append(void *data, size_t size) {
|
||||
expand(size);
|
||||
|
||||
// Fill the new space with the data to append
|
||||
lock();
|
||||
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.
|
||||
void KRDataBlock::append(KRDataBlock &data) {
|
||||
data.lock();
|
||||
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
|
||||
@@ -157,7 +244,7 @@ void KRDataBlock::append(const std::string &s)
|
||||
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) {
|
||||
int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
|
||||
if(fdNewFile == -1) {
|
||||
@@ -173,20 +260,16 @@ bool KRDataBlock::save(const std::string& path) {
|
||||
close(fdNewFile);
|
||||
return false;
|
||||
} else if(m_data != NULL) {
|
||||
|
||||
|
||||
// Copy data to new file
|
||||
memcpy(pNewData, m_data, m_data_size);
|
||||
copy(pNewData);
|
||||
|
||||
// Unload existing data allocation, which is now redundant
|
||||
size_t new_size = m_data_size; // We need to store this, as unload() will reset it
|
||||
unload();
|
||||
// Unmap the new file
|
||||
munmap(pNewData, m_data_size);
|
||||
|
||||
// Protect new mmap'ed memory
|
||||
mprotect(pNewData, m_data_size, PROT_READ);
|
||||
|
||||
// Switch pointer to use new mmap'ed memory
|
||||
m_data_size = new_size;
|
||||
m_fdPackFile = fdNewFile;
|
||||
m_data = pNewData;
|
||||
// Close the new file
|
||||
close(fdNewFile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -198,5 +281,102 @@ std::string KRDataBlock::getString()
|
||||
KRDataBlock b;
|
||||
b.append(*this);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -34,9 +34,12 @@
|
||||
|
||||
#include "KREngine-common.h"
|
||||
|
||||
#define KRENGINE_MIN_MMAP 32768
|
||||
|
||||
class KRDataBlock {
|
||||
public:
|
||||
KRDataBlock();
|
||||
KRDataBlock(void *data, size_t size);
|
||||
~KRDataBlock();
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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.
|
||||
void append(void *data, size_t size);
|
||||
|
||||
@@ -74,15 +80,42 @@ public:
|
||||
|
||||
// Get the contents as a string
|
||||
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:
|
||||
void *m_data;
|
||||
size_t m_data_size;
|
||||
size_t m_data_offset;
|
||||
|
||||
// For memory mapped objects:
|
||||
int m_fdPackFile;
|
||||
std::string m_fileName;
|
||||
KRDataBlock *m_fileOwnerDataBlock;
|
||||
void *m_mmapData;
|
||||
|
||||
// For malloc'ed objects:
|
||||
bool m_bMalloced;
|
||||
|
||||
// Lock refcount
|
||||
int m_lockCount;
|
||||
|
||||
// Read-only allocation
|
||||
bool m_bReadOnly;
|
||||
|
||||
// Assert if not locked
|
||||
void assertLocked();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &
|
||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@
|
||||
#ifndef KRENGINE_COMMON_H
|
||||
#define KRENGINE_COMMON_H
|
||||
|
||||
#define KRENGINE_MAX_TEXTURE_UNITS 8
|
||||
|
||||
float const PI = 3.141592653589793f;
|
||||
float const D2R = PI * 2 / 360;
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -47,6 +46,9 @@ float const D2R = PI * 2 / 360;
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/signals2/mutex.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
|
||||
@@ -69,6 +71,12 @@ using std::queue;
|
||||
#define KRAKEN_HAVE_BLAS 1
|
||||
#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__)
|
||||
#define KRAKEN_USE_ARM_NEON
|
||||
|
||||
@@ -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_TEXTURE_MEM = total_ram * 1 / 8;
|
||||
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_MEM = 64000000 * 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_MIN_TEXTURE_DIM = 64;
|
||||
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_MEM = 64000000;
|
||||
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 48000000;
|
||||
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 32000000;
|
||||
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
|
||||
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
|
||||
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_MEM = 512000000;
|
||||
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MAX = 384000000;
|
||||
KRContext::KRENGINE_TARGET_TEXTURE_MEM_MIN = 256000000;
|
||||
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
|
||||
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
|
||||
KRContext::KRENGINE_MAX_TEXTURE_THROUGHPUT = 128000000;
|
||||
@@ -425,7 +421,7 @@ void kraken::set_debug_text(const std::string &print_text)
|
||||
[self getAmbientIntensity],
|
||||
[self getSunTemperature],
|
||||
[self getSunIntensity],
|
||||
_settings.dof_quality,
|
||||
static_cast<float>(_settings.dof_quality),
|
||||
_settings.dof_depth,
|
||||
_settings.dof_falloff,
|
||||
_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.getPerspectiveNearZ(),
|
||||
_settings.getPerspectiveFarZ(),
|
||||
_settings.volumetric_environment_enable,
|
||||
5 - _settings.volumetric_environment_downsample,
|
||||
static_cast<float>(_settings.volumetric_environment_enable),
|
||||
static_cast<float>(5 - _settings.volumetric_environment_downsample),
|
||||
_settings.volumetric_environment_max_distance,
|
||||
_settings.volumetric_environment_quality,
|
||||
_settings.volumetric_environment_intensity,
|
||||
_settings.fog_type,
|
||||
static_cast<float>(_settings.fog_type),
|
||||
_settings.fog_near,
|
||||
_settings.fog_far,
|
||||
_settings.fog_density,
|
||||
_settings.fog_color.x,
|
||||
_settings.fog_color.y,
|
||||
_settings.fog_color.z,
|
||||
_settings.dust_particle_enable,
|
||||
static_cast<float>(_settings.dust_particle_enable),
|
||||
_settings.dust_particle_intensity,
|
||||
_settings.getLODBias(),
|
||||
_settings.getEnableRealtimeOcclusion(),
|
||||
static_cast<float>(_settings.getEnableRealtimeOcclusion()),
|
||||
_settings.debug_display,
|
||||
_settings.siren_enable,
|
||||
_settings.siren_enable_reverb,
|
||||
_settings.siren_enable_hrtf,
|
||||
static_cast<float>(_settings.siren_enable),
|
||||
static_cast<float>(_settings.siren_enable_reverb),
|
||||
static_cast<float>(_settings.siren_enable_hrtf),
|
||||
_settings.siren_reverb_max_length,
|
||||
_settings.max_anisotropy
|
||||
};
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "KRResource.h"
|
||||
#include "KRNode.h"
|
||||
#include "KRTexture.h"
|
||||
|
||||
class KRLODGroup : public KRNode {
|
||||
public:
|
||||
|
||||
35
KREngine/kraken/KRLODSet.cpp
Normal file
35
KREngine/kraken/KRLODSet.cpp
Normal 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);
|
||||
}
|
||||
26
KREngine/kraken/KRLODSet.h
Normal file
26
KREngine/kraken/KRLODSet.h
Normal 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
|
||||
@@ -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_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));
|
||||
}
|
||||
}
|
||||
@@ -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_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));
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize);
|
||||
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, 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));
|
||||
}
|
||||
}
|
||||
|
||||
35
KREngine/kraken/KRLocator.cpp
Normal file
35
KREngine/kraken/KRLocator.cpp
Normal 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);
|
||||
}
|
||||
27
KREngine/kraken/KRLocator.h
Normal file
27
KREngine/kraken/KRLocator.h
Normal 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
|
||||
@@ -87,7 +87,7 @@ float KRMat4::operator[](unsigned i) const {
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class KRMat4 {
|
||||
KRMat4& operator=(const KRMat4 &m);
|
||||
|
||||
// Overload comparison operator
|
||||
bool operator==(const KRMat4 &m);
|
||||
bool operator==(const KRMat4 &m) const;
|
||||
|
||||
// Overload compound multiply operator
|
||||
KRMat4& operator*=(const KRMat4 &m);
|
||||
|
||||
@@ -100,7 +100,7 @@ void KRMaterialManager::add(KRMaterial *new_material) {
|
||||
bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
|
||||
KRMaterial *pMaterial = NULL;
|
||||
char szSymbol[16][256];
|
||||
|
||||
data->lock();
|
||||
|
||||
char *pScan = (char *)data->getStart();
|
||||
char *pEnd = (char *)data->getEnd();
|
||||
@@ -282,7 +282,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data->unlock();
|
||||
delete data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,20 +42,23 @@
|
||||
|
||||
|
||||
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);
|
||||
|
||||
m_hasTransparency = false;
|
||||
m_pData = NULL;
|
||||
m_pMetaData = NULL;
|
||||
m_pIndexBaseData = NULL;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
m_hasTransparency = false;
|
||||
m_pData = NULL;
|
||||
m_pMetaData = NULL;
|
||||
m_pIndexBaseData = NULL;
|
||||
|
||||
loadPack(data);
|
||||
}
|
||||
|
||||
@@ -103,8 +106,24 @@ int KRMesh::GetLODCoverage(const std::string &name)
|
||||
|
||||
|
||||
KRMesh::~KRMesh() {
|
||||
clearData();
|
||||
if(m_pData) delete m_pData;
|
||||
releaseData();
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -112,28 +131,36 @@ std::string KRMesh::getExtension() {
|
||||
}
|
||||
|
||||
bool KRMesh::save(const std::string& path) {
|
||||
clearBuffers();
|
||||
return m_pData->save(path);
|
||||
}
|
||||
|
||||
bool KRMesh::save(KRDataBlock &data) {
|
||||
clearBuffers();
|
||||
data.append(*m_pData);
|
||||
return true;
|
||||
}
|
||||
|
||||
void KRMesh::loadPack(KRDataBlock *data) {
|
||||
clearData();
|
||||
delete m_pData;
|
||||
releaseData();
|
||||
|
||||
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();
|
||||
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) {
|
||||
|
||||
|
||||
//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) {
|
||||
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) {
|
||||
//m_pData->lock();
|
||||
getSubmeshes();
|
||||
Submesh *pSubmesh = m_submeshes[iSubmesh];
|
||||
int cVertexes = pSubmesh->vertex_count;
|
||||
// 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();
|
||||
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) {
|
||||
|
||||
|
||||
|
||||
|
||||
__uint16_t *index_data = getIndexData();
|
||||
int index_group = getSubmesh(iSubmesh)->index_group;
|
||||
int index_group_offset = getSubmesh(iSubmesh)->index_group_offset;
|
||||
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;
|
||||
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;
|
||||
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 {
|
||||
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 iBuffer = iVertex / MAX_VBO_SIZE;
|
||||
iVertex = iVertex % MAX_VBO_SIZE;
|
||||
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;
|
||||
|
||||
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes;
|
||||
void *buffer_end = m_pData->getEnd();
|
||||
assert(vbo_end <= buffer_end);
|
||||
assert(cBufferVertexes <= 65535);
|
||||
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 + 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) {
|
||||
@@ -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
|
||||
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 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;
|
||||
|
||||
m_pData = new KRDataBlock();
|
||||
m_pMetaData = m_pData;
|
||||
m_pData->expand(new_file_size);
|
||||
|
||||
m_pData->lock();
|
||||
pack_header *pHeader = getHeader();
|
||||
memset(pHeader, 0, sizeof(pack_header));
|
||||
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();
|
||||
}
|
||||
@@ -585,10 +645,6 @@ KRVector3 KRMesh::getMaxPoint() const {
|
||||
return m_maxPoint;
|
||||
}
|
||||
|
||||
void KRMesh::clearData() {
|
||||
m_pData->unload();
|
||||
}
|
||||
|
||||
void KRMesh::clearBuffers() {
|
||||
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
|
||||
{
|
||||
return (pack_header *)m_pData->getStart();
|
||||
return (pack_header *)m_pMetaData->getStart();
|
||||
}
|
||||
|
||||
KRMesh::pack_bone *KRMesh::getBone(int index)
|
||||
{
|
||||
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 {
|
||||
return ((unsigned char *)m_pData->getStart()) + getVertexDataOffset();
|
||||
}
|
||||
|
||||
size_t KRMesh::getVertexDataOffset() const {
|
||||
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 {
|
||||
|
||||
return (__uint16_t *)((unsigned char *)m_pData->getStart() + getIndexDataOffset());
|
||||
}
|
||||
|
||||
size_t KRMesh::getIndexDataOffset() const {
|
||||
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 {
|
||||
if(m_pIndexBaseData == NULL) {
|
||||
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));
|
||||
} else {
|
||||
return (__uint32_t *)m_pIndexBaseData->getStart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@@ -658,7 +727,8 @@ unsigned char *KRMesh::getVertexData(int index) const
|
||||
int KRMesh::getSubmeshCount() const
|
||||
{
|
||||
pack_header *header = getHeader();
|
||||
return header->submesh_count;
|
||||
int submesh_count = header->submesh_count;
|
||||
return submesh_count;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
pack_header *header = getHeader();
|
||||
return header->bone_count;
|
||||
int bone_count = header->bone_count;
|
||||
return bone_count;
|
||||
}
|
||||
|
||||
char *KRMesh::getBoneName(int bone_index)
|
||||
@@ -908,7 +979,8 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index)
|
||||
|
||||
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)
|
||||
@@ -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
|
||||
{
|
||||
m_pData->lock();
|
||||
bool hit_found = false;
|
||||
for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) {
|
||||
// int vertex_start = getSubmesh(submesh_index)->start_vertex;
|
||||
@@ -1036,26 +1109,30 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_pData->unlock();
|
||||
return hit_found;
|
||||
}
|
||||
|
||||
bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const
|
||||
{
|
||||
m_pData->lock();
|
||||
KRHitInfo new_hitinfo;
|
||||
KRVector3 dir = KRVector3::Normalize(v1 - v0);
|
||||
if(rayCast(v0, dir, new_hitinfo)) {
|
||||
if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) {
|
||||
// The hit was between v1 and v2
|
||||
hitinfo = new_hitinfo;
|
||||
m_pData->unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_pData->unlock();
|
||||
return false; // Either no hit, or the hit was beyond v1
|
||||
}
|
||||
|
||||
void KRMesh::convertToIndexed()
|
||||
{
|
||||
|
||||
m_pData->lock();
|
||||
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
|
||||
@@ -1230,6 +1307,8 @@ void KRMesh::convertToIndexed()
|
||||
|
||||
|
||||
mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
|
||||
|
||||
m_pData->unlock();
|
||||
LoadData(mi, false, false);
|
||||
}
|
||||
|
||||
@@ -1264,6 +1343,9 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
|
||||
switch(getModelFormat()) {
|
||||
case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
|
||||
{
|
||||
__uint16_t *index_data = getIndexData();
|
||||
|
||||
|
||||
int start_index_offset, start_vertex_offset, index_count, vertex_count;
|
||||
int index_group = getSubmesh(submesh)->index_group;
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
@@ -1284,7 +1366,8 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
|
||||
|
||||
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 *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t));
|
||||
@@ -1365,4 +1448,7 @@ void KRMesh::optimizeIndexes()
|
||||
free(new_indices);
|
||||
free(vertex_mapping);
|
||||
free(new_vertex_data);
|
||||
} // if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES)
|
||||
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
GLsizei vertex_count;
|
||||
char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
|
||||
} Submesh;
|
||||
vector<KRDataBlock *> vertex_data_blocks;
|
||||
vector<KRDataBlock *> index_data_blocks;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
@@ -198,6 +211,10 @@ public:
|
||||
|
||||
static int GetLODCoverage(const std::string &name);
|
||||
private:
|
||||
KRDataBlock *m_pData;
|
||||
KRDataBlock *m_pMetaData;
|
||||
KRDataBlock *m_pIndexBaseData;
|
||||
|
||||
void getSubmeshes();
|
||||
|
||||
// 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;
|
||||
|
||||
KRDataBlock *m_pData;
|
||||
|
||||
|
||||
|
||||
@@ -235,7 +251,6 @@ private:
|
||||
void updateAttributeOffsets();
|
||||
|
||||
|
||||
void clearData();
|
||||
void clearBuffers();
|
||||
|
||||
void setName(const std::string name);
|
||||
@@ -244,14 +259,19 @@ private:
|
||||
|
||||
pack_material *getSubmesh(int mesh_index) const;
|
||||
unsigned char *getVertexData() const;
|
||||
size_t getVertexDataOffset() const;
|
||||
unsigned char *getVertexData(int index) const;
|
||||
__uint16_t *getIndexData() const;
|
||||
size_t getIndexDataOffset() const;
|
||||
__uint32_t *getIndexBaseData() const;
|
||||
pack_header *getHeader() const;
|
||||
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 releaseData();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -37,14 +37,12 @@
|
||||
#include "KRMeshCube.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_indexes = -1;
|
||||
m_currentVBO.vao_handle = -1;
|
||||
m_currentVBO.data = NULL;
|
||||
m_vboMemUsed = 0;
|
||||
m_randomParticleVertexData = NULL;
|
||||
m_volumetricLightingVertexData = NULL;
|
||||
m_memoryTransferredThisFrame = 0;
|
||||
|
||||
// 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));
|
||||
m_draw_call_logging_enabled = 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() {
|
||||
@@ -59,8 +96,6 @@ KRMeshManager::~KRMeshManager() {
|
||||
delete (*itr).second;
|
||||
}
|
||||
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) {
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
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");
|
||||
GLDEBUG(glFinish());
|
||||
|
||||
// The VBO is active
|
||||
vbo_to_release = m_vbosActive[data];
|
||||
m_vbosActive.erase(data);
|
||||
vbo_to_release = m_vbosActive[&data];
|
||||
m_vbosActive.erase(&data);
|
||||
} else {
|
||||
// The VBO is inactive
|
||||
vbo_to_release = m_vbosPool[data];
|
||||
m_vbosPool.erase(data);
|
||||
vbo_to_release = m_vbosPool[&data];
|
||||
m_vbosPool.erase(&data);
|
||||
}
|
||||
|
||||
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()) {
|
||||
m_currentVBO = m_vbosActive[data];
|
||||
if(m_vbosActive.find(&data) != m_vbosActive.end()) {
|
||||
m_currentVBO = m_vbosActive[&data];
|
||||
#if GL_OES_vertex_array_object
|
||||
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
||||
#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));
|
||||
}
|
||||
#endif
|
||||
} else if(m_vbosPool.find(data) != m_vbosPool.end()) {
|
||||
m_currentVBO = m_vbosPool[data];
|
||||
m_vbosPool.erase(data);
|
||||
m_vbosActive[data] = m_currentVBO;
|
||||
} else if(m_vbosPool.find(&data) != m_vbosPool.end()) {
|
||||
m_currentVBO = m_vbosPool[&data];
|
||||
m_vbosPool.erase(&data);
|
||||
m_vbosActive[&data] = m_currentVBO;
|
||||
#if GL_OES_vertex_array_object
|
||||
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
||||
#else
|
||||
@@ -181,12 +216,12 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
||||
} 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()) {
|
||||
fprintf(stderr, "flushBuffers due to VBO exhaustion...\n");
|
||||
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;
|
||||
#if GL_OES_vertex_array_object
|
||||
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_indexes = -1;
|
||||
GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle));
|
||||
if(index_data != NULL) {
|
||||
if(index_data.getSize() > 0) {
|
||||
GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes));
|
||||
}
|
||||
|
||||
@@ -214,25 +249,49 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
||||
#endif
|
||||
|
||||
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
|
||||
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
|
||||
m_memoryTransferredThisFrame += size;
|
||||
m_vboMemUsed += size;
|
||||
#if GL_OES_mapbuffer
|
||||
|
||||
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);
|
||||
|
||||
m_currentVBO.size = size;
|
||||
m_currentVBO.data = data;
|
||||
m_currentVBO.size = data.getSize();
|
||||
m_currentVBO.data = &data;
|
||||
|
||||
if(index_data == NULL) {
|
||||
if(index_data.getSize() == 0) {
|
||||
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
} else {
|
||||
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;
|
||||
m_vboMemUsed += index_data_size;
|
||||
m_currentVBO.size += index_data_size;
|
||||
|
||||
#if GL_OES_mapbuffer
|
||||
|
||||
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 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;
|
||||
}
|
||||
return mem_active;
|
||||
@@ -332,56 +391,56 @@ void KRMeshManager::rotateBuffers(bool new_frame)
|
||||
|
||||
}
|
||||
|
||||
KRMeshManager::VolumetricLightingVertexData *KRMeshManager::getVolumetricLightingVertexes()
|
||||
KRDataBlock &KRMeshManager::getVolumetricLightingVertexes()
|
||||
{
|
||||
if(m_volumetricLightingVertexData == NULL) {
|
||||
m_volumetricLightingVertexData = (VolumetricLightingVertexData *)malloc(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6);
|
||||
if(m_volumetricLightingVertexData.getSize() == 0) {
|
||||
m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6);
|
||||
m_volumetricLightingVertexData.lock();
|
||||
VolumetricLightingVertexData * vertex_data = (VolumetricLightingVertexData *)m_volumetricLightingVertexData.getStart();
|
||||
int iVertex=0;
|
||||
for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) {
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = -1.0f;
|
||||
vertex_data[iVertex].vertex.y = -1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = 1.0f;
|
||||
vertex_data[iVertex].vertex.y = -1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = -1.0f;
|
||||
vertex_data[iVertex].vertex.y = 1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = -1.0f;
|
||||
vertex_data[iVertex].vertex.y = 1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = 1.0f;
|
||||
vertex_data[iVertex].vertex.y = -1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
|
||||
m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f;
|
||||
m_volumetricLightingVertexData[iVertex].vertex.z = iPlane;
|
||||
vertex_data[iVertex].vertex.x = 1.0f;
|
||||
vertex_data[iVertex].vertex.y = 1.0f;
|
||||
vertex_data[iVertex].vertex.z = iPlane;
|
||||
iVertex++;
|
||||
|
||||
// -1.0f, -1.0f,
|
||||
// 1.0f, -1.0f,
|
||||
// -1.0f, 1.0f,
|
||||
// 1.0f, 1.0f,
|
||||
}
|
||||
m_volumetricLightingVertexData.unlock();
|
||||
}
|
||||
return m_volumetricLightingVertexData;
|
||||
}
|
||||
|
||||
KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles()
|
||||
KRDataBlock &KRMeshManager::getRandomParticles()
|
||||
{
|
||||
if(m_randomParticleVertexData == NULL) {
|
||||
m_randomParticleVertexData = (RandomParticleVertexData *)malloc(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3);
|
||||
if(m_randomParticleVertexData.getSize() == 0) {
|
||||
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
|
||||
|
||||
@@ -390,27 +449,28 @@ KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles()
|
||||
|
||||
int iVertex=0;
|
||||
for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) {
|
||||
m_randomParticleVertexData[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
m_randomParticleVertexData[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
m_randomParticleVertexData[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
m_randomParticleVertexData[iVertex].uva.u = -0.5f;
|
||||
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius;
|
||||
vertex_data[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
vertex_data[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
vertex_data[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f;
|
||||
vertex_data[iVertex].uva.u = -0.5f;
|
||||
vertex_data[iVertex].uva.v = -inscribed_circle_radius;
|
||||
iVertex++;
|
||||
|
||||
m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x;
|
||||
m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y;
|
||||
m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z;
|
||||
m_randomParticleVertexData[iVertex].uva.u = 0.5f;
|
||||
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius;
|
||||
vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x;
|
||||
vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y;
|
||||
vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z;
|
||||
vertex_data[iVertex].uva.u = 0.5f;
|
||||
vertex_data[iVertex].uva.v = -inscribed_circle_radius;
|
||||
iVertex++;
|
||||
|
||||
m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x;
|
||||
m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y;
|
||||
m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z;
|
||||
m_randomParticleVertexData[iVertex].uva.u = 0.0f;
|
||||
m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height;
|
||||
vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x;
|
||||
vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y;
|
||||
vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z;
|
||||
vertex_data[iVertex].uva.u = 0.0f;
|
||||
vertex_data[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height;
|
||||
iVertex++;
|
||||
}
|
||||
m_randomParticleVertexData.unlock();
|
||||
}
|
||||
return m_randomParticleVertexData;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "KRDataBlock.h"
|
||||
#include "KRNode.h"
|
||||
|
||||
#include "KRMeshStreamer.h"
|
||||
|
||||
class KRContext;
|
||||
class KRMesh;
|
||||
|
||||
@@ -59,8 +61,8 @@ public:
|
||||
std::vector<std::string> getModelNames();
|
||||
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 releaseVBO(GLvoid *data);
|
||||
void bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo);
|
||||
void releaseVBO(KRDataBlock &data);
|
||||
void unbindVBO();
|
||||
long getMemUsed();
|
||||
long getMemActive();
|
||||
@@ -88,10 +90,8 @@ public:
|
||||
} VolumetricLightingVertexData;
|
||||
|
||||
|
||||
|
||||
|
||||
RandomParticleVertexData *getRandomParticles();
|
||||
VolumetricLightingVertexData *getVolumetricLightingVertexes();
|
||||
KRDataBlock &getRandomParticles();
|
||||
KRDataBlock &getVolumetricLightingVertexes();
|
||||
|
||||
|
||||
long getMemoryTransferedThisFrame();
|
||||
@@ -110,6 +110,12 @@ public:
|
||||
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:
|
||||
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 vao_handle;
|
||||
GLsizeiptr size;
|
||||
GLvoid *data;
|
||||
KRDataBlock *data;
|
||||
} vbo_info_type;
|
||||
|
||||
long m_vboMemUsed;
|
||||
vbo_info_type m_currentVBO;
|
||||
|
||||
unordered_map<GLvoid *, vbo_info_type> m_vbosActive;
|
||||
unordered_map<GLvoid *, vbo_info_type> m_vbosPool;
|
||||
unordered_map<KRDataBlock *, vbo_info_type> m_vbosActive;
|
||||
unordered_map<KRDataBlock *, vbo_info_type> m_vbosPool;
|
||||
|
||||
RandomParticleVertexData *m_randomParticleVertexData;
|
||||
VolumetricLightingVertexData *m_volumetricLightingVertexData;
|
||||
KRDataBlock m_randomParticleVertexData;
|
||||
KRDataBlock m_volumetricLightingVertexData;
|
||||
|
||||
long m_memoryTransferredThisFrame;
|
||||
|
||||
@@ -136,6 +142,8 @@ private:
|
||||
bool m_draw_call_logging_enabled;
|
||||
bool m_draw_call_log_used;
|
||||
|
||||
KRMeshStreamer m_streamer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
57
KREngine/kraken/KRMeshStreamer.h
Normal file
57
KREngine/kraken/KRMeshStreamer.h
Normal 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) */
|
||||
47
KREngine/kraken/KRMeshStreamer.mm
Normal file
47
KREngine/kraken/KRMeshStreamer.mm
Normal 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 );
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,23 @@ KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_na
|
||||
m_min_lod_coverage = lod_min_coverage;
|
||||
m_receivesShadow = receives_shadow;
|
||||
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() {
|
||||
@@ -155,7 +172,12 @@ KRAABB KRModel::getBounds() {
|
||||
float max_dimension = normal_bounds.longest_radius();
|
||||
return KRAABB(normal_bounds.center()-KRVector3(max_dimension), normal_bounds.center() + KRVector3(max_dimension));
|
||||
} 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 {
|
||||
return KRAABB::Infinite();
|
||||
|
||||
@@ -74,6 +74,10 @@ private:
|
||||
|
||||
bool m_receivesShadow;
|
||||
bool m_faces_camera;
|
||||
|
||||
|
||||
KRMat4 m_boundsCachedMat;
|
||||
KRAABB m_boundsCached;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "KRAABB.h"
|
||||
#include "KRQuaternion.h"
|
||||
#include "KRBone.h"
|
||||
#include "KRLocator.h"
|
||||
#include "KRAudioSource.h"
|
||||
#include "KRAmbientZone.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);
|
||||
} else if(strcmp(szElementName, "bone") == 0) {
|
||||
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) {
|
||||
new_node = new KRAudioSource(scene, szName);
|
||||
} else if(strcmp(szElementName, "ambient_zone") == 0) {
|
||||
|
||||
@@ -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)) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_
|
||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||
|
||||
// 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));
|
||||
} else {
|
||||
#if GL_OES_vertex_array_object
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "KRScene.h"
|
||||
#include "KRQuaternion.h"
|
||||
#include "KRBone.h"
|
||||
#include "KRLocator.h"
|
||||
#include "KRBundle.h"
|
||||
#include "KRModel.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 *LoadLight(KRNode *parent_node, 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);
|
||||
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)
|
||||
{
|
||||
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
|
||||
// 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
|
||||
return "default_camera";
|
||||
} else {
|
||||
@@ -955,37 +973,27 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
||||
case KFbxNodeAttribute::eSkeleton:
|
||||
new_node = LoadSkeleton(parent_node, pFbxScene, pNode);
|
||||
break;
|
||||
|
||||
case KFbxNodeAttribute::eCamera:
|
||||
new_node = LoadCamera(parent_node, pNode);
|
||||
break;
|
||||
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) {
|
||||
// Create an empty node, for inheritence of transforms
|
||||
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) {
|
||||
@@ -995,14 +1003,10 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
||||
*/
|
||||
// LOD Enabled group node
|
||||
KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name);
|
||||
lod_group->setMinDistance(min_distance);
|
||||
lod_group->setMaxDistance(max_distance);
|
||||
lod_group->setMinDistance(0.0f);
|
||||
lod_group->setMaxDistance(0.0f);
|
||||
new_node = lod_group;
|
||||
/*
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1526,6 +1530,21 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode)
|
||||
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) {
|
||||
FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute();
|
||||
const char *szName = pNode->GetName();
|
||||
|
||||
@@ -272,7 +272,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &visi
|
||||
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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
doc.Parse((char *)data->getStart());
|
||||
doc.Parse(xml_string.c_str());
|
||||
KRScene *new_scene = new KRScene(context, name);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
delete data;
|
||||
|
||||
return new_scene;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,12 +254,12 @@ bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KR
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
#define KRSTOCKGEOMETRY_H
|
||||
|
||||
#include "KRMesh.h"
|
||||
|
||||
static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
|
||||
#include "KRDataBlock.h"
|
||||
/*
|
||||
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,
|
||||
@@ -28,32 +29,20 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
|
||||
-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 GLfloat KRENGINE_VERTICES_2D_SQUARE[] = {
|
||||
-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[] = {
|
||||
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
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -15,26 +15,42 @@
|
||||
KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name)
|
||||
{
|
||||
m_iHandle = 0;
|
||||
m_iNewHandle = 0;
|
||||
m_textureMemUsed = 0;
|
||||
m_newTextureMemUsed = 0;
|
||||
m_last_frame_used = 0;
|
||||
m_last_frame_bound = 0;
|
||||
m_handle_lock.clear();
|
||||
}
|
||||
|
||||
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) {
|
||||
GLDEBUG(glDeleteTextures(1, &m_iHandle));
|
||||
getContext().getTextureManager()->memoryChanged(-getMemSize());
|
||||
m_iHandle = 0;
|
||||
m_textureMemUsed = 0;
|
||||
}
|
||||
|
||||
m_handle_lock.clear();
|
||||
|
||||
getContext().getTextureManager()->memoryChanged(-mem_size);
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -44,42 +60,36 @@ long KRTexture::getReferencedMemSize() {
|
||||
|
||||
void KRTexture::resize(int max_dim)
|
||||
{
|
||||
if(!m_handle_lock.test_and_set())
|
||||
{
|
||||
if(m_iHandle == m_iNewHandle) {
|
||||
if(max_dim == 0) {
|
||||
releaseHandle();
|
||||
m_iNewHandle = 0;
|
||||
} else {
|
||||
int target_dim = max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
|
||||
int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim);
|
||||
int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize();
|
||||
|
||||
if(requiredMemoryDelta) {
|
||||
// Only resize / regenerate the texture if it actually changes the size of the texture (Assumption: textures of different sizes will always consume different amounts of memory)
|
||||
if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) {
|
||||
assert(m_newTextureMemUsed == 0);
|
||||
m_newTextureMemUsed = getMemRequiredForSize(target_dim);
|
||||
|
||||
if(getContext().getTextureManager()->getMemoryTransferedThisFrame() + requiredMemoryTransfer > getContext().KRENGINE_MAX_TEXTURE_THROUGHPUT) {
|
||||
// Exceeding per-frame transfer throughput; can't resize now
|
||||
return;
|
||||
}
|
||||
getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed);
|
||||
getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed);
|
||||
|
||||
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)) {
|
||||
getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed);
|
||||
m_newTextureMemUsed = 0;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_handle_lock.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLuint KRTexture::getHandle() {
|
||||
if(m_iHandle == 0) {
|
||||
//resize(getContext().KRENGINE_MIN_TEXTURE_DIM);
|
||||
resize(m_min_lod_max_dim);
|
||||
}
|
||||
resetPoolExpiry();
|
||||
return m_iHandle;
|
||||
}
|
||||
@@ -89,34 +99,6 @@ void KRTexture::resetPoolExpiry()
|
||||
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()
|
||||
{
|
||||
return m_last_frame_used;
|
||||
@@ -147,3 +129,28 @@ int KRTexture::getMinMipMap() {
|
||||
bool KRTexture::hasMipmaps() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,13 +46,12 @@ public:
|
||||
KRTexture(KRContext &context, std::string name);
|
||||
virtual ~KRTexture();
|
||||
|
||||
virtual void bind(GLuint texture_unit) = 0;
|
||||
void releaseHandle();
|
||||
virtual void bind(GLuint texture_unit);
|
||||
void releaseHandles();
|
||||
long getMemSize();
|
||||
virtual long getReferencedMemSize();
|
||||
|
||||
virtual long getMemRequiredForSize(int max_dim) = 0;
|
||||
virtual long getThroughputRequiredForResize(int max_dim);
|
||||
virtual void resize(int max_dim);
|
||||
|
||||
long getLastFrameUsed();
|
||||
@@ -66,13 +65,17 @@ public:
|
||||
int getMinMipMap();
|
||||
bool hasMipmaps();
|
||||
|
||||
bool canStreamOut() const;
|
||||
|
||||
void _swapHandles();
|
||||
protected:
|
||||
virtual bool createGLTexture(int lod_max_dim) = 0;
|
||||
GLuint getHandle();
|
||||
|
||||
|
||||
GLuint m_iHandle;
|
||||
long m_textureMemUsed;
|
||||
GLuint m_iNewHandle;
|
||||
std::atomic_flag m_handle_lock;
|
||||
|
||||
int m_current_lod_max_dim;
|
||||
|
||||
@@ -80,6 +83,11 @@ protected:
|
||||
uint32_t m_min_lod_max_dim;
|
||||
|
||||
long m_last_frame_used;
|
||||
long m_last_frame_bound;
|
||||
|
||||
private:
|
||||
std::atomic<long> m_textureMemUsed;
|
||||
std::atomic<long> m_newTextureMemUsed;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -43,54 +43,47 @@ KRTexture2D::~KRTexture2D() {
|
||||
}
|
||||
|
||||
bool KRTexture2D::createGLTexture(int lod_max_dim) {
|
||||
if(m_iHandle != m_iNewHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
GLuint prev_handle = 0;
|
||||
int prev_lod_max_dim = 0;
|
||||
long prev_mem_size = 0;
|
||||
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
|
||||
|
||||
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;
|
||||
}
|
||||
#else
|
||||
releaseHandle();
|
||||
#endif
|
||||
|
||||
m_iNewHandle = 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;
|
||||
} else {
|
||||
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iHandle));
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iNewHandle));
|
||||
if (hasMipmaps()) {
|
||||
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
|
||||
} else {
|
||||
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)) {
|
||||
GLDEBUG(glDeleteTextures(1, &m_iHandle));
|
||||
m_iHandle = 0;
|
||||
m_current_lod_max_dim = 0;
|
||||
if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, prev_lod_max_dim)) {
|
||||
GLDEBUG(glDeleteTextures(1, &m_iNewHandle));
|
||||
m_iNewHandle = m_iHandle;
|
||||
m_current_lod_max_dim = prev_lod_max_dim;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(prev_handle != 0) {
|
||||
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
|
||||
GLDEBUG(glDeleteTextures(1, &prev_handle));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void KRTexture2D::bind(GLuint texture_unit) {
|
||||
KRTexture::bind(texture_unit);
|
||||
GLuint handle = getHandle();
|
||||
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle));
|
||||
@@ -101,7 +94,6 @@ void KRTexture2D::bind(GLuint texture_unit) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool KRTexture2D::save(const std::string& path)
|
||||
{
|
||||
if(m_pData) {
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
|
||||
virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0;
|
||||
virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim) = 0;
|
||||
virtual void bind(GLuint texture_unit);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -114,6 +114,7 @@ void KRTextureAnimated::resetPoolExpiry()
|
||||
|
||||
void KRTextureAnimated::bind(GLuint texture_unit)
|
||||
{
|
||||
KRTexture::bind(texture_unit);
|
||||
int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count));
|
||||
KRTexture2D *frame_texture = textureForFrame(frame_number);
|
||||
if(frame_texture) {
|
||||
|
||||
@@ -55,32 +55,25 @@ KRTextureCube::~KRTextureCube()
|
||||
|
||||
bool KRTextureCube::createGLTexture(int lod_max_dim)
|
||||
{
|
||||
assert(m_iNewHandle == m_iHandle); // Only allow one resize per frame
|
||||
|
||||
bool success = true;
|
||||
GLuint prev_handle = 0;
|
||||
int prev_lod_max_dim = 0;
|
||||
long prev_mem_size = 0;
|
||||
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
releaseHandle();
|
||||
#endif
|
||||
|
||||
m_current_lod_max_dim = 0;
|
||||
GLDEBUG(glGenTextures(1, &m_iHandle));
|
||||
if(m_iHandle == 0) {
|
||||
success = false;
|
||||
} else {
|
||||
m_iNewHandle = 0;
|
||||
GLDEBUG(glGenTextures(1, &m_iNewHandle));
|
||||
assert(m_iNewHandle != 0);
|
||||
|
||||
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;
|
||||
|
||||
@@ -89,7 +82,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
|
||||
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName);
|
||||
if(faceTexture) {
|
||||
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(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
|
||||
}
|
||||
}
|
||||
|
||||
if(prev_handle != 0) {
|
||||
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
|
||||
GLDEBUG(glDeleteTextures(1, &prev_handle));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -141,6 +129,7 @@ void KRTextureCube::resetPoolExpiry()
|
||||
|
||||
void KRTextureCube::bind(GLuint texture_unit)
|
||||
{
|
||||
KRTexture::bind(texture_unit);
|
||||
GLuint handle = getHandle();
|
||||
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle));
|
||||
if(handle) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "KRTextureAnimated.h"
|
||||
#include "KRContext.h"
|
||||
|
||||
KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context) {
|
||||
KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context), m_streamer(context) {
|
||||
m_textureMemUsed = 0;
|
||||
|
||||
for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
|
||||
@@ -215,9 +215,20 @@ long KRTextureManager::getMemActive() {
|
||||
|
||||
void KRTextureManager::startFrame(float deltaTime)
|
||||
{
|
||||
m_streamer.startStreamer();
|
||||
_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;
|
||||
balanceTextureMemory();
|
||||
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()
|
||||
{
|
||||
// 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
|
||||
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;
|
||||
|
||||
wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize();
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -254,7 +276,7 @@ void KRTextureManager::balanceTextureMemory()
|
||||
maxDimInactive = maxDimInactive >> 1;
|
||||
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;
|
||||
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
|
||||
if(potentialMemoryDelta < 0) {
|
||||
@@ -265,12 +287,19 @@ void KRTextureManager::balanceTextureMemory()
|
||||
|
||||
// Strip off mipmap levels of inactive textures to free up memory
|
||||
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;
|
||||
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
|
||||
long mem_required = poolTexture->getMemRequiredForSize(maxDimInactive);
|
||||
long potentialMemoryDelta = mem_required - poolTexture->getMemSize();
|
||||
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);
|
||||
inactive_texture_mem_used_target += poolTexture->getMemRequiredForSize(maxDimInactive);
|
||||
}
|
||||
}
|
||||
inactive_texture_mem_used_target += mem_required;
|
||||
} else {
|
||||
inactive_texture_mem_used_target += poolTexture->getMemSize();
|
||||
}
|
||||
@@ -280,8 +309,8 @@ void KRTextureManager::balanceTextureMemory()
|
||||
long memory_available = 0;
|
||||
long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM;
|
||||
while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) {
|
||||
memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target;
|
||||
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) {
|
||||
memory_available = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - inactive_texture_mem_used_target;
|
||||
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
|
||||
KRTexture *activeTexture = *itr;
|
||||
memory_available -= activeTexture->getMemRequiredForSize(maxDimActive);
|
||||
}
|
||||
@@ -292,10 +321,17 @@ void KRTextureManager::balanceTextureMemory()
|
||||
}
|
||||
|
||||
// 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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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;
|
||||
if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) {
|
||||
expiredTextures.insert(poolTexture);
|
||||
poolTexture->releaseHandle();
|
||||
poolTexture->releaseHandles();
|
||||
}
|
||||
}
|
||||
for(std::set<KRTexture *>::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) {
|
||||
@@ -318,6 +354,7 @@ void KRTextureManager::rotateBuffers()
|
||||
}
|
||||
|
||||
// ----====---- Swap the buffers ----====----
|
||||
|
||||
m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end());
|
||||
m_activeTextures.clear();
|
||||
}
|
||||
@@ -335,6 +372,7 @@ void KRTextureManager::addMemoryTransferredThisFrame(long memoryTransferred)
|
||||
void KRTextureManager::memoryChanged(long 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()
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "KREngine-common.h"
|
||||
#include "KRDataBlock.h"
|
||||
#include "KRContext.h"
|
||||
#include "KRTextureStreamer.h"
|
||||
|
||||
class KRTextureManager : public KRContextObject {
|
||||
public:
|
||||
@@ -77,6 +78,8 @@ public:
|
||||
void _clearGLState();
|
||||
void setMaxAnisotropy(float max_anisotropy);
|
||||
|
||||
void doStreaming();
|
||||
|
||||
private:
|
||||
int m_iActiveTexture;
|
||||
|
||||
@@ -88,13 +91,24 @@ private:
|
||||
GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS];
|
||||
GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS];
|
||||
float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS];
|
||||
|
||||
|
||||
std::set<KRTexture *> m_activeTextures;
|
||||
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 balanceTextureMemory();
|
||||
|
||||
KRTextureStreamer m_streamer;
|
||||
|
||||
std::mutex m_streamerFenceMutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,8 +64,11 @@ typedef struct _PVRTexHeader
|
||||
|
||||
KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) {
|
||||
#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) {
|
||||
m_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
} else if(formatFlags == kPVRTextureFlagTypePVRTC_2) {
|
||||
@@ -74,7 +77,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
|
||||
assert(false);
|
||||
}
|
||||
|
||||
uint32_t pvrTag = header->pvrTag;
|
||||
uint32_t pvrTag = header.pvrTag;
|
||||
if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
|
||||
gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
|
||||
gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
|
||||
@@ -82,12 +85,12 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
|
||||
assert(false);
|
||||
}
|
||||
|
||||
m_iWidth = header->width; // Note: call __builtin_bswap32 when needed to switch endianness
|
||||
m_iHeight = header->height;
|
||||
m_bHasAlpha = header->bitmaskAlpha;
|
||||
m_iWidth = header.width; // Note: call __builtin_bswap32 when needed to switch endianness
|
||||
m_iHeight = header.height;
|
||||
m_bHasAlpha = header.bitmaskAlpha;
|
||||
|
||||
uint8_t *bytes = ((uint8_t *)m_pData->getStart()) + sizeof(PVRTexHeader);
|
||||
uint32_t dataLength = header->dataLength, dataOffset = 0, dataSize = 0;
|
||||
uint32_t dataStart = sizeof(PVRTexHeader);
|
||||
uint32_t dataLength = header.dataLength, dataOffset = 0, dataSize = 0;
|
||||
uint32_t width = m_iWidth, height = m_iHeight, bpp = 4;
|
||||
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);
|
||||
|
||||
dataBlockStruct newBlock;
|
||||
newBlock.start = bytes+dataOffset;
|
||||
newBlock.length = dataSize;
|
||||
|
||||
m_blocks.push_back(newBlock);
|
||||
m_blocks.push_back(m_pData->getSubBlock(dataStart + 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_min_lod_max_dim = width > height ? width : height;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -152,10 +154,10 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
|
||||
int height = m_iHeight;
|
||||
long memoryRequired = 0;
|
||||
|
||||
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
dataBlockStruct block = *itr;
|
||||
for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
KRDataBlock *block = *itr;
|
||||
if(width <= target_dim && height <= target_dim) {
|
||||
memoryRequired += block.length;
|
||||
memoryRequired += block->getSize();
|
||||
}
|
||||
|
||||
width = width >> 1;
|
||||
@@ -171,13 +173,11 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
|
||||
return memoryRequired;
|
||||
}
|
||||
|
||||
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
|
||||
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim)
|
||||
{
|
||||
int target_dim = 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) {
|
||||
return false;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
int level_count=0;
|
||||
int max_lod_width=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(max_lod_width == 0) {
|
||||
max_lod_width = width;
|
||||
@@ -229,8 +229,8 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
// Upload texture data
|
||||
int destination_level=0;
|
||||
int source_level = 0;
|
||||
for(std::list<dataBlockStruct>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
dataBlockStruct block = *itr;
|
||||
for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
|
||||
KRDataBlock *block = *itr;
|
||||
if(width <= target_dim && height <= target_dim) {
|
||||
|
||||
if(width > current_lod_max_dim) {
|
||||
@@ -243,22 +243,25 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
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(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 {
|
||||
// glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
|
||||
GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, block.length, block.start));
|
||||
// GLDEBUG(glCompressedTexImage2D(target, destination_level, m_internalFormat, width, height, 0, block.length, block.start));
|
||||
memoryTransferred += block.length; // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE
|
||||
block->lock();
|
||||
GLDEBUG(glCompressedTexSubImage2D(target, destination_level, 0, 0, width, height, m_internalFormat, (GLsizei)block->getSize(), block->getStart()));
|
||||
block->unlock();
|
||||
|
||||
memoryTransferred += block->getSize(); // memoryTransferred does not include throughput of mipmap levels copied through glCopyTextureLevelsAPPLE
|
||||
}
|
||||
#else
|
||||
block->lock();
|
||||
#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
|
||||
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
|
||||
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
|
||||
memoryRequired += block.length;
|
||||
memoryRequired += block->getSize();
|
||||
//
|
||||
// err = glGetError();
|
||||
// if (err != GL_NO_ERROR) {
|
||||
@@ -284,10 +287,6 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
}
|
||||
}
|
||||
|
||||
textureMemUsed += memoryRequired;
|
||||
getContext().getTextureManager()->memoryChanged(memoryTransferred);
|
||||
getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual ~KRTexturePVR();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim);
|
||||
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
|
||||
@@ -29,12 +29,7 @@ protected:
|
||||
GLenum m_internalFormat;
|
||||
bool m_bHasAlpha;
|
||||
|
||||
struct dataBlockStruct {
|
||||
void *start;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
std::list<dataBlockStruct> m_blocks;
|
||||
std::list<KRDataBlock *> m_blocks;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
61
KREngine/kraken/KRTextureStreamer.h
Normal file
61
KREngine/kraken/KRTextureStreamer.h
Normal 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) */
|
||||
57
KREngine/kraken/KRTextureStreamer.mm
Normal file
57
KREngine/kraken/KRTextureStreamer.mm
Normal 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;
|
||||
}
|
||||
@@ -28,10 +28,40 @@ typedef struct {
|
||||
|
||||
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
|
||||
{
|
||||
data->lock();
|
||||
TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart();
|
||||
|
||||
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
|
||||
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()
|
||||
@@ -39,12 +69,14 @@ KRTextureTGA::~KRTextureTGA()
|
||||
|
||||
}
|
||||
|
||||
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
|
||||
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim)
|
||||
{
|
||||
m_pData->lock();
|
||||
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);
|
||||
|
||||
if(pHeader->colourmaptype != 0) {
|
||||
m_pData->unlock();
|
||||
return false; // Mapped colors not supported
|
||||
}
|
||||
|
||||
@@ -73,15 +105,12 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
}
|
||||
//#endif
|
||||
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();
|
||||
if (err != GL_NO_ERROR) {
|
||||
m_pData->unlock();
|
||||
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;
|
||||
}
|
||||
break;
|
||||
@@ -90,47 +119,29 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)pData);
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
m_pData->unlock();
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_pData->unlock();
|
||||
return false; // 16-bit images not yet supported
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m_pData->unlock();
|
||||
return false; // Image type not yet supported
|
||||
}
|
||||
|
||||
m_pData->unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
long KRTextureTGA::getMemRequiredForSize(int max_dim)
|
||||
{
|
||||
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();
|
||||
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;
|
||||
return m_imageSize;
|
||||
}
|
||||
|
||||
std::string KRTextureTGA::getExtension()
|
||||
|
||||
@@ -18,9 +18,11 @@ public:
|
||||
virtual ~KRTextureTGA();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, int prev_lod_max_dim);
|
||||
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
private:
|
||||
long m_imageSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user