Преглед изворни кода

Changes to DepthStencilTarget where DEPTH24 -> DEPTH and DEPTH24_STENCIL8 -> DEPTH_STENCIL to be more flexible to allow the platform to implement less or more supported precision.
Changes to FrameBuffer now requiring framebuffers to be a power of 2 and width/height to be required. No empty framebuffers of no size supported now.
Removes Texture::DEPTH type which is not supported on all platforms. User instead must use standard render targets.
Added Texture::getFormat()
Added RenderState::getVertexAttributeBinding()
Removed typdefs on NodeCloneContext for std::map definitions to be more explicit.
Updated API documentation.

setaylor пре 13 година
родитељ
комит
63ad96eed6

+ 84 - 41
gameplay.doxyfile

@@ -1,4 +1,4 @@
-# Doxyfile 1.7.5.1
+# Doxyfile 1.8.0
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
@@ -32,7 +32,7 @@ PROJECT_NAME           = gameplay
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.3.0
+PROJECT_NUMBER         = 1.4.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # for a project that appears at the top of each page and should give viewer 
@@ -205,6 +205,13 @@ TAB_SIZE               = 8
 
 ALIASES                = 
 
+# This tag can be used to specify a number of word-keyword mappings (TCL only). 
+# A mapping has the form "name=value". For example adding 
+# "class=itcl::class" will allow you to use the command class in the 
+# itcl::class meaning.
+
+TCL_SUBST              = 
+
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
 # sources only. Doxygen will then generate output that is more tailored for C. 
 # For instance, some of the names that are used will be different. The list 
@@ -243,6 +250,15 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 
 EXTENSION_MAPPING      = 
 
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 
+# comments according to the Markdown format, which allows for more readable 
+# documentation. See http://daringfireball.net/projects/markdown/ for details. 
+# The output of markdown processing is further processed by doxygen, so you 
+# can mix doxygen, HTML, and XML commands with Markdown formatting. 
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
 # to include (a tag file for) the STL sources as input, then you should 
 # set this tag to YES in order to let doxygen match functions declarations and 
@@ -325,10 +341,21 @@ TYPEDEF_HIDES_STRUCT   = NO
 # a logarithmic scale so increasing the size by one will roughly double the 
 # memory usage. The cache size is given by this formula: 
 # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
-# corresponding to a cache size of 2^16 = 65536 symbols
+# corresponding to a cache size of 2^16 = 65536 symbols.
 
 SYMBOL_CACHE_SIZE      = 0
 
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
+# their name and scope. Since this can be an expensive process and often the 
+# same symbol appear multiple times in the code, doxygen keeps a cache of 
+# pre-resolved symbols. If the cache is too small doxygen will become slower. 
+# If the cache is too large, memory is wasted. The cache size is given by this 
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
@@ -345,6 +372,11 @@ EXTRACT_ALL            = NO
 
 EXTRACT_PRIVATE        = NO
 
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
 # If the EXTRACT_STATIC tag is set to YES all static members of a file 
 # will be included in the documentation.
 
@@ -354,7 +386,7 @@ EXTRACT_STATIC         = NO
 # defined locally in source files will be included in the documentation. 
 # If set to NO only classes defined in header files are included.
 
-EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_CLASSES  = NO
 
 # This flag is only useful for Objective-C code. When set to YES local 
 # methods, which are defined in the implementation section but not in 
@@ -391,7 +423,7 @@ HIDE_UNDOC_CLASSES     = NO
 # If set to NO (the default) these declarations will be included in the 
 # documentation.
 
-HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_FRIEND_COMPOUNDS  = YES
 
 # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
 # documentation blocks found inside the body of a function. 
@@ -574,7 +606,8 @@ LAYOUT_FILE            =
 # .bib extension is automatically appended if omitted. Using this command 
 # requires the bibtex tool to be installed. See also 
 # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
-# of the bibliography can be controlled using LATEX_BIB_STYLE.
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# feature you need bibtex and perl available in the search path.
 
 CITE_BIB_FILES         = 
 
@@ -665,14 +698,15 @@ FILE_PATTERNS          = *.h \
 
 RECURSIVE              = NO
 
-# The EXCLUDE tag can be used to specify files and/or directories that should 
+# The EXCLUDE tag can be used to specify files and/or directories that should be 
 # excluded from the INPUT source files. This way you can easily exclude a 
 # subdirectory from a directory tree whose root is specified with the INPUT tag. 
