Пример #1
0
 CallFuncN::CallFuncN(SELProtocol *t, SELECTOR_PTR s)
 : p_targetCallback(t)
 , p_selector(s)
 {
     FZ_ASSERT( p_targetCallback != NULL, "Selector must be non-NULL");
     FZ_ASSERT( p_selector != NULL, "Target must be non-NULL");
 }
Пример #2
0
    void AutoList::insert(fzListItem *position, fzListItem *newItem)
    {
        FZ_ASSERT(newItem != NULL, "New item cannot be NULL");

        if(position != NULL)
        {
            FZ_ASSERT(m_count > 0, "Strange bug: List is empty");
            
            // POSITION != NULL -> INSERT AT POSITION
            newItem->p_next = position;
            newItem->p_prev = position->p_prev;
            if(position->p_prev)
                position->p_prev->p_next = newItem;
            
            position->p_prev = newItem;

        }else
        {
            // POSITION == NULL -> PUSH_BACK
            if(p_back)
                p_back->p_next = newItem;
            
            newItem->p_prev = p_back;
            newItem->p_next = NULL;
            
            p_back = newItem;
        }
        if(newItem->p_prev == NULL)
            p_front = newItem;
        
        ++m_count;
    }
Пример #3
0
    void Director::runWithScene(Scene *scene)
    {
        FZ_ASSERT( scene != NULL, "Scene must be non-NULL");
        FZ_ASSERT( p_runningScene == NULL, "You can't run an scene if another Scene is running. Use replaceScene or pushScene instead");

        pushScene(scene);
    }
Пример #4
0
fzBuffer ResourcesManager::loadResource(const char *filename, fzUInt *outFactor) const
{
    FZ_ASSERT(filename != NULL, "Filename can not be NULL.");
    FZ_ASSERT(outFactor != NULL, "outFactor can not be NULL.");

    // REMOVING FORCED FLAGS
    char *filenameCpy = fzStrcpy(filename);
    IO::removeFileSuffix(filenameCpy);

    // LOOK FOR TEXTURE
    *outFactor = 0;
    char absolutePath[STRING_MAX_SIZE];
    fzUInt factor, priority = 0;

    while (getPath(filenameCpy, priority, absolutePath, &factor))
    {
        fzBuffer buffer = IO::loadFile(absolutePath);
        if(!buffer.isEmpty()) {
            *outFactor = factor;
            delete filenameCpy;
            return buffer;
        }
        ++priority;
    }

    FZLOGERROR("IO: \"%s\" not found.", filename);
    delete filenameCpy;
    return fzBuffer::empty();
}
Пример #5
0
 void MS::pop()
 {
     FZ_ASSERT(_initialized, "The matrix stack is not initialized.");
     FZ_ASSERT(_modelview_stack.num > 1, "Cannot pop an empty stack");
     
     --_modelview_stack.num;
 }
Пример #6
0
    void fzMath_mat4Vec4(const float* m1, const float* m2, float* mat)
    {
        FZ_ASSERT(m1 != NULL, "Input matrix 1 cannot be NULL.");
        FZ_ASSERT(m2 != NULL, "Input matrix 2 cannot be NULL.");
        FZ_ASSERT(mat != NULL, "Output pointer cannot be NULL.");
        
#if defined(__ARM_NEON__)
        
        _NEON_mat4Vec4(m1, m2, mat);
        
#else
        
        mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[12];
        mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[13];
        mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[14];
        
        mat[4] = m1[0] * m2[2] + m1[4] * m2[3] + m1[12];
        mat[5] = m1[1] * m2[2] + m1[5] * m2[3] + m1[13];
        mat[6] = m1[2] * m2[2] + m1[6] * m2[3] + m1[14];
        
        mat[8] = m1[0] * m2[4] + m1[4] * m2[5] + m1[12];
        mat[9] = m1[1] * m2[4] + m1[5] * m2[5] + m1[13];
        mat[10] = m1[2] * m2[4] + m1[6] * m2[5] + m1[14];
        
        mat[12] = m1[0] * m2[6] + m1[4] * m2[7] + m1[12];
        mat[13] = m1[1] * m2[6] + m1[5] * m2[7] + m1[13];
        mat[14] = m1[2] * m2[6] + m1[6] * m2[7] + m1[14];
        
#endif
    }
