Procházet zdrojové kódy

Merge branch 'next' of https://github.com/blackberry/GamePlay into next

Conflicts:
	gameplay/src/Form.cpp
Adam Blake před 13 roky
rodič
revize
4286cd5b0e

+ 1 - 1
gameplay-newproject.sh

@@ -173,7 +173,7 @@ fi
 # Copy Microsoft Visual Studio project files
 # Copy Microsoft Visual Studio project files
 #############################################
 #############################################
 cp "gameplay-template/gameplay-template.vcxproj" "$projPath/$projName.vcxproj"
 cp "gameplay-template/gameplay-template.vcxproj" "$projPath/$projName.vcxproj"
-aliassedinplace "s*TEMPLATE_PROJECT*$projectName*g" "$projPath/$projName.vcxproj"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj"
 
 

+ 91 - 49
gameplay-template/gameplay-template.xcodeproj/project.pbxproj

@@ -8,8 +8,8 @@
 
 
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
 		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
 		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
-		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
 		424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424CC03B161FCBDD00577827 /* IOKit.framework */; };
 		424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424CC03B161FCBDD00577827 /* IOKit.framework */; };
+		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
 		42C932EE1491A4CB0098216A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		42C932EE1491A4CB0098216A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		42C932F11491A5160098216A /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
 		42C932F11491A5160098216A /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
@@ -17,22 +17,9 @@
 		42C933171491A5EB0098216A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933161491A5EB0098216A /* OpenGL.framework */; };
 		42C933171491A5EB0098216A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933161491A5EB0098216A /* OpenGL.framework */; };
 		42C9331D1491A6750098216A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331C1491A6750098216A /* QuartzCore.framework */; };
 		42C9331D1491A6750098216A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331C1491A6750098216A /* QuartzCore.framework */; };
 		42C9331F1491A67F0098216A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331E1491A67F0098216A /* OpenAL.framework */; };
 		42C9331F1491A67F0098216A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331E1491A67F0098216A /* OpenAL.framework */; };
-		42C933211491A6C70098216A /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933201491A6C70098216A /* libbullet.a */; };
-		42C933261491A6E50098216A /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933221491A6E50098216A /* libogg.a */; };
-		42C933271491A6E50098216A /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933231491A6E50098216A /* libvorbis.a */; };
-		42C933281491A6E50098216A /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933241491A6E50098216A /* libvorbisenc.a */; };
-		42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933251491A6E50098216A /* libvorbisfile.a */; };
-		42C9332C1491A7680098216A /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332A1491A7390098216A /* libpng.a */; };
 		42C9332F1491A78D0098216A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		42C9332F1491A78D0098216A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		5B61611614CCC24C0073B857 /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
 		5B61611614CCC24C0073B857 /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
 		5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
 		5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
-		5B61611914CCC24C0073B857 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933201491A6C70098216A /* libbullet.a */; };
-		5B61611A14CCC24C0073B857 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933221491A6E50098216A /* libogg.a */; };
-		5B61611B14CCC24C0073B857 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933231491A6E50098216A /* libvorbis.a */; };
-		5B61611C14CCC24C0073B857 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933241491A6E50098216A /* libvorbisenc.a */; };
-		5B61611D14CCC24C0073B857 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933251491A6E50098216A /* libvorbisfile.a */; };
-		5B61611E14CCC24C0073B857 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332A1491A7390098216A /* libpng.a */; };
-		5B61611F14CCC24C0073B857 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		5B61612614CCC24C0073B857 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		5B61612614CCC24C0073B857 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		5B61612714CCC24C0073B857 /* res in Resources */ = {isa = PBXBuildFile; fileRef = 42C932F21491A53E0098216A /* res */; };
 		5B61612714CCC24C0073B857 /* res in Resources */ = {isa = PBXBuildFile; fileRef = 42C932F21491A53E0098216A /* res */; };
 		5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */; };
 		5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */; };
@@ -41,12 +28,27 @@
 		5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */; };
 		5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */; };
 		5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */; };
 		5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */; };
 		5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206C152F2DDD003E2AC3 /* UIKit.framework */; };
 		5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206C152F2DDD003E2AC3 /* UIKit.framework */; };
+		F1F49B8B16AD8E02008715A2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8A16AD8E02008715A2 /* libz.dylib */; };
+		F1F49B8D16AD8F1B008715A2 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8C16AD8F1B008715A2 /* libbullet.a */; };
+		F1F49B8F16AD8F3F008715A2 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8E16AD8F3F008715A2 /* libbullet.a */; };
+		F1F49BC616AD94EE008715A2 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC216AD94EE008715A2 /* libogg.a */; };
+		F1F49BC716AD94EE008715A2 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC316AD94EE008715A2 /* libvorbis.a */; };
+		F1F49BC816AD94EE008715A2 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC416AD94EE008715A2 /* libvorbisenc.a */; };
+		F1F49BC916AD94EE008715A2 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC516AD94EE008715A2 /* libvorbisfile.a */; };
+		F1F49BCC16AD9502008715A2 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCB16AD9502008715A2 /* libpng.a */; };
+		F1F49BD116AD951A008715A2 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCD16AD951A008715A2 /* libogg.a */; };
+		F1F49BD216AD951A008715A2 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCE16AD951A008715A2 /* libvorbis.a */; };
+		F1F49BD316AD951A008715A2 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCF16AD951A008715A2 /* libvorbisenc.a */; };
+		F1F49BD416AD951A008715A2 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BD016AD951A008715A2 /* libvorbisfile.a */; };
+		F1F49BD616AD9535008715A2 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BD516AD9535008715A2 /* libpng.a */; };
+		F1F49BEE16AD9BD4008715A2 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BED16AD9BD4008715A2 /* liblua.a */; };
+		F1F49BF116AD9BFB008715A2 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BF016AD9BFB008715A2 /* liblua.a */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
-		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		42438B521491AD2000D218B8 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
 		42438B521491AD2000D218B8 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
 		424CC03B161FCBDD00577827 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
 		424CC03B161FCBDD00577827 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		42C932C01491A0DB0098216A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		42C932C01491A0DB0098216A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		42C932ED1491A4CB0098216A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
 		42C932ED1491A4CB0098216A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
@@ -56,12 +58,6 @@
 		42C933161491A5EB0098216A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		42C933161491A5EB0098216A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		42C9331C1491A6750098216A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		42C9331C1491A6750098216A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		42C9331E1491A67F0098216A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
 		42C9331E1491A67F0098216A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
-		42C933201491A6C70098216A /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
-		42C933221491A6E50098216A /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
-		42C933231491A6E50098216A /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
-		42C933241491A6E50098216A /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisenc.a"; sourceTree = "<group>"; };
-		42C933251491A6E50098216A /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisfile.a"; sourceTree = "<group>"; };
-		42C9332A1491A7390098216A /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
 		42C9332D1491A7810098216A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		42C9332D1491A7810098216A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-macosx.plist"; sourceTree = "<group>"; };
 		5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-macosx.plist"; sourceTree = "<group>"; };
 		5B61612C14CCC24C0073B857 /* TEMPLATE_PROJECT-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		5B61612C14CCC24C0073B857 /* TEMPLATE_PROJECT-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -74,6 +70,21 @@
 		5BAF206C152F2DDD003E2AC3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		5BAF206C152F2DDD003E2AC3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gameplay.xcodeproj; path = GAMEPLAY_PATH/gameplay/gameplay.xcodeproj; sourceTree = SOURCE_ROOT; };
 		5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gameplay.xcodeproj; path = GAMEPLAY_PATH/gameplay/gameplay.xcodeproj; sourceTree = SOURCE_ROOT; };
 		5BC4E849150F911D00CBE1C0 /* shaders */ = {isa = PBXFileReference; lastKnownFileType = text; name = shaders; path = GAMEPLAY_PATH/gameplay/res/shaders; sourceTree = SOURCE_ROOT; };
 		5BC4E849150F911D00CBE1C0 /* shaders */ = {isa = PBXFileReference; lastKnownFileType = text; name = shaders; path = GAMEPLAY_PATH/gameplay/res/shaders; sourceTree = SOURCE_ROOT; };
+		F1F49B8A16AD8E02008715A2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		F1F49B8C16AD8F1B008715A2 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = GAMEPLAY_PATH/bullet/lib/macosx/libbullet.a; sourceTree = "<group>"; };
+		F1F49B8E16AD8F3F008715A2 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/bullet/lib/ios/$(CURRENT_ARCH)/libbullet.a"; sourceTree = "<group>"; };
+		F1F49BC216AD94EE008715A2 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libogg.a; sourceTree = "<group>"; };
+		F1F49BC316AD94EE008715A2 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbis.a; sourceTree = "<group>"; };
+		F1F49BC416AD94EE008715A2 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbisenc.a; sourceTree = "<group>"; };
+		F1F49BC516AD94EE008715A2 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbisfile.a; sourceTree = "<group>"; };
+		F1F49BCB16AD9502008715A2 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = GAMEPLAY_PATH/libpng/lib/macosx/libpng.a; sourceTree = "<group>"; };
+		F1F49BCD16AD951A008715A2 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libogg.a"; sourceTree = "<group>"; };
+		F1F49BCE16AD951A008715A2 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbis.a"; sourceTree = "<group>"; };
+		F1F49BCF16AD951A008715A2 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbisenc.a"; sourceTree = "<group>"; };
+		F1F49BD016AD951A008715A2 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbisfile.a"; sourceTree = "<group>"; };
+		F1F49BD516AD9535008715A2 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/libpng/lib/ios/$(CURRENT_ARCH)/libpng.a"; sourceTree = "<group>"; };
+		F1F49BED16AD9BD4008715A2 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
+		F1F49BF016AD9BFB008715A2 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/lua/lib/ios/$(CURRENT_ARCH)/liblua.a"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -82,12 +93,13 @@
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
 				42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */,
 				42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */,