-# Note that relative paths are relative to directory from which doxygen is run.
+# Note that relative paths are relative to the directory from which doxygen is 
+# run.
 
 EXCLUDE                = 
 
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
 # directories that are symbolic links (a Unix file system feature) are excluded 
 # from the input.
 
@@ -857,7 +891,7 @@ HTML_FILE_EXTENSION    = .html
 # standard header. Note that when using a custom header you are responsible  
 # for the proper inclusion of any scripts and style sheets that doxygen 
 # needs, which is dependent on the configuration options used. 
-# It is adviced to generate a default header using "doxygen -w html 
+# It is advised to generate a default header using "doxygen -w html 
 # header.html footer.html stylesheet.css YourConfigFile" and then modify 
 # that header. Note that the header is subject to change so you typically 
 # have to redo this when upgrading to a newer version of doxygen or when 
@@ -876,7 +910,7 @@ HTML_FOOTER            =
 # fine-tune the look of the HTML output. If the tag is left blank doxygen 
 # will generate a default style sheet. Note that doxygen will try to copy 
 # the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
+# style sheet in the HTML output directory as well, or it will be erased!
 
 HTML_STYLESHEET        = 
 
@@ -890,7 +924,7 @@ HTML_STYLESHEET        =
 HTML_EXTRA_FILES       = 
 
 # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
-# Doxygen will adjust the colors in the stylesheet and background images 
+# Doxygen will adjust the colors in the style sheet and background images 
 # according to this color. Hue is specified as an angle on a colorwheel, 
 # see http://en.wikipedia.org/wiki/Hue for more information. 
 # For instance the value 0 represents red, 60 is yellow, 120 is green, 
@@ -1085,29 +1119,33 @@ GENERATE_ECLIPSEHELP   = NO
 
 ECLIPSE_DOC_ID         = org.doxygen.Project
 
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
+# at top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. Since the tabs have the same information as the 
+# navigation tree you can set this option to NO if you already set 
+# GENERATE_TREEVIEW to YES.
 
 DISABLE_INDEX          = NO
 
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
-# documentation. Note that a value of 0 will completely suppress the enum 
-# values from appearing in the overview section.
-
-ENUM_VALUES_PER_LINE   = 4
-
 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
 # structure should be generated to display hierarchical information. 
 # If the tag value is set to YES, a side panel will be generated 
 # containing a tree-like index structure (just like the one that 
 # is generated for HTML Help). For this to work a browser that supports 
 # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
-# Windows users are probably better off using the HTML help feature.
+# Windows users are probably better off using the HTML help feature. 
+# Since the tree basically has the same information as the tab index you 
+# could consider to set DISABLE_INDEX to NO when enabling this option.
 
 GENERATE_TREEVIEW      = NO
 
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
 # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
 # and Class Hierarchy pages using a tree view instead of an ordered list.
 
@@ -1144,7 +1182,7 @@ FORMULA_TRANSPARENT    = YES
 # (see http://www.mathjax.org) which uses client side Javascript for the 
 # rendering instead of using prerendered bitmaps. Use this if you do not 
 # have LaTeX installed or if you want to formulas look prettier in the HTML 
-# output. When enabled you also need to install MathJax separately and 
+# output. When enabled you may also need to install MathJax separately and 
 # configure the path to it using the MATHJAX_RELPATH option.
 
 USE_MATHJAX            = NO
@@ -1153,10 +1191,10 @@ USE_MATHJAX            = NO
 # HTML output directory using the MATHJAX_RELPATH option. The destination 
 # directory should contain the MathJax.js script. For instance, if the mathjax 
 # directory is located at the same level as the HTML output directory, then 
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
-# mathjax.org site, so you can quickly see the result without installing 
-# MathJax, but it is strongly recommended to install a local copy of MathJax 
-# before deployment.
+# MATHJAX_RELPATH should be ../mathjax. The default value points to 
+# the MathJax Content Delivery Network so you can quickly see the result without 
+# installing MathJax.  However, it is strongly recommended to install a local 
+# copy of MathJax from http://www.mathjax.org before deployment.
 
 MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
 