Пример #7
0
void ResourcesManager::_generateAbsolutePath(const char *filename, const char *suffix, char *absolutePath) const
{
    FZ_ASSERT(filename != NULL, "Filename can not be NULL.");
    FZ_ASSERT(absolutePath != NULL, "AbsolutePath must be a valid pointer.");

    if(suffix == NULL) {
        if(filename[0] == '/')
            strcpy(absolutePath, filename);
        else
            IO::appendPaths(p_resourcesPath, filename, absolutePath);

    } else {
        // GET EXTENSION
        const char *extension = strchr(filename, '.');
        if(extension == NULL)
            extension = filename + strlen(filename);

        // GET NAME
        size_t nameLength = extension - filename;
        char *name = fzStrcpy(filename, nameLength);

        // BUILD
        if(filename[0] == '/')
            sprintf(absolutePath, "%s%c%s%s", name, FZ_IO_SUBFIX_CHAR, suffix, extension);
        else
        {
            char relativePath[STRING_MAX_SIZE];
            sprintf(relativePath, "%s%c%s%s", name, FZ_IO_SUBFIX_CHAR, suffix, extension);
            IO::appendPaths(p_resourcesPath, relativePath, absolutePath);
        }

        delete [] name;
    }
}
Пример #8
0
    void fzMath_mat4Multiply(const float* m1, const float* m2, float* mat)
    {
        FZ_ASSERT(m1 != NULL, "Input matrix 1 cannot be NULL.");
        FZ_ASSERT(m2 != NULL, "Input matrix 2 cannot be NULL.");
        FZ_ASSERT(m1 != mat, "Input matrix and output matrix cannot be the same one.");

        
        mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
        mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
        mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
        mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
        
        mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
        mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
        mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
        mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
        
        mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
        mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
        mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
        mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
        
        mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
        mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
        mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
        mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
    }
Пример #9
0
    void Director::applicationLaunched(void *options)
    {
        FZ_ASSERT(m_isInitialized == false, "FORZE was already launched.")
        FZ_ASSERT(p_appdelegate, "FORZE was not initialized properly. App delegate is missing.");
        FZ_ASSERT(OSW::Instance(), "OS wrapper should call Director::applicationLaunching() before.");
        FZLOGINFO("Director: Application launched.");

        if(!m_isInitialized) {
            
            m_isInitialized = true;

            // initialize singletons
            DataStore::Instance();
            DeviceConfig::Instance().logDebugMode();
            DeviceConfig::Instance().logDeviceInfo();
            
            // set default GL values
            setDefaultGLValues();
            
            p_appdelegate->applicationLaunched(options);
            
            if(m_scenesStack.size() == 0)
            {
                FZLOGERROR("Director: A running scene is expected before applicationLaunched() is called.");
                FZLOGERROR("Director: You should call Director::Instance().runWithScene( <YOUR FORZE::SCENE> ).\n");
            }
            startAnimation();
        }
    }
Пример #10
0
 void MS::loadBaseMatrix(float *matrix)
 {
     FZ_ASSERT(_initialized, "The matrix stack is not initialized.");
     FZ_ASSERT(matrix != NULL, "Matrix cannot be NULL");
     
     _modelview_stack.stack[0] = matrix;
 }
Пример #11
0
    void fzMath_mat4Copy(const float* src, float* dst)
    {
        FZ_ASSERT(src != NULL, "Source matrix cannot be NULL.");
        FZ_ASSERT(dst != NULL, "Destination matrix cannot be NULL.");

        _inline_mat4Copy(src, dst);
    }