-				42C933211491A6C70098216A /* libbullet.a in Frameworks */,
-				42C933261491A6E50098216A /* libogg.a in Frameworks */,
-				42C933271491A6E50098216A /* libvorbis.a in Frameworks */,
-				42C933281491A6E50098216A /* libvorbisenc.a in Frameworks */,
-				42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */,
-				42C9332C1491A7680098216A /* libpng.a in Frameworks */,
+				F1F49B8D16AD8F1B008715A2 /* libbullet.a in Frameworks */,
+				F1F49BEE16AD9BD4008715A2 /* liblua.a in Frameworks */,
+				F1F49BC616AD94EE008715A2 /* libogg.a in Frameworks */,
+				F1F49BC716AD94EE008715A2 /* libvorbis.a in Frameworks */,
+				F1F49BC816AD94EE008715A2 /* libvorbisenc.a in Frameworks */,
+				F1F49BC916AD94EE008715A2 /* libvorbisfile.a in Frameworks */,
+				F1F49BCC16AD9502008715A2 /* libpng.a in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
 				424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */,
 				424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
@@ -101,20 +113,21 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */,
+				F1F49B8F16AD8F3F008715A2 /* libbullet.a in Frameworks */,
+				F1F49BF116AD9BFB008715A2 /* liblua.a in Frameworks */,
+				F1F49BD116AD951A008715A2 /* libogg.a in Frameworks */,
+				F1F49BD216AD951A008715A2 /* libvorbis.a in Frameworks */,
+				F1F49BD316AD951A008715A2 /* libvorbisenc.a in Frameworks */,
+				F1F49BD416AD951A008715A2 /* libvorbisfile.a in Frameworks */,
+				F1F49BD616AD9535008715A2 /* libpng.a in Frameworks */,
+				F1F49B8B16AD8E02008715A2 /* libz.dylib in Frameworks */,
 				5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */,
 				5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */,
 				5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */,
 				5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */,
 				5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */,
 				5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */,
 				5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */,
 				5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */,
 				5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */,
 				5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */,
 				5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */,
 				5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */,
-				5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */,
-				5B61611914CCC24C0073B857 /* libbullet.a in Frameworks */,
-				5B61611A14CCC24C0073B857 /* libogg.a in Frameworks */,
-				5B61611B14CCC24C0073B857 /* libvorbis.a in Frameworks */,
-				5B61611C14CCC24C0073B857 /* libvorbisenc.a in Frameworks */,
-				5B61611D14CCC24C0073B857 /* libvorbisfile.a in Frameworks */,
-				5B61611E14CCC24C0073B857 /* libpng.a in Frameworks */,
-				5B61611F14CCC24C0073B857 /* libz.dylib in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -148,7 +161,6 @@
 		42C932BF1491A0DB0098216A /* Frameworks */ = {
 		42C932BF1491A0DB0098216A /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				5BC4E825150F8CE600CBE1C0 /* GamePlay */,
 				5B61613A14CCC3590073B857 /* MacOSX */,
 				5B61613A14CCC3590073B857 /* MacOSX */,
 				5B61613914CCC3560073B857 /* iOS */,
 				5B61613914CCC3560073B857 /* iOS */,
 			);
 			);
@@ -168,13 +180,9 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				42438B521491AD2000D218B8 /* libgameplay.a */,
 				42438B521491AD2000D218B8 /* libgameplay.a */,
-				42C933201491A6C70098216A /* libbullet.a */,
-				42C933221491A6E50098216A /* libogg.a */,
-				42C933231491A6E50098216A /* libvorbis.a */,
-				42C933241491A6E50098216A /* libvorbisenc.a */,
-				42C933251491A6E50098216A /* libvorbisfile.a */,
-				42C9332A1491A7390098216A /* libpng.a */,
-				42C9332D1491A7810098216A /* libz.dylib */,
+				5BC4E825150F8CE600CBE1C0 /* GamePlay */,
+				F1F49B8516AD8C22008715A2 /* MacOSX */,
+				F1F49B8716AD8C30008715A2 /* iOS */,
 			);
 			);
 			name = Libraries;
 			name = Libraries;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -213,6 +221,36 @@
 			name = GamePlay;
 			name = GamePlay;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		F1F49B8516AD8C22008715A2 /* MacOSX */ = {
+			isa = PBXGroup;
+			children = (
+				F1F49B8C16AD8F1B008715A2 /* libbullet.a */,
+				F1F49BED16AD9BD4008715A2 /* liblua.a */,
+				F1F49BC216AD94EE008715A2 /* libogg.a */,
+				F1F49BC316AD94EE008715A2 /* libvorbis.a */,
+				F1F49BC416AD94EE008715A2 /* libvorbisenc.a */,
+				F1F49BC516AD94EE008715A2 /* libvorbisfile.a */,
+				F1F49BCB16AD9502008715A2 /* libpng.a */,
+				42C9332D1491A7810098216A /* libz.dylib */,
+			);
+			name = MacOSX;
+			sourceTree = "<group>";
+		};
+		F1F49B8716AD8C30008715A2 /* iOS */ = {
+			isa = PBXGroup;
+			children = (
+				F1F49B8E16AD8F3F008715A2 /* libbullet.a */,
+				F1F49BF016AD9BFB008715A2 /* liblua.a */,
+				F1F49BCD16AD951A008715A2 /* libogg.a */,
+				F1F49BCE16AD951A008715A2 /* libvorbis.a */,
+				F1F49BCF16AD951A008715A2 /* libvorbisenc.a */,
+				F1F49BD016AD951A008715A2 /* libvorbisfile.a */,
+				F1F49BD516AD9535008715A2 /* libpng.a */,
+				F1F49B8A16AD8E02008715A2 /* libz.dylib */,
+			);
+			name = iOS;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXNativeTarget section */
 /* Begin PBXNativeTarget section */
@@ -420,6 +458,7 @@
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
 				);
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
@@ -447,6 +486,7 @@
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
 				);
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
@@ -457,7 +497,7 @@
 		5B61612A14CCC24C0073B857 /* Debug */ = {
 		5B61612A14CCC24C0073B857 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
-                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@@ -470,15 +510,16 @@
 					"GAMEPLAY_PATH/external-deps/lua/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
 				);
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-                IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1;
 				LIBRARY_SEARCH_PATHS = (
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(inherited)",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
 				);
 				);
 				SDKROOT = iphoneos;
 				SDKROOT = iphoneos;
-                TARGETED_DEVICE_FAMILY = "1,2";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
 				WRAPPER_EXTENSION = app;
 				WRAPPER_EXTENSION = app;
 			};
 			};
@@ -487,7 +528,7 @@
 		5B61612B14CCC24C0073B857 /* Release */ = {
 		5B61612B14CCC24C0073B857 /* Release */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
-                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@@ -500,15 +541,16 @@
 					"GAMEPLAY_PATH/external-deps/lua/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
 				);
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-                IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 5.1;
 				LIBRARY_SEARCH_PATHS = (
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(inherited)",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
 				);
 				);
 				SDKROOT = iphoneos;
 				SDKROOT = iphoneos;
-                TARGETED_DEVICE_FAMILY = "1,2";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
 				WRAPPER_EXTENSION = app;
 				WRAPPER_EXTENSION = app;
 			};
 			};

+ 16 - 12
gameplay/res/shaders/terrain.frag

@@ -24,42 +24,46 @@ vec3 v_normalVector;                            // Normal vector variable (from
 varying vec3 v_normalVector;					// Normal vector from vertex shader
 varying vec3 v_normalVector;					// Normal vector from vertex shader
 #endif
 #endif
 varying vec2 v_texCoord0;
 varying vec2 v_texCoord0;
+#if (LAYER_COUNT > 0)
+varying vec2 v_texCoordLayer0;
+#endif
+#if (LAYER_COUNT > 1)
+varying vec2 v_texCoordLayer1;
+#endif
+#if (LAYER_COUNT > 2)
+varying vec2 v_texCoordLayer2;
+#endif
 
 
 // Lighting
 // Lighting
 #include "lighting.frag"
 #include "lighting.frag"
 #include "lighting-directional.frag"
 #include "lighting-directional.frag"
 
 
 #if (LAYER_COUNT > 1)
 #if (LAYER_COUNT > 1)