@@ -1315,7 +1353,7 @@ COMPACT_RTF            = NO
 
 RTF_HYPERLINKS         = NO
 
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# Load style sheet definitions from file. Syntax is similar to doxygen's 
 # config file, i.e. a series of assignments. You only have to provide 
 # replacements, missing definitions are set to their default value.
 
@@ -1504,20 +1542,16 @@ SKIP_FUNCTION_MACROS   = YES
 # Configuration::additions related to external references
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
+# The TAGFILES option can be used to specify one or more tagfiles. For each 
+# tag file the location of the external documentation should be added. The 
+# format of a tag file without this location is as follows: 
 #   TAGFILES = file1 file2 ... 
 # Adding location for the tag files is done as follows: 
 #   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links. 
-# Note that each tag file must have a unique name 
-# (where the name does NOT include the path) 
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
+# where "loc1" and "loc2" can be relative or absolute paths 
+# or URLs. Note that each tag file must have a unique name (where the name does 
+# NOT include the path). If a tag file is not located in the directory in which 
+# doxygen is run, you must also specify the path to the tagfile here.
 
 TAGFILES               = 
 
@@ -1608,7 +1642,7 @@ DOT_FONTPATH           =
 # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
 # will generate a graph for each documented class showing the direct and 
 # indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
+# CLASS_DIAGRAMS tag to NO.
 
 CLASS_GRAPH            = YES
 
@@ -1630,6 +1664,15 @@ GROUP_GRAPHS           = YES
 
 UML_LOOK               = NO
 
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside 
+# the class node. If there are many fields or methods and many nodes the 
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 
+# threshold limits the number of items for each type to make the size more 
+# managable. Set this to 0 for no limit. Note that the threshold may be 
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
 # If set to YES, the inheritance and collaboration graphs will show the 
 # relations between templates and their instances.
 

+ 1 - 1
gameplay/gameplay.vcxproj

@@ -365,4 +365,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 1 - 1
gameplay/gameplay.vcxproj.filters

@@ -715,4 +715,4 @@
       <Filter>src</Filter>
     </None>
   </ItemGroup>
-</Project>
+</Project>

+ 2 - 0
gameplay/src/Base.h

@@ -188,6 +188,7 @@ extern void printError(const char* format, ...);
     extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
     extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
     extern PFNGLISVERTEXARRAYOESPROC glIsVertexArray;
+    #define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
     #define glClearDepth glClearDepthf
     #define OPENGL_ES
     #define USE_PVRTC
@@ -202,6 +203,7 @@ extern void printError(const char* format, ...);
     extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
     extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
     extern PFNGLISVERTEXARRAYOESPROC glIsVertexArray;
+    #define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
     #define glClearDepth glClearDepthf
     #define OPENGL_ES
 #elif WIN32

+ 3 - 39
gameplay/src/DepthStencilTarget.cpp

@@ -7,19 +7,15 @@ namespace gameplay
 static std::vector<DepthStencilTarget*> __depthStencilTargets;
 
 DepthStencilTarget::DepthStencilTarget(const char* id, Format format)
-    : _id(id ? id : ""), _format(format), _depthTexture(NULL), _stencilBuffer(0)
+    : _id(id ? id : ""), _format(format), _renderBuffer(0)
 {
 }
 
 DepthStencilTarget::~DepthStencilTarget()
 {
-    SAFE_RELEASE(_depthTexture);
-
     // Destroy GL resources.
-    if (_stencilBuffer)
-    {
-        GL_ASSERT( glDeleteTextures(1, &_stencilBuffer) );
-    }
+    if (_renderBuffer)
+        GL_ASSERT( glDeleteTextures(1, &_renderBuffer) );
 
     // Remove from vector.
     std::vector<DepthStencilTarget*>::iterator it = std::find(__depthStencilTargets.begin(), __depthStencilTargets.end(), this);
@@ -31,34 +27,8 @@ DepthStencilTarget::~DepthStencilTarget()
 
 DepthStencilTarget* DepthStencilTarget::create(const char* id, Format format, unsigned int width, unsigned int height)
 {
-    // Create a backing texture buffer.
-    Texture* depthTexture = Texture::create(Texture::DEPTH, width, height, NULL, false);
-    if (depthTexture == NULL)
-    {
-        return NULL;
-    }
-
-    // Create stencil renderbuffer if format is DEPTH24_STENCIL8.
-    RenderBufferHandle stencilBuffer = 0;
-    if (format == DEPTH24_STENCIL8)
-    {
-        // Backup the existing render buffer.
-        GLint currentRbo = 0;
-        GL_ASSERT( glGetIntegerv(GL_RENDERBUFFER_BINDING, &currentRbo) );
-
-        // Create the new render buffer.
-        GL_ASSERT( glGenRenderbuffers(1, &stencilBuffer) );
-        GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer) );
-        GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height) );
-
-        // Restore the old render buffer.
-        GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, currentRbo) );
-    }
-
     // Create the depth stencil target.
     DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, format);
