Преглед на файлове

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

seanpaultaylor преди 11 години
родител
ревизия
d304fd0625

+ 4 - 0
gameplay/CMakeLists.txt

@@ -539,12 +539,16 @@ set(GAMEPLAY_LUA
     src/lua/lua_TextBoxInputMode.h
     src/lua/lua_TextBoxInputMode.h
     src/lua/lua_Texture.cpp
     src/lua/lua_Texture.cpp
     src/lua/lua_Texture.h
     src/lua/lua_Texture.h
+    src/lua/lua_TextureCubeFace.cpp
+    src/lua/lua_TextureCubeFace.h
     src/lua/lua_TextureFilter.cpp
     src/lua/lua_TextureFilter.cpp
     src/lua/lua_TextureFilter.h
     src/lua/lua_TextureFilter.h
     src/lua/lua_TextureFormat.cpp
     src/lua/lua_TextureFormat.cpp
     src/lua/lua_TextureFormat.h
     src/lua/lua_TextureFormat.h
     src/lua/lua_TextureSampler.cpp
     src/lua/lua_TextureSampler.cpp
     src/lua/lua_TextureSampler.h
     src/lua/lua_TextureSampler.h
+    src/lua/lua_TextureType.cpp
+    src/lua/lua_TextureType.h
     src/lua/lua_TextureWrap.cpp
     src/lua/lua_TextureWrap.cpp
     src/lua/lua_TextureWrap.h
     src/lua/lua_TextureWrap.h
     src/lua/lua_Theme.cpp
     src/lua/lua_Theme.cpp

+ 2 - 0
gameplay/android/jni/Android.mk

@@ -262,9 +262,11 @@ LOCAL_SRC_FILES := \
     lua/lua_TextBox.cpp \
     lua/lua_TextBox.cpp \
     lua/lua_TextBoxInputMode.cpp \
     lua/lua_TextBoxInputMode.cpp \
     lua/lua_Texture.cpp \
     lua/lua_Texture.cpp \
+    lua/lua_TextureCubeFace.cpp \
     lua/lua_TextureFilter.cpp \
     lua/lua_TextureFilter.cpp \
     lua/lua_TextureFormat.cpp \
     lua/lua_TextureFormat.cpp \
     lua/lua_TextureSampler.cpp \
     lua/lua_TextureSampler.cpp \
+    lua/lua_TextureType.cpp \
     lua/lua_TextureWrap.cpp \
     lua/lua_TextureWrap.cpp \
     lua/lua_Theme.cpp \
     lua/lua_Theme.cpp \
     lua/lua_ThemeSideRegions.cpp \
     lua/lua_ThemeSideRegions.cpp \

+ 4 - 0
gameplay/gameplay.vcxproj

@@ -217,9 +217,11 @@
     <ClCompile Include="src\lua\lua_TextBox.cpp" />
     <ClCompile Include="src\lua\lua_TextBox.cpp" />
     <ClCompile Include="src\lua\lua_TextBoxInputMode.cpp" />
     <ClCompile Include="src\lua\lua_TextBoxInputMode.cpp" />
     <ClCompile Include="src\lua\lua_Texture.cpp" />
     <ClCompile Include="src\lua\lua_Texture.cpp" />
+    <ClCompile Include="src\lua\lua_TextureCubeFace.cpp" />
     <ClCompile Include="src\lua\lua_TextureFilter.cpp" />
     <ClCompile Include="src\lua\lua_TextureFilter.cpp" />
     <ClCompile Include="src\lua\lua_TextureFormat.cpp" />
     <ClCompile Include="src\lua\lua_TextureFormat.cpp" />
     <ClCompile Include="src\lua\lua_TextureSampler.cpp" />
     <ClCompile Include="src\lua\lua_TextureSampler.cpp" />
+    <ClCompile Include="src\lua\lua_TextureType.cpp" />
     <ClCompile Include="src\lua\lua_TextureWrap.cpp" />
     <ClCompile Include="src\lua\lua_TextureWrap.cpp" />
     <ClCompile Include="src\lua\lua_Theme.cpp" />
     <ClCompile Include="src\lua\lua_Theme.cpp" />
     <ClCompile Include="src\lua\lua_ThemeSideRegions.cpp" />
     <ClCompile Include="src\lua\lua_ThemeSideRegions.cpp" />
@@ -505,9 +507,11 @@
     <ClInclude Include="src\lua\lua_TextBox.h" />
     <ClInclude Include="src\lua\lua_TextBox.h" />
     <ClInclude Include="src\lua\lua_TextBoxInputMode.h" />
     <ClInclude Include="src\lua\lua_TextBoxInputMode.h" />
     <ClInclude Include="src\lua\lua_Texture.h" />
     <ClInclude Include="src\lua\lua_Texture.h" />
+    <ClInclude Include="src\lua\lua_TextureCubeFace.h" />
     <ClInclude Include="src\lua\lua_TextureFilter.h" />
     <ClInclude Include="src\lua\lua_TextureFilter.h" />
     <ClInclude Include="src\lua\lua_TextureFormat.h" />
     <ClInclude Include="src\lua\lua_TextureFormat.h" />
     <ClInclude Include="src\lua\lua_TextureSampler.h" />
     <ClInclude Include="src\lua\lua_TextureSampler.h" />
+    <ClInclude Include="src\lua\lua_TextureType.h" />
     <ClInclude Include="src\lua\lua_TextureWrap.h" />
     <ClInclude Include="src\lua\lua_TextureWrap.h" />
     <ClInclude Include="src\lua\lua_Theme.h" />
     <ClInclude Include="src\lua\lua_Theme.h" />
     <ClInclude Include="src\lua\lua_ThemeSideRegions.h" />
     <ClInclude Include="src\lua\lua_ThemeSideRegions.h" />

+ 12 - 0
gameplay/gameplay.vcxproj.filters

@@ -876,6 +876,12 @@
     <ClCompile Include="src\lua\lua_ContainerDirection.cpp">
     <ClCompile Include="src\lua\lua_ContainerDirection.cpp">
       <Filter>src\lua</Filter>
       <Filter>src\lua</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\lua\lua_TextureCubeFace.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_TextureType.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Plane.h">
     <ClInclude Include="src\Plane.h">
@@ -1739,6 +1745,12 @@
     <ClInclude Include="src\lua\lua_ContainerDirection.h">
     <ClInclude Include="src\lua\lua_ContainerDirection.h">
       <Filter>src\lua</Filter>
       <Filter>src\lua</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\lua\lua_TextureCubeFace.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_TextureType.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="src\ScriptController.inl">
     <None Include="src\ScriptController.inl">

+ 16 - 0
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -588,6 +588,10 @@
 		6290E04C18223DDD00A28FB9 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6290E04B18223DDD00A28FB9 /* GameKit.framework */; };
 		6290E04C18223DDD00A28FB9 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6290E04B18223DDD00A28FB9 /* GameKit.framework */; };
 		8BA1B8BF197C3212009FF517 /* lua_ContainerDirection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */; };
 		8BA1B8BF197C3212009FF517 /* lua_ContainerDirection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */; };
 		8BA1B8C0197C3212009FF517 /* lua_ContainerDirection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */; };
 		8BA1B8C0197C3212009FF517 /* lua_ContainerDirection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */; };
+		8C974D86193F709700FF9730 /* lua_TextureCubeFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C974D82193F709700FF9730 /* lua_TextureCubeFace.cpp */; };
+		8C974D87193F709700FF9730 /* lua_TextureCubeFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C974D82193F709700FF9730 /* lua_TextureCubeFace.cpp */; };
+		8C974D88193F709700FF9730 /* lua_TextureType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C974D84193F709700FF9730 /* lua_TextureType.cpp */; };
+		8C974D89193F709700FF9730 /* lua_TextureType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C974D84193F709700FF9730 /* lua_TextureType.cpp */; };
 		BD2636E516CF5B7400CFE15F /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */; };
 		BD2636E516CF5B7400CFE15F /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */; };
 		BD2636E616CF5B7400CFE15F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636E016CF5B7400CFE15F /* Foundation.framework */; };
 		BD2636E616CF5B7400CFE15F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636E016CF5B7400CFE15F /* Foundation.framework */; };
 		BD2636E716CF5B7400CFE15F /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636E116CF5B7400CFE15F /* OpenAL.framework */; };
 		BD2636E716CF5B7400CFE15F /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD2636E116CF5B7400CFE15F /* OpenAL.framework */; };
@@ -1219,6 +1223,10 @@
 		6290E04B18223DDD00A28FB9 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
 		6290E04B18223DDD00A28FB9 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
 		8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_ContainerDirection.cpp; sourceTree = "<group>"; };
 		8BA1B8BD197C3212009FF517 /* lua_ContainerDirection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_ContainerDirection.cpp; sourceTree = "<group>"; };
 		8BA1B8BE197C3212009FF517 /* lua_ContainerDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_ContainerDirection.h; sourceTree = "<group>"; };
 		8BA1B8BE197C3212009FF517 /* lua_ContainerDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_ContainerDirection.h; sourceTree = "<group>"; };
+		8C974D82193F709700FF9730 /* lua_TextureCubeFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_TextureCubeFace.cpp; sourceTree = "<group>"; };
+		8C974D83193F709700FF9730 /* lua_TextureCubeFace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_TextureCubeFace.h; sourceTree = "<group>"; };
+		8C974D84193F709700FF9730 /* lua_TextureType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_TextureType.cpp; sourceTree = "<group>"; };
+		8C974D85193F709700FF9730 /* lua_TextureType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_TextureType.h; sourceTree = "<group>"; };
 		BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
 		BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
 		BD2636E016CF5B7400CFE15F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
 		BD2636E016CF5B7400CFE15F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
 		BD2636E116CF5B7400CFE15F /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
 		BD2636E116CF5B7400CFE15F /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
@@ -1571,6 +1579,10 @@
 				420BBBDB1817416E00C7B720 /* lua_TextBoxInputMode.h */,
 				420BBBDB1817416E00C7B720 /* lua_TextBoxInputMode.h */,
 				420BBBDC1817416E00C7B720 /* lua_Texture.cpp */,
 				420BBBDC1817416E00C7B720 /* lua_Texture.cpp */,
 				420BBBDD1817416E00C7B720 /* lua_Texture.h */,
 				420BBBDD1817416E00C7B720 /* lua_Texture.h */,
+				8C974D82193F709700FF9730 /* lua_TextureCubeFace.cpp */,
+				8C974D83193F709700FF9730 /* lua_TextureCubeFace.h */,
+				8C974D84193F709700FF9730 /* lua_TextureType.cpp */,
+				8C974D85193F709700FF9730 /* lua_TextureType.h */,
 				420BBBDE1817416E00C7B720 /* lua_TextureFilter.cpp */,
 				420BBBDE1817416E00C7B720 /* lua_TextureFilter.cpp */,
 				420BBBDF1817416E00C7B720 /* lua_TextureFilter.h */,
 				420BBBDF1817416E00C7B720 /* lua_TextureFilter.h */,
 				420BBBE01817416E00C7B720 /* lua_TextureFormat.cpp */,
 				420BBBE01817416E00C7B720 /* lua_TextureFormat.cpp */,