Пример #12
0
 CallFuncND::CallFuncND(SELProtocol *t, SELECTOR_2PTR s, void* d)
 : p_targetCallback(t)
 , p_selector(s)
 , p_pointer(d)
 {
     FZ_ASSERT( p_targetCallback != NULL, "Selector must be non-NULL");
     FZ_ASSERT( p_selector != NULL, "Target must be non-NULL");
 }
Пример #13
0
 void MS::loadMatrix(float *matrix)
 {
     FZ_ASSERT(_initialized, "The matrix stack is not initialized.");
     FZ_ASSERT(matrix != NULL, "Input matrix can not be NULL");
     FZ_ASSERT(_modelview_stack.num > 1, "Use MS::loadBaseMatrix() instead.");
     
     _modelview_stack.stack[_modelview_stack.num-1] = matrix;
 }
Пример #14
0
 void fzMath_mat4Vec4(const float* m1, const float* v1, float* vOut)
 {
     FZ_ASSERT(m1 != NULL, "Input matrix 1 cannot be NULL.");
     FZ_ASSERT(v1 != NULL, "Input matrix 2 cannot be NULL.");
     FZ_ASSERT(vOut != NULL, "Output vertices cannot be NULL.");
     
     _inline_mat4Vec4(m1, v1, vOut);
 }
Пример #15
0
 GLShader::GLShader(const char *source, GLenum type)
 : m_shaderType(type), m_shader(0)
 {
     FZ_ASSERT(m_shaderType == GL_VERTEX_SHADER || m_shaderType == GL_FRAGMENT_SHADER, "Invalid shader type");
     FZ_ASSERT(source != NULL, "Argumment must be non-NULL");
     
     if(!compileShader(source))
         FZ_RAISE("GLProgram: Error compiling shader.");
 }
Пример #16
0
    void Director::setClearColor(const fzColor4F& color)
    {
        FZ_ASSERT(color.r >= 0 && color.r <= 1.0f, "Red component is out of bounds [0, 1]");
        FZ_ASSERT(color.g >= 0 && color.g <= 1.0f, "Green component is out of bounds [0, 1]");
        FZ_ASSERT(color.b >= 0 && color.b <= 1.0f, "Blue component is out of bounds [0, 1]");
        FZ_ASSERT(color.a >= 0 && color.a <= 1.0f, "Alpha component is out of bounds [0, 1]");

        m_clearColor = color;
    }
Пример #17
0
    void fzMath_mat4MultiplySafe(const float* m1, const float* m2, float* mOut)
    {
        FZ_ASSERT(m1 != NULL, "Input matrix 1 cannot be NULL.");
        FZ_ASSERT(m2 != NULL, "Input matrix 2 cannot be NULL.");
        FZ_ASSERT(mOut != NULL, "Output matrix cannot be NULL.");
        FZ_ASSERT(m1 != mOut, "Input and output can not have the same pointer.");

        _inline_mat4MultiplySafe(m1, m2, mOut);
    }
Пример #18
0
    Event* EventManager::addEvent(const Event& newEvent)
    {
        FZ_ASSERT(newEvent.getOwner(), "Event owner can not be NULL.");

        if(!(newEvent.getType() & m_flags))
            return NULL;
            
        switch (newEvent.getState())
        {
            case kFZEventState_Began:
#if FORZE_DEBUG > 0
            {
                eventList::const_iterator it(m_events.begin());
                for(; it != m_events.end(); ++it) {
                    if(newEvent.getIdentifier() == it->getIdentifier() &&
                       newEvent.getOwner() == it->getOwner())
                    {
                        FZLOGERROR("EventManager: Event duplicated:");
                        it->log();
                    }
                }
            }
#endif
            case kFZEventState_Indifferent:
            {
                FZ_ASSERT(newEvent.getDelegate() == NULL, "Event delegate should be NULL.");
                m_events.push_back(newEvent);
                return &(m_events.back());
            }
            case kFZEventState_Updated:
            case kFZEventState_Ended:
            case kFZEventState_Cancelled:
            {
                eventList::iterator it(m_events.begin());
                for(; it != m_events.end(); ++it) {
                    Event *e = &(*it);
                    if(newEvent.getIdentifier() == e->getIdentifier() &&
                       newEvent.getOwner() == e->getOwner() &&
                       newEvent.getType() == e->getType())
                    {
                        e->update(newEvent);
                        return e;
                    }
                }
                return NULL;
            }
            default:
            {
                FZ_ASSERT(false, "Invalid event state.");
                return NULL;
            }
        }
    }