-    depthStencilTarget->_depthTexture = depthTexture;
-    depthStencilTarget->_stencilBuffer = stencilBuffer;
 
     // Add it to the cache.
     __depthStencilTargets.push_back(depthStencilTarget);
@@ -81,7 +51,6 @@ DepthStencilTarget* DepthStencilTarget::getDepthStencilTarget(const char* id)
             return dst;
         }
     }
-
     return NULL;
 }
 
@@ -95,9 +64,4 @@ DepthStencilTarget::Format DepthStencilTarget::getFormat() const
     return _format;
 }
 
-Texture* DepthStencilTarget::getTexture() const
-{
-    return _depthTexture;
-}
-
 }

+ 5 - 15
gameplay/src/DepthStencilTarget.h

@@ -26,16 +26,14 @@ public:
     enum Format
     {
         /**
-         * A target with 24-bits of depth data.
-         *
-         * This format may be internally stored as a 32-bit buffer with 8 bits of unused data.
+         * A target with depth data.
          */
-        DEPTH24,
+        DEPTH,
 
         /**
-         * A target with 24 bits of depth data and 8 bits stencil data.
+         * A target with depth data and stencil data.
          */
-        DEPTH24_STENCIL8
+        DEPTH_STENCIL
     };
 
     /**
@@ -73,13 +71,6 @@ public:
      */
     Format getFormat() const;
 
-    /**
-     * Returns the depth texture for this DepthStencilTarget.
-     *
-     * @return The depth texture for this DepthStencilTarget.
-     */
-    Texture* getTexture() const;
-
 private:
 
     /**
@@ -94,8 +85,7 @@ private:
 
     std::string _id;
     Format _format;
-    Texture* _depthTexture;
-    RenderBufferHandle _stencilBuffer;
+    RenderBufferHandle _renderBuffer;
 };
 
 }

+ 2 - 2
gameplay/src/Effect.cpp

@@ -420,8 +420,8 @@ void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 
 void Effect::bind()
 {
-    GL_ASSERT( glUseProgram(_program) );
-
+   glUseProgram(_program) ;
+   GLenum test = glGetError();
     __currentEffect = this;
 }
 

+ 24 - 32
gameplay/src/Form.cpp

@@ -77,6 +77,7 @@ Form* Form::create(const char* url)
         break;
     default:
         GP_ERROR("Unsupported layout type '%d'.", getLayoutType(layoutString));
+        break;
     }
 
     Theme* theme = Theme::create(themeFile);
@@ -173,34 +174,17 @@ void Form::setSize(float width, float height)
     if (width != _bounds.width || height != _bounds.height)
     {
         // Width and height must be powers of two to create a texture.
-        int w = width;
-        int h = height;
-
-        if (!((w & (w - 1)) == 0))
-        {
-            w = nextHighestPowerOfTwo(w);
-        }
-
-        if (!((h & (h - 1)) == 0))
-        {
-            h = nextHighestPowerOfTwo(h);
-        }
-
+        unsigned int w = nextPowerOfTwo(width);
+        unsigned int h = nextPowerOfTwo(height);
         _u2 = width / (float)w;
         _v1 = height / (float)h;
 
         // Create framebuffer if necessary.
-        if (!_frameBuffer)
-        {
-            _frameBuffer = FrameBuffer::create(_id.c_str());
-            GP_ASSERT(_frameBuffer);
-        }
-     
-        // Re-create render target.
-        RenderTarget* rt = RenderTarget::create(_id.c_str(), w, h);
-        GP_ASSERT(rt);
-        _frameBuffer->setRenderTarget(rt);
-        SAFE_RELEASE(rt);
+        if (_frameBuffer)
+            SAFE_RELEASE(_frameBuffer)
+        
+        _frameBuffer = FrameBuffer::create(_id.c_str(), w, h);
+        GP_ASSERT(_frameBuffer);
 
         // Re-create projection matrix.
         Matrix::createOrthographicOffCenter(0, width, height, 0, 0, 1, &_projectionMatrix);
@@ -641,15 +625,23 @@ void Form::keyEventInternal(Keyboard::KeyEvent evt, int key)
     }
 }
 
-int Form::nextHighestPowerOfTwo(int x)
+unsigned int Form::nextPowerOfTwo(unsigned int v)
 {
-    x--;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    return x + 1;
+
+    if (!((v & (v - 1)) == 0))
+    {
+        v--;
+        v |= v >> 1;
+        v |= v >> 2;
+        v |= v >> 4;
+        v |= v >> 8;
+        v |= v >> 16;
+        return v + 1;
+    }
+    else
+    {
+        return v;
+    }
 }
 
 }

+ 1 - 1
gameplay/src/Form.h

@@ -178,7 +178,7 @@ private:
      */
     static void keyEventInternal(Keyboard::KeyEvent evt, int key);
 