@@ -2107,6 +2119,7 @@
 				42CC55941809A4EF00AAD8AD /* AnimationValue.cpp in Sources */,
 				42CC55941809A4EF00AAD8AD /* AnimationValue.cpp in Sources */,
 				42CC5A0E1809A4EF00AAD8AD /* Vector3.cpp in Sources */,
 				42CC5A0E1809A4EF00AAD8AD /* Vector3.cpp in Sources */,
 				420BBCC61817416F00C7B720 /* lua_FontFormat.cpp in Sources */,
 				420BBCC61817416F00C7B720 /* lua_FontFormat.cpp in Sources */,
+				8C974D88193F709700FF9730 /* lua_TextureType.cpp in Sources */,
 				42CC55BA1809A4EF00AAD8AD /* Camera.cpp in Sources */,
 				42CC55BA1809A4EF00AAD8AD /* Camera.cpp in Sources */,
 				42CC59201809A4EF00AAD8AD /* Model.cpp in Sources */,
 				42CC59201809A4EF00AAD8AD /* Model.cpp in Sources */,
 				420BBC161817416F00C7B720 /* lua_AIAgent.cpp in Sources */,
 				420BBC161817416F00C7B720 /* lua_AIAgent.cpp in Sources */,
@@ -2233,6 +2246,7 @@
 				420BBC0E1817416F00C7B720 /* ControlFactory.cpp in Sources */,
 				420BBC0E1817416F00C7B720 /* ControlFactory.cpp in Sources */,
 				420BBD021817416F00C7B720 /* lua_Global.cpp in Sources */,
 				420BBD021817416F00C7B720 /* lua_Global.cpp in Sources */,
 				42CC55741809A4EF00AAD8AD /* AIController.cpp in Sources */,
 				42CC55741809A4EF00AAD8AD /* AIController.cpp in Sources */,
+				8C974D86193F709700FF9730 /* lua_TextureCubeFace.cpp in Sources */,
 				420BBC9A1817416F00C7B720 /* lua_ControlListener.cpp in Sources */,
 				420BBC9A1817416F00C7B720 /* lua_ControlListener.cpp in Sources */,
 				42CC59361809A4EF00AAD8AD /* PhysicsCollisionObject.cpp in Sources */,
 				42CC59361809A4EF00AAD8AD /* PhysicsCollisionObject.cpp in Sources */,
 				420BBCFA1817416F00C7B720 /* lua_Gesture.cpp in Sources */,
 				420BBCFA1817416F00C7B720 /* lua_Gesture.cpp in Sources */,
@@ -2402,6 +2416,7 @@
 				42CC55951809A4EF00AAD8AD /* AnimationValue.cpp in Sources */,
 				42CC55951809A4EF00AAD8AD /* AnimationValue.cpp in Sources */,
 				420BBCC71817416F00C7B720 /* lua_FontFormat.cpp in Sources */,
 				420BBCC71817416F00C7B720 /* lua_FontFormat.cpp in Sources */,
 				42CC5A0F1809A4EF00AAD8AD /* Vector3.cpp in Sources */,
 				42CC5A0F1809A4EF00AAD8AD /* Vector3.cpp in Sources */,
+				8C974D89193F709700FF9730 /* lua_TextureType.cpp in Sources */,
 				42CC55BB1809A4EF00AAD8AD /* Camera.cpp in Sources */,
 				42CC55BB1809A4EF00AAD8AD /* Camera.cpp in Sources */,
 				420BBC171817416F00C7B720 /* lua_AIAgent.cpp in Sources */,
 				420BBC171817416F00C7B720 /* lua_AIAgent.cpp in Sources */,
 				42CC59211809A4EF00AAD8AD /* Model.cpp in Sources */,
 				42CC59211809A4EF00AAD8AD /* Model.cpp in Sources */,
@@ -2527,6 +2542,7 @@
 				420BBC0F1817416F00C7B720 /* ControlFactory.cpp in Sources */,
 				420BBC0F1817416F00C7B720 /* ControlFactory.cpp in Sources */,
 				420BBD031817416F00C7B720 /* lua_Global.cpp in Sources */,
 				420BBD031817416F00C7B720 /* lua_Global.cpp in Sources */,
 				42CC55751809A4EF00AAD8AD /* AIController.cpp in Sources */,
 				42CC55751809A4EF00AAD8AD /* AIController.cpp in Sources */,
+				8C974D87193F709700FF9730 /* lua_TextureCubeFace.cpp in Sources */,
 				420BBC9B1817416F00C7B720 /* lua_ControlListener.cpp in Sources */,
 				420BBC9B1817416F00C7B720 /* lua_ControlListener.cpp in Sources */,
 				42CC59371809A4EF00AAD8AD /* PhysicsCollisionObject.cpp in Sources */,
 				42CC59371809A4EF00AAD8AD /* PhysicsCollisionObject.cpp in Sources */,
 				420BBCFB1817416F00C7B720 /* lua_Gesture.cpp in Sources */,
 				420BBCFB1817416F00C7B720 /* lua_Gesture.cpp in Sources */,

+ 1 - 1
gameplay/src/Camera.h

@@ -51,7 +51,7 @@ public:
     /**
     /**
      * Creates a perspective camera.
      * Creates a perspective camera.
      *
      *
-     * @param fieldOfView The field of view for the perspective camera (normally in the range of 40-60 degrees).
+     * @param fieldOfView The field of view in degrees for the perspective camera (normally in the range of 40-60 degrees).
      * @param aspectRatio The aspect ratio of the camera (normally the width of the viewport divided by the height of the viewport).
      * @param aspectRatio The aspect ratio of the camera (normally the width of the viewport divided by the height of the viewport).
      * @param nearPlane The near plane distance.
      * @param nearPlane The near plane distance.
      * @param farPlane The far plane distance.
      * @param farPlane The far plane distance.

+ 7 - 3
gameplay/src/Effect.cpp

@@ -439,7 +439,7 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
                 uniform->_name = uniformName;
                 uniform->_name = uniformName;
                 uniform->_location = uniformLocation;
                 uniform->_location = uniformLocation;
                 uniform->_type = uniformType;
                 uniform->_type = uniformType;
-                if (uniformType == GL_SAMPLER_2D)
+                if (uniformType == GL_SAMPLER_2D || uniformType == GL_SAMPLER_CUBE)
                 {
                 {
                     uniform->_index = samplerIndex;
                     uniform->_index = samplerIndex;
                     samplerIndex += uniformSize;
                     samplerIndex += uniformSize;
@@ -608,8 +608,10 @@ void Effect::setValue(Uniform* uniform, const Vector4* values, unsigned int coun
 void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 {
 {
     GP_ASSERT(uniform);
     GP_ASSERT(uniform);
-    GP_ASSERT(uniform->_type == GL_SAMPLER_2D);
+    GP_ASSERT(uniform->_type == GL_SAMPLER_2D || uniform->_type == GL_SAMPLER_CUBE);
     GP_ASSERT(sampler);
     GP_ASSERT(sampler);
+    GP_ASSERT((sampler->getTexture()->getType() == Texture::TEXTURE_2D && uniform->_type == GL_SAMPLER_2D) || 
+        (sampler->getTexture()->getType() == Texture::TEXTURE_CUBE && uniform->_type == GL_SAMPLER_CUBE));
 
 
     GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index) );
     GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index) );
 
 
@@ -622,13 +624,15 @@ void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 void Effect::setValue(Uniform* uniform, const Texture::Sampler** values, unsigned int count)
 void Effect::setValue(Uniform* uniform, const Texture::Sampler** values, unsigned int count)
 {
 {
     GP_ASSERT(uniform);
     GP_ASSERT(uniform);
-    GP_ASSERT(uniform->_type == GL_SAMPLER_2D);
+    GP_ASSERT(uniform->_type == GL_SAMPLER_2D || uniform->_type == GL_SAMPLER_CUBE);
     GP_ASSERT(values);
     GP_ASSERT(values);
 
 
     // Set samplers as active and load texture unit array
     // Set samplers as active and load texture unit array
     GLint units[32];
     GLint units[32];
     for (unsigned int i = 0; i < count; ++i)
     for (unsigned int i = 0; i < count; ++i)
     {
     {
+        GP_ASSERT((const_cast<Texture::Sampler*>(values[i])->getTexture()->getType() == Texture::TEXTURE_2D && uniform->_type == GL_SAMPLER_2D) || 
+            (const_cast<Texture::Sampler*>(values[i])->getTexture()->getType() == Texture::TEXTURE_CUBE && uniform->_type == GL_SAMPLER_CUBE));
         GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index + i) );
         GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index + i) );
 
 
         // Bind the sampler - this binds the texture and applies sampler state
         // Bind the sampler - this binds the texture and applies sampler state

+ 29 - 15
gameplay/src/FrameBuffer.cpp

@@ -155,13 +155,28 @@ unsigned int FrameBuffer::getMaxRenderTargets()
 
 
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 {
 {
-    GP_ASSERT(index < _maxRenderTargets);
-    GP_ASSERT(_renderTargets);
+    GP_ASSERT(!target || (target->getTexture() && target->getTexture()->getType() == Texture::TEXTURE_2D));
 
 
     // No change
     // No change
     if (_renderTargets[index] == target)
     if (_renderTargets[index] == target)
         return;
         return;
 
 
+    setRenderTarget(target, index, GL_TEXTURE_2D);
+}
+
+void FrameBuffer::setRenderTarget(RenderTarget* target, Texture::CubeFace face, unsigned int index)
+{
+    GP_ASSERT(face >= Texture::POSITIVE_X && face <= Texture::NEGATIVE_Z);
+    GP_ASSERT(!target || (target->getTexture() && target->getTexture()->getType() == Texture::TEXTURE_CUBE));
+
+    setRenderTarget(target, index, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face);
+}
+
+void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index, GLenum textureTarget)
+{
+    GP_ASSERT(index < _maxRenderTargets);
+    GP_ASSERT(_renderTargets);
+
     // Release our reference to the current RenderTarget at this index.
     // Release our reference to the current RenderTarget at this index.
     if (_renderTargets[index])
     if (_renderTargets[index])
     {
     {
@@ -173,8 +188,6 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 
 
     if (target)
     if (target)
     {
     {
-        GP_ASSERT( _renderTargets[index]->getTexture() );
-
         ++_renderTargetCount;
         ++_renderTargetCount;
 
 
         // This FrameBuffer now references the RenderTarget.
         // This FrameBuffer now references the RenderTarget.
@@ -183,7 +196,7 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
         // Now set this target as the color attachment corresponding to index.
         // Now set this target as the color attachment corresponding to index.
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
         GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
         GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
-        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, _renderTargets[index]->getTexture()->getHandle(), 0) );
+        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textureTarget, _renderTargets[index]->getTexture()->getHandle(), 0) );
         GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
         GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
         if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
         if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
         {
         {
@@ -271,22 +284,23 @@ FrameBuffer* FrameBuffer::bind()
 
 
 void FrameBuffer::getScreenshot(Image* image)
 void FrameBuffer::getScreenshot(Image* image)
 {
 {
-	GP_ASSERT(image);
-	GP_ASSERT(image->getFormat() == Image::RGBA);
+    GP_ASSERT( image );
 
 
-	unsigned int width = _currentFrameBuffer->getWidth();
-	unsigned int height = _currentFrameBuffer->getHeight();
+    unsigned int width = _currentFrameBuffer->getWidth();
+    unsigned int height = _currentFrameBuffer->getHeight();
 
 
-	if (image->getWidth() == width && image->getHeight() == height)
-		GL_ASSERT( glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image->getData()) );
+	if (image->getWidth() == width && image->getHeight() == height) {
+		GLenum format = image->getFormat() == Image::RGB ? GL_RGB : GL_RGBA;
+        GL_ASSERT( glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, image->getData()) );
+	}
 }
 }
 
 
-Image* FrameBuffer::createScreenshot()
+Image* FrameBuffer::createScreenshot(Image::Format format)
 {
 {
-	Image* screenshot = Image::create(_currentFrameBuffer->getWidth(), _currentFrameBuffer->getHeight(), Image::RGBA, NULL);
-	getScreenshot(screenshot);
+    Image* screenshot = Image::create(_currentFrameBuffer->getWidth(), _currentFrameBuffer->getHeight(), format, NULL);
+    getScreenshot(screenshot);
 
 
-	return screenshot;
+    return screenshot;
 }
 }
 
 
 FrameBuffer* FrameBuffer::bindDefault()
 FrameBuffer* FrameBuffer::bindDefault()

+ 27 - 16
gameplay/src/FrameBuffer.h

@@ -101,11 +101,20 @@ public:
     /**
     /**
      * Set a RenderTarget on this FrameBuffer's color attachment at the specified index.
      * Set a RenderTarget on this FrameBuffer's color attachment at the specified index.
      *
      *
-     * @param target The RenderTarget to set.
+     * @param target The 2D RenderTarget to set.
      * @param index The index of the color attachment to set.
      * @param index The index of the color attachment to set.
      */
      */
     void setRenderTarget(RenderTarget* target, unsigned int index = 0);
     void setRenderTarget(RenderTarget* target, unsigned int index = 0);
 
 