Пример #19
0
void Grabber::begin()
{
    FZ_ASSERT(m_fbo != 0, "FBO is uninitilialez, you must grab a texture first.");
    FZ_ASSERT(m_oldFBO == -1, "This FBO is already opened");

    // cache current framebuffer
    m_oldFBO = fzGLGetFramebuffer();

    // bind FBO
    fzGLBindFramebuffer(m_fbo);

    CHECK_GL_ERROR_DEBUG();
}
Пример #20
0
 void MS::pushMatrix(float *matrix)
 {
     FZ_ASSERT(_initialized, "The matrix stack is not initialized.");
     FZ_ASSERT(matrix != NULL, "Matrix cannot be NULL");
     
     _modelview_stack.stack[_modelview_stack.num++] = matrix;
     
     if(_modelview_stack.num >= _modelview_stack.capacity)
     {
         _modelview_stack.capacity += STACK_INCREMENT;
         realloc(_modelview_stack.stack, _modelview_stack.capacity * sizeof(float*));
     }
 }
Пример #21
0
 bool MenuItem::event(Event& event)
 {
     FZ_ASSERT(event.isType(kFZEventType_Tap), "Event is a touch event");
     
     if(!isVisible())
         return false;
     
     switch (event.getState())
     {
         case kFZEventState_Began:
         {
             if( !m_isWaiting || !isVisible() )
                 return false;
             
             if(getBoundingBox().contains(event.getPoint())) {
                 selected();
                 m_isWaiting = false;
                 return true;
             }
             break;
         }
         case kFZEventState_Updated:
         {
             FZ_ASSERT(!m_isWaiting, "[Event updated] -- invalid state");
             
             bool isSelected = getBoundingBox().contains(event.getPoint());
             if (isSelected != m_isSelected) {
                 if(isSelected)
                     selected();
                 else
                     unselected();
             }
             
             break;
         }
         case kFZEventState_Ended:
             if(m_isSelected)
                 activate();
             
         case kFZEventState_Cancelled:
             if(m_isSelected)
                 unselected();
             
             m_isWaiting = true;
             
             break;
         default: break;
     }
     
     return false;
 }
Пример #22
0
 void Director::applicationLaunching(void *OSWrapper)
 {
     FZ_ASSERT(p_appdelegate, "FORZE was not initialized properly. App delegate is missing.");
     FZ_ASSERT(OSW::p_oswrapper == NULL, "OS Wrapper already initialized.");
     FZ_ASSERT(OSWrapper, "OS Wrapper can not be NULL");
     
     FZLOGINFO("Director: Application launching.");
     OSW::setInstance(OSWrapper);
     
     // GET OPENGL CONFIG
     m_glConfig = p_appdelegate->fzGLConfig();
     
     // GLConfig::validate() will throw an exception if the configuration is invalid.
     m_glConfig.validate();
 }
Пример #23
0
 Speed::Speed(Action *a, fzFloat s)
 : p_innerAction(a)
 , m_speed(s)
 {
     FZ_ASSERT(p_innerAction != NULL, "ActionInterval cannot be NULL.");
     p_innerAction->retain();
 }