-    static int nextHighestPowerOfTwo(int x);
+    static unsigned int nextPowerOfTwo(unsigned int v);
 
     Theme* _theme;              // The Theme applied to this Form.
     Model* _quad;               // Quad for rendering this Form in world-space.

+ 74 - 49
gameplay/src/FrameBuffer.cpp

@@ -12,8 +12,9 @@ static unsigned int __maxRenderTargets = 0;
 static std::vector<FrameBuffer*> __frameBuffers;
 static FrameBufferHandle __defaultHandle = 0;
 
-FrameBuffer::FrameBuffer(const char* id) :
-    _id(id ? id : ""), _handle(0), _renderTargets(NULL), _depthStencilTarget(NULL)
+FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height) :
+    _id(id ? id : ""), _width(width), _height(height), _handle(0), 
+    _renderTargets(NULL), _depthStencilTarget(NULL)
 {
 }
 
@@ -27,6 +28,10 @@ FrameBuffer::~FrameBuffer()
         }
         SAFE_DELETE_ARRAY(_renderTargets);
     }
+    if (_depthStencilTarget)
+    {
+        SAFE_RELEASE(_depthStencilTarget);
+    }
 
     // Release GL resource.
     if (_handle)
@@ -49,51 +54,40 @@ void FrameBuffer::initialize()
     __defaultHandle = (FrameBufferHandle)fbo;
 }
 
-FrameBuffer* FrameBuffer::create(const char* id)
+FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned int height)
 {
-    // Create GL FBO resource.
-    GLuint handle = 0;
-    GL_ASSERT( glGenFramebuffers(1, &handle) );
+    if (!isPowerOfTwo(width) | !isPowerOfTwo(height))
+    {
+        GP_ERROR("Failed to create render target for frame buffer. Width and Height must be a power of 2.");
+        return NULL;
+    }
 
     // Call getMaxRenderTargets() to force __maxRenderTargets to be set
     getMaxRenderTargets();
 
-    // Create the render target array for the new frame buffer
-    RenderTarget** renderTargets = new RenderTarget*[__maxRenderTargets];
-    memset(renderTargets, 0, sizeof(RenderTarget*) * __maxRenderTargets);
-
-    // Create the new frame buffer
-    FrameBuffer* frameBuffer = new FrameBuffer(id);
-    frameBuffer->_handle = handle;
-    frameBuffer->_renderTargets = renderTargets;
-
-    // Add to the global list of managed frame buffers
-    __frameBuffers.push_back(frameBuffer);
-
-    return frameBuffer;
-}
-
-FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned int height)
-{
     // Create RenderTarget with same ID.
-    RenderTarget* renderTarget = RenderTarget::create(id, width, height);
+    RenderTarget* renderTarget = NULL;
+    renderTarget = RenderTarget::create(id, width, height);
     if (renderTarget == NULL)
     {
         GP_ERROR("Failed to create render target for frame buffer.");
         return NULL;
     }
 
-    // Create the frame buffer.
-    FrameBuffer* frameBuffer = create(id);
-    if (frameBuffer == NULL)
-    {
-        GP_ERROR("Failed to create frame buffer.");
-        return NULL;
-    }
+    // Create the frame buffer
+    GLuint handle = 0;
+    GL_ASSERT( glGenFramebuffers(1, &handle) );
+    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height);
+    frameBuffer->_handle = handle;
+    
+    // Create the render target array for the new frame buffer
+    RenderTarget** renderTargets = new RenderTarget*[__maxRenderTargets];
+    memset(renderTargets, 0, sizeof(RenderTarget*) * __maxRenderTargets);
+    frameBuffer->_renderTargets = renderTargets;
 