-void blendLayer(sampler2D textureMap, vec2 textureRepeat, float alphaBlend)
+void blendLayer(sampler2D textureMap, vec2 texCoord, float alphaBlend)
 {
 {
-    vec2 uv = mod(v_texCoord0 * textureRepeat, vec2(1,1));
-
     // Sample full intensity diffuse color
     // Sample full intensity diffuse color
-    vec3 diffuse = texture2D(textureMap, uv).rgb;
+    vec3 diffuse = texture2D(textureMap,  mod(texCoord, vec2(1,1))).rgb;
 
 
     _baseColor.rgb = _baseColor.rgb * (1.0 - alphaBlend) + diffuse * alphaBlend;
     _baseColor.rgb = _baseColor.rgb * (1.0 - alphaBlend) + diffuse * alphaBlend;
 }
 }
 #endif
 #endif
 
 
-
 void main()
 void main()
 {
 {
 #if (LAYER_COUNT > 0)
 #if (LAYER_COUNT > 0)
-    // Set base diffuse color
-    vec2 uvCoord = mod(v_texCoord0 * TEXTURE_REPEAT_0, vec2(1,1));
-	_baseColor.rgb = texture2D(u_samplers[TEXTURE_INDEX_0], uvCoord).rgb;
+    // Sample base texture
+	_baseColor.rgb = texture2D(u_samplers[TEXTURE_INDEX_0], mod(v_texCoordLayer0, vec2(1,1))).rgb;
     _baseColor.a = 1.0;
     _baseColor.a = 1.0;
 #else
 #else
-    // If no layers are defined, simple use a white color
+    // If no layers are defined, simply use a white color
     _baseColor = vec4(1,1,1,1);
     _baseColor = vec4(1,1,1,1);
 #endif
 #endif
 
 
 #if (LAYER_COUNT > 1)
 #if (LAYER_COUNT > 1)
-    blendLayer(u_samplers[TEXTURE_INDEX_1], TEXTURE_REPEAT_1, texture2D(u_samplers[BLEND_INDEX_1], v_texCoord0)[BLEND_CHANNEL_1]);
+    blendLayer(u_samplers[TEXTURE_INDEX_1], v_texCoordLayer1, texture2D(u_samplers[BLEND_INDEX_1], v_texCoord0)[BLEND_CHANNEL_1]);
 #endif
 #endif
-
 #if (LAYER_COUNT > 2)
 #if (LAYER_COUNT > 2)
-    blendLayer(u_samplers[TEXTURE_INDEX_2], TEXTURE_REPEAT_2, texture2D(u_samplers[BLEND_INDEX_2], v_texCoord0)[BLEND_CHANNEL_2]);
+    blendLayer(u_samplers[TEXTURE_INDEX_2], v_texCoordLayer2, texture2D(u_samplers[BLEND_INDEX_2], v_texCoord0)[BLEND_CHANNEL_2]);
 #endif
 #endif
 
 
 #if defined(DEBUG_PATCHES)
 #if defined(DEBUG_PATCHES)

+ 14 - 20
gameplay/res/shaders/terrain.vert

@@ -4,15 +4,6 @@ attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 attribute vec3 a_normal;									// Vertex Normal							(x, y, z)
 attribute vec3 a_normal;									// Vertex Normal							(x, y, z)
 #endif
 #endif
 attribute vec2 a_texCoord0;
 attribute vec2 a_texCoord0;
-#if LAYER_COUNT > 1
-attribute vec2 a_texCoord1;
-#endif
-#if LAYER_COUNT > 2
-attribute vec2 a_texCoord2;
-#endif
-#if LAYER_COUNT > 3
-attribute vec2 a_texCoord3;
-#endif
 
 
 // Uniforms
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// World view projection matrix
 uniform mat4 u_worldViewProjectionMatrix;					// World view projection matrix
@@ -26,16 +17,15 @@ uniform vec3 u_lightDirection;								// Direction of light
 varying vec3 v_normalVector;								// Normal vector out
 varying vec3 v_normalVector;								// Normal vector out
 #endif
 #endif
 varying vec2 v_texCoord0;
 varying vec2 v_texCoord0;
+#if LAYER_COUNT > 0
+varying vec2 v_texCoordLayer0;
+#endif
 #if LAYER_COUNT > 1
 #if LAYER_COUNT > 1
-varying vec2 v_texCoord1;
+varying vec2 v_texCoordLayer1;
 #endif
 #endif
 #if LAYER_COUNT > 2
 #if LAYER_COUNT > 2
-varying vec2 v_texCoord2;
+varying vec2 v_texCoordLayer2;
 #endif
 #endif
-#if LAYER_COUNT > 3
-varying vec2 v_texCoord3;
-#endif
-
 
 
 void main()
 void main()
 {
 {
@@ -46,14 +36,18 @@ void main()
     // Pass normal to fragment shader
     // Pass normal to fragment shader
     v_normalVector = (u_normalMatrix * vec4(a_normal.x, a_normal.y, a_normal.z, 0)).xyz;
     v_normalVector = (u_normalMatrix * vec4(a_normal.x, a_normal.y, a_normal.z, 0)).xyz;
 #endif
 #endif
+
+    // Pass base texture coord
     v_texCoord0 = a_texCoord0;
     v_texCoord0 = a_texCoord0;
+
+    // Pass repeated texture coordinates for each layer
+#if LAYER_COUNT > 0
+    v_texCoordLayer0 = a_texCoord0 * TEXTURE_REPEAT_0;
+#endif
 #if LAYER_COUNT > 1
 #if LAYER_COUNT > 1
-    v_texCoord1 = a_texCoord1;
+    v_texCoordLayer1 = a_texCoord0 * TEXTURE_REPEAT_1;
 #endif
 #endif
 #if LAYER_COUNT > 2
 #if LAYER_COUNT > 2
-    v_texCoord2 = a_texCoord2;
-#endif
-#if LAYER_COUNT > 3
-    v_texCoord3 = a_texCoord3;
+    v_texCoordLayer2 = a_texCoord0 * TEXTURE_REPEAT_2;
 #endif
 #endif
 }
 }

+ 1 - 1
gameplay/src/Base.h

@@ -279,7 +279,7 @@ typedef GLuint FrameBufferHandle;
 typedef GLuint RenderBufferHandle;
 typedef GLuint RenderBufferHandle;
 
 
 /** Gamepad handle definitions vary by platform. */
 /** Gamepad handle definitions vary by platform. */
-#ifdef __QNX__
+#if defined(__QNX__) && defined (USE_BLACKBERRY_GAMEPAD)
     typedef screen_device_t GamepadHandle;
     typedef screen_device_t GamepadHandle;
 #elif USE_XINPUT
 #elif USE_XINPUT
     typedef unsigned long GamepadHandle;
     typedef unsigned long GamepadHandle;

+ 2 - 0
gameplay/src/Control.cpp

@@ -43,6 +43,8 @@ void Control::initialize(Theme::Style* style, Properties* properties)
 
 
     _consumeInputEvents = properties->getBool("consumeInputEvents", true);
     _consumeInputEvents = properties->getBool("consumeInputEvents", true);
 
 
+    _visible = properties->getBool("visible", true);
+
     if (properties->exists("zIndex"))
     if (properties->exists("zIndex"))
     {
     {
         _zIndex = properties->getInt("zIndex");
         _zIndex = properties->getInt("zIndex");

+ 16 - 14
gameplay/src/Form.cpp

@@ -26,7 +26,6 @@ Form::Form() : _theme(NULL), _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL)
 
 
 Form::~Form()
 Form::~Form()
 {
 {
-    SAFE_RELEASE(_node);
     SAFE_DELETE(_spriteBatch);
     SAFE_DELETE(_spriteBatch);
     SAFE_RELEASE(_frameBuffer);
     SAFE_RELEASE(_frameBuffer);
     SAFE_RELEASE(_theme);
     SAFE_RELEASE(_theme);
@@ -233,7 +232,7 @@ void Form::setSize(float width, float height)
         _u2 = width / (float)w;
         _u2 = width / (float)w;
         _v1 = height / (float)h;
         _v1 = height / (float)h;
 
 
-        // Create framebuffer if necessary.
+        // Create framebuffer if necessary. TODO: Use pool to cache.
         if (_frameBuffer)
         if (_frameBuffer)
             SAFE_RELEASE(_frameBuffer)
             SAFE_RELEASE(_frameBuffer)
         
         
@@ -250,16 +249,17 @@ void Form::setSize(float width, float height)
 
 
         // Clear the framebuffer black
         // Clear the framebuffer black
         Game* game = Game::getInstance();
         Game* game = Game::getInstance();
-        _frameBuffer->bind();
-        Rectangle prevViewport = game->getViewport();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
+        Rectangle previousViewport = game->getViewport();
+
         game->setViewport(Rectangle(0, 0, width, height));
         game->setViewport(Rectangle(0, 0, width, height));
         _theme->setProjectionMatrix(_projectionMatrix);
         _theme->setProjectionMatrix(_projectionMatrix);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
-        FrameBuffer::bindDefault();
-        game->setViewport(prevViewport);
+
+        previousFrameBuffer->bind();
+        game->setViewport(previousViewport);
     }
     }
-    
     _bounds.width = width;
     _bounds.width = width;
     _bounds.height = height;
     _bounds.height = height;
     _dirty = true;
     _dirty = true;
@@ -481,10 +481,9 @@ void Form::updateBounds()
         }
         }
  
  
         _viewportClipBounds.set(x, y, width, height);
         _viewportClipBounds.set(x, y, width, height);
-
         _absoluteClipBounds.set(x - border.left - padding.left, y - border.top - padding.top,
         _absoluteClipBounds.set(x - border.left - padding.left, y - border.top - padding.top,
-            width + border.left + padding.left + border.right + padding.right,
-            height + border.top + padding.top + border.bottom + padding.bottom);
+                                width + border.left + padding.left + border.right + padding.right,
+                                height + border.top + padding.top + border.bottom + padding.bottom);
         if (_clearBounds.isEmpty())
         if (_clearBounds.isEmpty())
         {
         {
             _clearBounds.set(_absoluteClipBounds);
             _clearBounds.set(_absoluteClipBounds);
@@ -515,9 +514,13 @@ void Form::updateBounds()
 
 
         GP_ASSERT(_layout);
         GP_ASSERT(_layout);
         if (_scroll != SCROLL_NONE)
         if (_scroll != SCROLL_NONE)
+        {
             updateScroll();
             updateScroll();
+        }
         else
         else
+        {
             _layout->update(this, Vector2::zero());
             _layout->update(this, Vector2::zero());
+        }
     }
     }
 }
 }
 
 
