Browse Source

Merge pull request #1195 from seanpaultaylor/next

Next
Sean Taylor 12 years ago
parent
commit
0e07c7d9d0
55 changed files with 2318 additions and 283 deletions
  1. 40 42
      gameplay/android/java/src/org/gameplay3d/GamePlayActivity.java
  2. 39 53
      gameplay/android/java/src/org/gameplay3d/GooglePlayClientHelper.java
  3. 3 4
      gameplay/android/java/src/org/gameplay3d/GooglePlaySocial.java
  4. 0 12
      gameplay/android/java/src/org/gameplay3d/lib/TestClass.java
  5. 17 2
      gameplay/gameplay.vcxproj
  6. 51 6
      gameplay/gameplay.vcxproj.filters
  7. 3 2
      gameplay/src/Form.cpp
  8. 1 1
      gameplay/src/Form.h
  9. 58 38
      gameplay/src/Model.cpp
  10. 44 5
      gameplay/src/Model.h
  11. 27 1
      gameplay/src/Node.cpp
  12. 42 17
      gameplay/src/Node.h
  13. 3 4
      gameplay/src/ParticleEmitter.cpp
  14. 1 1
      gameplay/src/ParticleEmitter.h
  15. 26 0
      gameplay/src/SceneRenderer.cpp
  16. 62 0
      gameplay/src/SceneRenderer.h
  17. 73 0
      gameplay/src/SceneRendererForward.cpp
  18. 49 0
      gameplay/src/SceneRendererForward.h
  19. 2 2
      gameplay/src/SocialController.cpp
  20. 2 1
      gameplay/src/Terrain.cpp
  21. 2 1
      gameplay/src/Terrain.h
  22. 5 5
      gameplay/src/TerrainPatch.cpp
  23. 1 1
      gameplay/src/TerrainPatch.h
  24. 48 0
      gameplay/src/VisibleSet.h
  25. 89 0
      gameplay/src/VisibleSetDefault.cpp
  26. 73 0
      gameplay/src/VisibleSetDefault.h
  27. 5 1
      gameplay/src/gameplay.h
  28. 6 3
      gameplay/src/lua/lua_Form.cpp
  29. 2 0
      gameplay/src/lua/lua_Global.cpp
  30. 109 0
      gameplay/src/lua/lua_Joint.cpp
  31. 3 0
      gameplay/src/lua/lua_Joint.h
  32. 158 6
      gameplay/src/lua/lua_Model.cpp
  33. 4 0
      gameplay/src/lua/lua_Model.h
  34. 109 0
      gameplay/src/lua/lua_Node.cpp
  35. 3 0
      gameplay/src/lua/lua_Node.h
  36. 6 3
      gameplay/src/lua/lua_ParticleEmitter.cpp
  37. 186 0
      gameplay/src/lua/lua_SceneRenderer.cpp
  38. 17 0
      gameplay/src/lua/lua_SceneRenderer.h
  39. 194 0
      gameplay/src/lua/lua_SceneRendererForward.cpp
  40. 17 0
      gameplay/src/lua/lua_SceneRendererForward.h
  41. 12 6
      gameplay/src/lua/lua_Terrain.cpp
  42. 232 0
      gameplay/src/lua/lua_VisibleSet.cpp
  43. 18 0
      gameplay/src/lua/lua_VisibleSet.h
  44. 251 0
      gameplay/src/lua/lua_VisibleSetDefault.cpp
  45. 18 0
      gameplay/src/lua/lua_VisibleSetDefault.h
  46. 4 0
      gameplay/src/lua/lua_all_bindings.cpp
  47. 4 0
      gameplay/src/lua/lua_all_bindings.h
  48. 26 37
      gameplay/src/social/GooglePlaySocialSession.cpp
  49. 8 8
      gameplay/src/social/GooglePlaySocialSession.h
  50. 16 14
      samples/browser/sample-browser.vcxproj
  51. 6 0
      samples/browser/sample-browser.vcxproj.filters
  52. 6 6
      samples/browser/src/GamepadSample.cpp
  53. 99 0
      samples/browser/src/SceneRendererSample.cpp
  54. 37 0
      samples/browser/src/SceneRendererSample.h
  55. 1 1
      samples/browser/src/TerrainSample.cpp

+ 40 - 42
gameplay/android/java/src/org/gameplay3d/lib/BaseGameActivity.java → gameplay/android/java/src/org/gameplay3d/GamePlayActivity.java

@@ -14,12 +14,11 @@
  * limitations under the License.
  */
 
-package org.gameplay3d.sample_spaceship.basegameutils;
+package org.gameplay3d;
 
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.app.FragmentActivity;
-
 import com.google.android.gms.appstate.AppStateClient;
 import com.google.android.gms.common.ConnectionResult;
 import com.google.android.gms.games.GamesClient;