+    /**
+    * Set a RenderTarget on this FrameBuffer's color attachment at the specified index.
+    *
+    * @param target The Cubemap RenderTarget to set.
+    * @param face The face of the cubemap to target.
+    * @param index The index of the color attachment to set.
+    */
+    void setRenderTarget(RenderTarget* target, Texture::CubeFace face, unsigned int index = 0);
+
     /**
     /**
      * Get the RenderTarget attached to the FrameBuffer's color attachment at the specified index.
      * Get the RenderTarget attached to the FrameBuffer's color attachment at the specified index.
      *
      *
@@ -152,22 +161,22 @@ public:
      */
      */
     FrameBuffer* bind();
     FrameBuffer* bind();
 
 
-	/**
-	 * Records a screenshot of what is stored on the current FrameBuffer.
-	 *
-	 * @return A screenshot of the current framebuffer's content.
-	 */
-	static Image* createScreenshot();
+    /**
+     * Records a screenshot of what is stored on the current FrameBuffer.
+     *
+     * @param format The format the Image should be in.
+     * @return A screenshot of the current framebuffer's content.
+     */
+    static Image* createScreenshot(Image::Format format = Image::RGBA);
 
 
-	/**
-	 * Records a screenshot of what is stored on the current FrameBuffer to an Image.
-	 *
-	 * The Image must be the same size as the FrameBuffer, otherwise the operation will fail.
-	 * The Image must be format RGBA.
-	 *
-	 * @param image The Image to write the current framebuffer's content to.
-	 */
-	static void getScreenshot(Image* image);
+    /**
+     * Records a screenshot of what is stored on the current FrameBuffer to an Image.
+     *
+     * The Image must be the same size as the FrameBuffer, otherwise the operation will fail.
+     *
+     * @param image The Image to write the current framebuffer's content to.
+     */
+    static void getScreenshot(Image* image);
 
 
     /**
     /**
      * Binds the default FrameBuffer for rendering to the display.
      * Binds the default FrameBuffer for rendering to the display.
@@ -200,6 +209,8 @@ private:
      */
      */
     FrameBuffer& operator=(const FrameBuffer&);
     FrameBuffer& operator=(const FrameBuffer&);
 
 
+    void setRenderTarget(RenderTarget* target, unsigned int index, GLenum textureTarget);
+
     static void initialize();
     static void initialize();
 
 
     static void finalize();
     static void finalize();

+ 26 - 26
gameplay/src/Image.cpp

@@ -109,32 +109,32 @@ Image* Image::create(const char* path)
 
 
 Image* Image::create(unsigned int width, unsigned int height, Image::Format format, unsigned char* data)
 Image* Image::create(unsigned int width, unsigned int height, Image::Format format, unsigned char* data)
 {
 {
-	GP_ASSERT(width > 0 && height > 0);
-	GP_ASSERT(format >= RGB && format <= RGBA);
-
-	unsigned int pixelSize = 0;
-	switch(format)
-	{
-	case Image::RGB:
-		pixelSize = 3;
-		break;
-	case Image::RGBA:
-		pixelSize = 4;
-		break;
-	}
-
-	Image* image = new Image();
-
-	unsigned int dataSize = width * height * pixelSize;
-
-	image->_width = width;
-	image->_height = height;
-	image->_format = format;
-	image->_data = new unsigned char[dataSize];
-	if (data)
-		memcpy(image->_data, data, dataSize);
-
-	return image;
+    GP_ASSERT(width > 0 && height > 0);
+    GP_ASSERT(format >= RGB && format <= RGBA);
+
+    unsigned int pixelSize = 0;
+    switch(format)
+    {
+    case Image::RGB:
+        pixelSize = 3;
+        break;
+    case Image::RGBA:
+        pixelSize = 4;
+        break;
+    }
+
+    Image* image = new Image();
+
+    unsigned int dataSize = width * height * pixelSize;
+
+    image->_width = width;
+    image->_height = height;
+    image->_format = format;
+    image->_data = new unsigned char[dataSize];
+    if (data)
+        memcpy(image->_data, data, dataSize);
+
+    return image;
 }
 }
 
 
 Image::Image() : _data(NULL), _format(RGB), _width(0), _height(0)
 Image::Image() : _data(NULL), _format(RGB), _width(0), _height(0)

+ 5 - 5
gameplay/src/Image.h

@@ -33,17 +33,17 @@ public:
      */
      */
     static Image* create(const char* path);
     static Image* create(const char* path);
 
 
-	/**
+    /**
      * Creates an image from the data provided
      * Creates an image from the data provided
      *
      *
      * @param width The width of the image data.
      * @param width The width of the image data.
-	 * @param height The height of the image data.
-	 * @param format The format of the image data.
-	 * @param data The image data. If NULL, the data will be allocated.
+     * @param height The height of the image data.
+     * @param format The format of the image data.
+     * @param data The image data. If NULL, the data will be allocated.
      * @return The newly created image.
      * @return The newly created image.
      * @script{create}
      * @script{create}
      */
      */