@@ -535,7 +538,7 @@ void Form::draw()
     if (isDirty())
     if (isDirty())
     {
     {
         GP_ASSERT(_frameBuffer);
         GP_ASSERT(_frameBuffer);
-        _frameBuffer->bind();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
 
 
         Game* game = Game::getInstance();
         Game* game = Game::getInstance();
         Rectangle prevViewport = game->getViewport();
         Rectangle prevViewport = game->getViewport();
@@ -547,11 +550,10 @@ void Form::draw()
                         _skin != NULL, false, _bounds.height);
                         _skin != NULL, false, _bounds.height);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
 
 
-        // Rebind the default framebuffer and game viewport.
-        FrameBuffer::bindDefault();
-
         // restore the previous game viewport
         // restore the previous game viewport
         game->setViewport(prevViewport);
         game->setViewport(prevViewport);
+        // Rebind the previous framebuffer and game viewport.
+        previousFrameBuffer->bind();
     }
     }
 
 
     // Draw either with a 3D quad or sprite batch
     // Draw either with a 3D quad or sprite batch

+ 42 - 47
gameplay/src/FrameBuffer.cpp

@@ -1,20 +1,19 @@
-/**
- * FrameBuffer.cpp
- */
-
 #include "Base.h"
 #include "Base.h"
 #include "FrameBuffer.h"
 #include "FrameBuffer.h"
+#include "Game.h"
+
+#define FRAMEBUFFER_ID_DEFAULT "org.gameplay3d.framebuffer.default"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-static unsigned int __maxRenderTargets = 0;
-static std::vector<FrameBuffer*> __frameBuffers;
-static FrameBufferHandle __defaultHandle = 0;
-static FrameBufferHandle __currentHandle = 0;
+unsigned int FrameBuffer::_maxRenderTargets = 0;
+std::vector<FrameBuffer*> FrameBuffer::_frameBuffers;
+FrameBuffer* FrameBuffer::_defaultFrameBuffer = NULL;
+FrameBuffer* FrameBuffer::_currentFrameBuffer = NULL;
 
 
-FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height) :
-    _id(id ? id : ""), _width(width), _height(height), _handle(0), 
+FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle) :
+    _id(id ? id : ""), _width(width), _height(height), _handle(handle), 
     _renderTargets(NULL), _depthStencilTarget(NULL)
     _renderTargets(NULL), _depthStencilTarget(NULL)
 {
 {
 }
 }
@@ -23,7 +22,7 @@ FrameBuffer::~FrameBuffer()
 {
 {
     if (_renderTargets)
     if (_renderTargets)
     {
     {
-        for (unsigned int i = 0; i < __maxRenderTargets; ++i)
+        for (unsigned int i = 0; i < _maxRenderTargets; ++i)
         {
         {
             if (_renderTargets[i])
             if (_renderTargets[i])
             {
             {
@@ -44,10 +43,10 @@ FrameBuffer::~FrameBuffer()
     }
     }
 
 
     // Remove self from vector.
     // Remove self from vector.
-    std::vector<FrameBuffer*>::iterator it = std::find(__frameBuffers.begin(), __frameBuffers.end(), this);
-    if (it != __frameBuffers.end())
+    std::vector<FrameBuffer*>::iterator it = std::find(_frameBuffers.begin(), _frameBuffers.end(), this);
+    if (it != _frameBuffers.end())
     {
     {
-        __frameBuffers.erase(it);
+        _frameBuffers.erase(it);
     }
     }
 }
 }
 
 
@@ -57,20 +56,25 @@ void FrameBuffer::initialize()
     // On many platforms this will simply be the zero (0) handle, but this is not always the case.
     // On many platforms this will simply be the zero (0) handle, but this is not always the case.
     GLint fbo;
     GLint fbo;
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
-    __defaultHandle = (FrameBufferHandle)fbo;
-    __currentHandle = __defaultHandle;
+    _defaultFrameBuffer = new FrameBuffer(FRAMEBUFFER_ID_DEFAULT, 0, 0, (FrameBufferHandle)fbo);
+    _currentFrameBuffer = _defaultFrameBuffer;
 
 
     // Query the max supported color attachments. This glGet operation is not supported
     // Query the max supported color attachments. This glGet operation is not supported
     // on GL ES 2.x, so if the define does not exist, assume a value of 1.
     // on GL ES 2.x, so if the define does not exist, assume a value of 1.
 #ifdef GL_MAX_COLOR_ATTACHMENTS
 #ifdef GL_MAX_COLOR_ATTACHMENTS
         GLint val;
         GLint val;
         GL_ASSERT( glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &val) );
         GL_ASSERT( glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &val) );
-        __maxRenderTargets = (unsigned int)std::max(1, val);
+        _maxRenderTargets = (unsigned int)std::max(1, val);
 #else
 #else
-        __maxRenderTargets = 1;
+        _maxRenderTargets = 1;
 #endif
 #endif
 }
 }
 
 
+void FrameBuffer::finalize()
+{
+    SAFE_RELEASE(_defaultFrameBuffer);
+}
+
 FrameBuffer* FrameBuffer::create(const char* id)
 FrameBuffer* FrameBuffer::create(const char* id)
 {
 {
     return create(id, 0, 0);
     return create(id, 0, 0);
@@ -78,9 +82,6 @@ FrameBuffer* FrameBuffer::create(const char* id)
 
 
 FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned int height)
 FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned int height)
 {
 {
-    // Call getMaxRenderTargets() to force __maxRenderTargets to be set
-    getMaxRenderTargets();
-
     RenderTarget* renderTarget = NULL;
     RenderTarget* renderTarget = NULL;
     if (width > 0 && height > 0)
     if (width > 0 && height > 0)
     {
     {
@@ -96,12 +97,11 @@ FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned in
     // Create the frame buffer
     // Create the frame buffer
     GLuint handle = 0;
     GLuint handle = 0;
     GL_ASSERT( glGenFramebuffers(1, &handle) );
     GL_ASSERT( glGenFramebuffers(1, &handle) );
-    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height);
-    frameBuffer->_handle = handle;
+    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height, handle);
     
     
     // Create the render target array for the new frame buffer
     // Create the render target array for the new frame buffer
-    frameBuffer->_renderTargets = new RenderTarget*[__maxRenderTargets];
-    memset(frameBuffer->_renderTargets, 0, sizeof(RenderTarget*) * __maxRenderTargets);
+    frameBuffer->_renderTargets = new RenderTarget*[_maxRenderTargets];
+    memset(frameBuffer->_renderTargets, 0, sizeof(RenderTarget*) * _maxRenderTargets);
 
 
     if (renderTarget)
     if (renderTarget)
     {
     {
@@ -109,7 +109,7 @@ FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned in
         SAFE_RELEASE(renderTarget);
         SAFE_RELEASE(renderTarget);
     }
     }
 
 
-    __frameBuffers.push_back(frameBuffer);
+    _frameBuffers.push_back(frameBuffer);
 
 
     return frameBuffer;
     return frameBuffer;
 }
 }
@@ -120,7 +120,7 @@ FrameBuffer* FrameBuffer::getFrameBuffer(const char* id)
 
 
     // Search the vector for a matching ID.
     // Search the vector for a matching ID.
     std::vector<FrameBuffer*>::const_iterator it;
     std::vector<FrameBuffer*>::const_iterator it;