-    // Add the render target as the first color attachment.
-    frameBuffer->setRenderTarget(renderTarget);
-    SAFE_RELEASE(renderTarget);
+    frameBuffer->setRenderTarget(renderTarget, 0);
+
+    __frameBuffers.push_back(frameBuffer);
 
     return frameBuffer;
 }
@@ -113,7 +107,6 @@ FrameBuffer* FrameBuffer::getFrameBuffer(const char* id)
             return fb;
         }
     }
-
     return NULL;
 }
 
@@ -122,6 +115,16 @@ const char* FrameBuffer::getID() const
     return _id.c_str();
 }
 
+unsigned int FrameBuffer::getWidth() const
+{
+    return _width;
+}
+
+unsigned int FrameBuffer::getHeight() const
+{
+    return _height;
+}
+
 unsigned int FrameBuffer::getMaxRenderTargets()
 {
     if (__maxRenderTargets == 0)
@@ -134,7 +137,6 @@ unsigned int FrameBuffer::getMaxRenderTargets()
         __maxRenderTargets = 1;
 #endif
     }
-
     return __maxRenderTargets;
 }
 
@@ -165,10 +167,20 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 
         // Now set this target as the color attachment corresponding to index.
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
+        GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _renderTargets[index]->getTexture()->getHandle()) );
+        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) );
+        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) );
+        GL_ASSERT( glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
+        GL_ASSERT( glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
+        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL) );
         GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
-        GP_ASSERT(_renderTargets[index]->getTexture());
+        GP_ASSERT( _renderTargets[index]->getTexture() );
         GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, _renderTargets[index]->getTexture()->getHandle(), 0) );
-
+        GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+        if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
+        {
+            GP_ERROR("Framebuffer status incompleted: 0x%x", fboStatus);
+        }
         // Restore the FBO binding
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, currentFbo) );
     }
@@ -188,9 +200,7 @@ RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
 void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
 {
     if (_depthStencilTarget == target)
-    {
-        return; // No change
-    }
+        return;
 
     // Release our existing depth stencil target.
     SAFE_RELEASE(_depthStencilTarget);
@@ -208,17 +218,27 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
 
         // Now set this target as the color attachment corresponding to index.
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
+        
+        // Create a render buffer 
+        RenderBufferHandle renderBuffer = 0;
+        GL_ASSERT( glGenRenderbuffers(1, &renderBuffer) );
+        GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer) );
+        GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, _width, _height) );
+        GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer) );
+        // Attach the 
+        if (target->getFormat() == DepthStencilTarget::DEPTH_STENCIL)
+        {
+            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer) );
+        }
 
-        // Bind the depth texture.
-        GP_ASSERT(_depthStencilTarget);
-        GP_ASSERT(_depthStencilTarget->getTexture());
-        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthStencilTarget->getTexture()->getHandle(), 0) );
-
-        // If the taget has a stencil buffer, bind that as well
-        if (target->getFormat() == DepthStencilTarget::DEPTH24_STENCIL8)
+        // Check the framebuffer is good to go.
+        GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+        if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
         {
-            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_stencilBuffer) );
+            GP_ERROR("Framebuffer status incompleted: 0x%x", fboStatus);
         }
+        _depthStencilTarget->_renderBuffer = renderBuffer;
+
 
         // Restore the FBO binding
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, currentFbo) );
@@ -241,4 +261,9 @@ void FrameBuffer::bindDefault()
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultHandle) );
 }
 
+bool FrameBuffer::isPowerOfTwo(unsigned int value)
+{
+    return (value != 0) && ((value & (value - 1)) == 0);
+}
+
 }

+ 23 - 12
gameplay/src/FrameBuffer.h