@@ -32,28 +31,27 @@ import com.google.android.gms.plus.PlusClient;
  * methods. To initiate the sign-in flow when the user clicks the sign-in
  * button, subclasses should call @link{#beginUserInitiatedSignIn}. By default,
  * this class only instantiates the GamesClient object. If the PlusClient or
- * AppStateClient objects are also wanted, call the BaseGameActivity(int)
+ * AppStateClient objects are also wanted, call the BaseGooglePlayActivity(int)
  * constructor and specify the requested clients. For example, to request
- * PlusClient and GamesClient, use BaseGameActivity(CLIENT_GAMES | CLIENT_PLUS).
- * To request all available clients, use BaseGameActivity(CLIENT_ALL).
+ * PlusClient and GamesClient, use BaseGooglePlayActivity(CLIENT_GAMES | CLIENT_PLUS).
+ * To request all available clients, use BaseGooglePlayActivity(CLIENT_ALL).
  * Alternatively, you can also specify the requested clients via
  * @link{#setRequestedClients}, but you must do so before @link{#onCreate}
  * gets called, otherwise the call will have no effect.
  *
  * @author Bruno Oliveira (Google)
  */
-public abstract class BaseGameActivity extends FragmentActivity implements
-        GameHelper.GameHelperListener {
+public abstract class GooglePlayActivity extends FragmentActivity implements GooglePlayClientHelper.GamePlayClientHelperListener {
 
     // The game helper object. This class is mainly a wrapper around this object.
-    protected GameHelper mHelper;
+    protected GamePlayClientHelper mClient;
 
     // We expose these constants here because we don't want users of this class
-    // to have to know about GameHelper at all.
-    public static final int CLIENT_GAMES = GameHelper.CLIENT_GAMES;
-    public static final int CLIENT_APPSTATE = GameHelper.CLIENT_APPSTATE;
-    public static final int CLIENT_PLUS = GameHelper.CLIENT_PLUS;
-    public static final int CLIENT_ALL = GameHelper.CLIENT_ALL;
+    // to have to know about GamePlayClientHelper at all.
+    public static final int CLIENT_GAMES = GamePlayClientHelper.CLIENT_GAMES;
+    public static final int CLIENT_APPSTATE = GamePlayClientHelper.CLIENT_APPSTATE;
+    public static final int CLIENT_PLUS = GamePlayClientHelper.CLIENT_PLUS;
+    public static final int CLIENT_ALL = GamePlayClientHelper.CLIENT_ALL;
 
     // Requested clients. By default, that's just the games client.
     protected int mRequestedClients = CLIENT_GAMES;
@@ -61,21 +59,21 @@ public abstract class BaseGameActivity extends FragmentActivity implements
     // stores any additional scopes.
     private String[] mAdditionalScopes;
 
-    protected String mDebugTag = "BaseGameActivity";
+    protected String mDebugTag = "GooglePlayActivity";
     protected boolean mDebugLog = false;
 
-    /** Constructs a BaseGameActivity with default client (GamesClient). */
-    protected BaseGameActivity() {
+    /** Constructs a BaseGooglePlayActivity with default client (GamesClient). */
+    protected GooglePlayActivity() {
         super();
-        mHelper = new GameHelper(this);
+        mClient = new GamePlayClientHelper(this);
     }
 
     /**
-     * Constructs a BaseGameActivity with the requested clients.
+     * Constructs a GooglePlayActivity with the requested clients.
      * @param requestedClients The requested clients (a combination of CLIENT_GAMES,
      *         CLIENT_PLUS and CLIENT_APPSTATE).
      */
-    protected BaseGameActivity(int requestedClients) {
+    protected GooglePlayActivity(int requestedClients) {
         super();
         setRequestedClients(requestedClients);
     }
@@ -99,92 +97,92 @@ public abstract class BaseGameActivity extends FragmentActivity implements
     @Override
     protected void onCreate(Bundle b) {
         super.onCreate(b);
-        mHelper = new GameHelper(this);
+        mClient = new GamePlayClientHelper(this);
         if (mDebugLog) {
-            mHelper.enableDebugLog(mDebugLog, mDebugTag);
+            mClient.enableDebugLog(mDebugLog, mDebugTag);
         }
-        mHelper.setup(this, mRequestedClients, mAdditionalScopes);
+        mClient.setup(this, mRequestedClients, mAdditionalScopes);
     }
 
     @Override
     protected void onStart() {
         super.onStart();
-        mHelper.onStart(this);
+        mClient.onStart(this);
     }
 
     @Override
     protected void onStop() {
         super.onStop();
-        mHelper.onStop();
+        mClient.onStop();
     }
 
     @Override
     protected void onActivityResult(int request, int response, Intent data) {
         super.onActivityResult(request, response, data);
-        mHelper.onActivityResult(request, response, data);
+        mClient.onActivityResult(request, response, data);
     }
 
     protected GamesClient getGamesClient() {
-        return mHelper.getGamesClient();
+        return mClient.getGamesClient();
     }
 
     protected AppStateClient getAppStateClient() {
-        return mHelper.getAppStateClient();
+        return mClient.getAppStateClient();
     }
 
     protected PlusClient getPlusClient() {
-        return mHelper.getPlusClient();
+        return mClient.getPlusClient();
     }
 
     protected boolean isSignedIn() {
-        return mHelper.isSignedIn();
+        return mClient.isSignedIn();
     }
 
     protected void beginUserInitiatedSignIn() {
-        mHelper.beginUserInitiatedSignIn();
+        mClient.beginUserInitiatedSignIn();
     }
 
     protected void signOut() {
-        mHelper.signOut();
+        mClient.signOut();
     }
 
     protected void showAlert(String title, String message) {
-        mHelper.showAlert(title, message);
+        mClient.showAlert(title, message);
     }
 
     protected void showAlert(String message) {
-        mHelper.showAlert(message);
+        mClient.showAlert(message);
     }
 
     protected void enableDebugLog(boolean enabled, String tag) {
         mDebugLog = true;
         mDebugTag = tag;
-        if (mHelper != null) {
-            mHelper.enableDebugLog(enabled, tag);
+        if (mClient != null) {
+            mClient.enableDebugLog(enabled, tag);
         }
     }
 
     protected String getInvitationId() {
-        return mHelper.getInvitationId();
+        return mClient.getInvitationId();
     }
 
     protected void reconnectClients(int whichClients) {
-        mHelper.reconnectClients(whichClients);
+        mClient.reconnectClients(whichClients);
     }
 
     protected String getScopes() {
-        return mHelper.getScopes();
+        return mClient.getScopes();
     }
 
     protected String[] getScopesArray() {
-        return mHelper.getScopesArray();
+        return mClient.getScopesArray();
     }
 
     protected boolean hasSignInError() {
-        return mHelper.hasSignInError();
+        return mClient.hasSignInError();
     }
 
-    protected GameHelper.SignInFailureReason getSignInError() {
-        return mHelper.getSignInError();
+    protected GamePlayClientHelper.SignInFailureReason getSignInError() {
+        return mClient.getSignInError();
     }
 }

+ 39 - 53
gameplay/android/java/src/org/gameplay3d/lib/GameHelper.java → gameplay/android/java/src/org/gameplay3d/GooglePlayClientHelper.java

@@ -1,20 +1,5 @@
-/*
- * Copyright (C) 2013 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.gameplay3d.sample_spaceship.basegameutils;
+
+package org.gameplay3d;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -43,11 +28,12 @@ import com.google.android.gms.games.GamesClient;
 import com.google.android.gms.games.multiplayer.Invitation;
 import com.google.android.gms.plus.PlusClient;
 
-public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
-        GooglePlayServicesClient.OnConnectionFailedListener {
+public class GooglePlayClientHelper implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener 
+{
 
     /** Listener for sign-in success or failure events. */
-    public interface GameHelperListener {
+    public interface GooglePlayClientHelperListener 
+    {
         /**
          * Called when sign-in fails. As a result, a "Sign-In" button can be
          * shown to the user; when that button is clicked, call
@@ -71,13 +57,13 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     public static final int STATE_CONNECTED = 3;
 
     // State names (for debug logging, etc)
-    public static final String[] STATE_NAMES = {
+    public static final String[] STATE_NAMES = 
+    {
             "UNCONFIGURED", "DISCONNECTED", "CONNECTING", "CONNECTED"
     };
 
     // State we are in right now
     int mState = STATE_UNCONFIGURED;
-
     // Are we expecting the result of a resolution flow?
     boolean mExpectingResolution = false;
 
@@ -138,7 +124,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
 
     // Print debug logs?
     boolean mDebugLog = false;
-    String mDebugTag = "GameHelper";
+    String mDebugTag = "GooglePlayClientHelper";
 
     /*
      * If we got an invitation id when we connected to the games client, it's
@@ -147,19 +133,19 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     String mInvitationId;
 
     // Listener
-    GameHelperListener mListener = null;
+    GooglePlayClientHelperListener mListener = null;
 
     /**
-     * Construct a GameHelper object, initially tied to the given Activity.
+     * Construct a GooglePlayClientHelper object, initially tied to the given Activity.
      * After constructing this object, call @link{setup} from the onCreate()
      * method of your Activity.
      */
-    public GameHelper(Activity activity) {
+    public GooglePlayClientHelper(Activity activity) {
         mActivity = activity;
     }
 
     static private final int TYPE_DEVELOPER_ERROR = 1001;
-    static private final int TYPE_GAMEHELPER_BUG = 1002;
+    static private final int TYPE_GooglePlayClientHelper_BUG = 1002;
     boolean checkState(int type, String operation, String warning, int... expectedStates) {
         for (int expectedState : expectedStates) {
             if (mState == expectedState) {
@@ -168,9 +154,9 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
         }
         StringBuilder sb = new StringBuilder();
         if (type == TYPE_DEVELOPER_ERROR) {
-            sb.append("GameHelper: you attempted an operation at an invalid. ");
+            sb.append("GooglePlayClientHelper: you attempted an operation at an invalid. ");
         } else {
-            sb.append("GameHelper: bug detected. Please report it at our bug tracker ");
+            sb.append("GooglePlayClientHelper: bug detected. Please report it at our bug tracker ");
             sb.append("https://github.com/playgameservices/android-samples/issues. ");
             sb.append("Please include the last couple hundred lines of logcat output ");
             sb.append("and describe the operation that caused this. ");
@@ -194,7 +180,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
 
     void assertConfigured(String operation) {
         if (mState == STATE_UNCONFIGURED) {
-            String error = "GameHelper error: Operation attempted without setup: " + operation +
+            String error = "GooglePlayClientHelper error: Operation attempted without setup: " + operation +
                     ". The setup() method must be called before attempting any other operation.";
             logError(error);
             throw new IllegalStateException(error);
@@ -202,15 +188,15 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     }
 
     /**
-     * Same as calling @link{setup(GameHelperListener, int)} requesting only the
+     * Same as calling @link{setup(GooglePlayClientHelperListener, int)} requesting only the
      * CLIENT_GAMES client.
      */
-    public void setup(GameHelperListener listener) {
+    public void setup(GooglePlayClientHelperListener listener) {
         setup(listener, CLIENT_GAMES);
     }
 
     /**
-     * Performs setup on this GameHelper object. Call this from the onCreate()
+     * Performs setup on this GooglePlayClientHelper object. Call this from the onCreate()
      * method of your Activity. This will create the clients and do a few other
      * initialization tasks. Next, call @link{#onStart} from the onStart()
      * method of your Activity.
@@ -224,9 +210,9 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
      *            I.E. for YouTube uploads one would add
      *            "https://www.googleapis.com/auth/youtube.upload"
      */
-    public void setup(GameHelperListener listener, int clientsToUse, String ... additionalScopes) {
+    public void setup(GooglePlayClientHelperListener listener, int clientsToUse, String ... additionalScopes) {
         if (mState != STATE_UNCONFIGURED) {
-            String error = "GameHelper: you called GameHelper.setup() twice. You can only call " +
+            String error = "GooglePlayClientHelper: you called GooglePlayClientHelper.setup() twice. You can only call " +
                     "it once.";
             logError(error);
             throw new IllegalStateException(error);
@@ -416,9 +402,9 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
 
     /**
      * Returns the invitation ID received through an invitation notification.
-     * This should be called from your GameHelperListener's
+     * This should be called from your GooglePlayClientHelperListener's
      *
-     * @link{GameHelperListener#onSignInSucceeded} method, to check if there's an
+     * @link{GooglePlayClientHelperListener#onSignInSucceeded} method, to check if there's an
      * invitation available. In that case, accept the invitation.
      * @return The id of the invitation, or null if none was received.
      */
@@ -493,7 +479,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     }
 
     void killConnections() {
-        if (!checkState(TYPE_GAMEHELPER_BUG, "killConnections", "killConnections() should only " +
+        if (!checkState(TYPE_GooglePlayClientHelper_BUG, "killConnections", "killConnections() should only " +
                 "get called while connected or connecting.", STATE_CONNECTED, STATE_CONNECTING)) {
             return;
         }
@@ -604,7 +590,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     /**
      * Starts a user-initiated sign-in flow. This should be called when the user
      * clicks on a "Sign In" button. As a result, authentication/consent dialogs
-     * may show up. At the end of the process, the GameHelperListener's
+     * may show up. At the end of the process, the GooglePlayClientHelperListener's
      * onSignInSucceeded() or onSignInFailed() methods will be called.
      */
     public void beginUserInitiatedSignIn() {
@@ -672,7 +658,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     }
 
     void startConnections() {
-        if (!checkState(TYPE_GAMEHELPER_BUG, "startConnections", "startConnections should " +
+        if (!checkState(TYPE_GooglePlayClientHelper_BUG, "startConnections", "startConnections should " +
                 "only get called when disconnected.", STATE_DISCONNECTED)) {
             return;
         }
@@ -735,10 +721,10 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     void connectCurrentClient() {
         if (mState == STATE_DISCONNECTED) {
             // we got disconnected during the connection process, so abort
-            logWarn("GameHelper got disconnected during connection process. Aborting.");
+            logWarn("GooglePlayClientHelper got disconnected during connection process. Aborting.");
             return;
         }
-        if (!checkState(TYPE_GAMEHELPER_BUG, "connectCurrentClient", "connectCurrentClient " +
+        if (!checkState(TYPE_GooglePlayClientHelper_BUG, "connectCurrentClient", "connectCurrentClient " +
                 "should only get called when connecting.", STATE_CONNECTING)) {
             return;
         }
@@ -782,7 +768,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
         if ((whatClients & CLIENT_PLUS) != 0 && mPlusClient != null
                 && mPlusClient.isConnected()) {
             // PlusClient doesn't need reconnections.
-            logWarn("GameHelper is ignoring your request to reconnect " +
+            logWarn("GooglePlayClientHelper is ignoring your request to reconnect " +
                     "PlusClient because this is unnecessary.");
         }
 
@@ -823,7 +809,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
     }
 
     void succeedSignIn() {
-        checkState(TYPE_GAMEHELPER_BUG, "succeedSignIn", "succeedSignIn should only " +
+        checkState(TYPE_GooglePlayClientHelper_BUG, "succeedSignIn", "succeedSignIn should only " +
                 "get called in the connecting or connected state. Proceeding anyway.",
                 STATE_CONNECTING, STATE_CONNECTED);
         debugLog("All requested clients connected. Sign-in succeeded!");
@@ -875,7 +861,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
      */
     void resolveConnectionResult() {
         // Try to resolve the problem
-        checkState(TYPE_GAMEHELPER_BUG, "resolveConnectionResult",
+        checkState(TYPE_GooglePlayClientHelper_BUG, "resolveConnectionResult",
                 "resolveConnectionResult should only be called when connecting. Proceeding anyway.",
                 STATE_CONNECTING);
 
@@ -914,7 +900,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
      * new version, etc).
      */
     void giveUp(SignInFailureReason reason) {
-        checkState(TYPE_GAMEHELPER_BUG, "giveUp", "giveUp should only be called when " +
+        checkState(TYPE_GooglePlayClientHelper_BUG, "giveUp", "giveUp should only be called when " +
                 "connecting. Proceeding anyway.", STATE_CONNECTING);
         mAutoSignIn = false;
         killConnections();
@@ -960,16 +946,16 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
         switch (actResp) {
             case GamesActivityResultCodes.RESULT_APP_MISCONFIGURED:
                 errorDialog = makeSimpleDialog(ctx.getString(
-                        R.string.gamehelper_app_misconfigured));
+                        R.string.GooglePlayClientHelper_app_misconfigured));
                 printMisconfiguredDebugInfo();
                 break;
             case GamesActivityResultCodes.RESULT_SIGN_IN_FAILED:
                 errorDialog = makeSimpleDialog(ctx.getString(
-                        R.string.gamehelper_sign_in_failed));
+                        R.string.GooglePlayClientHelper_sign_in_failed));
                 break;
             case GamesActivityResultCodes.RESULT_LICENSE_FAILED:
                 errorDialog = makeSimpleDialog(ctx.getString(
-                        R.string.gamehelper_license_failed));
+                        R.string.GooglePlayClientHelper_license_failed));
                 break;
             default:
                 // No meaningful Activity response code, so generate default Google
@@ -979,7 +965,7 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
                 if (errorDialog == null) {
                     // get fallback dialog
                     debugLog("No standard error dialog available. Making fallback dialog.");
-                    errorDialog = makeSimpleDialog(ctx.getString(R.string.gamehelper_unknown_error)
+                    errorDialog = makeSimpleDialog(ctx.getString(R.string.GooglePlayClientHelper_unknown_error)
                             + " " + errorCodeToString(errorCode));
                 }
         }
@@ -995,16 +981,16 @@ public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
 
     void debugLog(String message) {
         if (mDebugLog) {
-            Log.d(mDebugTag, "GameHelper: " + message);
+            Log.d(mDebugTag, "GooglePlayClientHelper: " + message);
         }
     }
 
     void logWarn(String message) {
-        Log.w(mDebugTag, "!!! GameHelper WARNING: " + message);
+        Log.w(mDebugTag, "!!! GooglePlayClientHelper WARNING: " + message);
     }
 
     void logError(String message) {
-        Log.e(mDebugTag, "*** GameHelper ERROR: " + message);
+        Log.e(mDebugTag, "*** GooglePlayClientHelper ERROR: " + message);
     }
 
     static String errorCodeToString(int errorCode) {

+ 3 - 4
gameplay/android/java/src/org/gameplay3d/lib/GoogleGamesSocial.java → gameplay/android/java/src/org/gameplay3d/GooglePlaySocial.java

@@ -1,17 +1,16 @@
     
-package org.gameplay3d.lib;
+package org.gameplay3d;
 
 import android.content.Context;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.util.Log;
 import android.widget.Toast;
-
 import com.google.android.gms.games.Player;
 import com.google.example.games.basegameutils.BaseGameActivity;
 
-public class GoogleGamesSocial extends BaseGameActivity {
-	
+public class GooglePlaySocial extends BaseGameActivity 
+{	
 	private static List<Player> mFriends = new ArrayList<Player>();
     private static final int FRIENDS_PER_PAGE = 10;
 	

+ 0 - 12
gameplay/android/java/src/org/gameplay3d/lib/TestClass.java

@@ -1,12 +0,0 @@
-
-package org.gameplay3d.lib;
-
-public class TestClass
-{
-   public TestClass() { }
- 
-   public int ComputeMult(float a, float b)
-   {
-      return (int)(a * b);
-   }
-}

+ 17 - 2
gameplay/gameplay.vcxproj

@@ -240,6 +240,8 @@
     <ClCompile Include="src\lua\lua_RenderTarget.cpp" />
     <ClCompile Include="src\lua\lua_Scene.cpp" />
     <ClCompile Include="src\lua\lua_SceneDebugFlags.cpp" />
+    <ClCompile Include="src\lua\lua_SceneRenderer.cpp" />
+    <ClCompile Include="src\lua\lua_SceneRendererForward.cpp" />
     <ClCompile Include="src\lua\lua_ScreenDisplayer.cpp" />
     <ClCompile Include="src\lua\lua_ScriptController.cpp" />
     <ClCompile Include="src\lua\lua_ScriptTarget.cpp" />
@@ -274,6 +276,8 @@
     <ClCompile Include="src\lua\lua_VertexFormatElement.cpp" />
     <ClCompile Include="src\lua\lua_VertexFormatUsage.cpp" />
     <ClCompile Include="src\lua\lua_VerticalLayout.cpp" />
+    <ClCompile Include="src\lua\lua_VisibleSet.cpp" />
+    <ClCompile Include="src\lua\lua_VisibleSetDefault.cpp" />
     <ClCompile Include="src\Material.cpp" />
     <ClCompile Include="src\MathUtil.cpp" />
     <ClCompile Include="src\MeshBatch.cpp" />
@@ -317,6 +321,8 @@
     <ClCompile Include="src\RenderTarget.cpp" />
     <ClCompile Include="src\Scene.cpp" />
     <ClCompile Include="src\SceneLoader.cpp" />
+    <ClCompile Include="src\SceneRenderer.cpp" />
+    <ClCompile Include="src\SceneRendererForward.cpp" />
     <ClCompile Include="src\ScreenDisplayer.cpp" />
     <ClCompile Include="src\ScriptController.cpp" />
     <ClCompile Include="src\ScriptTarget.cpp" />
@@ -327,7 +333,7 @@
     <ClCompile Include="src\SocialPlayer.cpp" />
     <ClCompile Include="src\SocialScore.cpp" />
     <ClCompile Include="src\SocialSessionListener.cpp" />
-    <ClCompile Include="src\social\GoogleGamesSocialSession.cpp" />
+    <ClCompile Include="src\social\GooglePlaySocialSession.cpp" />
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\Technique.cpp" />
@@ -344,6 +350,7 @@
     <ClCompile Include="src\VertexAttributeBinding.cpp" />
     <ClCompile Include="src\VertexFormat.cpp" />
     <ClCompile Include="src\VerticalLayout.cpp" />
+    <ClCompile Include="src\VisibleSetDefault.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\AbsoluteLayout.h" />
@@ -535,6 +542,8 @@
     <ClInclude Include="src\lua\lua_RenderTarget.h" />
     <ClInclude Include="src\lua\lua_Scene.h" />
     <ClInclude Include="src\lua\lua_SceneDebugFlags.h" />
+    <ClInclude Include="src\lua\lua_SceneRenderer.h" />
+    <ClInclude Include="src\lua\lua_SceneRendererForward.h" />
     <ClInclude Include="src\lua\lua_ScreenDisplayer.h" />
     <ClInclude Include="src\lua\lua_ScriptController.h" />
     <ClInclude Include="src\lua\lua_ScriptTarget.h" />
@@ -569,6 +578,8 @@
     <ClInclude Include="src\lua\lua_VertexFormatElement.h" />
     <ClInclude Include="src\lua\lua_VertexFormatUsage.h" />
     <ClInclude Include="src\lua\lua_VerticalLayout.h" />
+    <ClInclude Include="src\lua\lua_VisibleSet.h" />
+    <ClInclude Include="src\lua\lua_VisibleSetDefault.h" />
     <ClInclude Include="src\Material.h" />
     <ClInclude Include="src\MathUtil.h" />
     <ClInclude Include="src\MeshBatch.h" />
@@ -609,6 +620,8 @@
     <ClInclude Include="src\RenderTarget.h" />
     <ClInclude Include="src\Scene.h" />
     <ClInclude Include="src\SceneLoader.h" />
+    <ClInclude Include="src\SceneRenderer.h" />
+    <ClInclude Include="src\SceneRendererForward.h" />
     <ClInclude Include="src\ScreenDisplayer.h" />
     <ClInclude Include="src\ScriptController.h" />
     <ClInclude Include="src\ScriptTarget.h" />
@@ -620,7 +633,7 @@
     <ClInclude Include="src\SocialScore.h" />
     <ClInclude Include="src\SocialSession.h" />
     <ClInclude Include="src\SocialSessionListener.h" />
-    <ClInclude Include="src\social\GoogleGamesSocialSession.h" />
+    <ClInclude Include="src\social\GooglePlaySocialSession.h" />
     <ClInclude Include="src\social\ScoreloopSocialSession.h" />
     <ClInclude Include="src\SpriteBatch.h" />
     <ClInclude Include="src\Stream.h" />
@@ -640,6 +653,8 @@
     <ClInclude Include="src\VertexAttributeBinding.h" />
     <ClInclude Include="src\VertexFormat.h" />
     <ClInclude Include="src\VerticalLayout.h" />
+    <ClInclude Include="src\VisibleSet.h" />
+    <ClInclude Include="src\VisibleSetDefault.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="res\logo_black.png" />

+ 51 - 6
gameplay/gameplay.vcxproj.filters

@@ -870,9 +870,6 @@
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp">
       <Filter>src\social</Filter>
     </ClCompile>
-    <ClCompile Include="src\social\GoogleGamesSocialSession.cpp">
-      <Filter>src\social</Filter>
-    </ClCompile>
     <ClCompile Include="src\SocialAchievement.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -897,6 +894,30 @@
     <ClCompile Include="src\lua\lua_RenderStateFrontFace.cpp">
       <Filter>src\lua</Filter>
     </ClCompile>
+    <ClCompile Include="src\SceneRenderer.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SceneRendererForward.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\VisibleSetDefault.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\social\GooglePlaySocialSession.cpp">
+      <Filter>src\social</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_SceneRenderer.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_SceneRendererForward.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_VisibleSet.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_VisibleSetDefault.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
@@ -1766,9 +1787,6 @@
     <ClInclude Include="src\social\ScoreloopSocialSession.h">
       <Filter>src\social</Filter>
     </ClInclude>
-    <ClInclude Include="src\social\GoogleGamesSocialSession.h">
-      <Filter>src\social</Filter>
-    </ClInclude>
     <ClInclude Include="src\SocialChallenge.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -1781,6 +1799,33 @@
     <ClInclude Include="src\lua\lua_RenderStateFrontFace.h">
       <Filter>src\lua</Filter>
     </ClInclude>
+    <ClInclude Include="src\SceneRenderer.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\SceneRendererForward.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\VisibleSet.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\VisibleSetDefault.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\social\GooglePlaySocialSession.h">
+      <Filter>src\social</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_SceneRenderer.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_SceneRendererForward.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_VisibleSet.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_VisibleSetDefault.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\Game.inl">

+ 3 - 2
gameplay/src/Form.cpp

@@ -385,10 +385,10 @@ void Form::update(const Control* container, const Vector2& offset)
     }
 }
 
-void Form::draw()
+unsigned int Form::draw()
 {
     if (!_visible || !_frameBuffer)
-        return;
+        return 0;
 
     // The first time a form is drawn, its contents are rendered into a framebuffer.
     // The framebuffer will only be drawn into again when the contents of the form change.
@@ -435,6 +435,7 @@ void Form::draw()
         _spriteBatch->draw(_bounds.x, _bounds.y, 0, _bounds.width, _bounds.height, 0, _v1, _u2, 0, Vector4::one());
         _spriteBatch->finish();
     }
+    return 2;
 }
 
 const char* Form::getType() const

+ 1 - 1
gameplay/src/Form.h

@@ -112,7 +112,7 @@ public:
     /**
      * Draws this form.
      */
-    void draw();
+    unsigned int draw();
 
     /**
      * @see Control::getType

+ 58 - 38
gameplay/src/Model.cpp

@@ -10,7 +10,7 @@ namespace gameplay
 {
 
 Model::Model(Mesh* mesh) :
-    _mesh(mesh), _material(NULL), _partCount(0), _partMaterials(NULL), _node(NULL), _skin(NULL)
+    _mesh(mesh), _material(NULL), _partCount(0), _partMaterials(NULL), _node(NULL), _skin(NULL), _shadowCaster(true), _shadowReceiver(true)
 {
     GP_ASSERT(mesh);
     _partCount = mesh->getPartCount();
@@ -256,6 +256,26 @@ void Model::setNode(Node* node)
     }
 }
 
+void Model::setShadowCaster(bool casts)
+{
+    _shadowCaster = casts;
+}
+
+bool Model::isShadowCaster() const
+{
+    return _shadowCaster;
+}
+
+void Model::setShadowReceiver(bool receives)
+{
+    _shadowReceiver = receives;
+}
+
+bool Model::isShadowReceiver() const
+{
+    return _shadowReceiver;
+}
+
 static bool drawWireframe(Mesh* mesh)
 {
     switch (mesh->getPrimitiveType())
@@ -332,7 +352,7 @@ static bool drawWireframe(MeshPart* part)
     }
 }
 
-void Model::draw(bool wireframe)
+unsigned int Model::draw(bool wireframe)
 {
     GP_ASSERT(_mesh);
 
@@ -388,33 +408,34 @@ void Model::draw(bool wireframe)
             }
         }
     }
+    return partCount;
 }
 
-void Model::validatePartCount()
+void Model::setMaterialNodeBinding(Material *material)
 {
-    GP_ASSERT(_mesh);
-    unsigned int partCount = _mesh->getPartCount();
+    GP_ASSERT(material);
 
-    if (_partCount != partCount)
+    if (_node)
     {
-        // Allocate new arrays and copy old items to them.
-        if (_partMaterials)
+        material->setNodeBinding(_node);
+
+        unsigned int techniqueCount = material->getTechniqueCount();
+        for (unsigned int i = 0; i < techniqueCount; ++i)
         {
-            Material** oldArray = _partMaterials;
-            _partMaterials = new Material*[partCount];
-            memset(_partMaterials, 0, sizeof(Material*) * partCount);
-            if (oldArray)
+            Technique* technique = material->getTechniqueByIndex(i);
+            GP_ASSERT(technique);
+            
+            technique->setNodeBinding(_node);
+
+            unsigned int passCount = technique->getPassCount();
+            for (unsigned int j = 0; j < passCount; ++j)
             {
-                for (unsigned int i = 0; i < _partCount; ++i)
-                {
-                    _partMaterials[i] = oldArray[i];
-                }
+                Pass* pass = technique->getPassByIndex(j);
+                GP_ASSERT(pass);
+
+                pass->setNodeBinding(_node);
             }
-            SAFE_DELETE_ARRAY(oldArray);
         }
-
-        // Update local part count.
-        _partCount = _mesh->getPartCount();
     }
 }
 
@@ -458,31 +479,30 @@ Model* Model::clone(NodeCloneContext &context)
     return model;
 }
 
-void Model::setMaterialNodeBinding(Material *material)
+void Model::validatePartCount()
 {
-    GP_ASSERT(material);
+    GP_ASSERT(_mesh);
+    unsigned int partCount = _mesh->getPartCount();
 
-    if (_node)
+    if (_partCount != partCount)
     {
-        material->setNodeBinding(_node);
-
-        unsigned int techniqueCount = material->getTechniqueCount();
-        for (unsigned int i = 0; i < techniqueCount; ++i)
+        // Allocate new arrays and copy old items to them.
+        if (_partMaterials)
         {
-            Technique* technique = material->getTechniqueByIndex(i);
-            GP_ASSERT(technique);
-            
-            technique->setNodeBinding(_node);
-
-            unsigned int passCount = technique->getPassCount();
-            for (unsigned int j = 0; j < passCount; ++j)
+            Material** oldArray = _partMaterials;
+            _partMaterials = new Material*[partCount];
+            memset(_partMaterials, 0, sizeof(Material*) * partCount);
+            if (oldArray)
             {
-                Pass* pass = technique->getPassByIndex(j);
-                GP_ASSERT(pass);
-
-                pass->setNodeBinding(_node);
+                for (unsigned int i = 0; i < _partCount; ++i)
+                {
+                    _partMaterials[i] = oldArray[i];
+                }
             }
+            SAFE_DELETE_ARRAY(oldArray);
         }
+        // Update local part count.
+        _partCount = _mesh->getPartCount();
     }
 }
 

+ 44 - 5
gameplay/src/Model.h

@@ -14,8 +14,7 @@ class Node;
 class NodeCloneContext;
 
 /**
- * Defines a Model which is an instance of a Mesh that can be drawn
- * with the specified Materials.
+ * Defines a Model (MeshRenderer) which is an instance of a Mesh that can be drawn with the specified Materials.
  */
 class Model : public Ref
 {
@@ -145,6 +144,43 @@ public:
      */
     void setNode(Node* node);
 
+    /**
+     * Sets if this model cast shadows.
+     *
+     * Note: This is only applied to a SceneRenderer.
+     * 
+     * @param casts if this model casts shadows
+     * @see SceneRenderer
+     */
+    void setShadowCaster(bool casts);
+
+    /**
+     * Returns whether this model cast shadows.
+     *
+     * Note: This is only applied to a SceneRenderer.
+     *
+     * @return if this model casts shadows
+     * @see SceneRenderer
+     */
+    bool isShadowCaster() const;
+
+    /**
+     * Sets if this object receives shadows.
+     *
+     * @param bool if this object receives shadows
+     */
+    void setShadowReceiver(bool receives);
+
+    /**
+     * Returns whether this objects recieves shadows.
+     *
+     * Note: This is only applied to a SceneRenderer.
+     *
+     * @return if this object receives shadows
+     * @see SceneRenderer
+     */
+    bool isShadowReceiver() const;
+
     /**
      * Draws this mesh instance.
      *
@@ -154,8 +190,9 @@ public:
      * and so on, should be set up before calling this method.
      *
      * @param wireframe If true, draw the model in wireframe mode.
+     * @return The number of draw calls (mesh parts).
      */
-    void draw(bool wireframe = false);
+    unsigned int draw(bool wireframe = false);
 
 private:
 
@@ -186,8 +223,6 @@ private:
      */
     void setMaterialNodeBinding(Material *m);
 
-    void validatePartCount();
-
     /**
      * Clones the model and returns a new model.
      * 
@@ -196,12 +231,16 @@ private:
      */
     Model* clone(NodeCloneContext &context);
 
+    void validatePartCount();
+
     Mesh* _mesh;
     Material* _material;
     unsigned int _partCount;
     Material** _partMaterials;
     Node* _node;
     MeshSkin* _skin;
+    bool _shadowCaster;
+    bool _shadowReceiver;
 };
 
 }

+ 27 - 1
gameplay/src/Node.cpp

@@ -20,7 +20,7 @@ namespace gameplay
 {
 
 Node::Node(const char* id)
-    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(0),
+    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(0), _visible(true),
     _tags(NULL), _camera(NULL), _light(NULL), _model(NULL), _terrain(NULL), _form(NULL), _audioSource(NULL), _particleEmitter(NULL),
     _collisionObject(NULL), _agent(NULL), _dirtyBits(NODE_DIRTY_ALL), _notifyHierarchyChanged(true), _userData(NULL)
 {
@@ -292,6 +292,32 @@ void Node::setUserPointer(void* pointer, void (*cleanupCallback)(void*))
     }
 }
 
+void Node::setVisible(bool visible)
+{
+    if (_visible != visible)
+    {
+        _visible = visible;
+    }
+}
+
+bool Node::isVisible() const
+{
+    return _visible;
+}
+
+bool Node::isVisibleInHierarchy() const
+{
+   if (!_visible)
+       return false;
+   Node* node = _parent;
+   while (node)
+   {
+       if (!node->_visible)
+           return false;
+   }
+   return true;
+}
+
 unsigned int Node::getChildCount() const
 {
     return _childCount;

+ 42 - 17
gameplay/src/Node.h

@@ -117,13 +117,19 @@ public:
     Node* getParent() const;
 
     /**
-     * Determines if a custom tag with the specified name is set.
+     * Sets a custom tag on this Node.
      *
-     * @param name Name of the tag to query.
+     * Custom tags can be used for a variety of purposes within a game. For example,
+     * a tag called "transparent" can be added to nodes, to indicate which nodes in
+     * a scene are transparent. This tag can then be read during rendering to sort
+     * transparent and opaque objects for correct drawing order. 
      *
-     * @return true if the tag is set, false otherwise.
+     * Setting a tag to NULL removes the tag from the Node.
+     *
+     * @param name Name of the tag to set.
+     * @param value Optional value of the tag (empty string by default).
      */
-    bool hasTag(const char* name) const;
+    void setTag(const char* name, const char* value = "");
 
     /**
      * Returns the value of the custom tag with the given name.
@@ -135,21 +141,13 @@ public:
     const char* getTag(const char* name) const;
 
     /**
-     * Sets a custom tag on this Node.
-     *
-     * Custom tags can be used for a variety of purposes within a game. For example,
-     * a tag called "transparent" can be added to nodes, to indicate which nodes in
-     * a scene are transparent. This tag can then be read during rendering to sort
-     * transparent and opaque objects for correct drawing order. Another example
-     * is using a "visible" tag to mark nodes as invisible to be skipped during
-     * rendering.
+     * Determines if a custom tag with the specified name is set.
      *
-     * Setting a tag to NULL removes the tag from the Node.
+     * @param name Name of the tag to query.
      *
-     * @param name Name of the tag to set.
-     * @param value Optional value of the tag (empty string by default).
+     * @return true if the tag is set, false otherwise.
      */
-    void setTag(const char* name, const char* value = "");
+    bool hasTag(const char* name) const;
 
     /**
      * Returns the user pointer for this node.
@@ -182,6 +180,28 @@ public:
      */
     void setUserPointer(void* pointer, void (*cleanupCallback)(void*) = NULL);
 
+    /**
+     * Sets if visual components themselves set as visible.
+     *
+     * @param visible if visual components themselves set as visible.
+     */
+    void setVisible(bool visible);
+
+    /**
+     * Gets if visual components themselves set as visible.
+     *
+     * @return if visual components themselves set as visible.
+     */
+    bool isVisible() const;
+
+    /**
+     * Gets if visual components are either inherited visible or they are themselves.
+     *
+     * @param inherit true if visible is based on inherited behaviour or false is its self is visible.
+     * @return if visual components attached on this node should be drawn.
+     */
+    bool isVisibleInHierarchy() const;
+
     /**
      * Returns the number of direct children of this item.
      *
@@ -230,7 +250,7 @@ public:
      * Gets the top level node in this node's parent hierarchy.
      */
     Node* getRootNode() const;
-    
+
     /**
      * Returns whether the transformation of this node is static.
      *
@@ -780,6 +800,11 @@ protected:
      */
     unsigned int _childCount;
 
+    /**
+     * If this node is visible. This may not be visiblein hierarchy if its parents are hidden
+     */
+    bool _visible;
+
     /**
      * List of custom tags for a node.
      */

+ 3 - 4
gameplay/src/ParticleEmitter.cpp

@@ -981,12 +981,10 @@ void ParticleEmitter::update(float elapsedTime)
     }
 }
 
-void ParticleEmitter::draw()
+unsigned int ParticleEmitter::draw()
 {
     if (!isActive())
-    {
-        return;
-    }
+        return 0;
 
     if (_particleCount > 0)
     {
@@ -1027,6 +1025,7 @@ void ParticleEmitter::draw()
         // Render.
         _spriteBatch->finish();
     }
+    return 1;
 }
 
 ParticleEmitter* ParticleEmitter::clone()

+ 1 - 1
gameplay/src/ParticleEmitter.h

@@ -700,7 +700,7 @@ public:
     /**
      * Draws the particles currently being emitted.
      */
-    void draw();
+    unsigned int draw();
 
     /**
      * Gets a TextureBlending enum from a corresponding string.

+ 26 - 0
gameplay/src/SceneRenderer.cpp

@@ -0,0 +1,26 @@
+#include "Base.h"
+#include "SceneRenderer.h"
+
+namespace gameplay
+{
+
+SceneRenderer::SceneRenderer()
+    : _wireframe(false)
+{
+}
+
+SceneRenderer::~SceneRenderer()
+{
+}
+
+void SceneRenderer::setWireframe(bool wireframe)
+{
+    _wireframe = wireframe;
+}
+
+bool SceneRenderer::isWireframe() const
+{
+    return _wireframe;
+}
+
+}

+ 62 - 0
gameplay/src/SceneRenderer.h

@@ -0,0 +1,62 @@
+#ifndef SCENERENDERER_H_
+#define SCENERENDERER_H_
+
+#include "Scene.h"
+#include "VisibleSet.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a class that support rendering of the active models in a scene 
+ * and that are visible to the camera. 
+ */
+class SceneRenderer
+{
+public:
+
+    /**
+     * Constructor.
+     *
+     * @param scene The scene to render.
+     * @param lighting The type of lighting system to use.
+     */
+    SceneRenderer();
+
+    /**
+     * Destructor.
+     */
+    virtual ~SceneRenderer();
+
+    /**
+     * Sets if the scene should be rendered in wireframe mode.
+     *
+     * @param wireframe if the scene should be rendered in wireframe mode.
+     */
+    void setWireframe(bool wireframe);
+
+    /**
+     * Determines if the scene should be rendered in wireframe mode.
+     *
+     * @return if the scene should be rendered in wireframe mode.
+     */
+    bool isWireframe() const;
+
+    /**
+     * Renders the scene with all the nodes visible from the active camera in the scene.
+     *
+     * @param scene
+     * param
+     * @return The number of nodes visited.
+     */
+    virtual unsigned int render(VisibleSet* set) = 0;
+
+protected:
+
+    bool _wireframe;
+
+};
+
+}
+
+#endif

+ 73 - 0
gameplay/src/SceneRendererForward.cpp

@@ -0,0 +1,73 @@
+#include "Base.h"
+#include "SceneRendererForward.h"
+#include "Terrain.h"
+#include "Model.h"
+#include "ParticleEmitter.h"
+#include "Form.h"
+
+namespace gameplay
+{
+
+SceneRendererForward::SceneRendererForward()
+    : SceneRenderer()
+{
+}
+
+SceneRendererForward::SceneRendererForward(const SceneRendererForward& copy)
+{
+}
+
+SceneRendererForward::~SceneRendererForward()
+{
+}
+
+SceneRendererForward* SceneRendererForward::create()
+{
+    return new SceneRendererForward();
+}
+
+unsigned int SceneRendererForward::render(VisibleSet* set)
+{
+    set->reset();
+    unsigned int drawCalls = 0;
+    Node* next = set->getNext();
+    do
+    {
+        drawCalls += drawNode(next);
+        next = set->getNext();
+
+    } while ( next != NULL);
+
+    return drawCalls;
+}
+
+unsigned int SceneRendererForward::drawNode(Node* node)
+{
+    unsigned int drawCalls = 0;
+
+    // Draw Terrain
+    Terrain* terrain = node->getTerrain();
+    if (terrain)
+        drawCalls += terrain->draw(isWireframe());
+
+    // Draw Models (Shadows) TODO:
+
+    // Draw Modes
+    Model* model = node->getModel();
+    if (model)
+        drawCalls += model->draw(isWireframe());
+
+    // Draw particles
+    ParticleEmitter* emitter = node->getParticleEmitter();
+    if (emitter)
+        drawCalls += emitter->draw();
+
+    // Draw forms
+    Form* form = node->getForm();
+    if (form)
+        drawCalls += form->draw();
+
+    return drawCalls;
+}
+
+}

+ 49 - 0
gameplay/src/SceneRendererForward.h

@@ -0,0 +1,49 @@
+#ifndef SCENERENDERERFORWARD_H_
+#define SCENERENDERERFORWARD_H_
+
+#include "SceneRenderer.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a class that support rendering of the active models in a scene 
+ * and that are visible to the camera. 
+ */
+class SceneRendererForward : public SceneRenderer
+{
+public:
+
+    /**
+     * Creates a forward scene renderer
+     */
+    static SceneRendererForward* create();
+
+    /**
+     * @see SceneRenderer#render
+     */
+    unsigned int render(VisibleSet* set);
+
+private:
+
+    /**
+     * Constructor.
+     */
+    SceneRendererForward();
+
+    /**
+     * Constructor.
+     */
+    SceneRendererForward(const SceneRendererForward& copy);
+
+    /**
+     * Destructor.
+     */
+    ~SceneRendererForward();
+
+    unsigned int drawNode(Node* node);
+};
+
+}
+
+#endif

+ 2 - 2
gameplay/src/SocialController.cpp

@@ -2,7 +2,7 @@
 #include "SocialController.h"
 #include "Game.h"
 #include "social/ScoreloopSocialSession.h"
-#include "social/GoogleGamesSocialSession.h"
+#include "social/GooglePlaySocialSession.h"
 
 namespace gameplay
 {
@@ -77,7 +77,7 @@ void SocialController::authenticate(SocialSessionListener* listener)
     	providerStr = socialProperties->getString("provider");
     }
 
-    if (strcmp(providerStr, "GoogleGames") == 0)
+    if (strcmp(providerStr, "GooglePlay") == 0)
     {
         _session = GoogleGamesSocialSession::authenticate(listener, socialProperties);
     }

+ 2 - 1
gameplay/src/Terrain.cpp

@@ -509,12 +509,13 @@ float Terrain::getHeight(float x, float z) const
     return height;
 }
 
-void Terrain::draw(bool wireframe)
+unsigned int Terrain::draw(bool wireframe)
 {
     for (size_t i = 0, count = _patches.size(); i < count; ++i)
     {
         _patches[i]->draw(wireframe);
     }
+    return getVisiblePatchCount();
 }
 
 void Terrain::transformChanged(Transform* transform, long cookie)

+ 2 - 1
gameplay/src/Terrain.h

@@ -311,8 +311,9 @@ public:
      * Draws the terrain.
      *
      * @param wireframe True to draw the terrain as wireframe, false to draw it solid (default).
+     * @return The number of draw call taken to drawn the terrain
      */
-    void draw(bool wireframe = false);
+    unsigned int draw(bool wireframe = false);
 
     /**
      * @see Transform::Listener::transformChanged.

+ 5 - 5
gameplay/src/TerrainPatch.cpp

@@ -513,28 +513,28 @@ bool TerrainPatch::updateMaterial()
     return true;
 }
 
-void TerrainPatch::draw(bool wireframe)
+unsigned int TerrainPatch::draw(bool wireframe)
 {
     Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
     Camera* camera = scene ? scene->getActiveCamera() : NULL;
     if (!camera)
-        return;
+        return 0;
 
     // Get our world-space bounding box
     BoundingBox bounds = getBoundingBox(true);
 
     // If the box does not intersect the view frustum, cull it
     if (_terrain->isFlagSet(Terrain::FRUSTUM_CULLING) && !camera->getFrustum().intersects(bounds))
-        return;
+        return 0;
 
     if (!updateMaterial())
-        return;
+        return 0;
 
     // Compute the LOD level from the camera's perspective
     size_t lod = computeLOD(camera, bounds);
 
     // Draw the model for the current LOD
-    _levels[lod]->model->draw(wireframe);
+    return _levels[lod]->model->draw(wireframe);
 }
 
 bool TerrainPatch::isVisible() const

+ 1 - 1
gameplay/src/TerrainPatch.h

@@ -119,7 +119,7 @@ private:
     /**
      * Draws the terrain patch.
      */
-    void draw(bool wireframe);
+    unsigned int draw(bool wireframe);
 
     /**
      * Updates the material for the patch.

+ 48 - 0
gameplay/src/VisibleSet.h

@@ -0,0 +1,48 @@
+#ifndef VISIBLESET_H_
+#define VISIBLESET_H_
+
+#include "Scene.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a set of nodes that are visible from the
+ * scenes active camera. This provides an enumerator
+ * to traverse the scene returning only visible nodes.
+ */
+class VisibleSet
+{
+public:
+
+    /**
+     * Sets the scene to determine the visible set from.
+     *
+     * @param scene The scene to determine the visible set from.
+     */
+    virtual void setScene(Scene* scene) = 0;
+
+    /**
+     * Gets the scene to determine the visible set from.
+     *
+     * @param scene The scene to determine the visible set from.
+     */
+    virtual Scene* getScene() = 0;
+
+    /**
+     * Resets the enumerator for enumerating the visible set.
+     */
+    virtual void reset() = 0;
+
+    /**
+     * Gets the next visible node in the set or NULL 
+     * onces you have reached the end of the set.
+     * 
+     * @return The next visible node in the set or NULL at end of set.
+     */
+    virtual Node* getNext() = 0;
+};
+
+}
+
+#endif

+ 89 - 0
gameplay/src/VisibleSetDefault.cpp

@@ -0,0 +1,89 @@
+#include "Base.h"
+#include "VisibleSetDefault.h"
+
+namespace gameplay
+{
+
+VisibleSetDefault* VisibleSetDefault::create(Scene* scene)
+{
+    return new VisibleSetDefault(scene);
+}
+
+VisibleSetDefault::VisibleSetDefault(Scene* scene) 
+    : _scene(NULL), _next(NULL)
+{
+    setScene(scene);
+}
+
+VisibleSetDefault::VisibleSetDefault(const VisibleSetDefault& copy)
+{
+}
+
+VisibleSetDefault::~VisibleSetDefault()
+{
+}
+
+void VisibleSetDefault::setScene(Scene* scene)
+{
+    _scene = scene;
+    reset();
+}
+
+Scene* VisibleSetDefault::getScene()
+{
+    return _scene;
+}
+
+void VisibleSetDefault::reset()
+{
+    _next = _scene->getFirstNode();
+    while (_next && !_next->isVisible())
+    {
+        _next = _next->getNextSibling();
+    }
+}
+
+Node* VisibleSetDefault::getNext()
+{
+    Node* node = _next;
+    if (_next)
+    {
+        Node* next = _next->getFirstChild();
+        if (!next || !isNodeVisible(next))
+        {
+            next = _next->getNextSibling();
+            if (!next || !isNodeVisible(next))
+            {
+                next = _next->getParent();
+                while (next && (!next->getNextSibling() || !isNodeVisible(next)))
+                {
+                    next = next->getParent();
+                }
+                if (next)
+                {
+                    next = next->getNextSibling();
+                }
+            }
+        }
+       _next = next;
+    }
+    return node;
+}
+
+bool VisibleSetDefault::isNodeVisible(Node* node)
+{
+    if (!node->isVisible())
+        return false;
+
+    if (node->getForm() || node->getParticleEmitter() || node->getTerrain() || node->getLight() || node->getCamera())
+    {
+        return true;
+    }
+    else
+    {
+       return node->getBoundingSphere().intersects(_scene->getActiveCamera()->getFrustum());
+    }
+    return false;
+}
+
+}

+ 73 - 0
gameplay/src/VisibleSetDefault.h

@@ -0,0 +1,73 @@
+#ifndef VISIBLESETDEFAULT_H_
+#define VISIBLESETDEFAULT_H_
+
+#include "VisibleSet.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a default implementation of a VisibleSet.
+ *
+ * All nodes visible to the active camera in the scene are returned.
+ * @see VisibleSet
+ */
+class VisibleSetDefault : public VisibleSet
+{
+public:
+
+    /**
+     * Creates a new default VisibleSet
+     *
+     * @param scene The scene to use for determining visible nodes.
+     */
+    static VisibleSetDefault* create(Scene* scene);
+
+    /**
+     * @see VisibleSet::setScene
+     */
+    void setScene(Scene* scene);
+
+    /**
+     * @see VisibleSet::getScene
+     */
+    Scene* getScene();
+
+    /**
+     * @see VisibleSet::reset
+     */
+    void reset();
+
+    /**
+     * @see VisibleSet::getNext
+     */
+    Node* getNext();
+
+private:
+    
+    /**
+     * Constructor.
+     */
+    VisibleSetDefault(Scene* scene);
+
+    /**
+     * Constructor.
+     */
+    VisibleSetDefault(const VisibleSetDefault& copy);
+
+    /**
+     * Destructor.
+     */
+    ~VisibleSetDefault();
+
+    bool isNodeVisible(Node* node);
+
+private:
+
+    Scene* _scene;
+    Node* _next;
+};
+
+}
+
+#endif

+ 5 - 1
gameplay/src/gameplay.h

@@ -40,9 +40,11 @@
 #include "Model.h"
 #include "Camera.h"
 #include "Light.h"
-#include "Scene.h"
 #include "Node.h"
 #include "Joint.h"
+#include "Scene.h"
+#include "SceneRenderer.h"
+#include "SceneRendererForward.h"
 #include "Font.h"
 #include "SpriteBatch.h"
 #include "ParticleEmitter.h"
@@ -52,6 +54,8 @@
 #include "ScreenDisplayer.h"
 #include "HeightField.h"
 #include "Terrain.h"
+#include "VisibleSet.h"
+#include "VisibleSetDefault.h"
 
 // Audio
 #include "AudioController.h"

+ 6 - 3
gameplay/src/lua/lua_Form.cpp

@@ -784,9 +784,12 @@ int lua_Form_draw(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 Form* instance = getInstance(state);
-                instance->draw();
-                
-                return 0;
+                unsigned int result = instance->draw();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_Form_draw - Failed to match the given parameters to a valid function signature.");

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

@@ -112,6 +112,7 @@ void luaRegister_lua_Global()
     gameplay::ScriptUtil::setGlobalHierarchyPair("RenderState", "Material");
     gameplay::ScriptUtil::setGlobalHierarchyPair("RenderState", "Pass");
     gameplay::ScriptUtil::setGlobalHierarchyPair("RenderState", "Technique");
+    gameplay::ScriptUtil::setGlobalHierarchyPair("SceneRenderer", "SceneRendererForward");
     gameplay::ScriptUtil::setGlobalHierarchyPair("ScriptTarget", "AIAgent");
     gameplay::ScriptUtil::setGlobalHierarchyPair("ScriptTarget", "AIState");
     gameplay::ScriptUtil::setGlobalHierarchyPair("ScriptTarget", "Button");
@@ -139,6 +140,7 @@ void luaRegister_lua_Global()
     gameplay::ScriptUtil::setGlobalHierarchyPair("Transform::Listener", "PhysicsGhostObject");
     gameplay::ScriptUtil::setGlobalHierarchyPair("Transform::Listener", "PhysicsRigidBody");
     gameplay::ScriptUtil::setGlobalHierarchyPair("Transform::Listener", "Terrain");
+    gameplay::ScriptUtil::setGlobalHierarchyPair("VisibleSet", "VisibleSetDefault");
     gameplay::ScriptUtil::addStringFromEnumConversionFunction(&gameplay::lua_stringFromEnumGlobal);
 
     // Register enumeration AIMessage::ParameterType.

+ 109 - 0
gameplay/src/lua/lua_Joint.cpp

@@ -105,6 +105,8 @@ void luaRegister_Joint()
         {"getWorldViewProjectionMatrix", lua_Joint_getWorldViewProjectionMatrix},
         {"hasTag", lua_Joint_hasTag},
         {"isStatic", lua_Joint_isStatic},
+        {"isVisible", lua_Joint_isVisible},
+        {"isVisibleInHierarchy", lua_Joint_isVisibleInHierarchy},
         {"release", lua_Joint_release},
         {"removeAllChildren", lua_Joint_removeAllChildren},
         {"removeChild", lua_Joint_removeChild},
@@ -141,6 +143,7 @@ void luaRegister_Joint()
         {"setTranslationX", lua_Joint_setTranslationX},
         {"setTranslationY", lua_Joint_setTranslationY},
         {"setTranslationZ", lua_Joint_setTranslationZ},
+        {"setVisible", lua_Joint_setVisible},
         {"transformPoint", lua_Joint_transformPoint},
         {"transformVector", lua_Joint_transformVector},
         {"translate", lua_Joint_translate},
@@ -3970,6 +3973,76 @@ int lua_Joint_isStatic(lua_State* state)
     return 0;
 }
 
+int lua_Joint_isVisible(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))
+            {
+                Joint* instance = getInstance(state);
+                bool result = instance->isVisible();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Joint_isVisible - 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_Joint_isVisibleInHierarchy(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))
+            {
+                Joint* instance = getInstance(state);
+                bool result = instance->isVisibleInHierarchy();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Joint_isVisibleInHierarchy - 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_Joint_release(lua_State* state)
 {
     // Get the number of parameters.
@@ -6070,6 +6143,42 @@ int lua_Joint_setTranslationZ(lua_State* state)
     return 0;
 }
 
+int lua_Joint_setVisible(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Joint* instance = getInstance(state);
+                instance->setVisible(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Joint_setVisible - 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_Joint_static_ANIMATE_ROTATE(lua_State* state)
 {
     // Validate the number of parameters.

+ 3 - 0
gameplay/src/lua/lua_Joint.h

@@ -80,6 +80,8 @@ int lua_Joint_getWorldViewMatrix(lua_State* state);
 int lua_Joint_getWorldViewProjectionMatrix(lua_State* state);
 int lua_Joint_hasTag(lua_State* state);
 int lua_Joint_isStatic(lua_State* state);
+int lua_Joint_isVisible(lua_State* state);
+int lua_Joint_isVisibleInHierarchy(lua_State* state);
 int lua_Joint_release(lua_State* state);
 int lua_Joint_removeAllChildren(lua_State* state);
 int lua_Joint_removeChild(lua_State* state);
@@ -116,6 +118,7 @@ int lua_Joint_setTranslation(lua_State* state);
 int lua_Joint_setTranslationX(lua_State* state);
 int lua_Joint_setTranslationY(lua_State* state);
 int lua_Joint_setTranslationZ(lua_State* state);
+int lua_Joint_setVisible(lua_State* state);
 int lua_Joint_static_ANIMATE_ROTATE(lua_State* state);
 int lua_Joint_static_ANIMATE_ROTATE_TRANSLATE(lua_State* state);
 int lua_Joint_static_ANIMATE_SCALE(lua_State* state);

+ 158 - 6
gameplay/src/lua/lua_Model.cpp

@@ -27,9 +27,13 @@ void luaRegister_Model()
         {"getRefCount", lua_Model_getRefCount},
         {"getSkin", lua_Model_getSkin},
         {"hasMaterial", lua_Model_hasMaterial},
+        {"isShadowCaster", lua_Model_isShadowCaster},
+        {"isShadowReceiver", lua_Model_isShadowReceiver},
         {"release", lua_Model_release},
         {"setMaterial", lua_Model_setMaterial},
         {"setNode", lua_Model_setNode},
+        {"setShadowCaster", lua_Model_setShadowCaster},
+        {"setShadowReceiver", lua_Model_setShadowReceiver},
         {NULL, NULL}
     };
     const luaL_Reg lua_statics[] = 
@@ -132,9 +136,12 @@ int lua_Model_draw(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 Model* instance = getInstance(state);
-                instance->draw();
-                
-                return 0;
+                unsigned int result = instance->draw();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_Model_draw - Failed to match the given parameters to a valid function signature.");
@@ -150,9 +157,12 @@ int lua_Model_draw(lua_State* state)
                 bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
                 Model* instance = getInstance(state);
-                instance->draw(param1);
-                
-                return 0;
+                unsigned int result = instance->draw(param1);
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_Model_draw - Failed to match the given parameters to a valid function signature.");
@@ -484,6 +494,76 @@ int lua_Model_hasMaterial(lua_State* state)
     return 0;
 }
 
+int lua_Model_isShadowCaster(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))
+            {
+                Model* instance = getInstance(state);
+                bool result = instance->isShadowCaster();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Model_isShadowCaster - 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_Model_isShadowReceiver(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))
+            {
+                Model* instance = getInstance(state);
+                bool result = instance->isShadowReceiver();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Model_isShadowReceiver - 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_Model_release(lua_State* state)
 {
     // Get the number of parameters.
@@ -803,6 +883,78 @@ int lua_Model_setNode(lua_State* state)
     return 0;
 }
 
+int lua_Model_setShadowCaster(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Model* instance = getInstance(state);
+                instance->setShadowCaster(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Model_setShadowCaster - 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_Model_setShadowReceiver(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Model* instance = getInstance(state);
+                instance->setShadowReceiver(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Model_setShadowReceiver - 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_Model_static_create(lua_State* state)
 {
     // Get the number of parameters.

+ 4 - 0
gameplay/src/lua/lua_Model.h

@@ -15,9 +15,13 @@ int lua_Model_getNode(lua_State* state);
 int lua_Model_getRefCount(lua_State* state);
 int lua_Model_getSkin(lua_State* state);
 int lua_Model_hasMaterial(lua_State* state);
+int lua_Model_isShadowCaster(lua_State* state);
+int lua_Model_isShadowReceiver(lua_State* state);
 int lua_Model_release(lua_State* state);
 int lua_Model_setMaterial(lua_State* state);
 int lua_Model_setNode(lua_State* state);
+int lua_Model_setShadowCaster(lua_State* state);
+int lua_Model_setShadowReceiver(lua_State* state);
 int lua_Model_static_create(lua_State* state);
 
 void luaRegister_Model();

+ 109 - 0
gameplay/src/lua/lua_Node.cpp

@@ -103,6 +103,8 @@ void luaRegister_Node()
         {"getWorldViewProjectionMatrix", lua_Node_getWorldViewProjectionMatrix},
         {"hasTag", lua_Node_hasTag},
         {"isStatic", lua_Node_isStatic},
+        {"isVisible", lua_Node_isVisible},
+        {"isVisibleInHierarchy", lua_Node_isVisibleInHierarchy},
         {"release", lua_Node_release},
         {"removeAllChildren", lua_Node_removeAllChildren},
         {"removeChild", lua_Node_removeChild},
@@ -139,6 +141,7 @@ void luaRegister_Node()
         {"setTranslationX", lua_Node_setTranslationX},
         {"setTranslationY", lua_Node_setTranslationY},
         {"setTranslationZ", lua_Node_setTranslationZ},
+        {"setVisible", lua_Node_setVisible},
         {"transformPoint", lua_Node_transformPoint},
         {"transformVector", lua_Node_transformVector},
         {"translate", lua_Node_translate},
@@ -3925,6 +3928,76 @@ int lua_Node_isStatic(lua_State* state)
     return 0;
 }
 
+int lua_Node_isVisible(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))
+            {
+                Node* instance = getInstance(state);
+                bool result = instance->isVisible();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Node_isVisible - 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_Node_isVisibleInHierarchy(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))
+            {
+                Node* instance = getInstance(state);
+                bool result = instance->isVisibleInHierarchy();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Node_isVisibleInHierarchy - 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_Node_release(lua_State* state)
 {
     // Get the number of parameters.
@@ -6025,6 +6098,42 @@ int lua_Node_setTranslationZ(lua_State* state)
     return 0;
 }
 
+int lua_Node_setVisible(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Node* instance = getInstance(state);
+                instance->setVisible(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Node_setVisible - 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_Node_static_ANIMATE_ROTATE(lua_State* state)
 {
     // Validate the number of parameters.

+ 3 - 0
gameplay/src/lua/lua_Node.h

@@ -79,6 +79,8 @@ int lua_Node_getWorldViewMatrix(lua_State* state);
 int lua_Node_getWorldViewProjectionMatrix(lua_State* state);
 int lua_Node_hasTag(lua_State* state);
 int lua_Node_isStatic(lua_State* state);
+int lua_Node_isVisible(lua_State* state);
+int lua_Node_isVisibleInHierarchy(lua_State* state);
 int lua_Node_release(lua_State* state);
 int lua_Node_removeAllChildren(lua_State* state);
 int lua_Node_removeChild(lua_State* state);
@@ -115,6 +117,7 @@ int lua_Node_setTranslation(lua_State* state);
 int lua_Node_setTranslationX(lua_State* state);
 int lua_Node_setTranslationY(lua_State* state);
 int lua_Node_setTranslationZ(lua_State* state);
+int lua_Node_setVisible(lua_State* state);
 int lua_Node_static_ANIMATE_ROTATE(lua_State* state);
 int lua_Node_static_ANIMATE_ROTATE_TRANSLATE(lua_State* state);
 int lua_Node_static_ANIMATE_SCALE(lua_State* state);

+ 6 - 3
gameplay/src/lua/lua_ParticleEmitter.cpp

@@ -235,9 +235,12 @@ int lua_ParticleEmitter_draw(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 ParticleEmitter* instance = getInstance(state);
-                instance->draw();
-                
-                return 0;
+                unsigned int result = instance->draw();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_ParticleEmitter_draw - Failed to match the given parameters to a valid function signature.");

+ 186 - 0
gameplay/src/lua/lua_SceneRenderer.cpp

@@ -0,0 +1,186 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_SceneRenderer.h"
+#include "Base.h"
+#include "SceneRenderer.h"
+
+namespace gameplay
+{
+
+void luaRegister_SceneRenderer()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"isWireframe", lua_SceneRenderer_isWireframe},
+        {"render", lua_SceneRenderer_render},
+        {"setWireframe", lua_SceneRenderer_setWireframe},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("SceneRenderer", lua_members, NULL, lua_SceneRenderer__gc, lua_statics, scopePath);
+}
+
+static SceneRenderer* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "SceneRenderer");
+    luaL_argcheck(state, userdata != NULL, 1, "'SceneRenderer' expected.");
+    return (SceneRenderer*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_SceneRenderer__gc(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))
+            {
+                void* userdata = luaL_checkudata(state, 1, "SceneRenderer");
+                luaL_argcheck(state, userdata != NULL, 1, "'SceneRenderer' expected.");
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    SceneRenderer* instance = (SceneRenderer*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_SceneRenderer__gc - 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_SceneRenderer_isWireframe(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))
+            {
+                SceneRenderer* instance = getInstance(state);
+                bool result = instance->isWireframe();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_SceneRenderer_isWireframe - 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_SceneRenderer_render(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<VisibleSet> param1 = gameplay::ScriptUtil::getObjectPointer<VisibleSet>(2, "VisibleSet", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'VisibleSet'.");
+                    lua_error(state);
+                }
+
+                SceneRenderer* instance = getInstance(state);
+                unsigned int result = instance->render(param1);
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_SceneRenderer_render - 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_SceneRenderer_setWireframe(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                SceneRenderer* instance = getInstance(state);
+                instance->setWireframe(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_SceneRenderer_setWireframe - 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;
+}
+
+}

+ 17 - 0
gameplay/src/lua/lua_SceneRenderer.h

@@ -0,0 +1,17 @@
+#ifndef LUA_SCENERENDERER_H_
+#define LUA_SCENERENDERER_H_
+
+namespace gameplay
+{
+
+// Lua bindings for SceneRenderer.
+int lua_SceneRenderer__gc(lua_State* state);
+int lua_SceneRenderer_isWireframe(lua_State* state);
+int lua_SceneRenderer_render(lua_State* state);
+int lua_SceneRenderer_setWireframe(lua_State* state);
+
+void luaRegister_SceneRenderer();
+
+}
+
+#endif

+ 194 - 0
gameplay/src/lua/lua_SceneRendererForward.cpp

@@ -0,0 +1,194 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_SceneRendererForward.h"
+#include "Base.h"
+#include "Form.h"
+#include "Model.h"
+#include "ParticleEmitter.h"
+#include "SceneRenderer.h"
+#include "SceneRendererForward.h"
+#include "Terrain.h"
+
+namespace gameplay
+{
+
+void luaRegister_SceneRendererForward()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"isWireframe", lua_SceneRendererForward_isWireframe},
+        {"render", lua_SceneRendererForward_render},
+        {"setWireframe", lua_SceneRendererForward_setWireframe},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_SceneRendererForward_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("SceneRendererForward", lua_members, NULL, NULL, lua_statics, scopePath);
+}
+
+static SceneRendererForward* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "SceneRendererForward");
+    luaL_argcheck(state, userdata != NULL, 1, "'SceneRendererForward' expected.");
+    return (SceneRendererForward*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_SceneRendererForward_isWireframe(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))
+            {
+                SceneRendererForward* instance = getInstance(state);
+                bool result = instance->isWireframe();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_SceneRendererForward_isWireframe - 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_SceneRendererForward_render(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<VisibleSet> param1 = gameplay::ScriptUtil::getObjectPointer<VisibleSet>(2, "VisibleSet", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'VisibleSet'.");
+                    lua_error(state);
+                }
+
+                SceneRendererForward* instance = getInstance(state);
+                unsigned int result = instance->render(param1);
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_SceneRendererForward_render - 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_SceneRendererForward_setWireframe(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_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                SceneRendererForward* instance = getInstance(state);
+                instance->setWireframe(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_SceneRendererForward_setWireframe - 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_SceneRendererForward_static_create(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 0:
+        {
+            void* returnPtr = (void*)SceneRendererForward::create();
+            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, "SceneRendererForward");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 17 - 0
gameplay/src/lua/lua_SceneRendererForward.h

@@ -0,0 +1,17 @@
+#ifndef LUA_SCENERENDERERFORWARD_H_
+#define LUA_SCENERENDERERFORWARD_H_
+
+namespace gameplay
+{
+
+// Lua bindings for SceneRendererForward.
+int lua_SceneRendererForward_isWireframe(lua_State* state);
+int lua_SceneRendererForward_render(lua_State* state);
+int lua_SceneRendererForward_setWireframe(lua_State* state);
+int lua_SceneRendererForward_static_create(lua_State* state);
+
+void luaRegister_SceneRendererForward();
+
+}
+
+#endif

+ 12 - 6
gameplay/src/lua/lua_Terrain.cpp

@@ -188,9 +188,12 @@ int lua_Terrain_draw(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 Terrain* instance = getInstance(state);
-                instance->draw();
-                
-                return 0;
+                unsigned int result = instance->draw();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_Terrain_draw - Failed to match the given parameters to a valid function signature.");
@@ -206,9 +209,12 @@ int lua_Terrain_draw(lua_State* state)
                 bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
                 Terrain* instance = getInstance(state);
-                instance->draw(param1);
-                
-                return 0;
+                unsigned int result = instance->draw(param1);
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_Terrain_draw - Failed to match the given parameters to a valid function signature.");

+ 232 - 0
gameplay/src/lua/lua_VisibleSet.cpp

@@ -0,0 +1,232 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_VisibleSet.h"
+#include "VisibleSet.h"
+
+namespace gameplay
+{
+
+void luaRegister_VisibleSet()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"getNext", lua_VisibleSet_getNext},
+        {"getScene", lua_VisibleSet_getScene},
+        {"reset", lua_VisibleSet_reset},
+        {"setScene", lua_VisibleSet_setScene},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("VisibleSet", lua_members, NULL, lua_VisibleSet__gc, lua_statics, scopePath);
+}
+
+static VisibleSet* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "VisibleSet");
+    luaL_argcheck(state, userdata != NULL, 1, "'VisibleSet' expected.");
+    return (VisibleSet*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_VisibleSet__gc(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))
+            {
+                void* userdata = luaL_checkudata(state, 1, "VisibleSet");
+                luaL_argcheck(state, userdata != NULL, 1, "'VisibleSet' expected.");
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    VisibleSet* instance = (VisibleSet*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_VisibleSet__gc - 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_VisibleSet_getNext(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))
+            {
+                VisibleSet* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getNext();
+                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, "Node");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_VisibleSet_getNext - 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_VisibleSet_getScene(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))
+            {
+                VisibleSet* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getScene();
+                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, "Scene");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_VisibleSet_getScene - 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_VisibleSet_reset(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))
+            {
+                VisibleSet* instance = getInstance(state);
+                instance->reset();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_VisibleSet_reset - 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_VisibleSet_setScene(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Scene> param1 = gameplay::ScriptUtil::getObjectPointer<Scene>(2, "Scene", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Scene'.");
+                    lua_error(state);
+                }
+
+                VisibleSet* instance = getInstance(state);
+                instance->setScene(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_VisibleSet_setScene - 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;
+}
+
+}

+ 18 - 0
gameplay/src/lua/lua_VisibleSet.h

@@ -0,0 +1,18 @@
+#ifndef LUA_VISIBLESET_H_
+#define LUA_VISIBLESET_H_
+
+namespace gameplay
+{
+
+// Lua bindings for VisibleSet.
+int lua_VisibleSet__gc(lua_State* state);
+int lua_VisibleSet_getNext(lua_State* state);
+int lua_VisibleSet_getScene(lua_State* state);
+int lua_VisibleSet_reset(lua_State* state);
+int lua_VisibleSet_setScene(lua_State* state);
+
+void luaRegister_VisibleSet();
+
+}
+
+#endif

+ 251 - 0
gameplay/src/lua/lua_VisibleSetDefault.cpp

@@ -0,0 +1,251 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_VisibleSetDefault.h"
+#include "Base.h"
+#include "VisibleSetDefault.h"
+
+namespace gameplay
+{
+
+void luaRegister_VisibleSetDefault()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"getNext", lua_VisibleSetDefault_getNext},
+        {"getScene", lua_VisibleSetDefault_getScene},
+        {"reset", lua_VisibleSetDefault_reset},
+        {"setScene", lua_VisibleSetDefault_setScene},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_VisibleSetDefault_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    gameplay::ScriptUtil::registerClass("VisibleSetDefault", lua_members, NULL, NULL, lua_statics, scopePath);
+}
+
+static VisibleSetDefault* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "VisibleSetDefault");
+    luaL_argcheck(state, userdata != NULL, 1, "'VisibleSetDefault' expected.");
+    return (VisibleSetDefault*)((gameplay::ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_VisibleSetDefault_getNext(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))
+            {
+                VisibleSetDefault* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getNext();
+                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, "Node");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_VisibleSetDefault_getNext - 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_VisibleSetDefault_getScene(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))
+            {
+                VisibleSetDefault* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getScene();
+                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, "Scene");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_VisibleSetDefault_getScene - 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_VisibleSetDefault_reset(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))
+            {
+                VisibleSetDefault* instance = getInstance(state);
+                instance->reset();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_VisibleSetDefault_reset - 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_VisibleSetDefault_setScene(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Scene> param1 = gameplay::ScriptUtil::getObjectPointer<Scene>(2, "Scene", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Scene'.");
+                    lua_error(state);
+                }
+
+                VisibleSetDefault* instance = getInstance(state);
+                instance->setScene(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_VisibleSetDefault_setScene - 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_VisibleSetDefault_static_create(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 || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Scene> param1 = gameplay::ScriptUtil::getObjectPointer<Scene>(1, "Scene", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Scene'.");
+                    lua_error(state);
+                }
+
+                void* returnPtr = (void*)VisibleSetDefault::create(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, "VisibleSetDefault");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_VisibleSetDefault_static_create - 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;
+}
+
+}

+ 18 - 0
gameplay/src/lua/lua_VisibleSetDefault.h

@@ -0,0 +1,18 @@
+#ifndef LUA_VISIBLESETDEFAULT_H_
+#define LUA_VISIBLESETDEFAULT_H_
+
+namespace gameplay
+{
+
+// Lua bindings for VisibleSetDefault.
+int lua_VisibleSetDefault_getNext(lua_State* state);
+int lua_VisibleSetDefault_getScene(lua_State* state);
+int lua_VisibleSetDefault_reset(lua_State* state);
+int lua_VisibleSetDefault_setScene(lua_State* state);
+int lua_VisibleSetDefault_static_create(lua_State* state);
+
+void luaRegister_VisibleSetDefault();
+
+}
+
+#endif

+ 4 - 0
gameplay/src/lua/lua_all_bindings.cpp

@@ -103,6 +103,8 @@ void lua_RegisterAllBindings()
     luaRegister_RenderStateStateBlock();
     luaRegister_RenderTarget();
     luaRegister_Scene();
+    luaRegister_SceneRenderer();
+    luaRegister_SceneRendererForward();
     luaRegister_ScreenDisplayer();
     luaRegister_ScriptController();
     luaRegister_ScriptTarget();
@@ -130,6 +132,8 @@ void lua_RegisterAllBindings()
     luaRegister_VertexFormat();
     luaRegister_VertexFormatElement();
     luaRegister_VerticalLayout();
+    luaRegister_VisibleSet();
+    luaRegister_VisibleSetDefault();
     luaRegister_lua_Global();
 }
 

+ 4 - 0
gameplay/src/lua/lua_all_bindings.h

@@ -98,6 +98,8 @@
 #include "lua_RenderStateStateBlock.h"
 #include "lua_RenderTarget.h"
 #include "lua_Scene.h"
+#include "lua_SceneRenderer.h"
+#include "lua_SceneRendererForward.h"
 #include "lua_ScreenDisplayer.h"
 #include "lua_ScriptController.h"
 #include "lua_ScriptTarget.h"
@@ -125,6 +127,8 @@
 #include "lua_VertexFormat.h"
 #include "lua_VertexFormatElement.h"
 #include "lua_VerticalLayout.h"
+#include "lua_VisibleSet.h"
+#include "lua_VisibleSetDefault.h"
 #include "lua_Global.h"
 
 namespace gameplay

+ 26 - 37
gameplay/src/social/GoogleGamesSocialSession.cpp → gameplay/src/social/GooglePlaySocialSession.cpp

@@ -1,7 +1,7 @@
 #if defined(__ANDROID__) && defined(GP_USE_SOCIAL)
 
 #include "Base.h"
-#include "GoogleGamesSocialSession.h"
+#include "GooglePlaySocialSession.h"
 #include <android_native_app_glue.h>
 #include <android/log.h>
 
@@ -10,9 +10,9 @@ namespace gameplay
 
 extern struct android_app* __state;
 
-GoogleGamesSocialSession* GoogleGamesSocialSession::_session = NULL;
+GooglePlaySocialSession* GooglePlaySocialSession::_session = NULL;
 
-GoogleGamesSocialSession::GoogleGamesSocialSession()
+GooglePlaySocialSession::GooglePlaySocialSession()
     : SocialSession(),
       _listener(NULL), _properties(NULL), _pendingUserResponse(false), _pendingFriendsResponse(false),
       _pendingScoresResponse(false), _pendingSubmitScoreResponse(false), _pendingAchievementResponse(false),
@@ -22,20 +22,20 @@ GoogleGamesSocialSession::GoogleGamesSocialSession()
     _userOp = USEROP_GET_LOCALUSER;
 }
 
-GoogleGamesSocialSession::~GoogleGamesSocialSession()
+GooglePlaySocialSession::~GooglePlaySocialSession()
 {
 }
 
-SocialSessionListener* GoogleGamesSocialSession::getListener()
+SocialSessionListener* GooglePlaySocialSession::getListener()
 {
     return _listener;
 }
 
-SocialSession *GoogleGamesSocialSession::authenticate(SocialSessionListener* listener, Properties* properties)
+SocialSession *GooglePlaySocialSession::authenticate(SocialSessionListener* listener, Properties* properties)
 {
     if (!_session)
     {
-		_session = new GoogleGamesSocialSession();
+		_session = new GooglePlaySocialSession();
 		_session->_listener = listener;
 		_session->_properties = properties;
 
@@ -75,7 +75,7 @@ SocialSession *GoogleGamesSocialSession::authenticate(SocialSessionListener* lis
     return _session;
 }
 
-const SocialPlayer& GoogleGamesSocialSession::getUser() const
+const SocialPlayer& GooglePlaySocialSession::getUser() const
 {
 	return _user;
 }
@@ -83,108 +83,97 @@ const SocialPlayer& GoogleGamesSocialSession::getUser() const
 /**
  * @see SocialSession::loadFriends
  */
-void GoogleGamesSocialSession::loadFriends()
+void GooglePlaySocialSession::loadFriends()
 {
-
 }
 
 /**
  * @see SocialSession::loadAchievements
  */
-void GoogleGamesSocialSession::loadAchievements()
+void GooglePlaySocialSession::loadAchievements()
 {
-
 }
 
 /**
  * @see SocialSession::submitAchievement
  */
-void GoogleGamesSocialSession::submitAchievement(const char* achievementId, unsigned int value, bool achieved=false)
+void GooglePlaySocialSession::submitAchievement(const char* achievementId, unsigned int value, bool achieved=false)
 {
-
 }
 
 /**
  * @see SocialSession::incrementAchievement
  */
-void GoogleGamesSocialSession::incrementAchievement(const char* achievementId, unsigned int increment=1)
+void GooglePlaySocialSession::incrementAchievement(const char* achievementId, unsigned int increment=1)
 {
-
 }
 
 /**
-  * @see SocialSession::syncAchievements
+  * @see SocialSession::synchronizeAchievements
   */
-void GoogleGamesSocialSession::synchronizeAchievements()
+void GooglePlaySocialSession::synchronizeAchievements()
 {
-
 }
 
 /**
  * @see SocialSession::loadScores
  */
-void GoogleGamesSocialSession::loadScores(const char* leaderboardId, SocialSession::CommunityScope community, SocialSession::TimeScope time, const SocialPlayer& player, unsigned int count)
+void GooglePlaySocialSession::loadScores(const char* leaderboardId, SocialSession::CommunityScope community, SocialSession::TimeScope time, const SocialPlayer& player, unsigned int count)
 {
-
 }
 
 /**
  * @see SocialSession::loadScores
  */
-void GoogleGamesSocialSession::loadScores(const char* leaderboardId, SocialSession::CommunityScope community, SocialSession::TimeScope time, unsigned int start, unsigned int count)
+void GooglePlaySocialSession::loadScores(const char* leaderboardId, SocialSession::CommunityScope community, SocialSession::TimeScope time, unsigned int start, unsigned int count)
 {
-
 }
 
 /**
  * @see SocialSession::submitScore
  */
-void GoogleGamesSocialSession::submitScore(const char* leaderboardId, float score)
+void GooglePlaySocialSession::submitScore(const char* leaderboardId, float score)
 {
-
 }
 
 /**
   * @see SocialSession::submitChallenge
   */
-void GoogleGamesSocialSession::submitChallenge(const SocialPlayer *player, unsigned int wager, float score, const char* leaderboardId=0)
+void GooglePlaySocialSession::submitChallenge(const SocialPlayer *player, unsigned int wager, float score, const char* leaderboardId=0)
 {
-
 }
 
 /**
   * @see SocialSession::loadChallenges
   */
-void GoogleGamesSocialSession::loadChallenges(bool showOpenChallengesOnly=true)
+void GooglePlaySocialSession::loadChallenges(bool showOpenChallengesOnly=true)
 {
-
 }
 
 /**
   * @see SocialSession::acceptChallenge
   */
-void GoogleGamesSocialSession::replyToChallenge(const SocialChallenge *challenge, bool accept)
+void GooglePlaySocialSession::replyToChallenge(const SocialChallenge *challenge, bool accept)
 {
-
 }
 
 /**
  * @see SocialSession::requestSavedData
  */
-void GoogleGamesSocialSession::loadSavedData(const char* key) {}
+void GooglePlaySocialSession::loadSavedData(const char* key) {}
 
 /**
  * @see SocialSession::submitSavedData
  */
-void GoogleGamesSocialSession::submitSavedData(const char* key, std::string data) {}
+void GooglePlaySocialSession::submitSavedData(const char* key, std::string data) {}
 
-void GoogleGamesSocialSession::displayLeaderboard(const char* leaderboardId) {}
+void GooglePlaySocialSession::displayLeaderboard(const char* leaderboardId) {}
 
-void GoogleGamesSocialSession::displayAchievements() {}
+void GooglePlaySocialSession::displayAchievements() {}
 
-void GoogleGamesSocialSession::displayChallenges() {}
+void GooglePlaySocialSession::displayChallenges() {}
 
-void GoogleGamesSocialSession::displayChallengeSubmit(const SocialChallenge *challenge, float score) {}
+void GooglePlaySocialSession::displayChallengeSubmit(const SocialChallenge *challenge, float score) {}
 
 
 }

+ 8 - 8
gameplay/src/social/GoogleGamesSocialSession.h → gameplay/src/social/GooglePlaySocialSession.h

@@ -1,7 +1,7 @@
 #if defined(__ANDROID__) && defined(GP_USE_SOCIAL)
 
-#ifndef GOOGLEGAMESSOCIALSESSION_H_
-#define GOOGLEGAMESSOCIALSESSION_H_
+#ifndef GOOGLEPLAYSOCIALSESSION_H_
+#define GOOGLEPLAYSOCIALSESSION_H_
 
 #include "SocialSession.h"
 
@@ -9,14 +9,14 @@ namespace gameplay
 {
 
 /**
- * Google Games implementation of SocialSession
+ * Google Play (game services) implementation of SocialSession
  *
  * Note: ensure game.config has the following properties
  *
   @verbatim
     social
     {
-         provider = GoogleGames
+         provider = GooglePlay
          id = d346c484-12aa-49a2-a0a0-de2f87492d72
          secret = aAa+DehBfyGO/CYaE3nWomgu7SIbWFczUih+Qwf3/n7u0y3nyq5Hag==
          version = 1.0
@@ -37,7 +37,7 @@ namespace gameplay
  *
  * @script{ignore}
  */
-class GoogleGamesSocialSession : public SocialSession
+class GooglePlaySocialSession : public SocialSession
 {
     friend class SocialController;
 
@@ -142,12 +142,12 @@ private:
     /**
      * Contructor
      */
-    GoogleGamesSocialSession();
+    GooglePlaySocialSession();
 
     /**
      * Destructor
      */
-    virtual ~GoogleGamesSocialSession();
+    virtual ~GooglePlaySocialSession();
 #if 0
 
     static void userCallback(void* cookie, unsigned int result);
@@ -168,7 +168,7 @@ private:
 
     SocialChallenge &addChallenge(SC_Challenge_h challenge);
 #endif
-    static GoogleGamesSocialSession* _session;
+    static GooglePlaySocialSession* _session;
 
     enum UserOp
     {

+ 16 - 14
samples/browser/sample-browser.vcxproj

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="DebugMem|BlackBerry">
@@ -263,8 +263,8 @@
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x86;../../external-deps/bullet/lib/windows/x86;../../external-deps/openal/lib/windows/x86;../../external-deps/oggvorbis/lib/windows/x86;../../external-deps/glew/lib/windows/x86;../../external-deps/png/lib/windows/x86;../../external-deps/zlib/lib/windows/x86;../../gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -293,8 +293,8 @@
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x64;../../external-deps/bullet/lib/windows/x64;../../external-deps/openal/lib/windows/x64;../../external-deps/oggvorbis/lib/windows/x64;../../external-deps/glew/lib/windows/x64;../../external-deps/png/lib/windows/x64;../../external-deps/zlib/lib/windows/x64;../../gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -388,8 +388,8 @@
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x86;../../external-deps/bullet/lib/windows/x86;../../external-deps/openal/lib/windows/x86;../../external-deps/oggvorbis/lib/windows/x86;../../external-deps/glew/lib/windows/x86;../../external-deps/png/lib/windows/x86;../../external-deps/zlib/lib/windows/x86;../../gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -420,8 +420,8 @@
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x64;../../external-deps/bullet/lib/windows/x64;../../external-deps/openal/lib/windows/x64;../../external-deps/oggvorbis/lib/windows/x64;../../external-deps/glew/lib/windows/x64;../../external-deps/png/lib/windows/x64;../../external-deps/zlib/lib/windows/x64;../../gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -511,14 +511,14 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../gameplay/src;../../external-deps/lua/include;../../external-deps/bullet/include;../../external-deps/openal/include/AL;../../external-deps/oggvorbis/include;../../external-deps/png/include;../../external-deps/zlib/include;../../external-deps/glew/include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>../../gameplay/src;../../external-deps/lua/include;../../external-deps/bullet/include;../../external-deps/openal/include/AL;../../external-deps/oggvorbis/include;../../external-deps/png/include;../../external-deps/zlib/include;../../external-deps/glew/include</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x86;../../external-deps/bullet/lib/windows/x86;../../external-deps/openal/lib/windows/x86;../../external-deps/oggvorbis/lib/windows/x86;../../external-deps/glew/lib/windows/x86;../../external-deps/png/lib/windows/x86;../../external-deps/zlib/lib/windows/x86;../../gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -549,8 +549,8 @@
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../../external-deps/lua/lib/windows/x64;../../external-deps/bullet/lib/windows/x64;../../external-deps/openal/lib/windows/x64;../../external-deps/oggvorbis/lib/windows/x64;../../external-deps/glew/lib/windows/x64;../../external-deps/png/lib/windows/x64;../../external-deps/zlib/lib/windows/x64;../../gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
@@ -649,6 +649,7 @@
     <ClCompile Include="src\GestureSample.cpp" />
     <ClCompile Include="src\LightSample.cpp" />
     <ClCompile Include="src\PostProcessSample.cpp" />
+    <ClCompile Include="src\SceneRendererSample.cpp" />
     <ClCompile Include="src\TerrainSample.cpp" />
     <ClCompile Include="src\TriangleSample.cpp" />
     <ClCompile Include="src\FirstPersonCamera.cpp" />
@@ -673,6 +674,7 @@
     <ClInclude Include="src\GestureSample.h" />
     <ClInclude Include="src\LightSample.h" />
     <ClInclude Include="src\PostProcessSample.h" />
+    <ClInclude Include="src\SceneRendererSample.h" />
     <ClInclude Include="src\TerrainSample.h" />
     <ClInclude Include="src\TriangleSample.h" />
     <ClInclude Include="src\FirstPersonCamera.h" />

+ 6 - 0
samples/browser/sample-browser.vcxproj.filters

@@ -79,6 +79,9 @@
     <ClInclude Include="src\TerrainSample.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\SceneRendererSample.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\MeshPrimitiveSample.cpp">
@@ -147,5 +150,8 @@
     <ClCompile Include="src\TerrainSample.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\SceneRendererSample.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 6 - 6
samples/browser/src/GamepadSample.cpp

@@ -4,15 +4,10 @@
     ADD_SAMPLE("Input", "Gamepads", GamepadSample, 3);
 #endif
 
-GamepadSample::GamepadSample() : _gamepad(NULL)
+GamepadSample::GamepadSample() : _font(NULL), _gamepad(NULL)
 {
 }
 
-void GamepadSample::finalize()
-{
-    SAFE_RELEASE(_font);
-}
-
 void GamepadSample::initialize()
 {
     setMultiTouch(true);
@@ -27,6 +22,11 @@ void GamepadSample::initialize()
     _status = "Looking for gamepads...";
 }
 
+void GamepadSample::finalize()
+{
+    SAFE_RELEASE(_font);
+}
+
 void GamepadSample::updateGamepad(float elapsedTime, Gamepad* gamepad, unsigned int player)
 {
     char s[128];

+ 99 - 0
samples/browser/src/SceneRendererSample.cpp

@@ -0,0 +1,99 @@
+#include "SceneRendererSample.h"
+#include "SamplesGame.h"
+
+#if defined(ADD_SAMPLE)
+    ADD_SAMPLE("Scene", "SceneRenderer", SceneRendererSample, 3);
+#endif
+
+SceneRendererSample::SceneRendererSample() : _font(NULL), _scene(NULL), _visibleSet(NULL), _lightNode(NULL)
+{
+}
+
+void SceneRendererSample::initialize()
+{
+    setMultiTouch(true);
+
+    _font = Font::create("res/common/arial.gpb");
+    _scene = Scene::load("res/common/sample.scene");
+    _visibleSet = VisibleSetDefault::create(_scene);
+    _renderer = SceneRendererForward::create();
+
+    // Find the light node
+    _lightNode = _scene->findNode("directionalLight");
+
+    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
+
+    _scene->visit(this, &SceneRendererSample::bindLights);
+}
+
+void SceneRendererSample::finalize()
+{
+    SAFE_RELEASE(_font);
+}
+
+void SceneRendererSample::update(float elapsedTime)
+{
+}
+
+void SceneRendererSample::render(float elapsedTime)
+{
+    clear(CLEAR_COLOR_DEPTH, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+
+    _renderer->render(_visibleSet);
+
+    drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate());
+}
+
+void SceneRendererSample::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+{
+    switch (evt)
+    {
+    case Touch::TOUCH_PRESS:
+        if (x < 75 && y < 50)
+        {
+            // Toggle Vsync if the user touches the top left corner
+            setVsync(!isVsync());
+            return;
+        }
+        break;
+    case Touch::TOUCH_RELEASE:
+        break;
+    case Touch::TOUCH_MOVE:
+        break;
+    };
+}
+
+void SceneRendererSample::keyEvent(Keyboard::KeyEvent evt, int key)
+{
+}
+
+bool SceneRendererSample::bindLights(Node* node)
+{
+    Model* model = node->getModel();
+    if (model)
+    {
+        Material* material = model->getMaterial();
+        if (material)
+        {
+            MaterialParameter* ambientColorParam = material->getParameter("u_ambientColor");
+            if (ambientColorParam)
+            {
+                ambientColorParam->setValue(_scene->getAmbientColor());
+            }
+            if (_lightNode && _lightNode->getLight())
+            {
+                MaterialParameter* lightDirectionParam = material->getParameter("u_lightDirection");
+                MaterialParameter* lightColorParam = material->getParameter("u_lightColor");
+                if (lightDirectionParam)
+                {
+                    lightDirectionParam->bindValue(_lightNode, &Node::getForwardVectorView);
+                }
+                if (lightColorParam)
+                {
+                    lightColorParam->setValue(_lightNode->getLight()->getColor());
+                }
+            }
+        }
+    }
+    return true;
+}

+ 37 - 0
samples/browser/src/SceneRendererSample.h

@@ -0,0 +1,37 @@
+#ifndef SCENERENDERERSAMPLE_H_
+#define SCENERENDERERSAMPLE_H_
+
+#include "gameplay.h"
+#include "Sample.h"
+
+using namespace gameplay;
+
+/**
+ * Sample to show case the SceneRenderer
+ */
+class SceneRendererSample : public Sample
+{
+public:
+
+    SceneRendererSample();
+
+protected:
+    void initialize();
+    void finalize();
+    void update(float elapsedTime);
+    void render(float elapsedTime);
+    void touchEvent(Touch::TouchEvent event, int x, int y, unsigned int contactIndex);
+    void keyEvent(Keyboard::KeyEvent evt, int key);
+
+private:
+
+    bool bindLights(Node* node);
+
+    Font* _font;
+    Scene* _scene;
+    Node* _lightNode;
+    VisibleSet* _visibleSet;
+    SceneRenderer* _renderer;
+};
+
+#endif

+ 1 - 1
samples/browser/src/TerrainSample.cpp

@@ -2,7 +2,7 @@
 #include "SamplesGame.h"
 
 #if defined(ADD_SAMPLE)
-    ADD_SAMPLE("Scene", "Terrain", TerrainSample, 3);
+    ADD_SAMPLE("Scene", "Terrain", TerrainSample, 4);
 #endif
 
 struct TerrainHitFilter : public PhysicsController::HitFilter