-    for (it = __frameBuffers.begin(); it < __frameBuffers.end(); ++it)
+    for (it = _frameBuffers.begin(); it < _frameBuffers.end(); ++it)
     {
     {
         FrameBuffer* fb = *it;
         FrameBuffer* fb = *it;
         GP_ASSERT(fb);
         GP_ASSERT(fb);
@@ -149,19 +149,17 @@ unsigned int FrameBuffer::getHeight() const
 
 
 unsigned int FrameBuffer::getMaxRenderTargets()
 unsigned int FrameBuffer::getMaxRenderTargets()
 {
 {
-    return __maxRenderTargets;
+    return _maxRenderTargets;
 }
 }
 
 
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 {
 {
-    GP_ASSERT(index < __maxRenderTargets);
+    GP_ASSERT(index < _maxRenderTargets);
     GP_ASSERT(_renderTargets);
     GP_ASSERT(_renderTargets);
 
 
+    // No change
     if (_renderTargets[index] == target)
     if (_renderTargets[index] == target)
-    {
-        // No change.
         return;
         return;
-    }
 
 
     // Release our reference to the current RenderTarget at this index.
     // Release our reference to the current RenderTarget at this index.
     SAFE_RELEASE(_renderTargets[index]);
     SAFE_RELEASE(_renderTargets[index]);
@@ -186,18 +184,18 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
         }
         }
 
 
         // Restore the FBO binding
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _currentFrameBuffer->_handle) );
     }
     }
+
 }
 }
 
 
 RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
 RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
 {
 {
     GP_ASSERT(_renderTargets);
     GP_ASSERT(_renderTargets);
-    if (index < __maxRenderTargets)
+    if (index < _maxRenderTargets)
     {
     {
         return _renderTargets[index];
         return _renderTargets[index];
     }
     }
-
     return NULL;
     return NULL;
 }
 }
 
 
@@ -234,7 +232,7 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
         }
         }
 
 
         // Restore the FBO binding
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _currentFrameBuffer->_handle) );
     }
     }
 }
 }
 
 
@@ -243,22 +241,19 @@ DepthStencilTarget* FrameBuffer::getDepthStencilTarget() const
     return _depthStencilTarget;
     return _depthStencilTarget;
 }
 }
 
 
-void FrameBuffer::bind()
+FrameBuffer* FrameBuffer::bind()
 {
 {
-    // Bind this FrameBuffer for rendering.
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
-
-    // Update the current FBO handle
-    __currentHandle = _handle;
+    FrameBuffer* previousFrameBuffer = _currentFrameBuffer;
+    _currentFrameBuffer = this;
+    return previousFrameBuffer;
 }
 }
 
 
-void FrameBuffer::bindDefault()
+FrameBuffer* FrameBuffer::bindDefault()
 {
 {
-    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultHandle) );
-
-    // Update the current FBO handle
-    __currentHandle = __defaultHandle;
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _defaultFrameBuffer->_handle) );
+    _currentFrameBuffer = _defaultFrameBuffer;
+    return _defaultFrameBuffer;
 }
 }
 
 
-
 }
 }

+ 28 - 12
gameplay/src/FrameBuffer.h