Пример #24
0
void Grabber::grab(Texture2D* texture)
{
    FZ_ASSERT(texture, "Texture can not be NULL");

    FZRETAIN_TEMPLATE(texture, p_texture);

    // generate FBO
    if(m_fbo == 0)
        fzGLGenFramebuffers(1, &m_fbo);

    // cache current framebuffer
    m_oldFBO = fzGLGetFramebuffer();

    // bind FBO
    fzGLBindFramebuffer(m_fbo);

    // associate texture with FBO
    fzGLFramebufferTexture2D(FZ_FRAMEBUFFER, FZ_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture->getName(), 0);

    // check if it worked
    GLuint status = fzGLCheckFramebufferStatus(FZ_FRAMEBUFFER);
    if (status != FZ_FRAMEBUFFER_COMPLETE) {
        FZLOGERROR("Grabber: Could not attach texture to framebuffer. Status: 0x%04X.", status);
    }

    fzGLClearColor(fzColor4F(0,0,0,0));
    glClear(GL_COLOR_BUFFER_BIT);

    fzGLBindFramebuffer(m_oldFBO);
    m_oldFBO = -1;

    CHECK_GL_ERROR_DEBUG();
}
Пример #25
0
    void fzMath_mat4PerspectiveProjection(fzFloat fovY, fzFloat aspect,
                                          fzFloat zNear, fzFloat zFar,
                                          float *output)
    {        
        FZ_ASSERT(output != NULL, "Output matrix cannot be NULL.");

        fzFloat r = FZ_DEGREES_TO_RADIANS(fovY / 2);
        fzFloat deltaZ = zFar - zNear;
        fzFloat s = fzMath_sin(r);
        fzFloat cotangent = 0;
        
        if (deltaZ == 0 || s == 0 || aspect == 0) {
            FZLOGERROR("Perpertive impossible.");
            return;
        }
        
        cotangent = fzMath_cos(r) / s;
        
        fzMath_mat4Identity(output);
        output[0] = cotangent / aspect;
        output[5] = cotangent;
        output[10] = -(zFar + zNear) / deltaZ;
        output[11] = -1;
        output[14] = -2 * zNear * zFar / deltaZ;
        output[15] = 0;
    }
Пример #26
0
    void Sprite::draw()
    {
        FZ_ASSERT(m_mode == kFZSprite_SelfRendering, "If Sprite is being rendered by SpriteBatch, Sprite::draw SHOULD NOT be called.");

        // Bind texture
        fzGLSetMode(kFZGLMode_TextureNoColor);
        if(mode.A.p_texture)
            mode.A.p_texture->bind();
        
        fzGLBlendFunc( m_blendFunc );
        
#if FZ_GL_SHADERS
        
        p_glprogram->use();
        p_glprogram->setUniform4f(kFZUniformColor_s, m_color.r/255.0f, m_color.g/255.0f, m_color.b/255.0f, (m_cachedOpacity * m_alpha)/255.0f);
        
        // atributes
        glVertexAttribPointer(kFZAttribTexCoords, 2, GL_FLOAT, GL_FALSE, 0, m_texCoords);
        glVertexAttribPointer(kFZAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(fzVec4), mode.A.m_finalVertices);
        
#else
        glLoadIdentity();
        
        // atributes
        fzGLColor(m_color);
        glVertexPointer(3, GL_FLOAT, sizeof(fzVec4), mode.A.m_finalVertices);	
        glTexCoordPointer(2, GL_FLOAT, 0, m_texCoords);
#endif
        
        // Rendering
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);	
    }
Пример #27
0
 fzBuffer IO::loadFile(const char *absolutePath)
 {
     FZ_ASSERT(absolutePath, "Absolute path cannot be NULL.");
     if(absolutePath[0] == '\0')
         return fzBuffer::empty();
     
     FILE *f = fopen(absolutePath, "rb");
     if( f == NULL )
         return fzBuffer::empty();
     
     
     fseek(f, 0, SEEK_END);
     size_t size = ftell(f);
     fseek(f, 0, SEEK_SET);
     
     
     char *buffer = new(std::nothrow) char[size+1];
     if(buffer == NULL) {
         fclose(f);
         FZLOGERROR("IO: Impossible to allocate memory.");
         return fzBuffer::empty();
     }
     size_t read = fread(buffer, 1, size, f);
     fclose(f);
     if( read != size ) {
         FZLOGERROR("IO: Abnormal reading error. Probably the path is not a file.");
         delete [] buffer;
         return fzBuffer::empty();
     }
     // NULL TERMINATED
     buffer[size] = '\0';
     
     return fzBuffer(buffer, size+1);
 }
Пример #28
0
    void Sprite::insertChild(Node *child)
    {
#if FZ_SPRITE_CHILDREN
        FZ_ASSERT(dynamic_cast<Sprite*>(child), "Child should be a sprite.");
        
        Node::insertChild(child);
        
        if(m_mode == kFZSprite_BatchRendering) {
            Sprite *sprite = static_cast<Sprite*>(child);
            sprite->useBatchRender(mode.B.p_batchNode);
        }
#else
        (void)child;
        FZ_ASSERT(false, "Children in Sprite are disabled. Set FZ_SPRITE_CHILDREN 1.");
#endif
    }
Пример #29
0
    bool Menu::event(Event& event)
    {
        if(!event.isType(kFZEventType_Tap))
            return false;
        
        fzPoint point = event.getPoint();
        
        switch (event.getState())
        {
            case kFZEventState_Began:
            {
                if( m_isWaiting == false || !isVisible() )
                    return false;
                
                p_selectedItem = itemForPosition(point);
                
                if( p_selectedItem ) {
                    p_selectedItem->selected();
                    m_isWaiting = false;

                    return true;
                }
                
                break;
            }
            case kFZEventState_Updated:
            {
                FZ_ASSERT(!m_isWaiting, "[Event updated] -- invalid state.");
                
                MenuItem *currentItem = itemForPosition(point);
                
                if (currentItem != p_selectedItem) {
                    if(p_selectedItem)
                        p_selectedItem->unselected();
                        
                    p_selectedItem = currentItem;
                        
                    if(p_selectedItem)
                        p_selectedItem->selected();
                }
                
                break;
            }
            case kFZEventState_Ended:
                if(p_selectedItem)
                    p_selectedItem->activate();
                
            case kFZEventState_Cancelled:
                if(p_selectedItem)
                    p_selectedItem->unselected();
                
                m_isWaiting = true;
                
                break;
            default: break;
        }
        
        return false;
    }
Пример #30
0
    bool Director::drawScene()
    {   
        // CALCULATE DELTA TIME
        calculateDeltaTime();

        // DISPATCH EVENTS
        EventManager::Instance().dispatchEvents();
        
        // SCHEDULE
        if(!m_isPaused) {
            Scheduler::Instance().tick( m_dt );
            ActionManager::Instance().update( m_dt );
        }
        
        if(m_dirtyFlags)
            updateProjection();

        if(p_nextScene)
            setNextScene();
        

        // RENDERING
#if FZ_RENDER_ON_DEMAND
        bool newContent = m_sceneIsDirty;
        if(m_sceneIsDirty) {
#endif
            
#if !FZ_GL_SHADERS
            glLoadIdentity();
#endif
            MS::loadBaseMatrix(m_transformMV);
            
            // CLEAR OPENGL BUFFERS
            fzGLClearColor(m_clearColor);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            
            if(p_runningScene) {
                p_runningScene->internalVisit();
                CHECK_GL_ERROR_DEBUG();
            }
            
            FZ_ASSERT(MS::getLevel() == 1, "A matrix hasn't been popped. Review the push/pop code.");
        
            // SHOW FPS
            if( m_displayFPS )
                showFPS();
            
#if FZ_RENDER_ON_DEMAND
            m_sceneIsDirty = false;
        }
#endif
        PerformManager::Instance().clean();
        
#if FZ_RENDER_ON_DEMAND
        return newContent;
#else
        return true;
#endif
    }