Merged async_streaming branch into default.

This commit is contained in:
2013-11-16 15:50:22 -08:00
56 changed files with 1665 additions and 668 deletions

View File

@@ -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;

View File

@@ -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();
}
}
}
}

View File

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

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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();
}
}
}

View File

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

View File

@@ -17,7 +17,6 @@ int KRContext::KRENGINE_MAX_SHADER_HANDLES;
int KRContext::KRENGINE_MAX_TEXTURE_HANDLES;
int KRContext::KRENGINE_MAX_TEXTURE_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
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -101,7 +101,6 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_VBO_MEM = total_ram * 2 / 4;
KRContext::KRENGINE_MAX_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
};

View File

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

View File

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

View File

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

View File

@@ -226,7 +226,8 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()));
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_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));
}
}

View File

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

View File

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

View File

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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -133,11 +133,24 @@ public:
typedef struct {
class Submesh {
public:
Submesh() {};
~Submesh() {
for(std::vector<KRDataBlock *>::iterator itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) {
delete (*itr);
}
for(std::vector<KRDataBlock *>::iterator itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) {
delete (*itr);
}
};
GLint start_vertex;
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();
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -0,0 +1,57 @@
//
// KRMeshManager.h
// KREngine
//
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#ifndef KRMESHSTREAMER_H
#define KRMESHSTREAMER_H
#include "KREngine-common.h"
#include <thread>
#include <atomic>
class KRContext;
class KRMeshStreamer
{
public:
KRMeshStreamer(KRContext &context);
~KRMeshStreamer();
private:
KRContext &m_context;
std::thread m_thread;
std::atomic<bool> m_stop;
void run();
};
#endif /* defined(KRMESHSTREAMER_H) */

View File

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

View File

@@ -43,6 +43,23 @@ KRModel::KRModel(KRScene &scene, std::string instance_name, std::string model_na
m_min_lod_coverage = lod_min_coverage;
m_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();

View File

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

View File

@@ -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) {

View File

@@ -77,7 +77,9 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
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));
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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;
};

View File

@@ -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) {

View File

@@ -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 &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0;
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim) = 0;
virtual void bind(GLuint texture_unit);
protected:

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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()

View File

@@ -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

View File

@@ -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 &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim)
{
int target_dim = lod_max_dim;
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 &current_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 &current_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 &current_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 &current_lo
}
}
textureMemUsed += memoryRequired;
getContext().getTextureManager()->memoryChanged(memoryTransferred);
getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred);
return true;
}

View File

@@ -18,7 +18,7 @@ public:
virtual ~KRTexturePVR();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim);
virtual long getMemRequiredForSize(int max_dim);
@@ -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

View File

@@ -0,0 +1,61 @@
//
// KRTextureManager.h
// KREngine
//
// Copyright 2012 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#ifndef KRTEXTURESTREAMER_H
#define KRTEXTURESTREAMER_H
#include "KREngine-common.h"
#include <thread>
#include <atomic>
class KRContext;
class KRTextureStreamer
{
public:
KRTextureStreamer(KRContext &context);
~KRTextureStreamer();
void startStreamer();
private:
KRContext &m_context;
std::thread m_thread;
std::atomic<bool> m_stop;
std::atomic<bool> m_running;
void run();
};
#endif /* defined(KRTEXTURESTREAMER_H) */

View File

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

View File

@@ -28,10 +28,40 @@ typedef struct {
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
{
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 &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, int prev_lod_max_dim)
{
m_pData->lock();
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();
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 &current_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 &current_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()

View File

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