@@ -9,13 +9,17 @@ namespace gameplay
 {
 {
 
 
 /**
 /**
- * Defines a video output off all graphics buffer containing a complete frame of data.
- * This consists of a RenderTarget and DepthStencilTarget holding the color, depth and
- * stencil data in the rendering frame. 
- * 
- * to change the default Game framebuffer call Game::setFrameBuffer(myFrameBuffer);
- * To restore back to the default call Game::setFrameBuffer(NULL).
- * This is useful for rendering shadows and other post-processing effects.
+ * Defines a frame buffer object that may contain one or more render targets and optionally
+ * a depth-stencil target.
+ *
+ * Frame buffers can be created and used for off-screen rendering, which is useful for 
+ * techniques such as shadow mapping and post-processing. Render targets within a frame
+ * buffer can be both written to and read (by calling RenderTarget::getTexture).
+ *
+ * When binding a custom frame buffer, you should always store the return value of 
+ * FrameBuffer::bind and restore it when you are finished drawing to your frame buffer.
+ *
+ * To bind the default frame buffer, call FrameBuffer::bindDefault.
  */
  */
 class FrameBuffer : public Ref
 class FrameBuffer : public Ref
 {
 {
@@ -125,22 +129,27 @@ public:
     DepthStencilTarget* getDepthStencilTarget() const;
     DepthStencilTarget* getDepthStencilTarget() const;
  
  
     /**
     /**
-     * Binds this FrameBuffer for off-screen rendering.
+     * Binds this FrameBuffer for off-screen rendering and return you the curently bound one.
+     *
+     * You should keep the return FrameBuffer and store it and call bind() when you rendering is complete.
+     *
+     * @ return The currently bound framebuffer.
      */
      */
-    void bind();
+    FrameBuffer* bind();
 
 
     /**
     /**
      * Binds the default FrameBuffer for rendering to the display.
      * Binds the default FrameBuffer for rendering to the display.
+     *
+     * @ return The default framebuffer.
      */
      */
-    static void bindDefault(); 
+    static FrameBuffer* bindDefault(); 
      
      
 private:
 private:
 
 
-
     /**
     /**
      * Constructor.
      * Constructor.
      */
      */
-    FrameBuffer(const char* id, unsigned int width, unsigned int height);
+    FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle);
 
 
     /**
     /**
      * Destructor.
      * Destructor.
@@ -154,6 +163,8 @@ private:
 
 
     static void initialize();
     static void initialize();
 
 
+    static void finalize();
+
     static bool isPowerOfTwo(unsigned int value);
     static bool isPowerOfTwo(unsigned int value);
 
 
     std::string _id;
     std::string _id;
@@ -162,6 +173,11 @@ private:
     FrameBufferHandle _handle;
     FrameBufferHandle _handle;
     RenderTarget** _renderTargets;
     RenderTarget** _renderTargets;
     DepthStencilTarget* _depthStencilTarget;
     DepthStencilTarget* _depthStencilTarget;
+
+    static unsigned int _maxRenderTargets;
+    static std::vector<FrameBuffer*> _frameBuffers;
+    static FrameBuffer* _defaultFrameBuffer;
+    static FrameBuffer* _currentFrameBuffer;
 };
 };
 
 
 }
 }

+ 1 - 0
gameplay/src/Game.cpp

@@ -206,6 +206,7 @@ void Game::shutdown()
 
 
         SAFE_DELETE(_audioListener);
         SAFE_DELETE(_audioListener);
 
 
+        FrameBuffer::finalize();
         RenderState::finalize();
         RenderState::finalize();
 
 
         SAFE_DELETE(_properties);
         SAFE_DELETE(_properties);

+ 6 - 3
gameplay/src/Gamepad.cpp

@@ -2,6 +2,7 @@
 #include "Gamepad.h"
 #include "Gamepad.h"
 #include "Game.h"
 #include "Game.h"
 #include "Button.h"
 #include "Button.h"
+#include "Platform.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -9,7 +10,8 @@ namespace gameplay
 static std::vector<Gamepad*> __gamepads;
 static std::vector<Gamepad*> __gamepads;
 
 
 Gamepad::Gamepad(const char* formPath)
 Gamepad::Gamepad(const char* formPath)
-    : _handle(INT_MAX), _vendorId(0), _productId(0), _buttonCount(0), _joystickCount(0), _triggerCount(0), _form(NULL), _buttons(0)
+    : _handle((GamepadHandle)INT_MAX), _buttonCount(0), _joystickCount(0), _triggerCount(0), _vendorId(0), _productId(0),
+      _form(NULL), _buttons(0)
 {
 {
     GP_ASSERT(formPath);
     GP_ASSERT(formPath);
     _form = Form::create(formPath);
     _form = Form::create(formPath);
@@ -33,8 +35,9 @@ Gamepad::Gamepad(const char* formPath)
 
 
 Gamepad::Gamepad(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
 Gamepad::Gamepad(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
                  unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
                  unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
-    : _handle(handle), _vendorId(vendorId), _productId(productId), _vendorString(vendorString), _productString(productString),
-      _buttonCount(buttonCount), _joystickCount(joystickCount), _triggerCount(triggerCount), _form(NULL), _buttons(0)
+    : _handle(handle), _buttonCount(buttonCount), _joystickCount(joystickCount), _triggerCount(triggerCount),
+      _vendorId(vendorId), _productId(productId), _vendorString(vendorString), _productString(productString),
+      _form(NULL), _buttons(0)
 {
 {
 }
 }
 
 

+ 3 - 11
gameplay/src/HeightField.cpp

@@ -50,21 +50,13 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
     GP_ASSERT(path);
     GP_ASSERT(path);
     GP_ASSERT(heightMax >= heightMin);
     GP_ASSERT(heightMax >= heightMin);
 
 
-    // Validate input parameters
-    size_t pathLength = strlen(path);
-    if (pathLength <= 4)
-    {
-        GP_WARN("Unrecognized file extension for heightfield image: %s.", path);
-        return NULL;
-    }
-
     float heightScale = heightMax - heightMin;
     float heightScale = heightMax - heightMin;
 
 
     HeightField* heightfield = NULL;
     HeightField* heightfield = NULL;
 
 
     // Load height data from image
     // Load height data from image
-    const char* ext = path + (pathLength - 4);
-    if (ext[0] == '.' && toupper(ext[1]) == 'P' && toupper(ext[2]) == 'N' && toupper(ext[3]) == 'G')
+    std::string ext = FileSystem::getExtension(path);
+    if (ext == ".PNG")
     {
     {
         // Normal image
         // Normal image
         Image* image = Image::create(path);
         Image* image = Image::create(path);
@@ -102,7 +94,7 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
 
 
         SAFE_RELEASE(image);
         SAFE_RELEASE(image);
     }
     }
-    else if (ext[0] == '.' && toupper(ext[1]) == 'R' && toupper(ext[2]) == 'A' && toupper(ext[3]) == 'W')
+    else if (ext == ".RAW" || ext == ".R16")
     {
     {
         // RAW image (headerless)
         // RAW image (headerless)
         if (width < 2 || height < 2 || heightMax < 0)
         if (width < 2 || height < 2 || heightMax < 0)

+ 2 - 2
gameplay/src/HeightField.h

@@ -52,7 +52,7 @@ namespace gameplay
          * or 16-bit (RAW16) format. RAW16 files must have little endian (PC) byte ordering. Since
          * or 16-bit (RAW16) format. RAW16 files must have little endian (PC) byte ordering. Since
          * RAW files have no header, you must specify the dimensions of the data in the file.
          * RAW files have no header, you must specify the dimensions of the data in the file.
          * This method automatically determines (based on file size) whether the input file
          * This method automatically determines (based on file size) whether the input file
-         * is RAW8 or RAW16.
+         * is RAW8 or RAW16. RAW files must have a .raw or .r16 file extension.
          *
          *
          * RAW files are commonly used in software that produces heightmap images. Using RAW16 is 
          * RAW files are commonly used in software that produces heightmap images. Using RAW16 is 
          * preferred or any 8-bit heightfield source since it allows greater precision, resulting in
          * preferred or any 8-bit heightfield source since it allows greater precision, resulting in
@@ -62,7 +62,7 @@ namespace gameplay
          * intensity to height values. The minHeight parameter is mapped to zero intensity
          * intensity to height values. The minHeight parameter is mapped to zero intensity
          * pixel, while maxHeight maxHeight is mapped to full intensity pixels.
          * pixel, while maxHeight maxHeight is mapped to full intensity pixels.
          *
          *
-         * @param path Path to the RAW file.
+         * @param path Path to the RAW file (must end in a .raw or .r16 file extension).
          * @param width Width of the RAW data.
          * @param width Width of the RAW data.
          * @param height Height of the RAW data.
          * @param height Height of the RAW data.
          * @param heightMin Minimum height value for a zero intensity pixel.
          * @param heightMin Minimum height value for a zero intensity pixel.

+ 0 - 6
gameplay/src/Light.cpp

@@ -161,15 +161,11 @@ void Light::setRange(float range)
     {
     {
     case POINT:
     case POINT:
         GP_ASSERT(_point);
         GP_ASSERT(_point);
-        GP_ASSERT(range);
-
         _point->range = range;
         _point->range = range;
         _point->rangeInverse = 1.0f / range;
         _point->rangeInverse = 1.0f / range;
         break;
         break;
     case SPOT:
     case SPOT:
         GP_ASSERT(_spot);
         GP_ASSERT(_spot);
-        GP_ASSERT(range);
-
         _spot->range = range;
         _spot->range = range;
         _spot->rangeInverse = 1.0f / range;
         _spot->rangeInverse = 1.0f / range;
         break;
         break;
@@ -276,14 +272,12 @@ Light::Directional::Directional(const Vector3& color)
 Light::Point::Point(const Vector3& color, float range)
 Light::Point::Point(const Vector3& color, float range)
     : color(color), range(range)
     : color(color), range(range)
 {
 {
-    GP_ASSERT(range);
     rangeInverse = 1.0f / range;
     rangeInverse = 1.0f / range;
 }
 }
 
 
 Light::Spot::Spot(const Vector3& color, float range, float innerAngle, float outerAngle)
 Light::Spot::Spot(const Vector3& color, float range, float innerAngle, float outerAngle)
     : color(color), range(range), innerAngle(innerAngle), outerAngle(outerAngle)
     : color(color), range(range), innerAngle(innerAngle), outerAngle(outerAngle)
 {
 {
-    GP_ASSERT(range);
     rangeInverse = 1.0f / range;
     rangeInverse = 1.0f / range;
     innerAngleCos = cos(innerAngle);
     innerAngleCos = cos(innerAngle);
     outerAngleCos = cos(outerAngle);
     outerAngleCos = cos(outerAngle);

+ 0 - 1
gameplay/src/Node.cpp

@@ -844,7 +844,6 @@ void Node::setForm(Form* form)
     }
     }
 }
 }
 
 
-
 const BoundingSphere& Node::getBoundingSphere() const
 const BoundingSphere& Node::getBoundingSphere() const
 {
 {
     if (_dirtyBits & NODE_DIRTY_BOUNDS)
     if (_dirtyBits & NODE_DIRTY_BOUNDS)

+ 1 - 1
gameplay/src/PhysicsCollisionObject.cpp

@@ -35,7 +35,7 @@ struct CollidesWithCallback : public btCollisionWorld::ContactResultCallback
 };
 };
 
 
 PhysicsCollisionObject::PhysicsCollisionObject(Node* node)
 PhysicsCollisionObject::PhysicsCollisionObject(Node* node)
-    : _node(node), _motionState(NULL), _collisionShape(NULL), _enabled(true), _scriptListeners(NULL)
+    : _node(node), _collisionShape(NULL), _enabled(true), _scriptListeners(NULL), _motionState(NULL)
 {
 {
 }
 }
 
 

+ 1 - 1
gameplay/src/PhysicsCollisionShape.cpp

@@ -332,7 +332,7 @@ PhysicsCollisionShape::Definition PhysicsCollisionShape::Definition::create(Node
                 HeightField* heightfield = NULL;
                 HeightField* heightfield = NULL;
                 if (ext == ".PNG")
                 if (ext == ".PNG")
                     heightfield = HeightField::createFromImage(imagePath, minHeight, maxHeight);
                     heightfield = HeightField::createFromImage(imagePath, minHeight, maxHeight);
-                else if (ext == ".RAW")
+                else if (ext == ".RAW" || ext == ".R16")
                     heightfield = HeightField::createFromRAW(imagePath, (unsigned int)width, (unsigned int)height, minHeight, maxHeight);
                     heightfield = HeightField::createFromRAW(imagePath, (unsigned int)width, (unsigned int)height, minHeight, maxHeight);
 
 
                 if (heightfield)
                 if (heightfield)

+ 9 - 7
gameplay/src/Platform.h

@@ -231,13 +231,6 @@ private:
      */
      */
     static bool isGestureRegistered(Gesture::GestureEvent evt);
     static bool isGestureRegistered(Gesture::GestureEvent evt);
 
 
-    /**
-     * Polls the platform for the updated Gamepad states such as joysticks, buttons and trigger values.
-     *
-     * @param gamepad The gamepad to be returned with the latest polled values populated.
-     */
-    static void pollGamepadState(Gamepad* gamepad);
-
     /**
     /**
      * Opens an URL in an external browser, if available.
      * Opens an URL in an external browser, if available.
      *
      *
@@ -295,6 +288,15 @@ public:
      */
      */
     static void gamepadEventDisconnectedInternal(GamepadHandle handle);
     static void gamepadEventDisconnectedInternal(GamepadHandle handle);
 
 
+    /**
+     * Internal metehod used by Gamepad that polls the platform for the updated Gamepad
+     * states such as joysticks, buttons and trigger values.
+     *
+     * @param gamepad The gamepad to be returned with the latest polled values populated.
+     * @script{ignore}
+     */
+    static void pollGamepadState(Gamepad* gamepad);
+
 private:
 private:
 
 
     Game* _game;                // The game this platform is interfacing with.
     Game* _game;                // The game this platform is interfacing with.

+ 16 - 12
gameplay/src/PlatformBlackBerry.cpp

@@ -491,35 +491,31 @@ void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* para
     }
     }
 }
 }
 
 
-#ifdef BLACKBERRY_USE_GAMEPAD
+#ifdef USE_BLACKBERRY_GAMEPAD
 
 
 static const char* __vendorStrings[] =
 static const char* __vendorStrings[] =
 {
 {
     "SteelSeries",
     "SteelSeries",
     "Nintendo",
     "Nintendo",
-    "Fructel"
 };
 };
 
 
 static const char* __productStrings[] =
 static const char* __productStrings[] =
 {
 {
     "FREE",
     "FREE",
     "Wii Remote",
     "Wii Remote",
-    "Gametel"
 };
 };
 
 
 static const int __VIDs[] = {
 static const int __VIDs[] = {
     0x1038,
     0x1038,
     0x057e,
     0x057e,
-    0x25b6
 };
 };
 
 
 static const int __PIDs[] = {
 static const int __PIDs[] = {
     0x1412,
     0x1412,
     0x0306,
     0x0306,
-    0x0001
 };
 };
 
 