@@ -24,17 +24,9 @@ class FrameBuffer : public Ref
 public:
 
     /**
-     * Creates an empty FrameBuffer and adds it to the list of available FrameBuffers.
-     *
-     * @param id The ID of the new FrameBuffer.  Uniqueness is recommended but not enforced.
-     *
-     * @return A newly created FrameBuffer.
-     */
-    static FrameBuffer* create(const char* id);
-
-    /**
-     * Creates a new FrameBuffer with a RenderTarget of the specified width and height,
+     * Creates a new FrameBuffer with a single RenderTarget of the specified width and height,
      * and adds the FrameBuffer to the list of available FrameBuffers.
+     * You can additionally add a DepthStencilTarget using FrameBuffer::setDepthStencilTarget.
      *
      * @param id The ID of the new FrameBuffer.  Uniqueness is recommended but not enforced.
      * @param width The width of the RenderTarget to be created and attached.
@@ -60,6 +52,20 @@ public:
      */
     const char* getID() const;
 
+    /**
+     * Gets the width of the frame buffer.
+     *
+     * @return The width of the frame buffer.
+     */
+    unsigned int getWidth() const;
+
+    /**
+     * Gets the height of the frame buffer.
+     *
+     * @return The height of the frame buffer.
+     */
+    unsigned int getHeight() const;
+
     /**
      * Get the number of color attachments available on the current hardware.
      *
@@ -109,11 +115,12 @@ public:
     static void bindDefault(); 
      
 private:
- 
+
+
     /**
      * Constructor.
      */
-    FrameBuffer(const char* id);
+    FrameBuffer(const char* id, unsigned int width, unsigned int height);
 
     /**
      * Destructor.
@@ -122,7 +129,11 @@ private:
 
     static void initialize();
 
+    static bool isPowerOfTwo(unsigned int value);
+
     std::string _id;
+    unsigned int _width;
+    unsigned int _height;
     FrameBufferHandle _handle;
     RenderTarget** _renderTargets;
     DepthStencilTarget* _depthStencilTarget;

+ 2 - 4
gameplay/src/Node.cpp

@@ -1079,19 +1079,17 @@ PhysicsCollisionObject* Node::setCollisionObject(Properties* properties)
 
 NodeCloneContext::NodeCloneContext()
 {
-    
 }
 
 NodeCloneContext::~NodeCloneContext()
 {
-
 }
 
 Animation* NodeCloneContext::findClonedAnimation(const Animation* animation)
 {
     GP_ASSERT(animation);
 
-    AnimationMap::iterator it = _clonedAnimations.find(animation);
+    std::map<const Animation*, Animation*>::iterator it = _clonedAnimations.find(animation);
     return it != _clonedAnimations.end() ? it->second : NULL;
 }
 
@@ -1107,7 +1105,7 @@ Node* NodeCloneContext::findClonedNode(const Node* node)
 {
     GP_ASSERT(node);
 
-    NodeMap::iterator it = _clonedNodes.find(node);
+    std::map<const Node*, Node*>::iterator it = _clonedNodes.find(node);
     return it != _clonedNodes.end() ? it->second : NULL;
 }
 

+ 2 - 6
gameplay/src/Node.h

@@ -823,12 +823,8 @@ private:
      */
     NodeCloneContext& operator=(const NodeCloneContext&);
 
-private:
-    typedef std::map<const Animation*, Animation*> AnimationMap;
-    typedef std::map<const Node*, Node*> NodeMap;
-
-    AnimationMap _clonedAnimations;
-    NodeMap _clonedNodes;
+    std::map<const Animation*, Animation*> _clonedAnimations;
+    std::map<const Node*, Node*> _clonedNodes;
 };
 
 }

+ 5 - 0
gameplay/src/Pass.cpp

@@ -54,6 +54,11 @@ void Pass::setVertexAttributeBinding(VertexAttributeBinding* binding)
     }
 }
 