-	static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data = NULL);
+    static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data = NULL);
 
 
     /**
     /**
      * Gets the image's raw pixel data.
      * Gets the image's raw pixel data.

+ 6 - 1
gameplay/src/Material.cpp

@@ -464,6 +464,11 @@ void Material::loadRenderState(RenderState* renderState, Properties* properties)
             bool mipmap = ns->getBool("mipmap");
             bool mipmap = ns->getBool("mipmap");
             Texture::Wrap wrapS = parseTextureWrapMode(ns->getString("wrapS"), Texture::REPEAT);
             Texture::Wrap wrapS = parseTextureWrapMode(ns->getString("wrapS"), Texture::REPEAT);
             Texture::Wrap wrapT = parseTextureWrapMode(ns->getString("wrapT"), Texture::REPEAT);
             Texture::Wrap wrapT = parseTextureWrapMode(ns->getString("wrapT"), Texture::REPEAT);
+            Texture::Wrap wrapR = Texture::REPEAT;
+            if(ns->exists("wrapR"))
+            {
+                wrapR = parseTextureWrapMode(ns->getString("wrapR"), Texture::REPEAT);
+            }
             Texture::Filter minFilter = parseTextureFilterMode(ns->getString("minFilter"), mipmap ? Texture::NEAREST_MIPMAP_LINEAR : Texture::LINEAR);
             Texture::Filter minFilter = parseTextureFilterMode(ns->getString("minFilter"), mipmap ? Texture::NEAREST_MIPMAP_LINEAR : Texture::LINEAR);
             Texture::Filter magFilter = parseTextureFilterMode(ns->getString("magFilter"), Texture::LINEAR);
             Texture::Filter magFilter = parseTextureFilterMode(ns->getString("magFilter"), Texture::LINEAR);
 
 
@@ -472,7 +477,7 @@ void Material::loadRenderState(RenderState* renderState, Properties* properties)
             Texture::Sampler* sampler = renderState->getParameter(name)->setValue(path.c_str(), mipmap);
             Texture::Sampler* sampler = renderState->getParameter(name)->setValue(path.c_str(), mipmap);
             if (sampler)
             if (sampler)
             {
             {
-                sampler->setWrapMode(wrapS, wrapT);
+                sampler->setWrapMode(wrapS, wrapT, wrapR);
                 sampler->setFilterMode(minFilter, magFilter);
                 sampler->setFilterMode(minFilter, magFilter);
             }
             }
         }
         }

+ 1 - 1
gameplay/src/PlatformWindows.cpp

@@ -1429,7 +1429,7 @@ std::string Platform::displayFileDialog(size_t mode, const char* title, const ch
         GetSaveFileNameA(&ofn);
         GetSaveFileNameA(&ofn);
     }
     }
 
 
-    filename = szFileName;            
+    filename = szFileName;
         
         
     SetCurrentDirectoryA(currentDir);
     SetCurrentDirectoryA(currentDir);
 
 

+ 1 - 0
gameplay/src/SpriteBatch.cpp

@@ -58,6 +58,7 @@ SpriteBatch* SpriteBatch::create(const char* texturePath, Effect* effect, unsign
 SpriteBatch* SpriteBatch::create(Texture* texture,  Effect* effect, unsigned int initialCapacity)
 SpriteBatch* SpriteBatch::create(Texture* texture,  Effect* effect, unsigned int initialCapacity)
 {
 {
     GP_ASSERT(texture != NULL);
     GP_ASSERT(texture != NULL);
+    GP_ASSERT(texture->getType() == Texture::TEXTURE_2D);
 
 
     bool customEffect = (effect != NULL);
     bool customEffect = (effect != NULL);
     if (!customEffect)
     if (!customEffect)

+ 3 - 0
gameplay/src/Terrain.cpp

@@ -259,7 +259,10 @@ Terrain* Terrain::create(HeightField* heightfield, const Vector3& scale,
     BoundingBox& bounds = terrain->_boundingBox;
     BoundingBox& bounds = terrain->_boundingBox;
 
 
     if (normalMapPath)
     if (normalMapPath)
+    {
         terrain->_normalMap = Texture::Sampler::create(normalMapPath, true);
         terrain->_normalMap = Texture::Sampler::create(normalMapPath, true);
+        GP_ASSERT( terrain->_normalMap->getTexture()->getType() == Texture::TEXTURE_2D );
+    }
 
 
     float halfWidth = (width - 1) * 0.5f;
     float halfWidth = (width - 1) * 0.5f;
     float halfHeight = (height - 1) * 0.5f;
     float halfHeight = (height - 1) * 0.5f;

+ 7 - 0
gameplay/src/TerrainPatch.cpp

@@ -384,6 +384,13 @@ int TerrainPatch::addSampler(const char* path)
     if (!texture)
     if (!texture)
         return -1;
         return -1;
 
 
+    // Textures should only be 2D
+    if (texture->getType() != Texture::TEXTURE_2D)
+    {
+        SAFE_RELEASE(texture);
+        return -1;
+    }
+
     int firstAvailableIndex = -1;
     int firstAvailableIndex = -1;
     for (size_t i = 0, count = _samplers.size(); i < count; ++i)
     for (size_t i = 0, count = _samplers.size(); i < count; ++i)
     {
     {

+ 396 - 114
gameplay/src/Texture.cpp

@@ -48,10 +48,11 @@ namespace gameplay
 {
 {
 
 
 static std::vector<Texture*> __textureCache;
 static std::vector<Texture*> __textureCache;
-static TextureHandle __currentTextureId;
+static TextureHandle __currentTextureId = 0;
+static Texture::Type __currentTextureType = Texture::TEXTURE_2D;
 
 
-Texture::Texture() : _handle(0), _format(UNKNOWN), _width(0), _height(0), _mipmapped(false), _cached(false), _compressed(false),
-    _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _minFilter(Texture::NEAREST_MIPMAP_LINEAR), _magFilter(Texture::LINEAR)
+Texture::Texture() : _handle(0), _format(UNKNOWN), _type((Texture::Type)0), _width(0), _height(0), _mipmapped(false), _cached(false), _compressed(false),
+    _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _wrapR(Texture::REPEAT), _minFilter(Texture::NEAREST_MIPMAP_LINEAR), _magFilter(Texture::LINEAR)
 {
 {
 }
 }
 
 
@@ -76,13 +77,13 @@ Texture::~Texture()
 
 
 Texture* Texture::create(const char* path, bool generateMipmaps)
 Texture* Texture::create(const char* path, bool generateMipmaps)
 {
 {
-    GP_ASSERT(path);
+    GP_ASSERT( path );
 
 
     // Search texture cache first.
     // Search texture cache first.
     for (size_t i = 0, count = __textureCache.size(); i < count; ++i)
     for (size_t i = 0, count = __textureCache.size(); i < count; ++i)
     {
     {
         Texture* t = __textureCache[i];
         Texture* t = __textureCache[i];
-        GP_ASSERT(t);
+        GP_ASSERT( t );
         if (t->_path == path)
         if (t->_path == path)
         {
         {
             // If 'generateMipmaps' is true, call Texture::generateMipamps() to force the
             // If 'generateMipmaps' is true, call Texture::generateMipamps() to force the
@@ -146,7 +147,7 @@ Texture* Texture::create(const char* path, bool generateMipmaps)
 
 
 Texture* Texture::create(Image* image, bool generateMipmaps)
 Texture* Texture::create(Image* image, bool generateMipmaps)
 {
 {
-    GP_ASSERT(image);
+    GP_ASSERT( image );
 
 
     switch (image->getFormat())
     switch (image->getFormat())
     {
     {
@@ -160,28 +161,69 @@ Texture* Texture::create(Image* image, bool generateMipmaps)
     }
     }
 }
 }
 
 
-Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps)
+Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps, Texture::Type type)
 {
 {
-    // Create and load the texture.
+    GP_ASSERT( type == Texture::TEXTURE_2D || type == Texture::TEXTURE_CUBE );
+
+    GLenum target = (GLenum)type;
+
+    // Create the texture.
     GLuint textureId;
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
     GL_ASSERT( glPixelStorei(GL_UNPACK_ALIGNMENT, 1) );
     GL_ASSERT( glPixelStorei(GL_UNPACK_ALIGNMENT, 1) );
 #ifndef OPENGL_ES
 #ifndef OPENGL_ES
     // glGenerateMipmap is new in OpenGL 3.0. For OpenGL 2.0 we must fallback to use glTexParameteri
     // glGenerateMipmap is new in OpenGL 3.0. For OpenGL 2.0 we must fallback to use glTexParameteri
     // with GL_GENERATE_MIPMAP prior to actual texture creation (glTexImage2D)
     // with GL_GENERATE_MIPMAP prior to actual texture creation (glTexImage2D)
-    if ( generateMipmaps && glGenerateMipmap == NULL )
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE) );
+    if ( generateMipmaps && !std::addressof(glGenerateMipmap) )
+        GL_ASSERT( glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE) );
 #endif
 #endif
-    GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
+
+    // Load the texture
+    if (type == Texture::TEXTURE_2D)
+    {
+        // Texture 2D
+        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
+    }
+    else
+    {
+        // Get texture size
+        unsigned int textureSize = width * height;
+        switch (format)
+        {
+            case Texture::RGB:
+                textureSize *= 3;
+                break;
+            case Texture::RGBA:
+                textureSize *= 4;
+                break;
+            case Texture::ALPHA:
+                break;
+            case Texture::UNKNOWN:
+                if (data)
+                {
+                    glDeleteTextures(1, &textureId);
+                    GP_ERROR("Failed to determine texture size because format is UNKNOWN.");
+                    return NULL;
+                }
+                break;
+        }
+        // Texture Cube
+        for (unsigned int i = 0; i < 6; i++)
+        {
+            const unsigned char* texturePtr = (data == NULL) ? NULL : &data[i * textureSize];
+            GL_ASSERT( glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, texturePtr) );
+        }
+    }
 
 
     // Set initial minification filter based on whether or not mipmaping was enabled.
     // Set initial minification filter based on whether or not mipmaping was enabled.
     Filter minFilter = generateMipmaps ? NEAREST_MIPMAP_LINEAR : LINEAR;
     Filter minFilter = generateMipmaps ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
 
 
     Texture* texture = new Texture();
     Texture* texture = new Texture();
     texture->_handle = textureId;
     texture->_handle = textureId;
     texture->_format = format;
     texture->_format = format;
+    texture->_type = type;
     texture->_width = width;
     texture->_width = width;
     texture->_height = height;
     texture->_height = height;
     texture->_minFilter = minFilter;
     texture->_minFilter = minFilter;
@@ -191,16 +233,33 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
     }
     }
 
 
     // Restore the texture id
     // Restore the texture id
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, __currentTextureId) );
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
 
 
     return texture;
     return texture;
 }
 }
 
 
 Texture* Texture::create(TextureHandle handle, int width, int height, Format format)
 Texture* Texture::create(TextureHandle handle, int width, int height, Format format)
 {
 {
-    GP_ASSERT(handle);
+    GP_ASSERT( handle );
 
 
     Texture* texture = new Texture();
     Texture* texture = new Texture();
+    if (glIsTexture(handle))
+    {
+        // There is no real way to query for texture type, but an error will be returned if a cube texture is bound to a 2D texture... so check for that
+        glBindTexture(GL_TEXTURE_CUBE_MAP, handle);
+        if (glGetError() == GL_NO_ERROR)
+        {
+            texture->_type = TEXTURE_CUBE;
+        }
+        else
+        {
+            // For now, it's either or. But if 3D textures and others are added, it might be useful to simply test a bunch of bindings and seeing which one doesn't error out
+            texture->_type = TEXTURE_2D;
+        }
+
+        // Restore the texture id
+        GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+    }
     texture->_handle = handle;
     texture->_handle = handle;
     texture->_format = format;
     texture->_format = format;
     texture->_width = width;
     texture->_width = width;
@@ -209,6 +268,50 @@ Texture* Texture::create(TextureHandle handle, int width, int height, Format for
     return texture;
     return texture;
 }
 }
 
 
+void Texture::setData(const unsigned char* data)
+{
+    // Don't work with any compressed or cached textures
+    GP_ASSERT( data );
+    GP_ASSERT( (!_compressed) );
+    GP_ASSERT( (!_cached) );
+
+    GL_ASSERT( glBindTexture((GLenum)_type, _handle) );
+
+    if (_type == Texture::TEXTURE_2D)
+    {
+        GL_ASSERT( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, data) );
+    }
+    else
+    {
+        // Get texture size
+        unsigned int textureSize = _width * _height;
+        switch (_format)
+        {
+            case Texture::RGB:
+                textureSize *= 3;
+                break;
+            case Texture::RGBA:
+                textureSize *= 4;
+                break;
+            case Texture::ALPHA:
+                break;
+        }
+        // Texture Cube
+        for (unsigned int i = 0; i < 6; i++)
+        {
+            GL_ASSERT( glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, &data[i * textureSize]) );
+        }
+    }
+
+    if (_mipmapped)
+    {
+        generateMipmaps();
+    }
+
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+}
+
 // Computes the size of a PVRTC data chunk for a mipmap level of the given size.
 // Computes the size of a PVRTC data chunk for a mipmap level of the given size.
 static unsigned int computePVRTCDataSize(int width, int height, int bpp)
 static unsigned int computePVRTCDataSize(int width, int height, int bpp)
 {
 {
@@ -263,16 +366,18 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     GLenum format;
     GLenum format;
     GLubyte* data = NULL;
     GLubyte* data = NULL;
     unsigned int mipMapCount;
     unsigned int mipMapCount;
+    unsigned int faceCount;
+    GLenum faces[6] = { GL_TEXTURE_2D };
 
 
     if (version == 0x03525650)
     if (version == 0x03525650)
     {
     {
         // Modern PVR file format.
         // Modern PVR file format.
-        data = readCompressedPVRTC(path, stream.get(), &width, &height, &format, &mipMapCount);
+        data = readCompressedPVRTC(path, stream.get(), &width, &height, &format, &mipMapCount, &faceCount, faces);
     }
     }
     else
     else
     {
     {
         // Legacy PVR file format.
         // Legacy PVR file format.
-        data = readCompressedPVRTCLegacy(path, stream.get(), &width, &height, &format, &mipMapCount);
+        data = readCompressedPVRTCLegacy(path, stream.get(), &width, &height, &format, &mipMapCount, &faceCount, faces);
     }
     }
     if (data == NULL)
     if (data == NULL)
     {
     {
@@ -284,15 +389,17 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     int bpp = (format == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) ? 2 : 4;
     int bpp = (format == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) ? 2 : 4;
 
 
     // Generate our texture.
     // Generate our texture.
+    GLenum target = faceCount > 1 ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
     GLuint textureId;
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
 
 
     Filter minFilter = mipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
     Filter minFilter = mipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
 
 
     Texture* texture = new Texture();
     Texture* texture = new Texture();
     texture->_handle = textureId;
     texture->_handle = textureId;
+    texture->_type = faceCount > 1 ? TEXTURE_CUBE : TEXTURE_2D;
     texture->_width = width;
     texture->_width = width;
     texture->_height = height;
     texture->_height = height;
     texture->_mipmapped = mipMapCount > 1;
     texture->_mipmapped = mipMapCount > 1;
@@ -305,28 +412,36 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     {
     {
         unsigned int dataSize = computePVRTCDataSize(width, height, bpp);
         unsigned int dataSize = computePVRTCDataSize(width, height, bpp);
 
 
-        // Upload data to GL.
-        GL_ASSERT( glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, dataSize, ptr) );
+        for (unsigned int face = 0; face < faceCount; ++face)
+        {
+            // Upload data to GL.
+            GL_ASSERT(glCompressedTexImage2D(faces[face], level, format, width, height, 0, dataSize, &ptr[face * dataSize]));
+        }
 
 
         width = std::max(width >> 1, 1);
         width = std::max(width >> 1, 1);
         height = std::max(height >> 1, 1);
         height = std::max(height >> 1, 1);
-        ptr += dataSize;
+        ptr += dataSize * faceCount;
     }
     }
 
 
     // Free data.
     // Free data.
     SAFE_DELETE_ARRAY(data);
     SAFE_DELETE_ARRAY(data);
 
 
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+
     return texture;
     return texture;
 }
 }
 
 
-GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount)
+GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum* faces)
 {
 {
-    GP_ASSERT(stream);
-    GP_ASSERT(path);
-    GP_ASSERT(width);
-    GP_ASSERT(height);
-    GP_ASSERT(format);
-    GP_ASSERT(mipMapCount);
+    GP_ASSERT( stream );
+    GP_ASSERT( path );
+    GP_ASSERT( width );
+    GP_ASSERT( height );
+    GP_ASSERT( format );
+    GP_ASSERT( mipMapCount );
+    GP_ASSERT( faceCount );
+    GP_ASSERT( faces );
 
 
     struct pvrtc_file_header
     struct pvrtc_file_header
     {
     {
@@ -344,6 +459,13 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
         unsigned int metaDataSize;
         unsigned int metaDataSize;
     };
     };
 
 
+    struct pvrtc_metadata
+    {
+        char fourCC[4];
+        unsigned int key;
+        unsigned int dataSize;
+    };
+
     size_t read;
     size_t read;
 
 
     // Read header data.
     // Read header data.
@@ -390,12 +512,78 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     *width = (GLsizei)header.width;
     *width = (GLsizei)header.width;
     *height = (GLsizei)header.height;
     *height = (GLsizei)header.height;
     *mipMapCount = header.mipMapCount;
     *mipMapCount = header.mipMapCount;
+    *faceCount = std::min(header.faceCount, 6u);
 
 
-    // Skip meta-data.
-    if (stream->seek(header.metaDataSize, SEEK_CUR) == false)
+    if ((*faceCount) > 1)
     {
     {
-        GP_ERROR("Failed to seek past header meta data in PVR file '%s'.", path);
-        return NULL;
+        // Look for cubemap metadata and setup faces
+        unsigned int remainingMetadata = header.metaDataSize;
+        pvrtc_metadata mdHeader;
+        bool foundTextureCubeMeta = false;
+        while (remainingMetadata > 0)
+        {
+            read = stream->read(&mdHeader, sizeof(pvrtc_metadata), 1);
+            if (read != 1)
+            {
+                GP_ERROR("Failed to read PVR metadata header data for file '%s'.", path);
+                return NULL;
+            }
+            remainingMetadata -= sizeof(pvrtc_metadata) + mdHeader.dataSize;
+
+            // Check that it's a known metadata type (specifically, cubemap order), otherwise skip to next metadata
+            if ((mdHeader.fourCC[0] != 'P') ||
+                (mdHeader.fourCC[1] != 'V') ||
+                (mdHeader.fourCC[2] != 'R') ||
+                (mdHeader.fourCC[3] != 3) ||
+                (mdHeader.key != 2) || // Everything except cubemap order (cubemap order key is 2)
+                (mdHeader.dataSize != 6)) // Cubemap order datasize should be 6
+            {
+                if (stream->seek(mdHeader.dataSize, SEEK_CUR) == false)
+                {
+                    GP_ERROR("Failed to seek to next meta data header in PVR file '%s'.", path);
+                    return NULL;
+                }
+                continue;
+            }
+
+            // Get cubemap order
+            foundTextureCubeMeta = true;
+            char faceOrder[6];
+            read = stream->read(faceOrder, 1, sizeof(faceOrder));
+            if (read != sizeof(faceOrder))
+            {
+                GP_ERROR("Failed to read cubemap face order meta data for file '%s'.", path);
+                return NULL;
+            }
+            for (unsigned int face = 0; face < (*faceCount); ++face)
+            {
+                faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (faceOrder[face] <= 'Z' ?
+                    ((faceOrder[face] - 'X') * 2) :
+                    (((faceOrder[face] - 'x') * 2) + 1));
+                if (faces[face] < GL_TEXTURE_CUBE_MAP_POSITIVE_X)
+                {
+                    // Just overwrite this face
+                    faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+                }
+            }
+        }
+        if (!foundTextureCubeMeta)
+        {
+            // Didn't find cubemap metadata. Just assume it's "in order"
+            for (unsigned int face = 0; face < (*faceCount); ++face)
+            {
+                faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+            }
+        }
+    }
+    else
+    {
+        // Skip meta-data.
+        if (stream->seek(header.metaDataSize, SEEK_CUR) == false)
+        {
+            GP_ERROR("Failed to seek past header meta data in PVR file '%s'.", path);
+            return NULL;
+        }
     }
     }
 
 
     // Compute total size of data to be read.
     // Compute total size of data to be read.
@@ -404,7 +592,7 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     size_t dataSize = 0;
     size_t dataSize = 0;
     for (unsigned int level = 0; level < header.mipMapCount; ++level)
     for (unsigned int level = 0; level < header.mipMapCount; ++level)
     {
     {
-        dataSize += computePVRTCDataSize(w, h, bpp);
+        dataSize += computePVRTCDataSize(w, h, bpp) * (*faceCount);
         w = std::max(w>>1, 1);
         w = std::max(w>>1, 1);
         h = std::max(h>>1, 1);
         h = std::max(h>>1, 1);
     }
     }
@@ -422,7 +610,7 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     return data;
     return data;
 }
 }
 
 
-GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount)
+GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum* faces)
 {
 {
     char PVRTCIdentifier[] = "PVR!";
     char PVRTCIdentifier[] = "PVR!";
 
 
@@ -481,13 +669,32 @@ GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GL
     *width = (GLsizei)header.width;
     *width = (GLsizei)header.width;
     *height = (GLsizei)header.height;
     *height = (GLsizei)header.height;
     *mipMapCount = header.mipmapCount + 1; // +1 because mipmapCount does not include the base level
     *mipMapCount = header.mipmapCount + 1; // +1 because mipmapCount does not include the base level
+    *faceCount = 1;
 
 
-    GLubyte* data = new GLubyte[header.dataSize];
-    read = (int)stream->read(data, 1, header.dataSize);
-    if (read != header.dataSize)
+    // Flags (needed legacy documentation on format, pre-PVR Format 3.0)
+    if ((header.formatflags & 0x1000) != 0)
+    {
+        // Texture cube
+        *faceCount = std::min(header.surfaceCount, 6u);
+        for (unsigned int face = 0; face < (*faceCount); ++face)
+        {
+            faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+        }
+    }
+    else if ((header.formatflags & 0x4000) != 0)
+    {
+        // Volume texture
+        GP_ERROR("Failed to load pvrtc file '%s': volume texture is not supported.", path);
+        return NULL;
+    }
+
+    unsigned int totalSize = header.dataSize; // Docs say dataSize is the size of the whole surface, or one face of a texture cube. But this does not appear to be the case with the latest PVRTexTool
+    GLubyte* data = new GLubyte[totalSize];
+    read = (int)stream->read(data, 1, totalSize);
+    if (read != totalSize)
     {
     {
-        GP_ERROR("Failed to load texture data for pvrtc file '%s'.", path);
         SAFE_DELETE_ARRAY(data);
         SAFE_DELETE_ARRAY(data);
+        GP_ERROR("Failed to load texture data for pvrtc file '%s'.", path);
         return NULL;
         return NULL;
     }
     }
 
 
@@ -513,7 +720,7 @@ int Texture::getMaskByteIndex(unsigned int mask)
 
 
 Texture* Texture::createCompressedDDS(const char* path)
 Texture* Texture::createCompressedDDS(const char* path)
 {
 {
-    GP_ASSERT(path);
+    GP_ASSERT( path );
 
 
     // DDS file structures.
     // DDS file structures.
     struct dds_pixel_format
     struct dds_pixel_format
@@ -586,9 +793,32 @@ Texture* Texture::createCompressedDDS(const char* path)
         header.dwMipMapCount = 1;
         header.dwMipMapCount = 1;
     }
     }
 
 
+    // Check type of images. Default is a regular texture
+    unsigned int facecount = 1;
+    GLenum faces[6] = { GL_TEXTURE_2D };
+    GLenum target = GL_TEXTURE_2D;
+    if ((header.dwCaps2 & 0x200/*DDSCAPS2_CUBEMAP*/) != 0)
+    {
+        facecount = 0;
+        for (unsigned int off = 0, flag = 0x400/*DDSCAPS2_CUBEMAP_POSITIVEX*/; off < 6; ++off, flag <<= 1)
+        {
+            if ((header.dwCaps2 & flag) != 0)
+            {
+                faces[facecount++] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + off;
+            }
+        }
+        target = GL_TEXTURE_CUBE_MAP;
+    }
+    else if ((header.dwCaps2 & 0x200000/*DDSCAPS2_VOLUME*/) != 0)
+    {
+        // Volume textures unsupported.
+        GP_ERROR("Failed to create texture from DDS file '%s': volume textures are unsupported.", path);
+        return NULL;
+    }
+
     // Allocate mip level structures.
     // Allocate mip level structures.
-    dds_mip_level* mipLevels = new dds_mip_level[header.dwMipMapCount];
-    memset(mipLevels, 0, sizeof(dds_mip_level) * header.dwMipMapCount);
+    dds_mip_level* mipLevels = new dds_mip_level[header.dwMipMapCount * facecount];
+    memset(mipLevels, 0, sizeof(dds_mip_level) * header.dwMipMapCount * facecount);
 
 
     GLenum format = 0;
     GLenum format = 0;
     GLenum internalFormat = 0;
     GLenum internalFormat = 0;
@@ -639,28 +869,34 @@ Texture* Texture::createCompressedDDS(const char* path)
             return NULL;
             return NULL;
         }
         }
 
 
-        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+        for (unsigned int face = 0; face < facecount; ++face)
         {
         {
-            dds_mip_level& level = mipLevels[i];
+            for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+            {
+                dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
 
 
-            level.width = width;
-            level.height = height;
-            level.size =  std::max(1, (width+3) >> 2) * std::max(1, (height+3) >> 2) * bytesPerBlock;
-            level.data = new GLubyte[level.size];
+                level.width = width;
+                level.height = height;
+                level.size = std::max(1, (width + 3) >> 2) * std::max(1, (height + 3) >> 2) * bytesPerBlock;
+                level.data = new GLubyte[level.size];
 
 
-            if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
-            {
-                GP_ERROR("Failed to load dds compressed texture bytes for texture: %s", path);
+                if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
+                {
+                    GP_ERROR("Failed to load dds compressed texture bytes for texture: %s", path);
+
+                    // Cleanup mip data.
+                    for (unsigned int face = 0; face < facecount; ++face)
+                        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                            SAFE_DELETE_ARRAY(mipLevels[i + face * header.dwMipMapCount].data);
+                    SAFE_DELETE_ARRAY(mipLevels);
+                    return texture;
+                }
 
 
-                // Cleanup mip data.
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
-                    SAFE_DELETE_ARRAY(level.data);
-                SAFE_DELETE_ARRAY(mipLevels);
-                return texture;
+                width = std::max(1, width >> 1);
+                height = std::max(1, height >> 1);
             }
             }
-
-            width  = std::max(1, width >> 1);
-            height = std::max(1, height >> 1);
+            width = header.dwWidth;
+            height = header.dwHeight;
         }
         }
     }
     }
     else if (header.ddspf.dwFlags & 0x40/*DDPF_RGB*/)
     else if (header.ddspf.dwFlags & 0x40/*DDPF_RGB*/)
@@ -710,28 +946,34 @@ Texture* Texture::createCompressedDDS(const char* path)
         }
         }
 
 
         // Read data.
         // Read data.
-        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+        for (unsigned int face = 0; face < facecount; ++face)
         {
         {
-            dds_mip_level& level = mipLevels[i];
+            for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+            {
+                dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
 
 
-            level.width = width;
-            level.height = height;
-            level.size =  width * height * (header.ddspf.dwRGBBitCount >> 3);
-            level.data = new GLubyte[level.size];
+                level.width = width;
+                level.height = height;
+                level.size = width * height * (header.ddspf.dwRGBBitCount >> 3);
+                level.data = new GLubyte[level.size];
 
 
-            if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
-            {
-                GP_ERROR("Failed to load bytes for RGB dds texture: %s", path);
+                if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
+                {
+                    GP_ERROR("Failed to load bytes for RGB dds texture: %s", path);
+
+                    // Cleanup mip data.
+                    for (unsigned int face = 0; face < facecount; ++face)
+                        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                            SAFE_DELETE_ARRAY(mipLevels[i + face * header.dwMipMapCount].data);
+                    SAFE_DELETE_ARRAY(mipLevels);
+                    return texture;
+                }
 
 
-                // Cleanup mip data.
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
-                    SAFE_DELETE_ARRAY(level.data);
-                SAFE_DELETE_ARRAY(mipLevels);
-                return texture;
+                width = std::max(1, width >> 1);
+                height = std::max(1, height >> 1);
             }
             }
-
-            width  = std::max(1, width >> 1);
-            height = std::max(1, height >> 1);
+            width = header.dwWidth;
+            height = header.dwHeight;
         }
         }
 
 
         // Perform color conversion.
         // Perform color conversion.
@@ -746,27 +988,33 @@ Texture* Texture::createCompressedDDS(const char* path)
             GLubyte *pixel, r, g, b, a;
             GLubyte *pixel, r, g, b, a;
             if (format == GL_RGB)
             if (format == GL_RGB)
             {
             {
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                for (unsigned int face = 0; face < facecount; ++face)
                 {
                 {
-                    dds_mip_level& level = mipLevels[i];
-                    for (int j = 0; j < level.size; j += 3)
+                    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
                     {
                     {
-                        pixel = &level.data[j];
-                        r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx];
-                        pixel[0] = r; pixel[1] = g; pixel[2] = b;
+                        dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+                        for (int j = 0; j < level.size; j += 3)
+                        {
+                            pixel = &level.data[j];
+                            r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx];
+                            pixel[0] = r; pixel[1] = g; pixel[2] = b;
+                        }
                     }
                     }
                 }
                 }
             }
             }
             else if (format == GL_RGBA)
             else if (format == GL_RGBA)
             {
             {
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                for (unsigned int face = 0; face < facecount; ++face)
                 {
                 {
-                    dds_mip_level& level = mipLevels[i];
-                    for (int j = 0; j < level.size; j += 4)
+                    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
                     {
                     {
-                        pixel = &level.data[j];
-                        r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx]; a = pixel[aidx];
-                        pixel[0] = r; pixel[1] = g; pixel[2] = b; pixel[3] = a;
+                        dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+                        for (int j = 0; j < level.size; j += 4)
+                        {
+                            pixel = &level.data[j];
+                            r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx]; a = pixel[aidx];
+                            pixel[0] = r; pixel[1] = g; pixel[2] = b; pixel[3] = a;
+                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -786,14 +1034,15 @@ Texture* Texture::createCompressedDDS(const char* path)
     // Generate GL texture.
     // Generate GL texture.
     GLuint textureId;
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
 
 
     Filter minFilter = header.dwMipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
     Filter minFilter = header.dwMipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter ) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter ) );
 
 
     // Create gameplay texture.
     // Create gameplay texture.
     texture = new Texture();
     texture = new Texture();
     texture->_handle = textureId;
     texture->_handle = textureId;
+    texture->_type = (Type)target;
     texture->_width = header.dwWidth;
     texture->_width = header.dwWidth;
     texture->_height = header.dwHeight;
     texture->_height = header.dwHeight;
     texture->_compressed = compressed;
     texture->_compressed = compressed;
@@ -801,25 +1050,32 @@ Texture* Texture::createCompressedDDS(const char* path)
     texture->_minFilter = minFilter;
     texture->_minFilter = minFilter;
 
 
     // Load texture data.
     // Load texture data.
-    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+    for (unsigned int face = 0; face < facecount; ++face)
     {
     {
-        dds_mip_level& level = mipLevels[i];
-        if (compressed)
-        {
-            GL_ASSERT( glCompressedTexImage2D(GL_TEXTURE_2D, i, format, level.width, level.height, 0, level.size, level.data) );
-        }
-        else
+        GLenum texImageTarget = faces[face];
+        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
         {
         {
-            GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, i, internalFormat, level.width, level.height, 0, format, GL_UNSIGNED_BYTE, level.data) );
-        }
+            dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+            if (compressed)
+            {
+                GL_ASSERT(glCompressedTexImage2D(texImageTarget, i, format, level.width, level.height, 0, level.size, level.data));
+            }
+            else
+            {
+                GL_ASSERT(glTexImage2D(texImageTarget, i, internalFormat, level.width, level.height, 0, format, GL_UNSIGNED_BYTE, level.data));
+            }
 
 
-        // Clean up the texture data.
-        SAFE_DELETE_ARRAY(level.data);
+            // Clean up the texture data.
+            SAFE_DELETE_ARRAY(level.data);
+        }
     }
     }
 
 
     // Clean up mip levels structure.
     // Clean up mip levels structure.
     SAFE_DELETE_ARRAY(mipLevels);
     SAFE_DELETE_ARRAY(mipLevels);
 
 
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+
     return texture;
     return texture;
 }
 }
 
 
@@ -828,6 +1084,11 @@ Texture::Format Texture::getFormat() const
     return _format;
     return _format;
 }
 }
 
 
+Texture::Type Texture::getType() const
+{
+    return _type;
+}
+
 const char* Texture::getPath() const
 const char* Texture::getPath() const
 {
 {
     return _path.c_str();
     return _path.c_str();
@@ -852,12 +1113,16 @@ void Texture::generateMipmaps()
 {
 {
     if (!_mipmapped)
     if (!_mipmapped)
     {
     {
-        GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _handle) );
+        GLenum target = (GLenum)_type;
+        GL_ASSERT( glBindTexture(target, _handle) );
         GL_ASSERT( glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) );
         GL_ASSERT( glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) );
-        if (std::addressof(glGenerateMipmap))
-            GL_ASSERT( glGenerateMipmap(GL_TEXTURE_2D) );
+        if( std::addressof(glGenerateMipmap) )
+            GL_ASSERT( glGenerateMipmap(target) );
 
 
         _mipmapped = true;
         _mipmapped = true;
+
+        // Restore the texture id
+        GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
     }
     }
 }
 }
 
 
@@ -872,9 +1137,9 @@ bool Texture::isCompressed() const
 }
 }
 
 
 Texture::Sampler::Sampler(Texture* texture)
 Texture::Sampler::Sampler(Texture* texture)
-    : _texture(texture), _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT)
+    : _texture(texture), _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _wrapR(Texture::REPEAT)
 {
 {
-    GP_ASSERT(texture);
+    GP_ASSERT( texture );
     _minFilter = texture->_minFilter;
     _minFilter = texture->_minFilter;
     _magFilter = texture->_magFilter;
     _magFilter = texture->_magFilter;
 }
 }
@@ -886,7 +1151,8 @@ Texture::Sampler::~Sampler()
 
 
 Texture::Sampler* Texture::Sampler::create(Texture* texture)
 Texture::Sampler* Texture::Sampler::create(Texture* texture)
 {
 {
-    GP_ASSERT(texture);
+    GP_ASSERT( texture );
+    GP_ASSERT( texture->_type == Texture::TEXTURE_2D || texture->_type == Texture::TEXTURE_CUBE );
     texture->addRef();
     texture->addRef();
     return new Sampler(texture);
     return new Sampler(texture);
 }
 }
@@ -897,10 +1163,11 @@ Texture::Sampler* Texture::Sampler::create(const char* path, bool generateMipmap
     return texture ? new Sampler(texture) : NULL;
     return texture ? new Sampler(texture) : NULL;
 }
 }
 
 
-void Texture::Sampler::setWrapMode(Wrap wrapS, Wrap wrapT)
+void Texture::Sampler::setWrapMode(Wrap wrapS, Wrap wrapT, Wrap wrapR)
 {
 {
     _wrapS = wrapS;
     _wrapS = wrapS;
     _wrapT = wrapT;
     _wrapT = wrapT;
+    _wrapR = wrapR;
 }
 }
 
 
 void Texture::Sampler::setFilterMode(Filter minificationFilter, Filter magnificationFilter)
 void Texture::Sampler::setFilterMode(Filter minificationFilter, Filter magnificationFilter)
@@ -916,33 +1183,48 @@ Texture* Texture::Sampler::getTexture() const
 
 
 void Texture::Sampler::bind()
 void Texture::Sampler::bind()
 {
 {
-    GP_ASSERT(_texture);
+    GP_ASSERT( _texture );
 
 
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _texture->_handle) );
+    GLenum target = (GLenum)_texture->_type;
+    if (__currentTextureId != _texture->_handle)
+    {
+        GL_ASSERT( glBindTexture(target, _texture->_handle) );
+        __currentTextureId = _texture->_handle;
+        __currentTextureType = _texture->_type;
+    }
 
 
     if (_texture->_minFilter != _minFilter)
     if (_texture->_minFilter != _minFilter)
     {
     {
         _texture->_minFilter = _minFilter;
         _texture->_minFilter = _minFilter;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)_minFilter) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, (GLenum)_minFilter) );
     }
     }
 
 
     if (_texture->_magFilter != _magFilter)
     if (_texture->_magFilter != _magFilter)
     {
     {
         _texture->_magFilter = _magFilter;
         _texture->_magFilter = _magFilter;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)_magFilter) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MAG_FILTER, (GLenum)_magFilter) );
     }
     }
 
 
     if (_texture->_wrapS != _wrapS)
     if (_texture->_wrapS != _wrapS)
     {
     {
         _texture->_wrapS = _wrapS;
         _texture->_wrapS = _wrapS;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)_wrapS) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_S, (GLenum)_wrapS) );
     }
     }
 
 
     if (_texture->_wrapT != _wrapT)
     if (_texture->_wrapT != _wrapT)
     {
     {
         _texture->_wrapT = _wrapT;
         _texture->_wrapT = _wrapT;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)_wrapT) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_T, (GLenum)_wrapT) );
     }
     }
+
+#if defined(GL_TEXTURE_WRAP_R) // OpenGL ES 3.x and up, OpenGL 1.2 and up
+    if (_texture->_wrapR != _wrapR)
+    {
+        _texture->_wrapR = _wrapR;
+        if (target == GL_TEXTURE_CUBE_MAP) // We don't want to run this on something that we know will fail
+            GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_R, (GLenum)_wrapR) );
+    }
+#endif
 }
 }
 
 
 }
 }

+ 52 - 7
gameplay/src/Texture.h

@@ -50,6 +50,28 @@ public:
         REPEAT = GL_REPEAT,
         REPEAT = GL_REPEAT,
         CLAMP = GL_CLAMP_TO_EDGE
         CLAMP = GL_CLAMP_TO_EDGE
     };
     };
+
+    /**
+     * Defines the type of Texture in use.
+     */
+    enum Type
+    {
+        TEXTURE_2D = GL_TEXTURE_2D,
+        TEXTURE_CUBE = GL_TEXTURE_CUBE_MAP
+    };
+
+    /**
+     * Defines a face of a Texture of Type: cube.
+     */
+    enum CubeFace
+    {
+        POSITIVE_X,
+        NEGATIVE_X,
+        POSITIVE_Y,
+        NEGATIVE_Y,
+        POSITIVE_Z,
+        NEGATIVE_Z
+    };
     
     
     /**
     /**
      * Defines a texture sampler.
      * Defines a texture sampler.
@@ -96,8 +118,9 @@ public:
          *
          *
          * @param wrapS The horizontal wrap mode.
          * @param wrapS The horizontal wrap mode.
          * @param wrapT The vertical wrap mode.
          * @param wrapT The vertical wrap mode.
+         * @param wrapR The depth wrap mode.
          */
          */
-        void setWrapMode(Wrap wrapS, Wrap wrapT);
+        void setWrapMode(Wrap wrapS, Wrap wrapT, Wrap wrapR = REPEAT);
 
 
         /**
         /**
          * Sets the texture filter modes for this sampler.
          * Sets the texture filter modes for this sampler.
@@ -134,6 +157,7 @@ public:
         Texture* _texture;
         Texture* _texture;
         Wrap _wrapS;
         Wrap _wrapS;
         Wrap _wrapT;
         Wrap _wrapT;
+        Wrap _wrapR;
         Filter _minFilter;
         Filter _minFilter;
         Filter _magFilter;
         Filter _magFilter;
     };
     };
@@ -169,15 +193,18 @@ public:
      * The data in the texture is expected to be tightly packed (no padding at the end of rows).
      * The data in the texture is expected to be tightly packed (no padding at the end of rows).
      *
      *
      * @param format Format of the texture data.
      * @param format Format of the texture data.
-     * @param width Width of the texture data.
-     * @param height Height of the texture data.
-     * @param data Raw texture data (expected to be tightly packed).
+     * @param width Width of the texture data. If type is TEX_CUBE, then this is the cube face width.
+     * @param height Height of the texture data. If type is TEX_CUBE, then this is the cube face height.
+     * @param data Raw texture data (expected to be tightly packed). If the type parameter is set 
+     *   to TEXTURE_CUBE, then data is expected to be each face stored back contiguously within the
+     *   array.
      * @param generateMipmaps True to generate a full mipmap chain, false otherwise.
      * @param generateMipmaps True to generate a full mipmap chain, false otherwise.
+     * @param type What type of Texture should be created.
      *
      *
      * @return The new texture.
      * @return The new texture.
      * @script{create}
      * @script{create}
      */
      */
-    static Texture* create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps = false);
+    static Texture* create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps = false, Type type = TEXTURE_2D);
 
 
     /**
     /**
      * Creates a texture object to wrap the specified pre-created native texture handle.
      * Creates a texture object to wrap the specified pre-created native texture handle.
@@ -199,6 +226,15 @@ public:
      */
      */
     static Texture* create(TextureHandle handle, int width, int height, Format format = UNKNOWN);
     static Texture* create(TextureHandle handle, int width, int height, Format format = UNKNOWN);
 
 
+    /**
+     * Set texture data to replace current texture image.
+     * 
+     * @param data Raw texture data (expected to be tightly packed). If the type parameter is set 
+     *   to TEXTURE_CUBE, then data is expected to be each face stored back contiguously within the
+     *   array.
+     */
+    void setData(const unsigned char* data);
+
     /**
     /**
      * Returns the path that the texture was originally loaded from (if applicable).
      * Returns the path that the texture was originally loaded from (if applicable).
      *
      *
@@ -213,6 +249,13 @@ public:
      */
      */
     Format getFormat() const;
     Format getFormat() const;
 
 
+    /**
+     * Gets the texture type.
+     *
+     * @return The texture type.
+     */
+    Type getType() const;
+
     /**
     /**
      * Gets the texture width.
      * Gets the texture width.
      *
      *
@@ -277,15 +320,16 @@ private:
 
 
     static Texture* createCompressedDDS(const char* path);
     static Texture* createCompressedDDS(const char* path);
 
 
-    static GLubyte* readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
+    static GLubyte* readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum faces[6]);
 
 
-    static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
+    static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum faces[6]);
 
 
     static int getMaskByteIndex(unsigned int mask);
     static int getMaskByteIndex(unsigned int mask);
 
 
     std::string _path;
     std::string _path;
     TextureHandle _handle;
     TextureHandle _handle;
     Format _format;
     Format _format;
+    Type _type;
     unsigned int _width;
     unsigned int _width;
     unsigned int _height;
     unsigned int _height;
     bool _mipmapped;
     bool _mipmapped;
@@ -293,6 +337,7 @@ private:
     bool _compressed;
     bool _compressed;
     Wrap _wrapS;
     Wrap _wrapS;
     Wrap _wrapT;
     Wrap _wrapT;
+    Wrap _wrapR;
     Filter _minFilter;
     Filter _minFilter;
     Filter _magFilter;
     Filter _magFilter;
 };
 };

+ 116 - 32
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -5,6 +5,8 @@
 #include "FrameBuffer.h"
 #include "FrameBuffer.h"
 #include "Game.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Ref.h"
+#include "lua_ImageFormat.h"
+#include "lua_TextureCubeFace.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -577,23 +579,23 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
-                if (!param1Valid)
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
                 {
                 {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'RenderTarget'.");
-                    lua_error(state);
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1);
+                    
+                    return 0;
                 }
                 }
-
-                FrameBuffer* instance = getInstance(state);
-                instance->setRenderTarget(param1);
-                
-                return 0;
-            }
+            } while (0);
 
 
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -601,27 +603,81 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
         }
         }
         case 3:
         case 3:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
-                if (!param1Valid)
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER)
                 {
                 {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'RenderTarget'.");
-                    lua_error(state);
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2);
+                    
+                    return 0;
                 }
                 }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
 
 
-                // Get parameter 2 off the stack.
-                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+                    // Get parameter 2 off the stack.
+                    Texture::CubeFace param2 = (Texture::CubeFace)lua_enumFromString_TextureCubeFace(luaL_checkstring(state, 3));
 
 
-                FrameBuffer* instance = getInstance(state);
-                instance->setRenderTarget(param1, param2);
-                
-                return 0;
-            }
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 4:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL) &&
+                    lua_type(state, 4) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    Texture::CubeFace param2 = (Texture::CubeFace)lua_enumFromString_TextureCubeFace(luaL_checkstring(state, 3));
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2, param3);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -629,7 +685,7 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
         }
         }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2, 3 or 4).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -789,9 +845,37 @@ int lua_FrameBuffer_static_createScreenshot(lua_State* state)
             return 1;
             return 1;
             break;
             break;
         }
         }
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Image::Format param1 = (Image::Format)lua_enumFromString_ImageFormat(luaL_checkstring(state, 1));
+
+                void* returnPtr = (void*)FrameBuffer::createScreenshot(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Image");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FrameBuffer_static_createScreenshot - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_pushstring(state, "Invalid number of parameters (expected 0 or 1).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 24 - 0
gameplay/src/lua/lua_Global.cpp

@@ -861,6 +861,18 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerConstantString("PASSWORD", "PASSWORD", scopePath);
         gameplay::ScriptUtil::registerConstantString("PASSWORD", "PASSWORD", scopePath);
     }
     }
 
 
+    // Register enumeration Texture::CubeFace.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("Texture");
+        gameplay::ScriptUtil::registerConstantString("POSITIVE_X", "POSITIVE_X", scopePath);
+        gameplay::ScriptUtil::registerConstantString("NEGATIVE_X", "NEGATIVE_X", scopePath);
+        gameplay::ScriptUtil::registerConstantString("POSITIVE_Y", "POSITIVE_Y", scopePath);
+        gameplay::ScriptUtil::registerConstantString("NEGATIVE_Y", "NEGATIVE_Y", scopePath);
+        gameplay::ScriptUtil::registerConstantString("POSITIVE_Z", "POSITIVE_Z", scopePath);
+        gameplay::ScriptUtil::registerConstantString("NEGATIVE_Z", "NEGATIVE_Z", scopePath);
+    }
+
     // Register enumeration Texture::Filter.
     // Register enumeration Texture::Filter.
     {
     {
         std::vector<std::string> scopePath;
         std::vector<std::string> scopePath;
@@ -883,6 +895,14 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerConstantString("ALPHA", "ALPHA", scopePath);
         gameplay::ScriptUtil::registerConstantString("ALPHA", "ALPHA", scopePath);
     }
     }
 
 
+    // Register enumeration Texture::Type.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("Texture");
+        gameplay::ScriptUtil::registerConstantString("TEXTURE_2D", "TEXTURE_2D", scopePath);
+        gameplay::ScriptUtil::registerConstantString("TEXTURE_CUBE", "TEXTURE_CUBE", scopePath);
+    }
+
     // Register enumeration Texture::Wrap.
     // Register enumeration Texture::Wrap.
     {
     {
         std::vector<std::string> scopePath;
         std::vector<std::string> scopePath;
@@ -1057,10 +1077,14 @@ const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value)
         return lua_stringFromEnum_TerrainFlags((Terrain::Flags)value);
         return lua_stringFromEnum_TerrainFlags((Terrain::Flags)value);
     if (enumname == "TextBox::InputMode")
     if (enumname == "TextBox::InputMode")
         return lua_stringFromEnum_TextBoxInputMode((TextBox::InputMode)value);
         return lua_stringFromEnum_TextBoxInputMode((TextBox::InputMode)value);
+    if (enumname == "Texture::CubeFace")
+        return lua_stringFromEnum_TextureCubeFace((Texture::CubeFace)value);
     if (enumname == "Texture::Filter")
     if (enumname == "Texture::Filter")
         return lua_stringFromEnum_TextureFilter((Texture::Filter)value);
         return lua_stringFromEnum_TextureFilter((Texture::Filter)value);
     if (enumname == "Texture::Format")
     if (enumname == "Texture::Format")
         return lua_stringFromEnum_TextureFormat((Texture::Format)value);
         return lua_stringFromEnum_TextureFormat((Texture::Format)value);
+    if (enumname == "Texture::Type")
+        return lua_stringFromEnum_TextureType((Texture::Type)value);
     if (enumname == "Texture::Wrap")
     if (enumname == "Texture::Wrap")
         return lua_stringFromEnum_TextureWrap((Texture::Wrap)value);
         return lua_stringFromEnum_TextureWrap((Texture::Wrap)value);
     if (enumname == "Touch::TouchEvent")
     if (enumname == "Touch::TouchEvent")

+ 2 - 0
gameplay/src/lua/lua_Global.h

@@ -46,8 +46,10 @@
 #include "lua_RenderStateStencilOperation.h"
 #include "lua_RenderStateStencilOperation.h"
 #include "lua_TerrainFlags.h"
 #include "lua_TerrainFlags.h"
 #include "lua_TextBoxInputMode.h"
 #include "lua_TextBoxInputMode.h"
+#include "lua_TextureCubeFace.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFormat.h"
 #include "lua_TextureFormat.h"
+#include "lua_TextureType.h"
 #include "lua_TextureWrap.h"
 #include "lua_TextureWrap.h"
 #include "lua_TouchTouchEvent.h"
 #include "lua_TouchTouchEvent.h"
 #include "lua_VertexFormatUsage.h"
 #include "lua_VertexFormatUsage.h"

+ 126 - 1
gameplay/src/lua/lua_Texture.cpp

@@ -9,6 +9,7 @@
 #include "Texture.h"
 #include "Texture.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFormat.h"
 #include "lua_TextureFormat.h"
+#include "lua_TextureType.h"
 #include "lua_TextureWrap.h"
 #include "lua_TextureWrap.h"
 
 
 namespace gameplay
 namespace gameplay
@@ -25,10 +26,12 @@ void luaRegister_Texture()
         {"getHeight", lua_Texture_getHeight},
         {"getHeight", lua_Texture_getHeight},
         {"getPath", lua_Texture_getPath},
         {"getPath", lua_Texture_getPath},
         {"getRefCount", lua_Texture_getRefCount},
         {"getRefCount", lua_Texture_getRefCount},
+        {"getType", lua_Texture_getType},
         {"getWidth", lua_Texture_getWidth},
         {"getWidth", lua_Texture_getWidth},
         {"isCompressed", lua_Texture_isCompressed},
         {"isCompressed", lua_Texture_isCompressed},
         {"isMipmapped", lua_Texture_isMipmapped},
         {"isMipmapped", lua_Texture_isMipmapped},
         {"release", lua_Texture_release},
         {"release", lua_Texture_release},
+        {"setData", lua_Texture_setData},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
     const luaL_Reg lua_statics[] = 
     const luaL_Reg lua_statics[] = 
@@ -334,6 +337,41 @@ int lua_Texture_getRefCount(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Texture_getType(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Texture* instance = getInstance(state);
+                Texture::Type result = instance->getType();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_TextureType(result));
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Texture_getType - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Texture_getWidth(lua_State* state)
 int lua_Texture_getWidth(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -471,6 +509,42 @@ int lua_Texture_release(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Texture_setData(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                gameplay::ScriptUtil::LuaArray<unsigned char> param1 = gameplay::ScriptUtil::getUnsignedCharPointer(2);
+
+                Texture* instance = getInstance(state);
+                instance->setData(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Texture_setData - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Texture_static_create(lua_State* state)
 int lua_Texture_static_create(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -777,9 +851,60 @@ int lua_Texture_static_create(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 6:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                    lua_type(state, 2) == LUA_TNUMBER &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA) &&
+                    lua_type(state, 5) == LUA_TBOOLEAN &&
+                    (lua_type(state, 6) == LUA_TSTRING || lua_type(state, 6) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Texture::Format param1 = (Texture::Format)lua_enumFromString_TextureFormat(luaL_checkstring(state, 1));
+
+                    // Get parameter 2 off the stack.
+                    unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    // Get parameter 4 off the stack.
+                    gameplay::ScriptUtil::LuaArray<unsigned char> param4 = gameplay::ScriptUtil::getUnsignedCharPointer(4);
+
+                    // Get parameter 5 off the stack.
+                    bool param5 = gameplay::ScriptUtil::luaCheckBool(state, 5);
+
+                    // Get parameter 6 off the stack.
+                    Texture::Type param6 = (Texture::Type)lua_enumFromString_TextureType(luaL_checkstring(state, 6));
+
+                    void* returnPtr = (void*)Texture::create(param1, param2, param3, param4, param5, param6);
+                    if (returnPtr)
+                    {
+                        gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Texture");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Texture_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 1, 2, 3, 4 or 5).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1, 2, 3, 4, 5 or 6).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 2 - 0
gameplay/src/lua/lua_Texture.h

@@ -13,10 +13,12 @@ int lua_Texture_getHandle(lua_State* state);
 int lua_Texture_getHeight(lua_State* state);
 int lua_Texture_getHeight(lua_State* state);
 int lua_Texture_getPath(lua_State* state);
 int lua_Texture_getPath(lua_State* state);
 int lua_Texture_getRefCount(lua_State* state);
 int lua_Texture_getRefCount(lua_State* state);
+int lua_Texture_getType(lua_State* state);
 int lua_Texture_getWidth(lua_State* state);
 int lua_Texture_getWidth(lua_State* state);
 int lua_Texture_isCompressed(lua_State* state);
 int lua_Texture_isCompressed(lua_State* state);
 int lua_Texture_isMipmapped(lua_State* state);
 int lua_Texture_isMipmapped(lua_State* state);
 int lua_Texture_release(lua_State* state);
 int lua_Texture_release(lua_State* state);
+int lua_Texture_setData(lua_State* state);
 int lua_Texture_static_create(lua_State* state);
 int lua_Texture_static_create(lua_State* state);
 
 
 void luaRegister_Texture();
 void luaRegister_Texture();

+ 51 - 0
gameplay/src/lua/lua_TextureCubeFace.cpp

@@ -0,0 +1,51 @@
+#include "Base.h"
+#include "lua_TextureCubeFace.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_TextureCubeFace_POSITIVE_X = "POSITIVE_X";
+static const char* luaEnumString_TextureCubeFace_NEGATIVE_X = "NEGATIVE_X";
+static const char* luaEnumString_TextureCubeFace_POSITIVE_Y = "POSITIVE_Y";
+static const char* luaEnumString_TextureCubeFace_NEGATIVE_Y = "NEGATIVE_Y";
+static const char* luaEnumString_TextureCubeFace_POSITIVE_Z = "POSITIVE_Z";
+static const char* luaEnumString_TextureCubeFace_NEGATIVE_Z = "NEGATIVE_Z";
+
+Texture::CubeFace lua_enumFromString_TextureCubeFace(const char* s)
+{
+    if (strcmp(s, luaEnumString_TextureCubeFace_POSITIVE_X) == 0)
+        return Texture::POSITIVE_X;
+    if (strcmp(s, luaEnumString_TextureCubeFace_NEGATIVE_X) == 0)
+        return Texture::NEGATIVE_X;
+    if (strcmp(s, luaEnumString_TextureCubeFace_POSITIVE_Y) == 0)
+        return Texture::POSITIVE_Y;
+    if (strcmp(s, luaEnumString_TextureCubeFace_NEGATIVE_Y) == 0)
+        return Texture::NEGATIVE_Y;
+    if (strcmp(s, luaEnumString_TextureCubeFace_POSITIVE_Z) == 0)
+        return Texture::POSITIVE_Z;
+    if (strcmp(s, luaEnumString_TextureCubeFace_NEGATIVE_Z) == 0)
+        return Texture::NEGATIVE_Z;
+    return Texture::POSITIVE_X;
+}
+
+const char* lua_stringFromEnum_TextureCubeFace(Texture::CubeFace e)
+{
+    if (e == Texture::POSITIVE_X)
+        return luaEnumString_TextureCubeFace_POSITIVE_X;
+    if (e == Texture::NEGATIVE_X)
+        return luaEnumString_TextureCubeFace_NEGATIVE_X;
+    if (e == Texture::POSITIVE_Y)
+        return luaEnumString_TextureCubeFace_POSITIVE_Y;
+    if (e == Texture::NEGATIVE_Y)
+        return luaEnumString_TextureCubeFace_NEGATIVE_Y;
+    if (e == Texture::POSITIVE_Z)
+        return luaEnumString_TextureCubeFace_POSITIVE_Z;
+    if (e == Texture::NEGATIVE_Z)
+        return luaEnumString_TextureCubeFace_NEGATIVE_Z;
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_TextureCubeFace.h

@@ -0,0 +1,15 @@
+#ifndef LUA_TEXTURECUBEFACE_H_
+#define LUA_TEXTURECUBEFACE_H_
+
+#include "Texture.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for Texture::CubeFace.
+Texture::CubeFace lua_enumFromString_TextureCubeFace(const char* s);
+const char* lua_stringFromEnum_TextureCubeFace(Texture::CubeFace e);
+
+}
+
+#endif

+ 28 - 1
gameplay/src/lua/lua_TextureSampler.cpp

@@ -9,6 +9,7 @@
 #include "Texture.h"
 #include "Texture.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFilter.h"
 #include "lua_TextureFormat.h"
 #include "lua_TextureFormat.h"
+#include "lua_TextureType.h"
 #include "lua_TextureWrap.h"
 #include "lua_TextureWrap.h"
 
 
 namespace gameplay
 namespace gameplay
@@ -328,9 +329,35 @@ int lua_TextureSampler_setWrapMode(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL) &&
+                (lua_type(state, 4) == LUA_TSTRING || lua_type(state, 4) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Texture::Wrap param1 = (Texture::Wrap)lua_enumFromString_TextureWrap(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                Texture::Wrap param2 = (Texture::Wrap)lua_enumFromString_TextureWrap(luaL_checkstring(state, 3));
+
+                // Get parameter 3 off the stack.
+                Texture::Wrap param3 = (Texture::Wrap)lua_enumFromString_TextureWrap(luaL_checkstring(state, 4));
+
+                Texture::Sampler* instance = getInstance(state);
+                instance->setWrapMode(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_TextureSampler_setWrapMode - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_pushstring(state, "Invalid number of parameters (expected 3 or 4).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 31 - 0
gameplay/src/lua/lua_TextureType.cpp

@@ -0,0 +1,31 @@
+#include "Base.h"
+#include "lua_TextureType.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_TextureType_TEXTURE_2D = "TEXTURE_2D";
+static const char* luaEnumString_TextureType_TEXTURE_CUBE = "TEXTURE_CUBE";
+
+Texture::Type lua_enumFromString_TextureType(const char* s)
+{
+    if (strcmp(s, luaEnumString_TextureType_TEXTURE_2D) == 0)
+        return Texture::TEXTURE_2D;
+    if (strcmp(s, luaEnumString_TextureType_TEXTURE_CUBE) == 0)
+        return Texture::TEXTURE_CUBE;
+    return Texture::TEXTURE_2D;
+}
+
+const char* lua_stringFromEnum_TextureType(Texture::Type e)
+{
+    if (e == Texture::TEXTURE_2D)
+        return luaEnumString_TextureType_TEXTURE_2D;
+    if (e == Texture::TEXTURE_CUBE)
+        return luaEnumString_TextureType_TEXTURE_CUBE;
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_TextureType.h

@@ -0,0 +1,15 @@
+#ifndef LUA_TEXTURETYPE_H_
+#define LUA_TEXTURETYPE_H_
+
+#include "Texture.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for Texture::Type.
+Texture::Type lua_enumFromString_TextureType(const char* s);
+const char* lua_stringFromEnum_TextureType(Texture::Type e);
+
+}
+
+#endif