-static const unsigned int __knownGamepads = 3;
+static const unsigned int __knownGamepads = 2;
 
 
 void queryGamepad(GamepadHandle handle, int* buttonCount, int* joystickCount, int* productId, int* vendorId, char* productString, char* vendorString)
 void queryGamepad(GamepadHandle handle, int* buttonCount, int* joystickCount, int* productId, int* vendorId, char* productString, char* vendorString)
 {
 {
@@ -627,6 +623,10 @@ void Platform::pollGamepadState(Gamepad* gamepad)
         gamepad->_triggers[i] = value;
         gamepad->_triggers[i] = value;
     }
     }
 }
 }
+#else
+void Platform::pollGamepadState(Gamepad* gamepad)
+{
+}
 #endif
 #endif
 
 
 Platform::Platform(Game* game)
 Platform::Platform(Game* game)
@@ -683,8 +683,6 @@ Platform* Platform::create(Game* game, void* attachToWindow)
     FileSystem::setResourcePath("./app/native/");
     FileSystem::setResourcePath("./app/native/");
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
 
 
-    screen_device_t* screenDevs;
-
     // Query game config
     // Query game config
     int samples = 0;
     int samples = 0;
     Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true);
     Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true);
@@ -972,7 +970,10 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
         glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
     }
     }
 
 
- #ifdef BLACKBERRY_USE_GAMEPAD
+ #ifdef USE_BLACKBERRY_GAMEPAD
+
+    screen_device_t* screenDevs;
+
     // Discover initial gamepad devices.
     // Discover initial gamepad devices.
     int count;
     int count;
     screen_get_context_property_iv(__screenContext, SCREEN_PROPERTY_DEVICE_COUNT, &count);
     screen_get_context_property_iv(__screenContext, SCREEN_PROPERTY_DEVICE_COUNT, &count);
@@ -1220,7 +1221,7 @@ int Platform::enterMessagePump()
                         }
                         }
                         break;
                         break;
                     }
                     }
-#ifdef BLACKBERRY_USE_GAMEPAD
+#ifdef USE_BLACKBERRY_GAMEPAD
                     case SCREEN_EVENT_DEVICE:
                     case SCREEN_EVENT_DEVICE:
                     {
                     {
                         // A device was attached or removed.
                         // A device was attached or removed.
@@ -1288,7 +1289,10 @@ int Platform::enterMessagePump()
                     break;
                     break;
                 }
                 }
                 case NAVIGATOR_EXIT:
                 case NAVIGATOR_EXIT:
-                    _game->exit();
+                	// Call Game::shutdown directly, instead of Game::exit.
+                	// We need to do this since exit() queues a request to shutdown for the
+                	// next frame, which will never get executed because we are suspended.
+                    _game->shutdown();
                     break;
                     break;
                 }
                 }
             }
             }
@@ -1326,7 +1330,7 @@ int Platform::enterMessagePump()
             rc = eglSwapBuffers(__eglDisplay, __eglSurface);
             rc = eglSwapBuffers(__eglDisplay, __eglSurface);
             if (rc != EGL_TRUE)
             if (rc != EGL_TRUE)
             {
             {
-                _game->exit();
+                _game->shutdown();
                 perror("eglSwapBuffers");
                 perror("eglSwapBuffers");
                 break;
                 break;
             }
             }

+ 1 - 1
gameplay/src/PlatformMacOSX.mm

@@ -935,7 +935,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
 - (void) mouseDragged: (NSEvent*) event
 - (void) mouseDragged: (NSEvent*) event
 {
 {
     NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
     NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
-    if (__leftMouseDown)
+    if (__leftMouseDown && !__mouseCaptured)
     {
     {
         [self mouse: Mouse::MOUSE_MOVE orTouchEvent: Touch::TOUCH_MOVE x: point.x y: __height - point.y s: 0];
         [self mouse: Mouse::MOUSE_MOVE orTouchEvent: Touch::TOUCH_MOVE x: point.x y: __height - point.y s: 0];
     }
     }

+ 31 - 30
gameplay/src/Scene.h

@@ -239,6 +239,10 @@ public:
      * The visitMethod parameter must be a pointer to a method that has a bool
      * The visitMethod parameter must be a pointer to a method that has a bool
      * return type and accepts a single parameter of type Node*.
      * return type and accepts a single parameter of type Node*.
      *
      *
+     * A depth-first traversal of the scene continues while the visit method
+     * returns true. Returning false will stop traversing further children for
+     * the given node and the traversal will continue at the next sibling.
+     *
      * @param instance The pointer to an instance of the object that contains visitMethod.
      * @param instance The pointer to an instance of the object that contains visitMethod.
      * @param visitMethod The pointer to the class method to call for each node in the scene.
      * @param visitMethod The pointer to the class method to call for each node in the scene.
      */
      */
@@ -253,8 +257,11 @@ public:
      * 
      * 
      * The visitMethod parameter must be a pointer to a method that has a bool
      * The visitMethod parameter must be a pointer to a method that has a bool
      * return type and accepts two parameters: a Node pointer and a cookie of a
      * return type and accepts two parameters: a Node pointer and a cookie of a
-     * user-specified type. The scene traversal continues while visitMethod return
-     * true. Returning false will cause the traversal to stop.
+     * user-specified type.
+     *
+     * A depth-first traversal of the scene continues while the visit method
+     * returns true. Returning false will stop traversing further children for
+     * the given node and the traversal will continue at the next sibling.
      *
      *
      * @param instance The pointer to an instance of the object that contains visitMethod.
      * @param instance The pointer to an instance of the object that contains visitMethod.
      * @param visitMethod The pointer to the class method to call for each node in the scene.
      * @param visitMethod The pointer to the class method to call for each node in the scene.
@@ -273,6 +280,10 @@ public:
      * valid Lua function that has a boolean return type and accepts a 
      * valid Lua function that has a boolean return type and accepts a 
      * single parameter of type Node*.
      * single parameter of type Node*.
      *
      *
+     * A depth-first traversal of the scene continues while the visit method
+     * returns true. Returning false will stop traversing further children for
+     * the given node and the traversal will continue at the next sibling.
+     *
      * @param visitMethod The name of the Lua function to call for each node in the scene.
      * @param visitMethod The name of the Lua function to call for each node in the scene.
      */
      */
     inline void visit(const char* visitMethod);
     inline void visit(const char* visitMethod);
@@ -311,18 +322,18 @@ private:
      * Visits the given node and all of its children recursively.
      * Visits the given node and all of its children recursively.
      */
      */
     template <class T>
     template <class T>
-    bool visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*));
+    void visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*));
 
 
     /**
     /**
      * Visits the given node and all of its children recursively.
      * Visits the given node and all of its children recursively.
      */
      */
     template <class T, class C>
     template <class T, class C>
-    bool visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*,C), C cookie);
+    void visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*,C), C cookie);
 
 
     /**
     /**
      * Visits the given node and all of its children recursively.
      * Visits the given node and all of its children recursively.
      */
      */
-    inline bool visitNode(Node* node, const char* visitMethod);
+    inline void visitNode(Node* node, const char* visitMethod);
 
 
     std::string _id;
     std::string _id;
     Camera* _activeCamera;
     Camera* _activeCamera;
@@ -341,8 +352,7 @@ void Scene::visit(T* instance, bool (T::*visitMethod)(Node*))
 {
 {
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     {
     {
-        if (!visitNode(node, instance, visitMethod))
-            return;
+        visitNode(node, instance, visitMethod);
     }
     }
 }
 }
 
 
@@ -352,8 +362,7 @@ void Scene::visit(T* instance, bool (T::*visitMethod)(Node*,C), C cookie)
 {
 {
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     {
     {
-        if (!visitNode(node, instance, visitMethod, cookie))
-            return;
+        visitNode(node, instance, visitMethod, cookie);
     }
     }
 }
 }
 
 
@@ -361,59 +370,51 @@ inline void Scene::visit(const char* visitMethod)
 {
 {
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     for (Node* node = getFirstNode(); node != NULL; node = node->getNextSibling())
     {
     {
-        if (!visitNode(node, visitMethod))
-            return;
+        visitNode(node, visitMethod);
     }
     }
 }
 }
 
 
 template <class T>
 template <class T>
-bool Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*))
+void Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*))
 {
 {
     // Invoke the visit method for this node.
     // Invoke the visit method for this node.
     if (!(instance->*visitMethod)(node))
     if (!(instance->*visitMethod)(node))
-        return false;
+        return;
 
 
     // Recurse for all children.
     // Recurse for all children.
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     {
     {
-        if (!visitNode(child, instance, visitMethod))
-            return false;
+        visitNode(child, instance, visitMethod);
     }
     }
-
-    return true;
 }
 }
 
 
 template <class T, class C>
 template <class T, class C>