+ VertexAttributeBinding* Pass::getVertexAttributeBinding() const
+ {
+     return _vaBinding;
+ }
+
 void Pass::bind()
 {
     GP_ASSERT(_effect);

+ 8 - 1
gameplay/src/Pass.h

@@ -41,7 +41,7 @@ public:
     const std::vector<std::string>* getAutoBindProperties() const;
 
     /**
-     * Stores a vertex attribute binding for this pass.
+     * Sets a vertex attribute binding for this pass.
      *
      * When a mesh binding is set, the VertexAttributeBinding will be automatically
      * bound when the bind() method is called for the pass.
@@ -50,6 +50,13 @@ public:
      */
     void setVertexAttributeBinding(VertexAttributeBinding* binding);
 
+    /**
+     * Sets a vertex attribute binding for this pass.
+     *
+     * @return The vertextu attribute binding for this pass.
+     */
+    VertexAttributeBinding* getVertexAttributeBinding() const;
+
     /**
      * Binds the render state for this pass.
      *

+ 5 - 12
gameplay/src/Texture.cpp

@@ -44,7 +44,7 @@ namespace gameplay
 
 static std::vector<Texture*> __textureCache;
 
-Texture::Texture() : _handle(0), _mipmapped(false), _cached(false), _compressed(false)
+Texture::Texture() : _handle(0), _format(RGBA), _width(0), _height(0), _mipmapped(false), _cached(false), _compressed(false)
 {
 }
 
@@ -159,32 +159,25 @@ Texture* Texture::create(Image* image, bool generateMipmaps)
 
 Texture* Texture::create(Format format, unsigned int width, unsigned int height, unsigned char* data, bool generateMipmaps)
 {
-    // Load our texture.
+    // Create and load the texture.
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
     GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
 
-    if (format == DEPTH)
-    {
-        // <type> must be UNSIGNED_SHORT or UNSIGNED_INT for a format of DEPTH_COMPONENT.
-        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_INT, data) );
-    }
-    else
-    {
-        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
-    }
 
     // Set initial minification filter based on whether or not mipmaping was enabled.
     GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, generateMipmaps ? GL_NEAREST_MIPMAP_LINEAR : GL_LINEAR) );
 
     Texture* texture = new Texture();
     texture->_handle = textureId;
+    texture->_format = format;
     texture->_width = width;
     texture->_height = height;
-
     if (generateMipmaps)
     {
         texture->generateMipmaps();
+        texture->_mipmapped = true;
     }
 
     return texture;

+ 18 - 8
gameplay/src/Texture.h

@@ -10,10 +10,6 @@ class Image;
 
 /**
  * Represents a texture.
- *
- * TODO: Addd support for the following: 
- * COMPRESSED_RGBA_ATITC = GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
- * COMPRESSED_RGBA_DXT1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
  */
 class Texture : public Ref
 {
@@ -28,8 +24,7 @@ public:
     {
         RGB     = GL_RGB,
         RGBA    = GL_RGBA,
-        ALPHA   = GL_ALPHA,
-        DEPTH   = GL_DEPTH_COMPONENT
+        ALPHA   = GL_ALPHA
     };
 
     /**
@@ -116,6 +111,7 @@ public:
     private:
 
         Sampler(Texture* texture);
+
         ~Sampler();
 
         Texture* _texture;
@@ -149,12 +145,23 @@ public:
     static Texture* create(Format format, unsigned int width, unsigned int height, unsigned char* data, bool generateMipmaps = false);
 
     /**
-     * Returns the texture width.
+     * Gets the format of the texture.
+     *
+     * @return The texture format.
+     */
+    Format getFormat() const;
+
+    /**
+     * Gets the texture width.
+     *
+     * @return The texture width.
      */
     unsigned int getWidth() const;
 
     /**
-     * Returns the texture height.
+     * Gets the texture height.
+     *
+     * @return The texture height.
      */
     unsigned int getHeight() const;
 
@@ -216,13 +223,16 @@ private:
     virtual ~Texture();
 
     static Texture* createCompressedPVRTC(const char* path);
+
     static Texture* createCompressedDDS(const char* path);
 
     static GLubyte* readCompressedPVRTC(const char* path, FILE* file, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
+
     static GLubyte* readCompressedPVRTCLegacy(const char* path, FILE* file, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
 
     std::string _path;
     TextureHandle _handle;
+    Format _format;
     unsigned int _width;
     unsigned int _height;
     bool _mipmapped;

+ 1 - 1
gameplay/src/gameplay.h

@@ -84,8 +84,8 @@
 #include "TextBox.h"
 #include "RadioButton.h"
 #include "Slider.h"
+#include "Joystick.h"
 #include "Layout.h"
 #include "AbsoluteLayout.h"
 #include "VerticalLayout.h"
-#include "Joystick.h"