-bool Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*,C), C cookie)
+void Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*,C), C cookie)
 {
 {
     // Invoke the visit method for this node.
     // Invoke the visit method for this node.
     if (!(instance->*visitMethod)(node, cookie))
     if (!(instance->*visitMethod)(node, cookie))
-        return false;
+        return;
 
 
     // Recurse for all children.
     // Recurse for all children.
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     {
     {
-        if (!visitNode(child, instance, visitMethod, cookie))
-            return false;
+        visitNode(child, instance, visitMethod, cookie);
     }
     }
-
-    return true;
 }
 }
 
 
-inline bool Scene::visitNode(Node* node, const char* visitMethod)
+inline void Scene::visitNode(Node* node, const char* visitMethod)
 {
 {
+    ScriptController* sc = Game::getInstance()->getScriptController();
+
     // Invoke the visit method for this node.
     // Invoke the visit method for this node.
-    if (!Game::getInstance()->getScriptController()->executeFunction<bool>(visitMethod, "<Node>", node))
-        return false;
+    if (!sc->executeFunction<bool>(visitMethod, "<Node>", node))
+        return;
 
 
     // Recurse for all children.
     // Recurse for all children.
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     {
     {
-        if (!Game::getInstance()->getScriptController()->executeFunction<bool>(visitMethod, "<Node>", child))
-            return false;
+        visitNode(child, visitMethod);
     }
     }
-
-    return true;
 }
 }
 
 
 }
 }

+ 15 - 2
gameplay/src/Terrain.cpp

@@ -1,5 +1,6 @@
 #include "Base.h"
 #include "Base.h"
 #include "Terrain.h"
 #include "Terrain.h"
+#include "TerrainPatch.h"
 #include "Node.h"
 #include "Node.h"
 #include "FileSystem.h"
 #include "FileSystem.h"
 
 
@@ -103,7 +104,7 @@ Terrain* Terrain::create(const char* path, Properties* properties)
                 // Read normalized height values from heightmap image
                 // Read normalized height values from heightmap image
                 heightfield = HeightField::createFromImage(heightmap, 0, 1);
                 heightfield = HeightField::createFromImage(heightmap, 0, 1);
             }
             }
-            else if (ext == ".RAW")
+            else if (ext == ".RAW" || ext == ".R16")
             {
             {
                 // Require additional properties to be specified for RAW files
                 // Require additional properties to be specified for RAW files
                 Vector2 imageSize;
                 Vector2 imageSize;
@@ -145,7 +146,7 @@ Terrain* Terrain::create(const char* path, Properties* properties)
                 // Read normalized height values from heightmap image
                 // Read normalized height values from heightmap image
                 heightfield = HeightField::createFromImage(heightmap, 0, 1);
                 heightfield = HeightField::createFromImage(heightmap, 0, 1);
             }
             }
-            else if (ext == ".RAW")
+            else if (ext == ".RAW" || ext == ".R16")
             {
             {
                 GP_WARN("RAW heightmaps must be specified inside a heightmap block with width and height properties.");
                 GP_WARN("RAW heightmaps must be specified inside a heightmap block with width and height properties.");
                 if (!externalProperties)
                 if (!externalProperties)
@@ -553,6 +554,18 @@ const Matrix& Terrain::getNormalMatrix() const
     return _normalMatrix;
     return _normalMatrix;
 }
 }
 
 
+const Matrix& Terrain::getWorldViewMatrix() const
+{
+    static Matrix worldView;
+
+    if (_node)
+        Matrix::multiply(_node->getViewMatrix(), getWorldMatrix(), &worldView);
+    else
+        worldView = getWorldMatrix(); // no node, so nothing to get view from
+
+    return worldView;
+}
+
 const Matrix& Terrain::getWorldViewProjectionMatrix() const
 const Matrix& Terrain::getWorldViewProjectionMatrix() const
 {
 {
     static Matrix worldViewProj;
     static Matrix worldViewProj;

+ 11 - 2
gameplay/src/Terrain.h

@@ -1,15 +1,18 @@
 #ifndef TERRAIN_H_
 #ifndef TERRAIN_H_
 #define TERRAIN_H_
 #define TERRAIN_H_
 
 
-#include "TerrainPatch.h"
 #include "Transform.h"
 #include "Transform.h"
 #include "Properties.h"
 #include "Properties.h"
 #include "HeightField.h"
 #include "HeightField.h"
+#include "Texture.h"
+#include "BoundingBox.h"
+#include "TerrainPatch.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
 
 
 class Node;
 class Node;
+class TerrainPatch;
 
 
 /**
 /**
  * Defines a Terrain that is capable of rendering large landscapes from 2D heightmap images.
  * Defines a Terrain that is capable of rendering large landscapes from 2D heightmap images.
@@ -21,7 +24,8 @@ class Node;
  * 2. 24-bit high precision heightmap image (PNG), which can be generated from a mesh using
  * 2. 24-bit high precision heightmap image (PNG), which can be generated from a mesh using
  *    gameplay-encoder.
  *    gameplay-encoder.
  * 3. 8-bit or 16-bit RAW heightmap image using PC byte ordering (little endian), which is
  * 3. 8-bit or 16-bit RAW heightmap image using PC byte ordering (little endian), which is
- *    compatible with many external tools such as World Machine, Unity and more.
+ *    compatible with many external tools such as World Machine, Unity and more. The file
+ *    extension must be either .raw or .r16 for RAW files.
  *
  *
  * Physics/collision is supported by setting a rigid body collision object on the Node that
  * Physics/collision is supported by setting a rigid body collision object on the Node that
  * the terrain is attached to. The collision shape should be specified using
  * the terrain is attached to. The collision shape should be specified using
@@ -349,6 +353,11 @@ private:
      */
      */
     const Matrix& getNormalMatrix() const;
     const Matrix& getNormalMatrix() const;
 
 
+    /**
+     * Returns the world view matrix for the terrain, factoring in terrain local scaling.
+     */
+    const Matrix& getWorldViewMatrix() const;
+
     /**
     /**
      * Returns the world view projection matrix for the terrain, factoring in terrain local scaling.
      * Returns the world view projection matrix for the terrain, factoring in terrain local scaling.
      */
      */

+ 5 - 2
gameplay/src/TerrainPatch.cpp

@@ -561,8 +561,11 @@ unsigned int TerrainPatch::getVisibleTriangleCount() const
 
 
     // Does the current camera intersect this patch at all?
     // Does the current camera intersect this patch at all?
     BoundingBox bounds = getBoundingBox(true);
     BoundingBox bounds = getBoundingBox(true);
-    if (!camera->getFrustum().intersects(bounds))
-        return 0;
+    if (_terrain->_flags & Terrain::FRUSTUM_CULLING)
+    {
+        if (!camera->getFrustum().intersects(bounds))
+            return 0;
+    }
 
 
     // Return the triangle count of the LOD level depending on the camera
     // Return the triangle count of the LOD level depending on the camera
     size_t lod = computeLOD(camera, bounds);
     size_t lod = computeLOD(camera, bounds);

+ 2 - 2
gameplay/src/gameplay.h

@@ -38,8 +38,6 @@
 #include "VertexFormat.h"
 #include "VertexFormat.h"
 #include "VertexAttributeBinding.h"
 #include "VertexAttributeBinding.h"
 #include "Model.h"
 #include "Model.h"
-#include "HeightField.h"
-#include "Terrain.h"
 #include "Camera.h"
 #include "Camera.h"
 #include "Light.h"
 #include "Light.h"
 #include "Scene.h"
 #include "Scene.h"
@@ -52,6 +50,8 @@
 #include "RenderTarget.h"
 #include "RenderTarget.h"
 #include "DepthStencilTarget.h"
 #include "DepthStencilTarget.h"
 #include "ScreenDisplayer.h"
 #include "ScreenDisplayer.h"
+#include "HeightField.h"
+#include "Terrain.h"
 
 
 // Audio
 // Audio
 #include "AudioController.h"
 #include "AudioController.h"

+ 30 - 6
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -129,9 +129,21 @@ int lua_FrameBuffer_bind(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 FrameBuffer* instance = getInstance(state);
                 FrameBuffer* instance = getInstance(state);
-                instance->bind();
-                
-                return 0;
+                void* returnPtr = (void*)instance->bind();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "FrameBuffer");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
             }
             }
 
 
             lua_pushstring(state, "lua_FrameBuffer_bind - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_FrameBuffer_bind - Failed to match the given parameters to a valid function signature.");
@@ -560,9 +572,21 @@ int lua_FrameBuffer_static_bindDefault(lua_State* state)
     {
     {
         case 0:
         case 0:
         {
         {
-            FrameBuffer::bindDefault();
-            
-            return 0;
+            void* returnPtr = (void*)FrameBuffer::bindDefault();
+            if (returnPtr)
+            {
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "FrameBuffer");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
             break;
             break;
         }
         }
         default:
         default: