From f0a262f511762f472ad81cd4e200073b63342a25 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 30 Oct 2013 17:03:59 -0700 Subject: [PATCH 01/98] Add AppCode project files to ignore list --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d6bae12eb7..df2eae5950 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,9 @@ xcschememanagement.plist xcuserdata/ DerivedData/ +# Ignore files build by AppCode +.idea + # Ignore files built by bada .Simulator-Debug/ .Target-Debug/ From e4ffd250cbaa73315219c148614a8100d5e35bad Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 4 Nov 2013 09:14:22 -0800 Subject: [PATCH 02/98] Simple implementation of RenderCommand and RenderQueue --- .../project.pbxproj.REMOVED.git-id | 2 +- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCDirector.cpp | 3 + cocos/2d/CCNewSprite.cpp | 56 ++++++++++ cocos/2d/CCNewSprite.h | 32 ++++++ cocos/2d/CCSprite.cpp | 6 + cocos/2d/CCSprite.h | 1 + cocos/2d/renderer/RenderCommand.cpp | 73 +++++++++++++ cocos/2d/renderer/RenderCommand.h | 64 +++++++++++ cocos/2d/renderer/Renderer.cpp | 103 ++++++++++++++++++ cocos/2d/renderer/Renderer.h | 39 +++++++ .../NewRendererTest/NewRendererTest.cpp | 80 ++++++++++++++ .../Classes/NewRendererTest/NewRendererTest.h | 35 ++++++ samples/Cpp/TestCpp/Classes/controller.cpp | 1 + samples/Cpp/TestCpp/Classes/tests.h | 1 + 15 files changed, 496 insertions(+), 2 deletions(-) create mode 100644 cocos/2d/CCNewSprite.cpp create mode 100644 cocos/2d/CCNewSprite.h create mode 100644 cocos/2d/renderer/RenderCommand.cpp create mode 100644 cocos/2d/renderer/RenderCommand.h create mode 100644 cocos/2d/renderer/Renderer.cpp create mode 100644 cocos/2d/renderer/Renderer.h create mode 100644 samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp create mode 100644 samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 4b66f8ecfe..563be79011 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -2fc86c9b16a099b711aabd5d29f835c45a1690a4 \ No newline at end of file +66497ec4f15de06d504b96da6ade60c7ad59ab44 \ No newline at end of file diff --git a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id index 3a1978b2ff..d7be8e0208 100644 --- a/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_samples.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -3cdc74655a14f57ae21036886ccf31e32aaadce4 \ No newline at end of file +65080d3ab5537396ff8b5ae41bfa1f9ac837c8c8 \ No newline at end of file diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index ef8b38f423..3e740e768d 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -60,6 +60,7 @@ THE SOFTWARE. #include "CCEGLView.h" #include "CCConfiguration.h" #include "CCEventDispatcher.h" +#include "Renderer.h" /** Position of the FPS @@ -274,6 +275,8 @@ void Director::drawScene() showStats(); } + Renderer::getInstance()->render(); + kmGLPopMatrix(); _totalFrames++; diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp new file mode 100644 index 0000000000..e259a7b27f --- /dev/null +++ b/cocos/2d/CCNewSprite.cpp @@ -0,0 +1,56 @@ +// +// CCNewSprite.cpp +// cocos2d_libs +// +// Created by NiTe Luo on 10/31/13. +// +// + +#include "CCNewSprite.h" +#include "RenderCommand.h" +#include "Renderer.h" + +NS_CC_BEGIN + +NewSprite* NewSprite::create() +{ + NewSprite* sprite = new NewSprite(); + if(sprite && sprite->init()) + { + sprite->autorelease(); + return sprite; + } + CC_SAFE_DELETE(sprite); + return NULL; +} + +NewSprite* NewSprite::create(const char *filename) +{ + NewSprite* sprite = new NewSprite(); + if(sprite && sprite->initWithFile(filename)) + { + sprite->autorelease(); + return sprite; + } + CC_SAFE_DELETE(sprite); + return NULL; +} + +NewSprite::NewSprite() +:Sprite() +{ + +} + +void NewSprite::draw(void) +{ + kmMat4 transform; + kmGLGetMatrix(KM_GL_MODELVIEW, &transform); + RenderCommand* renderCommand = new RenderCommand(); + renderCommand->setData(0, true, false, _ZOrder); + renderCommand->setQuadData(&transform, _quad, _texture->getName(), 0, 0); + + Renderer::getInstance()->addRenderCommand(renderCommand); +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h new file mode 100644 index 0000000000..e152b0d0fc --- /dev/null +++ b/cocos/2d/CCNewSprite.h @@ -0,0 +1,32 @@ +// +// CCNewSprite.h +// cocos2d_libs +// +// Created by NiTe Luo on 10/31/13. +// +// + +#ifndef __CCNEWSPRITE_H_ +#define __CCNEWSPRITE_H_ + +#include "CCSprite.h" +#include "CCPlatformMacros.h" + +NS_CC_BEGIN + +class NewSprite : public Sprite +{ + +public: + static NewSprite* create(); + static NewSprite* create(const char *filename); + + NewSprite(void); + virtual void draw(void) override; + +protected: +}; + +NS_CC_END + +#endif /* defined(__CCNEWSPRITE_H_) */ diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 676138d9b1..91228edf49 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -791,6 +791,12 @@ void Sprite::setPosition(const Point& pos) SET_DIRTY_RECURSIVELY(); } +void Sprite::setPosition(float x, float y) +{ + Node::setPosition(x, y); + SET_DIRTY_RECURSIVELY(); +} + void Sprite::setRotation(float rotation) { Node::setRotation(rotation); diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index cc6470c7da..2dd53438c7 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -499,6 +499,7 @@ public: * @lua NA */ virtual void setPosition(const Point& pos) override; + virtual void setPosition(float x, float y) override; virtual void setRotation(float rotation) override; virtual void setRotationX(float rotationX) override; virtual void setRotationY(float rotationY) override; diff --git a/cocos/2d/renderer/RenderCommand.cpp b/cocos/2d/renderer/RenderCommand.cpp new file mode 100644 index 0000000000..dc99e0670e --- /dev/null +++ b/cocos/2d/renderer/RenderCommand.cpp @@ -0,0 +1,73 @@ +// +// Created by NiTe Luo on 10/31/13. +// + + +#include "RenderCommand.h" + +NS_CC_BEGIN + +RenderCommand::RenderCommand() +:_viewport(0) +,_isTranslucent(false) +,_isCommand(false) +,_depth(0) +,_materialID(0) +{ + +} + +void RenderCommand::generateID() +{ + _renderCommandId = 0; + + _renderCommandId = (int64_t)_viewport << 61 + | (int64_t)_isTranslucent << 60 + | (int64_t)_isCommand << 59 + | (int64_t)_depth << 35 + | (int64_t)_materialID << 11; +} + +void printBits(size_t const size, void const * const ptr) +{ + unsigned char *b = (unsigned char*) ptr; + unsigned char byte; + int i, j; + + for (i=size-1;i>=0;i--) + { + for (j=7;j>=0;j--) + { + byte = b[i] & (1<>= j; + printf("%u", byte); + } + } + puts(""); +} + +void RenderCommand::printID() +{ + printf("CommandID: "); + printBits(sizeof(_renderCommandId), &_renderCommandId); + printf("\n"); +} + +void RenderCommand::setData(int viewport, bool isTranslucent, bool isCommand, int32_t depth) +{ + _viewport = viewport; + _isTranslucent = isTranslucent; + _isCommand = isCommand; + _depth = depth; +} + +void RenderCommand::setQuadData(kmMat4 *transform, V3F_C4B_T2F_Quad quad, GLuint textureID, int shaderID, int blendType) +{ + kmMat4Assign(&_transform, transform); + _quad = quad; + _textureID = textureID; + _shaderID = shaderID; + _blendType = blendType; +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h new file mode 100644 index 0000000000..7ffc599090 --- /dev/null +++ b/cocos/2d/renderer/RenderCommand.h @@ -0,0 +1,64 @@ +// +// Created by NiTe Luo on 10/31/13. +// + + + +#ifndef __CCRENDERCOMMAND_H_ +#define __CCRENDERCOMMAND_H_ + +#include "CCPlatformMacros.h" +#include +#include "ccTypes.h" +#include "kazmath/GL/matrix.h" + +NS_CC_BEGIN + +class RenderCommand +{ +public: + + RenderCommand(); + void setData(int viewport, bool isTranslucent, bool isCommand, int32_t depth); + void setQuadData(kmMat4* transform, V3F_C4B_T2F_Quad quad, GLuint textureID, int shaderID, int blendType); + + void generateID(); + + /** + * Get Render Command Id + */ + inline int64_t getID() { return _renderCommandId; } + inline bool isTranslucent() { return _isTranslucent; } + inline bool isCommand() { return _isCommand; } + inline int32_t getMaterialID() { return _materialID; } + + inline GLuint getTextureID() { return _textureID; } + inline kmMat4* getTransform() { return &_transform; } + inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } + inline int getShaderID() { return _shaderID; } + inline int getBlendType() { return _blendType; } + +protected: + void printID(); + +protected: + //Generated IDs + int64_t _renderCommandId; /// used for sorting render commands + int32_t _materialID; + + //Data + int _viewport; /// Which view port it belongs to + bool _isTranslucent; /// Is it translucent, if it is we will have to render it + bool _isCommand; + int32_t _depth; + + kmMat4 _transform; + V3F_C4B_T2F_Quad _quad; + GLuint _textureID; + int _shaderID; + int _blendType; +}; + +NS_CC_END + +#endif //__CCRENDERCOMMAND_H_ diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp new file mode 100644 index 0000000000..9de4827e73 --- /dev/null +++ b/cocos/2d/renderer/Renderer.cpp @@ -0,0 +1,103 @@ +// +// Created by NiTe Luo on 10/31/13. +// + + +#include "Renderer.h" + +#include "CCGL.h" +#include "ccMacros.h" +#include "CCShaderCache.h" +#include "ccGLStateCache.h" +#include "CCGLProgram.h" + +NS_CC_BEGIN +using namespace std; + +static Renderer* s_renderer; + +Renderer *Renderer::getInstance() +{ + if(!s_renderer) + { + s_renderer = new Renderer(); + } + return s_renderer; +} + +Renderer::Renderer() +:_currentMaterialID(0) +{ + _shaderProgram = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR); +} + +void Renderer::setOpenGLView(EGLView *newOpenGLView) +{ + //TODO move render related logic to render + _openGLView = newOpenGLView; +} + +void Renderer::addRenderCommand(RenderCommand *command) +{ + command.generateID(); + _renderQueue.push_back(command); +} + +void Renderer::render() +{ + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //Process render commands + //1. Sort render commands based on ID +// stable_sort(_renderQueue.begin(), _renderQueue.end()); +// sort(_renderQueue.begin(), _renderQueue.end()); + + //2. Process commands + for(vector::iterator it = _renderQueue.begin(); it != _renderQueue.end(); ++it) + { + //TODO: Perform Sprite batching here + auto command = *it; + + //Transform + kmGLMatrixMode(KM_GL_MODELVIEW); + kmGLLoadMatrix(command->getTransform()); + + //Set Shader + _shaderProgram->use(); + _shaderProgram->setUniformsForBuiltins(); + + //Set Blend Mode + //Set texture + GL::bindTexture2D(command->getTextureID()); + GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); + +#define kQuadSize sizeof(command->getQuad()->bl) + long offset = (long)command->getQuad(); + + // vertex + int diff = offsetof( V3F_C4B_T2F, vertices); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); + + // texCoods + diff = offsetof( V3F_C4B_T2F, texCoords); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); + + // color + diff = offsetof( V3F_C4B_T2F, colors); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); + + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + CHECK_GL_ERROR_DEBUG(); + CC_INCREMENT_GL_DRAWS(1); + + kmGLLoadIdentity(); + + delete command; + } + + _renderQueue.clear(); +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h new file mode 100644 index 0000000000..65048f06b1 --- /dev/null +++ b/cocos/2d/renderer/Renderer.h @@ -0,0 +1,39 @@ +// +// Created by NiTe Luo on 10/31/13. +// + + + +#ifndef __CCRENDERER_H_ +#define __CCRENDERER_H_ + +#include "CCPlatformMacros.h" +#include "CCEGLView.h" +#include "RenderCommand.h" +#include "CCGLProgram.h" + +NS_CC_BEGIN +using namespace std; + +class Renderer +{ +public: + static Renderer* getInstance(); + + void setOpenGLView(EGLView *newOpenGLView); + void addRenderCommand(RenderCommand* commnad); + void render(); + +protected: + Renderer(); + +protected: + EGLView* _openGLView; + vector _renderQueue; + GLProgram* _shaderProgram; + int _currentMaterialID; +}; + +NS_CC_END + +#endif //__CCRENDERER_H_ diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp new file mode 100644 index 0000000000..66d6e3eb00 --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -0,0 +1,80 @@ +// +// Created by NiTe Luo on 11/1/13. +// + + +#include "NewRendererTest.h" +#include "CCNewSprite.h" + + +NewRendererTest::NewRendererTest() +{ + auto touchListener = EventListenerTouchAllAtOnce::create(); + touchListener->onTouchesEnded = CC_CALLBACK_2(NewRendererTest::onTouchesEnded, this); + + createSpriteTest(); + createNewSpriteTest(); +} + +NewRendererTest::~NewRendererTest() +{ + +} + +void NewRendererTest::createSpriteTest() +{ + Size winSize = Director::getInstance()->getWinSize(); + + Sprite* parent = Sprite::create("Images/grossini.png"); + parent->setPosition(winSize.width/3, winSize.height/2); + Sprite* child1 = Sprite::create("Images/grossinis_sister1.png"); + child1->setPosition(0.0f, -20.0f); + Sprite* child2 = Sprite::create("Images/grossinis_sister2.png"); + child2->setPosition(20.0f, -20.0f); + Sprite* child3 = Sprite::create("Images/grossinis_sister1.png"); + child3->setPosition(40.0f, -20.0f); + Sprite* child4 = Sprite::create("Images/grossinis_sister2.png");\ + child4->setPosition(60.0f, -20.0f); + + parent->addChild(child1); + parent->addChild(child2); + parent->addChild(child3); + parent->addChild(child4); + addChild(parent); +} + +void NewRendererTest::createNewSpriteTest() +{ + Size winSize = Director::getInstance()->getWinSize(); + + NewSprite* parent = NewSprite::create("Images/grossini.png"); + parent->setPosition(winSize.width*2/3, winSize.height/2); + NewSprite* child1 = NewSprite::create("Images/grossinis_sister1.png"); + child1->setPosition(0.0f, -20.0f); + NewSprite* child2 = NewSprite::create("Images/grossinis_sister2.png"); + child2->setPosition(20.0f, -20.0f); + NewSprite* child3 = NewSprite::create("Images/grossinis_sister1.png"); + child3->setPosition(40.0f, -20.0f); + NewSprite* child4 = NewSprite::create("Images/grossinis_sister2.png"); + child4->setPosition(60.0f, -20.0f); + + parent->addChild(child1); + parent->addChild(child2); + parent->addChild(child3); + parent->addChild(child4); + addChild(parent); +} + +void NewRendererTest::onTouchesEnded(const std::vector &touches, Event *event) +{ + +} + +void NewRendererTestScene::runThisTest() +{ + auto layer = new NewRendererTest(); + addChild(layer); + + Director::getInstance()->replaceScene(this); + layer->release(); +} diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h new file mode 100644 index 0000000000..5a568bc621 --- /dev/null +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -0,0 +1,35 @@ +// +// Created by NiTe Luo on 11/1/13. +// + + + +#ifndef __NewRendererTest_H_ +#define __NewRendererTest_H_ + +#include "cocos2d.h" +#include "../testBasic.h" +#include "../BaseTest.h" + +class NewRendererTest : public Layer +{ +public: + NewRendererTest(); + ~NewRendererTest(); + + void createSpriteTest(); + void createNewSpriteTest(); + void onTouchesEnded(const std::vector& touches, Event* event); + +protected: + +}; + +class NewRendererTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + + +#endif //__NewRendererTest_H_ diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index 32051bbd1b..62071397bf 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -14,6 +14,7 @@ struct { const char *test_name; std::function callback; } g_aTestNames[] = { + { "NewRenderTest", []() { return new NewRendererTestScene(); } }, { "Accelerometer", []() { return new AccelerometerTestScene(); } }, { "ActionManagerTest", [](){return new ActionManagerTestScene(); } }, { "ActionsEaseTest", [](){return new ActionsEaseTestScene();} }, diff --git a/samples/Cpp/TestCpp/Classes/tests.h b/samples/Cpp/TestCpp/Classes/tests.h index b119f69de1..6e2a5a9cd0 100644 --- a/samples/Cpp/TestCpp/Classes/tests.h +++ b/samples/Cpp/TestCpp/Classes/tests.h @@ -1,6 +1,7 @@ #ifndef _TESTS_H_ #define _TESTS_H_ +#include "NewRendererTest/NewRendererTest.h" #include "NewEventDispatcherTest/NewEventDispatcherTest.h" #include "ActionsTest/ActionsTest.h" #include "TransitionsTest/TransitionsTest.h" From 51fb1edc0cc57bf9c1a541bd63fdfa146d533fea Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 5 Nov 2013 17:00:34 -0800 Subject: [PATCH 03/98] Fix sorting bug --- cocos/2d/renderer/Renderer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 9de4827e73..683c4a4b76 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -39,17 +39,22 @@ void Renderer::setOpenGLView(EGLView *newOpenGLView) void Renderer::addRenderCommand(RenderCommand *command) { - command.generateID(); + command->generateID(); _renderQueue.push_back(command); } +bool compareRenderCommand(RenderCommand* a, RenderCommand* b) +{ + return a->getID() < b->getID(); +} + void Renderer::render() { //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Process render commands //1. Sort render commands based on ID -// stable_sort(_renderQueue.begin(), _renderQueue.end()); + stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); // sort(_renderQueue.begin(), _renderQueue.end()); //2. Process commands From 3108d499e5a4ed0a7c58d08c295056542614928a Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 6 Nov 2013 14:24:56 -0800 Subject: [PATCH 04/98] use placeholder logic to generate material id --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCNewSprite.cpp | 5 +- cocos/2d/ccTypes.h | 10 +++ cocos/2d/renderer/MaterialManager.cpp | 87 +++++++++++++++++++ cocos/2d/renderer/MaterialManager.h | 50 +++++++++++ cocos/2d/renderer/QuadCommand.cpp | 6 ++ cocos/2d/renderer/QuadCommand.h | 32 +++++++ cocos/2d/renderer/RenderCommand.cpp | 46 +++++++++- cocos/2d/renderer/RenderCommand.h | 29 +++++-- cocos/2d/renderer/RenderMaterial.cpp | 6 ++ cocos/2d/renderer/RenderMaterial.h | 17 ++++ 11 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 cocos/2d/renderer/MaterialManager.cpp create mode 100644 cocos/2d/renderer/MaterialManager.h create mode 100644 cocos/2d/renderer/QuadCommand.cpp create mode 100644 cocos/2d/renderer/QuadCommand.h create mode 100644 cocos/2d/renderer/RenderMaterial.cpp create mode 100644 cocos/2d/renderer/RenderMaterial.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 563be79011..3a7bf34522 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -66497ec4f15de06d504b96da6ade60c7ad59ab44 \ No newline at end of file +a8deccd72bda63a9abc1fd55c4812468dc021fa8 \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index e259a7b27f..77c33318ff 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -47,8 +47,9 @@ void NewSprite::draw(void) kmMat4 transform; kmGLGetMatrix(KM_GL_MODELVIEW, &transform); RenderCommand* renderCommand = new RenderCommand(); - renderCommand->setData(0, true, false, _ZOrder); - renderCommand->setQuadData(&transform, _quad, _texture->getName(), 0, 0); + renderCommand->setKeyData(0, true, false, _ZOrder); + renderCommand->setMaterialData(_texture->getName(), _shaderProgram->getProgram(), _blendFunc); + renderCommand->setQuadData(&transform, _quad); Renderer::getInstance()->addRenderCommand(renderCommand); } diff --git a/cocos/2d/ccTypes.h b/cocos/2d/ccTypes.h index f7bb8d19cb..2e6d1846af 100644 --- a/cocos/2d/ccTypes.h +++ b/cocos/2d/ccTypes.h @@ -329,6 +329,16 @@ struct BlendFunc const static BlendFunc ALPHA_NON_PREMULTIPLIED; //! Enables Additive blending. Uses {GL_SRC_ALPHA, GL_ONE} const static BlendFunc ADDITIVE; + + bool const operator==(const BlendFunc &a) + { + return src == a.src && dst == a.dst; + } + + bool const operator<(const BlendFunc &a) + { + return src < a.src || (src < a.src && dst < a.dst); + } }; // Label::VAlignment diff --git a/cocos/2d/renderer/MaterialManager.cpp b/cocos/2d/renderer/MaterialManager.cpp new file mode 100644 index 0000000000..c5ec115cfb --- /dev/null +++ b/cocos/2d/renderer/MaterialManager.cpp @@ -0,0 +1,87 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + +#include "MaterialManager.h" + +NS_CC_BEGIN + +using namespace std; + +static MaterialManager* s_instance = 0; + +MaterialManager *MaterialManager::getInstance() +{ + if(!s_instance) + { + s_instance = new MaterialManager(); + if(!s_instance->init()) + { + CC_SAFE_DELETE(s_instance); + } + } + return s_instance; +} + +void MaterialManager::destroyInstance() +{ + CC_SAFE_RELEASE_NULL(s_instance); +} + +void MaterialManager::getMaterialID(GLuint textureID, GLuint shaderID, BlendFunc blendFunc) +{ + +} + +void MaterialManager::registerTexture(GLuint textureID) +{ + +} + +void MaterialManager::unregisterTexture(GLuint textureID) +{ + +} + +void MaterialManager::registerShader(GLuint shaderID) +{ + +} + +void MaterialManager::unregisterShader(GLuint shaderID) +{ + +} + +MaterialManager::MaterialManager() +{ + +} + +MaterialManager::~MaterialManager() +{ + +} + +bool MaterialManager::init() +{ + return false; +} + +int MaterialManager::getTextureID(GLuint textureID) +{ + return 0; +} + +int MaterialManager::getShaderID(GLuint shaderID) +{ + return 0; +} + +int MaterialManager::getBlendFuncID(GLint blendFunc) +{ + return 0; +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/MaterialManager.h b/cocos/2d/renderer/MaterialManager.h new file mode 100644 index 0000000000..f0e6e8d902 --- /dev/null +++ b/cocos/2d/renderer/MaterialManager.h @@ -0,0 +1,50 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + + +#ifndef _CC_MATERIALMANAGER_H_ +#define _CC_MATERIALMANAGER_H_ + +#include "CCPlatformMacros.h" +#include "CCObject.h" +#include "ccTypes.h" +#include + +NS_CC_BEGIN +using namespace std; + +class MaterialManager : public Object +{ +public: + static MaterialManager* getInstance(); + static void destroyInstance(); + + + void getMaterialID(GLuint textureID, GLuint shaderID, BlendFunc blendFunc); + + void registerTexture(GLuint textureID); + void unregisterTexture(GLuint textureID); + + void registerShader(GLuint shaderID); + void unregisterShader(GLuint shaderID); + +protected: + MaterialManager(); + virtual ~MaterialManager(); + + bool init(); + + int getTextureID(GLuint textureID); + int getShaderID(GLuint shaderID); + int getBlendFuncID(GLint blendFunc); + + map _textureIDMapping; + map _shaderIDMapping; + map _blendFuncMapping; +}; + +NS_CC_END + +#endif //_CC_MATERIALMANAGER_H_ diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp new file mode 100644 index 0000000000..be2f14a365 --- /dev/null +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -0,0 +1,6 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + +#include "QuadCommand.h" diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h new file mode 100644 index 0000000000..94d96c8ef6 --- /dev/null +++ b/cocos/2d/renderer/QuadCommand.h @@ -0,0 +1,32 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + + +#ifndef _CC_QUADCOMMAND_H_ +#define _CC_QUADCOMMAND_H_ + +#include "RenderCommand.h" + +NS_CC_BEGIN + + +// +----------+----------+-----+-----------------------------------+ +// | | | | | | +// | ViewPort | Transluc | Cmd | Depth | Material ID | +// | 3 bits | 1 bit | 1 | 24 bits | 24 bit2 | +// +----------+----------+-----+----------------+------------------+ +class QuadCommandID : public RenderCommandID +{ + +}; + +class QuadCommand : public RenderCommand +{ + +}; + +NS_CC_END + +#endif //_CC_QUADCOMMAND_H_ diff --git a/cocos/2d/renderer/RenderCommand.cpp b/cocos/2d/renderer/RenderCommand.cpp index dc99e0670e..a514bd963b 100644 --- a/cocos/2d/renderer/RenderCommand.cpp +++ b/cocos/2d/renderer/RenderCommand.cpp @@ -21,6 +21,40 @@ void RenderCommand::generateID() { _renderCommandId = 0; + //Generate Material ID + //TODO fix shader ID generation + CCASSERT(_shaderID < 64, "ShaderID is greater than 64"); + //TODO fix texture ID generation + CCASSERT(_textureID < 1024, "TextureID is greater than 1024"); + + //TODO fix blend id generation + int blendID = 0; + if(_blendType == BlendFunc::DISABLE) + { + blendID = 0; + } + else if(_blendType == BlendFunc::ALPHA_PREMULTIPLIED) + { + blendID = 1; + } + else if(_blendType == BlendFunc::ALPHA_NON_PREMULTIPLIED) + { + blendID = 2; + } + else if(_blendType == BlendFunc::ADDITIVE) + { + blendID = 3; + } + else + { + blendID = 4; + } + + _materialID = (int32_t)_shaderID << 28 + | (int32_t)blendID << 24 + | (int32_t)_textureID << 14; + + //Generate RenderCommandID _renderCommandId = (int64_t)_viewport << 61 | (int64_t)_isTranslucent << 60 | (int64_t)_isCommand << 59 @@ -53,7 +87,7 @@ void RenderCommand::printID() printf("\n"); } -void RenderCommand::setData(int viewport, bool isTranslucent, bool isCommand, int32_t depth) +void RenderCommand::setKeyData(int viewport, bool isTranslucent, bool isCommand, int32_t depth) { _viewport = viewport; _isTranslucent = isTranslucent; @@ -61,13 +95,17 @@ void RenderCommand::setData(int viewport, bool isTranslucent, bool isCommand, in _depth = depth; } -void RenderCommand::setQuadData(kmMat4 *transform, V3F_C4B_T2F_Quad quad, GLuint textureID, int shaderID, int blendType) +void RenderCommand::setMaterialData(GLuint textureID, GLuint shaderID, BlendFunc blendType) { - kmMat4Assign(&_transform, transform); - _quad = quad; _textureID = textureID; _shaderID = shaderID; _blendType = blendType; } +void RenderCommand::setQuadData(kmMat4 *transform, V3F_C4B_T2F_Quad quad) +{ + kmMat4Assign(&_transform, transform); + _quad = quad; +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index 7ffc599090..c903e6f65d 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -14,13 +14,25 @@ NS_CC_BEGIN +class RenderCommandID +{ +public: + virtual int64_t generateID() = 0; + inline int64_t getID() { return _id; } + +protected: + int64_t _id; + +}; + class RenderCommand { public: RenderCommand(); - void setData(int viewport, bool isTranslucent, bool isCommand, int32_t depth); - void setQuadData(kmMat4* transform, V3F_C4B_T2F_Quad quad, GLuint textureID, int shaderID, int blendType); + void setKeyData(int viewport, bool isTranslucent, bool isCommand, int32_t depth); + void setMaterialData( GLuint textureID, GLuint shaderID, BlendFunc blendType); + void setQuadData(kmMat4* transform, V3F_C4B_T2F_Quad quad); void generateID(); @@ -35,8 +47,8 @@ public: inline GLuint getTextureID() { return _textureID; } inline kmMat4* getTransform() { return &_transform; } inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } - inline int getShaderID() { return _shaderID; } - inline int getBlendType() { return _blendType; } + inline GLuint getShaderID() { return _shaderID; } + inline BlendFunc getBlendType() { return _blendType; } protected: void printID(); @@ -46,17 +58,18 @@ protected: int64_t _renderCommandId; /// used for sorting render commands int32_t _materialID; - //Data + //Key Data int _viewport; /// Which view port it belongs to bool _isTranslucent; /// Is it translucent, if it is we will have to render it bool _isCommand; int32_t _depth; + //Maternal + GLuint _textureID; + GLuint _shaderID; + BlendFunc _blendType; kmMat4 _transform; V3F_C4B_T2F_Quad _quad; - GLuint _textureID; - int _shaderID; - int _blendType; }; NS_CC_END diff --git a/cocos/2d/renderer/RenderMaterial.cpp b/cocos/2d/renderer/RenderMaterial.cpp new file mode 100644 index 0000000000..594128f8ea --- /dev/null +++ b/cocos/2d/renderer/RenderMaterial.cpp @@ -0,0 +1,6 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + +#include "RenderMaterial.h" diff --git a/cocos/2d/renderer/RenderMaterial.h b/cocos/2d/renderer/RenderMaterial.h new file mode 100644 index 0000000000..fa570a8f49 --- /dev/null +++ b/cocos/2d/renderer/RenderMaterial.h @@ -0,0 +1,17 @@ +// +// Created by NiTe Luo on 11/6/13. +// + + + +#ifndef __RenderMaterial_H_ +#define __RenderMaterial_H_ + + +class RenderMaterial +{ + +}; + + +#endif //__RenderMaterial_H_ From 63324db70d987efb6778c97b49e15cf5e9cfc9e1 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 6 Nov 2013 14:57:42 -0800 Subject: [PATCH 05/98] Subclass QuadCommand --- cocos/2d/CCNewSprite.cpp | 6 +-- cocos/2d/renderer/QuadCommand.cpp | 64 ++++++++++++++++++++++++ cocos/2d/renderer/QuadCommand.h | 44 +++++++++++++---- cocos/2d/renderer/RenderCommand.cpp | 75 ++--------------------------- cocos/2d/renderer/RenderCommand.h | 48 ++++-------------- cocos/2d/renderer/Renderer.cpp | 63 ++++++++++++++---------- 6 files changed, 150 insertions(+), 150 deletions(-) diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 77c33318ff..55bd1f9964 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -9,6 +9,7 @@ #include "CCNewSprite.h" #include "RenderCommand.h" #include "Renderer.h" +#include "QuadCommand.h" NS_CC_BEGIN @@ -46,10 +47,7 @@ void NewSprite::draw(void) { kmMat4 transform; kmGLGetMatrix(KM_GL_MODELVIEW, &transform); - RenderCommand* renderCommand = new RenderCommand(); - renderCommand->setKeyData(0, true, false, _ZOrder); - renderCommand->setMaterialData(_texture->getName(), _shaderProgram->getProgram(), _blendFunc); - renderCommand->setQuadData(&transform, _quad); + QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram->getProgram(), _blendFunc, transform, _quad); Renderer::getInstance()->addRenderCommand(renderCommand); } diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index be2f14a365..88b6c4afe7 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -4,3 +4,67 @@ #include "QuadCommand.h" + +NS_CC_BEGIN + +QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, kmMat4 transform, V3F_C4B_T2F_Quad quad) +:RenderCommand() +,_viewport(viewport) +,_depth(depth) +,_textureID(textureID) +,_shaderID(shaderID) +,_blendType(blendType) +,_quad(quad) +{ + _type = QUAD_COMMAND; + kmMat4Assign(&_transform, &transform); +} + +int64_t QuadCommand::generateID() +{ + _id = 0; + + //Generate Material ID + //TODO fix shader ID generation + CCASSERT(_shaderID < 64, "ShaderID is greater than 64"); + //TODO fix texture ID generation + CCASSERT(_textureID < 1024, "TextureID is greater than 1024"); + + //TODO fix blend id generation + int blendID = 0; + if(_blendType == BlendFunc::DISABLE) + { + blendID = 0; + } + else if(_blendType == BlendFunc::ALPHA_PREMULTIPLIED) + { + blendID = 1; + } + else if(_blendType == BlendFunc::ALPHA_NON_PREMULTIPLIED) + { + blendID = 2; + } + else if(_blendType == BlendFunc::ADDITIVE) + { + blendID = 3; + } + else + { + blendID = 4; + } + + _materialID = (int32_t)_shaderID << 28 + | (int32_t)blendID << 24 + | (int32_t)_textureID << 14; + + //Generate RenderCommandID + _id = (int64_t)_viewport << 61 + | (int64_t)1 << 60 //translucent + | (int64_t)0 << 59 //is command + | (int64_t)_depth << 35 + | (int64_t)_materialID << 11; + + return _id; +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 94d96c8ef6..c38c219710 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -12,19 +12,43 @@ NS_CC_BEGIN -// +----------+----------+-----+-----------------------------------+ -// | | | | | | -// | ViewPort | Transluc | Cmd | Depth | Material ID | -// | 3 bits | 1 bit | 1 | 24 bits | 24 bit2 | -// +----------+----------+-----+----------------+------------------+ -class QuadCommandID : public RenderCommandID -{ - -}; - class QuadCommand : public RenderCommand { +public: + QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, kmMat4 transform, V3F_C4B_T2F_Quad quad); + // +----------+----------+-----+-----------------------------------+ + // | | | | | | + // | ViewPort | Transluc | Cmd | Depth | Material ID | + // | 3 bits | 1 bit | 1 | 24 bits | 24 bit2 | + // +----------+----------+-----+----------------+------------------+ + virtual int64_t generateID(); + + //TODO use material to decide if it is translucent + inline bool isTranslucent() { return true; } + inline bool isCommand() { return false; } + inline int32_t getMaterialID() { return _materialID; } + + inline GLuint getTextureID() { return _textureID; } + inline kmMat4* getTransform() { return &_transform; } + inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } + inline GLuint getShaderID() { return _shaderID; } + inline BlendFunc getBlendType() { return _blendType; } + +protected: + int32_t _materialID; + + //Key Data + int _viewport; /// Which view port it belongs to + //TODO use material to determine if it's translucent + int32_t _depth; + //Maternal + GLuint _textureID; + GLuint _shaderID; + BlendFunc _blendType; + + kmMat4 _transform; + V3F_C4B_T2F_Quad _quad; }; NS_CC_END diff --git a/cocos/2d/renderer/RenderCommand.cpp b/cocos/2d/renderer/RenderCommand.cpp index a514bd963b..baa691bbff 100644 --- a/cocos/2d/renderer/RenderCommand.cpp +++ b/cocos/2d/renderer/RenderCommand.cpp @@ -8,59 +8,11 @@ NS_CC_BEGIN RenderCommand::RenderCommand() -:_viewport(0) -,_isTranslucent(false) -,_isCommand(false) -,_depth(0) -,_materialID(0) { - + _id = 0; + _type = UNKNOWN_COMMAND; } -void RenderCommand::generateID() -{ - _renderCommandId = 0; - - //Generate Material ID - //TODO fix shader ID generation - CCASSERT(_shaderID < 64, "ShaderID is greater than 64"); - //TODO fix texture ID generation - CCASSERT(_textureID < 1024, "TextureID is greater than 1024"); - - //TODO fix blend id generation - int blendID = 0; - if(_blendType == BlendFunc::DISABLE) - { - blendID = 0; - } - else if(_blendType == BlendFunc::ALPHA_PREMULTIPLIED) - { - blendID = 1; - } - else if(_blendType == BlendFunc::ALPHA_NON_PREMULTIPLIED) - { - blendID = 2; - } - else if(_blendType == BlendFunc::ADDITIVE) - { - blendID = 3; - } - else - { - blendID = 4; - } - - _materialID = (int32_t)_shaderID << 28 - | (int32_t)blendID << 24 - | (int32_t)_textureID << 14; - - //Generate RenderCommandID - _renderCommandId = (int64_t)_viewport << 61 - | (int64_t)_isTranslucent << 60 - | (int64_t)_isCommand << 59 - | (int64_t)_depth << 35 - | (int64_t)_materialID << 11; -} void printBits(size_t const size, void const * const ptr) { @@ -83,29 +35,8 @@ void printBits(size_t const size, void const * const ptr) void RenderCommand::printID() { printf("CommandID: "); - printBits(sizeof(_renderCommandId), &_renderCommandId); + printBits(sizeof(_id), &_id); printf("\n"); } -void RenderCommand::setKeyData(int viewport, bool isTranslucent, bool isCommand, int32_t depth) -{ - _viewport = viewport; - _isTranslucent = isTranslucent; - _isCommand = isCommand; - _depth = depth; -} - -void RenderCommand::setMaterialData(GLuint textureID, GLuint shaderID, BlendFunc blendType) -{ - _textureID = textureID; - _shaderID = shaderID; - _blendType = blendType; -} - -void RenderCommand::setQuadData(kmMat4 *transform, V3F_C4B_T2F_Quad quad) -{ - kmMat4Assign(&_transform, transform); - _quad = quad; -} - NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index c903e6f65d..57ad8864c1 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -14,15 +14,12 @@ NS_CC_BEGIN -class RenderCommandID +enum RenderCommandType { -public: - virtual int64_t generateID() = 0; - inline int64_t getID() { return _id; } - -protected: - int64_t _id; - + QUAD_COMMAND, + CUSTOMIZE_COMMAND, + GROUP_COMMAND, + UNKNOWN_COMMAND, }; class RenderCommand @@ -30,46 +27,21 @@ class RenderCommand public: RenderCommand(); - void setKeyData(int viewport, bool isTranslucent, bool isCommand, int32_t depth); - void setMaterialData( GLuint textureID, GLuint shaderID, BlendFunc blendType); - void setQuadData(kmMat4* transform, V3F_C4B_T2F_Quad quad); - - void generateID(); + virtual int64_t generateID() = 0; /** * Get Render Command Id */ - inline int64_t getID() { return _renderCommandId; } - inline bool isTranslucent() { return _isTranslucent; } - inline bool isCommand() { return _isCommand; } - inline int32_t getMaterialID() { return _materialID; } - - inline GLuint getTextureID() { return _textureID; } - inline kmMat4* getTransform() { return &_transform; } - inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } - inline GLuint getShaderID() { return _shaderID; } - inline BlendFunc getBlendType() { return _blendType; } + inline int64_t getID() { return _id; } + inline RenderCommandType getType() { return _type; } protected: void printID(); protected: //Generated IDs - int64_t _renderCommandId; /// used for sorting render commands - int32_t _materialID; - - //Key Data - int _viewport; /// Which view port it belongs to - bool _isTranslucent; /// Is it translucent, if it is we will have to render it - bool _isCommand; - int32_t _depth; - //Maternal - GLuint _textureID; - GLuint _shaderID; - BlendFunc _blendType; - - kmMat4 _transform; - V3F_C4B_T2F_Quad _quad; + int64_t _id; /// used for sorting render commands + RenderCommandType _type; }; NS_CC_END diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 683c4a4b76..cf3bdcb815 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -10,6 +10,7 @@ #include "CCShaderCache.h" #include "ccGLStateCache.h" #include "CCGLProgram.h" +#include "QuadCommand.h" NS_CC_BEGIN using namespace std; @@ -50,12 +51,12 @@ bool compareRenderCommand(RenderCommand* a, RenderCommand* b) void Renderer::render() { + //Uncomment this once everything is rendered by new renderer //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Process render commands //1. Sort render commands based on ID stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); -// sort(_renderQueue.begin(), _renderQueue.end()); //2. Process commands for(vector::iterator it = _renderQueue.begin(); it != _renderQueue.end(); ++it) @@ -63,41 +64,51 @@ void Renderer::render() //TODO: Perform Sprite batching here auto command = *it; - //Transform - kmGLMatrixMode(KM_GL_MODELVIEW); - kmGLLoadMatrix(command->getTransform()); + switch(command->getType()) + { + case QUAD_COMMAND: + { + QuadCommand* cmd = (QuadCommand*)command; + //Transform + kmGLMatrixMode(KM_GL_MODELVIEW); + kmGLLoadMatrix(cmd->getTransform()); - //Set Shader - _shaderProgram->use(); - _shaderProgram->setUniformsForBuiltins(); + //Set Shader + _shaderProgram->use(); + _shaderProgram->setUniformsForBuiltins(); - //Set Blend Mode - //Set texture - GL::bindTexture2D(command->getTextureID()); - GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); + //Set Blend Mode + //Set texture + GL::bindTexture2D(cmd->getTextureID()); + GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); -#define kQuadSize sizeof(command->getQuad()->bl) - long offset = (long)command->getQuad(); +#define kQuadSize sizeof(cmd->getQuad()->bl) + long offset = (long)cmd->getQuad(); - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); + // vertex + int diff = offsetof( V3F_C4B_T2F, vertices); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); + // texCoods + diff = offsetof( V3F_C4B_T2F, texCoords); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); + // color + diff = offsetof( V3F_C4B_T2F, colors); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - CHECK_GL_ERROR_DEBUG(); - CC_INCREMENT_GL_DRAWS(1); + CHECK_GL_ERROR_DEBUG(); + CC_INCREMENT_GL_DRAWS(1); - kmGLLoadIdentity(); + kmGLLoadIdentity(); + break; + } + default: + break; + } delete command; } From 21cd03bc136b3a7df294c6d2d93d8d8a96e624b2 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 6 Nov 2013 16:39:20 -0800 Subject: [PATCH 06/98] Remove transform from QuadCommand, NewSprite using world coordinates --- cocos/2d/CCNewSprite.cpp | 68 +++++++++++++++++++++++++++++-- cocos/2d/CCNewSprite.h | 2 + cocos/2d/CCSprite.cpp | 2 +- cocos/2d/renderer/QuadCommand.cpp | 6 +-- cocos/2d/renderer/QuadCommand.h | 4 +- cocos/2d/renderer/Renderer.cpp | 6 +-- 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 55bd1f9964..fe517b0d99 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -13,6 +13,12 @@ NS_CC_BEGIN +#if CC_SPRITEBATCHNODE_RENDER_SUBPIXEL +#define RENDER_IN_SUBPIXEL +#else +#define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__)) +#endif + NewSprite* NewSprite::create() { NewSprite* sprite = new NewSprite(); @@ -43,11 +49,67 @@ NewSprite::NewSprite() } +void NewSprite::updateTransform() +{ + if(_dirty) + { + if(!_visible) + { + _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); + _shouldBeHidden = true; + } + else + { + _shouldBeHidden = false; + + //TODO optimize this transformation, should use parent's transformation instead + _transformToBatch = getNodeToWorldTransform(); + + // + // calculate the Quad based on the Affine Matrix + // + + Size size = _rect.size; + + float x1 = _offsetPosition.x; + float y1 = _offsetPosition.y; + + float x2 = x1 + size.width; + float y2 = y1 + size.height; + float x = _transformToBatch.tx; + float y = _transformToBatch.ty; + + float cr = _transformToBatch.a; + float sr = _transformToBatch.b; + float cr2 = _transformToBatch.d; + float sr2 = -_transformToBatch.c; + float ax = x1 * cr - y1 * sr2 + x; + float ay = x1 * sr + y1 * cr2 + y; + + float bx = x2 * cr - y1 * sr2 + x; + float by = x2 * sr + y1 * cr2 + y; + + float cx = x2 * cr - y2 * sr2 + x; + float cy = x2 * sr + y2 * cr2 + y; + + float dx = x1 * cr - y2 * sr2 + x; + float dy = x1 * sr + y2 * cr2 + y; + + _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); + _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); + _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); + _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); + } + } + + _recursiveDirty = false; + setDirty(false); +} + void NewSprite::draw(void) { - kmMat4 transform; - kmGLGetMatrix(KM_GL_MODELVIEW, &transform); - QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram->getProgram(), _blendFunc, transform, _quad); + updateTransform(); + QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram->getProgram(), _blendFunc, _quad); Renderer::getInstance()->addRenderCommand(renderCommand); } diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index e152b0d0fc..62a52495f6 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -22,6 +22,8 @@ public: static NewSprite* create(const char *filename); NewSprite(void); + + virtual void updateTransform(); virtual void draw(void) override; protected: diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 91228edf49..53c2ddac27 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -777,7 +777,7 @@ void Sprite::setDirtyRecursively(bool bValue) // XXX HACK: optimization #define SET_DIRTY_RECURSIVELY() { \ - if (_batchNode && ! _recursiveDirty) { \ + if (! _recursiveDirty) { \ _recursiveDirty = true; \ setDirty(true); \ if ( _hasChildren) \ diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 88b6c4afe7..1dd38714a4 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -7,7 +7,7 @@ NS_CC_BEGIN -QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, kmMat4 transform, V3F_C4B_T2F_Quad quad) +QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, V3F_C4B_T2F_Quad quad) :RenderCommand() ,_viewport(viewport) ,_depth(depth) @@ -17,7 +17,6 @@ QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint s ,_quad(quad) { _type = QUAD_COMMAND; - kmMat4Assign(&_transform, &transform); } int64_t QuadCommand::generateID() @@ -61,8 +60,7 @@ int64_t QuadCommand::generateID() _id = (int64_t)_viewport << 61 | (int64_t)1 << 60 //translucent | (int64_t)0 << 59 //is command - | (int64_t)_depth << 35 - | (int64_t)_materialID << 11; + | (int64_t)_depth << 35; return _id; } diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index c38c219710..6a0d7cf729 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -15,7 +15,7 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { public: - QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, kmMat4 transform, V3F_C4B_T2F_Quad quad); + QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, V3F_C4B_T2F_Quad quad); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -30,7 +30,6 @@ public: inline int32_t getMaterialID() { return _materialID; } inline GLuint getTextureID() { return _textureID; } - inline kmMat4* getTransform() { return &_transform; } inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } inline GLuint getShaderID() { return _shaderID; } inline BlendFunc getBlendType() { return _blendType; } @@ -47,7 +46,6 @@ protected: GLuint _shaderID; BlendFunc _blendType; - kmMat4 _transform; V3F_C4B_T2F_Quad _quad; }; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index cf3bdcb815..c05ce1415a 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -54,6 +54,8 @@ void Renderer::render() //Uncomment this once everything is rendered by new renderer //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //TODO setup camera or MVP + //Process render commands //1. Sort render commands based on ID stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); @@ -69,9 +71,6 @@ void Renderer::render() case QUAD_COMMAND: { QuadCommand* cmd = (QuadCommand*)command; - //Transform - kmGLMatrixMode(KM_GL_MODELVIEW); - kmGLLoadMatrix(cmd->getTransform()); //Set Shader _shaderProgram->use(); @@ -103,7 +102,6 @@ void Renderer::render() CHECK_GL_ERROR_DEBUG(); CC_INCREMENT_GL_DRAWS(1); - kmGLLoadIdentity(); break; } default: From 3421eb8e5dff3e1ed7b4c43f35769e3d9419a824 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 7 Nov 2013 10:09:53 -0800 Subject: [PATCH 07/98] Cleanup the code a bit before implement sprite batching --- cocos/2d/renderer/QuadCommand.cpp | 5 +++++ cocos/2d/renderer/QuadCommand.h | 10 ++++++++++ cocos/2d/renderer/RenderCommand.cpp | 3 +++ cocos/2d/renderer/RenderCommand.h | 1 + cocos/2d/renderer/Renderer.cpp | 8 +------- cocos/2d/renderer/Renderer.h | 6 +++--- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 1dd38714a4..f0a09f8d46 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -19,6 +19,11 @@ QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint s _type = QUAD_COMMAND; } +QuadCommand::~QuadCommand() +{ + +} + int64_t QuadCommand::generateID() { _id = 0; diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 6a0d7cf729..74c9293abc 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -16,6 +16,7 @@ class QuadCommand : public RenderCommand { public: QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, V3F_C4B_T2F_Quad quad); + ~QuadCommand(); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -26,12 +27,17 @@ public: //TODO use material to decide if it is translucent inline bool isTranslucent() { return true; } + inline bool isCommand() { return false; } + inline int32_t getMaterialID() { return _materialID; } inline GLuint getTextureID() { return _textureID; } + inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } + inline GLuint getShaderID() { return _shaderID; } + inline BlendFunc getBlendType() { return _blendType; } protected: @@ -39,11 +45,15 @@ protected: //Key Data int _viewport; /// Which view port it belongs to + //TODO use material to determine if it's translucent int32_t _depth; + //Maternal GLuint _textureID; + GLuint _shaderID; + BlendFunc _blendType; V3F_C4B_T2F_Quad _quad; diff --git a/cocos/2d/renderer/RenderCommand.cpp b/cocos/2d/renderer/RenderCommand.cpp index baa691bbff..6b94fd977d 100644 --- a/cocos/2d/renderer/RenderCommand.cpp +++ b/cocos/2d/renderer/RenderCommand.cpp @@ -13,6 +13,9 @@ RenderCommand::RenderCommand() _type = UNKNOWN_COMMAND; } +RenderCommand::~RenderCommand() +{ +} void printBits(size_t const size, void const * const ptr) { diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index 57ad8864c1..c7d8650ad5 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -27,6 +27,7 @@ class RenderCommand public: RenderCommand(); + virtual ~RenderCommand(); virtual int64_t generateID() = 0; /** diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index c05ce1415a..adfbca4298 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -27,17 +27,11 @@ Renderer *Renderer::getInstance() } Renderer::Renderer() -:_currentMaterialID(0) +:_lastMaterialID(0) { _shaderProgram = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR); } -void Renderer::setOpenGLView(EGLView *newOpenGLView) -{ - //TODO move render related logic to render - _openGLView = newOpenGLView; -} - void Renderer::addRenderCommand(RenderCommand *command) { command->generateID(); diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 65048f06b1..d1336372a9 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -20,7 +20,7 @@ class Renderer public: static Renderer* getInstance(); - void setOpenGLView(EGLView *newOpenGLView); + //TODO support multiple viewport void addRenderCommand(RenderCommand* commnad); void render(); @@ -28,10 +28,10 @@ protected: Renderer(); protected: - EGLView* _openGLView; vector _renderQueue; GLProgram* _shaderProgram; - int _currentMaterialID; + int _lastMaterialID; + V3F_C4B_T2F_Quad* _quadBuffer; }; NS_CC_END From d7cb4ed2192d677ca6a7db241ff03cb164ac67b3 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 7 Nov 2013 15:48:37 -0800 Subject: [PATCH 08/98] First attempt for batching --- cocos/2d/CCNewSprite.cpp | 2 +- cocos/2d/renderer/QuadCommand.cpp | 16 +++- cocos/2d/renderer/QuadCommand.h | 10 +- cocos/2d/renderer/Renderer.cpp | 95 +++++++++++++------ cocos/2d/renderer/Renderer.h | 12 ++- .../NewRendererTest/NewRendererTest.cpp | 24 ++++- 6 files changed, 116 insertions(+), 43 deletions(-) diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index fe517b0d99..92d5bc5a3c 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -109,7 +109,7 @@ void NewSprite::updateTransform() void NewSprite::draw(void) { updateTransform(); - QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram->getProgram(), _blendFunc, _quad); + QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram, _blendFunc, _quad); Renderer::getInstance()->addRenderCommand(renderCommand); } diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index f0a09f8d46..63e3275a78 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -4,19 +4,20 @@ #include "QuadCommand.h" +#include "ccGLStateCache.h" NS_CC_BEGIN -QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, V3F_C4B_T2F_Quad quad) +QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad quad) :RenderCommand() ,_viewport(viewport) ,_depth(depth) ,_textureID(textureID) -,_shaderID(shaderID) ,_blendType(blendType) ,_quad(quad) { _type = QUAD_COMMAND; + _shader = shader; } QuadCommand::~QuadCommand() @@ -30,7 +31,7 @@ int64_t QuadCommand::generateID() //Generate Material ID //TODO fix shader ID generation - CCASSERT(_shaderID < 64, "ShaderID is greater than 64"); + CCASSERT(_shader->getProgram() < 64, "ShaderID is greater than 64"); //TODO fix texture ID generation CCASSERT(_textureID < 1024, "TextureID is greater than 1024"); @@ -57,7 +58,7 @@ int64_t QuadCommand::generateID() blendID = 4; } - _materialID = (int32_t)_shaderID << 28 + _materialID = (int32_t)_shader->getProgram() << 28 | (int32_t)blendID << 24 | (int32_t)_textureID << 14; @@ -70,4 +71,11 @@ int64_t QuadCommand::generateID() return _id; } +void QuadCommand::useMaterial() +{ + _shader->use(); + //TODO once everything is using world coordinate, we can reduce the uniforms for shaders + _shader->setUniformsForBuiltins(); +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 74c9293abc..fb1ec48328 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -8,6 +8,7 @@ #define _CC_QUADCOMMAND_H_ #include "RenderCommand.h" +#include "CCGLProgram.h" NS_CC_BEGIN @@ -15,7 +16,7 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { public: - QuadCommand(int viewport, int32_t depth, GLuint textureID, GLuint shaderID, BlendFunc blendType, V3F_C4B_T2F_Quad quad); + QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad quad); ~QuadCommand(); // +----------+----------+-----+-----------------------------------+ @@ -25,6 +26,8 @@ public: // +----------+----------+-----+----------------+------------------+ virtual int64_t generateID(); + void useMaterial(); + //TODO use material to decide if it is translucent inline bool isTranslucent() { return true; } @@ -36,7 +39,7 @@ public: inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } - inline GLuint getShaderID() { return _shaderID; } + inline GLProgram* getShader() { return _shader; } inline BlendFunc getBlendType() { return _blendType; } @@ -52,7 +55,8 @@ protected: //Maternal GLuint _textureID; - GLuint _shaderID; + GLProgram* _shader; +// GLuint _shaderID; BlendFunc _blendType; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index adfbca4298..43bf524544 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -4,13 +4,8 @@ #include "Renderer.h" - -#include "CCGL.h" -#include "ccMacros.h" #include "CCShaderCache.h" #include "ccGLStateCache.h" -#include "CCGLProgram.h" -#include "QuadCommand.h" NS_CC_BEGIN using namespace std; @@ -28,8 +23,16 @@ Renderer *Renderer::getInstance() Renderer::Renderer() :_lastMaterialID(0) +,_numQuadsAlloc(0) +,_numQuads(0) { - _shaderProgram = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR); + _quadBuffer = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * NUM_QUADS_PER_ALLOC); + _numQuadsAlloc = NUM_QUADS_PER_ALLOC; +} + +Renderer::~Renderer() +{ + free(_quadBuffer); } void Renderer::addRenderCommand(RenderCommand *command) @@ -66,35 +69,27 @@ void Renderer::render() { QuadCommand* cmd = (QuadCommand*)command; - //Set Shader - _shaderProgram->use(); - _shaderProgram->setUniformsForBuiltins(); + if(_lastMaterialID != cmd->getMaterialID()) + { + //Draw batched data + if(_numQuads > 0) + { + drawQuads(); + } - //Set Blend Mode - //Set texture - GL::bindTexture2D(cmd->getTextureID()); - GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); + //Set new material + _lastMaterialID = cmd->getMaterialID(); -#define kQuadSize sizeof(cmd->getQuad()->bl) - long offset = (long)cmd->getQuad(); + //Set Shader + cmd->useMaterial(); - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); + //TODO: Set Blend Mode - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); + //Set texture + GL::bindTexture2D(cmd->getTextureID()); + } - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); - - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - CHECK_GL_ERROR_DEBUG(); - CC_INCREMENT_GL_DRAWS(1); + batchQuads(cmd); break; } @@ -105,7 +100,47 @@ void Renderer::render() delete command; } + drawQuads(); + _renderQueue.clear(); } +void Renderer::drawQuads() +{ + //Bind VAO + GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); + long offset = (long)_quadBuffer; + + // vertex + int diff = offsetof( V3F_C4B_T2F, vertices); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*) (offset + diff)); + + // texCoods + diff = offsetof( V3F_C4B_T2F, texCoords); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff)); + + // color + diff = offsetof( V3F_C4B_T2F, colors); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (void*)(offset + diff)); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4 * _numQuads); + + CHECK_GL_ERROR_DEBUG(); + CC_INCREMENT_GL_DRAWS(1); + + _numQuads = 0; +} + +void Renderer::batchQuads(QuadCommand* cmd) +{ + //Batch data + _numQuads++; //Every quad command only contains one quad + if(_numQuads > _numQuadsAlloc) + { + _numQuadsAlloc = _numQuads + NUM_QUADS_PER_ALLOC; + _quadBuffer = (V3F_C4B_T2F_Quad*)realloc(_quadBuffer, sizeof(V3F_C4B_T2F_Quad) * _numQuadsAlloc); + } + _quadBuffer[_numQuads - 1] = *cmd->getQuad(); +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index d1336372a9..fda7aa0aa4 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -11,6 +11,9 @@ #include "CCEGLView.h" #include "RenderCommand.h" #include "CCGLProgram.h" +#include "QuadCommand.h" + +#define NUM_QUADS_PER_ALLOC 20 NS_CC_BEGIN using namespace std; @@ -21,17 +24,22 @@ public: static Renderer* getInstance(); //TODO support multiple viewport - void addRenderCommand(RenderCommand* commnad); + void addRenderCommand(RenderCommand* command); void render(); protected: Renderer(); + ~Renderer(); + + void batchQuads(QuadCommand* cmd); + void drawQuads(); protected: vector _renderQueue; - GLProgram* _shaderProgram; int _lastMaterialID; V3F_C4B_T2F_Quad* _quadBuffer; + int _numQuadsAlloc; + int _numQuads; }; NS_CC_END diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 66d6e3eb00..f16de3ae8f 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -12,7 +12,7 @@ NewRendererTest::NewRendererTest() auto touchListener = EventListenerTouchAllAtOnce::create(); touchListener->onTouchesEnded = CC_CALLBACK_2(NewRendererTest::onTouchesEnded, this); - createSpriteTest(); +// createSpriteTest(); createNewSpriteTest(); } @@ -26,20 +26,29 @@ void NewRendererTest::createSpriteTest() Size winSize = Director::getInstance()->getWinSize(); Sprite* parent = Sprite::create("Images/grossini.png"); - parent->setPosition(winSize.width/3, winSize.height/2); + parent->setPosition(winSize.width/4, winSize.height/2); Sprite* child1 = Sprite::create("Images/grossinis_sister1.png"); child1->setPosition(0.0f, -20.0f); Sprite* child2 = Sprite::create("Images/grossinis_sister2.png"); child2->setPosition(20.0f, -20.0f); Sprite* child3 = Sprite::create("Images/grossinis_sister1.png"); child3->setPosition(40.0f, -20.0f); - Sprite* child4 = Sprite::create("Images/grossinis_sister2.png");\ + Sprite* child4 = Sprite::create("Images/grossinis_sister2.png"); child4->setPosition(60.0f, -20.0f); + Sprite* child5 = Sprite::create("Images/grossinis_sister2.png"); + child5->setPosition(80.0f, -20.0f); + Sprite* child6 = Sprite::create("Images/grossinis_sister2.png"); + child6->setPosition(100.0f, -20.0f); + Sprite* child7 = Sprite::create("Images/grossinis_sister2.png"); + child7->setPosition(120.0f, -20.0f); parent->addChild(child1); parent->addChild(child2); parent->addChild(child3); parent->addChild(child4); + parent->addChild(child5); + parent->addChild(child6); + parent->addChild(child7); addChild(parent); } @@ -57,11 +66,20 @@ void NewRendererTest::createNewSpriteTest() child3->setPosition(40.0f, -20.0f); NewSprite* child4 = NewSprite::create("Images/grossinis_sister2.png"); child4->setPosition(60.0f, -20.0f); + NewSprite* child5 = NewSprite::create("Images/grossinis_sister2.png"); + child5->setPosition(80.0f, -20.0f); + NewSprite* child6 = NewSprite::create("Images/grossinis_sister2.png"); + child6->setPosition(100.0f, -20.0f); + NewSprite* child7 = NewSprite::create("Images/grossinis_sister2.png"); + child7->setPosition(120.0f, -20.0f); parent->addChild(child1); parent->addChild(child2); parent->addChild(child3); parent->addChild(child4); + parent->addChild(child5); + parent->addChild(child6); + parent->addChild(child7); addChild(parent); } From 935d2bdebbe69fc425e956056db2f337bab510a4 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 7 Nov 2013 16:50:53 -0800 Subject: [PATCH 09/98] Implement sprite batching --- cocos/2d/renderer/Renderer.cpp | 124 +++++++++++++----- cocos/2d/renderer/Renderer.h | 18 ++- .../NewRendererTest/NewRendererTest.cpp | 2 +- 3 files changed, 109 insertions(+), 35 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 43bf524544..27e21093ad 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -10,29 +10,101 @@ NS_CC_BEGIN using namespace std; -static Renderer* s_renderer; +static Renderer*s_instance; Renderer *Renderer::getInstance() { - if(!s_renderer) + if(!s_instance) { - s_renderer = new Renderer(); + s_instance = new Renderer(); + if(!s_instance->init()) + { + CC_SAFE_DELETE(s_instance); + } } - return s_renderer; + return s_instance; +} + +void Renderer::destroyInstance() +{ + CC_SAFE_RELEASE_NULL(s_instance); } Renderer::Renderer() :_lastMaterialID(0) -,_numQuadsAlloc(0) ,_numQuads(0) { - _quadBuffer = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * NUM_QUADS_PER_ALLOC); - _numQuadsAlloc = NUM_QUADS_PER_ALLOC; + } Renderer::~Renderer() { - free(_quadBuffer); + free(_quads); +} + +bool Renderer::init() +{ + _quads = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * VBO_SIZE); + _indices = (GLushort*) malloc(sizeof(GLushort) * 6 * VBO_SIZE); + if( ! ( _quads && _indices) ) + { + //not enough memory + CC_SAFE_FREE(_quads); + CC_SAFE_FREE(_indices); + return false; + } + + setupIndices(); + + setupVBOAndVAO(); + + return true; +} + +void Renderer::setupIndices() +{ + for( int i=0; i < VBO_SIZE; i++) + { + _indices[i*6+0] = (GLushort) (i*4+0); + _indices[i*6+1] = (GLushort) (i*4+1); + _indices[i*6+2] = (GLushort) (i*4+2); + _indices[i*6+3] = (GLushort) (i*4+3); + _indices[i*6+4] = (GLushort) (i*4+2); + _indices[i*6+5] = (GLushort) (i*4+1); + } +} + +void Renderer::setupVBOAndVAO() +{ + glGenVertexArrays(1, &_VAOname); + GL::bindVAO(_VAOname); + + glGenBuffers(2, &_buffersVBO[0]); + + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * VBO_SIZE, _quads, GL_DYNAMIC_DRAW); + + // vertices + glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*) offsetof( V3F_C4B_T2F, vertices)); + + // colors + glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid*) offsetof( V3F_C4B_T2F, colors)); + + // tex coords + glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORDS); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*) offsetof( V3F_C4B_T2F, texCoords)); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices[0]) * VBO_SIZE * 6, _indices, GL_STATIC_DRAW); + + // Must unbind the VAO before changing the element buffer. + GL::bindVAO(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + CHECK_GL_ERROR_DEBUG(); } void Renderer::addRenderCommand(RenderCommand *command) @@ -69,7 +141,7 @@ void Renderer::render() { QuadCommand* cmd = (QuadCommand*)command; - if(_lastMaterialID != cmd->getMaterialID()) + if(_lastMaterialID != cmd->getMaterialID() || _numQuads == VBO_SIZE) { //Draw batched data if(_numQuads > 0) @@ -107,23 +179,20 @@ void Renderer::render() void Renderer::drawQuads() { + //Set VBO data + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + + glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW); + void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + //Bind VAO - GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); - long offset = (long)_quadBuffer; + GL::bindVAO(_VAOname); - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*) (offset + diff)); - - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff)); - - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (void*)(offset + diff)); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4 * _numQuads); + glDrawElements(GL_TRIANGLES, (GLsizei) _numQuads*6, GL_UNSIGNED_SHORT, 0 ); CHECK_GL_ERROR_DEBUG(); CC_INCREMENT_GL_DRAWS(1); @@ -135,12 +204,7 @@ void Renderer::batchQuads(QuadCommand* cmd) { //Batch data _numQuads++; //Every quad command only contains one quad - if(_numQuads > _numQuadsAlloc) - { - _numQuadsAlloc = _numQuads + NUM_QUADS_PER_ALLOC; - _quadBuffer = (V3F_C4B_T2F_Quad*)realloc(_quadBuffer, sizeof(V3F_C4B_T2F_Quad) * _numQuadsAlloc); - } - _quadBuffer[_numQuads - 1] = *cmd->getQuad(); + _quads[_numQuads - 1] = *cmd->getQuad(); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index fda7aa0aa4..9105443281 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -13,15 +13,16 @@ #include "CCGLProgram.h" #include "QuadCommand.h" -#define NUM_QUADS_PER_ALLOC 20 +#define VBO_SIZE 64 NS_CC_BEGIN using namespace std; -class Renderer +class Renderer : public Object { public: static Renderer* getInstance(); + static void destroyInstance(); //TODO support multiple viewport void addRenderCommand(RenderCommand* command); @@ -31,14 +32,23 @@ protected: Renderer(); ~Renderer(); + bool init(); + void setupIndices(); + void setupVBOAndVAO(); + void batchQuads(QuadCommand* cmd); void drawQuads(); protected: vector _renderQueue; int _lastMaterialID; - V3F_C4B_T2F_Quad* _quadBuffer; - int _numQuadsAlloc; + + + V3F_C4B_T2F_Quad*_quads; + GLushort* _indices; + GLuint _VAOname; + GLuint _buffersVBO[2]; //0: vertex 1: indices + int _numQuads; }; diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index f16de3ae8f..b0633c099b 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -12,7 +12,7 @@ NewRendererTest::NewRendererTest() auto touchListener = EventListenerTouchAllAtOnce::create(); touchListener->onTouchesEnded = CC_CALLBACK_2(NewRendererTest::onTouchesEnded, this); -// createSpriteTest(); + createSpriteTest(); createNewSpriteTest(); } From 72828acaec935983f479ccee8d09983c921e0451 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 7 Nov 2013 16:53:20 -0800 Subject: [PATCH 10/98] Add some todo --- cocos/2d/renderer/RenderCommand.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index c7d8650ad5..5f9f945ae9 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -22,6 +22,7 @@ enum RenderCommandType UNKNOWN_COMMAND, }; +//TODO make RenderCommand inherent from Object class RenderCommand { public: From fa9d8fe077b36b7a869714992d20ecae5631c565 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 8 Nov 2013 12:06:39 -0800 Subject: [PATCH 11/98] Add CustomCommand --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CustomCommand.cpp | 44 +++++++++++++++++ cocos/2d/CustomCommand.h | 47 +++++++++++++++++++ cocos/2d/renderer/RenderCommand.h | 2 +- cocos/2d/renderer/Renderer.cpp | 29 ++++++++++-- cocos/2d/renderer/Renderer.h | 5 +- 6 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 cocos/2d/CustomCommand.cpp create mode 100644 cocos/2d/CustomCommand.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 98b3f676bc..7008ca8012 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -483a248a4f35f5351b3ffaecb0911023bed1812b \ No newline at end of file +63359196a3b9f69ce5b8c2374708597ae31643e2 \ No newline at end of file diff --git a/cocos/2d/CustomCommand.cpp b/cocos/2d/CustomCommand.cpp new file mode 100644 index 0000000000..ee92cd6bd2 --- /dev/null +++ b/cocos/2d/CustomCommand.cpp @@ -0,0 +1,44 @@ +// +// Created by NiTe Luo on 11/8/13. +// + + +#include "CustomCommand.h" + +NS_CC_BEGIN + +CustomCommand::CustomCommand(int viewport, int32_t depth) +:RenderCommand() +, _viewport(viewport) +, _depth(depth) +, func(nullptr) +{ + _type = CUSTOM_COMMAND; +} + +CustomCommand::~CustomCommand() +{ + +} + +int64_t CustomCommand::generateID() +{ + _id = 0; + + _id = (int64_t)_viewport << 61 + | (int64_t)1 << 60 // translucent + | (int64_t)0 << 59 // is command + | (int64_t)_depth << 35; + + return _id; +} + +void CustomCommand::execute() +{ + if(func) + { + func(); + } +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CustomCommand.h b/cocos/2d/CustomCommand.h new file mode 100644 index 0000000000..a0f3bcd8ff --- /dev/null +++ b/cocos/2d/CustomCommand.h @@ -0,0 +1,47 @@ +// +// Created by NiTe Luo on 11/8/13. +// + + + +#ifndef _CC_CUSTOMCOMMAND_H_ +#define _CC_CUSTOMCOMMAND_H_ + +#include "RenderCommand.h" + +NS_CC_BEGIN +using namespace std; + +class CustomCommand : public RenderCommand +{ +public: + CustomCommand(int viewport, int32_t depth); + ~CustomCommand(); + + // +----------+----------+-----+-----------------------------------+ + // | | | | | | + // | ViewPort | Transluc | Cmd | Depth | | + // | 3 bits | 1 bit | 1 | 24 bits | | + // +----------+----------+-----+----------------+------------------+ + virtual int64_t generateID(); + + void execute(); + + inline bool isTranslucent() { return true; } + + //TODO support non-graphical command + inline bool isCommand() { return false; } + +public: + function func; + +protected: + int _viewport; + + int32_t _depth; + +}; + +NS_CC_END + +#endif //_CC_CUSTOMCOMMAND_H_ diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index 5f9f945ae9..fbc6678ed5 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -17,7 +17,7 @@ NS_CC_BEGIN enum RenderCommandType { QUAD_COMMAND, - CUSTOMIZE_COMMAND, + CUSTOM_COMMAND, GROUP_COMMAND, UNKNOWN_COMMAND, }; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 27e21093ad..67078d4894 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -6,6 +6,8 @@ #include "Renderer.h" #include "CCShaderCache.h" #include "ccGLStateCache.h" +#include "CustomCommand.h" + NS_CC_BEGIN using namespace std; @@ -144,11 +146,12 @@ void Renderer::render() if(_lastMaterialID != cmd->getMaterialID() || _numQuads == VBO_SIZE) { //Draw batched data - if(_numQuads > 0) - { - drawQuads(); - } + drawQuads(); + } + //Reset material if needed. + if(_lastMaterialID != cmd->getMaterialID()) + { //Set new material _lastMaterialID = cmd->getMaterialID(); @@ -161,10 +164,19 @@ void Renderer::render() GL::bindTexture2D(cmd->getTextureID()); } + batchQuads(cmd); break; } + case CUSTOM_COMMAND: + { + flush(); + CustomCommand* cmd = (CustomCommand*)command; + cmd->execute(); + + break; + } default: break; } @@ -179,6 +191,9 @@ void Renderer::render() void Renderer::drawQuads() { + if(_numQuads <= 0) + return; + //Set VBO data glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); @@ -207,4 +222,10 @@ void Renderer::batchQuads(QuadCommand* cmd) _quads[_numQuads - 1] = *cmd->getQuad(); } +void Renderer::flush() +{ + drawQuads(); + _lastMaterialID = 0; +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 9105443281..53f0f0ae2f 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -12,6 +12,7 @@ #include "RenderCommand.h" #include "CCGLProgram.h" #include "QuadCommand.h" +#include "CCGL.h" #define VBO_SIZE 64 @@ -39,11 +40,13 @@ protected: void batchQuads(QuadCommand* cmd); void drawQuads(); + //Draw the previews queued quads and flush previous context + void flush(); + protected: vector _renderQueue; int _lastMaterialID; - V3F_C4B_T2F_Quad*_quads; GLushort* _indices; GLuint _VAOname; From 050f3f705eb136133e7facfb6d97dbf8ac642883 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 8 Nov 2013 13:57:21 -0800 Subject: [PATCH 12/98] minor code format fix --- cocos/2d/CCTextureAtlas.h | 2 ++ cocos/2d/renderer/QuadCommand.cpp | 5 +++++ cocos/2d/renderer/Renderer.cpp | 14 +++++--------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cocos/2d/CCTextureAtlas.h b/cocos/2d/CCTextureAtlas.h index 1e5ec742d7..8e5a937337 100644 --- a/cocos/2d/CCTextureAtlas.h +++ b/cocos/2d/CCTextureAtlas.h @@ -215,6 +215,8 @@ public: void setQuads(V3F_C4B_T2F_Quad* quads); private: + void renderCommand(); + void setupIndices(); void mapBuffers(); #if CC_TEXTURE_ATLAS_USE_VAO diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 63e3275a78..391664148d 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -76,6 +76,11 @@ void QuadCommand::useMaterial() _shader->use(); //TODO once everything is using world coordinate, we can reduce the uniforms for shaders _shader->setUniformsForBuiltins(); + + //TODO set blend mode + + //Set texture + GL::bindTexture2D(_textureID); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 67078d4894..867c2ac8f5 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -7,6 +7,7 @@ #include "CCShaderCache.h" #include "ccGLStateCache.h" #include "CustomCommand.h" +#include "CCGL.h" NS_CC_BEGIN @@ -132,7 +133,7 @@ void Renderer::render() stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); //2. Process commands - for(vector::iterator it = _renderQueue.begin(); it != _renderQueue.end(); ++it) + for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it) { //TODO: Perform Sprite batching here auto command = *it; @@ -141,9 +142,9 @@ void Renderer::render() { case QUAD_COMMAND: { - QuadCommand* cmd = (QuadCommand*)command; + QuadCommand* cmd = static_cast(command); - if(_lastMaterialID != cmd->getMaterialID() || _numQuads == VBO_SIZE) + if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE) { //Draw batched data drawQuads(); @@ -157,11 +158,6 @@ void Renderer::render() //Set Shader cmd->useMaterial(); - - //TODO: Set Blend Mode - - //Set texture - GL::bindTexture2D(cmd->getTextureID()); } @@ -172,7 +168,7 @@ void Renderer::render() case CUSTOM_COMMAND: { flush(); - CustomCommand* cmd = (CustomCommand*)command; + CustomCommand* cmd = static_cast(command); cmd->execute(); break; From f68a2a47e73cc5bb39c6eadb9711db86ff759bfc Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 11 Nov 2013 00:14:29 -0800 Subject: [PATCH 13/98] Improved batching --- cocos/2d/CustomCommand.cpp | 3 +- cocos/2d/CustomCommand.h | 7 +- cocos/2d/renderer/QuadCommand.cpp | 4 +- cocos/2d/renderer/QuadCommand.h | 9 +- cocos/2d/renderer/Renderer.cpp | 179 +++++++++++++++++++++--------- cocos/2d/renderer/Renderer.h | 9 +- 6 files changed, 146 insertions(+), 65 deletions(-) diff --git a/cocos/2d/CustomCommand.cpp b/cocos/2d/CustomCommand.cpp index ee92cd6bd2..86befadde6 100644 --- a/cocos/2d/CustomCommand.cpp +++ b/cocos/2d/CustomCommand.cpp @@ -27,8 +27,7 @@ int64_t CustomCommand::generateID() _id = (int64_t)_viewport << 61 | (int64_t)1 << 60 // translucent - | (int64_t)0 << 59 // is command - | (int64_t)_depth << 35; + | (int64_t)_depth << 36; return _id; } diff --git a/cocos/2d/CustomCommand.h b/cocos/2d/CustomCommand.h index a0f3bcd8ff..bc6dc99684 100644 --- a/cocos/2d/CustomCommand.h +++ b/cocos/2d/CustomCommand.h @@ -20,8 +20,8 @@ public: // +----------+----------+-----+-----------------------------------+ // | | | | | | - // | ViewPort | Transluc | Cmd | Depth | | - // | 3 bits | 1 bit | 1 | 24 bits | | + // | ViewPort | Transluc | | Depth | | + // | 3 bits | 1 bit | | 24 bits | | // +----------+----------+-----+----------------+------------------+ virtual int64_t generateID(); @@ -29,9 +29,6 @@ public: inline bool isTranslucent() { return true; } - //TODO support non-graphical command - inline bool isCommand() { return false; } - public: function func; diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 391664148d..95a65f28f2 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -18,6 +18,7 @@ QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgra { _type = QUAD_COMMAND; _shader = shader; + _quadCount = 1; } QuadCommand::~QuadCommand() @@ -65,8 +66,7 @@ int64_t QuadCommand::generateID() //Generate RenderCommandID _id = (int64_t)_viewport << 61 | (int64_t)1 << 60 //translucent - | (int64_t)0 << 59 //is command - | (int64_t)_depth << 35; + | (int64_t)_depth << 36; return _id; } diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index fb1ec48328..6b984b322f 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -21,8 +21,8 @@ public: // +----------+----------+-----+-----------------------------------+ // | | | | | | - // | ViewPort | Transluc | Cmd | Depth | Material ID | - // | 3 bits | 1 bit | 1 | 24 bits | 24 bit2 | + // | ViewPort | Transluc | | Depth | Material ID | + // | 3 bits | 1 bit | | 24 bits | 24 bit2 | // +----------+----------+-----+----------------+------------------+ virtual int64_t generateID(); @@ -31,14 +31,14 @@ public: //TODO use material to decide if it is translucent inline bool isTranslucent() { return true; } - inline bool isCommand() { return false; } - inline int32_t getMaterialID() { return _materialID; } inline GLuint getTextureID() { return _textureID; } inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } + inline int getQuadCount() { return _quadCount; } + inline GLProgram* getShader() { return _shader; } inline BlendFunc getBlendType() { return _blendType; } @@ -61,6 +61,7 @@ protected: BlendFunc _blendType; V3F_C4B_T2F_Quad _quad; + int _quadCount; }; NS_CC_END diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 867c2ac8f5..dbb8450da4 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -36,27 +36,18 @@ void Renderer::destroyInstance() Renderer::Renderer() :_lastMaterialID(0) ,_numQuads(0) +,_firstCommand(0) +,_lastCommand(0) { } Renderer::~Renderer() { - free(_quads); } bool Renderer::init() { - _quads = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * VBO_SIZE); - _indices = (GLushort*) malloc(sizeof(GLushort) * 6 * VBO_SIZE); - if( ! ( _quads && _indices) ) - { - //not enough memory - CC_SAFE_FREE(_quads); - CC_SAFE_FREE(_indices); - return false; - } - setupIndices(); setupVBOAndVAO(); @@ -132,57 +123,145 @@ void Renderer::render() //1. Sort render commands based on ID stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); - //2. Process commands - for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it) + size_t len = _renderQueue.size(); + + for (size_t i = 0; i < len; i++) { - //TODO: Perform Sprite batching here - auto command = *it; + auto command = _renderQueue[i]; - switch(command->getType()) + if( command->getType() == QUAD_COMMAND ) { - case QUAD_COMMAND: + QuadCommand* cmd = static_cast(command); + + // + if(_numQuads + cmd->getQuadCount() < VBO_SIZE) { - QuadCommand* cmd = static_cast(command); - - if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE) - { - //Draw batched data - drawQuads(); - } - - //Reset material if needed. - if(_lastMaterialID != cmd->getMaterialID()) - { - //Set new material - _lastMaterialID = cmd->getMaterialID(); - - //Set Shader - cmd->useMaterial(); - } - - - batchQuads(cmd); - - break; + memcpy(_quads + _numQuads - 1, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); + _numQuads += cmd->getQuadCount(); + _lastCommand = i; } - case CUSTOM_COMMAND: + else { - flush(); - CustomCommand* cmd = static_cast(command); - cmd->execute(); - - break; + //Draw batched quads if VBO is full + drawBatchedQuads(); } - default: - break; + + } + else + { + //Draw batched quads if we encountered a different command + drawBatchedQuads(); } - - delete command; } - drawQuads(); + //Draw the batched quads + drawBatchedQuads(); + _firstCommand = _lastCommand = 0; + _lastMaterialID = 0; _renderQueue.clear(); + +// //2. Process commands +// for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it) +// { +// //TODO: Perform Sprite batching here +// auto command = *it; +// +// switch(command->getType()) +// { +// case QUAD_COMMAND: +// { +// QuadCommand* cmd = static_cast(command); +// +// if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE) +// { +// //Draw batched data +// drawQuads(); +// } +// +// //Reset material if needed. +// if(_lastMaterialID != cmd->getMaterialID()) +// { +// //Set new material +// _lastMaterialID = cmd->getMaterialID(); +// +// //Set Shader +// cmd->useMaterial(); +// } +// +// batchQuads(cmd); +// +// break; +// } +// case CUSTOM_COMMAND: +// { +// flush(); +// CustomCommand* cmd = static_cast(command); +// cmd->execute(); +// +// break; +// } +// default: +// break; +// } +// +// delete command; +// } +// +// drawQuads(); +// +// _renderQueue.clear(); +} + +void Renderer::drawBatchedQuads() +{ + int quadsToDraw = 0; + int startQuad = 0; + + //Upload buffer to VBO + if(_numQuads <= 0) + return; + + //Set VBO data + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + + glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW); + void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + //Bind VAO + GL::bindVAO(_VAOname); + + for(size_t i = _firstCommand; i <= _lastCommand; i++) + { + RenderCommand* command = _renderQueue[i]; + if (command->getType() == QUAD_COMMAND) + { + QuadCommand* cmd = static_cast(command); + if(_lastMaterialID != cmd->getMaterialID()) + { + //Draw quads + if(quadsToDraw > 0) + { + glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + startQuad += quadsToDraw; + quadsToDraw = 0; + } + + //Use new material + cmd->useMaterial(); + _lastMaterialID = cmd->getMaterialID(); + } + + quadsToDraw += cmd->getQuadCount(); + } + } + + _firstCommand = _lastCommand; + _numQuads = 0; } void Renderer::drawQuads() diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 53f0f0ae2f..d8c85e6836 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -47,12 +47,17 @@ protected: vector _renderQueue; int _lastMaterialID; - V3F_C4B_T2F_Quad*_quads; - GLushort* _indices; + size_t _firstCommand; + size_t _lastCommand; + + V3F_C4B_T2F_Quad _quads[VBO_SIZE]; + GLushort _indices[6 * VBO_SIZE]; GLuint _VAOname; GLuint _buffersVBO[2]; //0: vertex 1: indices int _numQuads; + + void drawBatchedQuads(); }; NS_CC_END From f6fb48ba56514946eafc2d5711e759a4acb4c1a2 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 11 Nov 2013 11:54:08 -0800 Subject: [PATCH 14/98] Fix crashing bug --- cocos/2d/renderer/Renderer.cpp | 142 +++++++++------------------------ cocos/2d/renderer/Renderer.h | 12 +-- 2 files changed, 42 insertions(+), 112 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index dbb8450da4..0f2aebdeff 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -7,6 +7,7 @@ #include "CCShaderCache.h" #include "ccGLStateCache.h" #include "CustomCommand.h" +#include "QuadCommand.h" #include "CCGL.h" @@ -129,88 +130,47 @@ void Renderer::render() { auto command = _renderQueue[i]; - if( command->getType() == QUAD_COMMAND ) + switch (command->getType()) { - QuadCommand* cmd = static_cast(command); - - // - if(_numQuads + cmd->getQuadCount() < VBO_SIZE) + case QUAD_COMMAND: { - memcpy(_quads + _numQuads - 1, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); - _numQuads += cmd->getQuadCount(); - _lastCommand = i; - } - else - { - //Draw batched quads if VBO is full - drawBatchedQuads(); - } + QuadCommand* cmd = static_cast(command); - } - else - { - //Draw batched quads if we encountered a different command - drawBatchedQuads(); + //Batch quads + if(_numQuads + cmd->getQuadCount() < VBO_SIZE) + { + memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); + _numQuads += cmd->getQuadCount(); + _lastCommand = i; + } + else + { + //Draw batched quads if VBO is full + drawBatchedQuads(); + } + break; + } + case CUSTOM_COMMAND: + { + flush(); + CustomCommand* cmd = static_cast(command); + cmd->execute(); + } + default: + flush(); + break; } } //Draw the batched quads drawBatchedQuads(); + //TODO give command back to command pool + for_each(_renderQueue.begin(), _renderQueue.end(), [](RenderCommand* cmd){delete cmd;}); + _firstCommand = _lastCommand = 0; _lastMaterialID = 0; _renderQueue.clear(); - -// //2. Process commands -// for(auto it = _renderQueue.begin(); it != _renderQueue.end(); ++it) -// { -// //TODO: Perform Sprite batching here -// auto command = *it; -// -// switch(command->getType()) -// { -// case QUAD_COMMAND: -// { -// QuadCommand* cmd = static_cast(command); -// -// if(_lastMaterialID != cmd->getMaterialID() || _numQuads >= VBO_SIZE) -// { -// //Draw batched data -// drawQuads(); -// } -// -// //Reset material if needed. -// if(_lastMaterialID != cmd->getMaterialID()) -// { -// //Set new material -// _lastMaterialID = cmd->getMaterialID(); -// -// //Set Shader -// cmd->useMaterial(); -// } -// -// batchQuads(cmd); -// -// break; -// } -// case CUSTOM_COMMAND: -// { -// flush(); -// CustomCommand* cmd = static_cast(command); -// cmd->execute(); -// -// break; -// } -// default: -// break; -// } -// -// delete command; -// } -// -// drawQuads(); -// -// _renderQueue.clear(); } void Renderer::drawBatchedQuads() @@ -235,6 +195,7 @@ void Renderer::drawBatchedQuads() //Bind VAO GL::bindVAO(_VAOname); + //Start drawing verties in batch for(size_t i = _firstCommand; i <= _lastCommand; i++) { RenderCommand* command = _renderQueue[i]; @@ -260,46 +221,19 @@ void Renderer::drawBatchedQuads() } } + //Draw any remaining quad + if(quadsToDraw > 0) + { + glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + } + _firstCommand = _lastCommand; _numQuads = 0; } -void Renderer::drawQuads() -{ - if(_numQuads <= 0) - return; - - //Set VBO data - glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); - - glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW); - void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); - glUnmapBuffer(GL_ARRAY_BUFFER); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - //Bind VAO - GL::bindVAO(_VAOname); - - glDrawElements(GL_TRIANGLES, (GLsizei) _numQuads*6, GL_UNSIGNED_SHORT, 0 ); - - CHECK_GL_ERROR_DEBUG(); - CC_INCREMENT_GL_DRAWS(1); - - _numQuads = 0; -} - -void Renderer::batchQuads(QuadCommand* cmd) -{ - //Batch data - _numQuads++; //Every quad command only contains one quad - _quads[_numQuads - 1] = *cmd->getQuad(); -} - void Renderer::flush() { - drawQuads(); + drawBatchedQuads(); _lastMaterialID = 0; } diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index d8c85e6836..f89129ed2a 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -4,15 +4,14 @@ -#ifndef __CCRENDERER_H_ -#define __CCRENDERER_H_ +#ifndef __CC_RENDERER_H_ +#define __CC_RENDERER_H_ #include "CCPlatformMacros.h" -#include "CCEGLView.h" #include "RenderCommand.h" #include "CCGLProgram.h" -#include "QuadCommand.h" #include "CCGL.h" +#include #define VBO_SIZE 64 @@ -37,9 +36,6 @@ protected: void setupIndices(); void setupVBOAndVAO(); - void batchQuads(QuadCommand* cmd); - void drawQuads(); - //Draw the previews queued quads and flush previous context void flush(); @@ -62,4 +58,4 @@ protected: NS_CC_END -#endif //__CCRENDERER_H_ +#endif //__CC_RENDERER_H_ From ab8b61aaecb8886d473ebc3714982efd64f4e5df Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 12 Nov 2013 11:14:34 -0800 Subject: [PATCH 15/98] Create NewSpriteBatchNode to use NewRender --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCNewSprite.cpp | 7 +- cocos/2d/CCNewSprite.h | 1 + cocos/2d/CCNewSpriteBatchNode.cpp | 103 ++++++++++++++++++ cocos/2d/CCNewSpriteBatchNode.h | 37 +++++++ cocos/2d/CCNewTextureAtlas.cpp | 58 ++++++++++ cocos/2d/CCNewTextureAtlas.h | 31 ++++++ cocos/2d/renderer/QuadCommand.cpp | 9 +- cocos/2d/renderer/QuadCommand.h | 6 +- cocos/2d/renderer/Renderer.cpp | 3 + cocos/2d/renderer/Renderer.h | 2 +- 11 files changed, 249 insertions(+), 10 deletions(-) create mode 100644 cocos/2d/CCNewSpriteBatchNode.cpp create mode 100644 cocos/2d/CCNewSpriteBatchNode.h create mode 100644 cocos/2d/CCNewTextureAtlas.cpp create mode 100644 cocos/2d/CCNewTextureAtlas.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 116c3b021b..3716b65641 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -cf362fb305dd6fddbfe3d6a139760ef2b8b94594 \ No newline at end of file +be9e000b84174e93d12ddd3b2508145ec5cf11bd \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 92d5bc5a3c..6863ec27f2 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -49,6 +49,10 @@ NewSprite::NewSprite() } +NewSprite::~NewSprite(void) +{ +} + void NewSprite::updateTransform() { if(_dirty) @@ -109,7 +113,8 @@ void NewSprite::updateTransform() void NewSprite::draw(void) { updateTransform(); - QuadCommand* renderCommand = new QuadCommand(0, _ZOrder,_texture->getName(), _shaderProgram, _blendFunc, _quad); + //TODO implement z order + QuadCommand* renderCommand = new QuadCommand(0, 0,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addRenderCommand(renderCommand); } diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index 62a52495f6..5b80716dd1 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -22,6 +22,7 @@ public: static NewSprite* create(const char *filename); NewSprite(void); + ~NewSprite(); virtual void updateTransform(); virtual void draw(void) override; diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp new file mode 100644 index 0000000000..49442fbaa8 --- /dev/null +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -0,0 +1,103 @@ +// +// Created by NiTe Luo on 11/11/13. +// + + +#include "CCNewSpriteBatchNode.h" +#include "CCDirector.h" +#include "CCShaderCache.h" +#include "CCTextureCache.h" +#include "CCSprite.h" +#include "CCNewSprite.h" +#include "QuadCommand.h" +#include "Renderer.h" + +NS_CC_BEGIN + +NewSpriteBatchNode *NewSpriteBatchNode::createWithTexture(Texture2D *tex, int capacity) +{ + NewSpriteBatchNode* batchNode = new NewSpriteBatchNode(); + batchNode->initWithTexture(tex, capacity); + batchNode->autorelease(); + + return batchNode; +} + +NewSpriteBatchNode *NewSpriteBatchNode::create(const char *fileImage, long capacity) +{ + NewSpriteBatchNode* batchNode = new NewSpriteBatchNode(); + batchNode->initWithFile(fileImage, capacity); + batchNode->autorelease(); + + return nullptr; +} + +NewSpriteBatchNode::NewSpriteBatchNode() +:SpriteBatchNode() +{ + +} + +NewSpriteBatchNode::~NewSpriteBatchNode() +{ + +} + +bool NewSpriteBatchNode::initWithTexture(Texture2D *tex, long capacity) +{ + CCASSERT(capacity>=0, "Capacity must be >= 0"); + + _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; + _textureAtlas = new TextureAtlas(); + + if (capacity == 0) + { + capacity = DEFAULT_CAPACITY; + } + + _textureAtlas->initWithTexture(tex, capacity); + + updateBlendFunc(); + + // no lazy alloc in this node + _children = new Array(); + _children->initWithCapacity(capacity); + + _descendants.reserve(capacity); + + setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); + return true; +} + +bool NewSpriteBatchNode::initWithFile(const char *fileImage, long capacity) +{ + Texture2D* tex = Director::getInstance()->getTextureCache()->addImage(fileImage); + return initWithTexture(tex, capacity); +} + +bool NewSpriteBatchNode::init() +{ + Texture2D* texture = new Texture2D(); + texture->autorelease(); + return this->initWithTexture(texture, 0); +} + +void NewSpriteBatchNode::draw() +{ + // Optimization: Fast Dispatch + if( _textureAtlas->getTotalQuads() == 0 ) + { + return; + } + + CC_NODE_DRAW_SETUP(); + + arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); + + GL::blendFunc( _blendFunc.src, _blendFunc.dst ); + + QuadCommand* cmd = new QuadCommand(0, 0, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); + Renderer::getInstance()->addRenderCommand(cmd); +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSpriteBatchNode.h b/cocos/2d/CCNewSpriteBatchNode.h new file mode 100644 index 0000000000..fe73796436 --- /dev/null +++ b/cocos/2d/CCNewSpriteBatchNode.h @@ -0,0 +1,37 @@ +// +// Created by NiTe Luo on 11/11/13. +// + + + +#ifndef __CCNewSpriteBatchNode_H_ +#define __CCNewSpriteBatchNode_H_ + +#include "CCPlatformMacros.h" +#include "CCTexture2D.h" +#include "CCSpriteBatchNode.h" + +NS_CC_BEGIN + +class NewSpriteBatchNode : public SpriteBatchNode +{ + static const int DEFAULT_CAPACITY = 29; +public: + static NewSpriteBatchNode* createWithTexture(Texture2D* tex, int capacity = DEFAULT_CAPACITY); + static NewSpriteBatchNode* create(const char* fileImage, long capacity = DEFAULT_CAPACITY); + + NewSpriteBatchNode(); + virtual ~NewSpriteBatchNode(); + + bool initWithTexture(Texture2D *tex, long capacity); + + bool initWithFile(const char* fileImage, long capacity); + + bool init(); + + void draw(void); +}; + +NS_CC_END + +#endif //__CCNewSpriteBatchNode_H_ diff --git a/cocos/2d/CCNewTextureAtlas.cpp b/cocos/2d/CCNewTextureAtlas.cpp new file mode 100644 index 0000000000..ee8be29b4d --- /dev/null +++ b/cocos/2d/CCNewTextureAtlas.cpp @@ -0,0 +1,58 @@ +// +// Created by NiTe Luo on 11/11/13. +// + + +#include "CCNewTextureAtlas.h" +#include "CCTexture2D.h" +#include "CCDirector.h" +#include "Renderer.h" +#include "QuadCommand.h" + +NS_CC_BEGIN + +NewTextureAtlas::NewTextureAtlas() +:TextureAtlas() +{ + +} + +NewTextureAtlas::~NewTextureAtlas() +{ + +} + +NewTextureAtlas *NewTextureAtlas::create(const char *file, long capacity) +{ + NewTextureAtlas * textureAtlas = new NewTextureAtlas(); + if(textureAtlas && textureAtlas->initWithFile(file, capacity)) + { + textureAtlas->autorelease(); + return textureAtlas; + } + CC_SAFE_DELETE(textureAtlas); + return NULL; +} + +NewTextureAtlas *NewTextureAtlas::createWithTexture(Texture2D *texture, long capacity) +{ + NewTextureAtlas * textureAtlas = new NewTextureAtlas(); + if (textureAtlas && textureAtlas->initWithTexture(texture, capacity)) + { + textureAtlas->autorelease(); + return textureAtlas; + } + CC_SAFE_DELETE(textureAtlas); + return NULL; +} + + +void NewTextureAtlas::drawNumberOfQuads(long numberOfQuads, long start) +{ +// updateTransform(); +// QuadCommand* renderCommand = new QuadCommand(0, 0,_texture->getName(), _shaderProgram, _blendFunc, _quad); +// +// Renderer::getInstance()->addRenderCommand(renderCommand); +} + +NS_CC_END diff --git a/cocos/2d/CCNewTextureAtlas.h b/cocos/2d/CCNewTextureAtlas.h new file mode 100644 index 0000000000..32550bd972 --- /dev/null +++ b/cocos/2d/CCNewTextureAtlas.h @@ -0,0 +1,31 @@ +// +// Created by NiTe Luo on 11/11/13. +// + + + +#ifndef __CCNewTextureAtlas_H_ +#define __CCNewTextureAtlas_H_ + +#include "CCPlatformMacros.h" +#include "CCTextureAtlas.h" + +NS_CC_BEGIN + +class NewTextureAtlas : public TextureAtlas +{ +public: + static NewTextureAtlas* create(const char* file, long capacity); + + static NewTextureAtlas* createWithTexture(Texture2D *texture, long capacity); + + NewTextureAtlas(); + + virtual ~NewTextureAtlas(); + + void drawNumberOfQuads(long numberOfQuads, long start); +}; + +NS_CC_END + +#endif //__CCNewTextureAtlas_H_ diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 95a65f28f2..972f28ffe4 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -8,22 +8,23 @@ NS_CC_BEGIN -QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad quad) +QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount) :RenderCommand() ,_viewport(viewport) ,_depth(depth) ,_textureID(textureID) ,_blendType(blendType) -,_quad(quad) +,_quadCount(quadCount) { _type = QUAD_COMMAND; _shader = shader; - _quadCount = 1; + _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); + memcpy(_quad, quad, sizeof(V3F_C4B_T2F_Quad) * quadCount); } QuadCommand::~QuadCommand() { - + free(_quad); } int64_t QuadCommand::generateID() diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 6b984b322f..9483ee8439 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -16,7 +16,7 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { public: - QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad quad); + QuadCommand(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); ~QuadCommand(); // +----------+----------+-----+-----------------------------------+ @@ -35,7 +35,7 @@ public: inline GLuint getTextureID() { return _textureID; } - inline V3F_C4B_T2F_Quad* getQuad() { return &_quad; } + inline V3F_C4B_T2F_Quad* getQuad() { return _quad; } inline int getQuadCount() { return _quadCount; } @@ -60,7 +60,7 @@ protected: BlendFunc _blendType; - V3F_C4B_T2F_Quad _quad; + V3F_C4B_T2F_Quad* _quad; int _quadCount; }; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 0f2aebdeff..2c471d8924 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -3,6 +3,7 @@ // +#include #include "Renderer.h" #include "CCShaderCache.h" #include "ccGLStateCache.h" @@ -136,6 +137,8 @@ void Renderer::render() { QuadCommand* cmd = static_cast(command); + CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) { diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index f89129ed2a..354d8e9f86 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -13,7 +13,7 @@ #include "CCGL.h" #include -#define VBO_SIZE 64 +#define VBO_SIZE 1024 NS_CC_BEGIN using namespace std; From 8c972d96a889c20f7d95d6dd07a6a11ef685b918 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 12 Nov 2013 11:19:18 -0800 Subject: [PATCH 16/98] Create new test for NewRenderer --- cocos/2d/CCNewSpriteBatchNode.cpp | 4 - .../NewRendererTest/NewRendererTest.cpp | 128 ++++++++++++++++-- .../Classes/NewRendererTest/NewRendererTest.h | 36 +++-- samples/Cpp/TestCpp/Classes/tests.h | 2 +- 4 files changed, 146 insertions(+), 24 deletions(-) diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp index 49442fbaa8..ee94483073 100644 --- a/cocos/2d/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -90,12 +90,8 @@ void NewSpriteBatchNode::draw() return; } - CC_NODE_DRAW_SETUP(); - arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); - QuadCommand* cmd = new QuadCommand(0, 0, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); Renderer::getInstance()->addRenderCommand(cmd); } diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index b0633c099b..121e0e9cf2 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -6,8 +6,112 @@ #include "NewRendererTest.h" #include "CCNewSprite.h" +static int sceneIdx = -1; -NewRendererTest::NewRendererTest() +Layer* nextSpriteTestAction(); +Layer* backSpriteTestAction(); +Layer* restartSpriteTestAction(); + +static std::function createFunctions[] = +{ + CL(NewRendererTest), +}; + +#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) + +Layer* nextTest() +{ + sceneIdx++; + sceneIdx = sceneIdx % MAX_LAYER; + + auto layer = (createFunctions[sceneIdx])(); + layer->autorelease(); + + return layer; +} + +Layer* prevTest() +{ + sceneIdx--; + int total = MAX_LAYER; + if( sceneIdx < 0 ) + sceneIdx += total; + + auto layer = (createFunctions[sceneIdx])(); + layer->autorelease(); + + return layer; +} + +Layer* restartTest() +{ + auto layer = (createFunctions[sceneIdx])(); + layer->autorelease(); + + return layer; +} + +void NewRendererTestScene::runThisTest() +{ + auto layer = nextTest(); + addChild(layer); + + Director::getInstance()->replaceScene(this); +} + +MultiSceneTest::MultiSceneTest() +{ + +} + +MultiSceneTest::~MultiSceneTest() +{ + +} + +string MultiSceneTest::title() +{ + return BaseTest::title(); +} + +string MultiSceneTest::subtitle() +{ + return BaseTest::subtitle(); +} + +void MultiSceneTest::onEnter() +{ + BaseTest::onEnter(); +} + +void MultiSceneTest::restartCallback(Object *sender) +{ + auto s = new NewRendererTestScene(); + s->addChild(restartTest()); + + Director::getInstance()->replaceScene(s); + s->release(); +} + +void MultiSceneTest::nextCallback(Object *sender) +{ + auto s = new NewRendererTestScene(); + s->addChild(nextTest()); + + Director::getInstance()->replaceScene(s); + s->release(); +} + +void MultiSceneTest::backCallback(Object *sender) +{ + auto s = new NewRendererTestScene(); + s->addChild(prevTest()); + + Director::getInstance()->replaceScene(s); + s->release(); +} + +NewSpriteTest::NewRendererTest() { auto touchListener = EventListenerTouchAllAtOnce::create(); touchListener->onTouchesEnded = CC_CALLBACK_2(NewRendererTest::onTouchesEnded, this); @@ -16,12 +120,12 @@ NewRendererTest::NewRendererTest() createNewSpriteTest(); } -NewRendererTest::~NewRendererTest() +NewSpriteTest::~NewRendererTest() { } -void NewRendererTest::createSpriteTest() +void NewSpriteTest::createSpriteTest() { Size winSize = Director::getInstance()->getWinSize(); @@ -52,7 +156,7 @@ void NewRendererTest::createSpriteTest() addChild(parent); } -void NewRendererTest::createNewSpriteTest() +void NewSpriteTest::createNewSpriteTest() { Size winSize = Director::getInstance()->getWinSize(); @@ -83,16 +187,18 @@ void NewRendererTest::createNewSpriteTest() addChild(parent); } -void NewRendererTest::onTouchesEnded(const std::vector &touches, Event *event) +void NewSpriteTest::onTouchesEnded(const std::vector &touches, Event *event) { } -void NewRendererTestScene::runThisTest() -{ - auto layer = new NewRendererTest(); - addChild(layer); - Director::getInstance()->replaceScene(this); - layer->release(); +string NewSpriteTest::title() +{ + return "NewRender"; +} + +string NewSpriteTest::subtitle() +{ + return "SpriteTest"; } diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 5a568bc621..e79f4ad4cb 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -11,11 +11,37 @@ #include "../testBasic.h" #include "../BaseTest.h" -class NewRendererTest : public Layer +using namespace std; + +class NewRendererTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + +class MultiSceneTest : public BaseTest +{ +public: + MultiSceneTest(); + virtual ~MultiSceneTest(); + + virtual string title(); + virtual string subtitle(); + virtual void onEnter(); + + void restartCallback(Object* sender); + void nextCallback(Object* sender); + void backCallback(Object* sender); +}; + +class NewSpriteTest : public MultiSceneTest { public: NewRendererTest(); - ~NewRendererTest(); + virtual ~NewRendererTest(); + + virtual string title(); + virtual string subtitle(); void createSpriteTest(); void createNewSpriteTest(); @@ -25,11 +51,5 @@ protected: }; -class NewRendererTestScene : public TestScene -{ -public: - virtual void runThisTest(); -}; - #endif //__NewRendererTest_H_ diff --git a/samples/Cpp/TestCpp/Classes/tests.h b/samples/Cpp/TestCpp/Classes/tests.h index f94c3b7c7b..7caec2abc1 100644 --- a/samples/Cpp/TestCpp/Classes/tests.h +++ b/samples/Cpp/TestCpp/Classes/tests.h @@ -1,7 +1,7 @@ #ifndef _TESTS_H_ #define _TESTS_H_ -#include "NewRendererTest/NewRendererTest.h" +#include "NewRendererTest.h" #include "NewEventDispatcherTest/NewEventDispatcherTest.h" #include "ActionsTest/ActionsTest.h" #include "TransitionsTest/TransitionsTest.h" From d7b76a871ebd079baa306fc68880043f7dd48c93 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 12 Nov 2013 11:23:10 -0800 Subject: [PATCH 17/98] Make sure it compiles after Change in test --- .../TestCpp/Classes/NewRendererTest/NewRendererTest.cpp | 8 ++++---- .../Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 121e0e9cf2..bad4eae26a 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -14,7 +14,7 @@ Layer* restartSpriteTestAction(); static std::function createFunctions[] = { - CL(NewRendererTest), + CL(NewSpriteTest), }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -111,16 +111,16 @@ void MultiSceneTest::backCallback(Object *sender) s->release(); } -NewSpriteTest::NewRendererTest() +NewSpriteTest::NewSpriteTest() { auto touchListener = EventListenerTouchAllAtOnce::create(); - touchListener->onTouchesEnded = CC_CALLBACK_2(NewRendererTest::onTouchesEnded, this); + touchListener->onTouchesEnded = CC_CALLBACK_2(NewSpriteTest::onTouchesEnded, this); createSpriteTest(); createNewSpriteTest(); } -NewSpriteTest::~NewRendererTest() +NewSpriteTest::~NewSpriteTest() { } diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index e79f4ad4cb..3e98250721 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -37,8 +37,8 @@ public: class NewSpriteTest : public MultiSceneTest { public: - NewRendererTest(); - virtual ~NewRendererTest(); + NewSpriteTest(); + virtual ~NewSpriteTest(); virtual string title(); virtual string subtitle(); From 0c0c11be5c6ac349041e0fbef642e1a8f152984d Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 12 Nov 2013 11:53:53 -0800 Subject: [PATCH 18/98] Finish NewSpriteBatchTest --- cocos/2d/CCNewSpriteBatchNode.cpp | 2 +- .../NewRendererTest/NewRendererTest.cpp | 72 +++++++++++++++++++ .../Classes/NewRendererTest/NewRendererTest.h | 16 +++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp index ee94483073..cf782e0701 100644 --- a/cocos/2d/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -29,7 +29,7 @@ NewSpriteBatchNode *NewSpriteBatchNode::create(const char *fileImage, long capac batchNode->initWithFile(fileImage, capacity); batchNode->autorelease(); - return nullptr; + return batchNode; } NewSpriteBatchNode::NewSpriteBatchNode() diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index bad4eae26a..3a2db0efdb 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -5,6 +5,7 @@ #include "NewRendererTest.h" #include "CCNewSprite.h" +#include "CCNewSpriteBatchNode.h" static int sceneIdx = -1; @@ -15,6 +16,7 @@ Layer* restartSpriteTestAction(); static std::function createFunctions[] = { CL(NewSpriteTest), + CL(NewSpriteBatchTest), }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -202,3 +204,73 @@ string NewSpriteTest::subtitle() { return "SpriteTest"; } + +//-------- New Sprite Batch Test + +NewSpriteBatchTest::NewSpriteBatchTest() +{ + auto touchListener = EventListenerTouchAllAtOnce::create(); + touchListener->onTouchesEnded = CC_CALLBACK_2(NewSpriteBatchTest::onTouchesEnded, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); + + auto BatchNode = NewSpriteBatchNode::create("Images/grossini_dance_atlas.png", 50); + addChild(BatchNode, 0, kTagSpriteBatchNode); +} + +NewSpriteBatchTest::~NewSpriteBatchTest() +{ + +} + +string NewSpriteBatchTest::title() +{ + return "NewRender"; +} + +string NewSpriteBatchTest::subtitle() +{ + return "SpriteBatchTest"; +} + +void NewSpriteBatchTest::onTouchesEnded(const vector &touches, Event *event) +{ + for (auto &touch : touches) + { + auto location = touch->getLocation(); + addNewSpriteWithCoords(location); + } +} + +void NewSpriteBatchTest::addNewSpriteWithCoords(Point p) +{ + auto BatchNode = static_cast( getChildByTag(kTagSpriteBatchNode) ); + + int idx = CCRANDOM_0_1() * 1400 / 100; + int x = (idx%5) * 85; + int y = (idx/5) * 121; + + + auto sprite = Sprite::createWithTexture(BatchNode->getTexture(), Rect(x,y,85,121)); + BatchNode->addChild(sprite); + + sprite->setPosition( Point( p.x, p.y) ); + +// ActionInterval* action; +// float random = CCRANDOM_0_1(); +// +// if( random < 0.20 ) +// action = ScaleBy::create(3, 2); +// else if(random < 0.40) +// action = RotateBy::create(3, 360); +// else if( random < 0.60) +// action = Blink::create(1, 3); +// else if( random < 0.8 ) +// action = TintBy::create(2, 0, -255, -255); +// else +// action = FadeOut::create(2); +// +// auto action_back = action->reverse(); +// auto seq = Sequence::create(action, action_back, NULL); +// +// sprite->runAction( RepeatForever::create(seq)); +} \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 3e98250721..30754a97bf 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -13,6 +13,8 @@ using namespace std; +#define kTagSpriteBatchNode 100 + class NewRendererTestScene : public TestScene { public: @@ -51,5 +53,19 @@ protected: }; +class NewSpriteBatchTest : public MultiSceneTest +{ +public: + NewSpriteBatchTest(); + virtual ~NewSpriteBatchTest(); + + virtual string title(); + virtual string subtitle(); + + void onTouchesEnded(const vector& touches, Event* event); + void addNewSpriteWithCoords(Point p); + +}; + #endif //__NewRendererTest_H_ From 05bc444ccbd6dde31e1667b74b380b0b7466de0a Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 13 Nov 2013 10:26:26 -0800 Subject: [PATCH 19/98] Add some optimization tips --- cocos/2d/renderer/Renderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 2c471d8924..23d453ba99 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -178,6 +178,8 @@ void Renderer::render() void Renderer::drawBatchedQuads() { + //TODO we can improve the draw performance by inseart material switching command before hand. + int quadsToDraw = 0; int startQuad = 0; From f17af1f3197a826ca41aaecf176d02ce51143fd3 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 13 Nov 2013 17:31:12 -0800 Subject: [PATCH 20/98] Add group command --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/GroupCommand.cpp | 36 ++++++++ cocos/2d/GroupCommand.h | 40 +++++++++ cocos/2d/renderer/RenderCommand.h | 5 +- cocos/2d/renderer/Renderer.cpp | 85 +++++++++++++++++-- cocos/2d/renderer/Renderer.h | 16 +++- 6 files changed, 170 insertions(+), 14 deletions(-) create mode 100644 cocos/2d/GroupCommand.cpp create mode 100644 cocos/2d/GroupCommand.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 3716b65641..f505d1f5ea 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -be9e000b84174e93d12ddd3b2508145ec5cf11bd \ No newline at end of file +2ac768774e5985125c7b8aec44806ade8178f5f6 \ No newline at end of file diff --git a/cocos/2d/GroupCommand.cpp b/cocos/2d/GroupCommand.cpp new file mode 100644 index 0000000000..46923eb1ee --- /dev/null +++ b/cocos/2d/GroupCommand.cpp @@ -0,0 +1,36 @@ +// +// Created by NiTe Luo on 11/13/13. +// + + +#include "GroupCommand.h" + +NS_CC_BEGIN + +GroupCommand::GroupCommand(int viewport, int32_t depth, int renderQueueID) +:RenderCommand() +, _viewport(viewport) +, _depth(depth) +, _renderQueueID(renderQueueID) +{ + _type = GROUP_COMMAND; +} + +GroupCommand::~GroupCommand() +{ + +} + +int64_t GroupCommand::generateID() +{ + _id = 0; + + _id = (int64_t)_viewport << 61 + | (int64_t)1 << 60 // translucent + | (int64_t)_depth << 36; + + return _id; +} + + +NS_CC_END diff --git a/cocos/2d/GroupCommand.h b/cocos/2d/GroupCommand.h new file mode 100644 index 0000000000..80c4fdd607 --- /dev/null +++ b/cocos/2d/GroupCommand.h @@ -0,0 +1,40 @@ +// +// Created by NiTe Luo on 11/13/13. +// + + + +#ifndef _CC_GROUPCOMMAND_H_ +#define _CC_GROUPCOMMAND_H_ + +#include "CCPlatformMacros.h" +#include "RenderCommand.h" + +NS_CC_BEGIN + +class GroupCommand : public RenderCommand +{ + +public: + GroupCommand(int viewport, int32_t depth, int renderQueueID); + ~GroupCommand(); + + // +----------+----------+-----+-----------------------------------+ + // | | | | | | + // | ViewPort | Transluc | | Depth | | + // | 3 bits | 1 bit | | 24 bits | | + // +----------+----------+-----+----------------+------------------+ + virtual int64_t generateID() override; + + inline bool isTranslucent() {return true;} + inline int getRenderQueueID() {return _renderQueueID;} + +protected: + int _viewport; + int32_t _depth; + int _renderQueueID; +}; + +NS_CC_END + +#endif //_CC_GROUPCOMMAND_H_ diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index fbc6678ed5..7c055e7cb7 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -31,11 +31,12 @@ public: virtual ~RenderCommand(); virtual int64_t generateID() = 0; - /** + virtual /** * Get Render Command Id */ inline int64_t getID() { return _id; } - inline RenderCommandType getType() { return _type; } + + virtual inline RenderCommandType getType() { return _type; } protected: void printID(); diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 23d453ba99..d3286c887c 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -10,6 +10,7 @@ #include "CustomCommand.h" #include "QuadCommand.h" #include "CCGL.h" +#include "GroupCommand.h" NS_CC_BEGIN @@ -41,11 +42,14 @@ Renderer::Renderer() ,_firstCommand(0) ,_lastCommand(0) { - + RenderQueue defaultRenderQueue; + _renderGroups.push_back(defaultRenderQueue); + _renderStack.push({DEFAULT_RENDER_QUEUE, 0}); } Renderer::~Renderer() { + _renderGroups.clear(); } bool Renderer::init() @@ -103,10 +107,10 @@ void Renderer::setupVBOAndVAO() CHECK_GL_ERROR_DEBUG(); } -void Renderer::addRenderCommand(RenderCommand *command) +void Renderer::addRenderCommand(RenderCommand *command, int renderQueue) { command->generateID(); - _renderQueue.push_back(command); + _renderGroups[renderQueue].push_back(command); } bool compareRenderCommand(RenderCommand* a, RenderCommand* b) @@ -123,13 +127,76 @@ void Renderer::render() //Process render commands //1. Sort render commands based on ID - stable_sort(_renderQueue.begin(), _renderQueue.end(), compareRenderCommand); + for (auto it = _renderGroups.begin(); it != _renderGroups.end(); ++it) + { + stable_sort((*it).begin(), (*it).end(), compareRenderCommand); + } - size_t len = _renderQueue.size(); + while(!_renderStack.empty()) + { + size_t len = _renderGroups[_renderStack.top().renderQueueID].size(); + + //If pop the render stack if we already processed all the commands + if(_renderStack.top().currentIndex >= len) + { + _renderStack.pop(); + continue; + } + + for(size_t i = _renderStack.top().currentIndex; i < len; i++) + { + auto command = _renderGroups[_renderStack.top().renderQueueID][i]; + + if(command->getType() == QUAD_COMMAND) + { + QuadCommand* cmd = static_cast(command); + + CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) + { + memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); + _numQuads += cmd->getQuadCount(); + _lastCommand = i; + } + else + { + //Draw batched quads if VBO is full + drawBatchedQuads(); + } + } + else if(command->getType() == CUSTOM_COMMAND) + { + flush(); + CustomCommand* cmd = static_cast(command); + cmd->execute(); + } + else if(command->getType() == GROUP_COMMAND) + { + GroupCommand* cmd = static_cast(command); + + _renderStack.top().currentIndex = i + 1; + + //push new renderQueue to renderStack + _renderStack.push({cmd->getRenderQueueID(), 0}); + + //Exit current loop + break; + } + else + { + flush(); + } + } + + } + + size_t len = _renderGroups[DEFAULT_RENDER_QUEUE].size(); for (size_t i = 0; i < len; i++) { - auto command = _renderQueue[i]; + auto command = _renderGroups[DEFAULT_RENDER_QUEUE][i]; switch (command->getType()) { @@ -169,11 +236,11 @@ void Renderer::render() drawBatchedQuads(); //TODO give command back to command pool - for_each(_renderQueue.begin(), _renderQueue.end(), [](RenderCommand* cmd){delete cmd;}); + for_each(_renderGroups[DEFAULT_RENDER_QUEUE].begin(), _renderGroups[DEFAULT_RENDER_QUEUE].end(), [](RenderCommand* cmd){delete cmd;}); _firstCommand = _lastCommand = 0; _lastMaterialID = 0; - _renderQueue.clear(); + _renderGroups[DEFAULT_RENDER_QUEUE].clear(); } void Renderer::drawBatchedQuads() @@ -203,7 +270,7 @@ void Renderer::drawBatchedQuads() //Start drawing verties in batch for(size_t i = _firstCommand; i <= _lastCommand; i++) { - RenderCommand* command = _renderQueue[i]; + RenderCommand* command = _renderGroups[DEFAULT_RENDER_QUEUE][i]; if (command->getType() == QUAD_COMMAND) { QuadCommand* cmd = static_cast(command); diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 354d8e9f86..f173d9587e 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -12,12 +12,22 @@ #include "CCGLProgram.h" #include "CCGL.h" #include +#include #define VBO_SIZE 1024 +#define DEFAULT_RENDER_QUEUE 0 NS_CC_BEGIN using namespace std; +typedef vector RenderQueue; + +struct RenderStackElement +{ + int renderQueueID; + size_t currentIndex; +}; + class Renderer : public Object { public: @@ -25,7 +35,7 @@ public: static void destroyInstance(); //TODO support multiple viewport - void addRenderCommand(RenderCommand* command); + void addRenderCommand(RenderCommand* command, int renderQueue = DEFAULT_RENDER_QUEUE); void render(); protected: @@ -40,7 +50,9 @@ protected: void flush(); protected: - vector _renderQueue; + stack _renderStack; + vector _renderGroups; + int _lastMaterialID; size_t _firstCommand; From 4f1858fa8a318903dd173bbc074a92d87d5b8dcd Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 14 Nov 2013 10:35:28 -0800 Subject: [PATCH 21/98] Crate NewClipping Node --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCNewSpriteBatchNode.cpp | 32 ----------- cocos/2d/CCNewSpriteBatchNode.h | 4 -- cocos/2d/GroupCommand.cpp | 3 +- cocos/2d/GroupCommand.h | 2 +- cocos/2d/NewClippingNode.cpp | 56 +++++++++++++++++++ cocos/2d/NewClippingNode.h | 32 +++++++++++ cocos/2d/renderer/Renderer.cpp | 55 ++++-------------- 8 files changed, 101 insertions(+), 85 deletions(-) create mode 100644 cocos/2d/NewClippingNode.cpp create mode 100644 cocos/2d/NewClippingNode.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index f505d1f5ea..71eb1341ad 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -2ac768774e5985125c7b8aec44806ade8178f5f6 \ No newline at end of file +d90317e96558b5bda3b3e122dd8c10034947c089 \ No newline at end of file diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp index cf782e0701..a39b1ed42b 100644 --- a/cocos/2d/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -43,38 +43,6 @@ NewSpriteBatchNode::~NewSpriteBatchNode() } -bool NewSpriteBatchNode::initWithTexture(Texture2D *tex, long capacity) -{ - CCASSERT(capacity>=0, "Capacity must be >= 0"); - - _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; - _textureAtlas = new TextureAtlas(); - - if (capacity == 0) - { - capacity = DEFAULT_CAPACITY; - } - - _textureAtlas->initWithTexture(tex, capacity); - - updateBlendFunc(); - - // no lazy alloc in this node - _children = new Array(); - _children->initWithCapacity(capacity); - - _descendants.reserve(capacity); - - setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); - return true; -} - -bool NewSpriteBatchNode::initWithFile(const char *fileImage, long capacity) -{ - Texture2D* tex = Director::getInstance()->getTextureCache()->addImage(fileImage); - return initWithTexture(tex, capacity); -} - bool NewSpriteBatchNode::init() { Texture2D* texture = new Texture2D(); diff --git a/cocos/2d/CCNewSpriteBatchNode.h b/cocos/2d/CCNewSpriteBatchNode.h index fe73796436..3981afbe63 100644 --- a/cocos/2d/CCNewSpriteBatchNode.h +++ b/cocos/2d/CCNewSpriteBatchNode.h @@ -23,10 +23,6 @@ public: NewSpriteBatchNode(); virtual ~NewSpriteBatchNode(); - bool initWithTexture(Texture2D *tex, long capacity); - - bool initWithFile(const char* fileImage, long capacity); - bool init(); void draw(void); diff --git a/cocos/2d/GroupCommand.cpp b/cocos/2d/GroupCommand.cpp index 46923eb1ee..dcf956ddc1 100644 --- a/cocos/2d/GroupCommand.cpp +++ b/cocos/2d/GroupCommand.cpp @@ -7,11 +7,10 @@ NS_CC_BEGIN -GroupCommand::GroupCommand(int viewport, int32_t depth, int renderQueueID) +GroupCommand::GroupCommand(int viewport, int32_t depth) :RenderCommand() , _viewport(viewport) , _depth(depth) -, _renderQueueID(renderQueueID) { _type = GROUP_COMMAND; } diff --git a/cocos/2d/GroupCommand.h b/cocos/2d/GroupCommand.h index 80c4fdd607..c005e6be2e 100644 --- a/cocos/2d/GroupCommand.h +++ b/cocos/2d/GroupCommand.h @@ -16,7 +16,7 @@ class GroupCommand : public RenderCommand { public: - GroupCommand(int viewport, int32_t depth, int renderQueueID); + GroupCommand(int viewport, int32_t depth); ~GroupCommand(); // +----------+----------+-----+-----------------------------------+ diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp new file mode 100644 index 0000000000..5a70971c61 --- /dev/null +++ b/cocos/2d/NewClippingNode.cpp @@ -0,0 +1,56 @@ +// +// Created by NiTe Luo on 11/13/13. +// + + +#include "NewClippingNode.h" +#include "GroupCommand.h" + +NS_CC_BEGIN + +NewClippingNode *NewClippingNode::create() +{ + NewClippingNode* pRet = new NewClippingNode(); + if(pRet && pRet->init()) + { + pRet->autorelease(); + } + else + { + CC_SAFE_DELETE(pRet); + } + return pRet; +} + +NewClippingNode *NewClippingNode::create(Node *pStencil) +{ + NewClippingNode* pRet = new NewClippingNode(); + if(pRet && pRet->init(pStencil)) + { + pRet->autorelease(); + } + else + { + CC_SAFE_DELETE(pRet); + } + return pRet; +} + +NewClippingNode::~NewClippingNode() +{ + +} + +NewClippingNode::NewClippingNode() +:ClippingNode() +{ + +} + +void NewClippingNode::visit() +{ + //Add group command + GroupCommand* groupCommand = new GroupCommand(0,0); +} + +NS_CC_END diff --git a/cocos/2d/NewClippingNode.h b/cocos/2d/NewClippingNode.h new file mode 100644 index 0000000000..b7a1cb84ee --- /dev/null +++ b/cocos/2d/NewClippingNode.h @@ -0,0 +1,32 @@ +// +// Created by NiTe Luo on 11/13/13. +// + + + +#ifndef __NewClippingNode_H_ +#define __NewClippingNode_H_ + +#include "CCPlatformMacros.h" +#include "CCClippingNode.h" + + +NS_CC_BEGIN + +class NewClippingNode : public ClippingNode +{ +public: + static NewClippingNode* create(); + static NewClippingNode* create(Node* pStencil); + + virtual ~NewClippingNode(); + + void visit(); + +protected: + NewClippingNode(); +}; + +NS_CC_END + +#endif //__NewClippingNode_H_ diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index d3286c887c..599ac28497 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -140,6 +140,7 @@ void Renderer::render() if(_renderStack.top().currentIndex >= len) { _renderStack.pop(); + _firstCommand = _lastCommand = 0; continue; } @@ -174,12 +175,14 @@ void Renderer::render() } else if(command->getType() == GROUP_COMMAND) { + flush(); GroupCommand* cmd = static_cast(command); _renderStack.top().currentIndex = i + 1; //push new renderQueue to renderStack _renderStack.push({cmd->getRenderQueueID(), 0}); + _firstCommand = _lastCommand = 0; //Exit current loop break; @@ -190,57 +193,19 @@ void Renderer::render() } } + //Draw the batched quads + drawBatchedQuads(); } - size_t len = _renderGroups[DEFAULT_RENDER_QUEUE].size(); - - for (size_t i = 0; i < len; i++) - { - auto command = _renderGroups[DEFAULT_RENDER_QUEUE][i]; - - switch (command->getType()) - { - case QUAD_COMMAND: - { - QuadCommand* cmd = static_cast(command); - - CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) - { - memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); - _numQuads += cmd->getQuadCount(); - _lastCommand = i; - } - else - { - //Draw batched quads if VBO is full - drawBatchedQuads(); - } - break; - } - case CUSTOM_COMMAND: - { - flush(); - CustomCommand* cmd = static_cast(command); - cmd->execute(); - } - default: - flush(); - break; - } - } - - //Draw the batched quads - drawBatchedQuads(); - //TODO give command back to command pool - for_each(_renderGroups[DEFAULT_RENDER_QUEUE].begin(), _renderGroups[DEFAULT_RENDER_QUEUE].end(), [](RenderCommand* cmd){delete cmd;}); + for (size_t j = 0 ; j < _renderGroups.size(); j++) + { + for_each(_renderGroups[j].begin(), _renderGroups[j].end(), [](RenderCommand* cmd){delete cmd;}); + _renderGroups[j].clear(); + } _firstCommand = _lastCommand = 0; _lastMaterialID = 0; - _renderGroups[DEFAULT_RENDER_QUEUE].clear(); } void Renderer::drawBatchedQuads() From 8d63faa0de768465770272decb66a1cfc0d0a4a9 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 14 Nov 2013 12:17:54 -0800 Subject: [PATCH 22/98] New Renderer working with RenderStack --- cocos/2d/renderer/Renderer.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 599ac28497..241fd884ba 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -134,19 +134,16 @@ void Renderer::render() while(!_renderStack.empty()) { - size_t len = _renderGroups[_renderStack.top().renderQueueID].size(); + RenderQueue currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; + size_t len = currRenderQueue.size(); - //If pop the render stack if we already processed all the commands - if(_renderStack.top().currentIndex >= len) - { - _renderStack.pop(); - _firstCommand = _lastCommand = 0; - continue; - } + //Refresh the batch command index in case the renderStack has changed. + _firstCommand = _lastCommand = _renderStack.top().currentIndex; + //Process RenderQueue for(size_t i = _renderStack.top().currentIndex; i < len; i++) { - auto command = _renderGroups[_renderStack.top().renderQueueID][i]; + auto command = currRenderQueue[i]; if(command->getType() == QUAD_COMMAND) { @@ -159,7 +156,7 @@ void Renderer::render() { memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); _numQuads += cmd->getQuadCount(); - _lastCommand = i; + _renderStack.top().currentIndex = _lastCommand = i; } else { @@ -182,7 +179,6 @@ void Renderer::render() //push new renderQueue to renderStack _renderStack.push({cmd->getRenderQueueID(), 0}); - _firstCommand = _lastCommand = 0; //Exit current loop break; @@ -195,6 +191,12 @@ void Renderer::render() //Draw the batched quads drawBatchedQuads(); + + //If pop the render stack if we already processed all the commands + if(_renderStack.top().currentIndex + 1 >= len) + { + _renderStack.pop(); + } } //TODO give command back to command pool @@ -204,6 +206,7 @@ void Renderer::render() _renderGroups[j].clear(); } + _renderStack.push({DEFAULT_RENDER_QUEUE, 0}); _firstCommand = _lastCommand = 0; _lastMaterialID = 0; } @@ -235,7 +238,7 @@ void Renderer::drawBatchedQuads() //Start drawing verties in batch for(size_t i = _firstCommand; i <= _lastCommand; i++) { - RenderCommand* command = _renderGroups[DEFAULT_RENDER_QUEUE][i]; + RenderCommand* command = _renderGroups[_renderStack.top().renderQueueID][i]; if (command->getType() == QUAD_COMMAND) { QuadCommand* cmd = static_cast(command); From 7ad93d8a942d864dafe492c26c9895ad0c365cb6 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 14 Nov 2013 16:39:03 -0800 Subject: [PATCH 23/98] Create new clippingNode --- cocos/2d/CCClippingNode.h | 2 +- cocos/2d/CCNewSprite.cpp | 2 +- cocos/2d/CCNewSpriteBatchNode.cpp | 2 +- cocos/2d/CCNewTextureAtlas.cpp | 2 +- cocos/2d/GroupCommand.cpp | 57 +++++- cocos/2d/GroupCommand.h | 19 ++ cocos/2d/NewClippingNode.cpp | 170 +++++++++++++++++- cocos/2d/NewClippingNode.h | 13 ++ cocos/2d/renderer/Renderer.cpp | 4 +- cocos/2d/renderer/Renderer.h | 2 +- .../Classes/NewRendererTest/NewRendererTest.h | 2 + 11 files changed, 266 insertions(+), 9 deletions(-) diff --git a/cocos/2d/CCClippingNode.h b/cocos/2d/CCClippingNode.h index ca2a17b8d7..52e1c3f577 100644 --- a/cocos/2d/CCClippingNode.h +++ b/cocos/2d/CCClippingNode.h @@ -109,7 +109,7 @@ public: virtual void onExit() override; virtual void visit() override; -private: +protected: /**draw fullscreen quad to clear stencil bits */ void drawFullScreenQuadClearStencil(); diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 6863ec27f2..3a33658c29 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -116,7 +116,7 @@ void NewSprite::draw(void) //TODO implement z order QuadCommand* renderCommand = new QuadCommand(0, 0,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); - Renderer::getInstance()->addRenderCommand(renderCommand); + Renderer::getInstance()->addCommand(renderCommand); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp index a39b1ed42b..19b9bb7611 100644 --- a/cocos/2d/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -61,7 +61,7 @@ void NewSpriteBatchNode::draw() arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); QuadCommand* cmd = new QuadCommand(0, 0, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); - Renderer::getInstance()->addRenderCommand(cmd); + Renderer::getInstance()->addCommand(cmd); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewTextureAtlas.cpp b/cocos/2d/CCNewTextureAtlas.cpp index ee8be29b4d..3d114ec99d 100644 --- a/cocos/2d/CCNewTextureAtlas.cpp +++ b/cocos/2d/CCNewTextureAtlas.cpp @@ -52,7 +52,7 @@ void NewTextureAtlas::drawNumberOfQuads(long numberOfQuads, long start) // updateTransform(); // QuadCommand* renderCommand = new QuadCommand(0, 0,_texture->getName(), _shaderProgram, _blendFunc, _quad); // -// Renderer::getInstance()->addRenderCommand(renderCommand); +// Renderer::getInstance()->addCommand(renderCommand); } NS_CC_END diff --git a/cocos/2d/GroupCommand.cpp b/cocos/2d/GroupCommand.cpp index dcf956ddc1..1140205855 100644 --- a/cocos/2d/GroupCommand.cpp +++ b/cocos/2d/GroupCommand.cpp @@ -7,17 +7,72 @@ NS_CC_BEGIN +static GroupCommandManager* s_instance; +GroupCommandManager *GroupCommandManager::getInstance() +{ + if(!s_instance) + { + s_instance = new GroupCommandManager(); + if(!s_instance->init()) + { + CC_SAFE_DELETE(s_instance); + } + } + return s_instance; +} + +GroupCommandManager::GroupCommandManager() +{ + +} + +GroupCommandManager::~GroupCommandManager() +{ + CC_SAFE_RELEASE_NULL(s_instance); +} + +bool GroupCommandManager::init() +{ + //0 is the default render group + _groupMapping[0] = true; + return true; +} + +int GroupCommandManager::getGroupID() +{ + //Reuse old id + for(auto it = _groupMapping.begin(); it != _groupMapping.end(); ++it) + { + if(!it->second) + { + return it->first; + } + } + + //Create new ID + int newID = _groupMapping.size(); + _groupMapping[newID] = true; + + return newID; +} + +void GroupCommandManager::releaseGroupID(int groupID) +{ + _groupMapping[groupID] = false; +} + GroupCommand::GroupCommand(int viewport, int32_t depth) :RenderCommand() , _viewport(viewport) , _depth(depth) { _type = GROUP_COMMAND; + _renderQueueID = GroupCommandManager::getInstance()->getGroupID(); } GroupCommand::~GroupCommand() { - + GroupCommandManager::getInstance()->releaseGroupID(_renderQueueID); } int64_t GroupCommand::generateID() diff --git a/cocos/2d/GroupCommand.h b/cocos/2d/GroupCommand.h index c005e6be2e..997f6e9622 100644 --- a/cocos/2d/GroupCommand.h +++ b/cocos/2d/GroupCommand.h @@ -9,8 +9,27 @@ #include "CCPlatformMacros.h" #include "RenderCommand.h" +#include NS_CC_BEGIN +using namespace std; + +class GroupCommandManager : public Object +{ +public: + static GroupCommandManager* getInstance(); + + ~GroupCommandManager(); + + bool init(); + + int getGroupID(); + void releaseGroupID(int groupID); + +protected: + GroupCommandManager(); + map _groupMapping; +}; class GroupCommand : public RenderCommand { diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp index 5a70971c61..f3efa0020d 100644 --- a/cocos/2d/NewClippingNode.cpp +++ b/cocos/2d/NewClippingNode.cpp @@ -5,9 +5,29 @@ #include "NewClippingNode.h" #include "GroupCommand.h" +#include "Renderer.h" +#include "CustomCommand.h" +#include "CCShaderCache.h" NS_CC_BEGIN +// store the current stencil layer (position in the stencil buffer), +// this will allow nesting up to n ClippingNode, +// where n is the number of bits of the stencil buffer. +static GLint layer = -1; + +static void setProgram(Node *n, GLProgram *p) +{ + n->setShaderProgram(p); + if (!n->getChildren()) return; + + Object* pObj = NULL; + CCARRAY_FOREACH(n->getChildren(), pObj) + { + setProgram(static_cast(pObj), p); + } +} + NewClippingNode *NewClippingNode::create() { NewClippingNode* pRet = new NewClippingNode(); @@ -44,13 +64,161 @@ NewClippingNode::~NewClippingNode() NewClippingNode::NewClippingNode() :ClippingNode() { - + currentStencilEnabled = GL_FALSE; + currentStencilWriteMask = ~0; + currentStencilFunc = GL_ALWAYS; + currentStencilRef = 0; + currentStencilValueMask = ~0; + currentStencilFail = GL_KEEP; + currentStencilPassDepthFail = GL_KEEP; + currentStencilPassDepthPass = GL_KEEP; } void NewClippingNode::visit() { //Add group command GroupCommand* groupCommand = new GroupCommand(0,0); + Renderer::getInstance()->addCommand(groupCommand, groupCommand->getRenderQueueID()); + + _stencil->visit(); + + Node::visit(); + + CustomCommand* prepareStencil = new CustomCommand(0,0); + prepareStencil->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); +} + +void NewClippingNode::beforeVisit() +{ + // store the current stencil layer (position in the stencil buffer), + // this will allow nesting up to n ClippingNode, + // where n is the number of bits of the stencil buffer. + static GLint layer = -1; + + /////////////////////////////////// + // INIT + + // increment the current layer + layer++; + + // mask of the current layer (ie: for layer 3: 00000100) + GLint mask_layer = 0x1 << layer; + // mask of all layers less than the current (ie: for layer 3: 00000011) + GLint mask_layer_l = mask_layer - 1; + // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) + GLint mask_layer_le = mask_layer | mask_layer_l; + + // manually save the stencil state + + currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST); + glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)¤tStencilWriteMask); + glGetIntegerv(GL_STENCIL_FUNC, (GLint *)¤tStencilFunc); + glGetIntegerv(GL_STENCIL_REF, ¤tStencilRef); + glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)¤tStencilValueMask); + glGetIntegerv(GL_STENCIL_FAIL, (GLint *)¤tStencilFail); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)¤tStencilPassDepthFail); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)¤tStencilPassDepthPass); + + // enable stencil use + glEnable(GL_STENCIL_TEST); + // check for OpenGL error while enabling stencil test + CHECK_GL_ERROR_DEBUG(); + + // all bits on the stencil buffer are readonly, except the current layer bit, + // this means that operation like glClear or glStencilOp will be masked with this value + glStencilMask(mask_layer); + + // manually save the depth test state + //GLboolean currentDepthTestEnabled = GL_TRUE; + GLboolean currentDepthWriteMask = GL_TRUE; + //currentDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); + glGetBooleanv(GL_DEPTH_WRITEMASK, ¤tDepthWriteMask); + + // disable depth test while drawing the stencil + //glDisable(GL_DEPTH_TEST); + // disable update to the depth buffer while drawing the stencil, + // as the stencil is not meant to be rendered in the real scene, + // it should never prevent something else to be drawn, + // only disabling depth buffer update should do + glDepthMask(GL_FALSE); + + /////////////////////////////////// + // CLEAR STENCIL BUFFER + + // manually clear the stencil buffer by drawing a fullscreen rectangle on it + // setup the stencil test func like this: + // for each pixel in the fullscreen rectangle + // never draw it into the frame buffer + // if not in inverted mode: set the current layer value to 0 in the stencil buffer + // if in inverted mode: set the current layer value to 1 in the stencil buffer + glStencilFunc(GL_NEVER, mask_layer, mask_layer); + glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP); + + // draw a fullscreen solid rectangle to clear the stencil buffer + //ccDrawSolidRect(Point::ZERO, ccpFromSize([[Director sharedDirector] winSize]), Color4F(1, 1, 1, 1)); + drawFullScreenQuadClearStencil(); + + /////////////////////////////////// + // DRAW CLIPPING STENCIL + + // setup the stencil test func like this: + // for each pixel in the stencil node + // never draw it into the frame buffer + // if not in inverted mode: set the current layer value to 1 in the stencil buffer + // if in inverted mode: set the current layer value to 0 in the stencil buffer + glStencilFunc(GL_NEVER, mask_layer, mask_layer); + glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); + + // since glAlphaTest do not exists in OES, use a shader that writes + // pixel only if greater than an alpha threshold + GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST); + GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); + // set our alphaThreshold + program->use(); + program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); + // we need to recursively apply this shader to all the nodes in the stencil node + // XXX: we should have a way to apply shader to all nodes without having to do this + setProgram(_stencil, program); + + //Draw _stencil + + // restore the depth test state + glDepthMask(currentDepthWriteMask); + //if (currentDepthTestEnabled) { + // glEnable(GL_DEPTH_TEST); + //} + + /////////////////////////////////// + // DRAW CONTENT + + // setup the stencil test func like this: + // for each pixel of this node and its childs + // if all layers less than or equals to the current are set to 1 in the stencil buffer + // draw the pixel and keep the current layer in the stencil buffer + // else + // do not draw the pixel but keep the current layer in the stencil buffer + glStencilFunc(GL_EQUAL, mask_layer_le, mask_layer_le); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // draw (according to the stencil test func) this node and its childs +} + +void NewClippingNode::afterVisit() +{ + /////////////////////////////////// + // CLEANUP + + // manually restore the stencil state + glStencilFunc(currentStencilFunc, currentStencilRef, currentStencilValueMask); + glStencilOp(currentStencilFail, currentStencilPassDepthFail, currentStencilPassDepthPass); + glStencilMask(currentStencilWriteMask); + if (!currentStencilEnabled) + { + glDisable(GL_STENCIL_TEST); + } + + // we are done using this layer, decrement + layer--; } NS_CC_END diff --git a/cocos/2d/NewClippingNode.h b/cocos/2d/NewClippingNode.h index b7a1cb84ee..ee078446e4 100644 --- a/cocos/2d/NewClippingNode.h +++ b/cocos/2d/NewClippingNode.h @@ -25,6 +25,19 @@ public: protected: NewClippingNode(); + + void beforeVisit(); + void afterVisit(); + +protected: + GLboolean currentStencilEnabled; + GLuint currentStencilWriteMask; + GLenum currentStencilFunc; + GLint currentStencilRef; + GLuint currentStencilValueMask; + GLenum currentStencilFail; + GLenum currentStencilPassDepthFail; + GLenum currentStencilPassDepthPass; }; NS_CC_END diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 241fd884ba..86555f5110 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -16,7 +16,7 @@ NS_CC_BEGIN using namespace std; -static Renderer*s_instance; +static Renderer* s_instance; Renderer *Renderer::getInstance() { @@ -107,7 +107,7 @@ void Renderer::setupVBOAndVAO() CHECK_GL_ERROR_DEBUG(); } -void Renderer::addRenderCommand(RenderCommand *command, int renderQueue) +void Renderer::addCommand(RenderCommand *command, int renderQueue) { command->generateID(); _renderGroups[renderQueue].push_back(command); diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index f173d9587e..c4a41f02c1 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -35,7 +35,7 @@ public: static void destroyInstance(); //TODO support multiple viewport - void addRenderCommand(RenderCommand* command, int renderQueue = DEFAULT_RENDER_QUEUE); + void addCommand(RenderCommand *command, int renderQueue = DEFAULT_RENDER_QUEUE); void render(); protected: diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 30754a97bf..267588cae6 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -68,4 +68,6 @@ public: }; + + #endif //__NewRendererTest_H_ From 566767da604ccc437416479a412af63b19be946e Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 15 Nov 2013 11:29:11 -0800 Subject: [PATCH 24/98] Add NewDrawNode --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCNewDrawNode.cpp | 45 ++++++++ cocos/2d/CCNewDrawNode.h | 32 ++++++ cocos/2d/CCNewSprite.cpp | 2 +- cocos/2d/CCNewSpriteBatchNode.cpp | 2 +- cocos/2d/GroupCommand.cpp | 4 +- cocos/2d/renderer/Renderer.cpp | 7 ++ cocos/2d/renderer/Renderer.h | 1 + .../NewRendererTest/NewRendererTest.cpp | 100 ++++++++++++++---- .../Classes/NewRendererTest/NewRendererTest.h | 17 +++ 10 files changed, 189 insertions(+), 23 deletions(-) create mode 100644 cocos/2d/CCNewDrawNode.cpp create mode 100644 cocos/2d/CCNewDrawNode.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 91fbe144ec..c884e74675 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -8e37ed57dcba682ce34245eba76540512157a176 \ No newline at end of file +7895c89d01616940f1f552efcc16408c76342f69 \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp new file mode 100644 index 0000000000..f243234ba9 --- /dev/null +++ b/cocos/2d/CCNewDrawNode.cpp @@ -0,0 +1,45 @@ +// +// Created by NiTe Luo on 11/14/13. +// + + +#include "CCNewDrawNode.h" + +NS_CC_BEGIN + +NewDrawNode *NewDrawNode::create() +{ + NewDrawNode* pRet = new NewDrawNode(); + if (pRet && pRet->init()) + { + pRet->autorelease(); + } + else + { + CC_SAFE_DELETE(pRet); + } + + return pRet; +} + +NewDrawNode::NewDrawNode() +{ + +} + +NewDrawNode::~NewDrawNode() +{ + +} + +bool NewDrawNode::init() +{ + return false; +} + +void NewDrawNode::draw() +{ + +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.h b/cocos/2d/CCNewDrawNode.h new file mode 100644 index 0000000000..6cfbfee8a3 --- /dev/null +++ b/cocos/2d/CCNewDrawNode.h @@ -0,0 +1,32 @@ +// +// Created by NiTe Luo on 11/14/13. +// + + + +#ifndef __CCNewDrawNode_H_ +#define __CCNewDrawNode_H_ + +#include "CCPlatformMacros.h" +#include "CCDrawNode.h" + +NS_CC_BEGIN + +class NewDrawNode : public DrawNode +{ +public: + static NewDrawNode* create(); + + virtual ~NewDrawNode(); + + virtual bool init(); + + void draw(); + +protected: + NewDrawNode(); +}; + +NS_CC_END + +#endif //__CCNewDrawNode_H_ diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 3a33658c29..fa248a283b 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -114,7 +114,7 @@ void NewSprite::draw(void) { updateTransform(); //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, 0,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/CCNewSpriteBatchNode.cpp b/cocos/2d/CCNewSpriteBatchNode.cpp index 19b9bb7611..8d4aac156e 100644 --- a/cocos/2d/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/CCNewSpriteBatchNode.cpp @@ -60,7 +60,7 @@ void NewSpriteBatchNode::draw() arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); - QuadCommand* cmd = new QuadCommand(0, 0, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); + QuadCommand* cmd = new QuadCommand(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/GroupCommand.cpp b/cocos/2d/GroupCommand.cpp index 1140205855..0e52cd9b76 100644 --- a/cocos/2d/GroupCommand.cpp +++ b/cocos/2d/GroupCommand.cpp @@ -4,6 +4,7 @@ #include "GroupCommand.h" +#include "Renderer.h" NS_CC_BEGIN @@ -50,7 +51,8 @@ int GroupCommandManager::getGroupID() } //Create new ID - int newID = _groupMapping.size(); +// int newID = _groupMapping.size(); + int newID = Renderer::getInstance()->createRenderQueue(); _groupMapping[newID] = true; return newID; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 86555f5110..4ca017d9e8 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -113,6 +113,13 @@ void Renderer::addCommand(RenderCommand *command, int renderQueue) _renderGroups[renderQueue].push_back(command); } +int Renderer::createRenderQueue() +{ + RenderQueue newRenderQueue; + _renderGroups.push_back(newRenderQueue); + return _renderGroups.size() - 1; +} + bool compareRenderCommand(RenderCommand* a, RenderCommand* b) { return a->getID() < b->getID(); diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index c4a41f02c1..b8c60c927a 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -36,6 +36,7 @@ public: //TODO support multiple viewport void addCommand(RenderCommand *command, int renderQueue = DEFAULT_RENDER_QUEUE); + int createRenderQueue(); void render(); protected: diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 3a2db0efdb..3ac7e56fe1 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -6,6 +6,7 @@ #include "NewRendererTest.h" #include "CCNewSprite.h" #include "CCNewSpriteBatchNode.h" +#include "NewClippingNode.h" static int sceneIdx = -1; @@ -17,6 +18,7 @@ static std::function createFunctions[] = { CL(NewSpriteTest), CL(NewSpriteBatchTest), + CL(NewClippingNodeTest), }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -254,23 +256,83 @@ void NewSpriteBatchTest::addNewSpriteWithCoords(Point p) BatchNode->addChild(sprite); sprite->setPosition( Point( p.x, p.y) ); +} -// ActionInterval* action; -// float random = CCRANDOM_0_1(); -// -// if( random < 0.20 ) -// action = ScaleBy::create(3, 2); -// else if(random < 0.40) -// action = RotateBy::create(3, 360); -// else if( random < 0.60) -// action = Blink::create(1, 3); -// else if( random < 0.8 ) -// action = TintBy::create(2, 0, -255, -255); -// else -// action = FadeOut::create(2); -// -// auto action_back = action->reverse(); -// auto seq = Sequence::create(action, action_back, NULL); -// -// sprite->runAction( RepeatForever::create(seq)); -} \ No newline at end of file +NewClippingNodeTest::NewClippingNodeTest() +{ + auto clipper = NewClippingNode::create(); + clipper->setTag( kTagClipperNode ); + clipper->setContentSize( Size(200, 200) ); + clipper->setAnchorPoint( Point(0.5, 0.5) ); + clipper->setPosition( Point(this->getContentSize().width / 2, this->getContentSize().height / 2) ); + clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); + this->addChild(clipper); + + auto stencil = DrawNode::create(); + Point rectangle[4]; + rectangle[0] = Point(0, 0); + rectangle[1] = Point(clipper->getContentSize().width, 0); + rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height); + rectangle[3] = Point(0, clipper->getContentSize().height); + + Color4F white(1, 1, 1, 1); + stencil->drawPolygon(rectangle, 4, white, 1, white); + clipper->setStencil(stencil); + + auto content = NewSprite::create("Images/background2.png"); + content->setTag( kTagContentNode ); + content->setAnchorPoint( Point(0.5, 0.5) ); + content->setPosition( Point(clipper->getContentSize().width / 2, clipper->getContentSize().height / 2) ); + clipper->addChild(content); + + _scrolling = false; + + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(NewClippingNodeTest::onTouchesBegan, this); + listener->onTouchesMoved = CC_CALLBACK_2(NewClippingNodeTest::onTouchesMoved, this); + listener->onTouchesEnded = CC_CALLBACK_2(NewClippingNodeTest::onTouchesEnded, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); +} + +NewClippingNodeTest::~NewClippingNodeTest() +{ + +} + +string NewClippingNodeTest::title() +{ + return "New Render"; +} + +string NewClippingNodeTest::subtitle() +{ + return "ClipNode"; +} + +void NewClippingNodeTest::onTouchesBegan(const std::vector &touches, Event *event) +{ + Touch *touch = touches[0]; + auto clipper = this->getChildByTag(kTagClipperNode); + Point point = clipper->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView())); + auto rect = Rect(0, 0, clipper->getContentSize().width, clipper->getContentSize().height); + _scrolling = rect.containsPoint(point); + _lastPoint = point; +} + +void NewClippingNodeTest::onTouchesMoved(const std::vector &touches, Event *event) +{ + if (!_scrolling) return; + Touch *touch = touches[0]; + auto clipper = this->getChildByTag(kTagClipperNode); + auto point = clipper->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView())); + Point diff = point - _lastPoint; + auto content = clipper->getChildByTag(kTagContentNode); + content->setPosition(content->getPosition() + diff); + _lastPoint = point; +} + +void NewClippingNodeTest::onTouchesEnded(const std::vector &touches, Event *event) +{ + if (!_scrolling) return; + _scrolling = false; +} diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 267588cae6..9bc6f29881 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -14,6 +14,8 @@ using namespace std; #define kTagSpriteBatchNode 100 +#define kTagClipperNode 101 +#define kTagContentNode 102 class NewRendererTestScene : public TestScene { @@ -67,7 +69,22 @@ public: }; +class NewClippingNodeTest : public MultiSceneTest +{ +public: + NewClippingNodeTest(); + virtual ~NewClippingNodeTest(); + virtual string title(); + virtual string subtitle(); + void onTouchesBegan(const std::vector& touches, Event *event); + void onTouchesMoved(const std::vector& touches, Event *event); + void onTouchesEnded(const std::vector& touches, Event *event); + +protected: + bool _scrolling; + Point _lastPoint; +}; #endif //__NewRendererTest_H_ From f5a8c1d02c9a2db4f16f7693ade962efd16bb0b9 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 15 Nov 2013 17:32:29 -0800 Subject: [PATCH 25/98] Fix NewClipNodeTest --- cocos/2d/CCNewDrawNode.cpp | 2 +- cocos/2d/NewClippingNode.cpp | 31 ++++++++++++++----- cocos/2d/NewClippingNode.h | 4 +++ cocos/2d/renderer/Renderer.cpp | 10 +++++- cocos/2d/renderer/Renderer.h | 7 ++++- .../NewRendererTest/NewRendererTest.cpp | 10 ++++-- 6 files changed, 52 insertions(+), 12 deletions(-) diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index f243234ba9..8066b135fd 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -34,7 +34,7 @@ NewDrawNode::~NewDrawNode() bool NewDrawNode::init() { - return false; + return DrawNode::init(); } void NewDrawNode::draw() diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp index f3efa0020d..ee3271afc6 100644 --- a/cocos/2d/NewClippingNode.cpp +++ b/cocos/2d/NewClippingNode.cpp @@ -72,20 +72,34 @@ NewClippingNode::NewClippingNode() currentStencilFail = GL_KEEP; currentStencilPassDepthFail = GL_KEEP; currentStencilPassDepthPass = GL_KEEP; + GLboolean currentDepthWriteMask = GL_TRUE; } void NewClippingNode::visit() { //Add group command - GroupCommand* groupCommand = new GroupCommand(0,0); - Renderer::getInstance()->addCommand(groupCommand, groupCommand->getRenderQueueID()); + GroupCommand* groupCommand = new GroupCommand(0,_vertexZ); + Renderer::getInstance()->addCommand(groupCommand); + + Renderer::getInstance()->setCurrentRenderQueue(groupCommand->getRenderQueueID()); + + CustomCommand* beforeVisitCmd = new CustomCommand(0,_vertexZ); + beforeVisitCmd->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); + Renderer::getInstance()->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); _stencil->visit(); + CustomCommand* afterDrawStencilCmd = new CustomCommand(0,_vertexZ); + afterDrawStencilCmd->func = CC_CALLBACK_0(NewClippingNode::afterDrawStencil, this); + Renderer::getInstance()->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); + Node::visit(); - CustomCommand* prepareStencil = new CustomCommand(0,0); - prepareStencil->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); + CustomCommand* afterVisitCmd = new CustomCommand(0,_vertexZ); + afterVisitCmd->func = CC_CALLBACK_0(NewClippingNode::afterVisit, this); + Renderer::getInstance()->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); + + Renderer::getInstance()->setCurrentRenderQueue(DEFAULT_RENDER_QUEUE); } void NewClippingNode::beforeVisit() @@ -106,7 +120,7 @@ void NewClippingNode::beforeVisit() // mask of all layers less than the current (ie: for layer 3: 00000011) GLint mask_layer_l = mask_layer - 1; // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) - GLint mask_layer_le = mask_layer | mask_layer_l; + mask_layer_le = mask_layer | mask_layer_l; // manually save the stencil state @@ -129,8 +143,7 @@ void NewClippingNode::beforeVisit() glStencilMask(mask_layer); // manually save the depth test state - //GLboolean currentDepthTestEnabled = GL_TRUE; - GLboolean currentDepthWriteMask = GL_TRUE; + //currentDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); glGetBooleanv(GL_DEPTH_WRITEMASK, ¤tDepthWriteMask); @@ -181,7 +194,10 @@ void NewClippingNode::beforeVisit() setProgram(_stencil, program); //Draw _stencil +} +void NewClippingNode::afterDrawStencil() +{ // restore the depth test state glDepthMask(currentDepthWriteMask); //if (currentDepthTestEnabled) { @@ -203,6 +219,7 @@ void NewClippingNode::beforeVisit() // draw (according to the stencil test func) this node and its childs } + void NewClippingNode::afterVisit() { /////////////////////////////////// diff --git a/cocos/2d/NewClippingNode.h b/cocos/2d/NewClippingNode.h index ee078446e4..3ce20609ec 100644 --- a/cocos/2d/NewClippingNode.h +++ b/cocos/2d/NewClippingNode.h @@ -27,6 +27,7 @@ protected: NewClippingNode(); void beforeVisit(); + void afterDrawStencil(); void afterVisit(); protected: @@ -38,6 +39,9 @@ protected: GLenum currentStencilFail; GLenum currentStencilPassDepthFail; GLenum currentStencilPassDepthPass; + GLboolean currentDepthWriteMask; + + GLint mask_layer_le; }; NS_CC_END diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 4ca017d9e8..2b36284f79 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -42,6 +42,8 @@ Renderer::Renderer() ,_firstCommand(0) ,_lastCommand(0) { + _currRenderQueueID = DEFAULT_RENDER_QUEUE; + RenderQueue defaultRenderQueue; _renderGroups.push_back(defaultRenderQueue); _renderStack.push({DEFAULT_RENDER_QUEUE, 0}); @@ -107,7 +109,13 @@ void Renderer::setupVBOAndVAO() CHECK_GL_ERROR_DEBUG(); } -void Renderer::addCommand(RenderCommand *command, int renderQueue) +void Renderer::addCommand(RenderCommand* command) +{ + command->generateID(); + _renderGroups[_currRenderQueueID].push_back(command); +} + +void Renderer::addCommand(RenderCommand* command, int renderQueue) { command->generateID(); _renderGroups[renderQueue].push_back(command); diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index b8c60c927a..9faca1164e 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -35,10 +35,13 @@ public: static void destroyInstance(); //TODO support multiple viewport - void addCommand(RenderCommand *command, int renderQueue = DEFAULT_RENDER_QUEUE); + void addCommand(RenderCommand* command); + void addCommand(RenderCommand* command, int renderQueue); int createRenderQueue(); void render(); + inline void setCurrentRenderQueue(int renderQueueID) { _currRenderQueueID = renderQueueID; } + protected: Renderer(); ~Renderer(); @@ -54,6 +57,8 @@ protected: stack _renderStack; vector _renderGroups; + int _currRenderQueueID; + int _lastMaterialID; size_t _firstCommand; diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 3ac7e56fe1..9c8900e296 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -7,6 +7,7 @@ #include "CCNewSprite.h" #include "CCNewSpriteBatchNode.h" #include "NewClippingNode.h" +#include "CCNewDrawNode.h" static int sceneIdx = -1; @@ -260,15 +261,17 @@ void NewSpriteBatchTest::addNewSpriteWithCoords(Point p) NewClippingNodeTest::NewClippingNodeTest() { + auto s = Director::getInstance()->getWinSize(); + auto clipper = NewClippingNode::create(); clipper->setTag( kTagClipperNode ); clipper->setContentSize( Size(200, 200) ); clipper->setAnchorPoint( Point(0.5, 0.5) ); - clipper->setPosition( Point(this->getContentSize().width / 2, this->getContentSize().height / 2) ); + clipper->setPosition( Point(s.width / 2, s.height / 2) ); clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); this->addChild(clipper); - auto stencil = DrawNode::create(); + auto stencil = NewDrawNode::create(); Point rectangle[4]; rectangle[0] = Point(0, 0); rectangle[1] = Point(clipper->getContentSize().width, 0); @@ -279,6 +282,9 @@ NewClippingNodeTest::NewClippingNodeTest() stencil->drawPolygon(rectangle, 4, white, 1, white); clipper->setStencil(stencil); +// auto stencil = NewSprite::create("Images/background2.png"); +// clipper->setStencil(stencil); + auto content = NewSprite::create("Images/background2.png"); content->setTag( kTagContentNode ); content->setAnchorPoint( Point(0.5, 0.5) ); From c288e5ef9c0377d7f7e2fede9a41afb761a9aac4 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 18 Nov 2013 14:58:41 -0800 Subject: [PATCH 26/98] Fix Clipping Node --- cocos/2d/CCNewDrawNode.cpp | 3 + cocos/2d/CCNewSprite.cpp | 2 +- cocos/2d/NewClippingNode.cpp | 69 ++++++++++++++----- cocos/2d/NewClippingNode.h | 6 +- cocos/2d/renderer/Renderer.cpp | 6 +- .../NewRendererTest/NewRendererTest.cpp | 25 +++---- 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 8066b135fd..164bb5b4b0 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -4,6 +4,7 @@ #include "CCNewDrawNode.h" +#include "QuadCommand.h" NS_CC_BEGIN @@ -39,7 +40,9 @@ bool NewDrawNode::init() void NewDrawNode::draw() { + updateTransform(); +// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, 0, _shaderProgram, _blendFunc, ) } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index fa248a283b..95a670a856 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -114,7 +114,7 @@ void NewSprite::draw(void) { updateTransform(); //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, _vertexZ,_texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp index ee3271afc6..8e0a8151ca 100644 --- a/cocos/2d/NewClippingNode.cpp +++ b/cocos/2d/NewClippingNode.cpp @@ -72,7 +72,11 @@ NewClippingNode::NewClippingNode() currentStencilFail = GL_KEEP; currentStencilPassDepthFail = GL_KEEP; currentStencilPassDepthPass = GL_KEEP; - GLboolean currentDepthWriteMask = GL_TRUE; + currentDepthWriteMask = GL_TRUE; + + currentAlphaTestEnabled = GL_FALSE; + currentAlphaTestFunc = GL_ALWAYS; + currentAlphaTestRef = 1; } void NewClippingNode::visit() @@ -104,11 +108,6 @@ void NewClippingNode::visit() void NewClippingNode::beforeVisit() { - // store the current stencil layer (position in the stencil buffer), - // this will allow nesting up to n ClippingNode, - // where n is the number of bits of the stencil buffer. - static GLint layer = -1; - /////////////////////////////////// // INIT @@ -182,22 +181,60 @@ void NewClippingNode::beforeVisit() glStencilFunc(GL_NEVER, mask_layer, mask_layer); glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); - // since glAlphaTest do not exists in OES, use a shader that writes - // pixel only if greater than an alpha threshold - GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST); - GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); - // set our alphaThreshold - program->use(); - program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); - // we need to recursively apply this shader to all the nodes in the stencil node - // XXX: we should have a way to apply shader to all nodes without having to do this - setProgram(_stencil, program); + // enable alpha test only if the alpha threshold < 1, + // indeed if alpha threshold == 1, every pixel will be drawn anyways +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) +// GLboolean currentAlphaTestEnabled = GL_FALSE; +// GLenum currentAlphaTestFunc = GL_ALWAYS; +// GLclampf currentAlphaTestRef = 1; +#endif + if (_alphaThreshold < 1) { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) + // manually save the alpha test state + currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); + glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)¤tAlphaTestFunc); + glGetFloatv(GL_ALPHA_TEST_REF, ¤tAlphaTestRef); + // enable alpha testing + glEnable(GL_ALPHA_TEST); + // check for OpenGL error while enabling alpha test + CHECK_GL_ERROR_DEBUG(); + // pixel will be drawn only if greater than an alpha threshold + glAlphaFunc(GL_GREATER, _alphaThreshold); +#else + // since glAlphaTest do not exists in OES, use a shader that writes + // pixel only if greater than an alpha threshold + GLProgram *program = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST); + GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); + // set our alphaThreshold + program->use(); + program->setUniformLocationWith1f(alphaValueLocation, _alphaThreshold); + // we need to recursively apply this shader to all the nodes in the stencil node + // XXX: we should have a way to apply shader to all nodes without having to do this + setProgram(_stencil, program); + +#endif + } //Draw _stencil } void NewClippingNode::afterDrawStencil() { + // restore alpha test state + if (_alphaThreshold < 1) + { +#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) + // manually restore the alpha test state + glAlphaFunc(currentAlphaTestFunc, currentAlphaTestRef); + if (!currentAlphaTestEnabled) + { + glDisable(GL_ALPHA_TEST); + } +#else +// XXX: we need to find a way to restore the shaders of the stencil node and its childs +#endif + } + // restore the depth test state glDepthMask(currentDepthWriteMask); //if (currentDepthTestEnabled) { diff --git a/cocos/2d/NewClippingNode.h b/cocos/2d/NewClippingNode.h index 3ce20609ec..b064f5b5c5 100644 --- a/cocos/2d/NewClippingNode.h +++ b/cocos/2d/NewClippingNode.h @@ -21,7 +21,7 @@ public: virtual ~NewClippingNode(); - void visit(); + virtual void visit() override; protected: NewClippingNode(); @@ -41,6 +41,10 @@ protected: GLenum currentStencilPassDepthPass; GLboolean currentDepthWriteMask; + GLboolean currentAlphaTestEnabled; + GLenum currentAlphaTestFunc; + GLclampf currentAlphaTestRef; + GLint mask_layer_le; }; diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 2b36284f79..85a231d5c4 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -171,7 +171,7 @@ void Renderer::render() { memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); _numQuads += cmd->getQuadCount(); - _renderStack.top().currentIndex = _lastCommand = i; + _lastCommand = i; } else { @@ -202,11 +202,15 @@ void Renderer::render() { flush(); } + + _renderStack.top().currentIndex = i; } //Draw the batched quads drawBatchedQuads(); + currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; + len = currRenderQueue.size(); //If pop the render stack if we already processed all the commands if(_renderStack.top().currentIndex + 1 >= len) { diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 9c8900e296..33b503c56e 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -271,20 +271,21 @@ NewClippingNodeTest::NewClippingNodeTest() clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); this->addChild(clipper); - auto stencil = NewDrawNode::create(); - Point rectangle[4]; - rectangle[0] = Point(0, 0); - rectangle[1] = Point(clipper->getContentSize().width, 0); - rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height); - rectangle[3] = Point(0, clipper->getContentSize().height); - - Color4F white(1, 1, 1, 1); - stencil->drawPolygon(rectangle, 4, white, 1, white); - clipper->setStencil(stencil); - -// auto stencil = NewSprite::create("Images/background2.png"); +// auto stencil = NewDrawNode::create(); +// Point rectangle[4]; +// rectangle[0] = Point(0, 0); +// rectangle[1] = Point(clipper->getContentSize().width, 0); +// rectangle[2] = Point(clipper->getContentSize().width, clipper->getContentSize().height); +// rectangle[3] = Point(0, clipper->getContentSize().height); +// +// Color4F white(1, 1, 1, 1); +// stencil->drawPolygon(rectangle, 4, white, 1, white); // clipper->setStencil(stencil); + auto stencil = NewSprite::create("Images/grossini.png"); + stencil->setPosition(s.width/2, s.height/2); + clipper->setStencil(stencil); + auto content = NewSprite::create("Images/background2.png"); content->setTag( kTagContentNode ); content->setAnchorPoint( Point(0.5, 0.5) ); From abb011f0ef601f040509d6ff3925488876e27570 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 18 Nov 2013 15:52:47 -0800 Subject: [PATCH 27/98] Test clipping node with alpha --- cocos/2d/renderer/Renderer.cpp | 10 ++++++---- .../Classes/NewRendererTest/NewRendererTest.cpp | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 85a231d5c4..7ee9486e2c 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -158,6 +158,7 @@ void Renderer::render() //Process RenderQueue for(size_t i = _renderStack.top().currentIndex; i < len; i++) { + _renderStack.top().currentIndex = _lastCommand = i; auto command = currRenderQueue[i]; if(command->getType() == QUAD_COMMAND) @@ -171,7 +172,7 @@ void Renderer::render() { memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); _numQuads += cmd->getQuadCount(); - _lastCommand = i; + } else { @@ -202,8 +203,6 @@ void Renderer::render() { flush(); } - - _renderStack.top().currentIndex = i; } //Draw the batched quads @@ -232,14 +231,17 @@ void Renderer::render() void Renderer::drawBatchedQuads() { - //TODO we can improve the draw performance by inseart material switching command before hand. + //TODO we can improve the draw performance by insert material switching command before hand. int quadsToDraw = 0; int startQuad = 0; //Upload buffer to VBO if(_numQuads <= 0) + { + _firstCommand = _lastCommand; return; + } //Set VBO data glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 33b503c56e..12b8a8077c 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -268,6 +268,7 @@ NewClippingNodeTest::NewClippingNodeTest() clipper->setContentSize( Size(200, 200) ); clipper->setAnchorPoint( Point(0.5, 0.5) ); clipper->setPosition( Point(s.width / 2, s.height / 2) ); + clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); this->addChild(clipper); @@ -282,7 +283,9 @@ NewClippingNodeTest::NewClippingNodeTest() // stencil->drawPolygon(rectangle, 4, white, 1, white); // clipper->setStencil(stencil); + clipper->setAlphaThreshold(0.05f); auto stencil = NewSprite::create("Images/grossini.png"); + stencil->setScale(2.0f); stencil->setPosition(s.width/2, s.height/2); clipper->setStencil(stencil); From 7ad64ece3647bc73b0e46df53b9c85a4e5272695 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 19 Nov 2013 11:06:26 -0800 Subject: [PATCH 28/98] Add Transform to DrawNode --- cocos/2d/CCDrawNode.cpp | 4 ++ cocos/2d/CCDrawNode.h | 1 + cocos/2d/CCNewDrawNode.cpp | 51 ++++++++++++++++++- cocos/2d/CCNewDrawNode.h | 1 + cocos/2d/renderer/QuadCommand.h | 1 + .../NewRendererTest/NewRendererTest.cpp | 2 +- 6 files changed, 58 insertions(+), 2 deletions(-) diff --git a/cocos/2d/CCDrawNode.cpp b/cocos/2d/CCDrawNode.cpp index 67ba1075b1..7d63c3f992 100644 --- a/cocos/2d/CCDrawNode.cpp +++ b/cocos/2d/CCDrawNode.cpp @@ -102,6 +102,7 @@ DrawNode::DrawNode() , _bufferCapacity(0) , _bufferCount(0) , _buffer(NULL) +, _finalBuffer(NULL) , _dirty(false) { _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; @@ -111,6 +112,8 @@ DrawNode::~DrawNode() { free(_buffer); _buffer = NULL; + free(_finalBuffer); + _finalBuffer = NULL; glDeleteBuffers(1, &_vbo); _vbo = 0; @@ -150,6 +153,7 @@ void DrawNode::ensureCapacity(long count) { _bufferCapacity += MAX(_bufferCapacity, count); _buffer = (V2F_C4B_T2F*)realloc(_buffer, _bufferCapacity*sizeof(V2F_C4B_T2F)); + _finalBuffer = (V2F_C4B_T2F*)realloc(_buffer, _bufferCapacity*sizeof(V2F_C4B_T2F)); } } diff --git a/cocos/2d/CCDrawNode.h b/cocos/2d/CCDrawNode.h index fe7312ade8..2355ec55db 100644 --- a/cocos/2d/CCDrawNode.h +++ b/cocos/2d/CCDrawNode.h @@ -108,6 +108,7 @@ protected: long _bufferCapacity; GLsizei _bufferCount; V2F_C4B_T2F *_buffer; + V2F_C4B_T2F *_finalBuffer; BlendFunc _blendFunc; diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 164bb5b4b0..6eb6330ab9 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -5,6 +5,7 @@ #include "CCNewDrawNode.h" #include "QuadCommand.h" +#include "Renderer.h" NS_CC_BEGIN @@ -38,11 +39,59 @@ bool NewDrawNode::init() return DrawNode::init(); } +void NewDrawNode::updateTransform() +{ + if(_dirty && _visible) + { + //TODO optimize this transformation, should use parent's transformation instead + AffineTransform _transformToBatch = getNodeToWorldTransform(); + + // + // calculate the Quad based on the Affine Matrix + // + + Size size = _rect.size; + + float x1 = _offsetPosition.x; + float y1 = _offsetPosition.y; + + float x2 = x1 + size.width; + float y2 = y1 + size.height; + float x = _transformToBatch.tx; + float y = _transformToBatch.ty; + + float cr = _transformToBatch.a; + float sr = _transformToBatch.b; + float cr2 = _transformToBatch.d; + float sr2 = -_transformToBatch.c; + float ax = x1 * cr - y1 * sr2 + x; + float ay = x1 * sr + y1 * cr2 + y; + + float bx = x2 * cr - y1 * sr2 + x; + float by = x2 * sr + y1 * cr2 + y; + + float cx = x2 * cr - y2 * sr2 + x; + float cy = x2 * sr + y2 * cr2 + y; + + float dx = x1 * cr - y2 * sr2 + x; + float dy = x1 * sr + y2 * cr2 + y; + + _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); + _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); + _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); + _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); + } + + _recursiveDirty = false; + setDirty(false); +} + void NewDrawNode::draw() { updateTransform(); -// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, 0, _shaderProgram, _blendFunc, ) +// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, CC_NO_TEXTURE, _shaderProgram, _blendFunc, &_quads, _bufferCount); +// Renderer::getInstance()-> } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.h b/cocos/2d/CCNewDrawNode.h index 6cfbfee8a3..702d465ca7 100644 --- a/cocos/2d/CCNewDrawNode.h +++ b/cocos/2d/CCNewDrawNode.h @@ -21,6 +21,7 @@ public: virtual bool init(); + void updateTransform(); void draw(); protected: diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 9483ee8439..422f00202e 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -12,6 +12,7 @@ NS_CC_BEGIN +#define CC_NO_TEXTURE 0 class QuadCommand : public RenderCommand { diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 12b8a8077c..ccadcaf1bd 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -283,9 +283,9 @@ NewClippingNodeTest::NewClippingNodeTest() // stencil->drawPolygon(rectangle, 4, white, 1, white); // clipper->setStencil(stencil); + //Test with alpha Test clipper->setAlphaThreshold(0.05f); auto stencil = NewSprite::create("Images/grossini.png"); - stencil->setScale(2.0f); stencil->setPosition(s.width/2, s.height/2); clipper->setStencil(stencil); From 8ce16e1e12dffc2db7bd0d6fb6acd3234f6d2231 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 19 Nov 2013 13:57:39 -0800 Subject: [PATCH 29/98] Finish DrawNode --- cocos/2d/CCDrawNode.cpp | 4 -- cocos/2d/CCDrawNode.h | 1 - cocos/2d/CCNewDrawNode.cpp | 67 +++++-------------- cocos/2d/CCNewDrawNode.h | 5 +- .../NewRendererTest/NewRendererTest.cpp | 39 +++++++++++ .../Classes/NewRendererTest/NewRendererTest.h | 13 ++++ 6 files changed, 73 insertions(+), 56 deletions(-) diff --git a/cocos/2d/CCDrawNode.cpp b/cocos/2d/CCDrawNode.cpp index 7d63c3f992..67ba1075b1 100644 --- a/cocos/2d/CCDrawNode.cpp +++ b/cocos/2d/CCDrawNode.cpp @@ -102,7 +102,6 @@ DrawNode::DrawNode() , _bufferCapacity(0) , _bufferCount(0) , _buffer(NULL) -, _finalBuffer(NULL) , _dirty(false) { _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; @@ -112,8 +111,6 @@ DrawNode::~DrawNode() { free(_buffer); _buffer = NULL; - free(_finalBuffer); - _finalBuffer = NULL; glDeleteBuffers(1, &_vbo); _vbo = 0; @@ -153,7 +150,6 @@ void DrawNode::ensureCapacity(long count) { _bufferCapacity += MAX(_bufferCapacity, count); _buffer = (V2F_C4B_T2F*)realloc(_buffer, _bufferCapacity*sizeof(V2F_C4B_T2F)); - _finalBuffer = (V2F_C4B_T2F*)realloc(_buffer, _bufferCapacity*sizeof(V2F_C4B_T2F)); } } diff --git a/cocos/2d/CCDrawNode.h b/cocos/2d/CCDrawNode.h index 2355ec55db..fe7312ade8 100644 --- a/cocos/2d/CCDrawNode.h +++ b/cocos/2d/CCDrawNode.h @@ -108,7 +108,6 @@ protected: long _bufferCapacity; GLsizei _bufferCount; V2F_C4B_T2F *_buffer; - V2F_C4B_T2F *_finalBuffer; BlendFunc _blendFunc; diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 6eb6330ab9..90183feca6 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -6,6 +6,7 @@ #include "CCNewDrawNode.h" #include "QuadCommand.h" #include "Renderer.h" +#include "CustomCommand.h" NS_CC_BEGIN @@ -39,59 +40,25 @@ bool NewDrawNode::init() return DrawNode::init(); } -void NewDrawNode::updateTransform() -{ - if(_dirty && _visible) - { - //TODO optimize this transformation, should use parent's transformation instead - AffineTransform _transformToBatch = getNodeToWorldTransform(); - - // - // calculate the Quad based on the Affine Matrix - // - - Size size = _rect.size; - - float x1 = _offsetPosition.x; - float y1 = _offsetPosition.y; - - float x2 = x1 + size.width; - float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; - - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; - float ax = x1 * cr - y1 * sr2 + x; - float ay = x1 * sr + y1 * cr2 + y; - - float bx = x2 * cr - y1 * sr2 + x; - float by = x2 * sr + y1 * cr2 + y; - - float cx = x2 * cr - y2 * sr2 + x; - float cy = x2 * sr + y2 * cr2 + y; - - float dx = x1 * cr - y2 * sr2 + x; - float dy = x1 * sr + y2 * cr2 + y; - - _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); - _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); - _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); - _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); - } - - _recursiveDirty = false; - setDirty(false); -} - void NewDrawNode::draw() { - updateTransform(); + kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); -// QuadCommand* quadCommand = new QuadCommand(0, _vertexZ, CC_NO_TEXTURE, _shaderProgram, _blendFunc, &_quads, _bufferCount); -// Renderer::getInstance()-> + CustomCommand* cmd = new CustomCommand(0, _vertexZ); + cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); + Renderer::getInstance()->addCommand(cmd); +} + +void NewDrawNode::onDraw() +{ + kmGLLoadMatrix(&_matrixMV); + + CC_NODE_DRAW_SETUP(); + GL::blendFunc(_blendFunc.src, _blendFunc.dst); + + render(); + + kmGLLoadIdentity(); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.h b/cocos/2d/CCNewDrawNode.h index 702d465ca7..5030f49121 100644 --- a/cocos/2d/CCNewDrawNode.h +++ b/cocos/2d/CCNewDrawNode.h @@ -21,11 +21,14 @@ public: virtual bool init(); - void updateTransform(); void draw(); + void onDraw(); + protected: NewDrawNode(); + + kmMat4 _matrixMV; }; NS_CC_END diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index ccadcaf1bd..764164b0e9 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -20,6 +20,7 @@ static std::function createFunctions[] = CL(NewSpriteTest), CL(NewSpriteBatchTest), CL(NewClippingNodeTest), + CL(NewDrawNodeTest), }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -346,3 +347,41 @@ void NewClippingNodeTest::onTouchesEnded(const std::vector &touches, Ev if (!_scrolling) return; _scrolling = false; } + +/** +* NewDrawNode +*/ +NewDrawNodeTest::NewDrawNodeTest() +{ + auto s = Director::getInstance()->getWinSize(); + + auto parent = Node::create(); + parent->setPosition(s.width/2, s.height/2); + addChild(parent); + + auto rectNode = NewDrawNode::create(); + Point rectangle[4]; + rectangle[0] = Point(-50, -50); + rectangle[1] = Point(50, -50); + rectangle[2] = Point(50, 50); + rectangle[3] = Point(-50, 50); + + Color4F white(1, 1, 1, 1); + rectNode->drawPolygon(rectangle, 4, white, 1, white); + parent->addChild(rectNode); +} + +NewDrawNodeTest::~NewDrawNodeTest() +{ + +} + +string NewDrawNodeTest::title() +{ + return "New Render"; +} + +string NewDrawNodeTest::subtitle() +{ + return "DrawNode"; +} diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 9bc6f29881..85be3bddd1 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -87,4 +87,17 @@ protected: Point _lastPoint; }; +class NewDrawNodeTest : public MultiSceneTest +{ +public: + NewDrawNodeTest(); + virtual ~NewDrawNodeTest(); + + virtual string title(); + virtual string subtitle(); + +protected: + +}; + #endif //__NewRendererTest_H_ From 0e51504ee6547f43b1c83fbda7f0eef0a18afc14 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 20 Nov 2013 11:05:01 -0800 Subject: [PATCH 30/98] Use stack to manage current RenderGroup --- cocos/2d/NewClippingNode.cpp | 15 +++++++++------ cocos/2d/renderer/Renderer.cpp | 20 ++++++++++++++------ cocos/2d/renderer/Renderer.h | 9 +++++---- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/cocos/2d/NewClippingNode.cpp b/cocos/2d/NewClippingNode.cpp index 8e0a8151ca..b480e2d837 100644 --- a/cocos/2d/NewClippingNode.cpp +++ b/cocos/2d/NewClippingNode.cpp @@ -82,28 +82,31 @@ NewClippingNode::NewClippingNode() void NewClippingNode::visit() { //Add group command + + Renderer* renderer = Renderer::getInstance(); + GroupCommand* groupCommand = new GroupCommand(0,_vertexZ); - Renderer::getInstance()->addCommand(groupCommand); + renderer->addCommand(groupCommand); - Renderer::getInstance()->setCurrentRenderQueue(groupCommand->getRenderQueueID()); + renderer->pushGroup(groupCommand->getRenderQueueID()); CustomCommand* beforeVisitCmd = new CustomCommand(0,_vertexZ); beforeVisitCmd->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); - Renderer::getInstance()->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); _stencil->visit(); CustomCommand* afterDrawStencilCmd = new CustomCommand(0,_vertexZ); afterDrawStencilCmd->func = CC_CALLBACK_0(NewClippingNode::afterDrawStencil, this); - Renderer::getInstance()->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); Node::visit(); CustomCommand* afterVisitCmd = new CustomCommand(0,_vertexZ); afterVisitCmd->func = CC_CALLBACK_0(NewClippingNode::afterVisit, this); - Renderer::getInstance()->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); - Renderer::getInstance()->setCurrentRenderQueue(DEFAULT_RENDER_QUEUE); + renderer->popGroup(); } void NewClippingNode::beforeVisit() diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 7ee9486e2c..0a240b3ecd 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -3,13 +3,11 @@ // -#include #include "Renderer.h" #include "CCShaderCache.h" #include "ccGLStateCache.h" #include "CustomCommand.h" #include "QuadCommand.h" -#include "CCGL.h" #include "GroupCommand.h" @@ -42,8 +40,8 @@ Renderer::Renderer() ,_firstCommand(0) ,_lastCommand(0) { - _currRenderQueueID = DEFAULT_RENDER_QUEUE; - + _commandGroupStack.push(DEFAULT_RENDER_QUEUE); + RenderQueue defaultRenderQueue; _renderGroups.push_back(defaultRenderQueue); _renderStack.push({DEFAULT_RENDER_QUEUE, 0}); @@ -112,7 +110,7 @@ void Renderer::setupVBOAndVAO() void Renderer::addCommand(RenderCommand* command) { command->generateID(); - _renderGroups[_currRenderQueueID].push_back(command); + _renderGroups[_commandGroupStack.top()].push_back(command); } void Renderer::addCommand(RenderCommand* command, int renderQueue) @@ -121,11 +119,21 @@ void Renderer::addCommand(RenderCommand* command, int renderQueue) _renderGroups[renderQueue].push_back(command); } +void Renderer::pushGroup(int renderQueueID) +{ + _commandGroupStack.push(renderQueueID); +} + +void Renderer::popGroup() +{ + _commandGroupStack.pop(); +} + int Renderer::createRenderQueue() { RenderQueue newRenderQueue; _renderGroups.push_back(newRenderQueue); - return _renderGroups.size() - 1; + return (int)_renderGroups.size() - 1; } bool compareRenderCommand(RenderCommand* a, RenderCommand* b) diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 9faca1164e..9d0ca59e00 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -37,11 +37,12 @@ public: //TODO support multiple viewport void addCommand(RenderCommand* command); void addCommand(RenderCommand* command, int renderQueue); + void pushGroup(int renderQueueID); + void popGroup(); + int createRenderQueue(); void render(); - inline void setCurrentRenderQueue(int renderQueueID) { _currRenderQueueID = renderQueueID; } - protected: Renderer(); ~Renderer(); @@ -54,11 +55,11 @@ protected: void flush(); protected: + stack _commandGroupStack; + stack _renderStack; vector _renderGroups; - int _currRenderQueueID; - int _lastMaterialID; size_t _firstCommand; From db52698b26c22c08b1e93e487f0ee3428f92e86a Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 20 Nov 2013 20:39:32 -0800 Subject: [PATCH 31/98] Fix the crash on ios 7 --- cocos/2d/renderer/Renderer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 0a240b3ecd..dd18ac896c 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -276,13 +276,17 @@ void Renderer::drawBatchedQuads() //Draw quads if(quadsToDraw > 0) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +// GL::bindVAO(0); startQuad += quadsToDraw; quadsToDraw = 0; } //Use new material cmd->useMaterial(); +// GL::bindVAO(_VAOname); _lastMaterialID = cmd->getMaterialID(); } @@ -293,9 +297,13 @@ void Renderer::drawBatchedQuads() //Draw any remaining quad if(quadsToDraw > 0) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + GL::bindVAO(0); + _firstCommand = _lastCommand; _numQuads = 0; } From 43941bcbe05c65c114f3f78536cf0b8726bcd571 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 21 Nov 2013 16:36:19 -0800 Subject: [PATCH 32/98] Only init render after GLview has been initialized --- cocos/2d/CCDirector.cpp | 2 + cocos/2d/renderer/QuadCommand.cpp | 5 +- cocos/2d/renderer/Renderer.cpp | 172 +++++++++++++++++------------- cocos/2d/renderer/Renderer.h | 12 ++- 4 files changed, 111 insertions(+), 80 deletions(-) diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 9d6a831b42..535ccbb1a0 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -358,6 +358,8 @@ void Director::setOpenGLView(EGLView *openGLView) setGLDefaultValues(); } + Renderer::getInstance()->initGLView(); + CHECK_GL_ERROR_DEBUG(); // _touchDispatcher->setDispatchEvents(true); diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 972f28ffe4..cc18bd9c45 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -75,10 +75,11 @@ int64_t QuadCommand::generateID() void QuadCommand::useMaterial() { _shader->use(); - //TODO once everything is using world coordinate, we can reduce the uniforms for shaders + _shader->setUniformsForBuiltins(); - //TODO set blend mode + //set blend mode + GL::blendFunc(_blendType.src, _blendType.dst); //Set texture GL::bindTexture2D(_textureID); diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index dd18ac896c..7bc5d43def 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -39,6 +39,7 @@ Renderer::Renderer() ,_numQuads(0) ,_firstCommand(0) ,_lastCommand(0) +,_glViewAssigned(false) { _commandGroupStack.push(DEFAULT_RENDER_QUEUE); @@ -50,17 +51,30 @@ Renderer::Renderer() Renderer::~Renderer() { _renderGroups.clear(); + + glDeleteBuffers(2, _buffersVBO); + +// if (Configuration::getInstance()->supportsShareableVAO()) +// { + glDeleteVertexArrays(1, &_VAOname); + GL::bindVAO(0); +// } } bool Renderer::init() { - setupIndices(); - - setupVBOAndVAO(); - return true; } +void Renderer::initGLView() +{ + setupIndices(); + + setupVBOAndVAO(); + + _glViewAssigned = true; +} + void Renderer::setupIndices() { for( int i=0; i < VBO_SIZE; i++) @@ -148,80 +162,83 @@ void Renderer::render() //TODO setup camera or MVP - //Process render commands - //1. Sort render commands based on ID - for (auto it = _renderGroups.begin(); it != _renderGroups.end(); ++it) + if (_glViewAssigned) { - stable_sort((*it).begin(), (*it).end(), compareRenderCommand); - } - - while(!_renderStack.empty()) - { - RenderQueue currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; - size_t len = currRenderQueue.size(); - - //Refresh the batch command index in case the renderStack has changed. - _firstCommand = _lastCommand = _renderStack.top().currentIndex; - - //Process RenderQueue - for(size_t i = _renderStack.top().currentIndex; i < len; i++) + //Process render commands + //1. Sort render commands based on ID + for (auto it = _renderGroups.begin(); it != _renderGroups.end(); ++it) { - _renderStack.top().currentIndex = _lastCommand = i; - auto command = currRenderQueue[i]; - - if(command->getType() == QUAD_COMMAND) + stable_sort((*it).begin(), (*it).end(), compareRenderCommand); + } + + while(!_renderStack.empty()) + { + RenderQueue currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; + size_t len = currRenderQueue.size(); + + //Refresh the batch command index in case the renderStack has changed. + _firstCommand = _lastCommand = _renderStack.top().currentIndex; + + //Process RenderQueue + for(size_t i = _renderStack.top().currentIndex; i < len; i++) { - QuadCommand* cmd = static_cast(command); - - CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) + _renderStack.top().currentIndex = _lastCommand = i; + auto command = currRenderQueue[i]; + + if(command->getType() == QUAD_COMMAND) { - memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); - _numQuads += cmd->getQuadCount(); - + QuadCommand* cmd = static_cast(command); + + CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) + { + memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); + _numQuads += cmd->getQuadCount(); + + } + else + { + //Draw batched quads if VBO is full + drawBatchedQuads(); + } + } + else if(command->getType() == CUSTOM_COMMAND) + { + flush(); + CustomCommand* cmd = static_cast(command); + cmd->execute(); + } + else if(command->getType() == GROUP_COMMAND) + { + flush(); + GroupCommand* cmd = static_cast(command); + + _renderStack.top().currentIndex = i + 1; + + //push new renderQueue to renderStack + _renderStack.push({cmd->getRenderQueueID(), 0}); + + //Exit current loop + break; } else { - //Draw batched quads if VBO is full - drawBatchedQuads(); + flush(); } } - else if(command->getType() == CUSTOM_COMMAND) + + //Draw the batched quads + drawBatchedQuads(); + + currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; + len = currRenderQueue.size(); + //If pop the render stack if we already processed all the commands + if(_renderStack.top().currentIndex + 1 >= len) { - flush(); - CustomCommand* cmd = static_cast(command); - cmd->execute(); + _renderStack.pop(); } - else if(command->getType() == GROUP_COMMAND) - { - flush(); - GroupCommand* cmd = static_cast(command); - - _renderStack.top().currentIndex = i + 1; - - //push new renderQueue to renderStack - _renderStack.push({cmd->getRenderQueueID(), 0}); - - //Exit current loop - break; - } - else - { - flush(); - } - } - - //Draw the batched quads - drawBatchedQuads(); - - currRenderQueue = _renderGroups[_renderStack.top().renderQueueID]; - len = currRenderQueue.size(); - //If pop the render stack if we already processed all the commands - if(_renderStack.top().currentIndex + 1 >= len) - { - _renderStack.pop(); } } @@ -231,7 +248,12 @@ void Renderer::render() for_each(_renderGroups[j].begin(), _renderGroups[j].end(), [](RenderCommand* cmd){delete cmd;}); _renderGroups[j].clear(); } - + + //Clear the stack incase gl view hasn't been initialized yet + while(!_renderStack.empty()) + { + _renderStack.pop(); + } _renderStack.push({DEFAULT_RENDER_QUEUE, 0}); _firstCommand = _lastCommand = 0; _lastMaterialID = 0; @@ -276,17 +298,17 @@ void Renderer::drawBatchedQuads() //Draw quads if(quadsToDraw > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); + glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -// GL::bindVAO(0); +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + startQuad += quadsToDraw; quadsToDraw = 0; } //Use new material cmd->useMaterial(); -// GL::bindVAO(_VAOname); _lastMaterialID = cmd->getMaterialID(); } @@ -297,11 +319,13 @@ void Renderer::drawBatchedQuads() //Draw any remaining quad if(quadsToDraw > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); + glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + //Unbind VAO GL::bindVAO(0); _firstCommand = _lastCommand; diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 9d0ca59e00..9ecbefaaa9 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -33,7 +33,10 @@ class Renderer : public Object public: static Renderer* getInstance(); static void destroyInstance(); - + + //TODO manage GLView inside Render itself + void initGLView(); + //TODO support multiple viewport void addCommand(RenderCommand* command); void addCommand(RenderCommand* command, int renderQueue); @@ -48,9 +51,10 @@ protected: ~Renderer(); bool init(); + void setupIndices(); void setupVBOAndVAO(); - + void drawBatchedQuads(); //Draw the previews queued quads and flush previous context void flush(); @@ -71,8 +75,8 @@ protected: GLuint _buffersVBO[2]; //0: vertex 1: indices int _numQuads; - - void drawBatchedQuads(); + + bool _glViewAssigned; }; NS_CC_END From b02af0cbfe3b939d45e8ab34941e9ad7e865e5c3 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 22 Nov 2013 10:24:52 -0800 Subject: [PATCH 33/98] Clean up renderer code --- cocos/2d/renderer/Renderer.cpp | 14 ++++---------- cocos/2d/renderer/Renderer.h | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 7bc5d43def..8294ee1c6e 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -56,7 +56,7 @@ Renderer::~Renderer() // if (Configuration::getInstance()->supportsShareableVAO()) // { - glDeleteVertexArrays(1, &_VAOname); + glDeleteVertexArrays(1, &_quadVAO); GL::bindVAO(0); // } } @@ -90,8 +90,8 @@ void Renderer::setupIndices() void Renderer::setupVBOAndVAO() { - glGenVertexArrays(1, &_VAOname); - GL::bindVAO(_VAOname); + glGenVertexArrays(1, &_quadVAO); + GL::bindVAO(_quadVAO); glGenBuffers(2, &_buffersVBO[0]); @@ -284,7 +284,7 @@ void Renderer::drawBatchedQuads() glBindBuffer(GL_ARRAY_BUFFER, 0); //Bind VAO - GL::bindVAO(_VAOname); + GL::bindVAO(_quadVAO); //Start drawing verties in batch for(size_t i = _firstCommand; i <= _lastCommand; i++) @@ -298,10 +298,7 @@ void Renderer::drawBatchedQuads() //Draw quads if(quadsToDraw > 0) { -// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); - glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); -// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); startQuad += quadsToDraw; quadsToDraw = 0; @@ -319,10 +316,7 @@ void Renderer::drawBatchedQuads() //Draw any remaining quad if(quadsToDraw > 0) { -// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); - glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); -// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } //Unbind VAO diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 9ecbefaaa9..b160244371 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -71,7 +71,7 @@ protected: V3F_C4B_T2F_Quad _quads[VBO_SIZE]; GLushort _indices[6 * VBO_SIZE]; - GLuint _VAOname; + GLuint _quadVAO; GLuint _buffersVBO[2]; //0: vertex 1: indices int _numQuads; From b41d81f8100e7b5e6f292fb2b81b4e9b4a90314c Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 22 Nov 2013 15:05:18 -0800 Subject: [PATCH 34/98] Add actions to NewSpriteBatchNode test --- .../NewRendererTest/NewRendererTest.cpp | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 764164b0e9..3fdc5b5fc8 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -249,15 +249,34 @@ void NewSpriteBatchTest::addNewSpriteWithCoords(Point p) { auto BatchNode = static_cast( getChildByTag(kTagSpriteBatchNode) ); - int idx = CCRANDOM_0_1() * 1400 / 100; + int idx = (int) (CCRANDOM_0_1() * 1400 / 100); int x = (idx%5) * 85; int y = (idx/5) * 121; - auto sprite = Sprite::createWithTexture(BatchNode->getTexture(), Rect(x,y,85,121)); + auto sprite = NewSprite::createWithTexture(BatchNode->getTexture(), Rect(x,y,85,121)); BatchNode->addChild(sprite); sprite->setPosition( Point( p.x, p.y) ); + + ActionInterval* action; + float random = CCRANDOM_0_1(); + + if( random < 0.20 ) + action = ScaleBy::create(3, 2); + else if(random < 0.40) + action = RotateBy::create(3, 360); + else if( random < 0.60) + action = Blink::create(1, 3); + else if( random < 0.8 ) + action = TintBy::create(2, 0, -255, -255); + else + action = FadeOut::create(2); + + auto action_back = action->reverse(); + auto seq = Sequence::create(action, action_back, NULL); + + sprite->runAction( RepeatForever::create(seq)); } NewClippingNodeTest::NewClippingNodeTest() @@ -273,6 +292,7 @@ NewClippingNodeTest::NewClippingNodeTest() clipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); this->addChild(clipper); + //TODO Fix draw node as clip node // auto stencil = NewDrawNode::create(); // Point rectangle[4]; // rectangle[0] = Point(0, 0); From 60ada5dee3420d99889d060c23e964e399e994a6 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 22 Nov 2013 16:09:11 -0800 Subject: [PATCH 35/98] Fonts are now using NewSprite to render --- cocos/2d/CCLabelTTF.h | 4 ++-- cocos/2d/CCNewSprite.cpp | 18 ++++++++++++++---- cocos/2d/CCNewSprite.h | 2 ++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cocos/2d/CCLabelTTF.h b/cocos/2d/CCLabelTTF.h index 8c5689e3d0..b63d63db3b 100644 --- a/cocos/2d/CCLabelTTF.h +++ b/cocos/2d/CCLabelTTF.h @@ -25,7 +25,7 @@ THE SOFTWARE. #ifndef __CCLABELTTF_H__ #define __CCLABELTTF_H__ -#include "CCSprite.h" +#include "CCNewSprite.h" #include "CCTexture2D.h" NS_CC_BEGIN @@ -54,7 +54,7 @@ NS_CC_BEGIN * @endcode * */ -class CC_DLL LabelTTF : public Sprite, public LabelProtocol +class CC_DLL LabelTTF : public NewSprite, public LabelProtocol { public: /** diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 95a670a856..02d5ff5626 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -10,6 +10,7 @@ #include "RenderCommand.h" #include "Renderer.h" #include "QuadCommand.h" +#include "CCMenuItem.h" NS_CC_BEGIN @@ -53,10 +54,19 @@ NewSprite::~NewSprite(void) { } +bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotated) +{ + bool result = Sprite::initWithTexture(texture, rect, rotated); + _recursiveDirty = true; + setDirty(true); + return result; +} + void NewSprite::updateTransform() { - if(_dirty) - { + //TODO optimize the performance cache affineTransformation +// if(_dirty) +// { if(!_visible) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); @@ -104,9 +114,9 @@ void NewSprite::updateTransform() _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } - } +// } - _recursiveDirty = false; +// _recursiveDirty = false; setDirty(false); } diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index 5b80716dd1..ab7bebdc2b 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -24,6 +24,8 @@ public: NewSprite(void); ~NewSprite(); + virtual bool initWithTexture(Texture2D *texture, const Rect& rect, bool rotated); + virtual void updateTransform(); virtual void draw(void) override; From b67ec6618fb46d3cd7f29a0153c593d5dc988706 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 22 Nov 2013 17:14:24 -0800 Subject: [PATCH 36/98] Finish converting LayerColor start working on particle system --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCLayer.cpp | 16 ++++++++++++++ cocos/2d/CCLayer.h | 4 ++++ cocos/2d/CCNewParticleSystemQuad.cpp | 6 ++++++ cocos/2d/CCNewParticleSystemQuad.h | 21 +++++++++++++++++++ cocos/2d/renderer/Renderer.cpp | 2 ++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 cocos/2d/CCNewParticleSystemQuad.cpp create mode 100644 cocos/2d/CCNewParticleSystemQuad.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 99495acb22..bc19be45cc 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -a1c60b61d609599593419cf3b32d4b6259880b57 \ No newline at end of file +89e13afae7209dd4e3bc13d195b83c0be4cf85ae \ No newline at end of file diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index e7fe6f5342..01309b8b65 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -43,6 +43,8 @@ THE SOFTWARE. #include "CCEventListenerAcceleration.h" #include "platform/CCDevice.h" #include "CCScene.h" +#include "CustomCommand.h" +#include "Renderer.h" NS_CC_BEGIN @@ -692,6 +694,18 @@ void LayerColor::updateColor() void LayerColor::draw() { + kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); + CustomCommand* cmd = new CustomCommand(0, _vertexZ); + cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); + Renderer::getInstance()->addCommand(cmd); +} + +void LayerColor::onDraw() +{ + kmMat4 prevMat; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMat); + kmGLLoadMatrix(&_matrixMV); + CC_NODE_DRAW_SETUP(); GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR ); @@ -715,6 +729,8 @@ void LayerColor::draw() glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CC_INCREMENT_GL_DRAWS(1); + + kmGLLoadMatrix(&prevMat); } void LayerColor::setColor(const Color3B &color) diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index a33e949d12..8b9e377271 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -288,6 +288,8 @@ public: // Overrides // virtual void draw() override; + virtual void onDraw(); + virtual void setColor(const Color3B &color) override; virtual void setOpacity(GLubyte opacity) override; virtual void setContentSize(const Size & var) override; @@ -312,6 +314,8 @@ protected: BlendFunc _blendFunc; Vertex2F _squareVertices[4]; Color4F _squareColors[4]; + + kmMat4 _matrixMV; }; // diff --git a/cocos/2d/CCNewParticleSystemQuad.cpp b/cocos/2d/CCNewParticleSystemQuad.cpp new file mode 100644 index 0000000000..6adb2a0c7b --- /dev/null +++ b/cocos/2d/CCNewParticleSystemQuad.cpp @@ -0,0 +1,6 @@ +// +// Created by NiTe Luo on 11/22/13. +// + + +#include "CCNewParticleSystemQuad.h" diff --git a/cocos/2d/CCNewParticleSystemQuad.h b/cocos/2d/CCNewParticleSystemQuad.h new file mode 100644 index 0000000000..4d31f6e29c --- /dev/null +++ b/cocos/2d/CCNewParticleSystemQuad.h @@ -0,0 +1,21 @@ +// +// Created by NiTe Luo on 11/22/13. +// + + + +#ifndef __CCNewParticleSystemQuad_H_ +#define __CCNewParticleSystemQuad_H_ + +#include "CCParticleSystemQuad.h" + +NS_CC_BEGIN + +class NewParticleSystemQuad : public ParticleSystemQuad +{ + +}; + +NS_CC_END + +#endif //__CCNewParticleSystemQuad_H_ diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 8294ee1c6e..1c332b5d8e 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -299,6 +299,7 @@ void Renderer::drawBatchedQuads() if(quadsToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + CC_INCREMENT_GL_DRAWS(1); startQuad += quadsToDraw; quadsToDraw = 0; @@ -317,6 +318,7 @@ void Renderer::drawBatchedQuads() if(quadsToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) quadsToDraw*6, GL_UNSIGNED_SHORT, (GLvoid*) (startQuad*6*sizeof(_indices[0])) ); + CC_INCREMENT_GL_DRAWS(1); } //Unbind VAO From f3830985bb05a6bac82fc5d5e16e876933d567f0 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 25 Nov 2013 16:33:05 -0800 Subject: [PATCH 37/98] Sprite now using New renderer --- cocos/2d/CCLabelBMFont.h | 4 +- cocos/2d/CCLabelTTF.h | 2 +- cocos/2d/CCLayer.cpp | 12 +- cocos/2d/CCLayer.h | 2 +- cocos/2d/CCNewDrawNode.cpp | 9 +- cocos/2d/CCNewDrawNode.h | 2 +- cocos/2d/CCNewSprite.cpp | 49 ++++++- cocos/2d/CCSprite.cpp | 290 +++++++++++++++++++++++-------------- 8 files changed, 245 insertions(+), 125 deletions(-) diff --git a/cocos/2d/CCLabelBMFont.h b/cocos/2d/CCLabelBMFont.h index a825d28ed6..60ed157773 100644 --- a/cocos/2d/CCLabelBMFont.h +++ b/cocos/2d/CCLabelBMFont.h @@ -33,7 +33,7 @@ Use any of these editors to generate BMFonts: #ifndef __CCBITMAP_FONT_ATLAS_H__ #define __CCBITMAP_FONT_ATLAS_H__ -#include "CCSpriteBatchNode.h" +#include "CCNewSpriteBatchNode.h" #include "uthash.h" #include #include @@ -190,7 +190,7 @@ http://www.angelcode.com/products/bmfont/ (Free, Windows only) @since v0.8 */ -class CC_DLL LabelBMFont : public SpriteBatchNode, public LabelProtocol, public RGBAProtocol +class CC_DLL LabelBMFont : public NewSpriteBatchNode, public LabelProtocol, public RGBAProtocol { public: /** diff --git a/cocos/2d/CCLabelTTF.h b/cocos/2d/CCLabelTTF.h index b63d63db3b..0d35a2c4ce 100644 --- a/cocos/2d/CCLabelTTF.h +++ b/cocos/2d/CCLabelTTF.h @@ -198,7 +198,7 @@ protected: /** font tint */ Color3B _textFillColor; - + }; diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 01309b8b65..cb9c493df5 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -694,7 +694,7 @@ void LayerColor::updateColor() void LayerColor::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); CustomCommand* cmd = new CustomCommand(0, _vertexZ); cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); Renderer::getInstance()->addCommand(cmd); @@ -702,9 +702,11 @@ void LayerColor::draw() void LayerColor::onDraw() { - kmMat4 prevMat; - kmGLGetMatrix(KM_GL_MODELVIEW, &prevMat); - kmGLLoadMatrix(&_matrixMV); + //TODO we can just reuse the base MV matrix instead of save and reset everytime + //TODO need to find out where do we set the base MV matrix + kmMat4 prevMatrix; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); + kmGLLoadMatrix(&_transformMatrix); CC_NODE_DRAW_SETUP(); @@ -730,7 +732,7 @@ void LayerColor::onDraw() CC_INCREMENT_GL_DRAWS(1); - kmGLLoadMatrix(&prevMat); + kmGLLoadMatrix(&prevMatrix); } void LayerColor::setColor(const Color3B &color) diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index 8b9e377271..1fc8a5963a 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -315,7 +315,7 @@ protected: Vertex2F _squareVertices[4]; Color4F _squareColors[4]; - kmMat4 _matrixMV; + kmMat4 _transformMatrix; }; // diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 90183feca6..c10c472dcd 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -42,7 +42,7 @@ bool NewDrawNode::init() void NewDrawNode::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); CustomCommand* cmd = new CustomCommand(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); @@ -51,14 +51,17 @@ void NewDrawNode::draw() void NewDrawNode::onDraw() { - kmGLLoadMatrix(&_matrixMV); + kmMat4 prevMatrix; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); + + kmGLLoadMatrix(&_transformMatrix); CC_NODE_DRAW_SETUP(); GL::blendFunc(_blendFunc.src, _blendFunc.dst); render(); - kmGLLoadIdentity(); + kmGLLoadMatrix(&prevMatrix); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.h b/cocos/2d/CCNewDrawNode.h index 5030f49121..6b470d083a 100644 --- a/cocos/2d/CCNewDrawNode.h +++ b/cocos/2d/CCNewDrawNode.h @@ -28,7 +28,7 @@ public: protected: NewDrawNode(); - kmMat4 _matrixMV; + kmMat4 _transformMatrix; }; NS_CC_END diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 02d5ff5626..b93dabf6e2 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -64,10 +64,18 @@ bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotat void NewSprite::updateTransform() { + +#ifdef CC_USE_PHYSICS + updatePhysicsTransform(); + setDirty(true); +#endif + //TODO optimize the performance cache affineTransformation -// if(_dirty) -// { - if(!_visible) + + // recalculate matrix only if it is dirty + if(isDirty()) + { + if( !_visible || ( _parent && _parent != (Node*)_batchNode && static_cast(_parent)->_shouldBeHidden) ) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; @@ -76,6 +84,16 @@ void NewSprite::updateTransform() { _shouldBeHidden = false; +// if( ! _parent || _parent == (Node*)_batchNode ) +// { +// _transformToBatch = getNodeToParentTransform(); +// } +// else +// { +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); +// } + //TODO optimize this transformation, should use parent's transformation instead _transformToBatch = getNodeToWorldTransform(); @@ -114,10 +132,29 @@ void NewSprite::updateTransform() _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } -// } -// _recursiveDirty = false; - setDirty(false); + // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS + if (_textureAtlas) + { + _textureAtlas->updateQuad(&_quad, _atlasIndex); + } + + _recursiveDirty = false; + setDirty(false); + } + + Node::updateTransform(); + +#if CC_SPRITE_DEBUG_DRAW + // draw bounding box + Point vertices[4] = { + Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), + Point( _quad.br.vertices.x, _quad.br.vertices.y ), + Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), + Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), + }; + ccDrawPoly(vertices, 4, true); +#endif // CC_SPRITE_DEBUG_DRAW } void NewSprite::draw(void) diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index f4118fc505..6f5ccce9bb 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -44,6 +44,8 @@ THE SOFTWARE. #include "CCAffineTransform.h" #include "TransformUtils.h" #include "CCProfiling.h" +#include "Renderer.h" +#include "QuadCommand.h" // external #include "kazmath/GL/matrix.h" @@ -446,37 +448,189 @@ void Sprite::setTextureCoords(Rect rect) } } -void Sprite::updateTransform(void) -{ - CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); - -#ifdef CC_USE_PHYSICS - updatePhysicsTransform(); - setDirty(true); -#endif - - // recalculate matrix only if it is dirty - if( isDirty() ) { +//void Sprite::updateTransform(void) +//{ +// CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); +// +//#ifdef CC_USE_PHYSICS +// updatePhysicsTransform(); +// setDirty(true); +//#endif +// +// // recalculate matrix only if it is dirty +// if( isDirty() ) { +// +// // If it is not visible, or one of its ancestors is not visible, then do nothing: +// if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) +// { +// _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); +// _shouldBeHidden = true; +// } +// else +// { +// _shouldBeHidden = false; +// +// if( ! _parent || _parent == _batchNode ) +// { +// _transformToBatch = getNodeToParentTransform(); +// } +// else +// { +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); +// } +// +// // +// // calculate the Quad based on the Affine Matrix +// // +// +// Size size = _rect.size; +// +// float x1 = _offsetPosition.x; +// float y1 = _offsetPosition.y; +// +// float x2 = x1 + size.width; +// float y2 = y1 + size.height; +// float x = _transformToBatch.tx; +// float y = _transformToBatch.ty; +// +// float cr = _transformToBatch.a; +// float sr = _transformToBatch.b; +// float cr2 = _transformToBatch.d; +// float sr2 = -_transformToBatch.c; +// float ax = x1 * cr - y1 * sr2 + x; +// float ay = x1 * sr + y1 * cr2 + y; +// +// float bx = x2 * cr - y1 * sr2 + x; +// float by = x2 * sr + y1 * cr2 + y; +// +// float cx = x2 * cr - y2 * sr2 + x; +// float cy = x2 * sr + y2 * cr2 + y; +// +// float dx = x1 * cr - y2 * sr2 + x; +// float dy = x1 * sr + y2 * cr2 + y; +// +// _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); +// _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); +// _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); +// _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); +// } +// +// // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS +// if (_textureAtlas) +// { +// _textureAtlas->updateQuad(&_quad, _atlasIndex); +// } +// +// _recursiveDirty = false; +// setDirty(false); +// } +// +// // MARMALADE CHANGED +// // recursively iterate over children +///* if( _hasChildren ) +// { +// // MARMALADE: CHANGED TO USE Node* +// // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() +// arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); +// }*/ +// Node::updateTransform(); +// +//#if CC_SPRITE_DEBUG_DRAW +// // draw bounding box +// Point vertices[4] = { +// Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), +// Point( _quad.br.vertices.x, _quad.br.vertices.y ), +// Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), +// Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), +// }; +// ccDrawPoly(vertices, 4, true); +//#endif // CC_SPRITE_DEBUG_DRAW +//} - // If it is not visible, or one of its ancestors is not visible, then do nothing: - if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) +//// draw +// +//void Sprite::draw(void) +//{ +// CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +// +// CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); +// +// CC_NODE_DRAW_SETUP(); +// +// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); +// +// GL::bindTexture2D( _texture->getName() ); +// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); +// +//#define kQuadSize sizeof(_quad.bl) +//#ifdef EMSCRIPTEN +// long offset = 0; +// setGLBufferData(&_quad, 4 * kQuadSize, 0); +//#else +// long offset = (long)&_quad; +//#endif // EMSCRIPTEN +// +// // vertex +// int diff = offsetof( V3F_C4B_T2F, vertices); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); +// +// // texCoods +// diff = offsetof( V3F_C4B_T2F, texCoords); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); +// +// // color +// diff = offsetof( V3F_C4B_T2F, colors); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); +// +// +// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +// +// CHECK_GL_ERROR_DEBUG(); +// +// +//#if CC_SPRITE_DEBUG_DRAW == 1 +// // draw bounding box +// Point vertices[4]={ +// Point(_quad.tl.vertices.x,_quad.tl.vertices.y), +// Point(_quad.bl.vertices.x,_quad.bl.vertices.y), +// Point(_quad.br.vertices.x,_quad.br.vertices.y), +// Point(_quad.tr.vertices.x,_quad.tr.vertices.y), +// }; +// ccDrawPoly(vertices, 4, true); +//#elif CC_SPRITE_DEBUG_DRAW == 2 +// // draw texture box +// Size s = this->getTextureRect().size; +// Point offsetPix = this->getOffsetPosition(); +// Point vertices[4] = { +// Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), +// Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) +// }; +// ccDrawPoly(vertices, 4, true); +//#endif // CC_SPRITE_DEBUG_DRAW +// +// CC_INCREMENT_GL_DRAWS(1); +// +// CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +//} + + +void Sprite::updateTransform() +{ + //TODO optimize the performance cache affineTransformation + if(_dirty) + { + if(!_visible) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; } - else + else { _shouldBeHidden = false; - if( ! _parent || _parent == _batchNode ) - { - _transformToBatch = getNodeToParentTransform(); - } - else - { - CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); - _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); - } + //TODO optimize this transformation, should use parent's transformation instead + _transformToBatch = getNodeToWorldTransform(); // // calculate the Quad based on the Affine Matrix @@ -513,103 +667,27 @@ void Sprite::updateTransform(void) _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } - // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS if (_textureAtlas) - { + { _textureAtlas->updateQuad(&_quad, _atlasIndex); } - + _recursiveDirty = false; setDirty(false); + } - // MARMALADE CHANGED - // recursively iterate over children -/* if( _hasChildren ) - { - // MARMALADE: CHANGED TO USE Node* - // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() - arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); - }*/ Node::updateTransform(); - -#if CC_SPRITE_DEBUG_DRAW - // draw bounding box - Point vertices[4] = { - Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), - Point( _quad.br.vertices.x, _quad.br.vertices.y ), - Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), - Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW } -// draw - void Sprite::draw(void) { - CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); - - CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); - - CC_NODE_DRAW_SETUP(); + updateTransform(); + //TODO implement z order + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); - - GL::bindTexture2D( _texture->getName() ); - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); - -#define kQuadSize sizeof(_quad.bl) -#ifdef EMSCRIPTEN - long offset = 0; - setGLBufferData(&_quad, 4 * kQuadSize, 0); -#else - long offset = (long)&_quad; -#endif // EMSCRIPTEN - - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); - - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); - - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); - - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - CHECK_GL_ERROR_DEBUG(); - - -#if CC_SPRITE_DEBUG_DRAW == 1 - // draw bounding box - Point vertices[4]={ - Point(_quad.tl.vertices.x,_quad.tl.vertices.y), - Point(_quad.bl.vertices.x,_quad.bl.vertices.y), - Point(_quad.br.vertices.x,_quad.br.vertices.y), - Point(_quad.tr.vertices.x,_quad.tr.vertices.y), - }; - ccDrawPoly(vertices, 4, true); -#elif CC_SPRITE_DEBUG_DRAW == 2 - // draw texture box - Size s = this->getTextureRect().size; - Point offsetPix = this->getOffsetPosition(); - Point vertices[4] = { - Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), - Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW - - CC_INCREMENT_GL_DRAWS(1); - - CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); + Renderer::getInstance()->addCommand(renderCommand); } // Node overrides From 61ca4f01371a14b4a7983fffa9441d14e5e82cda Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 26 Nov 2013 11:48:37 -0800 Subject: [PATCH 38/98] Fix a bug with NewSprite Update Quad --- cocos/2d/CCNewSprite.cpp | 126 ++++++-------- cocos/2d/CCNewSprite.h | 2 +- cocos/2d/CCSprite.cpp | 360 +++++++++++++++++++-------------------- 3 files changed, 230 insertions(+), 258 deletions(-) diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index b93dabf6e2..e688ac4afe 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -62,7 +62,7 @@ bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotat return result; } -void NewSprite::updateTransform() +void NewSprite::updateQuadVerties() { #ifdef CC_USE_PHYSICS @@ -75,91 +75,63 @@ void NewSprite::updateTransform() // recalculate matrix only if it is dirty if(isDirty()) { - if( !_visible || ( _parent && _parent != (Node*)_batchNode && static_cast(_parent)->_shouldBeHidden) ) - { - _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); - _shouldBeHidden = true; - } - else - { - _shouldBeHidden = false; -// if( ! _parent || _parent == (Node*)_batchNode ) -// { -// _transformToBatch = getNodeToParentTransform(); -// } -// else -// { -// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); -// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); -// } - - //TODO optimize this transformation, should use parent's transformation instead - _transformToBatch = getNodeToWorldTransform(); - - // - // calculate the Quad based on the Affine Matrix - // - - Size size = _rect.size; - - float x1 = _offsetPosition.x; - float y1 = _offsetPosition.y; - - float x2 = x1 + size.width; - float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; - - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; - float ax = x1 * cr - y1 * sr2 + x; - float ay = x1 * sr + y1 * cr2 + y; - - float bx = x2 * cr - y1 * sr2 + x; - float by = x2 * sr + y1 * cr2 + y; - - float cx = x2 * cr - y2 * sr2 + x; - float cy = x2 * sr + y2 * cr2 + y; - - float dx = x1 * cr - y2 * sr2 + x; - float dy = x1 * sr + y2 * cr2 + y; - - _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); - _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); - _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); - _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); - } - - // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS - if (_textureAtlas) - { - _textureAtlas->updateQuad(&_quad, _atlasIndex); - } +// if( ! _parent || _parent == (Node*)_batchNode ) +// { +// _transformToBatch = getNodeToParentTransform(); +// } +// else +// { +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); +// } + + //TODO optimize this transformation, should use parent's transformation instead + _transformToBatch = getNodeToWorldTransform(); + + // + // calculate the Quad based on the Affine Matrix + // + + Size size = _rect.size; + + float x1 = _offsetPosition.x; + float y1 = _offsetPosition.y; + + float x2 = x1 + size.width; + float y2 = y1 + size.height; + float x = _transformToBatch.tx; + float y = _transformToBatch.ty; + + float cr = _transformToBatch.a; + float sr = _transformToBatch.b; + float cr2 = _transformToBatch.d; + float sr2 = -_transformToBatch.c; + float ax = x1 * cr - y1 * sr2 + x; + float ay = x1 * sr + y1 * cr2 + y; + + float bx = x2 * cr - y1 * sr2 + x; + float by = x2 * sr + y1 * cr2 + y; + + float cx = x2 * cr - y2 * sr2 + x; + float cy = x2 * sr + y2 * cr2 + y; + + float dx = x1 * cr - y2 * sr2 + x; + float dy = x1 * sr + y2 * cr2 + y; + + _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); + _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); + _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); + _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); _recursiveDirty = false; setDirty(false); } - - Node::updateTransform(); - -#if CC_SPRITE_DEBUG_DRAW - // draw bounding box - Point vertices[4] = { - Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), - Point( _quad.br.vertices.x, _quad.br.vertices.y ), - Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), - Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW } void NewSprite::draw(void) { - updateTransform(); + updateQuadVerties(); //TODO implement z order QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index ab7bebdc2b..8438493787 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -26,7 +26,7 @@ public: virtual bool initWithTexture(Texture2D *texture, const Rect& rect, bool rotated); - virtual void updateTransform(); + virtual void updateQuadVerties(); virtual void draw(void) override; protected: diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 6f5ccce9bb..3083d7164f 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -448,179 +448,20 @@ void Sprite::setTextureCoords(Rect rect) } } -//void Sprite::updateTransform(void) -//{ -// CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); -// -//#ifdef CC_USE_PHYSICS -// updatePhysicsTransform(); -// setDirty(true); -//#endif -// -// // recalculate matrix only if it is dirty -// if( isDirty() ) { -// -// // If it is not visible, or one of its ancestors is not visible, then do nothing: -// if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) -// { -// _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); -// _shouldBeHidden = true; -// } -// else -// { -// _shouldBeHidden = false; -// -// if( ! _parent || _parent == _batchNode ) -// { -// _transformToBatch = getNodeToParentTransform(); -// } -// else -// { -// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); -// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); -// } -// -// // -// // calculate the Quad based on the Affine Matrix -// // -// -// Size size = _rect.size; -// -// float x1 = _offsetPosition.x; -// float y1 = _offsetPosition.y; -// -// float x2 = x1 + size.width; -// float y2 = y1 + size.height; -// float x = _transformToBatch.tx; -// float y = _transformToBatch.ty; -// -// float cr = _transformToBatch.a; -// float sr = _transformToBatch.b; -// float cr2 = _transformToBatch.d; -// float sr2 = -_transformToBatch.c; -// float ax = x1 * cr - y1 * sr2 + x; -// float ay = x1 * sr + y1 * cr2 + y; -// -// float bx = x2 * cr - y1 * sr2 + x; -// float by = x2 * sr + y1 * cr2 + y; -// -// float cx = x2 * cr - y2 * sr2 + x; -// float cy = x2 * sr + y2 * cr2 + y; -// -// float dx = x1 * cr - y2 * sr2 + x; -// float dy = x1 * sr + y2 * cr2 + y; -// -// _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); -// _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); -// _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); -// _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); -// } -// -// // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS -// if (_textureAtlas) -// { -// _textureAtlas->updateQuad(&_quad, _atlasIndex); -// } -// -// _recursiveDirty = false; -// setDirty(false); -// } -// -// // MARMALADE CHANGED -// // recursively iterate over children -///* if( _hasChildren ) -// { -// // MARMALADE: CHANGED TO USE Node* -// // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() -// arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); -// }*/ -// Node::updateTransform(); -// -//#if CC_SPRITE_DEBUG_DRAW -// // draw bounding box -// Point vertices[4] = { -// Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), -// Point( _quad.br.vertices.x, _quad.br.vertices.y ), -// Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), -// Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), -// }; -// ccDrawPoly(vertices, 4, true); -//#endif // CC_SPRITE_DEBUG_DRAW -//} - -//// draw -// -//void Sprite::draw(void) -//{ -// CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); -// -// CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); -// -// CC_NODE_DRAW_SETUP(); -// -// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); -// -// GL::bindTexture2D( _texture->getName() ); -// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); -// -//#define kQuadSize sizeof(_quad.bl) -//#ifdef EMSCRIPTEN -// long offset = 0; -// setGLBufferData(&_quad, 4 * kQuadSize, 0); -//#else -// long offset = (long)&_quad; -//#endif // EMSCRIPTEN -// -// // vertex -// int diff = offsetof( V3F_C4B_T2F, vertices); -// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); -// -// // texCoods -// diff = offsetof( V3F_C4B_T2F, texCoords); -// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); -// -// // color -// diff = offsetof( V3F_C4B_T2F, colors); -// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); -// -// -// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); -// -// CHECK_GL_ERROR_DEBUG(); -// -// -//#if CC_SPRITE_DEBUG_DRAW == 1 -// // draw bounding box -// Point vertices[4]={ -// Point(_quad.tl.vertices.x,_quad.tl.vertices.y), -// Point(_quad.bl.vertices.x,_quad.bl.vertices.y), -// Point(_quad.br.vertices.x,_quad.br.vertices.y), -// Point(_quad.tr.vertices.x,_quad.tr.vertices.y), -// }; -// ccDrawPoly(vertices, 4, true); -//#elif CC_SPRITE_DEBUG_DRAW == 2 -// // draw texture box -// Size s = this->getTextureRect().size; -// Point offsetPix = this->getOffsetPosition(); -// Point vertices[4] = { -// Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), -// Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) -// }; -// ccDrawPoly(vertices, 4, true); -//#endif // CC_SPRITE_DEBUG_DRAW -// -// CC_INCREMENT_GL_DRAWS(1); -// -// CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); -//} - - -void Sprite::updateTransform() +void Sprite::updateTransform(void) { - //TODO optimize the performance cache affineTransformation - if(_dirty) - { - if(!_visible) + CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); + +#ifdef CC_USE_PHYSICS + updatePhysicsTransform(); + setDirty(true); +#endif + + // recalculate matrix only if it is dirty + if( isDirty() ) { + + // If it is not visible, or one of its ancestors is not visible, then do nothing: + if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; @@ -629,8 +470,15 @@ void Sprite::updateTransform() { _shouldBeHidden = false; - //TODO optimize this transformation, should use parent's transformation instead - _transformToBatch = getNodeToWorldTransform(); + if( ! _parent || _parent == _batchNode ) + { + _transformToBatch = getNodeToParentTransform(); + } + else + { + CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); + _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); + } // // calculate the Quad based on the Affine Matrix @@ -667,29 +515,181 @@ void Sprite::updateTransform() _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } + // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS if (_textureAtlas) - { + { _textureAtlas->updateQuad(&_quad, _atlasIndex); } _recursiveDirty = false; setDirty(false); - } + // MARMALADE CHANGED + // recursively iterate over children +/* if( _hasChildren ) + { + // MARMALADE: CHANGED TO USE Node* + // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() + arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); + }*/ Node::updateTransform(); + +#if CC_SPRITE_DEBUG_DRAW + // draw bounding box + Point vertices[4] = { + Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), + Point( _quad.br.vertices.x, _quad.br.vertices.y ), + Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), + Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), + }; + ccDrawPoly(vertices, 4, true); +#endif // CC_SPRITE_DEBUG_DRAW } +// draw + void Sprite::draw(void) { - updateTransform(); - //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); + + CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); + + CC_NODE_DRAW_SETUP(); - Renderer::getInstance()->addCommand(renderCommand); + GL::blendFunc( _blendFunc.src, _blendFunc.dst ); + + GL::bindTexture2D( _texture->getName() ); + GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); + +#define kQuadSize sizeof(_quad.bl) +#ifdef EMSCRIPTEN + long offset = 0; + setGLBufferData(&_quad, 4 * kQuadSize, 0); +#else + long offset = (long)&_quad; +#endif // EMSCRIPTEN + + // vertex + int diff = offsetof( V3F_C4B_T2F, vertices); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); + + // texCoods + diff = offsetof( V3F_C4B_T2F, texCoords); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); + + // color + diff = offsetof( V3F_C4B_T2F, colors); + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); + + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + CHECK_GL_ERROR_DEBUG(); + + +#if CC_SPRITE_DEBUG_DRAW == 1 + // draw bounding box + Point vertices[4]={ + Point(_quad.tl.vertices.x,_quad.tl.vertices.y), + Point(_quad.bl.vertices.x,_quad.bl.vertices.y), + Point(_quad.br.vertices.x,_quad.br.vertices.y), + Point(_quad.tr.vertices.x,_quad.tr.vertices.y), + }; + ccDrawPoly(vertices, 4, true); +#elif CC_SPRITE_DEBUG_DRAW == 2 + // draw texture box + Size s = this->getTextureRect().size; + Point offsetPix = this->getOffsetPosition(); + Point vertices[4] = { + Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), + Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) + }; + ccDrawPoly(vertices, 4, true); +#endif // CC_SPRITE_DEBUG_DRAW + + CC_INCREMENT_GL_DRAWS(1); + + CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); } + +//void Sprite::updateTransform() +//{ +// //TODO optimize the performance cache affineTransformation +// if(_dirty) +// { +// if(!_visible) +// { +// _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); +// _shouldBeHidden = true; +// } +// else +// { +// _shouldBeHidden = false; +// +// //TODO optimize this transformation, should use parent's transformation instead +// _transformToBatch = getNodeToWorldTransform(); +// +// // +// // calculate the Quad based on the Affine Matrix +// // +// +// Size size = _rect.size; +// +// float x1 = _offsetPosition.x; +// float y1 = _offsetPosition.y; +// +// float x2 = x1 + size.width; +// float y2 = y1 + size.height; +// float x = _transformToBatch.tx; +// float y = _transformToBatch.ty; +// +// float cr = _transformToBatch.a; +// float sr = _transformToBatch.b; +// float cr2 = _transformToBatch.d; +// float sr2 = -_transformToBatch.c; +// float ax = x1 * cr - y1 * sr2 + x; +// float ay = x1 * sr + y1 * cr2 + y; +// +// float bx = x2 * cr - y1 * sr2 + x; +// float by = x2 * sr + y1 * cr2 + y; +// +// float cx = x2 * cr - y2 * sr2 + x; +// float cy = x2 * sr + y2 * cr2 + y; +// +// float dx = x1 * cr - y2 * sr2 + x; +// float dy = x1 * sr + y2 * cr2 + y; +// +// _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); +// _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); +// _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); +// _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); +// } +// // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS +// if (_textureAtlas) +// { +// _textureAtlas->updateQuad(&_quad, _atlasIndex); +// } +// +// _recursiveDirty = false; +// setDirty(false); +// +// } +// +// Node::updateTransform(); +//} +// +//void Sprite::draw(void) +//{ +// updateTransform(); +// //TODO implement z order +// QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); +// +// Renderer::getInstance()->addCommand(renderCommand); +//} + // Node overrides void Sprite::addChild(Node* child) From f1ca3f9a8a950fdef2a9ee780c8443741552a49d Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 26 Nov 2013 16:54:48 -0800 Subject: [PATCH 39/98] Fix NewRendererTest after change --- .../NewRendererTest/NewRendererTest.cpp | 4 --- .../Classes/NewRendererTest/NewRendererTest.h | 33 +++++++++++-------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 3fdc5b5fc8..6b24656607 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -31,8 +31,6 @@ Layer* nextTest() sceneIdx = sceneIdx % MAX_LAYER; auto layer = (createFunctions[sceneIdx])(); - layer->autorelease(); - return layer; } @@ -44,7 +42,6 @@ Layer* prevTest() sceneIdx += total; auto layer = (createFunctions[sceneIdx])(); - layer->autorelease(); return layer; } @@ -52,7 +49,6 @@ Layer* prevTest() Layer* restartTest() { auto layer = (createFunctions[sceneIdx])(); - layer->autorelease(); return layer; } diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 85be3bddd1..17d3cd0267 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -26,9 +26,7 @@ public: class MultiSceneTest : public BaseTest { public: - MultiSceneTest(); - virtual ~MultiSceneTest(); - + CREATE_FUNC(MultiSceneTest); virtual string title(); virtual string subtitle(); virtual void onEnter(); @@ -36,13 +34,17 @@ public: void restartCallback(Object* sender); void nextCallback(Object* sender); void backCallback(Object* sender); + +protected: + MultiSceneTest(); + virtual ~MultiSceneTest(); + }; class NewSpriteTest : public MultiSceneTest { public: - NewSpriteTest(); - virtual ~NewSpriteTest(); + CREATE_FUNC(NewSpriteTest); virtual string title(); virtual string subtitle(); @@ -52,29 +54,31 @@ public: void onTouchesEnded(const std::vector& touches, Event* event); protected: - + NewSpriteTest(); + virtual ~NewSpriteTest(); }; class NewSpriteBatchTest : public MultiSceneTest { public: - NewSpriteBatchTest(); - virtual ~NewSpriteBatchTest(); + CREATE_FUNC(NewSpriteBatchTest); virtual string title(); virtual string subtitle(); void onTouchesEnded(const vector& touches, Event* event); void addNewSpriteWithCoords(Point p); +protected: + NewSpriteBatchTest(); + virtual ~NewSpriteBatchTest(); }; class NewClippingNodeTest : public MultiSceneTest { public: - NewClippingNodeTest(); - virtual ~NewClippingNodeTest(); + CREATE_FUNC(NewClippingNodeTest); virtual string title(); virtual string subtitle(); @@ -83,6 +87,9 @@ public: void onTouchesEnded(const std::vector& touches, Event *event); protected: + NewClippingNodeTest(); + virtual ~NewClippingNodeTest(); + bool _scrolling; Point _lastPoint; }; @@ -90,14 +97,14 @@ protected: class NewDrawNodeTest : public MultiSceneTest { public: - NewDrawNodeTest(); - virtual ~NewDrawNodeTest(); + CREATE_FUNC(NewDrawNodeTest) virtual string title(); virtual string subtitle(); protected: - + NewDrawNodeTest(); + virtual ~NewDrawNodeTest(); }; #endif //__NewRendererTest_H_ From bf53cc116b277df7d3089d9b1efb0cff4c944fbb Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 26 Nov 2013 17:01:32 -0800 Subject: [PATCH 40/98] use updateQuadVertices function to update vertices since update transform is highly customized for BatchNode --- cocos/2d/CCNewSprite.cpp | 4 ++-- cocos/2d/CCNewSprite.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index e688ac4afe..f9c201464d 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -62,7 +62,7 @@ bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotat return result; } -void NewSprite::updateQuadVerties() +void NewSprite::updateQuadVertices() { #ifdef CC_USE_PHYSICS @@ -131,7 +131,7 @@ void NewSprite::updateQuadVerties() void NewSprite::draw(void) { - updateQuadVerties(); + updateQuadVertices(); //TODO implement z order QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index 8438493787..752d4973f4 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -26,7 +26,7 @@ public: virtual bool initWithTexture(Texture2D *texture, const Rect& rect, bool rotated); - virtual void updateQuadVerties(); + virtual void updateQuadVertices(); virtual void draw(void) override; protected: From 3123c70153a45b80dc73ebd130ccf9e11c6b6c79 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Tue, 26 Nov 2013 17:13:04 -0800 Subject: [PATCH 41/98] Sprite are now using NewRenderer --- cocos/2d/CCSprite.cpp | 256 +++++++++++++++++++++--------------------- cocos/2d/CCSprite.h | 1 + 2 files changed, 129 insertions(+), 128 deletions(-) diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index ce0bdb2a24..2867d810b8 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -595,145 +595,145 @@ void Sprite::updateTransform(void) // draw +//void Sprite::draw(void) +//{ +// CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +// +// CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); +// +// CC_NODE_DRAW_SETUP(); +// +// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); +// +// GL::bindTexture2D( _texture->getName() ); +// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); +// +//#define kQuadSize sizeof(_quad.bl) +//#ifdef EMSCRIPTEN +// long offset = 0; +// setGLBufferData(&_quad, 4 * kQuadSize, 0); +//#else +// long offset = (long)&_quad; +//#endif // EMSCRIPTEN +// +// // vertex +// int diff = offsetof( V3F_C4B_T2F, vertices); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); +// +// // texCoods +// diff = offsetof( V3F_C4B_T2F, texCoords); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); +// +// // color +// diff = offsetof( V3F_C4B_T2F, colors); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); +// +// +// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +// +// CHECK_GL_ERROR_DEBUG(); +// +// +//#if CC_SPRITE_DEBUG_DRAW == 1 +// // draw bounding box +// Point vertices[4]={ +// Point(_quad.tl.vertices.x,_quad.tl.vertices.y), +// Point(_quad.bl.vertices.x,_quad.bl.vertices.y), +// Point(_quad.br.vertices.x,_quad.br.vertices.y), +// Point(_quad.tr.vertices.x,_quad.tr.vertices.y), +// }; +// ccDrawPoly(vertices, 4, true); +//#elif CC_SPRITE_DEBUG_DRAW == 2 +// // draw texture box +// Size s = this->getTextureRect().size; +// Point offsetPix = this->getOffsetPosition(); +// Point vertices[4] = { +// Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), +// Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) +// }; +// ccDrawPoly(vertices, 4, true); +//#endif // CC_SPRITE_DEBUG_DRAW +// +// CC_INCREMENT_GL_DRAWS(1); +// +// CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +//} + void Sprite::draw(void) { - CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); + updateQuadVertices(); + //TODO implement z order + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); - CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); - - CC_NODE_DRAW_SETUP(); - - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); - - GL::bindTexture2D( _texture->getName() ); - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); - -#define kQuadSize sizeof(_quad.bl) -#ifdef EMSCRIPTEN - long offset = 0; - setGLBufferData(&_quad, 4 * kQuadSize, 0); -#else - long offset = (long)&_quad; -#endif // EMSCRIPTEN - - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); - - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); - - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); - - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - CHECK_GL_ERROR_DEBUG(); - - -#if CC_SPRITE_DEBUG_DRAW == 1 - // draw bounding box - Point vertices[4]={ - Point(_quad.tl.vertices.x,_quad.tl.vertices.y), - Point(_quad.bl.vertices.x,_quad.bl.vertices.y), - Point(_quad.br.vertices.x,_quad.br.vertices.y), - Point(_quad.tr.vertices.x,_quad.tr.vertices.y), - }; - ccDrawPoly(vertices, 4, true); -#elif CC_SPRITE_DEBUG_DRAW == 2 - // draw texture box - Size s = this->getTextureRect().size; - Point offsetPix = this->getOffsetPosition(); - Point vertices[4] = { - Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), - Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW - - CC_INCREMENT_GL_DRAWS(1); - - CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); + Renderer::getInstance()->addCommand(renderCommand); } +void Sprite::updateQuadVertices() +{ -//void Sprite::updateTransform() -//{ -// //TODO optimize the performance cache affineTransformation -// if(_dirty) -// { -// if(!_visible) +#ifdef CC_USE_PHYSICS + updatePhysicsTransform(); + setDirty(true); +#endif + + //TODO optimize the performance cache affineTransformation + + // recalculate matrix only if it is dirty + if(isDirty()) + { + +// if( ! _parent || _parent == (Node*)_batchNode ) // { -// _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); -// _shouldBeHidden = true; +// _transformToBatch = getNodeToParentTransform(); // } // else // { -// _shouldBeHidden = false; -// -// //TODO optimize this transformation, should use parent's transformation instead -// _transformToBatch = getNodeToWorldTransform(); -// -// // -// // calculate the Quad based on the Affine Matrix -// // -// -// Size size = _rect.size; -// -// float x1 = _offsetPosition.x; -// float y1 = _offsetPosition.y; -// -// float x2 = x1 + size.width; -// float y2 = y1 + size.height; -// float x = _transformToBatch.tx; -// float y = _transformToBatch.ty; -// -// float cr = _transformToBatch.a; -// float sr = _transformToBatch.b; -// float cr2 = _transformToBatch.d; -// float sr2 = -_transformToBatch.c; -// float ax = x1 * cr - y1 * sr2 + x; -// float ay = x1 * sr + y1 * cr2 + y; -// -// float bx = x2 * cr - y1 * sr2 + x; -// float by = x2 * sr + y1 * cr2 + y; -// -// float cx = x2 * cr - y2 * sr2 + x; -// float cy = x2 * sr + y2 * cr2 + y; -// -// float dx = x1 * cr - y2 * sr2 + x; -// float dy = x1 * sr + y2 * cr2 + y; -// -// _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); -// _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); -// _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); -// _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); // } -// // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS -// if (_textureAtlas) -// { -// _textureAtlas->updateQuad(&_quad, _atlasIndex); -// } -// -// _recursiveDirty = false; -// setDirty(false); -// -// } -// -// Node::updateTransform(); -//} -// -//void Sprite::draw(void) -//{ -// updateTransform(); -// //TODO implement z order -// QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); -// -// Renderer::getInstance()->addCommand(renderCommand); -//} + + //TODO optimize this transformation, should use parent's transformation instead + _transformToBatch = getNodeToWorldTransform(); + + // + // calculate the Quad based on the Affine Matrix + // + + Size size = _rect.size; + + float x1 = _offsetPosition.x; + float y1 = _offsetPosition.y; + + float x2 = x1 + size.width; + float y2 = y1 + size.height; + float x = _transformToBatch.tx; + float y = _transformToBatch.ty; + + float cr = _transformToBatch.a; + float sr = _transformToBatch.b; + float cr2 = _transformToBatch.d; + float sr2 = -_transformToBatch.c; + float ax = x1 * cr - y1 * sr2 + x; + float ay = x1 * sr + y1 * cr2 + y; + + float bx = x2 * cr - y1 * sr2 + x; + float by = x2 * sr + y1 * cr2 + y; + + float cx = x2 * cr - y2 * sr2 + x; + float cy = x2 * sr + y2 * cr2 + y; + + float dx = x1 * cr - y2 * sr2 + x; + float dy = x1 * sr + y2 * cr2 + y; + + _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); + _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); + _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); + _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); + + _recursiveDirty = false; + setDirty(false); + } +} // Node overrides diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index 27eb9829dc..6c79a88729 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -421,6 +421,7 @@ public: virtual void setAnchorPoint(const Point& anchor) override; virtual void ignoreAnchorPointForPosition(bool value) override; virtual void setVisible(bool bVisible) override; + virtual void updateQuadVertices(); virtual void draw(void) override; /// @} From 80da1dac3f01a270ee22de46fac7cc084e8cbcbd Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 27 Nov 2013 10:34:30 +0800 Subject: [PATCH 42/98] add Frustum, AABB, ViewTransform --- cocos/2d/renderer/Frustum.cpp | 390 ++++++++++++++++++++++++++++++++++ cocos/2d/renderer/Frustum.h | 96 +++++++++ 2 files changed, 486 insertions(+) create mode 100644 cocos/2d/renderer/Frustum.cpp create mode 100644 cocos/2d/renderer/Frustum.h diff --git a/cocos/2d/renderer/Frustum.cpp b/cocos/2d/renderer/Frustum.cpp new file mode 100644 index 0000000000..c590a50c4d --- /dev/null +++ b/cocos/2d/renderer/Frustum.cpp @@ -0,0 +1,390 @@ +#include "Frustum.h" +#include +#include "CCCommon.h" + +NS_CC_BEGIN + +ViewTransform::ViewTransform() +{ + _position = {0, 0, 0}; + _focus = {0, 0, -1}; + _up = {0, 1, 0 }; + _dirty = true; + kmMat4Identity(&_matrix); +} + +ViewTransform::~ViewTransform() +{ +} + +void ViewTransform::Init(const kmVec3 &pos, const kmVec3 &focus, const kmVec3 &up) +{ + _position = pos; + _focus = focus; + _up = up; + _dirty = true; +} + +void ViewTransform::LazyAdjust() const +{ + if(!_dirty) return; + kmVec3Subtract(&_adjustDir, &_focus, &_position); + kmVec3Normalize(&_adjustDir, &_adjustDir); + + kmVec3Cross(&_adjustRight, &_adjustDir, &_up); + kmVec3Normalize(&_adjustRight, &_adjustRight); + + kmVec3Cross(&_adjustUp, &_adjustRight, &_adjustDir); + kmVec3Normalize(&_adjustUp, &_adjustUp); + + _dirty = false; +} + +const kmVec3& ViewTransform::getDirection() const +{ + LazyAdjust(); + return _adjustDir; +} + +const kmVec3& ViewTransform::getRight() const +{ + LazyAdjust(); + return _adjustRight; +} + +const kmVec3& ViewTransform::getUp() const +{ + LazyAdjust(); + return _adjustUp; +} + +AABB::AABB(const kmVec3& min, const kmVec3& max) +{ + _min = min; + _max = max; + if(_min.x > _max.x) + { + CCLOG("_min.x is greater than _max.x, it will be swapped!"); + float temp = _min.x; _min.x = _max.x; _max.x = temp; + } + if(_min.y > _max.y) + { + CCLOG("_min.y is greater than _max.y, it will be swapped!"); + float temp = _min.y; _min.y = _max.y; _max.y = temp; + } + if(_min.z > _max.z) + { + CCLOG("_min.z is greater than _max.z, it will be swapped!"); + float temp = _min.z; _min.z = _max.z; _max.z = temp; + } +} + +AABB::~AABB() +{ +} + +kmVec3 AABB::getCenter() const +{ + kmVec3 result; + + kmVec3Add(&result, &_min, &_max); + kmVec3Scale(&result, &result, 0.5f); + return result; +} + +float AABB::getDimensionX() const +{ + return _max.x - _min.x; +} + +float AABB::getDimensionY() const +{ + return _max.y - _min.y; +} + +float AABB::getDimensionZ() const +{ + return _max.z - _min.z; +} + +kmVec3 AABB::getPositivePoint(const kmVec3& direction) const +{ + kmVec3 result = _max; + if( direction.x < 0 ) result.x = _min.x; + if( direction.y < 0 ) result.y = _min.y; + if( direction.z < 0 ) result.z = _min.z; + + return result; +} + +const AABB& AABB::expand(const kmVec3& point) +{ + if(point.x > _max.x) _max.x = point.x; + if(point.y > _max.y) _max.y = point.y; + if(point.z > _max.z) _max.z = point.z; + + if(point.x < _min.x) _min.x = point.x; + if(point.y < _min.y) _min.y = point.y; + if(point.z < _min.z) _min.z = point.z; + + return *this; +} + +kmVec3 AABB::getNegativePoint(const kmVec3& direction) const +{ + kmVec3 result = _min; + if( direction.x < 0 ) result.x = _max.x; + if( direction.y < 0 ) result.y = _max.y; + if( direction.z < 0 ) result.z = _max.z; + + return result; +} + +Frustum::Frustum() +{ +} + +Frustum::~Frustum() +{ +} + +void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, float width, float height, float near, float far) +{ + kmVec3 cc = view.getPosition(); + kmVec3 cDir = view.getDirection(); + kmVec3 cRight = view.getRight(); + kmVec3 cUp = view.getUp(); + + kmVec3Normalize(&cDir, &cDir); + kmVec3Normalize(&cRight, &cRight); + kmVec3Normalize(&cUp, &cUp); + + //near + { + kmVec3 point; + kmVec3 normal; + normal = cDir; + kmVec3Scale(&point, &cDir, near); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::NEAR], &point, &normal); + } + + //far + { + kmVec3 point; + kmVec3 normal; + kmVec3Scale(&normal, &cDir, -1); + kmVec3Scale(&point, &cDir, far); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FAR], &point, &normal); + } + + //left + { + kmVec3 point; + kmVec3 normal; + normal = cRight; + kmVec3Scale(&point, &cRight, -width * 0.5); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::LEFT], &point, &normal); + } + + //right + { + kmVec3 point; + kmVec3 normal; + kmVec3Scale(&normal, &cRight, -1); + kmVec3Scale(&point, &cRight, width * 0.5); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::RIGHT], &point, &normal); + } + + //bottom + { + kmVec3 point; + kmVec3 normal; + normal = cUp; + kmVec3Scale(&point, &cUp, -height * 0.5); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::BOTTOM], &point, &normal); + } + + //top + { + kmVec3 point; + kmVec3 normal; + kmVec3Scale(&normal, &cUp, -1); + kmVec3Scale(&point, &cUp, height * 0.5); + kmVec3Add(&point, &point, &cc); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::TOP], &point, &normal); + } +} + +void Frustum::setupProjectionPerspective(const ViewTransform& view, float left, float right, float top, float bottom, float near, float far) +{ + kmVec3 cc = view.getPosition(); + kmVec3 cDir = view.getDirection(); + kmVec3 cRight = view.getRight(); + kmVec3 cUp = view.getUp(); + + kmVec3Normalize(&cDir, &cDir); + kmVec3Normalize(&cRight, &cRight); + kmVec3Normalize(&cUp, &cUp); + + kmVec3 nearCenter; + kmVec3 farCenter; + + kmVec3Scale(&nearCenter, &cDir, near); + kmVec3Add(&nearCenter, &nearCenter, &cc); + + kmVec3Scale(&farCenter, &cDir, far); + kmVec3Add(&farCenter, &farCenter, &cc); + + //near + { + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::NEAR], &nearCenter, &cDir); + } + + //far + { + kmVec3 normal; + kmVec3Scale(&normal, &cDir, -1); + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FAR], &farCenter, &normal); + } + + //left + { + kmVec3 point; + kmVec3Scale(&point, &cRight, left); + kmVec3Add(&point, &point, &nearCenter); + + kmVec3 normal; + kmVec3Subtract(&normal, &point, &cc); + kmVec3Cross(&normal, &normal, &cUp); + kmVec3Normalize(&normal, &normal); + + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::LEFT], &point, &normal); + } + + //right + { + kmVec3 point; + kmVec3Scale(&point, &cRight, right); + kmVec3Add(&point, &point, &nearCenter); + + kmVec3 normal; + kmVec3Subtract(&normal, &point, &cc); + kmVec3Cross(&normal, &cUp, &normal); + kmVec3Normalize(&normal, &normal); + + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::RIGHT], &point, &normal); + } + + //bottom + { + kmVec3 point; + kmVec3Scale(&point, &cUp, bottom); + kmVec3Add(&point, &point, &nearCenter); + + kmVec3 normal; + kmVec3Subtract(&normal, &point, &cc); + kmVec3Cross(&normal, &cRight, &normal); + kmVec3Normalize(&normal, &normal); + + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::BOTTOM], &point, &normal); + } + + //top + { + kmVec3 point; + kmVec3Scale(&point, &cUp, top); + kmVec3Add(&point, &point, &nearCenter); + + kmVec3 normal; + kmVec3Subtract(&normal, &point, &cc); + kmVec3Cross(&normal, &normal, &cRight); + kmVec3Normalize(&normal, &normal); + + kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::TOP], &point, &normal); + } + +} + +void Frustum::setupProjectionPerspectiveFov(const ViewTransform& view, float fov, float ratio, float near, float far) +{ + float width = 2 * near * tan(fov * 0.5); + float height = width/ratio; + setupProjectionPerspective(view, -width/2, width/2, height/2, -height/2, near, far); +} + +void Frustum::setupFromMatrix(const kmMat4 &view, const kmMat4 &projection) +{ + kmMat4 mvp; + kmMat4Multiply(&mvp, &projection, &view); + + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::NEAR], &mvp, KM_PLANE_NEAR); + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::FAR], &mvp, KM_PLANE_FAR); + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::LEFT], &mvp, KM_PLANE_LEFT); + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::RIGHT], &mvp, KM_PLANE_RIGHT); + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::BOTTOM], &mvp, KM_PLANE_BOTTOM); + kmMat4ExtractPlane(&_frustumPlanes[FrustumPlane::TOP], &mvp, KM_PLANE_TOP); +} + +Frustum::IntersectResult Frustum::intersectPoint(const kmVec3 &point) const +{ + int indexFirst = static_cast(FrustumPlane::NEAR); + int indexNumber = static_cast(FrustumPlane::NUMBER); + + for(int planeIndex = indexFirst; planeIndex < indexNumber; ++planeIndex) + { + if(kmPlaneDotCoord(&_frustumPlanes[static_cast(planeIndex)], &point) < 0) + return IntersectResult::OUTSIDE; + } + return IntersectResult::INSIDE; +} + +Frustum::IntersectResult Frustum::intersectAABB(const AABB& aabb) const +{ + IntersectResult result = IntersectResult::INSIDE; + int indexFirst = static_cast(FrustumPlane::NEAR); + int indexNumber = static_cast(FrustumPlane::NUMBER); + + for(int planeIndex = indexFirst; planeIndex < indexNumber; ++planeIndex) + { + kmPlane plane = _frustumPlanes[static_cast(planeIndex)]; + kmVec3 normal = {plane.a, plane.b, plane.c}; + kmVec3Normalize(&normal, &normal); + kmVec3 positivePoint = aabb.getPositivePoint(normal); + kmVec3 negativePoint = aabb.getNegativePoint(normal); + + if(kmPlaneDotCoord(&plane, &positivePoint) < 0) + return IntersectResult::OUTSIDE; + if(kmPlaneDotCoord(&plane, &negativePoint) < 0) + result = IntersectResult::INTERSECT; + } + + return result; +} + +Frustum::IntersectResult Frustum::intersectSphere(const kmVec3& center, float radius) const +{ + IntersectResult result = IntersectResult::INSIDE; + int indexFirst = static_cast(FrustumPlane::NEAR); + int indexNumber = static_cast(FrustumPlane::NUMBER); + + for(int planeIndex = indexFirst; planeIndex < indexNumber; ++planeIndex) + { + kmPlane plane = _frustumPlanes[static_cast(planeIndex)]; + kmVec3 normal = {plane.a, plane.b, plane.c}; + + float distance = kmPlaneDotCoord(&plane, ¢er); + distance = distance / kmVec3Length(&normal); + + if(distance < -radius) return IntersectResult::OUTSIDE; + if(distance <= radius && distance >= -radius) result = IntersectResult::INTERSECT; + } + + return result; +} + +NS_CC_END diff --git a/cocos/2d/renderer/Frustum.h b/cocos/2d/renderer/Frustum.h new file mode 100644 index 0000000000..d20bdf483a --- /dev/null +++ b/cocos/2d/renderer/Frustum.h @@ -0,0 +1,96 @@ +#ifndef __CC_FRUSTUM_H__ +#define __CC_FRUSTUM_H__ + +#include "CCPlatformMacros.h" +#include "math/kazmath/include/kazmath/kazmath.h" + +NS_CC_BEGIN + +class ViewTransform +{ +public: + ViewTransform(); + ~ViewTransform(); + void Init(const kmVec3& pos, const kmVec3& focus, const kmVec3& up); + + const kmVec3& getPosition() const { return _position; } + const kmVec3& getFocus() const { return _focus; } + const kmVec3& getDirection() const; + const kmVec3& getRight() const; + const kmVec3& getUp() const; + +private: + void LazyAdjust() const; +private: + kmVec3 _position; + kmVec3 _focus; + kmVec3 _up; + + mutable bool _dirty; + mutable kmMat4 _matrix; + mutable kmVec3 _adjustDir; + mutable kmVec3 _adjustRight; + mutable kmVec3 _adjustUp; +}; + +class AABB +{ +public: + AABB(const kmVec3& min, const kmVec3& max); + ~AABB(); + + kmVec3 getCenter() const; + + float getDimensionX() const; + float getDimensionY() const; + float getDimensionZ() const; + + kmVec3 getPositivePoint(const kmVec3& direction) const; + kmVec3 getNegativePoint(const kmVec3& direction) const; + + const AABB& expand(const kmVec3& point); +private: + kmVec3 _min; + kmVec3 _max; +}; + +class Frustum +{ +public: + enum class IntersectResult + { + OUTSIDE = 0, + INTERSECT = 1, + INSIDE = 2 + }; +public: + Frustum(); + ~Frustum(); + + void setupProjectionOrthogonal(const ViewTransform& view, float width, float height, float near, float far); + void setupProjectionPerspective(const ViewTransform& view, float left, float right, float top, float bottom, float near, float far); + void setupProjectionPerspectiveFov(const ViewTransform& view, float fov, float ratio, float near, float far); + + void setupFromMatrix(const kmMat4& view, const kmMat4& projection); + + IntersectResult intersectPoint(const kmVec3& point) const; + IntersectResult intersectAABB(const AABB& aabb) const; + IntersectResult intersectSphere(const kmVec3& center, float radius) const; + +private: + enum FrustumPlane + { + NEAR = 0, + FAR = 1, + BOTTOM = 2, + TOP = 3, + LEFT = 4, + RIGHT = 5, + NUMBER = 6 + }; + kmPlane _frustumPlanes[FrustumPlane::NUMBER]; +}; + +NS_CC_END + +#endif \ No newline at end of file From 3da196ea43003550a8c0a298bfb17e5afdcd91af Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 27 Nov 2013 10:35:12 +0800 Subject: [PATCH 43/98] add Frustum culling to new Sprite --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCDirector.cpp | 19 ++++++++-- cocos/2d/CCDirector.h | 9 +++++ cocos/2d/CCNewSprite.cpp | 38 +++++++++++++++++++ cocos/2d/CCNewSprite.h | 4 +- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index bc19be45cc..b50334c51a 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -89e13afae7209dd4e3bc13d195b83c0be4cf85ae \ No newline at end of file +897a831f2ce0489f68be53deb82150c0c7d86ad9 \ No newline at end of file diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 535ccbb1a0..c586407c46 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -62,7 +62,7 @@ THE SOFTWARE. #include "CCEventDispatcher.h" #include "CCFontFreeType.h" #include "Renderer.h" - +#include "renderer/Frustum.h" /** Position of the FPS @@ -136,7 +136,9 @@ bool Director::init(void) _winSizeInPoints = Size::ZERO; _openGLView = nullptr; - + + _cullingFrustum = new Frustum(); + _contentScaleFactor = 1.0f; // scheduler @@ -260,7 +262,17 @@ void Director::drawScene() } kmGLPushMatrix(); - + + //construct the frustum + { + kmMat4 view; + kmMat4 projection; + kmGLGetMatrix(KM_GL_PROJECTION, &projection); + kmGLGetMatrix(KM_GL_MODELVIEW, &view); + + _cullingFrustum->setupFromMatrix(view, projection); + } + // draw the scene if (_runningScene) { @@ -713,6 +725,7 @@ void Director::purgeDirector() CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_SPFLabel); CC_SAFE_RELEASE_NULL(_drawsLabel); + CC_SAFE_DELETE(_cullingFrustum); // purge bitmap cache LabelBMFont::purgeCachedData(); diff --git a/cocos/2d/CCDirector.h b/cocos/2d/CCDirector.h index 880117a2a3..89ea8197cc 100644 --- a/cocos/2d/CCDirector.h +++ b/cocos/2d/CCDirector.h @@ -55,6 +55,7 @@ class Scheduler; class ActionManager; class EventDispatcher; class TextureCache; +class Frustum; /** @brief Class that creates and handles the main Window and manages how @@ -330,6 +331,12 @@ public: */ void setContentScaleFactor(float scaleFactor); float getContentScaleFactor() const; + + /** + Get the Culling Frustum + */ + + Frustum* getFrustum() const { return _cullingFrustum; } public: /** Gets the Scheduler associated with this director @@ -434,6 +441,8 @@ protected: unsigned int _totalFrames; unsigned int _frames; float _secondsPerFrame; + + Frustum* _cullingFrustum; /* The running scene */ Scene *_runningScene; diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index f9c201464d..9d5570076e 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -11,6 +11,8 @@ #include "Renderer.h" #include "QuadCommand.h" #include "CCMenuItem.h" +#include "Frustum.h" +#include "CCDirector.h" NS_CC_BEGIN @@ -132,10 +134,46 @@ void NewSprite::updateQuadVertices() void NewSprite::draw(void) { updateQuadVertices(); + if(false == culling()) + { + static int count =0; + CCLOG("culling Sprite New to not visible %d ",++count); + return; + } + //TODO implement z order QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } +bool NewSprite::culling() const +{ + Frustum* frustum = Director::getInstance()->getFrustum(); + AffineTransform worldTM = getNodeToWorldTransform(); + //generate aabb + Point lowLeft(0,0); + Point topRight = lowLeft + Point(getContentSize()); + Point lowRight(topRight.x,0); + Point topLeft(0, topRight.y); + + lowLeft = PointApplyAffineTransform(lowLeft,worldTM); + lowRight = PointApplyAffineTransform(lowRight,worldTM); + topRight = PointApplyAffineTransform(topRight,worldTM); + topLeft = PointApplyAffineTransform(topLeft,worldTM); + + kmVec3 point = {lowLeft.x, lowLeft.y, _vertexZ}; + + AABB aabb(point,point); + point = {lowRight.x, lowRight.y, _vertexZ}; + aabb.expand(point); + point = {topLeft.x, topLeft.y, _vertexZ}; + aabb.expand(point); + point = {topRight.x, topRight.y, _vertexZ}; + aabb.expand(point); + + return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb); +} + + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.h b/cocos/2d/CCNewSprite.h index 752d4973f4..8d02b556e4 100644 --- a/cocos/2d/CCNewSprite.h +++ b/cocos/2d/CCNewSprite.h @@ -25,10 +25,12 @@ public: ~NewSprite(); virtual bool initWithTexture(Texture2D *texture, const Rect& rect, bool rotated); - + virtual void updateQuadVertices(); virtual void draw(void) override; + bool culling() const; + protected: }; From dd6c14e88d358f583914a20e850a7e9e233150e7 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 27 Nov 2013 10:35:23 +0800 Subject: [PATCH 44/98] add test case --- .../NewRendererTest/NewRendererTest.cpp | 34 +++++++++++++++++++ .../Classes/NewRendererTest/NewRendererTest.h | 13 +++++++ 2 files changed, 47 insertions(+) diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 6b24656607..8eaafe1a58 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -21,6 +21,7 @@ static std::function createFunctions[] = CL(NewSpriteBatchTest), CL(NewClippingNodeTest), CL(NewDrawNodeTest), + CL(NewCullingTest), }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -401,3 +402,36 @@ string NewDrawNodeTest::subtitle() { return "DrawNode"; } + +NewCullingTest::NewCullingTest() +{ + auto s = Director::getInstance()->getWinSize(); + + auto parent = Node::create(); + parent->setPosition(s.width/2, s.height/2); + addChild(parent); + auto parent2 = Node::create(); + parent2->setPosition(0,0); + parent->addChild(parent2); + parent2->runAction(RepeatForever::create((JumpBy::create(2, Point(0,0), 300, 1)))); + NewSprite* sprite = NewSprite::create("Images/grossini.png"); + sprite->setPosition(Point(0,0)); + sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); + parent2->addChild(sprite); +} + +NewCullingTest::~NewCullingTest() +{ + +} + +string NewCullingTest::title() +{ + return "New Render"; +} + +string NewCullingTest::subtitle() +{ + return "Culling"; +} + diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h index 17d3cd0267..5e0bf64e61 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.h @@ -107,4 +107,17 @@ protected: virtual ~NewDrawNodeTest(); }; +class NewCullingTest : public MultiSceneTest +{ +public: + + CREATE_FUNC(NewCullingTest) + virtual string title(); + virtual string subtitle(); + +protected: + NewCullingTest(); + virtual ~NewCullingTest(); +}; + #endif //__NewRendererTest_H_ From f8281cbb93e9db5349fbfe79e16cdba09e156c4a Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 27 Nov 2013 10:41:01 +0800 Subject: [PATCH 45/98] add test case scale --- .../Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 8eaafe1a58..8eaefd4586 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -416,7 +416,8 @@ NewCullingTest::NewCullingTest() parent2->runAction(RepeatForever::create((JumpBy::create(2, Point(0,0), 300, 1)))); NewSprite* sprite = NewSprite::create("Images/grossini.png"); sprite->setPosition(Point(0,0)); - sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); + //sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); + sprite->runAction(RepeatForever::create(Sequence::createWithTwoActions(ScaleBy::create(2, 2), ScaleBy::create(2,0.5)))); parent2->addChild(sprite); } From ea46e1c6582809fb307e2a5f71434168a303be57 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 27 Nov 2013 14:30:38 +0800 Subject: [PATCH 46/98] change test case --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCNewSprite.cpp | 4 +- .../NewRendererTest/NewRendererTest.cpp | 52 +++++++++++++++---- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index b50334c51a..cfea519254 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -897a831f2ce0489f68be53deb82150c0c7d86ad9 \ No newline at end of file +a5d82b59c287429e558e99fdb693f7507bd381cb \ No newline at end of file diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 9d5570076e..f09d0b549c 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -136,8 +136,8 @@ void NewSprite::draw(void) updateQuadVertices(); if(false == culling()) { - static int count =0; - CCLOG("culling Sprite New to not visible %d ",++count); + //static int count =0; + //CCLOG("culling Sprite New to not visible %d ",++count); return; } diff --git a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp index 8eaefd4586..3d49c82cfa 100644 --- a/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewRendererTest/NewRendererTest.cpp @@ -407,18 +407,52 @@ NewCullingTest::NewCullingTest() { auto s = Director::getInstance()->getWinSize(); + std::vector images; + images.push_back("Images/grossini_dance_01.png"); + images.push_back("Images/grossini_dance_02.png"); + images.push_back("Images/grossini_dance_03.png"); + images.push_back("Images/grossini_dance_04.png"); + images.push_back("Images/grossini_dance_05.png"); + images.push_back("Images/grossini_dance_06.png"); + images.push_back("Images/grossini_dance_07.png"); + images.push_back("Images/grossini_dance_08.png"); + images.push_back("Images/grossini_dance_09.png"); + images.push_back("Images/grossini_dance_10.png"); + images.push_back("Images/grossini_dance_11.png"); + images.push_back("Images/grossini_dance_12.png"); + images.push_back("Images/grossini_dance_13.png"); + images.push_back("Images/grossini_dance_14.png"); + images.push_back("Images/grossini.png"); auto parent = Node::create(); parent->setPosition(s.width/2, s.height/2); addChild(parent); - auto parent2 = Node::create(); - parent2->setPosition(0,0); - parent->addChild(parent2); - parent2->runAction(RepeatForever::create((JumpBy::create(2, Point(0,0), 300, 1)))); - NewSprite* sprite = NewSprite::create("Images/grossini.png"); - sprite->setPosition(Point(0,0)); - //sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); - sprite->runAction(RepeatForever::create(Sequence::createWithTwoActions(ScaleBy::create(2, 2), ScaleBy::create(2,0.5)))); - parent2->addChild(sprite); + for(int index = 0; index < 500; ++index) + { + auto parent2 = Node::create(); + parent2->setPosition(0,0); + parent->addChild(parent2); + parent2->setPosition(-50,0); + parent2->runAction(RepeatForever::create((JumpBy::create(10, Point(0,0), 400, 1)))); + NewSprite* sprite = NewSprite::create(images[index % images.size()].c_str()); + sprite->setPosition(Point(0,0)); + //sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); + sprite->runAction(RepeatForever::create(Sequence::createWithTwoActions(ScaleBy::create(2, 2), ScaleBy::create(2,0.5)))); + parent2->addChild(sprite); + } + + for(int index = 0; index < 500; ++index) + { + auto parent2 = Node::create(); + parent->addChild(parent2); + parent2->setPosition(50,0); + parent2->runAction(RepeatForever::create((JumpBy::create(7, Point(0,0), 400, 1)))); + NewSprite* sprite = NewSprite::create(images[index % images.size()].c_str()); + sprite->setPosition(Point(0,0)); + //sprite->runAction(RepeatForever::create(RotateBy::create(3, 360))); + sprite->runAction(RepeatForever::create(Sequence::createWithTwoActions(ScaleBy::create(2, 2), ScaleBy::create(2,0.5)))); + parent2->addChild(sprite); + } + } NewCullingTest::~NewCullingTest() From 8801f508ebd56f7ac8e6d7b0e315209774f4a160 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 2 Dec 2013 12:13:05 -0800 Subject: [PATCH 47/98] Partcle system use the new renderer --- cocos/2d/CCParticleSystemQuad.cpp | 89 +++++++++++++++++++++++++++++-- cocos/2d/CCParticleSystemQuad.h | 4 ++ cocos/2d/renderer/QuadCommand.cpp | 6 +-- 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index 0b80022d58..d4228cb8f0 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -38,9 +38,13 @@ THE SOFTWARE. #include "CCNotificationCenter.h" #include "CCEventType.h" #include "CCConfiguration.h" +#include "CustomCommand.h" // extern #include "kazmath/GL/matrix.h" +#include "Renderer.h" +#include "QuadCommand.h" +#include "CustomCommand.h" NS_CC_BEGIN @@ -347,10 +351,87 @@ void ParticleSystemQuad::postStep() } // overriding draw method +//void ParticleSystemQuad::draw() +//{ +// CCASSERT(!_batchNode,"draw should not be called when added to a particleBatchNode"); +// +// CC_NODE_DRAW_SETUP(); +// +// GL::bindTexture2D( _texture->getName() ); +// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); +// +// CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); +// +// if (Configuration::getInstance()->supportsShareableVAO()) +// { +// // +// // Using VBO and VAO +// // +// GL::bindVAO(_VAOname); +// +//#if CC_REBIND_INDICES_BUFFER +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); +//#endif +// +// glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0); +// +//#if CC_REBIND_INDICES_BUFFER +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +//#endif +// } +// else +// { +// // +// // Using VBO without VAO +// // +// +// #define kQuadSize sizeof(_quads[0].bl) +// +// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); +// +// glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); +// // vertices +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, vertices)); +// // colors +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, colors)); +// // tex coords +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, texCoords)); +// +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); +// +// glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0); +// +// glBindBuffer(GL_ARRAY_BUFFER, 0); +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +// } +// +// CC_INCREMENT_GL_DRAWS(1); +// CHECK_GL_ERROR_DEBUG(); +//} + + void ParticleSystemQuad::draw() -{ +{ + CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); + + CustomCommand* cmd = new CustomCommand(0, _vertexZ); + cmd->func = CC_CALLBACK_0(ParticleSystemQuad::onDraw, this); + Renderer::getInstance()->addCommand(cmd); + + //TODO render particle using quad command +// QuadCommand* cmd = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, _quads, _particleIdx); +// Renderer::getInstance()->addCommand(cmd); +} + +void ParticleSystemQuad::onDraw() +{ CCASSERT(!_batchNode,"draw should not be called when added to a particleBatchNode"); + kmMat4 prevMatrix; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); + kmGLLoadMatrix(&_transformMatrix); + CC_NODE_DRAW_SETUP(); GL::bindTexture2D( _texture->getName() ); @@ -381,7 +462,7 @@ void ParticleSystemQuad::draw() // Using VBO without VAO // - #define kQuadSize sizeof(_quads[0].bl) +#define kQuadSize sizeof(_quads[0].bl) GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); @@ -392,7 +473,7 @@ void ParticleSystemQuad::draw() glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, texCoords)); - + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0); @@ -403,6 +484,8 @@ void ParticleSystemQuad::draw() CC_INCREMENT_GL_DRAWS(1); CHECK_GL_ERROR_DEBUG(); + + kmGLLoadMatrix(&prevMatrix); } void ParticleSystemQuad::setTotalParticles(int tp) diff --git a/cocos/2d/CCParticleSystemQuad.h b/cocos/2d/CCParticleSystemQuad.h index 5f11dd1533..9b0849bea4 100644 --- a/cocos/2d/CCParticleSystemQuad.h +++ b/cocos/2d/CCParticleSystemQuad.h @@ -108,6 +108,9 @@ public: * @lua NA */ virtual void draw() override; + + void onDraw(); + /** * @js NA * @lua NA @@ -147,6 +150,7 @@ protected: GLuint _buffersVBO[2]; //0: vertex 1: indices + kmMat4 _transformMatrix; private: CC_DISALLOW_COPY_AND_ASSIGN(ParticleSystemQuad); }; diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index cc18bd9c45..ccacac4678 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -78,11 +78,11 @@ void QuadCommand::useMaterial() _shader->setUniformsForBuiltins(); - //set blend mode - GL::blendFunc(_blendType.src, _blendType.dst); - //Set texture GL::bindTexture2D(_textureID); + + //set blend mode + GL::blendFunc(_blendType.src, _blendType.dst); } NS_CC_END \ No newline at end of file From 6862d59bb26d23e79ed38f105b7bf50d43a00472 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 2 Dec 2013 17:23:52 -0800 Subject: [PATCH 48/98] Add NewRenderTexture to convert RenderTexture to use new renderer --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/renderer/CCNewRenderTexture.cpp | 6 +++++ cocos/2d/renderer/CCNewRenderTexture.h | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 cocos/2d/renderer/CCNewRenderTexture.cpp create mode 100644 cocos/2d/renderer/CCNewRenderTexture.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 3ad0e6b7e8..7e28dc21af 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b07400e8b509b42a418e61d158d09a07ec990937 \ No newline at end of file +944e3685bd356b66d0ca108edb041d22353c3edf \ No newline at end of file diff --git a/cocos/2d/renderer/CCNewRenderTexture.cpp b/cocos/2d/renderer/CCNewRenderTexture.cpp new file mode 100644 index 0000000000..d033729e38 --- /dev/null +++ b/cocos/2d/renderer/CCNewRenderTexture.cpp @@ -0,0 +1,6 @@ +// +// Created by NiTe Luo on 12/2/13. +// + + +#include "CCNewRenderTexture.h" diff --git a/cocos/2d/renderer/CCNewRenderTexture.h b/cocos/2d/renderer/CCNewRenderTexture.h new file mode 100644 index 0000000000..59127df957 --- /dev/null +++ b/cocos/2d/renderer/CCNewRenderTexture.h @@ -0,0 +1,26 @@ +// +// Created by NiTe Luo on 12/2/13. +// + + + +#ifndef __CCNewRenderTexture_H_ +#define __CCNewRenderTexture_H_ + +#include "CCRenderTexture.h" + +NS_CC_BEGIN + +class NewRenderTexture : public RenderTexture +{ +public: + +protected: + NewRenderTexture(); + + +}; + +NS_CC_END + +#endif //__CCNewRenderTexture_H_ From ace75eebce79d11f381c41dee2333c2c0aa72a7a Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 3 Dec 2013 11:11:46 +0800 Subject: [PATCH 49/98] refactor: quad command use a non parameter constructor and a reentrant init function --- cocos/2d/CCSprite.cpp | 4 ++-- cocos/2d/renderer/CCNewSprite.cpp | 3 ++- cocos/2d/renderer/CCNewSpriteBatchNode.cpp | 3 ++- cocos/2d/renderer/QuadCommand.cpp | 24 ++++++++++++++++------ cocos/2d/renderer/QuadCommand.h | 3 ++- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 095bf243d2..a77be3c41c 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -663,8 +663,8 @@ void Sprite::draw(void) { updateQuadVertices(); //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); - + QuadCommand* renderCommand = new QuadCommand(); + renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index f09d0b549c..4cce8cb3df 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -142,7 +142,8 @@ void NewSprite::draw(void) } //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + QuadCommand* renderCommand = new QuadCommand(); + renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp index 8d4aac156e..d10becd344 100644 --- a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp @@ -60,7 +60,8 @@ void NewSpriteBatchNode::draw() arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); - QuadCommand* cmd = new QuadCommand(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); + QuadCommand* cmd = new QuadCommand(); + cmd->init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index ccacac4678..5fd6ca5de1 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -8,16 +8,28 @@ NS_CC_BEGIN -QuadCommand::QuadCommand(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount) +QuadCommand::QuadCommand() :RenderCommand() -,_viewport(viewport) -,_depth(depth) -,_textureID(textureID) -,_blendType(blendType) -,_quadCount(quadCount) +,_viewport(0) +,_depth(0) +,_textureID(0) +,_blendType(BlendFunc::DISABLE) +,_quadCount(0) { _type = QUAD_COMMAND; + _shader = nullptr; + _quad = nullptr; +} + +void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount) +{ + _viewport = viewport; + _depth = depth; + _textureID = textureID; + _blendType = blendType; + _quadCount = quadCount; _shader = shader; + free(_quad); _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); memcpy(_quad, quad, sizeof(V3F_C4B_T2F_Quad) * quadCount); } diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 422f00202e..b15bb698a7 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -17,7 +17,8 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { public: - QuadCommand(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); + QuadCommand(); + void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); ~QuadCommand(); // +----------+----------+-----+-----------------------------------+ From d33f05b3f049507e628387816b50b6e0297ed95c Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 3 Dec 2013 11:17:21 +0800 Subject: [PATCH 50/98] refactor: custom command use a non parameter constructor and a reentrant init function --- cocos/2d/CCLayer.cpp | 3 ++- cocos/2d/CCParticleSystemQuad.cpp | 3 ++- cocos/2d/renderer/CCNewDrawNode.cpp | 3 ++- cocos/2d/renderer/CustomCommand.cpp | 12 +++++++++--- cocos/2d/renderer/CustomCommand.h | 3 ++- cocos/2d/renderer/NewClippingNode.cpp | 9 ++++++--- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index cb9c493df5..19892ac30e 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -695,7 +695,8 @@ void LayerColor::updateColor() void LayerColor::draw() { kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(0, _vertexZ); + CustomCommand* cmd = new CustomCommand(); + cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index d4228cb8f0..a7a43aa55f 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -415,7 +415,8 @@ void ParticleSystemQuad::draw() CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(0, _vertexZ); + CustomCommand* cmd = new CustomCommand(); + cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(ParticleSystemQuad::onDraw, this); Renderer::getInstance()->addCommand(cmd); diff --git a/cocos/2d/renderer/CCNewDrawNode.cpp b/cocos/2d/renderer/CCNewDrawNode.cpp index c10c472dcd..e2da995dcc 100644 --- a/cocos/2d/renderer/CCNewDrawNode.cpp +++ b/cocos/2d/renderer/CCNewDrawNode.cpp @@ -44,7 +44,8 @@ void NewDrawNode::draw() { kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(0, _vertexZ); + CustomCommand* cmd = new CustomCommand(); + cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/renderer/CustomCommand.cpp b/cocos/2d/renderer/CustomCommand.cpp index 86befadde6..7ff11d6310 100644 --- a/cocos/2d/renderer/CustomCommand.cpp +++ b/cocos/2d/renderer/CustomCommand.cpp @@ -7,15 +7,21 @@ NS_CC_BEGIN -CustomCommand::CustomCommand(int viewport, int32_t depth) +CustomCommand::CustomCommand() :RenderCommand() -, _viewport(viewport) -, _depth(depth) +, _viewport(0) +, _depth(0) , func(nullptr) { _type = CUSTOM_COMMAND; } +void CustomCommand::init(int viewport, int32_t depth) +{ + _viewport = viewport; + _depth = depth; +} + CustomCommand::~CustomCommand() { diff --git a/cocos/2d/renderer/CustomCommand.h b/cocos/2d/renderer/CustomCommand.h index bc6dc99684..cf66612b37 100644 --- a/cocos/2d/renderer/CustomCommand.h +++ b/cocos/2d/renderer/CustomCommand.h @@ -15,7 +15,8 @@ using namespace std; class CustomCommand : public RenderCommand { public: - CustomCommand(int viewport, int32_t depth); + CustomCommand(); + void init(int viewport, int32_t depth); ~CustomCommand(); // +----------+----------+-----+-----------------------------------+ diff --git a/cocos/2d/renderer/NewClippingNode.cpp b/cocos/2d/renderer/NewClippingNode.cpp index b480e2d837..1384a5b1a9 100644 --- a/cocos/2d/renderer/NewClippingNode.cpp +++ b/cocos/2d/renderer/NewClippingNode.cpp @@ -90,19 +90,22 @@ void NewClippingNode::visit() renderer->pushGroup(groupCommand->getRenderQueueID()); - CustomCommand* beforeVisitCmd = new CustomCommand(0,_vertexZ); + CustomCommand* beforeVisitCmd = new CustomCommand(); + beforeVisitCmd->init(0,_vertexZ); beforeVisitCmd->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); renderer->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); _stencil->visit(); - CustomCommand* afterDrawStencilCmd = new CustomCommand(0,_vertexZ); + CustomCommand* afterDrawStencilCmd = new CustomCommand(); + afterDrawStencilCmd->init(0,_vertexZ); afterDrawStencilCmd->func = CC_CALLBACK_0(NewClippingNode::afterDrawStencil, this); renderer->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); Node::visit(); - CustomCommand* afterVisitCmd = new CustomCommand(0,_vertexZ); + CustomCommand* afterVisitCmd = new CustomCommand(); + afterVisitCmd->init(0,_vertexZ); afterVisitCmd->func = CC_CALLBACK_0(NewClippingNode::afterVisit, this); renderer->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); From d4b9e0538b20d5a77892f24b1f7701a38c95692b Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 3 Dec 2013 11:24:03 +0800 Subject: [PATCH 51/98] refactor: group command use a non parameter constructor and a reentrant init function --- cocos/2d/renderer/GroupCommand.cpp | 14 +++++++++++--- cocos/2d/renderer/GroupCommand.h | 3 ++- cocos/2d/renderer/NewClippingNode.cpp | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cocos/2d/renderer/GroupCommand.cpp b/cocos/2d/renderer/GroupCommand.cpp index 0e52cd9b76..93530fb31f 100644 --- a/cocos/2d/renderer/GroupCommand.cpp +++ b/cocos/2d/renderer/GroupCommand.cpp @@ -63,15 +63,23 @@ void GroupCommandManager::releaseGroupID(int groupID) _groupMapping[groupID] = false; } -GroupCommand::GroupCommand(int viewport, int32_t depth) +GroupCommand::GroupCommand() :RenderCommand() -, _viewport(viewport) -, _depth(depth) +, _viewport(0) +, _depth(0) { _type = GROUP_COMMAND; _renderQueueID = GroupCommandManager::getInstance()->getGroupID(); } +void GroupCommand::init(int viewport, int32_t depth) +{ + _viewport = viewport; + _depth = depth; + GroupCommandManager::getInstance()->releaseGroupID(_renderQueueID); + _renderQueueID = GroupCommandManager::getInstance()->getGroupID(); +} + GroupCommand::~GroupCommand() { GroupCommandManager::getInstance()->releaseGroupID(_renderQueueID); diff --git a/cocos/2d/renderer/GroupCommand.h b/cocos/2d/renderer/GroupCommand.h index 997f6e9622..fdfce93be2 100644 --- a/cocos/2d/renderer/GroupCommand.h +++ b/cocos/2d/renderer/GroupCommand.h @@ -35,7 +35,8 @@ class GroupCommand : public RenderCommand { public: - GroupCommand(int viewport, int32_t depth); + GroupCommand(); + void init(int viewport, int32_t depth); ~GroupCommand(); // +----------+----------+-----+-----------------------------------+ diff --git a/cocos/2d/renderer/NewClippingNode.cpp b/cocos/2d/renderer/NewClippingNode.cpp index 1384a5b1a9..8caccbcbd6 100644 --- a/cocos/2d/renderer/NewClippingNode.cpp +++ b/cocos/2d/renderer/NewClippingNode.cpp @@ -85,7 +85,8 @@ void NewClippingNode::visit() Renderer* renderer = Renderer::getInstance(); - GroupCommand* groupCommand = new GroupCommand(0,_vertexZ); + GroupCommand* groupCommand = new GroupCommand(); + groupCommand->init(0,_vertexZ); renderer->addCommand(groupCommand); renderer->pushGroup(groupCommand->getRenderQueueID()); From 44f12ce8e4b2e6949e3397a80992c13345f612de Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 3 Dec 2013 11:52:51 +0800 Subject: [PATCH 52/98] add RenderCommandPool head file --- cocos/2d/renderer/RenderCommandPool.h | 75 +++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 cocos/2d/renderer/RenderCommandPool.h diff --git a/cocos/2d/renderer/RenderCommandPool.h b/cocos/2d/renderer/RenderCommandPool.h new file mode 100644 index 0000000000..330051bdec --- /dev/null +++ b/cocos/2d/renderer/RenderCommandPool.h @@ -0,0 +1,75 @@ +// +// RenderCommandPool.h +// cocos2d_libs +// +// Created by Huabing on 11/28/13. +// +// + +#ifndef __CC_RENDERCOMMANDPOOL_H__ +#define __CC_RENDERCOMMANDPOOL_H__ + +#include +#include +#include "CCPlatformMacros.h" +NS_CC_BEGIN + +template +class RenderCommandPool +{ +public: + RenderCommandPool() + { + } + ~RenderCommandPool() + { +// if( 0 != _usedPool.size()) +// { +// CCLOG("All RenderCommand should not be used when Pool is released!"); +// } + for (typename std::list::iterator iter = _freePool.begin(); iter != _freePool.end(); ++iter) + { + delete *iter; + *iter = nullptr; + } + _freePool.clear(); + } + +public: + T* generateCommand() + { + T* result = nullptr; + if(0 == _freePool.size()) + { + result = new T(); + } + else + { + result = _freePool.front(); + _freePool.pop_front(); + } + //_usedPool.insert(result); + return result; + } + + void pushBackCommand(T* ptr) + { +// if(_usedPool.find(ptr) == _usedPool.end()) +// { +// CCLOG("push Back Wrong command!"); +// return; +// } + + _freePool.push_back(ptr); + //_usedPool.erase(ptr); + + } + +private: + std::list _freePool; + //std::set _usedPool; +}; + +NS_CC_END + +#endif From 757f1abc7fe8a82a7abe55213e6dedceedb37cc8 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Tue, 3 Dec 2013 14:08:47 +0800 Subject: [PATCH 53/98] 1. protected render command construction/destruction function. 2. use renderCommandPool to allocate and deallocate command 3. use releaseToCommandPool interface to push command back to pool --- cocos/2d/CCLayer.cpp | 2 +- cocos/2d/CCParticleSystemQuad.cpp | 2 +- cocos/2d/CCSprite.cpp | 2 +- cocos/2d/renderer/CCNewDrawNode.cpp | 2 +- cocos/2d/renderer/CCNewSprite.cpp | 2 +- cocos/2d/renderer/CCNewSpriteBatchNode.cpp | 2 +- cocos/2d/renderer/CustomCommand.cpp | 6 ++++++ cocos/2d/renderer/CustomCommand.h | 14 ++++++++++++-- cocos/2d/renderer/GroupCommand.cpp | 6 ++++++ cocos/2d/renderer/GroupCommand.h | 16 ++++++++++++---- cocos/2d/renderer/NewClippingNode.cpp | 8 ++++---- cocos/2d/renderer/QuadCommand.cpp | 6 ++++++ cocos/2d/renderer/QuadCommand.h | 14 ++++++++++++-- cocos/2d/renderer/RenderCommand.h | 8 ++++---- cocos/2d/renderer/Renderer.cpp | 2 +- 15 files changed, 69 insertions(+), 23 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 19892ac30e..0878910518 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -695,7 +695,7 @@ void LayerColor::updateColor() void LayerColor::draw() { kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(); + CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); Renderer::getInstance()->addCommand(cmd); diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index a7a43aa55f..ad5c1b834e 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -415,7 +415,7 @@ void ParticleSystemQuad::draw() CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(); + CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(ParticleSystemQuad::onDraw, this); Renderer::getInstance()->addCommand(cmd); diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index a77be3c41c..815079eb8e 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -663,7 +663,7 @@ void Sprite::draw(void) { updateQuadVertices(); //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(); + QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/renderer/CCNewDrawNode.cpp b/cocos/2d/renderer/CCNewDrawNode.cpp index e2da995dcc..6b97034fc6 100644 --- a/cocos/2d/renderer/CCNewDrawNode.cpp +++ b/cocos/2d/renderer/CCNewDrawNode.cpp @@ -44,7 +44,7 @@ void NewDrawNode::draw() { kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = new CustomCommand(); + CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); Renderer::getInstance()->addCommand(cmd); diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 4cce8cb3df..cca9a811f1 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -142,7 +142,7 @@ void NewSprite::draw(void) } //TODO implement z order - QuadCommand* renderCommand = new QuadCommand(); + QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); diff --git a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp index d10becd344..bd1ab8a04c 100644 --- a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp @@ -60,7 +60,7 @@ void NewSpriteBatchNode::draw() arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); - QuadCommand* cmd = new QuadCommand(); + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/renderer/CustomCommand.cpp b/cocos/2d/renderer/CustomCommand.cpp index 7ff11d6310..c24dec1619 100644 --- a/cocos/2d/renderer/CustomCommand.cpp +++ b/cocos/2d/renderer/CustomCommand.cpp @@ -6,6 +6,7 @@ #include "CustomCommand.h" NS_CC_BEGIN +RenderCommandPool CustomCommand::_commandPool; CustomCommand::CustomCommand() :RenderCommand() @@ -46,4 +47,9 @@ void CustomCommand::execute() } } +void CustomCommand::releaseToCommandPool() +{ + getCommandPool().pushBackCommand(this); +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/CustomCommand.h b/cocos/2d/renderer/CustomCommand.h index cf66612b37..aa78f6657c 100644 --- a/cocos/2d/renderer/CustomCommand.h +++ b/cocos/2d/renderer/CustomCommand.h @@ -8,16 +8,19 @@ #define _CC_CUSTOMCOMMAND_H_ #include "RenderCommand.h" +#include "RenderCommandPool.h" NS_CC_BEGIN using namespace std; class CustomCommand : public RenderCommand { -public: +protected: CustomCommand(); - void init(int viewport, int32_t depth); ~CustomCommand(); + +public: + void init(int viewport, int32_t depth); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -29,6 +32,7 @@ public: void execute(); inline bool isTranslucent() { return true; } + virtual void releaseToCommandPool() override; public: function func; @@ -37,6 +41,12 @@ protected: int _viewport; int32_t _depth; + +public: + friend class RenderCommandPool; + static RenderCommandPool& getCommandPool() { return _commandPool; } +protected: + static RenderCommandPool _commandPool; }; diff --git a/cocos/2d/renderer/GroupCommand.cpp b/cocos/2d/renderer/GroupCommand.cpp index 93530fb31f..46939b267e 100644 --- a/cocos/2d/renderer/GroupCommand.cpp +++ b/cocos/2d/renderer/GroupCommand.cpp @@ -7,6 +7,7 @@ #include "Renderer.h" NS_CC_BEGIN +RenderCommandPool GroupCommand::_commandPool; static GroupCommandManager* s_instance; GroupCommandManager *GroupCommandManager::getInstance() @@ -96,5 +97,10 @@ int64_t GroupCommand::generateID() return _id; } +void GroupCommand::releaseToCommandPool() +{ + getCommandPool().pushBackCommand(this); +} + NS_CC_END diff --git a/cocos/2d/renderer/GroupCommand.h b/cocos/2d/renderer/GroupCommand.h index fdfce93be2..de99966b1e 100644 --- a/cocos/2d/renderer/GroupCommand.h +++ b/cocos/2d/renderer/GroupCommand.h @@ -9,6 +9,7 @@ #include "CCPlatformMacros.h" #include "RenderCommand.h" +#include "RenderCommandPool.h" #include NS_CC_BEGIN @@ -33,11 +34,11 @@ protected: class GroupCommand : public RenderCommand { - -public: +protected: GroupCommand(); - void init(int viewport, int32_t depth); ~GroupCommand(); +public: + void init(int viewport, int32_t depth); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -48,11 +49,18 @@ public: inline bool isTranslucent() {return true;} inline int getRenderQueueID() {return _renderQueueID;} - + virtual void releaseToCommandPool() override; + protected: int _viewport; int32_t _depth; int _renderQueueID; + +public: + friend class RenderCommandPool; + static RenderCommandPool& getCommandPool() { return _commandPool; } +protected: + static RenderCommandPool _commandPool; }; NS_CC_END diff --git a/cocos/2d/renderer/NewClippingNode.cpp b/cocos/2d/renderer/NewClippingNode.cpp index 8caccbcbd6..5474516336 100644 --- a/cocos/2d/renderer/NewClippingNode.cpp +++ b/cocos/2d/renderer/NewClippingNode.cpp @@ -85,27 +85,27 @@ void NewClippingNode::visit() Renderer* renderer = Renderer::getInstance(); - GroupCommand* groupCommand = new GroupCommand(); + GroupCommand* groupCommand = GroupCommand::getCommandPool().generateCommand(); groupCommand->init(0,_vertexZ); renderer->addCommand(groupCommand); renderer->pushGroup(groupCommand->getRenderQueueID()); - CustomCommand* beforeVisitCmd = new CustomCommand(); + CustomCommand* beforeVisitCmd = CustomCommand::getCommandPool().generateCommand(); beforeVisitCmd->init(0,_vertexZ); beforeVisitCmd->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); renderer->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); _stencil->visit(); - CustomCommand* afterDrawStencilCmd = new CustomCommand(); + CustomCommand* afterDrawStencilCmd = CustomCommand::getCommandPool().generateCommand(); afterDrawStencilCmd->init(0,_vertexZ); afterDrawStencilCmd->func = CC_CALLBACK_0(NewClippingNode::afterDrawStencil, this); renderer->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); Node::visit(); - CustomCommand* afterVisitCmd = new CustomCommand(); + CustomCommand* afterVisitCmd = CustomCommand::getCommandPool().generateCommand(); afterVisitCmd->init(0,_vertexZ); afterVisitCmd->func = CC_CALLBACK_0(NewClippingNode::afterVisit, this); renderer->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 5fd6ca5de1..1c5b190a1d 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -7,6 +7,7 @@ #include "ccGLStateCache.h" NS_CC_BEGIN +RenderCommandPool QuadCommand::_commandPool; QuadCommand::QuadCommand() :RenderCommand() @@ -97,4 +98,9 @@ void QuadCommand::useMaterial() GL::blendFunc(_blendType.src, _blendType.dst); } +void QuadCommand::releaseToCommandPool() +{ + getCommandPool().pushBackCommand(this); +} + NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index b15bb698a7..78e7323820 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -9,6 +9,7 @@ #include "RenderCommand.h" #include "CCGLProgram.h" +#include "RenderCommandPool.h" NS_CC_BEGIN @@ -16,10 +17,12 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { -public: +protected: QuadCommand(); - void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); ~QuadCommand(); + +public: + void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -44,6 +47,8 @@ public: inline GLProgram* getShader() { return _shader; } inline BlendFunc getBlendType() { return _blendType; } + + virtual void releaseToCommandPool() override; protected: int32_t _materialID; @@ -64,6 +69,11 @@ protected: V3F_C4B_T2F_Quad* _quad; int _quadCount; +public: + friend class RenderCommandPool; + static RenderCommandPool& getCommandPool() { return _commandPool; } +protected: + static RenderCommandPool _commandPool; }; NS_CC_END diff --git a/cocos/2d/renderer/RenderCommand.h b/cocos/2d/renderer/RenderCommand.h index 7c055e7cb7..eb136ec520 100644 --- a/cocos/2d/renderer/RenderCommand.h +++ b/cocos/2d/renderer/RenderCommand.h @@ -25,19 +25,19 @@ enum RenderCommandType //TODO make RenderCommand inherent from Object class RenderCommand { -public: - +protected: RenderCommand(); virtual ~RenderCommand(); +public: virtual int64_t generateID() = 0; virtual /** * Get Render Command Id */ inline int64_t getID() { return _id; } - + virtual inline RenderCommandType getType() { return _type; } - + virtual void releaseToCommandPool() =0; protected: void printID(); diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 1c332b5d8e..cb752b9b70 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -245,7 +245,7 @@ void Renderer::render() //TODO give command back to command pool for (size_t j = 0 ; j < _renderGroups.size(); j++) { - for_each(_renderGroups[j].begin(), _renderGroups[j].end(), [](RenderCommand* cmd){delete cmd;}); + for_each(_renderGroups[j].begin(), _renderGroups[j].end(), [](RenderCommand* cmd){ cmd->releaseToCommandPool(); }); _renderGroups[j].clear(); } From cd562676f5d393208f87bdadf60fb04de8b5719d Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Wed, 4 Dec 2013 10:39:34 +0800 Subject: [PATCH 54/98] use block allocation for commands --- cocos/2d/renderer/RenderCommandPool.h | 31 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/cocos/2d/renderer/RenderCommandPool.h b/cocos/2d/renderer/RenderCommandPool.h index 330051bdec..17e4716a38 100644 --- a/cocos/2d/renderer/RenderCommandPool.h +++ b/cocos/2d/renderer/RenderCommandPool.h @@ -27,27 +27,25 @@ public: // { // CCLOG("All RenderCommand should not be used when Pool is released!"); // } - for (typename std::list::iterator iter = _freePool.begin(); iter != _freePool.end(); ++iter) + _freePool.clear(); + for (typename std::list::iterator iter = _allocatedPoolBlocks.begin(); iter != _allocatedPoolBlocks.end(); ++iter) { - delete *iter; + delete[] *iter; *iter = nullptr; } - _freePool.clear(); + _allocatedPoolBlocks.clear(); } public: T* generateCommand() { T* result = nullptr; - if(0 == _freePool.size()) + if(_freePool.empty()) { - result = new T(); - } - else - { - result = _freePool.front(); - _freePool.pop_front(); + AllocateCommands(); } + result = _freePool.front(); + _freePool.pop_front(); //_usedPool.insert(result); return result; } @@ -64,8 +62,19 @@ public: //_usedPool.erase(ptr); } - private: + void AllocateCommands() + { + static const int COMMANDS_ALLOCATE_BLOCK_SIZE = 32; + T* commands = new T[COMMANDS_ALLOCATE_BLOCK_SIZE]; + _allocatedPoolBlocks.push_back(commands); + for(int index = 0; index < COMMANDS_ALLOCATE_BLOCK_SIZE; ++index) + { + _freePool.push_back(commands+index); + } + } +private: + std::list _allocatedPoolBlocks; std::list _freePool; //std::set _usedPool; }; From ae551ae294b709fbc528ba5d83165d399ba3467f Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 11:54:57 -0800 Subject: [PATCH 55/98] Convert RenderTexture to use RenderCommands --- cocos/2d/CCRenderTexture.cpp | 1 + cocos/2d/CCRenderTexture.h | 16 +- cocos/2d/CCTransitionProgress.cpp | 3 +- cocos/2d/renderer/CCNewRenderTexture.cpp | 293 ++++++++++++++++++ cocos/2d/renderer/CCNewRenderTexture.h | 23 ++ cocos/2d/renderer/CCNewSprite.cpp | 4 +- .../RenderTextureTest/RenderTextureTest.cpp | 13 +- .../RenderTextureTest/RenderTextureTest.h | 3 +- 8 files changed, 336 insertions(+), 20 deletions(-) diff --git a/cocos/2d/CCRenderTexture.cpp b/cocos/2d/CCRenderTexture.cpp index a35a564f85..9f1e10b1cb 100644 --- a/cocos/2d/CCRenderTexture.cpp +++ b/cocos/2d/CCRenderTexture.cpp @@ -411,6 +411,7 @@ void RenderTexture::end() kmGLPopMatrix(); } +//TODO find a better way to clear the screen, there is no need to rebind render buffer there. void RenderTexture::clear(float r, float g, float b, float a) { this->beginWithClear(r, g, b, a); diff --git a/cocos/2d/CCRenderTexture.h b/cocos/2d/CCRenderTexture.h index 5837848eab..8425f50b43 100644 --- a/cocos/2d/CCRenderTexture.h +++ b/cocos/2d/CCRenderTexture.h @@ -59,35 +59,35 @@ public: /** creates a RenderTexture object with width and height in Points, pixel format is RGBA8888 */ static RenderTexture * create(int w, int h); - /** starts grabbing */ + virtual /** starts grabbing */ void begin(); /** starts rendering to the texture while clearing the texture first. This is more efficient then calling -clear first and then -begin */ - void beginWithClear(float r, float g, float b, float a); + virtual void beginWithClear(float r, float g, float b, float a); /** starts rendering to the texture while clearing the texture first. This is more efficient then calling -clear first and then -begin */ - void beginWithClear(float r, float g, float b, float a, float depthValue); + virtual void beginWithClear(float r, float g, float b, float a, float depthValue); /** starts rendering to the texture while clearing the texture first. This is more efficient then calling -clear first and then -begin */ - void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue); + virtual void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue); /** end is key word of lua, use other name to export to lua. */ inline void endToLua(){ end();}; - /** ends grabbing*/ + virtual /** ends grabbing*/ void end(); /** clears the texture with a color */ void clear(float r, float g, float b, float a); /** clears the texture with a specified depth value */ - void clearDepth(float depthValue); + virtual void clearDepth(float depthValue); /** clears the texture with a specified stencil value */ - void clearStencil(int stencilValue); + virtual void clearStencil(int stencilValue); /* creates a new Image from with the texture's data. Caller is responsible for releasing it by calling delete. */ @@ -164,7 +164,7 @@ public: bool initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat eFormat, GLuint uDepthStencilFormat); protected: - void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags); + virtual void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags); GLuint _FBO; GLuint _depthRenderBufffer; diff --git a/cocos/2d/CCTransitionProgress.cpp b/cocos/2d/CCTransitionProgress.cpp index 1d53f9cbed..babf9e3ca7 100644 --- a/cocos/2d/CCTransitionProgress.cpp +++ b/cocos/2d/CCTransitionProgress.cpp @@ -77,8 +77,7 @@ void TransitionProgress::onEnter() texture->setAnchorPoint(Point(0.5f,0.5f)); // render outScene to its texturebuffer - texture->clear(0, 0, 0, 1); - texture->begin(); + texture->beginWithClear(0, 0, 0, 1); _sceneToBeModified->visit(); texture->end(); diff --git a/cocos/2d/renderer/CCNewRenderTexture.cpp b/cocos/2d/renderer/CCNewRenderTexture.cpp index d033729e38..b04b45d276 100644 --- a/cocos/2d/renderer/CCNewRenderTexture.cpp +++ b/cocos/2d/renderer/CCNewRenderTexture.cpp @@ -4,3 +4,296 @@ #include "CCNewRenderTexture.h" +#include "CustomCommand.h" +#include "Renderer.h" +#include "GroupCommand.h" +#include "CCConfiguration.h" +#include "CCDirector.h" + +NS_CC_BEGIN + +NewRenderTexture* NewRenderTexture::create(int w, int h, Texture2D::PixelFormat eFormat, GLuint uDepthStencilFormat) +{ + NewRenderTexture* pRet = new NewRenderTexture(); + + if(pRet && pRet->initWithWidthAndHeight(w, h, eFormat, uDepthStencilFormat)) + { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return NULL; +} + +NewRenderTexture* NewRenderTexture::create(int w, int h, Texture2D::PixelFormat eFormat) +{ + NewRenderTexture* pRet = new NewRenderTexture(); + + if(pRet && pRet->initWithWidthAndHeight(w, h, eFormat)) + { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return NULL; +} + +NewRenderTexture* NewRenderTexture::create(int w, int h) +{ + NewRenderTexture* pRet = new NewRenderTexture(); + + if(pRet && pRet->initWithWidthAndHeight(w, h, Texture2D::PixelFormat::RGB888 , 0)) + { + pRet->autorelease(); + return pRet; + } + CC_SAFE_DELETE(pRet); + return NULL; +} + +void NewRenderTexture::draw() +{ + if (_autoDraw) + { + //Begin will create a render group using new render target + begin(); + + //clear screen + CustomCommand* clearCmd = new CustomCommand(); + clearCmd->init(0, _vertexZ); + clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this); + Renderer::getInstance()->addCommand(clearCmd); + + //! make sure all children are drawn + sortAllChildren(); + + Object *pElement; + CCARRAY_FOREACH(_children, pElement) + { + Node *child = static_cast(pElement); + + if (child != _sprite) + { + child->visit(); + } + } + + //End will pop the current render group + end(); + } +} + +void NewRenderTexture::beginWithClear(float r, float g, float b, float a) +{ + beginWithClear(r, g, b, a, 0, 0, GL_COLOR_BUFFER_BIT); +} + +void NewRenderTexture::beginWithClear(float r, float g, float b, float a, float depthValue) +{ + beginWithClear(r, g, b, a, depthValue, 0, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); +} + +void NewRenderTexture::beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue) +{ + beginWithClear(r, g, b, a, depthValue, stencilValue, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); +} + +void NewRenderTexture::beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags) +{ + setClearColor({r, g, b, a}); + + setClearDepth(depthValue); + + setClearStencil(stencilValue); + + setClearFlags(flags); + + this->begin(); + + //clear screen + CustomCommand* clearCmd = new CustomCommand(); + clearCmd->init(0, _vertexZ); + clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this); + Renderer::getInstance()->addCommand(clearCmd); +} + +void NewRenderTexture::begin() +{ + kmGLMatrixMode(KM_GL_PROJECTION); + kmGLPushMatrix(); + kmGLGetMatrix(KM_GL_PROJECTION, &_projectionMatrix); + + kmGLMatrixMode(KM_GL_MODELVIEW); + kmGLPushMatrix(); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); + + GroupCommand* groupCommand = new GroupCommand(); + groupCommand->init(0, _vertexZ); + + Renderer::getInstance()->pushGroup(groupCommand->getRenderQueueID()); + + CustomCommand* beginCmd = new CustomCommand(); + beginCmd->init(0, _vertexZ); + beginCmd->func = CC_CALLBACK_0(NewRenderTexture::onBegin, this); + + Renderer::getInstance()->addCommand(beginCmd); +} + +void NewRenderTexture::end() +{ + CustomCommand* endCmd = new CustomCommand(); + endCmd->init(0, _vertexZ); + endCmd->func = CC_CALLBACK_0(NewRenderTexture::onEnd, this); + + Renderer::getInstance()->addCommand(endCmd); + + Renderer::getInstance()->popGroup(); +} + +void NewRenderTexture::onBegin() +{ + // + kmGLGetMatrix(KM_GL_PROJECTION, &_oldProjMatrix); + kmGLMatrixMode(KM_GL_PROJECTION); + kmGLLoadMatrix(&_projectionMatrix); + + kmGLGetMatrix(KM_GL_MODELVIEW, &_oldTransMatrix); + kmGLMatrixMode(KM_GL_MODELVIEW); + kmGLLoadMatrix(&_transformMatrix); + + Director *director = Director::getInstance(); + director->setProjection(director->getProjection()); + + const Size& texSize = _texture->getContentSizeInPixels(); + + // Calculate the adjustment ratios based on the old and new projections + Size size = director->getWinSizeInPixels(); + float widthRatio = size.width / texSize.width; + float heightRatio = size.height / texSize.height; + + // Adjust the orthographic projection and viewport + glViewport(0, 0, (GLsizei)texSize.width, (GLsizei)texSize.height); + + + kmMat4 orthoMatrix; + kmMat4OrthographicProjection(&orthoMatrix, (float)-1.0 / widthRatio, (float)1.0 / widthRatio, + (float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1,1 ); + kmGLMultMatrix(&orthoMatrix); + + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO); + glBindFramebuffer(GL_FRAMEBUFFER, _FBO); + + //TODO move this to configration, so we don't check it every time + /* Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers. + */ + if (Configuration::getInstance()->checkForGLExtension("GL_QCOM")) + { + // -- bind a temporary texture so we can clear the render buffer without losing our texture + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0); + CHECK_GL_ERROR_DEBUG(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0); + } +} + +void NewRenderTexture::onEnd() +{ + Director *director = Director::getInstance(); + + glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO); + + // restore viewport + director->setViewport(); + + // + kmGLMatrixMode(KM_GL_PROJECTION); + kmGLLoadMatrix(&_oldProjMatrix); + + kmGLMatrixMode(KM_GL_MODELVIEW); + kmGLLoadMatrix(&_oldTransMatrix); +} + +void NewRenderTexture::onClear() +{ + // save clear color + GLfloat oldClearColor[4] = {0.0f}; + GLfloat oldDepthClearValue = 0.0f; + GLint oldStencilClearValue = 0; + + // backup and set + if (_clearFlags & GL_COLOR_BUFFER_BIT) + { + glGetFloatv(GL_COLOR_CLEAR_VALUE, oldClearColor); + glClearColor(_clearColor.r, _clearColor.g, _clearColor.b, _clearColor.a); + } + + if (_clearFlags & GL_DEPTH_BUFFER_BIT) + { + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &oldDepthClearValue); + glClearDepth(_clearDepth); + } + + if (_clearFlags & GL_STENCIL_BUFFER_BIT) + { + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &oldStencilClearValue); + glClearStencil(_clearStencil); + } + + // clear + glClear(_clearFlags); + + // restore + if (_clearFlags & GL_COLOR_BUFFER_BIT) + { + glClearColor(oldClearColor[0], oldClearColor[1], oldClearColor[2], oldClearColor[3]); + } + if (_clearFlags & GL_DEPTH_BUFFER_BIT) + { + glClearDepth(oldDepthClearValue); + } + if (_clearFlags & GL_STENCIL_BUFFER_BIT) + { + glClearStencil(oldStencilClearValue); + } +} + +void NewRenderTexture::clearDepth(float depthValue) +{ + setClearDepth(depthValue); + + this->begin(); + + CustomCommand* cmd = new CustomCommand(); + cmd->init(0, _vertexZ); + cmd->func = CC_CALLBACK_0(NewRenderTexture::onClearDepth, this); + + Renderer::getInstance()->addCommand(cmd); + + this->end(); +} + +void NewRenderTexture::onClearDepth() +{ + //! save old depth value + GLfloat depthClearValue; + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depthClearValue); + + glClearDepth(_clearDepth); + glClear(GL_DEPTH_BUFFER_BIT); + + // restore clear color + glClearDepth(depthClearValue); +} + +NewRenderTexture::NewRenderTexture() +:RenderTexture() +{ + +} + +NewRenderTexture::~NewRenderTexture() +{ + +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/CCNewRenderTexture.h b/cocos/2d/renderer/CCNewRenderTexture.h index 59127df957..f6f29357a1 100644 --- a/cocos/2d/renderer/CCNewRenderTexture.h +++ b/cocos/2d/renderer/CCNewRenderTexture.h @@ -14,11 +14,34 @@ NS_CC_BEGIN class NewRenderTexture : public RenderTexture { public: + static NewRenderTexture* create(int w, int h, Texture2D::PixelFormat eFormat, GLuint uDepthStencilFormat); + static NewRenderTexture* create(int w, int h, Texture2D::PixelFormat eFormat); + static NewRenderTexture* create(int w, int h); + + void beginWithClear(float r, float g, float b, float a); + void beginWithClear(float r, float g, float b, float a, float depthValue); + void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue); + void beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags); + + virtual void begin() override; + virtual void end() override; + virtual void draw() override; + + void clearDepth(float depthValue); protected: NewRenderTexture(); + virtual ~NewRenderTexture(); + void onBegin(); + void onEnd(); + //Clear render buffer + void onClear(); + void onClearDepth(); + + kmMat4 _oldTransMatrix, _oldProjMatrix; + kmMat4 _transformMatrix, _projectionMatrix; }; NS_CC_END diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 4cce8cb3df..996478c493 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -134,10 +134,8 @@ void NewSprite::updateQuadVertices() void NewSprite::draw(void) { updateQuadVertices(); - if(false == culling()) + if(!culling()) { - //static int count =0; - //CCLOG("culling Sprite New to not visible %d ",++count); return; } diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp index ff4edc2b0a..069af3764c 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.cpp @@ -1,6 +1,7 @@ #include "CCConfiguration.h" #include "RenderTextureTest.h" #include "../testBasic.h" +#include "renderer/CCNewRenderTexture.h" // Test #1 by Jason Booth (slipster216) // Test #3 by David Deaco (ddeaco) @@ -92,7 +93,7 @@ RenderTextureSave::RenderTextureSave() auto s = Director::getInstance()->getWinSize(); // create a render texture, this is what we are going to draw into - _target = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888); + _target = NewRenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888); _target->retain(); _target->setPosition(Point(s.width / 2, s.height / 2)); @@ -240,7 +241,7 @@ RenderTextureIssue937::RenderTextureIssue937() /* A2 & B2 setup */ - auto rend = RenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888); + auto rend = NewRenderTexture::create(32, 64, Texture2D::PixelFormat::RGBA8888); if (NULL == rend) { @@ -409,7 +410,7 @@ void RenderTextureZbuffer::onTouchesEnded(const std::vector& touches, Ev void RenderTextureZbuffer::renderScreenShot() { - auto texture = RenderTexture::create(512, 512); + auto texture = NewRenderTexture::create(512, 512); if (NULL == texture) { return; @@ -443,7 +444,7 @@ RenderTextureTestDepthStencil::RenderTextureTestDepthStencil() auto sprite = Sprite::create("Images/fire.png"); sprite->setPosition(Point(s.width * 0.25f, 0)); sprite->setScale(10); - auto rend = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444, GL_DEPTH24_STENCIL8); + auto rend = NewRenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444, GL_DEPTH24_STENCIL8); glStencilMask(0xFF); rend->beginWithClear(0, 0, 0, 0, 0, 0); @@ -505,7 +506,7 @@ RenderTextureTargetNode::RenderTextureTargetNode() auto s = Director::getInstance()->getWinSize(); /* Create the render texture */ - auto renderTexture = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444); + auto renderTexture = NewRenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA4444); this->renderTexture = renderTexture; renderTexture->setPosition(Point(s.width/2, s.height/2)); @@ -590,7 +591,7 @@ void SpriteRenderTextureBug::SimpleSprite::draw() if (_rt == nullptr) { auto s = Director::getInstance()->getWinSize(); - _rt = RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888); + _rt = NewRenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888); _rt->retain(); } _rt->beginWithClear(0.0f, 0.0f, 0.0f, 1.0f); diff --git a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h index 47fde11c59..a5b30134fa 100644 --- a/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h +++ b/samples/Cpp/TestCpp/Classes/RenderTextureTest/RenderTextureTest.h @@ -4,6 +4,7 @@ #include "cocos2d.h" #include "../testBasic.h" #include "../BaseTest.h" +#include "renderer/CCNewRenderTexture.h" class RenderTextureTest : public BaseTest { @@ -30,7 +31,7 @@ public: void saveImage(Object *pSender); private: - RenderTexture *_target; + NewRenderTexture *_target; Sprite *_brush; }; From f423166471b8acdfc9941e20972d5ace1e265fb7 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 15:06:28 -0800 Subject: [PATCH 56/98] Fix bugs with RenderTexture with NewRender --- cocos/2d/renderer/CCNewRenderTexture.cpp | 1 + cocos/2d/renderer/NewClippingNode.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cocos/2d/renderer/CCNewRenderTexture.cpp b/cocos/2d/renderer/CCNewRenderTexture.cpp index b04b45d276..e69c39131b 100644 --- a/cocos/2d/renderer/CCNewRenderTexture.cpp +++ b/cocos/2d/renderer/CCNewRenderTexture.cpp @@ -130,6 +130,7 @@ void NewRenderTexture::begin() GroupCommand* groupCommand = new GroupCommand(); groupCommand->init(0, _vertexZ); + Renderer::getInstance()->addCommand(groupCommand); Renderer::getInstance()->pushGroup(groupCommand->getRenderQueueID()); CustomCommand* beginCmd = new CustomCommand(); diff --git a/cocos/2d/renderer/NewClippingNode.cpp b/cocos/2d/renderer/NewClippingNode.cpp index 8caccbcbd6..69a710fe79 100644 --- a/cocos/2d/renderer/NewClippingNode.cpp +++ b/cocos/2d/renderer/NewClippingNode.cpp @@ -94,21 +94,21 @@ void NewClippingNode::visit() CustomCommand* beforeVisitCmd = new CustomCommand(); beforeVisitCmd->init(0,_vertexZ); beforeVisitCmd->func = CC_CALLBACK_0(NewClippingNode::beforeVisit, this); - renderer->addCommand(beforeVisitCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(beforeVisitCmd); _stencil->visit(); CustomCommand* afterDrawStencilCmd = new CustomCommand(); afterDrawStencilCmd->init(0,_vertexZ); afterDrawStencilCmd->func = CC_CALLBACK_0(NewClippingNode::afterDrawStencil, this); - renderer->addCommand(afterDrawStencilCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(afterDrawStencilCmd); Node::visit(); CustomCommand* afterVisitCmd = new CustomCommand(); afterVisitCmd->init(0,_vertexZ); afterVisitCmd->func = CC_CALLBACK_0(NewClippingNode::afterVisit, this); - renderer->addCommand(afterVisitCmd, groupCommand->getRenderQueueID()); + renderer->addCommand(afterVisitCmd); renderer->popGroup(); } From 143df8af7d021c868ab9c79d62c1c69a8193e914 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 15:13:13 -0800 Subject: [PATCH 57/98] Fix RenderTexture after merging commandpool --- cocos/2d/renderer/CCNewRenderTexture.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cocos/2d/renderer/CCNewRenderTexture.cpp b/cocos/2d/renderer/CCNewRenderTexture.cpp index e69c39131b..9d2258f6e8 100644 --- a/cocos/2d/renderer/CCNewRenderTexture.cpp +++ b/cocos/2d/renderer/CCNewRenderTexture.cpp @@ -59,7 +59,7 @@ void NewRenderTexture::draw() begin(); //clear screen - CustomCommand* clearCmd = new CustomCommand(); + CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand(); clearCmd->init(0, _vertexZ); clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this); Renderer::getInstance()->addCommand(clearCmd); @@ -111,7 +111,7 @@ void NewRenderTexture::beginWithClear(float r, float g, float b, float a, float this->begin(); //clear screen - CustomCommand* clearCmd = new CustomCommand(); + CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand(); clearCmd->init(0, _vertexZ); clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this); Renderer::getInstance()->addCommand(clearCmd); @@ -127,13 +127,13 @@ void NewRenderTexture::begin() kmGLPushMatrix(); kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - GroupCommand* groupCommand = new GroupCommand(); + GroupCommand* groupCommand = GroupCommand::getCommandPool().generateCommand(); groupCommand->init(0, _vertexZ); Renderer::getInstance()->addCommand(groupCommand); Renderer::getInstance()->pushGroup(groupCommand->getRenderQueueID()); - CustomCommand* beginCmd = new CustomCommand(); + CustomCommand* beginCmd = CustomCommand::getCommandPool().generateCommand(); beginCmd->init(0, _vertexZ); beginCmd->func = CC_CALLBACK_0(NewRenderTexture::onBegin, this); @@ -142,7 +142,7 @@ void NewRenderTexture::begin() void NewRenderTexture::end() { - CustomCommand* endCmd = new CustomCommand(); + CustomCommand* endCmd = CustomCommand::getCommandPool().generateCommand(); endCmd->init(0, _vertexZ); endCmd->func = CC_CALLBACK_0(NewRenderTexture::onEnd, this); @@ -264,7 +264,7 @@ void NewRenderTexture::clearDepth(float depthValue) this->begin(); - CustomCommand* cmd = new CustomCommand(); + CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewRenderTexture::onClearDepth, this); From a98714f6a5b31561f1b17296703c5196602ae531 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 17:02:02 -0800 Subject: [PATCH 58/98] support device without VAO --- cocos/2d/renderer/Renderer.cpp | 112 ++++++++++++++++++++++++++++----- cocos/2d/renderer/Renderer.h | 7 +++ 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index cb752b9b70..5820046d3f 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -9,7 +9,7 @@ #include "CustomCommand.h" #include "QuadCommand.h" #include "GroupCommand.h" - +#include "CCConfiguration.h" NS_CC_BEGIN using namespace std; @@ -54,11 +54,11 @@ Renderer::~Renderer() glDeleteBuffers(2, _buffersVBO); -// if (Configuration::getInstance()->supportsShareableVAO()) -// { + if (Configuration::getInstance()->supportsShareableVAO()) + { glDeleteVertexArrays(1, &_quadVAO); GL::bindVAO(0); -// } + } } bool Renderer::init() @@ -68,13 +68,26 @@ bool Renderer::init() void Renderer::initGLView() { +#if CC_ENABLE_CACHE_TEXTURE_DATA + // listen the event when app go to background + NotificationCenter::getInstance()->addObserver(this, + callfuncO_selector(Renderer::onBackToForeground), + EVNET_COME_TO_FOREGROUND, + NULL); +#endif + setupIndices(); - setupVBOAndVAO(); + setupBuffer(); _glViewAssigned = true; } +void Renderer::onBackToForeground() +{ + setupBuffer(); +} + void Renderer::setupIndices() { for( int i=0; i < VBO_SIZE; i++) @@ -88,6 +101,18 @@ void Renderer::setupIndices() } } +void Renderer::setupBuffer() +{ + if(Configuration::getInstance()->supportsShareableVAO()) + { + setupVBOAndVAO(); + } + else + { + setupVBO(); + } +} + void Renderer::setupVBOAndVAO() { glGenVertexArrays(1, &_quadVAO); @@ -121,6 +146,29 @@ void Renderer::setupVBOAndVAO() CHECK_GL_ERROR_DEBUG(); } +void Renderer::setupVBO() +{ + glGenBuffers(2, &_buffersVBO[0]); + + mapBuffers(); +} + +void Renderer::mapBuffers() +{ + // Avoid changing the element buffer for whatever VAO might be bound. + GL::bindVAO(0); + + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * VBO_SIZE, _quads, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices[0]) * VBO_SIZE * 6, _indices, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + CHECK_GL_ERROR_DEBUG(); +} + void Renderer::addCommand(RenderCommand* command) { command->generateID(); @@ -273,18 +321,41 @@ void Renderer::drawBatchedQuads() return; } - //Set VBO data - glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + if (Configuration::getInstance()->supportsShareableVAO()) + { + //Set VBO data + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW); - void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); - glUnmapBuffer(GL_ARRAY_BUFFER); + glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * (_numQuads), NULL, GL_DYNAMIC_DRAW); + void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + memcpy(buf, _quads, sizeof(_quads[0])* (_numQuads)); + glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); - //Bind VAO - GL::bindVAO(_quadVAO); + //Bind VAO + GL::bindVAO(_quadVAO); + } + else + { +#define kQuadSize sizeof(_quads[0].bl) + glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); + + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_quads[0]) * _numQuads , _quads); + + GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); + + // vertices + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); + + // colors + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); + + // tex coords + glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); + } //Start drawing verties in batch for(size_t i = _firstCommand; i <= _lastCommand; i++) @@ -321,8 +392,17 @@ void Renderer::drawBatchedQuads() CC_INCREMENT_GL_DRAWS(1); } - //Unbind VAO - GL::bindVAO(0); + if (Configuration::getInstance()->supportsShareableVAO()) + { + //Unbind VAO + GL::bindVAO(0); + } + else + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + _firstCommand = _lastCommand; _numQuads = 0; diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index b160244371..067df355bf 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -53,11 +53,18 @@ protected: bool init(); void setupIndices(); + //Setup VBO or VAO based on OpenGL extensions + void setupBuffer(); void setupVBOAndVAO(); + void setupVBO(); + void mapBuffers(); + void drawBatchedQuads(); //Draw the previews queued quads and flush previous context void flush(); + void onBackToForeground(); + protected: stack _commandGroupStack; From e316ac779bf1450a7450fa1a0ee9a422f2e2be81 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 17:41:18 -0800 Subject: [PATCH 59/98] Sprite culling now using vertices directly to avoid calculation on transform --- cocos/2d/renderer/CCNewSprite.cpp | 54 ++++++------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 5ab1b3f345..047259f534 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -94,37 +94,12 @@ void NewSprite::updateQuadVertices() // // calculate the Quad based on the Affine Matrix // - - Size size = _rect.size; - - float x1 = _offsetPosition.x; - float y1 = _offsetPosition.y; - - float x2 = x1 + size.width; - float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; - - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; - float ax = x1 * cr - y1 * sr2 + x; - float ay = x1 * sr + y1 * cr2 + y; - - float bx = x2 * cr - y1 * sr2 + x; - float by = x2 * sr + y1 * cr2 + y; - - float cx = x2 * cr - y2 * sr2 + x; - float cy = x2 * sr + y2 * cr2 + y; - - float dx = x1 * cr - y2 * sr2 + x; - float dy = x1 * sr + y2 * cr2 + y; - - _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); - _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); - _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); - _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); + Rect newRect = RectApplyAffineTransform(_rect, _transformToBatch); + + _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); + _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); + _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ ); + _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ ); _recursiveDirty = false; setDirty(false); @@ -151,24 +126,15 @@ bool NewSprite::culling() const Frustum* frustum = Director::getInstance()->getFrustum(); AffineTransform worldTM = getNodeToWorldTransform(); //generate aabb - Point lowLeft(0,0); - Point topRight = lowLeft + Point(getContentSize()); - Point lowRight(topRight.x,0); - Point topLeft(0, topRight.y); - lowLeft = PointApplyAffineTransform(lowLeft,worldTM); - lowRight = PointApplyAffineTransform(lowRight,worldTM); - topRight = PointApplyAffineTransform(topRight,worldTM); - topLeft = PointApplyAffineTransform(topLeft,worldTM); - - kmVec3 point = {lowLeft.x, lowLeft.y, _vertexZ}; + kmVec3 point = {_quad.bl.vertices.x, _quad.bl.vertices.y, _vertexZ}; AABB aabb(point,point); - point = {lowRight.x, lowRight.y, _vertexZ}; + point = {_quad.br.vertices.x, _quad.br.vertices.y, _vertexZ}; aabb.expand(point); - point = {topLeft.x, topLeft.y, _vertexZ}; + point = {_quad.tl.vertices.x, _quad.tl.vertices.y, _vertexZ}; aabb.expand(point); - point = {topRight.x, topRight.y, _vertexZ}; + point = {_quad.tr.vertices.x, _quad.tr.vertices.y, _vertexZ}; aabb.expand(point); return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb); From 7a58cb5a29d11f1589e466915f243e161f7ffe40 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Thu, 5 Dec 2013 10:20:22 +0800 Subject: [PATCH 60/98] use quad command instead of custom command for ParticleSystemQuad::draw() --- cocos/2d/CCParticleSystemQuad.cpp | 44 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index ad5c1b834e..f723480d36 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -409,20 +409,44 @@ void ParticleSystemQuad::postStep() // CHECK_GL_ERROR_DEBUG(); //} - void ParticleSystemQuad::draw() { CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); - kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); + //quad command + if(_particleIdx > 0) + { + //transform vertices + std::vector drawQuads(_particleIdx); + memcpy(&drawQuads[0], _quads, sizeof(V3F_C4B_T2F_Quad) * _particleIdx); + AffineTransform worldTM = getNodeToWorldTransform(); + for(int index = 0; index <_particleIdx; ++index) + { + V3F_C4B_T2F_Quad* quad = _quads + index; + + Point pt(0,0); + pt = PointApplyAffineTransform( Point(quad->bl.vertices.x, quad->bl.vertices.y), worldTM); + drawQuads[index].bl.vertices.x = pt.x; + drawQuads[index].bl.vertices.y = pt.y; + + pt = PointApplyAffineTransform( Point(quad->br.vertices.x, quad->br.vertices.y), worldTM); + drawQuads[index].br.vertices.x = pt.x; + drawQuads[index].br.vertices.y = pt.y; + + pt = PointApplyAffineTransform( Point(quad->tl.vertices.x, quad->tl.vertices.y), worldTM); + drawQuads[index].tl.vertices.x = pt.x; + drawQuads[index].tl.vertices.y = pt.y; + + pt = PointApplyAffineTransform( Point(quad->tr.vertices.x, quad->tr.vertices.y), worldTM); + drawQuads[index].tr.vertices.x = pt.x; + drawQuads[index].tr.vertices.y = pt.y; + + } + + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); + cmd->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &drawQuads[0], _particleIdx); + Renderer::getInstance()->addCommand(cmd); + } - CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); - cmd->init(0, _vertexZ); - cmd->func = CC_CALLBACK_0(ParticleSystemQuad::onDraw, this); - Renderer::getInstance()->addCommand(cmd); - - //TODO render particle using quad command -// QuadCommand* cmd = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, _quads, _particleIdx); -// Renderer::getInstance()->addCommand(cmd); } void ParticleSystemQuad::onDraw() From e6823875d566459fb2d175b0a193e1b65b000074 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Thu, 5 Dec 2013 10:20:54 +0800 Subject: [PATCH 61/98] change VBO_SIZE to a big number to avoid crash temporarily --- cocos/2d/renderer/Renderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 067df355bf..3618187740 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -14,7 +14,7 @@ #include #include -#define VBO_SIZE 1024 +#define VBO_SIZE 8192 #define DEFAULT_RENDER_QUEUE 0 NS_CC_BEGIN From 9b0e0d21164eb2adc68dba448388134d654a119e Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Wed, 4 Dec 2013 19:05:17 -0800 Subject: [PATCH 62/98] Fix a bug with auto batching logic --- cocos/2d/renderer/Renderer.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index 5820046d3f..ab0a0bf323 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -236,11 +236,9 @@ void Renderer::render() if(command->getType() == QUAD_COMMAND) { QuadCommand* cmd = static_cast(command); - - CCASSERT(cmd->getQuadCount()getQuadCount() < VBO_SIZE) + if(_numQuads + cmd->getQuadCount() <= VBO_SIZE) { memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); _numQuads += cmd->getQuadCount(); @@ -248,8 +246,11 @@ void Renderer::render() } else { + CCASSERT(cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command"); + //Draw batched quads if VBO is full drawBatchedQuads(); + i--; } } else if(command->getType() == CUSTOM_COMMAND) From 42de943662ff7e4668ea5240f39d7072e306a758 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Thu, 5 Dec 2013 14:25:45 -0800 Subject: [PATCH 63/98] Fix Bug for Sprite performance test --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/renderer/Renderer.cpp | 12 ++++-------- cocos/2d/renderer/Renderer.h | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 0be606068f..c2ba69cc74 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b266b35a737f7500465360bf16cb73ce109762e2 \ No newline at end of file +aabba8b2acc64e67ede1a920dfe5ef9517b85865 \ No newline at end of file diff --git a/cocos/2d/renderer/Renderer.cpp b/cocos/2d/renderer/Renderer.cpp index ab0a0bf323..3ae2e798f1 100644 --- a/cocos/2d/renderer/Renderer.cpp +++ b/cocos/2d/renderer/Renderer.cpp @@ -238,20 +238,16 @@ void Renderer::render() QuadCommand* cmd = static_cast(command); //Batch quads - if(_numQuads + cmd->getQuadCount() <= VBO_SIZE) - { - memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); - _numQuads += cmd->getQuadCount(); - - } - else + if(_numQuads + cmd->getQuadCount() > VBO_SIZE) { CCASSERT(cmd->getQuadCount() < VBO_SIZE, "VBO is not big enough for quad data, please break the quad data down or use customized render command"); //Draw batched quads if VBO is full drawBatchedQuads(); - i--; } + + memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); + _numQuads += cmd->getQuadCount(); } else if(command->getType() == CUSTOM_COMMAND) { diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 3618187740..067df355bf 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -14,7 +14,7 @@ #include #include -#define VBO_SIZE 8192 +#define VBO_SIZE 1024 #define DEFAULT_RENDER_QUEUE 0 NS_CC_BEGIN From e699a3b765bce5c1a870dd654f7a0002770c59b9 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Thu, 5 Dec 2013 19:04:01 -0800 Subject: [PATCH 64/98] Uses MV in Quad Command --- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/CCAtlasNode.h | 2 +- cocos/2d/CCDirector.cpp | 8 +-- cocos/2d/CCGLProgram.cpp | 13 ++-- cocos/2d/CCGLProgram.h | 1 + cocos/2d/CCLabelAtlas.cpp | 5 +- cocos/2d/CCParticleSystemQuad.cpp | 59 ++++++++-------- cocos/2d/CCSprite.cpp | 8 ++- cocos/2d/renderer/CCNewLabelAtlas.cpp | 68 +++++++++++++++++++ cocos/2d/renderer/CCNewLabelAtlas.h | 52 ++++++++++++++ cocos/2d/renderer/CCNewSprite.cpp | 6 +- cocos/2d/renderer/CCNewSpriteBatchNode.cpp | 7 +- cocos/2d/renderer/QuadCommand.cpp | 53 ++++++++++++++- cocos/2d/renderer/QuadCommand.h | 8 ++- 14 files changed, 240 insertions(+), 52 deletions(-) create mode 100644 cocos/2d/renderer/CCNewLabelAtlas.cpp create mode 100644 cocos/2d/renderer/CCNewLabelAtlas.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 0be606068f..8f468680fe 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -b266b35a737f7500465360bf16cb73ce109762e2 \ No newline at end of file +9bfb5237a1dfb299a770a4f5a9b81d5b63e5a3a4 \ No newline at end of file diff --git a/cocos/2d/CCAtlasNode.h b/cocos/2d/CCAtlasNode.h index b196f45a1d..0516c004e0 100644 --- a/cocos/2d/CCAtlasNode.h +++ b/cocos/2d/CCAtlasNode.h @@ -98,7 +98,7 @@ protected: bool initWithTileFile(const std::string& tile, long tileWidth, long tileHeight, long itemsToRender); /** initializes an AtlasNode with a texture the width and height of each item measured in points and the quantity of items to render*/ - bool initWithTexture(Texture2D* texture, long tileWidth, long tileHeight, long itemsToRender); + virtual bool initWithTexture(Texture2D* texture, long tileWidth, long tileHeight, long itemsToRender); void calculateMaxItems(); void updateBlendFunc(); diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index e232a55039..5d3387b1b9 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -45,7 +45,7 @@ THE SOFTWARE. #include "platform/CCFileUtils.h" #include "CCApplication.h" #include "CCLabelBMFont.h" -#include "CCLabelAtlas.h" +#include "CCNewLabelAtlas.h" #include "CCActionManager.h" #include "CCAnimationCache.h" #include "CCTouch.h" @@ -926,17 +926,17 @@ void Director::createStatsLabel() */ float factor = EGLView::getInstance()->getDesignResolutionSize().height / 320.0f; - _FPSLabel = new LabelAtlas(); + _FPSLabel = new NewLabelAtlas; _FPSLabel->setIgnoreContentScaleFactor(true); _FPSLabel->initWithString("00.0", texture, 12, 32 , '.'); _FPSLabel->setScale(factor); - _SPFLabel = new LabelAtlas(); + _SPFLabel = new NewLabelAtlas; _SPFLabel->setIgnoreContentScaleFactor(true); _SPFLabel->initWithString("0.000", texture, 12, 32, '.'); _SPFLabel->setScale(factor); - _drawsLabel = new LabelAtlas(); + _drawsLabel = new NewLabelAtlas; _drawsLabel->setIgnoreContentScaleFactor(true); _drawsLabel->initWithString("000", texture, 12, 32, '.'); _drawsLabel->setScale(factor); diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index 81afbdc09f..5c6ab07e30 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -234,8 +234,9 @@ void GLProgram::updateUniforms() _uniforms[UNIFORM_SAMPLER] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER); + _flags.usesP = _uniforms[UNIFORM_P_MATRIX] != -1; + _flags.usesMV = _uniforms[UNIFORM_MV_MATRIX] != -1; _flags.usesMVP = _uniforms[UNIFORM_MVP_MATRIX] != -1; - _flags.usesMV = (_uniforms[UNIFORM_MV_MATRIX] != -1 && _uniforms[UNIFORM_P_MATRIX] != -1 ); _flags.usesTime = ( _uniforms[UNIFORM_TIME] != -1 || _uniforms[UNIFORM_SIN_TIME] != -1 || @@ -553,16 +554,18 @@ void GLProgram::setUniformsForBuiltins() kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV); + if(_flags.usesP) + setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixP.mat, 1); + + if(_flags.usesMV) + setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1); + if(_flags.usesMVP) { kmMat4 matrixMVP; kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1); } - if(_flags.usesMV) { - setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1); - setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MV_MATRIX], matrixMV.mat, 1); - } if(_flags.usesTime) { Director *director = Director::getInstance(); diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index 2d66baf3bb..d96edd474a 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -255,6 +255,7 @@ private: unsigned int usesTime:1; unsigned int usesMVP:1; unsigned int usesMV:1; + unsigned int usesP:1; unsigned int usesRandom:1; // handy way to initialize the bitfield diff --git a/cocos/2d/CCLabelAtlas.cpp b/cocos/2d/CCLabelAtlas.cpp index 4c64ca3418..b6aa433ef6 100644 --- a/cocos/2d/CCLabelAtlas.cpp +++ b/cocos/2d/CCLabelAtlas.cpp @@ -62,7 +62,7 @@ bool LabelAtlas::initWithString(const std::string& string, const std::string& ch bool LabelAtlas::initWithString(const std::string& string, Texture2D* texture, long itemWidth, long itemHeight, long startCharMap) { - if (AtlasNode::initWithTexture(texture, itemWidth, itemHeight, string.size())) + if (initWithTexture(texture, itemWidth, itemHeight, string.size())) { _mapStartChar = startCharMap; this->setString(string); @@ -169,7 +169,8 @@ void LabelAtlas::updateAtlasValues() quads[i].tr.vertices.x = (float)(i * _itemWidth + _itemWidth); quads[i].tr.vertices.y = (float)(_itemHeight); quads[i].tr.vertices.z = 0.0f; - Color4B c(_displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity); +// Color4B c(_displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity); + Color4B c(255,255,255,255); quads[i].tl.colors = c; quads[i].tr.colors = c; quads[i].bl.colors = c; diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index f723480d36..5f49ca60d3 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -415,35 +415,38 @@ void ParticleSystemQuad::draw() //quad command if(_particleIdx > 0) { - //transform vertices - std::vector drawQuads(_particleIdx); - memcpy(&drawQuads[0], _quads, sizeof(V3F_C4B_T2F_Quad) * _particleIdx); - AffineTransform worldTM = getNodeToWorldTransform(); - for(int index = 0; index <_particleIdx; ++index) - { - V3F_C4B_T2F_Quad* quad = _quads + index; - - Point pt(0,0); - pt = PointApplyAffineTransform( Point(quad->bl.vertices.x, quad->bl.vertices.y), worldTM); - drawQuads[index].bl.vertices.x = pt.x; - drawQuads[index].bl.vertices.y = pt.y; - - pt = PointApplyAffineTransform( Point(quad->br.vertices.x, quad->br.vertices.y), worldTM); - drawQuads[index].br.vertices.x = pt.x; - drawQuads[index].br.vertices.y = pt.y; - - pt = PointApplyAffineTransform( Point(quad->tl.vertices.x, quad->tl.vertices.y), worldTM); - drawQuads[index].tl.vertices.x = pt.x; - drawQuads[index].tl.vertices.y = pt.y; - - pt = PointApplyAffineTransform( Point(quad->tr.vertices.x, quad->tr.vertices.y), worldTM); - drawQuads[index].tr.vertices.x = pt.x; - drawQuads[index].tr.vertices.y = pt.y; - - } - +// //transform vertices +// std::vector drawQuads(_particleIdx); +// memcpy(&drawQuads[0], _quads, sizeof(V3F_C4B_T2F_Quad) * _particleIdx); +// AffineTransform worldTM = getNodeToWorldTransform(); +// for(int index = 0; index <_particleIdx; ++index) +// { +// V3F_C4B_T2F_Quad* quad = _quads + index; +// +// Point pt(0,0); +// pt = PointApplyAffineTransform( Point(quad->bl.vertices.x, quad->bl.vertices.y), worldTM); +// drawQuads[index].bl.vertices.x = pt.x; +// drawQuads[index].bl.vertices.y = pt.y; +// +// pt = PointApplyAffineTransform( Point(quad->br.vertices.x, quad->br.vertices.y), worldTM); +// drawQuads[index].br.vertices.x = pt.x; +// drawQuads[index].br.vertices.y = pt.y; +// +// pt = PointApplyAffineTransform( Point(quad->tl.vertices.x, quad->tl.vertices.y), worldTM); +// drawQuads[index].tl.vertices.x = pt.x; +// drawQuads[index].tl.vertices.y = pt.y; +// +// pt = PointApplyAffineTransform( Point(quad->tr.vertices.x, quad->tr.vertices.y), worldTM); +// drawQuads[index].tr.vertices.x = pt.x; +// drawQuads[index].tr.vertices.y = pt.y; +// +// } + + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); - cmd->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &drawQuads[0], _particleIdx); + cmd->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, _quads, _particleIdx, mv); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 3045297798..680bafe578 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -663,10 +663,14 @@ void Sprite::updateTransform(void) void Sprite::draw(void) { - updateQuadVertices(); +// updateQuadVertices(); + + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + //TODO implement z order QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); - renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, mv); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/renderer/CCNewLabelAtlas.cpp b/cocos/2d/renderer/CCNewLabelAtlas.cpp new file mode 100644 index 0000000000..aba1711220 --- /dev/null +++ b/cocos/2d/renderer/CCNewLabelAtlas.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + + +#include "CCNewLabelAtlas.h" +#include "RenderCommand.h" +#include "Renderer.h" +#include "QuadCommand.h" +#include "CCMenuItem.h" +#include "Frustum.h" +#include "CCDirector.h" +#include "CCTextureAtlas.h" +#include "CCShaderCache.h" + +NS_CC_BEGIN + +bool NewLabelAtlas::initWithTexture(Texture2D* texture, long tileWidth, long tileHeight, long itemsToRender) +{ + LabelAtlas::initWithTexture(texture, tileWidth, tileHeight, itemsToRender); + + // shader stuff + setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); + + return true; +} + + +void NewLabelAtlas::draw() +{ +// LabelAtlas::draw(); +// _renderCommand.init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, +// _textureAtlas->getQuads(), _textureAtlas->getTotalQuads() ); +// +// Renderer::getInstance()->addCommand(&_renderCommand); + + + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); + cmd->init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads(), mv); + + Renderer::getInstance()->addCommand(cmd); + +} + +NS_CC_END \ No newline at end of file diff --git a/cocos/2d/renderer/CCNewLabelAtlas.h b/cocos/2d/renderer/CCNewLabelAtlas.h new file mode 100644 index 0000000000..c5eaafc751 --- /dev/null +++ b/cocos/2d/renderer/CCNewLabelAtlas.h @@ -0,0 +1,52 @@ +/**************************************************************************** + Copyright (c) 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + + +#ifndef __CCNEWLABELATLAS_H_ +#define __CCNEWLABELATLAS_H_ + +#include "CCLabelAtlas.h" +#include "CCPlatformMacros.h" +#include "QuadCommand.h" + +NS_CC_BEGIN + +class NewLabelAtlas : public LabelAtlas +{ + +public: + NewLabelAtlas() {} + virtual ~NewLabelAtlas() {} + + virtual bool initWithTexture(Texture2D* texture, long tileWidth, long tileHeight, long itemsToRender); + + virtual void draw(void) override; + +protected: + QuadCommand _renderCommand; +}; + +NS_CC_END + +#endif /* defined(__CCNEWLABELATLAS_H_) */ diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 047259f534..197d0f2676 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -108,15 +108,17 @@ void NewSprite::updateQuadVertices() void NewSprite::draw(void) { - updateQuadVertices(); +// updateQuadVertices(); if(!culling()) { return; } + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); //TODO implement z order QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); - renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); + renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, mv); Renderer::getInstance()->addCommand(renderCommand); } diff --git a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp index 6c28176e32..389de382b3 100644 --- a/cocos/2d/renderer/CCNewSpriteBatchNode.cpp +++ b/cocos/2d/renderer/CCNewSpriteBatchNode.cpp @@ -60,11 +60,14 @@ void NewSpriteBatchNode::draw() for(const auto &child: _children) child->updateTransform(); - + // arrayMakeObjectsPerformSelector(_children, updateTransform, NewSprite*); + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); - cmd->init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads()); + cmd->init(0, _vertexZ, _textureAtlas->getTexture()->getName(), _shaderProgram, _blendFunc, _textureAtlas->getQuads(), _textureAtlas->getTotalQuads(), mv); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 1c5b190a1d..543396611b 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -16,13 +16,14 @@ QuadCommand::QuadCommand() ,_textureID(0) ,_blendType(BlendFunc::DISABLE) ,_quadCount(0) +,_capacity(0) { _type = QUAD_COMMAND; _shader = nullptr; _quad = nullptr; } -void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount) +void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount, const kmMat4 &mv) { _viewport = viewport; _depth = depth; @@ -30,9 +31,55 @@ void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* _blendType = blendType; _quadCount = quadCount; _shader = shader; - free(_quad); - _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); + + if(quadCount > _capacity ) { +// _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); + _quad = (V3F_C4B_T2F_Quad*) realloc(_quad, sizeof(*quad) * quadCount ); + _capacity = quadCount; + } + + _quadCount = quadCount; memcpy(_quad, quad, sizeof(V3F_C4B_T2F_Quad) * quadCount); + + for(int i=0; ibl.vertices.x; + vec1.y = q->bl.vertices.y; + vec1.z = q->bl.vertices.z; + kmVec3Transform(&out1, &vec1, &mv); + q->bl.vertices.x = out1.x; + q->bl.vertices.y = out1.y; + q->bl.vertices.z = out1.z; + + kmVec3 vec2, out2; + vec2.x = q->br.vertices.x; + vec2.y = q->br.vertices.y; + vec2.z = q->br.vertices.z; + kmVec3Transform(&out2, &vec2, &mv); + q->br.vertices.x = out2.x; + q->br.vertices.y = out2.y; + q->br.vertices.z = out2.z; + + kmVec3 vec3, out3; + vec3.x = q->tr.vertices.x; + vec3.y = q->tr.vertices.y; + vec3.z = q->tr.vertices.z; + kmVec3Transform(&out3, &vec3, &mv); + q->tr.vertices.x = out3.x; + q->tr.vertices.y = out3.y; + q->tr.vertices.z = out3.z; + + kmVec3 vec4, out4; + vec4.x = q->tl.vertices.x; + vec4.y = q->tl.vertices.y; + vec4.z = q->tl.vertices.z; + kmVec3Transform(&out4, &vec4, &mv); + q->tl.vertices.x = out4.x; + q->tl.vertices.y = out4.y; + q->tl.vertices.z = out4.z; + } } QuadCommand::~QuadCommand() diff --git a/cocos/2d/renderer/QuadCommand.h b/cocos/2d/renderer/QuadCommand.h index 78e7323820..f128fc057b 100644 --- a/cocos/2d/renderer/QuadCommand.h +++ b/cocos/2d/renderer/QuadCommand.h @@ -10,6 +10,7 @@ #include "RenderCommand.h" #include "CCGLProgram.h" #include "RenderCommandPool.h" +#include "kazmath.h" NS_CC_BEGIN @@ -17,12 +18,13 @@ NS_CC_BEGIN class QuadCommand : public RenderCommand { -protected: +public: QuadCommand(); ~QuadCommand(); public: - void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount); + void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, int quadCount, + const kmMat4& mv); // +----------+----------+-----+-----------------------------------+ // | | | | | | @@ -69,6 +71,8 @@ protected: V3F_C4B_T2F_Quad* _quad; int _quadCount; + int _capacity; + public: friend class RenderCommandPool; static RenderCommandPool& getCommandPool() { return _commandPool; } From dcf4eacd922504d919c321f503112d35fbf496b9 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Thu, 5 Dec 2013 22:24:51 -0800 Subject: [PATCH 65/98] update project --- build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 8f468680fe..48d3186a8e 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -9bfb5237a1dfb299a770a4f5a9b81d5b63e5a3a4 \ No newline at end of file +612d704070ee3832c50603bba7e6bdb461115fcf \ No newline at end of file From 3e0bee706e385733e607e3107e988f48f3729517 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 6 Dec 2013 11:41:24 -0800 Subject: [PATCH 66/98] Fix a hack in CCLabelAtlas for vertice color, add TODO for quad command --- cocos/2d/CCLabelAtlas.cpp | 3 +-- cocos/2d/renderer/QuadCommand.cpp | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/2d/CCLabelAtlas.cpp b/cocos/2d/CCLabelAtlas.cpp index 2a35b689aa..8ec15a3c1c 100644 --- a/cocos/2d/CCLabelAtlas.cpp +++ b/cocos/2d/CCLabelAtlas.cpp @@ -169,8 +169,7 @@ void LabelAtlas::updateAtlasValues() quads[i].tr.vertices.x = (float)(i * _itemWidth + _itemWidth); quads[i].tr.vertices.y = (float)(_itemHeight); quads[i].tr.vertices.z = 0.0f; -// Color4B c(_displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity); - Color4B c(255,255,255,255); + Color4B c(_displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity); quads[i].tl.colors = c; quads[i].tr.colors = c; quads[i].bl.colors = c; diff --git a/cocos/2d/renderer/QuadCommand.cpp b/cocos/2d/renderer/QuadCommand.cpp index 1f68a7774e..9b8952a617 100644 --- a/cocos/2d/renderer/QuadCommand.cpp +++ b/cocos/2d/renderer/QuadCommand.cpp @@ -33,6 +33,7 @@ void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* _shader = shader; if(quadCount > _capacity ) { + //TODO find a better way to manage quads, current way will result in memory be wasted // _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); _quad = (V3F_C4B_T2F_Quad*) realloc(_quad, sizeof(*quad) * quadCount ); _capacity = quadCount; From 745541979b49b6db6cb4641c032f7b0f2127a7a8 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Fri, 6 Dec 2013 11:51:17 -0800 Subject: [PATCH 67/98] Particles working again. Paticle Batch working too: increased VBO_SIE to 10500 --- cocos/2d/CCParticleBatchNode.cpp | 23 ++++++++++++++++++++--- cocos/2d/CCParticleSystemQuad.cpp | 4 +++- cocos/2d/renderer/Renderer.h | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cocos/2d/CCParticleBatchNode.cpp b/cocos/2d/CCParticleBatchNode.cpp index 74df4b4ad0..01e976f4cc 100644 --- a/cocos/2d/CCParticleBatchNode.cpp +++ b/cocos/2d/CCParticleBatchNode.cpp @@ -42,6 +42,8 @@ #include "platform/CCFileUtils.h" #include "kazmath/GL/matrix.h" #include "CCProfiling.h" +#include "QuadCommand.h" +#include "Renderer.h" NS_CC_BEGIN @@ -401,12 +403,27 @@ void ParticleBatchNode::draw(void) return; } - CC_NODE_DRAW_SETUP(); +// CC_NODE_DRAW_SETUP(); +// +// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); +// +// _textureAtlas->drawQuads(); - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); + auto shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP); - _textureAtlas->drawQuads(); + kmMat4 mv; + kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); + cmd->init(0, + _vertexZ, + _textureAtlas->getTexture()->getName(), + shader, + _blendFunc, + _textureAtlas->getQuads(), + _textureAtlas->getTotalQuads(), + mv); + Renderer::getInstance()->addCommand(cmd); CC_PROFILER_STOP("CCParticleBatchNode - draw"); } diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index 5f49ca60d3..197827a7bb 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -445,8 +445,10 @@ void ParticleSystemQuad::draw() kmMat4 mv; kmGLGetMatrix(KM_GL_MODELVIEW, &mv); + auto shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP); + QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); - cmd->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, _quads, _particleIdx, mv); + cmd->init(0, _vertexZ, _texture->getName(), shader, _blendFunc, _quads, _particleIdx, mv); Renderer::getInstance()->addCommand(cmd); } diff --git a/cocos/2d/renderer/Renderer.h b/cocos/2d/renderer/Renderer.h index 067df355bf..c87654fd16 100644 --- a/cocos/2d/renderer/Renderer.h +++ b/cocos/2d/renderer/Renderer.h @@ -14,7 +14,7 @@ #include #include -#define VBO_SIZE 1024 +#define VBO_SIZE 10500 #define DEFAULT_RENDER_QUEUE 0 NS_CC_BEGIN From 94255a9d5281331bc1b25f975720b67fb1b3c08c Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Fri, 6 Dec 2013 14:59:06 -0800 Subject: [PATCH 68/98] Fix culling --- cocos/2d/renderer/CCNewSprite.cpp | 32 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 197d0f2676..22301e9f7d 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -7,12 +7,10 @@ // #include "CCNewSprite.h" -#include "RenderCommand.h" #include "Renderer.h" -#include "QuadCommand.h" -#include "CCMenuItem.h" #include "Frustum.h" #include "CCDirector.h" +#include "QuadCommand.h" NS_CC_BEGIN @@ -108,35 +106,41 @@ void NewSprite::updateQuadVertices() void NewSprite::draw(void) { -// updateQuadVertices(); - if(!culling()) - { - return; - } - kmMat4 mv; kmGLGetMatrix(KM_GL_MODELVIEW, &mv); //TODO implement z order QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, mv); + if(!culling()) + { + renderCommand->releaseToCommandPool(); + return; + } + Renderer::getInstance()->addCommand(renderCommand); } bool NewSprite::culling() const { Frustum* frustum = Director::getInstance()->getFrustum(); + //TODO optimize this transformation, should use parent's transformation instead AffineTransform worldTM = getNodeToWorldTransform(); //generate aabb - - kmVec3 point = {_quad.bl.vertices.x, _quad.bl.vertices.y, _vertexZ}; + + // + // calculate the Quad based on the Affine Matrix + // + Rect newRect = RectApplyAffineTransform(_rect, worldTM); + + kmVec3 point = {newRect.getMinX(), newRect.getMinY(), _vertexZ}; AABB aabb(point,point); - point = {_quad.br.vertices.x, _quad.br.vertices.y, _vertexZ}; + point = {newRect.getMaxX(), newRect.getMinY(), _vertexZ}; aabb.expand(point); - point = {_quad.tl.vertices.x, _quad.tl.vertices.y, _vertexZ}; + point = {newRect.getMinX(), newRect.getMaxY(), _vertexZ}; aabb.expand(point); - point = {_quad.tr.vertices.x, _quad.tr.vertices.y, _vertexZ}; + point = {newRect.getMaxX(), newRect.getMaxY(), _vertexZ}; aabb.expand(point); return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb); From ee0ef6bf469c34d61b551cad4fa0409ea29e317a Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Fri, 6 Dec 2013 17:42:16 -0800 Subject: [PATCH 69/98] ProgressTimer works OK Adds _modelViewTransform as ivar of Node (temporary fix) --- cocos/2d/CCGLProgram.cpp | 26 ++++++----- cocos/2d/CCGLProgram.h | 16 ++++--- cocos/2d/CCNode.cpp | 4 +- cocos/2d/CCNode.h | 2 + cocos/2d/CCParticleSystemQuad.cpp | 69 +---------------------------- cocos/2d/CCParticleSystemQuad.h | 2 - cocos/2d/CCProgressTimer.cpp | 19 ++++++-- cocos/2d/CCProgressTimer.h | 2 + cocos/2d/ccMacros.h | 2 +- cocos/2d/renderer/CCNewDrawNode.cpp | 9 ---- 10 files changed, 49 insertions(+), 102 deletions(-) diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index 469ef80d73..528c01c05c 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -324,7 +324,7 @@ const char* GLProgram::getProgramLog() const // Uniform cache -bool GLProgram::updateUniformLocation(GLint location, GLvoid* data, unsigned int bytes) +bool GLProgram::updateUniformLocation(GLint location, const GLvoid* data, unsigned int bytes) { if (location < 0) { @@ -487,7 +487,7 @@ void GLProgram::setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, } } -void GLProgram::setUniformLocationWith2fv(GLint location, GLfloat* floats, unsigned int numberOfArrays) +void GLProgram::setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays) { bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays); @@ -497,7 +497,7 @@ void GLProgram::setUniformLocationWith2fv(GLint location, GLfloat* floats, unsig } } -void GLProgram::setUniformLocationWith3fv(GLint location, GLfloat* floats, unsigned int numberOfArrays) +void GLProgram::setUniformLocationWith3fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays) { bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays); @@ -507,7 +507,7 @@ void GLProgram::setUniformLocationWith3fv(GLint location, GLfloat* floats, unsig } } -void GLProgram::setUniformLocationWith4fv(GLint location, GLfloat* floats, unsigned int numberOfArrays) +void GLProgram::setUniformLocationWith4fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays) { bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays); @@ -517,7 +517,7 @@ void GLProgram::setUniformLocationWith4fv(GLint location, GLfloat* floats, unsig } } -void GLProgram::setUniformLocationWithMatrix2fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices) { +void GLProgram::setUniformLocationWithMatrix2fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices) { bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*4*numberOfMatrices); if( updated ) @@ -526,7 +526,7 @@ void GLProgram::setUniformLocationWithMatrix2fv(GLint location, GLfloat* matrixA } } -void GLProgram::setUniformLocationWithMatrix3fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices) { +void GLProgram::setUniformLocationWithMatrix3fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices) { bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*9*numberOfMatrices); if( updated ) @@ -536,7 +536,7 @@ void GLProgram::setUniformLocationWithMatrix3fv(GLint location, GLfloat* matrixA } -void GLProgram::setUniformLocationWithMatrix4fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices) +void GLProgram::setUniformLocationWithMatrix4fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices) { bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices); @@ -548,12 +548,17 @@ void GLProgram::setUniformLocationWithMatrix4fv(GLint location, GLfloat* matrixA void GLProgram::setUniformsForBuiltins() { - kmMat4 matrixP; kmMat4 matrixMV; + kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV); + + setUniformsForBuiltins(matrixMV); +} + +void GLProgram::setUniformsForBuiltins(const kmMat4 &matrixMV) +{ + kmMat4 matrixP; kmGLGetMatrix(KM_GL_PROJECTION, &matrixP); - kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV); - if(_flags.usesP) setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_P_MATRIX], matrixP.mat, 1); @@ -567,7 +572,6 @@ void GLProgram::setUniformsForBuiltins() setUniformLocationWithMatrix4fv(_uniforms[UNIFORM_MVP_MATRIX], matrixMVP.mat, 1); } - if(_flags.usesTime) { Director *director = Director::getInstance(); // This doesn't give the most accurate global time value. diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index 9dfcbbce2a..2bfe8c22bd 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -32,6 +32,7 @@ THE SOFTWARE. #include "CCObject.h" #include "CCGL.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -191,25 +192,26 @@ public: void setUniformLocationWith4f(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4); /** calls glUniform2fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith2fv(GLint location, GLfloat* floats, unsigned int numberOfArrays); + void setUniformLocationWith2fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays); /** calls glUniform3fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith3fv(GLint location, GLfloat* floats, unsigned int numberOfArrays); + void setUniformLocationWith3fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays); /** calls glUniform4fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith4fv(GLint location, GLfloat* floats, unsigned int numberOfArrays); + void setUniformLocationWith4fv(GLint location, const GLfloat* floats, unsigned int numberOfArrays); /** calls glUniformMatrix2fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWithMatrix2fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices); + void setUniformLocationWithMatrix2fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices); /** calls glUniformMatrix3fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWithMatrix3fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices); + void setUniformLocationWithMatrix3fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices); /** calls glUniformMatrix4fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWithMatrix4fv(GLint location, GLfloat* matrixArray, unsigned int numberOfMatrices); + void setUniformLocationWithMatrix4fv(GLint location, const GLfloat* matrixArray, unsigned int numberOfMatrices); /** will update the builtin uniforms if they are different than the previous call for this same shader program. */ void setUniformsForBuiltins(); + void setUniformsForBuiltins(const kmMat4 &modelView); /** returns the vertexShader error log */ const char* getVertexShaderLog() const; @@ -240,7 +242,7 @@ public: inline const GLuint getProgram() const { return _program; } private: - bool updateUniformLocation(GLint location, GLvoid* data, unsigned int bytes); + bool updateUniformLocation(GLint location, const GLvoid* data, unsigned int bytes); const char* description() const; bool compileShader(GLuint * shader, GLenum type, const GLchar* source); const char* logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const; diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 3a31d7efdf..65b0532b31 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -916,6 +916,9 @@ void Node::transform() kmGLMultMatrix( &transfrom4x4 ); + // saves the MV matrix + kmGLGetMatrix(KM_GL_MODELVIEW, &_modelViewTransform); + // XXX: Expensive calls. Camera should be integrated into the cached affine matrix if ( _camera != NULL && !(_grid != NULL && _grid->isActive()) ) @@ -930,7 +933,6 @@ void Node::transform() if( translate ) kmGLTranslatef(RENDER_IN_SUBPIXEL(-_anchorPointInPoints.x), RENDER_IN_SUBPIXEL(-_anchorPointInPoints.y), 0 ); } - } diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index c9de3a916c..bb49b013a4 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -39,6 +39,7 @@ #include "CCProtocols.h" #include "CCEventDispatcher.h" #include "CCVector.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -1433,6 +1434,7 @@ protected: mutable bool _additionalTransformDirty; ///< The flag to check whether the additional transform is dirty mutable bool _transformDirty; ///< transform dirty flag mutable bool _inverseDirty; ///< inverse transform dirty flag + kmMat4 _modelViewTransform; ///< ModelView transform of the Node. Camera *_camera; ///< a camera diff --git a/cocos/2d/CCParticleSystemQuad.cpp b/cocos/2d/CCParticleSystemQuad.cpp index 197827a7bb..8c0aa222ea 100644 --- a/cocos/2d/CCParticleSystemQuad.cpp +++ b/cocos/2d/CCParticleSystemQuad.cpp @@ -442,82 +442,15 @@ void ParticleSystemQuad::draw() // // } - kmMat4 mv; - kmGLGetMatrix(KM_GL_MODELVIEW, &mv); - auto shader = ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP); QuadCommand* cmd = QuadCommand::getCommandPool().generateCommand(); - cmd->init(0, _vertexZ, _texture->getName(), shader, _blendFunc, _quads, _particleIdx, mv); + cmd->init(0, _vertexZ, _texture->getName(), shader, _blendFunc, _quads, _particleIdx, _modelViewTransform); Renderer::getInstance()->addCommand(cmd); } } -void ParticleSystemQuad::onDraw() -{ - CCASSERT(!_batchNode,"draw should not be called when added to a particleBatchNode"); - - kmMat4 prevMatrix; - kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); - kmGLLoadMatrix(&_transformMatrix); - - CC_NODE_DRAW_SETUP(); - - GL::bindTexture2D( _texture->getName() ); - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); - - CCASSERT( _particleIdx == _particleCount, "Abnormal error in particle quad"); - - if (Configuration::getInstance()->supportsShareableVAO()) - { - // - // Using VBO and VAO - // - GL::bindVAO(_VAOname); - -#if CC_REBIND_INDICES_BUFFER - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); -#endif - - glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0); - -#if CC_REBIND_INDICES_BUFFER - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -#endif - } - else - { - // - // Using VBO without VAO - // - -#define kQuadSize sizeof(_quads[0].bl) - - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); - - glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); - // vertices - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, vertices)); - // colors - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, colors)); - // tex coords - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( V3F_C4B_T2F, texCoords)); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); - - glDrawElements(GL_TRIANGLES, (GLsizei) _particleIdx*6, GL_UNSIGNED_SHORT, 0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - CC_INCREMENT_GL_DRAWS(1); - CHECK_GL_ERROR_DEBUG(); - - kmGLLoadMatrix(&prevMatrix); -} - void ParticleSystemQuad::setTotalParticles(int tp) { // If we are setting the total number of particles to a number higher diff --git a/cocos/2d/CCParticleSystemQuad.h b/cocos/2d/CCParticleSystemQuad.h index 9b0849bea4..89b551a501 100644 --- a/cocos/2d/CCParticleSystemQuad.h +++ b/cocos/2d/CCParticleSystemQuad.h @@ -109,8 +109,6 @@ public: */ virtual void draw() override; - void onDraw(); - /** * @js NA * @lua NA diff --git a/cocos/2d/CCProgressTimer.cpp b/cocos/2d/CCProgressTimer.cpp index d370866d1b..a1c2c4ac5c 100644 --- a/cocos/2d/CCProgressTimer.cpp +++ b/cocos/2d/CCProgressTimer.cpp @@ -32,6 +32,9 @@ THE SOFTWARE. #include "CCDirector.h" #include "TransformUtils.h" #include "CCDrawingPrimitives.h" +#include "Renderer.h" +#include "CustomCommand.h" + // extern #include "kazmath/GL/matrix.h" @@ -497,10 +500,8 @@ Point ProgressTimer::boundaryTexCoord(char index) return Point::ZERO; } -void ProgressTimer::draw(void) +void ProgressTimer::onDraw() { - if( ! _vertexData || ! _sprite) - return; CC_NODE_DRAW_SETUP(); @@ -548,4 +549,16 @@ void ProgressTimer::draw(void) CC_INCREMENT_GL_DRAWS(1); } +void ProgressTimer::draw() +{ + if( ! _vertexData || ! _sprite) + return; + + CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); + cmd->init(0, _vertexZ); + cmd->func = CC_CALLBACK_0(ProgressTimer::onDraw, this); + Renderer::getInstance()->addCommand(cmd); +} + + NS_CC_END diff --git a/cocos/2d/CCProgressTimer.h b/cocos/2d/CCProgressTimer.h index 04c4e55246..44eb15e9e1 100644 --- a/cocos/2d/CCProgressTimer.h +++ b/cocos/2d/CCProgressTimer.h @@ -130,6 +130,8 @@ protected: /** Initializes a progress timer with the sprite as the shape the timer goes through */ bool initWithSprite(Sprite* sp); + void onDraw(); + Tex2F textureCoordFromAlphaPoint(Point alpha); Vertex2F vertexFromAlphaPoint(Point alpha); void updateProgress(void); diff --git a/cocos/2d/ccMacros.h b/cocos/2d/ccMacros.h index dbea2d512a..6332ae6078 100644 --- a/cocos/2d/ccMacros.h +++ b/cocos/2d/ccMacros.h @@ -100,7 +100,7 @@ do { \ CCASSERT(getShaderProgram(), "No shader program set for this node"); \ { \ getShaderProgram()->use(); \ - getShaderProgram()->setUniformsForBuiltins(); \ + getShaderProgram()->setUniformsForBuiltins(_modelViewTransform); \ } \ } while(0) diff --git a/cocos/2d/renderer/CCNewDrawNode.cpp b/cocos/2d/renderer/CCNewDrawNode.cpp index 6b97034fc6..c0379eb000 100644 --- a/cocos/2d/renderer/CCNewDrawNode.cpp +++ b/cocos/2d/renderer/CCNewDrawNode.cpp @@ -42,8 +42,6 @@ bool NewDrawNode::init() void NewDrawNode::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); - CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); @@ -52,17 +50,10 @@ void NewDrawNode::draw() void NewDrawNode::onDraw() { - kmMat4 prevMatrix; - kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); - - kmGLLoadMatrix(&_transformMatrix); - CC_NODE_DRAW_SETUP(); GL::blendFunc(_blendFunc.src, _blendFunc.dst); render(); - - kmGLLoadMatrix(&prevMatrix); } NS_CC_END \ No newline at end of file From 8df96b1a6e051a47bd70b727369b6ef207e51144 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Fri, 6 Dec 2013 17:59:34 -0800 Subject: [PATCH 70/98] Layercolor uses the new API --- cocos/2d/CCLayer.cpp | 9 --------- cocos/2d/CCLayer.h | 1 - cocos/2d/renderer/CCNewDrawNode.h | 4 +--- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index bcb5eaa03b..8dc43ab651 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -690,7 +690,6 @@ void LayerColor::updateColor() void LayerColor::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand(); cmd->init(0, _vertexZ); cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); @@ -699,12 +698,6 @@ void LayerColor::draw() void LayerColor::onDraw() { - //TODO we can just reuse the base MV matrix instead of save and reset everytime - //TODO need to find out where do we set the base MV matrix - kmMat4 prevMatrix; - kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); - kmGLLoadMatrix(&_transformMatrix); - CC_NODE_DRAW_SETUP(); GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR ); @@ -728,8 +721,6 @@ void LayerColor::onDraw() glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CC_INCREMENT_GL_DRAWS(1); - - kmGLLoadMatrix(&prevMatrix); } void LayerColor::setColor(const Color3B &color) diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index 106de3887e..360b46758a 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -299,7 +299,6 @@ protected: Vertex2F _squareVertices[4]; Color4F _squareColors[4]; - kmMat4 _transformMatrix; private: CC_DISALLOW_COPY_AND_ASSIGN(LayerColor); diff --git a/cocos/2d/renderer/CCNewDrawNode.h b/cocos/2d/renderer/CCNewDrawNode.h index 6b470d083a..8183efadf3 100644 --- a/cocos/2d/renderer/CCNewDrawNode.h +++ b/cocos/2d/renderer/CCNewDrawNode.h @@ -17,8 +17,6 @@ class NewDrawNode : public DrawNode public: static NewDrawNode* create(); - virtual ~NewDrawNode(); - virtual bool init(); void draw(); @@ -27,8 +25,8 @@ public: protected: NewDrawNode(); + virtual ~NewDrawNode(); - kmMat4 _transformMatrix; }; NS_CC_END From 0222c6544ee8ec6aaab87a5abc0410a0d02f265d Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Mon, 9 Dec 2013 17:32:51 -0800 Subject: [PATCH 71/98] Migration to Mat4x4 Armature not migrated yet Signed-off-by: Ricardo Quesada --- cocos/2d/CCNode.cpp | 130 ++++++++++++++----- cocos/2d/CCNode.h | 30 +++-- cocos/2d/CCSprite.cpp | 30 +++-- cocos/2d/CCSprite.h | 3 +- cocos/2d/renderer/CCNewSprite.cpp | 6 +- cocos/base/CCAffineTransform.cpp | 34 +++++ cocos/base/CCAffineTransform.h | 4 + extensions/GUI/CCEditBox/CCEditBox.cpp | 2 +- extensions/physics-nodes/CCPhysicsSprite.cpp | 10 +- extensions/physics-nodes/CCPhysicsSprite.h | 2 +- 10 files changed, 180 insertions(+), 71 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 65b0532b31..835a44d56e 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -103,9 +103,6 @@ Node::Node(void) , _anchorPointInPoints(Point::ZERO) , _anchorPoint(Point::ZERO) , _contentSize(Size::ZERO) -, _additionalTransform(AffineTransform::IDENTITY) -, _transform(AffineTransform::IDENTITY) -, _inverse(AffineTransform::IDENTITY) , _additionalTransformDirty(false) , _transformDirty(true) , _inverseDirty(true) @@ -144,6 +141,10 @@ Node::Node(void) ScriptEngineProtocol* pEngine = ScriptEngineManager::getInstance()->getScriptEngine(); _scriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone; + + kmMat4Identity(&_transform); + kmMat4Identity(&_inverse); + kmMat4Identity(&_additionalTransform); } Node::~Node() @@ -543,7 +544,7 @@ void Node::setShaderProgram(GLProgram *pShaderProgram) Rect Node::getBoundingBox() const { Rect rect = Rect(0, 0, _contentSize.width, _contentSize.height); - return RectApplyAffineTransform(rect, getNodeToParentTransform()); + return RectApplyAffineTransform(rect, getNodeToParentAffineTransform()); } Node * Node::create(void) @@ -906,14 +907,12 @@ void Node::transform() updatePhysicsTransform(); #endif - kmMat4 transfrom4x4; - - // Convert 3x3 into 4x4 matrix - CGAffineToGL(this->getNodeToParentTransform(), transfrom4x4.mat); + kmMat4 transfrom4x4 = this->getNodeToParentTransform(); // Update Z vertex manually transfrom4x4.mat[14] = _vertexZ; + kmGLMultMatrix( &transfrom4x4 ); // saves the MV matrix @@ -1184,16 +1183,25 @@ void Node::update(float fDelta) } } -const AffineTransform& Node::getNodeToParentTransform() const +AffineTransform Node::getNodeToParentAffineTransform() const { - if (_transformDirty) + AffineTransform ret; + kmMat4 ret4 = getNodeToParentTransform(); + GLToCGAffine(ret4.mat, &ret); + + return ret; +} + +const kmMat4& Node::getNodeToParentTransform() const +{ + if (_transformDirty) { // Translate values float x = _position.x; float y = _position.y; - if (_ignoreAnchorPointForPosition) + if (_ignoreAnchorPointForPosition) { x += _anchorPointInPoints.x; y += _anchorPointInPoints.y; @@ -1228,80 +1236,132 @@ const AffineTransform& Node::getNodeToParentTransform() const // Build Transform Matrix // Adjusted transform calculation for rotational skew - _transform = AffineTransformMake( cy * _scaleX, sy * _scaleX, - -sx * _scaleY, cx * _scaleY, - x, y ); + _transform = { cy * _scaleX, sy * _scaleX, 0, 0, + -sx * _scaleY, cx * _scaleY, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1 }; // XXX: Try to inline skew // If skew is needed, apply skew and then anchor point - if (needsSkewMatrix) + if (needsSkewMatrix) { - AffineTransform skewMatrix = AffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(_skewY)), - tanf(CC_DEGREES_TO_RADIANS(_skewX)), 1.0f, - 0.0f, 0.0f ); - _transform = AffineTransformConcat(skewMatrix, _transform); + kmMat4 skewMtrix = { 1, tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0, + tanf(CC_DEGREES_TO_RADIANS(_skewX)),1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + + kmMat4Multiply(&_transform, &skewMtrix, &_transform); // adjust anchor point if (!_anchorPointInPoints.equals(Point::ZERO)) { - _transform = AffineTransformTranslate(_transform, -_anchorPointInPoints.x, -_anchorPointInPoints.y); + // XXX: Argh, kmMat needs a "translate" method + _transform.mat[12] += -_anchorPointInPoints.x; + _transform.mat[13] += -_anchorPointInPoints.y; } } - + if (_additionalTransformDirty) { - _transform = AffineTransformConcat(_transform, _additionalTransform); + kmMat4Multiply(&_transform, &_transform, &_additionalTransform); _additionalTransformDirty = false; } - + _transformDirty = false; } - + return _transform; } void Node::setAdditionalTransform(const AffineTransform& additionalTransform) +{ + CGAffineToGL(additionalTransform, _additionalTransform.mat); + _transformDirty = true; + _additionalTransformDirty = true; +} + +void Node::setAdditionalTransform(const kmMat4& additionalTransform) { _additionalTransform = additionalTransform; _transformDirty = true; _additionalTransformDirty = true; } -const AffineTransform& Node::getParentToNodeTransform() const + +AffineTransform Node::getParentToNodeAffineTransform() const +{ + AffineTransform ret; + kmMat4 ret4 = getParentToNodeTransform(); + + GLToCGAffine(ret4.mat,&ret); + return ret; +} + +const kmMat4& Node::getParentToNodeTransform() const { if ( _inverseDirty ) { - _inverse = AffineTransformInvert(this->getNodeToParentTransform()); + kmMat4Inverse(&_inverse, &_transform); _inverseDirty = false; } return _inverse; } -AffineTransform Node::getNodeToWorldTransform() const + +AffineTransform Node::getNodeToWorldAffineTransform() const { - AffineTransform t = this->getNodeToParentTransform(); + AffineTransform t = this->getNodeToParentAffineTransform(); for (Node *p = _parent; p != NULL; p = p->getParent()) - t = AffineTransformConcat(t, p->getNodeToParentTransform()); + t = AffineTransformConcat(t, p->getNodeToParentAffineTransform()); return t; } -AffineTransform Node::getWorldToNodeTransform() const +kmMat4 Node::getNodeToWorldTransform() const { - return AffineTransformInvert(this->getNodeToWorldTransform()); + kmMat4 t = this->getNodeToParentTransform(); + + for (Node *p = _parent; p != NULL; p = p->getParent()) + kmMat4Multiply(&t, &t, &p->getNodeToParentTransform()); + + return t; } +AffineTransform Node::getWorldToNodeAffineTransform() const +{ + return AffineTransformInvert(this->getNodeToWorldAffineTransform()); +} + +kmMat4 Node::getWorldToNodeTransform() const +{ + kmMat4 tmp, tmp2; + + tmp2 = this->getNodeToWorldTransform(); + kmMat4Inverse(&tmp, &tmp2); + return tmp; +} + + Point Node::convertToNodeSpace(const Point& worldPoint) const { - Point ret = PointApplyAffineTransform(worldPoint, getWorldToNodeTransform()); - return ret; + kmMat4 tmp = getWorldToNodeTransform(); + kmVec3 vec3 = {worldPoint.x, worldPoint.y, 0}; + kmVec3 ret; + kmVec3Transform(&ret, &vec3, &tmp); + Point p = {ret.x, ret.y }; + return p; } Point Node::convertToWorldSpace(const Point& nodePoint) const { - Point ret = PointApplyAffineTransform(nodePoint, getNodeToWorldTransform()); - return ret; + kmMat4 tmp = getNodeToWorldTransform(); + kmVec3 vec3 = {nodePoint.x, nodePoint.y, 0}; + kmVec3 ret; + kmVec3Transform(&ret, &vec3, &tmp); + Point p = {ret.x, ret.y }; + return p; + } Point Node::convertToNodeSpaceAR(const Point& worldPoint) const diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index bb49b013a4..17b287a3c1 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -1228,35 +1228,40 @@ public: * Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates. * The matrix is in Pixels. */ - virtual const AffineTransform& getNodeToParentTransform() const; + virtual const kmMat4& getNodeToParentTransform() const; + virtual AffineTransform getNodeToParentAffineTransform() const; /** @deprecated use getNodeToParentTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToParentTransform() const { return getNodeToParentTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToParentTransform() const { return getNodeToParentAffineTransform(); } /** * Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates. * The matrix is in Pixels. */ - virtual const AffineTransform& getParentToNodeTransform() const; + virtual const kmMat4& getParentToNodeTransform() const; + virtual AffineTransform getParentToNodeAffineTransform() const; /** @deprecated Use getParentToNodeTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform parentToNodeTransform() const { return getParentToNodeTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform parentToNodeTransform() const { return getParentToNodeAffineTransform(); } /** * Returns the world affine transform matrix. The matrix is in Pixels. */ - virtual AffineTransform getNodeToWorldTransform() const; + virtual kmMat4 getNodeToWorldTransform() const; + virtual AffineTransform getNodeToWorldAffineTransform() const; /** @deprecated Use getNodeToWorldTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToWorldTransform() const { return getNodeToWorldTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToWorldTransform() const { return getNodeToWorldAffineTransform(); } /** * Returns the inverse world affine transform matrix. The matrix is in Pixels. */ - virtual AffineTransform getWorldToNodeTransform() const; + virtual kmMat4 getWorldToNodeTransform() const; + virtual AffineTransform getWorldToNodeAffineTransform() const; + /** @deprecated Use worldToNodeTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeAffineTransform(); } /// @} end of Transformations @@ -1345,6 +1350,7 @@ public: @endcode */ void setAdditionalTransform(const AffineTransform& additionalTransform); + void setAdditionalTransform(const kmMat4& additionalTransform); /// @} end of Coordinate Converters @@ -1428,13 +1434,13 @@ protected: Size _contentSize; ///< untransformed size of the node // "cache" variables are allowed to be mutable - mutable AffineTransform _additionalTransform; ///< transform - mutable AffineTransform _transform; ///< transform - mutable AffineTransform _inverse; ///< inverse transform + mutable kmMat4 _additionalTransform; ///< transform + mutable kmMat4 _transform; ///< transform + mutable kmMat4 _inverse; ///< inverse transform + kmMat4 _modelViewTransform; ///< ModelView transform of the Node. mutable bool _additionalTransformDirty; ///< The flag to check whether the additional transform is dirty mutable bool _transformDirty; ///< transform dirty flag mutable bool _inverseDirty; ///< inverse transform dirty flag - kmMat4 _modelViewTransform; ///< ModelView transform of the Node. Camera *_camera; ///< a camera diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index ceaeb8df18..10a2be7fd5 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -524,7 +524,9 @@ void Sprite::updateTransform(void) else { CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); - _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); + kmMat4 nodeToParent = getNodeToParentTransform(); + kmMat4 parentTransform = static_cast(_parent)->_transformToBatch; + kmMat4Multiply(&_transformToBatch, &nodeToParent, &parentTransform); } // @@ -538,13 +540,13 @@ void Sprite::updateTransform(void) float x2 = x1 + size.width; float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; + float x = _transformToBatch.mat[12]; + float y = _transformToBatch.mat[13]; - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; + float cr = _transformToBatch.mat[0]; + float sr = _transformToBatch.mat[1]; + float cr2 = _transformToBatch.mat[5]; + float sr2 = -_transformToBatch.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; @@ -719,13 +721,13 @@ void Sprite::updateQuadVertices() float x2 = x1 + size.width; float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; + float x = _transformToBatch.mat[12]; + float y = _transformToBatch.mat[13]; - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; + float cr = _transformToBatch.mat[0]; + float sr = _transformToBatch.mat[1]; + float cr2 = _transformToBatch.mat[5]; + float sr2 = -_transformToBatch.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; @@ -1208,7 +1210,7 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode) } else { // using batch - _transformToBatch = AffineTransformIdentity; + kmMat4Identity(&_transformToBatch); setTextureAtlas(_batchNode->getTextureAtlas()); // weak ref } } diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index 8b009dd21a..1b53acc3db 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -37,6 +37,7 @@ THE SOFTWARE. #include "CCGLBufferedNode.h" #endif // EMSCRIPTEN #include "CCPhysicsBody.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -544,7 +545,7 @@ protected: bool _recursiveDirty; /// Whether all of the sprite's children needs to be updated bool _hasChildren; /// Whether the sprite contains children bool _shouldBeHidden; /// should not be drawn because one of the ancestors is not visible - AffineTransform _transformToBatch; + kmMat4 _transformToBatch; // // Data used when the sprite is self-rendered diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 22301e9f7d..685f854052 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -92,7 +92,7 @@ void NewSprite::updateQuadVertices() // // calculate the Quad based on the Affine Matrix // - Rect newRect = RectApplyAffineTransform(_rect, _transformToBatch); + Rect newRect = RectApplyTransform(_rect, _transformToBatch); _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); @@ -125,13 +125,13 @@ bool NewSprite::culling() const { Frustum* frustum = Director::getInstance()->getFrustum(); //TODO optimize this transformation, should use parent's transformation instead - AffineTransform worldTM = getNodeToWorldTransform(); + kmMat4 worldTM = getNodeToWorldTransform(); //generate aabb // // calculate the Quad based on the Affine Matrix // - Rect newRect = RectApplyAffineTransform(_rect, worldTM); + Rect newRect = RectApplyTransform(_rect, worldTM); kmVec3 point = {newRect.getMinX(), newRect.getMinY(), _vertexZ}; diff --git a/cocos/base/CCAffineTransform.cpp b/cocos/base/CCAffineTransform.cpp index 2e39f344cc..7fbbd62eed 100644 --- a/cocos/base/CCAffineTransform.cpp +++ b/cocos/base/CCAffineTransform.cpp @@ -45,6 +45,14 @@ Point __CCPointApplyAffineTransform(const Point& point, const AffineTransform& t return p; } +Point PointApplyTransform(const Point& point, const kmMat4& transform) +{ + kmVec3 vec = {point.x, point.y, 0}; + kmVec3Transform(&vec, &vec, &transform); + return Point(vec.x, vec.y); +} + + Size __CCSizeApplyAffineTransform(const Size& size, const AffineTransform& t) { Size s; @@ -82,6 +90,32 @@ Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineT return Rect(minX, minY, (maxX - minX), (maxY - minY)); } +Rect RectApplyTransform(const Rect& rect, const kmMat4& transform) +{ + float top = rect.getMinY(); + float left = rect.getMinX(); + float right = rect.getMaxX(); + float bottom = rect.getMaxY(); + + kmVec3 topLeft = {left, top}; + kmVec3 topRight = {right, top}; + kmVec3 bottomLeft = {left, bottom}; + kmVec3 bottomRight = {right, bottom}; + + kmVec3Transform(&topLeft, &topLeft, &transform); + kmVec3Transform(&topRight, &topRight, &transform); + kmVec3Transform(&bottomLeft, &bottomLeft, &transform); + kmVec3Transform(&bottomRight, &bottomRight, &transform); + + float minX = min(min(topLeft.x, topRight.x), min(bottomLeft.x, bottomRight.x)); + float maxX = max(max(topLeft.x, topRight.x), max(bottomLeft.x, bottomRight.x)); + float minY = min(min(topLeft.y, topRight.y), min(bottomLeft.y, bottomRight.y)); + float maxY = max(max(topLeft.y, topRight.y), max(bottomLeft.y, bottomRight.y)); + + return Rect(minX, minY, (maxX - minX), (maxY - minY)); +} + + AffineTransform AffineTransformTranslate(const AffineTransform& t, float tx, float ty) { return __CCAffineTransformMake(t.a, t.b, t.c, t.d, t.tx + t.a * tx + t.c * ty, t.ty + t.b * tx + t.d * ty); diff --git a/cocos/base/CCAffineTransform.h b/cocos/base/CCAffineTransform.h index 66c76fc5f0..f1dbb6aece 100644 --- a/cocos/base/CCAffineTransform.h +++ b/cocos/base/CCAffineTransform.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include "CCGeometry.h" #include "CCPlatformMacros.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -49,6 +50,9 @@ CC_DLL Size __CCSizeApplyAffineTransform(const Size& size, const AffineTransform CC_DLL AffineTransform AffineTransformMakeIdentity(); CC_DLL Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineTransform); +CC_DLL Rect RectApplyTransform(const Rect& rect, const kmMat4& transform); +CC_DLL Point PointApplyTransform(const Point& point, const kmMat4& transform); + CC_DLL AffineTransform AffineTransformTranslate(const AffineTransform& t, float tx, float ty); CC_DLL AffineTransform AffineTransformRotate(const AffineTransform& aTransform, float anAngle); CC_DLL AffineTransform AffineTransformScale(const AffineTransform& t, float sx, float sy); diff --git a/extensions/GUI/CCEditBox/CCEditBox.cpp b/extensions/GUI/CCEditBox/CCEditBox.cpp index df598cd2af..db1d47a884 100644 --- a/extensions/GUI/CCEditBox/CCEditBox.cpp +++ b/extensions/GUI/CCEditBox/CCEditBox.cpp @@ -343,7 +343,7 @@ static Rect getRect(Node * pNode) { Size contentSize = pNode->getContentSize(); Rect rect = Rect(0, 0, contentSize.width, contentSize.height); - return RectApplyAffineTransform(rect, pNode->getNodeToWorldTransform()); + return RectApplyTransform(rect, pNode->getNodeToWorldTransform()); } void EditBox::keyboardWillShow(IMEKeyboardNotificationInfo& info) diff --git a/extensions/physics-nodes/CCPhysicsSprite.cpp b/extensions/physics-nodes/CCPhysicsSprite.cpp index 44054544bf..ff86d74120 100644 --- a/extensions/physics-nodes/CCPhysicsSprite.cpp +++ b/extensions/physics-nodes/CCPhysicsSprite.cpp @@ -342,7 +342,7 @@ void PhysicsSprite::setRotation(float fRotation) } // returns the transform matrix according the Chipmunk Body values -const AffineTransform& PhysicsSprite::getNodeToParentTransform() const +const kmMat4& PhysicsSprite::getNodeToParentTransform() const { // Although scale is not used by physics engines, it is calculated just in case // the sprite is animated (scaled up/down) using actions. @@ -360,9 +360,11 @@ const AffineTransform& PhysicsSprite::getNodeToParentTransform() const y += _anchorPointInPoints.y; } - return (_transform = AffineTransformMake(rot.x * _scaleX, rot.y * _scaleX, - -rot.y * _scaleY, rot.x * _scaleY, - x, y)); + _transform = { (kmScalar)rot.x * _scaleX, (kmScalar)rot.y * _scaleX, 0, 0, + (kmScalar)-rot.y * _scaleY, (kmScalar)rot.x * _scaleY, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1}; + return _transform; #elif CC_ENABLE_BOX2D_INTEGRATION diff --git a/extensions/physics-nodes/CCPhysicsSprite.h b/extensions/physics-nodes/CCPhysicsSprite.h index 1252af5919..50eb8a4158 100644 --- a/extensions/physics-nodes/CCPhysicsSprite.h +++ b/extensions/physics-nodes/CCPhysicsSprite.h @@ -111,7 +111,7 @@ public: virtual void setPosition(const Point &position) override; virtual float getRotation() const override; virtual void setRotation(float fRotation) override; - virtual const AffineTransform& getNodeToParentTransform() const override; + virtual const kmMat4& getNodeToParentTransform() const override; protected: const Point& getPosFromPhysics() const; From 23222923bf351b92a2630ac949858a7650be29a5 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Tue, 10 Dec 2013 11:07:15 -0800 Subject: [PATCH 72/98] Migrated code to Matrix4 --- cocos/2d/CCNode.cpp | 4 +- cocos/base/CCAffineTransform.cpp | 8 +++ cocos/base/CCAffineTransform.h | 2 + .../editor-support/cocostudio/CCArmature.cpp | 26 +++++---- cocos/editor-support/cocostudio/CCArmature.h | 2 +- cocos/editor-support/cocostudio/CCBone.cpp | 15 +++--- cocos/editor-support/cocostudio/CCBone.h | 6 +-- .../cocostudio/CCColliderDetector.cpp | 4 +- .../cocostudio/CCColliderDetector.h | 2 +- .../cocostudio/CCDisplayFactory.cpp | 10 ++-- cocos/editor-support/cocostudio/CCSkin.cpp | 34 ++++++------ cocos/editor-support/cocostudio/CCSkin.h | 6 +-- .../cocostudio/CCTransformHelp.cpp | 54 +++++++++++++++++++ .../cocostudio/CCTransformHelp.h | 2 + 14 files changed, 123 insertions(+), 52 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 835a44d56e..a5ea91f4fd 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -1245,12 +1245,12 @@ const kmMat4& Node::getNodeToParentTransform() const // If skew is needed, apply skew and then anchor point if (needsSkewMatrix) { - kmMat4 skewMtrix = { 1, tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0, + kmMat4 skewMatrix = { 1, tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0, tanf(CC_DEGREES_TO_RADIANS(_skewX)),1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - kmMat4Multiply(&_transform, &skewMtrix, &_transform); + kmMat4Multiply(&_transform, &skewMatrix, &_transform); // adjust anchor point if (!_anchorPointInPoints.equals(Point::ZERO)) diff --git a/cocos/base/CCAffineTransform.cpp b/cocos/base/CCAffineTransform.cpp index 7fbbd62eed..ff81b275d1 100644 --- a/cocos/base/CCAffineTransform.cpp +++ b/cocos/base/CCAffineTransform.cpp @@ -149,6 +149,14 @@ AffineTransform AffineTransformConcat(const AffineTransform& t1, const AffineTra t1.tx * t2.b + t1.ty * t2.d + t2.ty); //ty } +kmMat4 TransformConcat(const kmMat4& t1, const kmMat4& t2) +{ + kmMat4 ret; + kmMat4Multiply(&ret, &t1, &t2); + return ret; +} + + /* Return true if `t1' and `t2' are equal, false otherwise. */ bool AffineTransformEqualToTransform(const AffineTransform& t1, const AffineTransform& t2) { diff --git a/cocos/base/CCAffineTransform.h b/cocos/base/CCAffineTransform.h index f1dbb6aece..c3034bbf50 100644 --- a/cocos/base/CCAffineTransform.h +++ b/cocos/base/CCAffineTransform.h @@ -60,6 +60,8 @@ CC_DLL AffineTransform AffineTransformConcat(const AffineTransform& t1, const Af CC_DLL bool AffineTransformEqualToTransform(const AffineTransform& t1, const AffineTransform& t2); CC_DLL AffineTransform AffineTransformInvert(const AffineTransform& t); +kmMat4 TransformConcat(const kmMat4& t1, const kmMat4& t2); + extern CC_DLL const AffineTransform AffineTransformIdentity; NS_CC_END diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index 2585f00bfb..de8860a2ea 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -340,7 +340,7 @@ Dictionary *Armature::getBoneDic() const return _boneDic; } -const AffineTransform& Armature::getNodeToParentTransform() const +const kmMat4& Armature::getNodeToParentTransform() const { if (_transformDirty) { @@ -388,29 +388,33 @@ const AffineTransform& Armature::getNodeToParentTransform() const // Build Transform Matrix // Adjusted transform calculation for rotational skew - _transform = AffineTransformMake( cy * _scaleX, sy * _scaleX, - -sx * _scaleY, cx * _scaleY, - x, y ); + _transform = { cy * _scaleX, sy * _scaleX, 0, 0, + -sx * _scaleY, cx * _scaleY, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1 }; // XXX: Try to inline skew // If skew is needed, apply skew and then anchor point if (needsSkewMatrix) { - AffineTransform skewMatrix = AffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(_skewY)), - tanf(CC_DEGREES_TO_RADIANS(_skewX)), 1.0f, - 0.0f, 0.0f ); - _transform = AffineTransformConcat(skewMatrix, _transform); + kmMat4 skewMatrix = { 1, tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0, + tanf(CC_DEGREES_TO_RADIANS(_skewX)),1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + _transform = TransformConcat(skewMatrix, _transform); // adjust anchor point if (!_anchorPointInPoints.equals(Point::ZERO)) { - _transform = AffineTransformTranslate(_transform, -_anchorPointInPoints.x, -_anchorPointInPoints.y); + // XXX: Argh, kmMat needs a "translate" method + _transform.mat[12] += -_anchorPointInPoints.x; + _transform.mat[13] += -_anchorPointInPoints.y; } } if (_additionalTransformDirty) { - _transform = AffineTransformConcat(_transform, _additionalTransform); + _transform = TransformConcat(_transform, _additionalTransform); _additionalTransformDirty = false; } @@ -667,7 +671,7 @@ Rect Armature::getBoundingBox() const } } - return RectApplyAffineTransform(boundingBox, getNodeToParentTransform()); + return RectApplyTransform(boundingBox, getNodeToParentTransform()); } Bone *Armature::getBoneAtPoint(float x, float y) const diff --git a/cocos/editor-support/cocostudio/CCArmature.h b/cocos/editor-support/cocostudio/CCArmature.h index f9769434d7..0abd7b528c 100644 --- a/cocos/editor-support/cocostudio/CCArmature.h +++ b/cocos/editor-support/cocostudio/CCArmature.h @@ -161,7 +161,7 @@ public: virtual void update(float dt) override; virtual void draw() override; - virtual const cocos2d::AffineTransform& getNodeToParentTransform() const override; + virtual const kmMat4& getNodeToParentTransform() const override; /** * @js NA * @lua NA diff --git a/cocos/editor-support/cocostudio/CCBone.cpp b/cocos/editor-support/cocostudio/CCBone.cpp index 18b14e40b2..ec928689b3 100644 --- a/cocos/editor-support/cocostudio/CCBone.cpp +++ b/cocos/editor-support/cocostudio/CCBone.cpp @@ -71,7 +71,8 @@ Bone::Bone() _tween = nullptr; _displayManager = nullptr; _ignoreMovementBoneData = false; - _worldTransform = AffineTransformMake(1, 0, 0, 1, 0, 0); +// _worldTransform = AffineTransformMake(1, 0, 0, 1, 0, 0); + kmMat4Identity(&_worldTransform); _boneTransformDirty = true; _blendType = BLEND_NORMAL; _worldInfo = nullptr; @@ -221,7 +222,7 @@ void Bone::update(float delta) if (_armatureParentBone) { - _worldTransform = AffineTransformConcat(_worldTransform, _armature->getNodeToParentTransform()); + _worldTransform = TransformConcat(_worldTransform, _armature->getNodeToParentTransform()); } } @@ -239,8 +240,8 @@ void Bone::applyParentTransform(Bone *parent) { float x = _worldInfo->x; float y = _worldInfo->y; - _worldInfo->x = x * parent->_worldTransform.a + y * parent->_worldTransform.c + parent->_worldInfo->x; - _worldInfo->y = x * parent->_worldTransform.b + y * parent->_worldTransform.d + parent->_worldInfo->y; + _worldInfo->x = x * parent->_worldTransform.mat[0] + y * parent->_worldTransform.mat[4] + parent->_worldInfo->x; + _worldInfo->y = x * parent->_worldTransform.mat[1] + y * parent->_worldTransform.mat[5] + parent->_worldInfo->y; _worldInfo->scaleX = _worldInfo->scaleX * parent->_worldInfo->scaleX; _worldInfo->scaleY = _worldInfo->scaleY * parent->_worldInfo->scaleY; _worldInfo->skewX = _worldInfo->skewX + parent->_worldInfo->skewX; @@ -387,14 +388,14 @@ void Bone::setZOrder(int zOrder) Node::setZOrder(zOrder); } -AffineTransform Bone::getNodeToArmatureTransform() const +kmMat4 Bone::getNodeToArmatureTransform() const { return _worldTransform; } -AffineTransform Bone::getNodeToWorldTransform() const +kmMat4 Bone::getNodeToWorldTransform() const { - return AffineTransformConcat(_worldTransform, _armature->getNodeToWorldTransform()); + return TransformConcat(_worldTransform, _armature->getNodeToWorldTransform()); } Node *Bone::getDisplayRenderNode() diff --git a/cocos/editor-support/cocostudio/CCBone.h b/cocos/editor-support/cocostudio/CCBone.h index 815d60ceb8..0c7017deb4 100644 --- a/cocos/editor-support/cocostudio/CCBone.h +++ b/cocos/editor-support/cocostudio/CCBone.h @@ -152,8 +152,8 @@ public: virtual void setTransformDirty(bool dirty) { _boneTransformDirty = dirty; } virtual bool isTransformDirty() { return _boneTransformDirty; } - virtual cocos2d::AffineTransform getNodeToArmatureTransform() const; - virtual cocos2d::AffineTransform getNodeToWorldTransform() const override; + virtual kmMat4 getNodeToArmatureTransform() const; + virtual kmMat4 getNodeToWorldTransform() const override; Node *getDisplayRenderNode(); DisplayType getDisplayRenderNodeType(); @@ -233,7 +233,7 @@ protected: bool _boneTransformDirty; //! Whether or not transform dirty //! self Transform, use this to change display's state - cocos2d::AffineTransform _worldTransform; + kmMat4 _worldTransform; BaseData *_worldInfo; diff --git a/cocos/editor-support/cocostudio/CCColliderDetector.cpp b/cocos/editor-support/cocostudio/CCColliderDetector.cpp index 1a158c3734..74cf64ecbf 100644 --- a/cocos/editor-support/cocostudio/CCColliderDetector.cpp +++ b/cocos/editor-support/cocostudio/CCColliderDetector.cpp @@ -321,7 +321,7 @@ ColliderFilter *ColliderDetector::getColliderFilter() Point helpPoint; -void ColliderDetector::updateTransform(AffineTransform &t) +void ColliderDetector::updateTransform(kmMat4 &t) { if (!_active) { @@ -357,7 +357,7 @@ void ColliderDetector::updateTransform(AffineTransform &t) for (int i = 0; i < num; i++) { helpPoint.setPoint( vs[i]->x, vs[i]->y); - helpPoint = PointApplyAffineTransform(helpPoint, t); + helpPoint = PointApplyTransform(helpPoint, t); #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX diff --git a/cocos/editor-support/cocostudio/CCColliderDetector.h b/cocos/editor-support/cocostudio/CCColliderDetector.h index 29221af2a0..10a5e9ae04 100644 --- a/cocos/editor-support/cocostudio/CCColliderDetector.h +++ b/cocos/editor-support/cocostudio/CCColliderDetector.h @@ -155,7 +155,7 @@ public: void removeContourData(ContourData *contourData); void removeAll(); - void updateTransform(cocos2d::AffineTransform &t); + void updateTransform(kmMat4 &t); void setActive(bool active); bool getActive(); diff --git a/cocos/editor-support/cocostudio/CCDisplayFactory.cpp b/cocos/editor-support/cocostudio/CCDisplayFactory.cpp index 46c7750d48..8ebd027a13 100644 --- a/cocos/editor-support/cocostudio/CCDisplayFactory.cpp +++ b/cocos/editor-support/cocostudio/CCDisplayFactory.cpp @@ -86,12 +86,12 @@ void DisplayFactory::updateDisplay(Bone *bone, float dt, bool dirty) { CC_BREAK_IF(!detector->getBody()); - AffineTransform displayTransform = display->getNodeToParentTransform(); + kmMat4 displayTransform = display->getNodeToParentTransform(); Point anchorPoint = display->getAnchorPointInPoints(); - anchorPoint = PointApplyAffineTransform(anchorPoint, displayTransform); - displayTransform.tx = anchorPoint.x; - displayTransform.ty = anchorPoint.y; - AffineTransform t = AffineTransformConcat(displayTransform, bone->getArmature()->getNodeToParentTransform()); + anchorPoint = PointApplyTransform(anchorPoint, displayTransform); + displayTransform.mat[12] = anchorPoint.x; + displayTransform.mat[13] = anchorPoint.y; + kmMat4 t = TransformConcat(displayTransform, bone->getArmature()->getNodeToParentTransform()); detector->updateTransform(t); } while (0); diff --git a/cocos/editor-support/cocostudio/CCSkin.cpp b/cocos/editor-support/cocostudio/CCSkin.cpp index 394dfb48ec..5886b59850 100644 --- a/cocos/editor-support/cocostudio/CCSkin.cpp +++ b/cocos/editor-support/cocostudio/CCSkin.cpp @@ -80,7 +80,7 @@ Skin::Skin() , _armature(nullptr) , _displayName("") { - _skinTransform = AffineTransformIdentity; + kmMat4Identity(&_skinTransform); } bool Skin::initWithSpriteFrameName(const std::string& spriteFrameName) @@ -135,10 +135,10 @@ const BaseData &Skin::getSkinData() const void Skin::updateArmatureTransform() { - _transform = AffineTransformConcat(_skinTransform, _bone->getNodeToArmatureTransform()); + _transform = TransformConcat(_skinTransform, _bone->getNodeToArmatureTransform()); if(_armature && _armature->getBatchNode()) { - _transform = AffineTransformConcat(_transform, _armature->getNodeToParentTransform()); + _transform = TransformConcat(_transform, _armature->getNodeToParentTransform()); } } @@ -163,13 +163,13 @@ void Skin::updateTransform() float x2 = x1 + size.width; float y2 = y1 + size.height; - float x = _transform.tx; - float y = _transform.ty; + float x = _transform.mat[12]; + float y = _transform.mat[13]; - float cr = _transform.a; - float sr = _transform.b; - float cr2 = _transform.d; - float sr2 = -_transform.c; + float cr = _transform.mat[0]; + float sr = _transform.mat[1]; + float cr2 = _transform.mat[5]; + float sr2 = -_transform.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; @@ -195,22 +195,22 @@ void Skin::updateTransform() } } -AffineTransform Skin::getNodeToWorldTransform() const +kmMat4 Skin::getNodeToWorldTransform() const { - return AffineTransformConcat(_transform, _bone->getArmature()->getNodeToWorldTransform()); + return TransformConcat(_transform, _bone->getArmature()->getNodeToWorldTransform()); } -AffineTransform Skin::getNodeToWorldTransformAR() const +kmMat4 Skin::getNodeToWorldTransformAR() const { - AffineTransform displayTransform = _transform; + kmMat4 displayTransform = _transform; Point anchorPoint = _anchorPointInPoints; - anchorPoint = PointApplyAffineTransform(anchorPoint, displayTransform); + anchorPoint = PointApplyTransform(anchorPoint, displayTransform); - displayTransform.tx = anchorPoint.x; - displayTransform.ty = anchorPoint.y; + displayTransform.mat[12] = anchorPoint.x; + displayTransform.mat[13] = anchorPoint.y; - return AffineTransformConcat(displayTransform, _bone->getArmature()->getNodeToWorldTransform()); + return TransformConcat(displayTransform, _bone->getArmature()->getNodeToWorldTransform()); } void Skin::setBone(Bone *bone) diff --git a/cocos/editor-support/cocostudio/CCSkin.h b/cocos/editor-support/cocostudio/CCSkin.h index 4a944985c6..2c580c3038 100644 --- a/cocos/editor-support/cocostudio/CCSkin.h +++ b/cocos/editor-support/cocostudio/CCSkin.h @@ -48,8 +48,8 @@ public: void updateArmatureTransform(); void updateTransform() override; - cocos2d::AffineTransform getNodeToWorldTransform() const override; - cocos2d::AffineTransform getNodeToWorldTransformAR() const; + kmMat4 getNodeToWorldTransform() const override; + kmMat4 getNodeToWorldTransformAR() const; /** * @js NA * @lua NA @@ -69,7 +69,7 @@ protected: BaseData _skinData; Bone *_bone; Armature *_armature; - cocos2d::AffineTransform _skinTransform; + kmMat4 _skinTransform; std::string _displayName; }; diff --git a/cocos/editor-support/cocostudio/CCTransformHelp.cpp b/cocos/editor-support/cocostudio/CCTransformHelp.cpp index 0107760a3b..bc81478d17 100644 --- a/cocos/editor-support/cocostudio/CCTransformHelp.cpp +++ b/cocos/editor-support/cocostudio/CCTransformHelp.cpp @@ -118,6 +118,33 @@ void TransformHelp::nodeToMatrix(const BaseData &node, AffineTransform &matrix) matrix.ty = node.y; } +void TransformHelp::nodeToMatrix(const BaseData &node, kmMat4 &matrix) +{ + kmMat4Identity(&matrix); + + if (node.skewX == -node.skewY) + { + double sine = sin(node.skewX); + double cosine = cos(node.skewX); + + matrix.mat[0] = node.scaleX * cosine; + matrix.mat[1] = node.scaleX * -sine; + matrix.mat[4] = node.scaleY * sine; + matrix.mat[5] = node.scaleY * cosine; + } + else + { + matrix.mat[0] = node.scaleX * cos(node.skewY); + matrix.mat[1] = node.scaleX * sin(node.skewY); + matrix.mat[4] = node.scaleY * sin(node.skewX); + matrix.mat[5] = node.scaleY * cos(node.skewX); + } + + matrix.mat[12] = node.x; + matrix.mat[13] = node.y; +} + + void TransformHelp::matrixToNode(const AffineTransform &matrix, BaseData &node) { /* @@ -144,6 +171,33 @@ void TransformHelp::matrixToNode(const AffineTransform &matrix, BaseData &node) node.y = matrix.ty; } +void TransformHelp::matrixToNode(const kmMat4 &matrix, BaseData &node) +{ + /* + * In as3 language, there is a function called "deltaTransformPoint", it calculate a point used give Transform + * but not used the tx, ty value. we simulate the function here + */ + helpPoint1.x = 0; + helpPoint1.y = 1; + helpPoint1 = PointApplyTransform(helpPoint1, matrix); + helpPoint1.x -= matrix.mat[12]; + helpPoint1.y -= matrix.mat[13]; + + helpPoint2.x = 1; + helpPoint2.y = 0; + helpPoint2 = PointApplyTransform(helpPoint2, matrix); + helpPoint2.x -= matrix.mat[12]; + helpPoint2.y -= matrix.mat[13]; + + node.skewX = -(atan2f(helpPoint1.y, helpPoint1.x) - 1.5707964f); + node.skewY = atan2f(helpPoint2.y, helpPoint2.x); + node.scaleX = sqrt(matrix.mat[0] * matrix.mat[0] + matrix.mat[1] * matrix.mat[1]); + node.scaleY = sqrt(matrix.mat[4] * matrix.mat[4] + matrix.mat[5] * matrix.mat[5]); + node.x = matrix.mat[12]; + node.y = matrix.mat[13]; +} + + void TransformHelp::nodeConcat(BaseData &target, BaseData &source) { target.x += source.x; diff --git a/cocos/editor-support/cocostudio/CCTransformHelp.h b/cocos/editor-support/cocostudio/CCTransformHelp.h index 4e3e36e6d6..57b57fad9c 100644 --- a/cocos/editor-support/cocostudio/CCTransformHelp.h +++ b/cocos/editor-support/cocostudio/CCTransformHelp.h @@ -47,7 +47,9 @@ public: static void transformToParentWithoutScale(BaseData &node, const BaseData &parentNode); static void nodeToMatrix(const BaseData &_node, cocos2d::AffineTransform &_matrix); + static void nodeToMatrix(const BaseData &node, kmMat4 &matrix); static void matrixToNode(const cocos2d::AffineTransform &_matrix, BaseData &_node); + static void matrixToNode(const kmMat4 &_matrix, BaseData &_node); static void nodeConcat(BaseData &target, BaseData &source); static void nodeSub(BaseData &target, BaseData &source); From ab23b47043fa8088e08a499be0d86f1dd0e3ae4e Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 12 Dec 2013 10:29:07 +0800 Subject: [PATCH 73/98] use ssize_t for capacity and index in containers --- cocos/2d/ccCArray.cpp | 60 +++++++++--------- cocos/2d/ccCArray.h | 34 +++++----- cocos/base/CCArray.cpp | 40 ++++++------ cocos/base/CCArray.h | 32 +++++----- cocos/base/CCMap.h | 63 ++----------------- cocos/base/CCVector.h | 138 +++++++++++------------------------------ 6 files changed, 122 insertions(+), 245 deletions(-) diff --git a/cocos/2d/ccCArray.cpp b/cocos/2d/ccCArray.cpp index 2607450a55..e157d44bd2 100644 --- a/cocos/2d/ccCArray.cpp +++ b/cocos/2d/ccCArray.cpp @@ -28,10 +28,10 @@ THE SOFTWARE. NS_CC_BEGIN -const int CC_INVALID_INDEX = -1; +const ssize_t CC_INVALID_INDEX = -1; /** Allocates and initializes a new array with specified capacity */ -ccArray* ccArrayNew(int capacity) +ccArray* ccArrayNew(ssize_t capacity) { if (capacity == 0) capacity = 7; @@ -68,11 +68,11 @@ void ccArrayDoubleCapacity(ccArray *arr) arr->arr = newArr; } -void ccArrayEnsureExtraCapacity(ccArray *arr, int extra) +void ccArrayEnsureExtraCapacity(ccArray *arr, ssize_t extra) { while (arr->max < arr->num + extra) { - CCLOG("cocos2d: ccCArray: resizing ccArray capacity from [%d] to [%d].", + CCLOG("cocos2d: ccCArray: resizing ccArray capacity from [%zd] to [%zd].", arr->max, arr->max*2); @@ -82,7 +82,7 @@ void ccArrayEnsureExtraCapacity(ccArray *arr, int extra) void ccArrayShrink(ccArray *arr) { - int newSize = 0; + ssize_t newSize = 0; //only resize when necessary if (arr->max > arr->num && !(arr->num==0 && arr->max==1)) @@ -104,11 +104,11 @@ void ccArrayShrink(ccArray *arr) } /** Returns index of first occurrence of object, CC_INVALID_INDEX if object not found. */ -int ccArrayGetIndexOfObject(ccArray *arr, Object* object) +ssize_t ccArrayGetIndexOfObject(ccArray *arr, Object* object) { const auto arrNum = arr->num; Object** ptr = arr->arr; - for (int i = 0; i < arrNum; ++i, ++ptr) + for (ssize_t i = 0; i < arrNum; ++i, ++ptr) { if (*ptr == object) return i; @@ -143,7 +143,7 @@ void ccArrayAppendObjectWithResize(ccArray *arr, Object* object) enough capacity. */ void ccArrayAppendArray(ccArray *arr, ccArray *plusArr) { - for (int i = 0; i < plusArr->num; i++) + for (ssize_t i = 0; i < plusArr->num; i++) { ccArrayAppendObject(arr, plusArr->arr[i]); } @@ -157,14 +157,14 @@ void ccArrayAppendArrayWithResize(ccArray *arr, ccArray *plusArr) } /** Inserts an object at index */ -void ccArrayInsertObjectAtIndex(ccArray *arr, Object* object, int index) +void ccArrayInsertObjectAtIndex(ccArray *arr, Object* object, ssize_t index) { CCASSERT(index<=arr->num, "Invalid index. Out of bounds"); CCASSERT(object != NULL, "Invalid parameter!"); ccArrayEnsureExtraCapacity(arr, 1); - int remaining = arr->num - index; + ssize_t remaining = arr->num - index; if (remaining > 0) { memmove((void *)&arr->arr[index+1], (void *)&arr->arr[index], sizeof(Object*) * remaining ); @@ -176,7 +176,7 @@ void ccArrayInsertObjectAtIndex(ccArray *arr, Object* object, int index) } /** Swaps two objects */ -void ccArraySwapObjectsAtIndexes(ccArray *arr, int index1, int index2) +void ccArraySwapObjectsAtIndexes(ccArray *arr, ssize_t index1, ssize_t index2) { CCASSERT(index1>=0 && index1 < arr->num, "(1) Invalid index. Out of bounds"); CCASSERT(index2>=0 && index2 < arr->num, "(2) Invalid index. Out of bounds"); @@ -198,7 +198,7 @@ void ccArrayRemoveAllObjects(ccArray *arr) /** Removes object at specified index and pushes back all subsequent objects. Behavior undefined if index outside [0, num-1]. */ -void ccArrayRemoveObjectAtIndex(ccArray *arr, int index, bool bReleaseObj/* = true*/) +void ccArrayRemoveObjectAtIndex(ccArray *arr, ssize_t index, bool bReleaseObj/* = true*/) { CCASSERT(arr && arr->num > 0 && index>=0 && index < arr->num, "Invalid index. Out of bounds"); if (bReleaseObj) @@ -208,7 +208,7 @@ void ccArrayRemoveObjectAtIndex(ccArray *arr, int index, bool bReleaseObj/* = tr arr->num--; - int remaining = arr->num - index; + ssize_t remaining = arr->num - index; if(remaining>0) { memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1], remaining * sizeof(Object*)); @@ -218,7 +218,7 @@ void ccArrayRemoveObjectAtIndex(ccArray *arr, int index, bool bReleaseObj/* = tr /** Removes object at specified index and fills the gap with the last object, thereby avoiding the need to push back subsequent objects. Behavior undefined if index outside [0, num-1]. */ -void ccArrayFastRemoveObjectAtIndex(ccArray *arr, int index) +void ccArrayFastRemoveObjectAtIndex(ccArray *arr, ssize_t index) { CC_SAFE_RELEASE(arr->arr[index]); auto last = --arr->num; @@ -249,7 +249,7 @@ void ccArrayRemoveObject(ccArray *arr, Object* object, bool bReleaseObj/* = true first matching instance in arr will be removed. */ void ccArrayRemoveArray(ccArray *arr, ccArray *minusArr) { - for (int i = 0; i < minusArr->num; i++) + for (ssize_t i = 0; i < minusArr->num; i++) { ccArrayRemoveObject(arr, minusArr->arr[i]); } @@ -259,9 +259,9 @@ void ccArrayRemoveArray(ccArray *arr, ccArray *minusArr) matching instances in arr will be removed. */ void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr) { - int back = 0; + ssize_t back = 0; - for (int i = 0; i < arr->num; i++) + for (ssize_t i = 0; i < arr->num; i++) { if (ccArrayContainsObject(minusArr, arr->arr[i])) { @@ -281,7 +281,7 @@ void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr) // #pragma mark ccCArray for Values (c structures) /** Allocates and initializes a new C array with specified capacity */ -ccCArray* ccCArrayNew(int capacity) +ccCArray* ccCArrayNew(ssize_t capacity) { if (capacity == 0) { @@ -316,15 +316,15 @@ void ccCArrayDoubleCapacity(ccCArray *arr) } /** Increases array capacity such that max >= num + extra. */ -void ccCArrayEnsureExtraCapacity(ccCArray *arr, int extra) +void ccCArrayEnsureExtraCapacity(ccCArray *arr, ssize_t extra) { ccArrayEnsureExtraCapacity((ccArray*)arr,extra); } /** Returns index of first occurrence of value, CC_INVALID_INDEX if value not found. */ -int ccCArrayGetIndexOfValue(ccCArray *arr, void* value) +ssize_t ccCArrayGetIndexOfValue(ccCArray *arr, void* value) { - for(int i = 0; i < arr->num; i++) + for(ssize_t i = 0; i < arr->num; i++) { if( arr->arr[i] == value ) return i; @@ -339,7 +339,7 @@ bool ccCArrayContainsValue(ccCArray *arr, void* value) } /** Inserts a value at a certain position. Behavior undefined if array doesn't have enough capacity */ -void ccCArrayInsertValueAtIndex( ccCArray *arr, void* value, int index) +void ccCArrayInsertValueAtIndex( ccCArray *arr, void* value, ssize_t index) { CCASSERT( index < arr->max, "ccCArrayInsertValueAtIndex: invalid index"); @@ -384,7 +384,7 @@ void ccCArrayAppendValueWithResize(ccCArray *arr, void* value) enough capacity. */ void ccCArrayAppendArray(ccCArray *arr, ccCArray *plusArr) { - for( int i = 0; i < plusArr->num; i++) + for( ssize_t i = 0; i < plusArr->num; i++) { ccCArrayAppendValue(arr, plusArr->arr[i]); } @@ -407,9 +407,9 @@ void ccCArrayRemoveAllValues(ccCArray *arr) Behavior undefined if index outside [0, num-1]. @since v0.99.4 */ -void ccCArrayRemoveValueAtIndex(ccCArray *arr, int index) +void ccCArrayRemoveValueAtIndex(ccCArray *arr, ssize_t index) { - for( int last = --arr->num; index < last; index++) + for( ssize_t last = --arr->num; index < last; index++) { arr->arr[index] = arr->arr[index + 1]; } @@ -420,9 +420,9 @@ void ccCArrayRemoveValueAtIndex(ccCArray *arr, int index) Behavior undefined if index outside [0, num-1]. @since v0.99.4 */ -void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, int index) +void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, ssize_t index) { - auto last = --arr->num; + ssize_t last = --arr->num; arr->arr[index] = arr->arr[last]; } @@ -443,7 +443,7 @@ void ccCArrayRemoveValue(ccCArray *arr, void* value) */ void ccCArrayRemoveArray(ccCArray *arr, ccCArray *minusArr) { - for(int i = 0; i < minusArr->num; i++) + for(ssize_t i = 0; i < minusArr->num; i++) { ccCArrayRemoveValue(arr, minusArr->arr[i]); } @@ -454,9 +454,9 @@ void ccCArrayRemoveArray(ccCArray *arr, ccCArray *minusArr) */ void ccCArrayFullRemoveArray(ccCArray *arr, ccCArray *minusArr) { - int back = 0; + ssize_t back = 0; - for(int i = 0; i < arr->num; i++) + for(ssize_t i = 0; i < arr->num; i++) { if( ccCArrayContainsValue(minusArr, arr->arr[i]) ) { diff --git a/cocos/2d/ccCArray.h b/cocos/2d/ccCArray.h index fff5152904..8c86356980 100644 --- a/cocos/2d/ccCArray.h +++ b/cocos/2d/ccCArray.h @@ -51,20 +51,20 @@ THE SOFTWARE. NS_CC_BEGIN -extern const int CC_INVALID_INDEX; +extern const ssize_t CC_INVALID_INDEX; // Easy integration #define CCARRAYDATA_FOREACH(__array__, __object__) \ -__object__=__array__->arr[0]; for(int i=0, num=__array__->num; iarr[i]) \ +__object__=__array__->arr[0]; for(ssize_t i=0, num=__array__->num; iarr[i]) \ typedef struct _ccArray { - int num, max; + ssize_t num, max; Object** arr; } ccArray; /** Allocates and initializes a new array with specified capacity */ -ccArray* ccArrayNew(int capacity); +ccArray* ccArrayNew(ssize_t capacity); /** Frees array after removing all remaining objects. Silently ignores nil arr. */ void ccArrayFree(ccArray*& arr); @@ -73,13 +73,13 @@ void ccArrayFree(ccArray*& arr); void ccArrayDoubleCapacity(ccArray *arr); /** Increases array capacity such that max >= num + extra. */ -void ccArrayEnsureExtraCapacity(ccArray *arr, int extra); +void ccArrayEnsureExtraCapacity(ccArray *arr, ssize_t extra); /** shrinks the array so the memory footprint corresponds with the number of items */ void ccArrayShrink(ccArray *arr); /** Returns index of first occurrence of object, NSNotFound if object not found. */ -int ccArrayGetIndexOfObject(ccArray *arr, Object* object); +ssize_t ccArrayGetIndexOfObject(ccArray *arr, Object* object); /** Returns a Boolean value that indicates whether object is present in array. */ bool ccArrayContainsObject(ccArray *arr, Object* object); @@ -98,22 +98,22 @@ void ccArrayAppendArray(ccArray *arr, ccArray *plusArr); void ccArrayAppendArrayWithResize(ccArray *arr, ccArray *plusArr); /** Inserts an object at index */ -void ccArrayInsertObjectAtIndex(ccArray *arr, Object* object, int index); +void ccArrayInsertObjectAtIndex(ccArray *arr, Object* object, ssize_t index); /** Swaps two objects */ -void ccArraySwapObjectsAtIndexes(ccArray *arr, int index1, int index2); +void ccArraySwapObjectsAtIndexes(ccArray *arr, ssize_t index1, ssize_t index2); /** Removes all objects from arr */ void ccArrayRemoveAllObjects(ccArray *arr); /** Removes object at specified index and pushes back all subsequent objects. Behavior undefined if index outside [0, num-1]. */ -void ccArrayRemoveObjectAtIndex(ccArray *arr, int index, bool bReleaseObj = true); +void ccArrayRemoveObjectAtIndex(ccArray *arr, ssize_t index, bool bReleaseObj = true); /** Removes object at specified index and fills the gap with the last object, thereby avoiding the need to push back subsequent objects. Behavior undefined if index outside [0, num-1]. */ -void ccArrayFastRemoveObjectAtIndex(ccArray *arr, int index); +void ccArrayFastRemoveObjectAtIndex(ccArray *arr, ssize_t index); void ccArrayFastRemoveObject(ccArray *arr, Object* object); @@ -133,12 +133,12 @@ void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr); // #pragma mark ccCArray for Values (c structures) typedef struct _ccCArray { - int num, max; + ssize_t num, max; void** arr; } ccCArray; /** Allocates and initializes a new C array with specified capacity */ -ccCArray* ccCArrayNew(int capacity); +ccCArray* ccCArrayNew(ssize_t capacity); /** Frees C array after removing all remaining values. Silently ignores nil arr. */ void ccCArrayFree(ccCArray *arr); @@ -147,16 +147,16 @@ void ccCArrayFree(ccCArray *arr); void ccCArrayDoubleCapacity(ccCArray *arr); /** Increases array capacity such that max >= num + extra. */ -void ccCArrayEnsureExtraCapacity(ccCArray *arr, int extra); +void ccCArrayEnsureExtraCapacity(ccCArray *arr, ssize_t extra); /** Returns index of first occurrence of value, NSNotFound if value not found. */ -int ccCArrayGetIndexOfValue(ccCArray *arr, void* value); +ssize_t ccCArrayGetIndexOfValue(ccCArray *arr, void* value); /** Returns a Boolean value that indicates whether value is present in the C array. */ bool ccCArrayContainsValue(ccCArray *arr, void* value); /** Inserts a value at a certain position. Behavior undefined if array doesn't have enough capacity */ -void ccCArrayInsertValueAtIndex( ccCArray *arr, void* value, int index); +void ccCArrayInsertValueAtIndex( ccCArray *arr, void* value, ssize_t index); /** Appends an value. Behavior undefined if array doesn't have enough capacity. */ void ccCArrayAppendValue(ccCArray *arr, void* value); @@ -178,14 +178,14 @@ void ccCArrayRemoveAllValues(ccCArray *arr); Behavior undefined if index outside [0, num-1]. @since v0.99.4 */ -void ccCArrayRemoveValueAtIndex(ccCArray *arr, int index); +void ccCArrayRemoveValueAtIndex(ccCArray *arr, ssize_t index); /** Removes value at specified index and fills the gap with the last value, thereby avoiding the need to push back subsequent values. Behavior undefined if index outside [0, num-1]. @since v0.99.4 */ -void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, int index); +void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, ssize_t index); /** Searches for the first occurrence of value and removes it. If value is not found the function has no effect. @since v0.99.4 diff --git a/cocos/base/CCArray.cpp b/cocos/base/CCArray.cpp index 0a9bc7953b..f6014ce5ae 100644 --- a/cocos/base/CCArray.cpp +++ b/cocos/base/CCArray.cpp @@ -196,11 +196,11 @@ bool __Array::initWithArray(__Array* otherArray) return true; } -int __Array::getIndexOfObject(Object* object) const +ssize_t __Array::getIndexOfObject(Object* object) const { auto it = data.begin(); - for (int i = 0; it != data.end(); ++it, ++i) + for (ssize_t i = 0; it != data.end(); ++it, ++i) { if (it->get() == object) { @@ -232,13 +232,13 @@ Object* __Array::getRandomObject() bool __Array::containsObject(Object* object) const { - auto i = this->getIndexOfObject(object); + ssize_t i = this->getIndexOfObject(object); return (i >= 0); } bool __Array::isEqualToArray(__Array* otherArray) { - for (int i = 0; i < this->count(); ++i) + for (ssize_t i = 0; i < this->count(); ++i) { if (!this->getObjectAtIndex(i)->isEqual(otherArray->getObjectAtIndex(i))) { @@ -279,7 +279,7 @@ void __Array::removeObject(Object* object, bool releaseObj /* ignored */) data.erase(std::remove(data.begin(), data.end(), object)); } -void __Array::removeObjectAtIndex(int index, bool releaseObj /* ignored */) +void __Array::removeObjectAtIndex(ssize_t index, bool releaseObj /* ignored */) { auto obj = data[index]; data.erase(data.begin() + index); @@ -307,15 +307,15 @@ void __Array::fastRemoveObject(Object* object) void __Array::exchangeObject(Object* object1, Object* object2) { - auto idx1 = getIndexOfObject(object1); - auto idx2 = getIndexOfObject(object2); + ssize_t idx1 = getIndexOfObject(object1); + ssize_t idx2 = getIndexOfObject(object2); CCASSERT(idx1 >= 0 && idx2 >= 2, "invalid object index"); std::swap(data[idx1], data[idx2]); } -void __Array::exchangeObjectAtIndex(int index1, int index2) +void __Array::exchangeObjectAtIndex(ssize_t index1, ssize_t index2) { std::swap(data[index1], data[index2]); } @@ -448,7 +448,7 @@ __Array* __Array::createWithArray(__Array* otherArray) return otherArray->clone(); } -__Array* __Array::createWithCapacity(int capacity) +__Array* __Array::createWithCapacity(ssize_t capacity) { CCASSERT(capacity>=0, "Invalid capacity"); @@ -539,7 +539,7 @@ bool __Array::initWithObjects(Object* object, ...) return ret; } -bool __Array::initWithCapacity(int capacity) +bool __Array::initWithCapacity(ssize_t capacity) { CCASSERT(capacity>=0 && !data, "Array cannot be re-initialized"); @@ -563,7 +563,7 @@ bool __Array::initWithArray(__Array* otherArray) return ret; } -int __Array::getIndexOfObject(Object* object) const +ssize_t __Array::getIndexOfObject(Object* object) const { return ccArrayGetIndexOfObject(data, object); } @@ -614,13 +614,13 @@ void __Array::addObjectsFromArray(__Array* otherArray) ccArrayAppendArrayWithResize(data, otherArray->data); } -void __Array::insertObject(Object* object, int index) +void __Array::insertObject(Object* object, ssize_t index) { CCASSERT(data, "Array not initialized"); ccArrayInsertObjectAtIndex(data, object, index); } -void __Array::setObject(Object* object, int index) +void __Array::setObject(Object* object, ssize_t index) { CCASSERT(index >= 0 && index < count(), "Invalid index"); @@ -643,7 +643,7 @@ void __Array::removeObject(Object* object, bool releaseObj/* = true*/) ccArrayRemoveObject(data, object, releaseObj); } -void __Array::removeObjectAtIndex(int index, bool releaseObj) +void __Array::removeObjectAtIndex(ssize_t index, bool releaseObj) { ccArrayRemoveObjectAtIndex(data, index, releaseObj); } @@ -658,7 +658,7 @@ void __Array::removeAllObjects() ccArrayRemoveAllObjects(data); } -void __Array::fastRemoveObjectAtIndex(int index) +void __Array::fastRemoveObjectAtIndex(ssize_t index) { ccArrayFastRemoveObjectAtIndex(data, index); } @@ -685,12 +685,12 @@ void __Array::exchangeObject(Object* object1, Object* object2) ccArraySwapObjectsAtIndexes(data, index1, index2); } -void __Array::exchangeObjectAtIndex(int index1, int index2) +void __Array::exchangeObjectAtIndex(ssize_t index1, ssize_t index2) { ccArraySwapObjectsAtIndexes(data, index1, index2); } -void __Array::replaceObjectAtIndex(int index, Object* object, bool releaseObject/* = true*/) +void __Array::replaceObjectAtIndex(ssize_t index, Object* object, bool releaseObject/* = true*/) { ccArrayInsertObjectAtIndex(data, object, index); ccArrayRemoveObjectAtIndex(data, index + 1); @@ -701,10 +701,10 @@ void __Array::reverseObjects() if (data->num > 1) { // floorf(), since in the case of an even number, the number of swaps stays the same - auto count = static_cast(floorf(data->num/2.f)); - auto maxIndex = data->num - 1; + auto count = static_cast(floorf(data->num/2.f)); + ssize_t maxIndex = data->num - 1; - for (int i = 0; i < count ; ++i) + for (ssize_t i = 0; i < count ; ++i) { ccArraySwapObjectsAtIndexes(data, i, maxIndex); --maxIndex; diff --git a/cocos/base/CCArray.h b/cocos/base/CCArray.h index 2ecd9e5fe7..17166d7588 100644 --- a/cocos/base/CCArray.h +++ b/cocos/base/CCArray.h @@ -250,7 +250,7 @@ public: /** Create an array with a default capacity * @js NA */ - static __Array* createWithCapacity(int capacity); + static __Array* createWithCapacity(ssize_t capacity); /** Create an array with from an existing array * @js NA */ @@ -295,7 +295,7 @@ public: * @js NA * @lua NA */ - bool initWithCapacity(int capacity); + bool initWithCapacity(ssize_t capacity); /** Initializes an array with an existing array * @js NA * @lua NA @@ -307,7 +307,7 @@ public: /** Returns element count of the array * @js NA */ - int count() const + ssize_t count() const { #if CC_USE_ARRAY_VECTOR return data.size(); @@ -318,7 +318,7 @@ public: /** Returns capacity of the array * @js NA */ - int capacity() const + ssize_t capacity() const { #if CC_USE_ARRAY_VECTOR return data.capacity(); @@ -330,17 +330,17 @@ public: * @js NA * @lua NA */ - int getIndexOfObject(Object* object) const; + ssize_t getIndexOfObject(Object* object) const; /** * @js NA */ - CC_DEPRECATED_ATTRIBUTE int indexOfObject(Object* object) const { return getIndexOfObject(object); } + CC_DEPRECATED_ATTRIBUTE ssize_t indexOfObject(Object* object) const { return getIndexOfObject(object); } /** Returns an element with a certain index * @js NA * @lua NA */ - Object* getObjectAtIndex(int index) + Object* getObjectAtIndex(ssize_t index) { CCASSERT(index>=0 && index < count(), "index out of range in getObjectAtIndex()"); #if CC_USE_ARRAY_VECTOR @@ -349,7 +349,7 @@ public: return data->arr[index]; #endif } - CC_DEPRECATED_ATTRIBUTE Object* objectAtIndex(int index) { return getObjectAtIndex(index); } + CC_DEPRECATED_ATTRIBUTE Object* objectAtIndex(ssize_t index) { return getObjectAtIndex(index); } /** Returns the last element of the array * @js NA */ @@ -401,17 +401,17 @@ public: /** Insert a certain object at a certain index * @js NA */ - void insertObject(Object* object, int index); + void insertObject(Object* object, ssize_t index); /** sets a certain object at a certain index * @js NA * @lua NA */ - void setObject(Object* object, int index); + void setObject(Object* object, ssize_t index); /** sets a certain object at a certain index without retaining. Use it with caution * @js NA * @lua NA */ - void fastSetObject(Object* object, int index) + void fastSetObject(Object* object, ssize_t index) { #if CC_USE_ARRAY_VECTOR setObject(object, index); @@ -424,7 +424,7 @@ public: * @js NA * @lua NA */ - void swap( int indexOne, int indexTwo ) + void swap( ssize_t indexOne, ssize_t indexTwo ) { CCASSERT(indexOne >=0 && indexOne < count() && indexTwo >= 0 && indexTwo < count(), "Invalid indices"); #if CC_USE_ARRAY_VECTOR @@ -447,7 +447,7 @@ public: /** Remove an element with a certain index * @js NA */ - void removeObjectAtIndex(int index, bool releaseObj = true); + void removeObjectAtIndex(ssize_t index, bool releaseObj = true); /** Remove all elements * @js NA */ @@ -463,7 +463,7 @@ public: /** Fast way to remove an element with a certain index * @js NA */ - void fastRemoveObjectAtIndex(int index); + void fastRemoveObjectAtIndex(ssize_t index); // Rearranging Content @@ -474,12 +474,12 @@ public: /** Swap two elements with certain indexes * @js NA */ - void exchangeObjectAtIndex(int index1, int index2); + void exchangeObjectAtIndex(ssize_t index1, ssize_t index2); /** Replace object at index with another object. * @js NA */ - void replaceObjectAtIndex(int index, Object* object, bool releaseObject = true); + void replaceObjectAtIndex(ssize_t index, Object* object, bool releaseObject = true); /** Revers the array * @js NA diff --git a/cocos/base/CCMap.h b/cocos/base/CCMap.h index 67184cf20f..57445c3145 100644 --- a/cocos/base/CCMap.h +++ b/cocos/base/CCMap.h @@ -59,22 +59,19 @@ public: const_iterator cbegin() const { return _data.cbegin(); } const_iterator cend() const { return _data.cend(); } - /** Default constructor */ Map() : _data() { CCLOGINFO("In the default constructor of Map!"); } - /** Contructor with capacity */ - explicit Map(int capacity) + explicit Map(ssize_t capacity) : _data() { CCLOGINFO("In the constructor with capacity of Map!"); _data.reserve(capacity); } - /** Copy constructor */ Map(const Map& other) { CCLOGINFO("In the copy constructor of Map!"); @@ -82,50 +79,40 @@ public: addRefForAllObjects(); } - /** Move constructor */ Map(Map&& other) { CCLOGINFO("In the move constructor of Map!"); _data = std::move(other._data); } - /** Destructor - * It will release all objects in map. - */ ~Map() { CCLOGINFO("In the destructor of Map!"); clear(); } - /** Sets capacity of the map */ - void reserve(int capacity) + /** Sets capacity of current array */ + void reserve(ssize_t capacity) { _data.reserve(capacity); } - /** Returns capacity of the map */ + /** Returns capacity of the array */ size_t capacity() const { return _data.capacity(); } - /** The number of elements in the map. */ size_t size() const { return _data.size(); } - /** Returns a bool value indicating whether the map container is empty, i.e. whether its size is 0. - * @note This function does not modify the content of the container in any way. - * To clear the content of an array object, member function unordered_map::clear exists. - */ bool empty() const { return _data.empty(); } - /** Returns all keys in the map */ std::vector keys() const { std::vector keys; @@ -140,7 +127,6 @@ public: return keys; } - /** Returns all keys that matches the object */ std::vector keys(V object) const { std::vector keys; @@ -156,11 +142,6 @@ public: return keys; } - /** @brief Returns a reference to the mapped value of the element with key k in the map. - * @note If key does not match the key of any element in the container, the function return nullptr. - * @param key Key value of the element whose mapped value is accessed. - * Member type K is the keys for the elements in the container. defined in Map as an alias of its first template parameter (Key). - */ const V at(const K& key) const { auto iter = _data.find(key); @@ -177,13 +158,6 @@ public: return nullptr; } - /** @brief Searches the container for an element with 'key' as key and returns an iterator to it if found, - * otherwise it returns an iterator to Map::end (the element past the end of the container). - * @param key Key to be searched for. - * Member type 'K' is the type of the keys for the elements in the container, - * defined in Map as an alias of its first template parameter (Key). - * - */ const_iterator find(const K& key) const { return _data.find(key); @@ -194,11 +168,6 @@ public: return _data.find(key); } - /** @brief Inserts new elements in the map. - * @note If the container has already contained the key, this function will erase the old pair(key, object) and insert the new pair. - * @param key The key to be inserted. - * @param object The object to be inserted. - */ void insert(const K& key, V object) { CCASSERT(object != nullptr, "Object is nullptr!"); @@ -207,22 +176,11 @@ public: object->retain(); } - /** @brief Removes an element with an iterator from the Map container. - * @param position Iterator pointing to a single element to be removed from the Map. - * Member type const_iterator is a forward iterator type. - */ iterator erase(const_iterator position) { - CCASSERT(position != _data.cend(), "Invalid iterator!"); - position->second->release(); return _data.erase(position); } - /** @brief Removes an element with an iterator from the Map container. - * @param k Key of the element to be erased. - * Member type 'K' is the type of the keys for the elements in the container, - * defined in Map as an alias of its first template parameter (Key). - */ size_t erase(const K& k) { auto iter = _data.find(k); @@ -236,9 +194,6 @@ public: return 0; } - /** @brief Removes some elements with a vector which contains keys in the map. - * @param keys Keys of elements to be erased. - */ void erase(const std::vector& keys) { std::for_each(keys.cbegin(), keys.cend(), [this](const K& key){ @@ -246,10 +201,6 @@ public: }); } - /** All the elements in the Map container are dropped: - * their reference count will be decreased, and they are removed from the container, - * leaving it with a size of 0. - */ void clear() { for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter) @@ -260,9 +211,6 @@ public: _data.clear(); } - /** @brief Gets a random object in the map - * @return Returns the random object if the map isn't empty, otherwise it returns nullptr. - */ V getRandomObject() const { if (!_data.empty()) @@ -298,7 +246,6 @@ public: // return _data.at(key); // } - /** Copy assignment operator */ Map& operator= ( const Map& other ) { CCLOGINFO("In the copy assignment operator of Map!"); @@ -308,7 +255,6 @@ public: return *this; } - /** Move assignment operator */ Map& operator= ( Map&& other ) { CCLOGINFO("In the move assignment operator of Map!"); @@ -318,7 +264,6 @@ public: protected: - /** Retains all the objects in the map */ void addRefForAllObjects() { for (auto iter = _data.begin(); iter != _data.end(); ++iter) diff --git a/cocos/base/CCVector.h b/cocos/base/CCVector.h index 984e0a8314..5ae654c8b8 100644 --- a/cocos/base/CCVector.h +++ b/cocos/base/CCVector.h @@ -71,22 +71,20 @@ public: } - /** Constructor with a capacity */ - explicit Vector(int capacity) + /** creates an emptry Vector */ + explicit Vector(ssize_t capacity) : _data() { CCLOGINFO("In the default constructor with capacity of Vector."); reserve(capacity); } - /** Destructor */ ~Vector() { CCLOGINFO("In the destructor of Vector."); clear(); } - /** Copy constructor */ Vector(const Vector& other) { CCLOGINFO("In the copy constructor!"); @@ -101,7 +99,6 @@ public: _data = std::move(other._data); } - /** Copy assignment operator */ Vector& operator=(const Vector& other) { CCLOGINFO("In the copy assignment operator!"); @@ -111,7 +108,6 @@ public: return *this; } - /** Move assignment operator */ Vector& operator=(Vector&& other) { CCLOGINFO("In the move assignment operator!"); @@ -130,51 +126,33 @@ public: // return _data[index]; // } - /** @brief Request a change in capacity - * @param capacity Minimum capacity for the vector. - * If n is greater than the current vector capacity, - * the function causes the container to reallocate its storage increasing its capacity to n (or greater). - */ - void reserve(int n) + /** Sets capacity of current array */ + void reserve(ssize_t capacity) { - _data.reserve(n); + _data.reserve(capacity); } - /** @brief Returns the size of the storage space currently allocated for the vector, expressed in terms of elements. - * @note This capacity is not necessarily equal to the vector size. - * It can be equal or greater, with the extra space allowing to accommodate for growth without the need to reallocate on each insertion. - * @return The size of the currently allocated storage capacity in the vector, measured in terms of the number elements it can hold. - */ + /** Returns capacity of the array */ int capacity() const { return _data.capacity(); } - /** @brief Returns the number of elements in the vector. - * @note This is the number of actual objects held in the vector, which is not necessarily equal to its storage capacity. - * @return The number of elements in the container. - */ + // Querying an Array + + /** Returns element count of the array */ int size() const { return static_cast(_data.size()); } - /** @brief Returns whether the vector is empty (i.e. whether its size is 0). - * @note This function does not modify the container in any way. To clear the content of a vector, see Vector::clear. - */ bool empty() const { return _data.empty(); } - /** Returns the maximum number of elements that the vector can hold. */ - size_t max_size() const - { - return _data.max_size(); - } - /** Returns index of a certain object, return UINT_MAX if doesn't contain the object */ - int getIndex(T object) const + ssize_t getIndex(T object) const { auto iter = std::find(_data.begin(), _data.end(), object); if (iter != _data.end()) @@ -183,10 +161,6 @@ public: return -1; } - /** @brief Find the object in the vector. - * @return Returns an iterator to the first element in the range [first,last) that compares equal to val. - * If no such element is found, the function returns last. - */ const_iterator find(T object) const { return std::find(_data.begin(), _data.end(), object); @@ -197,26 +171,25 @@ public: return std::find(_data.begin(), _data.end(), object); } - /** Returns the element at position 'index' in the vector. */ - T at(int index) const + /** Returns an element with a certain index */ + T at(ssize_t index) const { CCASSERT( index >= 0 && index < size(), "index out of range in getObjectAtIndex()"); return _data[index]; } - /** Returns the first element in the vector. */ T front() const { return _data.front(); } - /** Returns the last element of the vector. */ + /** Returns the last element of the array */ T back() const { return _data.back(); } - /** Returns a random element of the vector. */ + /** Returns a random element */ T getRandomObject() const { if (!_data.empty()) @@ -227,20 +200,20 @@ public: return nullptr; } - /** Returns a Boolean value that indicates whether object is present in vector. */ + /** Returns a Boolean value that indicates whether object is present in array. */ bool contains(T object) const { return( std::find(_data.begin(), _data.end(), object) != _data.end() ); } - /** Returns true if the two vectors are equal */ + /** returns true if the the arrays are equal */ bool equals(const Vector &other) { - size_t s = this->size(); + ssize_t s = this->size(); if (s != other.size()) return false; - for (int i = 0; i < s; i++) + for (ssize_t i = 0; i < s; i++) { if (!this->at(i)->isEqual(other.at(i))) { @@ -250,13 +223,9 @@ public: return true; } - // Adds objects - - /** @brief Adds a new element at the end of the vector, after its current last element. - * @note This effectively increases the container size by one, - * which causes an automatic reallocation of the allocated storage space - * if -and only if- the new vector size surpasses the current vector capacity. - */ + // Adding Objects + + /** Add a certain object */ void pushBack(T object) { CCASSERT(object != nullptr, "The object should not be nullptr"); @@ -264,7 +233,7 @@ public: object->retain(); } - /** Inserts all elements of an existing vector */ + /** Add all elements of an existing array */ void insert(const Vector& other) { for( auto it = other.begin(); it != other.end(); ++it ) { @@ -273,13 +242,8 @@ public: } } - /** @brief Insert a certain object at a certain index - * @note The vector is extended by inserting new elements before the element at the specified 'index', - * effectively increasing the container size by the number of elements inserted. - * This causes an automatic reallocation of the allocated storage space - * if -and only if- the new vector size surpasses the current vector capacity. - */ - void insert(int index, T object) + /** Insert a certain object at a certain index */ + void insert(ssize_t index, T object) { CCASSERT(index >= 0 && index <= size(), "Invalid index!"); CCASSERT(object != nullptr, "The object should not be nullptr"); @@ -287,11 +251,9 @@ public: object->retain(); } - // Removes Objects + // Removing Objects - /** Removes the last element in the vector, - * effectively reducing the container size by one, decrease the referece count of the deleted object. - */ + /** Remove last object */ void popBack() { CCASSERT(!_data.empty(), "no objects added"); @@ -300,10 +262,7 @@ public: last->release(); } - /** @brief Remove a certain object. - * @param object The object to be removed. - * @param toRelease Whether to decrease the referece count of the deleted object. - */ + /** Remove a certain object */ void erase(T object, bool toRelease = true) { CCASSERT(object != nullptr, "The object should not be nullptr"); @@ -314,11 +273,7 @@ public: object->release(); } - /** @brief Removes from the vector with an iterator. - * @param position Iterator pointing to a single element to be removed from the vector. - * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. - * This is the container end if the operation erased the last element in the sequence. - */ + /** Removes an element with a certain index */ iterator erase(iterator position) { CCASSERT(position >= _data.begin() && position < _data.end(), "Invalid position!"); @@ -326,12 +281,6 @@ public: return _data.erase(position); } - /** @brief Removes from the vector with a range of elements ( [first, last) ). - * @param first The beginning of the range - * @param last The end of the range, the 'last' will not used, it's only for indicating the end of range. - * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. - * This is the container end if the operation erased the last element in the sequence. - */ iterator erase(const_iterator first, const_iterator last) { for (auto iter = first; iter != last; ++iter) @@ -342,22 +291,15 @@ public: return _data.erase(first, last); } - /** @brief Removes from the vector with an index. - * @param index The index of the element to be removed from the vector. - * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. - * This is the container end if the operation erased the last element in the sequence. - */ - iterator erase(int index) + void erase(int index) { CCASSERT(!_data.empty() && index >=0 && index < size(), "Invalid index!"); auto it = std::next( begin(), index ); (*it)->release(); - return _data.erase(it); + _data.erase(it); } - /** @brief Removes all elements from the vector (which are destroyed), leaving the container with a size of 0. - * @note All the elements in the vector will be released (referece count will be decreased). - */ + /** Removes all objects */ void clear() { for( auto it = std::begin(_data); it != std::end(_data); ++it ) { @@ -380,7 +322,7 @@ public: } /** Swap two elements with certain indexes */ - void swap(int index1, int index2) + void swap(ssize_t index1, ssize_t index2) { CCASSERT(index1 >=0 && index1 < size() && index2 >= 0 && index2 < size(), "Invalid indices"); @@ -388,7 +330,7 @@ public: } /** Replace object at index with another object. */ - void replace(int index, T object) + void replace(ssize_t index, T object) { CCASSERT(index >= 0 && index < size(), "Invalid index!"); CCASSERT(object != nullptr, "The object should not be nullptr"); @@ -398,19 +340,18 @@ public: object->retain(); } - /** reverses the vector */ + /** reverses the array */ void reverse() { std::reverse( std::begin(_data), std::end(_data) ); } - /** Shrinks the vector so the memory footprint corresponds with the number of items */ + /** Shrinks the array so the memory footprint corresponds with the number of items */ void shrinkToFit() { _data.shrink_to_fit(); } - /** Traverses through the vector and applys the callback function for each element */ void forEach(const std::function& callback) { if (empty()) @@ -421,7 +362,6 @@ public: }); } - /** Traverses through the vector and applys the callback function for each element */ void forEach(const std::function& callback) const { if (empty()) @@ -432,7 +372,6 @@ public: }); } - /** Traverses through the vector in reversed order and applys the callback function for each element */ void forEachReverse(const std::function& callback) { if (empty()) @@ -443,7 +382,6 @@ public: }); } - /** Traverses through the vector in reversed order and applys the callback function for each element */ void forEachReverse(const std::function& callback) const { if (empty()) @@ -454,11 +392,6 @@ public: }); } - /** @brief Sorts all elements in the vector according the binary callback function. - * @param callback Binary function that accepts two elements in the vector as arguments, - * and returns a value convertible to bool. - * The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines. - */ void sort(const std::function& callback) { if (empty()) @@ -471,7 +404,6 @@ public: protected: - /** Retains all the objects in the vector */ void addRefForAllObjects() { std::for_each(_data.begin(), _data.end(), [](T obj){ From 1e9c763b400fb0556ea5053224f179d465818793 Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 12 Dec 2013 12:07:20 +0800 Subject: [PATCH 74/98] use ssize_t for index and capacity --- cocos/2d/CCActionManager.cpp | 4 +- cocos/2d/CCActionManager.h | 6 +- cocos/2d/CCDirector.cpp | 6 +- cocos/2d/CCNode.cpp | 8 +- cocos/2d/CCNode.h | 8 +- cocos/2d/CCNotificationCenter.cpp | 2 +- cocos/2d/CCParticleBatchNode.cpp | 2 +- cocos/2d/CCParticleBatchNode.h | 2 +- cocos/2d/CCScheduler.cpp | 2 +- cocos/2d/CCSprite.cpp | 2 +- cocos/2d/CCSprite.h | 8 +- cocos/2d/CCSpriteBatchNode.cpp | 34 +++--- cocos/2d/CCSpriteBatchNode.h | 34 +++--- cocos/2d/CCTMXLayer.cpp | 30 ++--- cocos/2d/CCTMXLayer.h | 4 +- cocos/2d/CCTextureAtlas.cpp | 44 +++---- cocos/2d/CCTextureAtlas.h | 42 +++---- cocos/2d/CCTileMapAtlas.cpp | 2 +- cocos/base/CCAutoreleasePool.cpp | 2 +- cocos/base/CCVector.h | 109 +++++++----------- .../cocosbuilder/CCBAnimationManager.cpp | 8 +- .../cocosbuilder/CCNodeLoader.cpp | 8 +- cocos/editor-support/spine/SkeletonJson.cpp | 2 +- cocos/editor-support/spine/extension.cpp | 4 +- cocos/editor-support/spine/extension.h | 2 +- cocos/network/HttpRequest.h | 2 +- cocos/network/HttpResponse.h | 6 +- extensions/GUI/CCScrollView/CCTableView.cpp | 22 ++-- extensions/GUI/CCScrollView/CCTableView.h | 20 ++-- external/json/json_writer.cpp | 2 +- 30 files changed, 202 insertions(+), 225 deletions(-) diff --git a/cocos/2d/CCActionManager.cpp b/cocos/2d/CCActionManager.cpp index 07e721edc3..2fb08fd0bd 100644 --- a/cocos/2d/CCActionManager.cpp +++ b/cocos/2d/CCActionManager.cpp @@ -87,7 +87,7 @@ void ActionManager::actionAllocWithHashElement(tHashElement *element) } -void ActionManager::removeActionAtIndex(int index, tHashElement *element) +void ActionManager::removeActionAtIndex(ssize_t index, tHashElement *element) { Action *action = (Action*)element->actions->arr[index]; @@ -324,7 +324,7 @@ Action* ActionManager::getActionByTag(int tag, const Node *target) const // XXX: Passing "const O *" instead of "const O&" because HASH_FIND_IT requries the address of a pointer // and, it is not possible to get the address of a reference -int ActionManager::getNumberOfRunningActionsInTarget(const Node *target) const +ssize_t ActionManager::getNumberOfRunningActionsInTarget(const Node *target) const { tHashElement *element = NULL; HASH_FIND_PTR(_targets, &target, element); diff --git a/cocos/2d/CCActionManager.h b/cocos/2d/CCActionManager.h index a2fc0dcfb9..0f538e779c 100644 --- a/cocos/2d/CCActionManager.h +++ b/cocos/2d/CCActionManager.h @@ -100,10 +100,10 @@ public: * - If you are running 1 Sequence of 7 actions, it will return 1. * - If you are running 7 Sequences of 2 actions, it will return 7. */ - int getNumberOfRunningActionsInTarget(const Node *target) const; + ssize_t getNumberOfRunningActionsInTarget(const Node *target) const; /** @deprecated use getNumberOfRunningActionsInTarget() instead */ - CC_DEPRECATED_ATTRIBUTE inline int numberOfRunningActionsInTarget(Node *target) const { return getNumberOfRunningActionsInTarget(target); } + CC_DEPRECATED_ATTRIBUTE inline ssize_t numberOfRunningActionsInTarget(Node *target) const { return getNumberOfRunningActionsInTarget(target); } /** Pauses the target: all running actions and newly added actions will be paused. */ @@ -124,7 +124,7 @@ public: protected: // declared in ActionManager.m - void removeActionAtIndex(int index, struct _hashElement *pElement); + void removeActionAtIndex(ssize_t index, struct _hashElement *pElement); void deleteHashElement(struct _hashElement *pElement); void actionAllocWithHashElement(struct _hashElement *pElement); void update(float dt); diff --git a/cocos/2d/CCDirector.cpp b/cocos/2d/CCDirector.cpp index 93ed8b8932..1817371471 100644 --- a/cocos/2d/CCDirector.cpp +++ b/cocos/2d/CCDirector.cpp @@ -595,7 +595,7 @@ void Director::replaceScene(Scene *scene) CCASSERT(_runningScene, "Use runWithScene: instead to start the director"); CCASSERT(scene != nullptr, "the scene should not be null"); - int index = _scenesStack.size(); + ssize_t index = _scenesStack.size(); _sendCleanupToScene = true; _scenesStack.replace(index - 1, scene); @@ -618,7 +618,7 @@ void Director::popScene(void) CCASSERT(_runningScene != nullptr, "running scene should not null"); _scenesStack.popBack(); - int c = _scenesStack.size(); + ssize_t c = _scenesStack.size(); if (c == 0) { @@ -639,7 +639,7 @@ void Director::popToRootScene(void) void Director::popToSceneStackLevel(int level) { CCASSERT(_runningScene != nullptr, "A running Scene is needed"); - int c = _scenesStack.size(); + ssize_t c = _scenesStack.size(); // level 0? -> end if (level == 0) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index aafec6fd47..c839d686f6 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -395,7 +395,7 @@ void Node::setPositionY(float y) setPosition(Point(_position.x, y)); } -int Node::getChildrenCount() const +ssize_t Node::getChildrenCount() const { return _children.size(); } @@ -683,7 +683,7 @@ void Node::removeChild(Node* child, bool cleanup /* = true */) return; } - auto index = _children.getIndex(child); + ssize_t index = _children.getIndex(child); if( index != CC_INVALID_INDEX ) this->detachChild( child, index, cleanup ); } @@ -741,7 +741,7 @@ void Node::removeAllChildrenWithCleanup(bool cleanup) } -void Node::detachChild(Node *child, int childIndex, bool doCleanup) +void Node::detachChild(Node *child, ssize_t childIndex, bool doCleanup) { // IMPORTANT: // -1st do onExit @@ -1055,7 +1055,7 @@ Action * Node::getActionByTag(int tag) return _actionManager->getActionByTag(tag, this); } -int Node::getNumberOfRunningActions() const +ssize_t Node::getNumberOfRunningActions() const { return _actionManager->getNumberOfRunningActionsInTarget(this); } diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index 8a82c1bfa3..f93fb77cab 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -620,7 +620,7 @@ public: * * @return The amount of children. */ - int getChildrenCount() const; + ssize_t getChildrenCount() const; /** * Sets the parent node @@ -1041,10 +1041,10 @@ public: * * @return The number of actions that are running plus the ones that are schedule to run */ - int getNumberOfRunningActions() const; + ssize_t getNumberOfRunningActions() const; /** @deprecated Use getNumberOfRunningActions() instead */ - CC_DEPRECATED_ATTRIBUTE int numberOfRunningActions() const { return getNumberOfRunningActions(); }; + CC_DEPRECATED_ATTRIBUTE ssize_t numberOfRunningActions() const { return getNumberOfRunningActions(); }; /// @} end of Actions @@ -1401,7 +1401,7 @@ protected: void insertChild(Node* child, int z); /// Removes a child, call child->onExit(), do cleanup, remove it from children array. - void detachChild(Node *child, int index, bool doCleanup); + void detachChild(Node *child, ssize_t index, bool doCleanup); /// Convert cocos2d coordinates to UI windows coordinate. Point convertToWindowSpace(const Point& nodePoint) const; diff --git a/cocos/2d/CCNotificationCenter.cpp b/cocos/2d/CCNotificationCenter.cpp index 9d412c9a61..cdd5537404 100644 --- a/cocos/2d/CCNotificationCenter.cpp +++ b/cocos/2d/CCNotificationCenter.cpp @@ -143,7 +143,7 @@ int NotificationCenter::removeAllObservers(Object *target) } _observers->removeObjectsInArray(toRemove); - return toRemove->count(); + return static_cast(toRemove->count()); } void NotificationCenter::registerScriptObserver( Object *target, int handler,const char* name) diff --git a/cocos/2d/CCParticleBatchNode.cpp b/cocos/2d/CCParticleBatchNode.cpp index 3f1b3779bd..ce6e248ec7 100644 --- a/cocos/2d/CCParticleBatchNode.cpp +++ b/cocos/2d/CCParticleBatchNode.cpp @@ -412,7 +412,7 @@ void ParticleBatchNode::draw(void) -void ParticleBatchNode::increaseAtlasCapacityTo(int quantity) +void ParticleBatchNode::increaseAtlasCapacityTo(ssize_t quantity) { CCLOG("cocos2d: ParticleBatchNode: resizing TextureAtlas capacity from [%lu] to [%lu].", (long)_textureAtlas->getCapacity(), diff --git a/cocos/2d/CCParticleBatchNode.h b/cocos/2d/CCParticleBatchNode.h index 9f1a22b2ac..e8b75a3b70 100644 --- a/cocos/2d/CCParticleBatchNode.h +++ b/cocos/2d/CCParticleBatchNode.h @@ -129,7 +129,7 @@ public: private: void updateAllAtlasIndexes(); - void increaseAtlasCapacityTo(int quantity); + void increaseAtlasCapacityTo(ssize_t quantity); int searchNewPositionInChildrenForZ(int z); void getCurrentIndex(int* oldIndex, int* newIndex, Node* child, int z); int addChildHelper(ParticleSystem* child, int z, int aTag); diff --git a/cocos/2d/CCScheduler.cpp b/cocos/2d/CCScheduler.cpp index 5566c3f292..064e13b058 100644 --- a/cocos/2d/CCScheduler.cpp +++ b/cocos/2d/CCScheduler.cpp @@ -677,7 +677,7 @@ unsigned int Scheduler::scheduleScriptFunc(unsigned int handler, float interval, void Scheduler::unscheduleScriptEntry(unsigned int scheduleScriptEntryID) { - for (int i = _scriptHandlerEntries.size() - 1; i >= 0; i--) + for (ssize_t i = _scriptHandlerEntries.size() - 1; i >= 0; i--) { SchedulerScriptHandlerEntry* entry = _scriptHandlerEntries.at(i); if (entry->getEntryId() == (int)scheduleScriptEntryID) diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index 824af33470..d79d9d1bcd 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -1052,7 +1052,7 @@ void Sprite::setSpriteFrame(SpriteFrame *spriteFrame) setTextureRect(spriteFrame->getRect(), _rectRotated, spriteFrame->getOriginalSize()); } -void Sprite::setDisplayFrameWithAnimationName(const std::string& animationName, int frameIndex) +void Sprite::setDisplayFrameWithAnimationName(const std::string& animationName, ssize_t frameIndex) { CCASSERT(animationName.size()>0, "CCSprite#setDisplayFrameWithAnimationName. animationName must not be NULL"); diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index a78a120589..f61c319756 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -257,7 +257,7 @@ public: * Changes the display frame with animation name and index. * The animation name will be get from the AnimationCache */ - virtual void setDisplayFrameWithAnimationName(const std::string& animationName, int frameIndex); + virtual void setDisplayFrameWithAnimationName(const std::string& animationName, ssize_t frameIndex); /// @} @@ -291,13 +291,13 @@ public: /** * Returns the index used on the TextureAtlas. */ - inline int getAtlasIndex(void) const { return _atlasIndex; } + inline ssize_t getAtlasIndex(void) const { return _atlasIndex; } /** * Sets the index used on the TextureAtlas. * @warning Don't modify this value unless you know what you are doing */ - inline void setAtlasIndex(int atlasIndex) { _atlasIndex = atlasIndex; } + inline void setAtlasIndex(ssize_t atlasIndex) { _atlasIndex = atlasIndex; } /** * Returns the rect of the Sprite in points @@ -535,7 +535,7 @@ protected: // Data used when the sprite is rendered using a SpriteSheet // TextureAtlas* _textureAtlas; /// SpriteBatchNode texture atlas (weak reference) - int _atlasIndex; /// Absolute (real) Index on the SpriteSheet + ssize_t _atlasIndex; /// Absolute (real) Index on the SpriteSheet SpriteBatchNode* _batchNode; /// Used batch node (weak reference) bool _dirty; /// Whether the sprite needs to be updated diff --git a/cocos/2d/CCSpriteBatchNode.cpp b/cocos/2d/CCSpriteBatchNode.cpp index 748a248f58..edeb84747e 100644 --- a/cocos/2d/CCSpriteBatchNode.cpp +++ b/cocos/2d/CCSpriteBatchNode.cpp @@ -51,7 +51,7 @@ NS_CC_BEGIN * creation with Texture2D */ -SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, int capacity/* = DEFAULT_CAPACITY*/) +SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, ssize_t capacity/* = DEFAULT_CAPACITY*/) { SpriteBatchNode *batchNode = new SpriteBatchNode(); batchNode->initWithTexture(tex, capacity); @@ -64,7 +64,7 @@ SpriteBatchNode* SpriteBatchNode::createWithTexture(Texture2D* tex, int capacity * creation with File Image */ -SpriteBatchNode* SpriteBatchNode::create(const char *fileImage, int capacity/* = DEFAULT_CAPACITY*/) +SpriteBatchNode* SpriteBatchNode::create(const char *fileImage, ssize_t capacity/* = DEFAULT_CAPACITY*/) { SpriteBatchNode *batchNode = new SpriteBatchNode(); batchNode->initWithFile(fileImage, capacity); @@ -76,7 +76,7 @@ SpriteBatchNode* SpriteBatchNode::create(const char *fileImage, int capacity/* = /* * init with Texture2D */ -bool SpriteBatchNode::initWithTexture(Texture2D *tex, int capacity) +bool SpriteBatchNode::initWithTexture(Texture2D *tex, ssize_t capacity) { CCASSERT(capacity>=0, "Capacity must be >= 0"); @@ -110,7 +110,7 @@ bool SpriteBatchNode::init() /* * init with FileImage */ -bool SpriteBatchNode::initWithFile(const char* fileImage, int capacity) +bool SpriteBatchNode::initWithFile(const char* fileImage, ssize_t capacity) { Texture2D *texture2D = Director::getInstance()->getTextureCache()->addImage(fileImage); return initWithTexture(texture2D, capacity); @@ -215,7 +215,7 @@ void SpriteBatchNode::removeChild(Node *child, bool cleanup) Node::removeChild(sprite, cleanup); } -void SpriteBatchNode::removeChildAtIndex(int index, bool doCleanup) +void SpriteBatchNode::removeChildAtIndex(ssize_t index, bool doCleanup) { CCASSERT(index>=0 && index < _children.size(), "Invalid index"); removeChild(_children.at(index), doCleanup); @@ -274,7 +274,7 @@ void SpriteBatchNode::sortAllChildren() child->sortAllChildren(); }); - int index=0; + ssize_t index=0; //fast dispatch, give every child a new atlasIndex based on their relative zOrder (keep parent -> child relations intact) // and at the same time reorder descendants and the quads to the right index @@ -288,12 +288,12 @@ void SpriteBatchNode::sortAllChildren() } } -void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex) +void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, ssize_t* curIndex) { auto& array = sprite->getChildren(); auto count = array.size(); - int oldIndex = 0; + ssize_t oldIndex = 0; if( count == 0 ) { @@ -354,7 +354,7 @@ void SpriteBatchNode::updateAtlasIndex(Sprite* sprite, int* curIndex) } } -void SpriteBatchNode::swap(int oldIndex, int newIndex) +void SpriteBatchNode::swap(ssize_t oldIndex, ssize_t newIndex) { CCASSERT(oldIndex>=0 && oldIndex < (int)_descendants.size() && newIndex >=0 && newIndex < (int)_descendants.size(), "Invalid index"); @@ -406,9 +406,9 @@ void SpriteBatchNode::increaseAtlasCapacity(void) // if we're going beyond the current TextureAtlas's capacity, // all the previously initialized sprites will need to redo their texture coords // this is likely computationally expensive - int quantity = (_textureAtlas->getCapacity() + 1) * 4 / 3; + ssize_t quantity = (_textureAtlas->getCapacity() + 1) * 4 / 3; - CCLOG("cocos2d: SpriteBatchNode: resizing TextureAtlas capacity from [%d] to [%d].", + CCLOG("cocos2d: SpriteBatchNode: resizing TextureAtlas capacity from [%zd] to [%zd].", _textureAtlas->getCapacity(), quantity); @@ -420,7 +420,7 @@ void SpriteBatchNode::increaseAtlasCapacity(void) } } -int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index) +ssize_t SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, ssize_t index) { CCASSERT(index>=0 && index < _children.size(), "Invalid index"); @@ -452,7 +452,7 @@ int SpriteBatchNode::rebuildIndexInOrder(Sprite *parent, int index) return index; } -int SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite) +ssize_t SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite) { auto& children = sprite->getChildren(); @@ -466,7 +466,7 @@ int SpriteBatchNode::highestAtlasIndexInChild(Sprite *sprite) } } -int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite) +ssize_t SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite) { auto& children = sprite->getChildren(); @@ -480,7 +480,7 @@ int SpriteBatchNode::lowestAtlasIndexInChild(Sprite *sprite) } } -int SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ) +ssize_t SpriteBatchNode::atlasIndexForChild(Sprite *sprite, int nZ) { auto& siblings = sprite->getParent()->getChildren(); auto childIndex = siblings.getIndex(sprite); @@ -627,7 +627,7 @@ void SpriteBatchNode::setTexture(Texture2D *texture) // SpriteSheet Extension //implementation SpriteSheet (TMXTiledMapExtension) -void SpriteBatchNode::insertQuadFromSprite(Sprite *sprite, int index) +void SpriteBatchNode::insertQuadFromSprite(Sprite *sprite, ssize_t index) { CCASSERT( sprite != NULL, "Argument must be non-NULL"); CCASSERT( dynamic_cast(sprite), "CCSpriteBatchNode only supports Sprites as children"); @@ -652,7 +652,7 @@ void SpriteBatchNode::insertQuadFromSprite(Sprite *sprite, int index) sprite->updateTransform(); } -void SpriteBatchNode::updateQuadFromSprite(Sprite *sprite, int index) +void SpriteBatchNode::updateQuadFromSprite(Sprite *sprite, ssize_t index) { CCASSERT(sprite != NULL, "Argument must be non-nil"); CCASSERT(dynamic_cast(sprite) != NULL, "CCSpriteBatchNode only supports Sprites as children"); diff --git a/cocos/2d/CCSpriteBatchNode.h b/cocos/2d/CCSpriteBatchNode.h index 6ba402fe57..28c548e948 100644 --- a/cocos/2d/CCSpriteBatchNode.h +++ b/cocos/2d/CCSpriteBatchNode.h @@ -68,13 +68,13 @@ public: /** creates a SpriteBatchNode with a texture2d and capacity of children. The capacity will be increased in 33% in runtime if it run out of space. */ - static SpriteBatchNode* createWithTexture(Texture2D* tex, int capacity = DEFAULT_CAPACITY); + static SpriteBatchNode* createWithTexture(Texture2D* tex, ssize_t capacity = DEFAULT_CAPACITY); /** creates a SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and capacity of children. The capacity will be increased in 33% in runtime if it run out of space. The file will be loaded using the TextureMgr. */ - static SpriteBatchNode* create(const char* fileImage, int capacity = DEFAULT_CAPACITY); + static SpriteBatchNode* create(const char* fileImage, ssize_t capacity = DEFAULT_CAPACITY); /** * @js ctor */ @@ -88,14 +88,14 @@ public: /** initializes a SpriteBatchNode with a texture2d and capacity of children. The capacity will be increased in 33% in runtime if it run out of space. */ - bool initWithTexture(Texture2D *tex, int capacity); + bool initWithTexture(Texture2D *tex, ssize_t capacity); /** initializes a SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children. The capacity will be increased in 33% in runtime if it run out of space. The file will be loaded using the TextureMgr. * @js init * @lua init */ - bool initWithFile(const char* fileImage, int capacity); + bool initWithFile(const char* fileImage, ssize_t capacity); bool init(); /** returns the TextureAtlas object */ @@ -121,15 +121,15 @@ public: /** removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter. @warning Removing a child from a SpriteBatchNode is very slow */ - void removeChildAtIndex(int index, bool doCleanup); + void removeChildAtIndex(ssize_t index, bool doCleanup); void appendChild(Sprite* sprite); void removeSpriteFromAtlas(Sprite *sprite); - int rebuildIndexInOrder(Sprite *parent, int index); - int highestAtlasIndexInChild(Sprite *sprite); - int lowestAtlasIndexInChild(Sprite *sprite); - int atlasIndexForChild(Sprite *sprite, int z); + ssize_t rebuildIndexInOrder(Sprite *parent, ssize_t index); + ssize_t highestAtlasIndexInChild(Sprite *sprite); + ssize_t lowestAtlasIndexInChild(Sprite *sprite); + ssize_t atlasIndexForChild(Sprite *sprite, int z); /* Sprites use this to start sortChildren, don't call this manually */ void reorderBatch(bool reorder); @@ -137,7 +137,7 @@ public: // Overrides // // TextureProtocol - virtual Texture2D* getTexture(void) const override; + virtual Texture2D* getTexture() const override; virtual void setTexture(Texture2D *texture) override; /** *@code @@ -151,9 +151,9 @@ public: * @js NA * @lua NA */ - virtual const BlendFunc& getBlendFunc(void) const override; + virtual const BlendFunc& getBlendFunc() const override; - virtual void visit(void) override; + virtual void visit() override; virtual void addChild(Node* child) override{ Node::addChild(child);} virtual void addChild(Node * child, int zOrder) override { Node::addChild(child, zOrder);} virtual void addChild(Node * child, int zOrder, int tag) override; @@ -162,26 +162,26 @@ public: virtual void removeChild(Node *child, bool cleanup) override; virtual void removeAllChildrenWithCleanup(bool cleanup) override; virtual void sortAllChildren() override; - virtual void draw(void) override; + virtual void draw() override; protected: /** Inserts a quad at a certain index into the texture atlas. The Sprite won't be added into the children array. This method should be called only when you are dealing with very big AtlasSrite and when most of the Sprite won't be updated. For example: a tile map (TMXMap) or a label with lots of characters (LabelBMFont) */ - void insertQuadFromSprite(Sprite *sprite, int index); + void insertQuadFromSprite(Sprite *sprite, ssize_t index); /** Updates a quad at a certain index into the texture atlas. The Sprite won't be added into the children array. This method should be called only when you are dealing with very big AtlasSrite and when most of the Sprite won't be updated. For example: a tile map (TMXMap) or a label with lots of characters (LabelBMFont) */ - void updateQuadFromSprite(Sprite *sprite, int index); + void updateQuadFromSprite(Sprite *sprite, ssize_t index); /* This is the opposite of "addQuadFromSprite. It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas */ SpriteBatchNode * addSpriteWithoutQuad(Sprite *child, int z, int aTag); - void updateAtlasIndex(Sprite* sprite, int* curIndex); - void swap(int oldIndex, int newIndex); + void updateAtlasIndex(Sprite* sprite, ssize_t* curIndex); + void swap(ssize_t oldIndex, ssize_t newIndex); void updateBlendFunc(); TextureAtlas *_textureAtlas; diff --git a/cocos/2d/CCTMXLayer.cpp b/cocos/2d/CCTMXLayer.cpp index 8515989a6f..fb178a3d55 100644 --- a/cocos/2d/CCTMXLayer.cpp +++ b/cocos/2d/CCTMXLayer.cpp @@ -340,8 +340,8 @@ Sprite * TMXLayer::getTileAt(const Point& pos) tile->setAnchorPoint(Point::ZERO); tile->setOpacity(_opacity); - unsigned int indexForZ = atlasIndexForExistantZ(z); - this->addSpriteWithoutQuad(tile, indexForZ, z); + ssize_t indexForZ = atlasIndexForExistantZ(z); + this->addSpriteWithoutQuad(tile, static_cast(indexForZ), z); } } @@ -379,7 +379,7 @@ Sprite * TMXLayer::insertTileForGID(unsigned int gid, const Point& pos) setupTileSprite(tile, pos, gid); // get atlas index - unsigned int indexForZ = atlasIndexForNewZ(static_cast(z)); + ssize_t indexForZ = atlasIndexForNewZ(static_cast(z)); // Optimization: add the quad without adding a child this->insertQuadFromSprite(tile, indexForZ); @@ -393,7 +393,7 @@ Sprite * TMXLayer::insertTileForGID(unsigned int gid, const Point& pos) Sprite* sp = static_cast(child); if (child) { - int ai = sp->getAtlasIndex(); + ssize_t ai = sp->getAtlasIndex(); if ( ai >= indexForZ ) { sp->setAtlasIndex(ai+1); @@ -416,7 +416,7 @@ Sprite * TMXLayer::updateTileForGID(unsigned int gid, const Point& pos) setupTileSprite(tile ,pos ,gid); // get atlas index - unsigned int indexForZ = atlasIndexForExistantZ(z); + ssize_t indexForZ = atlasIndexForExistantZ(z); tile->setAtlasIndex(indexForZ); tile->setDirty(true); tile->updateTransform(); @@ -441,7 +441,7 @@ Sprite * TMXLayer::appendTileForGID(unsigned int gid, const Point& pos) // optimization: // The difference between appendTileForGID and insertTileforGID is that append is faster, since // it appends the tile at the end of the texture atlas - unsigned int indexForZ = _atlasIndexArray->num; + ssize_t indexForZ = _atlasIndexArray->num; // don't add it using the "standard" way. insertQuadFromSprite(tile, indexForZ); @@ -458,24 +458,24 @@ static inline int compareInts(const void * a, const void * b) return ((*(int*)a) - (*(int*)b)); } -unsigned int TMXLayer::atlasIndexForExistantZ(unsigned int z) +ssize_t TMXLayer::atlasIndexForExistantZ(unsigned int z) { int key=z; int *item = (int*)bsearch((void*)&key, (void*)&_atlasIndexArray->arr[0], _atlasIndexArray->num, sizeof(void*), compareInts); CCASSERT(item, "TMX atlas index not found. Shall not happen"); - int index = ((size_t)item - (size_t)_atlasIndexArray->arr) / sizeof(void*); + ssize_t index = ((size_t)item - (size_t)_atlasIndexArray->arr) / sizeof(void*); return index; } -unsigned int TMXLayer::atlasIndexForNewZ(int z) +ssize_t TMXLayer::atlasIndexForNewZ(int z) { // XXX: This can be improved with a sort of binary search - int i=0; + ssize_t i=0; for (i=0; i< _atlasIndexArray->num ; i++) { - int val = (size_t) _atlasIndexArray->arr[i]; + ssize_t val = (size_t) _atlasIndexArray->arr[i]; if (z < val) { break; @@ -558,8 +558,8 @@ void TMXLayer::removeChild(Node* node, bool cleanup) CCASSERT(_children.contains(sprite), "Tile does not belong to TMXLayer"); - unsigned int atlasIndex = sprite->getAtlasIndex(); - unsigned int zz = (size_t)_atlasIndexArray->arr[atlasIndex]; + ssize_t atlasIndex = sprite->getAtlasIndex(); + ssize_t zz = (size_t)_atlasIndexArray->arr[atlasIndex]; _tiles[zz] = 0; ccCArrayRemoveValueAtIndex(_atlasIndexArray, atlasIndex); SpriteBatchNode::removeChild(sprite, cleanup); @@ -575,7 +575,7 @@ void TMXLayer::removeTileAt(const Point& pos) if (gid) { unsigned int z = (unsigned int)(pos.x + pos.y * _layerSize.width); - unsigned int atlasIndex = atlasIndexForExistantZ(z); + ssize_t atlasIndex = atlasIndexForExistantZ(z); // remove tile from GID map _tiles[z] = 0; @@ -598,7 +598,7 @@ void TMXLayer::removeTileAt(const Point& pos) Sprite* child = static_cast(obj); if (child) { - unsigned int ai = child->getAtlasIndex(); + ssize_t ai = child->getAtlasIndex(); if ( ai >= atlasIndex ) { child->setAtlasIndex(ai-1); diff --git a/cocos/2d/CCTMXLayer.h b/cocos/2d/CCTMXLayer.h index 2667739599..b0bea3f991 100644 --- a/cocos/2d/CCTMXLayer.h +++ b/cocos/2d/CCTMXLayer.h @@ -209,8 +209,8 @@ private: int getVertexZForPos(const Point& pos); // index - unsigned int atlasIndexForExistantZ(unsigned int z); - unsigned int atlasIndexForNewZ(int z); + ssize_t atlasIndexForExistantZ(unsigned int z); + ssize_t atlasIndexForNewZ(int z); protected: //! name of the layer diff --git a/cocos/2d/CCTextureAtlas.cpp b/cocos/2d/CCTextureAtlas.cpp index 1a325d248b..3bf4f994e1 100644 --- a/cocos/2d/CCTextureAtlas.cpp +++ b/cocos/2d/CCTextureAtlas.cpp @@ -74,12 +74,12 @@ TextureAtlas::~TextureAtlas() #endif } -int TextureAtlas::getTotalQuads() const +ssize_t TextureAtlas::getTotalQuads() const { return _totalQuads; } -int TextureAtlas::getCapacity() const +ssize_t TextureAtlas::getCapacity() const { return _capacity; } @@ -110,7 +110,7 @@ void TextureAtlas::setQuads(V3F_C4B_T2F_Quad* quads) // TextureAtlas - alloc & init -TextureAtlas * TextureAtlas::create(const char* file, int capacity) +TextureAtlas * TextureAtlas::create(const char* file, ssize_t capacity) { TextureAtlas * textureAtlas = new TextureAtlas(); if(textureAtlas && textureAtlas->initWithFile(file, capacity)) @@ -122,7 +122,7 @@ TextureAtlas * TextureAtlas::create(const char* file, int capacity) return NULL; } -TextureAtlas * TextureAtlas::createWithTexture(Texture2D *texture, int capacity) +TextureAtlas * TextureAtlas::createWithTexture(Texture2D *texture, ssize_t capacity) { TextureAtlas * textureAtlas = new TextureAtlas(); if (textureAtlas && textureAtlas->initWithTexture(texture, capacity)) @@ -134,7 +134,7 @@ TextureAtlas * TextureAtlas::createWithTexture(Texture2D *texture, int capacity) return NULL; } -bool TextureAtlas::initWithFile(const char * file, int capacity) +bool TextureAtlas::initWithFile(const char * file, ssize_t capacity) { // retained in property Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(file); @@ -150,7 +150,7 @@ bool TextureAtlas::initWithFile(const char * file, int capacity) } } -bool TextureAtlas::initWithTexture(Texture2D *texture, int capacity) +bool TextureAtlas::initWithTexture(Texture2D *texture, ssize_t capacity) { CCASSERT(capacity>=0, "Capacity must be >= 0"); @@ -224,7 +224,7 @@ void TextureAtlas::listenBackToForeground(Object *obj) const char* TextureAtlas::description() const { - return String::createWithFormat("", _totalQuads)->getCString(); + return String::createWithFormat("", _totalQuads)->getCString(); } @@ -317,7 +317,7 @@ void TextureAtlas::mapBuffers() // TextureAtlas - Update, Insert, Move & Remove -void TextureAtlas::updateQuad(V3F_C4B_T2F_Quad *quad, int index) +void TextureAtlas::updateQuad(V3F_C4B_T2F_Quad *quad, ssize_t index) { CCASSERT( index >= 0 && index < _capacity, "updateQuadWithTexture: Invalid index"); @@ -330,7 +330,7 @@ void TextureAtlas::updateQuad(V3F_C4B_T2F_Quad *quad, int index) } -void TextureAtlas::insertQuad(V3F_C4B_T2F_Quad *quad, int index) +void TextureAtlas::insertQuad(V3F_C4B_T2F_Quad *quad, ssize_t index) { CCASSERT( index>=0 && index<_capacity, "insertQuadWithTexture: Invalid index"); @@ -354,7 +354,7 @@ void TextureAtlas::insertQuad(V3F_C4B_T2F_Quad *quad, int index) } -void TextureAtlas::insertQuads(V3F_C4B_T2F_Quad* quads, int index, int amount) +void TextureAtlas::insertQuads(V3F_C4B_T2F_Quad* quads, ssize_t index, ssize_t amount) { CCASSERT(index>=0 && amount>=0 && index+amount<=_capacity, "insertQuadWithTexture: Invalid index + amount"); @@ -375,7 +375,7 @@ void TextureAtlas::insertQuads(V3F_C4B_T2F_Quad* quads, int index, int amount) auto max = index + amount; int j = 0; - for (int i = index; i < max ; i++) + for (ssize_t i = index; i < max ; i++) { _quads[index] = quads[j]; index++; @@ -385,7 +385,7 @@ void TextureAtlas::insertQuads(V3F_C4B_T2F_Quad* quads, int index, int amount) _dirty = true; } -void TextureAtlas::insertQuadFromIndex(int oldIndex, int newIndex) +void TextureAtlas::insertQuadFromIndex(ssize_t oldIndex, ssize_t newIndex) { CCASSERT( newIndex >= 0 && newIndex < _totalQuads, "insertQuadFromIndex:atIndex: Invalid index"); CCASSERT( oldIndex >= 0 && oldIndex < _totalQuads, "insertQuadFromIndex:atIndex: Invalid index"); @@ -414,7 +414,7 @@ void TextureAtlas::insertQuadFromIndex(int oldIndex, int newIndex) _dirty = true; } -void TextureAtlas::removeQuadAtIndex(int index) +void TextureAtlas::removeQuadAtIndex(ssize_t index) { CCASSERT( index>=0 && index<_totalQuads, "removeQuadAtIndex: Invalid index"); @@ -433,7 +433,7 @@ void TextureAtlas::removeQuadAtIndex(int index) _dirty = true; } -void TextureAtlas::removeQuadsAtIndex(int index, int amount) +void TextureAtlas::removeQuadsAtIndex(ssize_t index, ssize_t amount) { CCASSERT(index>=0 && amount>=0 && index+amount<=_totalQuads, "removeQuadAtIndex: index + amount out of bounds"); @@ -455,7 +455,7 @@ void TextureAtlas::removeAllQuads() } // TextureAtlas - Resize -bool TextureAtlas::resizeCapacity(int newCapacity) +bool TextureAtlas::resizeCapacity(ssize_t newCapacity) { CCASSERT(newCapacity>=0, "capacity >= 0"); if( newCapacity == _capacity ) @@ -529,13 +529,13 @@ bool TextureAtlas::resizeCapacity(int newCapacity) return true; } -void TextureAtlas::increaseTotalQuadsWith(int amount) +void TextureAtlas::increaseTotalQuadsWith(ssize_t amount) { CCASSERT(amount>=0, "amount >= 0"); _totalQuads += amount; } -void TextureAtlas::moveQuadsFromIndex(int oldIndex, int amount, int newIndex) +void TextureAtlas::moveQuadsFromIndex(ssize_t oldIndex, ssize_t amount, ssize_t newIndex) { CCASSERT(oldIndex>=0 && amount>=0 && newIndex>=0, "values must be >= 0"); CCASSERT(newIndex + amount <= _totalQuads, "insertQuadFromIndex:atIndex: Invalid index"); @@ -567,7 +567,7 @@ void TextureAtlas::moveQuadsFromIndex(int oldIndex, int amount, int newIndex) _dirty = true; } -void TextureAtlas::moveQuadsFromIndex(int index, int newIndex) +void TextureAtlas::moveQuadsFromIndex(ssize_t index, ssize_t newIndex) { CCASSERT(index>=0 && newIndex>=0, "values must be >= 0"); CCASSERT(newIndex + (_totalQuads - index) <= _capacity, "moveQuadsFromIndex move is out of bounds"); @@ -575,14 +575,14 @@ void TextureAtlas::moveQuadsFromIndex(int index, int newIndex) memmove(_quads + newIndex,_quads + index, (_totalQuads - index) * sizeof(_quads[0])); } -void TextureAtlas::fillWithEmptyQuadsFromIndex(int index, int amount) +void TextureAtlas::fillWithEmptyQuadsFromIndex(ssize_t index, ssize_t amount) { CCASSERT(index>=0 && amount>=0, "values must be >= 0"); V3F_C4B_T2F_Quad quad; memset(&quad, 0, sizeof(quad)); auto to = index + amount; - for (int i = index ; i < to ; i++) + for (ssize_t i = index ; i < to ; i++) { _quads[i] = quad; } @@ -595,13 +595,13 @@ void TextureAtlas::drawQuads() this->drawNumberOfQuads(_totalQuads, 0); } -void TextureAtlas::drawNumberOfQuads(int numberOfQuads) +void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads) { CCASSERT(numberOfQuads>=0, "numberOfQuads must be >= 0"); this->drawNumberOfQuads(numberOfQuads, 0); } -void TextureAtlas::drawNumberOfQuads(int numberOfQuads, int start) +void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start) { CCASSERT(numberOfQuads>=0 && start>=0, "numberOfQuads and start must be >= 0"); diff --git a/cocos/2d/CCTextureAtlas.h b/cocos/2d/CCTextureAtlas.h index 47a5c1c484..40b32d8273 100644 --- a/cocos/2d/CCTextureAtlas.h +++ b/cocos/2d/CCTextureAtlas.h @@ -59,13 +59,13 @@ public: /** creates a TextureAtlas with an filename and with an initial capacity for Quads. * The TextureAtlas capacity can be increased in runtime. */ - static TextureAtlas* create(const char* file , int capacity); + static TextureAtlas* create(const char* file , ssize_t capacity); /** creates a TextureAtlas with a previously initialized Texture2D object, and * with an initial capacity for n Quads. * The TextureAtlas capacity can be increased in runtime. */ - static TextureAtlas* createWithTexture(Texture2D *texture, int capacity); + static TextureAtlas* createWithTexture(Texture2D *texture, ssize_t capacity); /** * @js ctor */ @@ -81,7 +81,7 @@ public: * * WARNING: Do not reinitialize the TextureAtlas because it will leak memory (issue #706) */ - bool initWithFile(const char* file, int capacity); + bool initWithFile(const char* file, ssize_t capacity); /** initializes a TextureAtlas with a previously initialized Texture2D object, and * with an initial capacity for Quads. @@ -89,43 +89,43 @@ public: * * WARNING: Do not reinitialize the TextureAtlas because it will leak memory (issue #706) */ - bool initWithTexture(Texture2D *texture, int capacity); + bool initWithTexture(Texture2D *texture, ssize_t capacity); /** updates a Quad (texture, vertex and color) at a certain index * index must be between 0 and the atlas capacity - 1 @since v0.8 */ - void updateQuad(V3F_C4B_T2F_Quad* quad, int index); + void updateQuad(V3F_C4B_T2F_Quad* quad, ssize_t index); /** Inserts a Quad (texture, vertex and color) at a certain index index must be between 0 and the atlas capacity - 1 @since v0.8 */ - void insertQuad(V3F_C4B_T2F_Quad* quad, int index); + void insertQuad(V3F_C4B_T2F_Quad* quad, ssize_t index); /** Inserts a c array of quads at a given index index must be between 0 and the atlas capacity - 1 this method doesn't enlarge the array when amount + index > totalQuads @since v1.1 */ - void insertQuads(V3F_C4B_T2F_Quad* quads, int index, int amount); + void insertQuads(V3F_C4B_T2F_Quad* quads, ssize_t index, ssize_t amount); /** Removes the quad that is located at a certain index and inserts it at a new index This operation is faster than removing and inserting in a quad in 2 different steps @since v0.7.2 */ - void insertQuadFromIndex(int fromIndex, int newIndex); + void insertQuadFromIndex(ssize_t fromIndex, ssize_t newIndex); /** removes a quad at a given index number. The capacity remains the same, but the total number of quads to be drawn is reduced in 1 @since v0.7.2 */ - void removeQuadAtIndex(int index); + void removeQuadAtIndex(ssize_t index); /** removes a amount of quads starting from index @since 1.1 */ - void removeQuadsAtIndex(int index, int amount); + void removeQuadsAtIndex(ssize_t index, ssize_t amount); /** removes all Quads. The TextureAtlas capacity remains untouched. No memory is freed. The total number of quads to be drawn will be 0 @@ -138,19 +138,19 @@ public: * It returns true if the resize was successful. * If it fails to resize the capacity it will return false with a new capacity of 0. */ - bool resizeCapacity(int capacity); + bool resizeCapacity(ssize_t capacity); /** Used internally by ParticleBatchNode don't use this unless you know what you're doing @since 1.1 */ - void increaseTotalQuadsWith(int amount); + void increaseTotalQuadsWith(ssize_t amount); /** Moves an amount of quads from oldIndex at newIndex @since v1.1 */ - void moveQuadsFromIndex(int oldIndex, int amount, int newIndex); + void moveQuadsFromIndex(ssize_t oldIndex, ssize_t amount, ssize_t newIndex); /** Moves quads from index till totalQuads to the newIndex @@ -158,26 +158,26 @@ public: This method doesn't enlarge the array if newIndex + quads to be moved > capacity @since 1.1 */ - void moveQuadsFromIndex(int index, int newIndex); + void moveQuadsFromIndex(ssize_t index, ssize_t newIndex); /** Ensures that after a realloc quads are still empty Used internally by ParticleBatchNode @since 1.1 */ - void fillWithEmptyQuadsFromIndex(int index, int amount); + void fillWithEmptyQuadsFromIndex(ssize_t index, ssize_t amount); /** draws n quads * n can't be greater than the capacity of the Atlas */ - void drawNumberOfQuads(int n); + void drawNumberOfQuads(ssize_t n); /** draws n quads from an index (offset). n + start can't be greater than the capacity of the atlas @since v1.0 */ - void drawNumberOfQuads(int numberOfQuads, int start); + void drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start); /** draws all the Atlas's Quads */ @@ -197,10 +197,10 @@ public: const char* description() const; /** Gets the quantity of quads that are going to be drawn */ - int getTotalQuads() const; + ssize_t getTotalQuads() const; /** Gets the quantity of quads that can be stored with the current texture atlas size */ - int getCapacity() const; + ssize_t getCapacity() const; /** Gets the texture of the texture atlas */ Texture2D* getTexture() const; @@ -226,9 +226,9 @@ protected: GLuint _buffersVBO[2]; //0: vertex 1: indices bool _dirty; //indicates whether or not the array buffer of the VBO needs to be updated /** quantity of quads that are going to be drawn */ - int _totalQuads; + ssize_t _totalQuads; /** quantity of quads that can be stored with the current texture atlas size */ - int _capacity; + ssize_t _capacity; /** Texture of the texture atlas */ Texture2D* _texture; /** Quads that are going to be rendered */ diff --git a/cocos/2d/CCTileMapAtlas.cpp b/cocos/2d/CCTileMapAtlas.cpp index 001a2aca6d..49add06d73 100644 --- a/cocos/2d/CCTileMapAtlas.cpp +++ b/cocos/2d/CCTileMapAtlas.cpp @@ -222,7 +222,7 @@ void TileMapAtlas::updateAtlasValueAt(const Point& pos, const Color3B& value, in quad->bl.colors = color; _textureAtlas->setDirty(true); - int totalQuads = _textureAtlas->getTotalQuads(); + ssize_t totalQuads = _textureAtlas->getTotalQuads(); if (index + 1 > totalQuads) { _textureAtlas->increaseTotalQuadsWith(index + 1 - totalQuads); } diff --git a/cocos/base/CCAutoreleasePool.cpp b/cocos/base/CCAutoreleasePool.cpp index 01f65a7d3a..f1619b3746 100644 --- a/cocos/base/CCAutoreleasePool.cpp +++ b/cocos/base/CCAutoreleasePool.cpp @@ -141,7 +141,7 @@ void PoolManager::pop() return; } - int count = _releasePoolStack.size(); + ssize_t count = _releasePoolStack.size(); _curReleasePool->clear(); diff --git a/cocos/base/CCVector.h b/cocos/base/CCVector.h index 5ae654c8b8..dfe5ef4b88 100644 --- a/cocos/base/CCVector.h +++ b/cocos/base/CCVector.h @@ -37,34 +37,6 @@ template class CC_DLL Vector { public: - // ------------------------------------------ - // Iterators - // ------------------------------------------ - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - - typedef typename std::vector::reverse_iterator reverse_iterator; - typedef typename std::vector::const_reverse_iterator const_reverse_iterator; - - iterator begin() { return _data.begin(); } - const_iterator begin() const { return _data.begin(); } - - iterator end() { return _data.end(); } - const_iterator end() const { return _data.end(); } - - const_iterator cbegin() const { return _data.cbegin(); } - const_iterator cend() const { return _data.cend(); } - - reverse_iterator rbegin() { return _data.rbegin(); } - const_reverse_iterator rbegin() const { return _data.rbegin(); } - - reverse_iterator rend() { return _data.rend(); } - const_reverse_iterator rend() const { return _data.rend(); } - - const_reverse_iterator crbegin() const { return _data.crbegin(); } - const_reverse_iterator crend() const { return _data.crend(); } - - /** Constructor */ Vector() : _data() { @@ -133,7 +105,7 @@ public: } /** Returns capacity of the array */ - int capacity() const + ssize_t capacity() const { return _data.capacity(); } @@ -141,9 +113,9 @@ public: // Querying an Array /** Returns element count of the array */ - int size() const + ssize_t size() const { - return static_cast(_data.size()); + return _data.size(); } bool empty() const @@ -154,23 +126,18 @@ public: /** Returns index of a certain object, return UINT_MAX if doesn't contain the object */ ssize_t getIndex(T object) const { - auto iter = std::find(_data.begin(), _data.end(), object); - if (iter != _data.end()) - return iter - _data.begin(); - + ssize_t i = 0; + for (auto it = _data.begin(); it != _data.end(); ++it, ++i) + { + if (*it == object) + { + return i; + } + } + return -1; } - const_iterator find(T object) const - { - return std::find(_data.begin(), _data.end(), object); - } - - iterator find(T object) - { - return std::find(_data.begin(), _data.end(), object); - } - /** Returns an element with a certain index */ T at(ssize_t index) const { @@ -194,7 +161,7 @@ public: { if (!_data.empty()) { - int randIdx = rand() % _data.size(); + ssize_t randIdx = rand() % _data.size(); return *(_data.begin() + randIdx); } return nullptr; @@ -261,9 +228,9 @@ public: _data.pop_back(); last->release(); } - + /** Remove a certain object */ - void erase(T object, bool toRelease = true) + void removeObject(T object, bool toRelease = true) { CCASSERT(object != nullptr, "The object should not be nullptr"); auto iter = std::find(_data.begin(), _data.end(), object); @@ -274,24 +241,7 @@ public: } /** Removes an element with a certain index */ - iterator erase(iterator position) - { - CCASSERT(position >= _data.begin() && position < _data.end(), "Invalid position!"); - (*position)->release(); - return _data.erase(position); - } - - iterator erase(const_iterator first, const_iterator last) - { - for (auto iter = first; iter != last; ++iter) - { - (*iter)->release(); - } - - return _data.erase(first, last); - } - - void erase(int index) + void remove(ssize_t index) { CCASSERT(!_data.empty() && index >=0 && index < size(), "Invalid index!"); auto it = std::next( begin(), index ); @@ -402,6 +352,33 @@ public: }); } + // ------------------------------------------ + // Iterators + // ------------------------------------------ + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; + + typedef typename std::vector::reverse_iterator reverse_iterator; + typedef typename std::vector::const_reverse_iterator const_reverse_iterator; + + iterator begin() { return _data.begin(); } + const_iterator begin() const { return _data.begin(); } + + iterator end() { return _data.end(); } + const_iterator end() const { return _data.end(); } + + const_iterator cbegin() const { return _data.cbegin(); } + const_iterator cend() const { return _data.cend(); } + + reverse_iterator rbegin() { return _data.rbegin(); } + const_reverse_iterator rbegin() const { return _data.rbegin(); } + + reverse_iterator rend() { return _data.rend(); } + const_reverse_iterator rend() const { return _data.rend(); } + + const_reverse_iterator crbegin() const { return _data.crbegin(); } + const_reverse_iterator crend() const { return _data.crend(); } + protected: void addRefForAllObjects() diff --git a/cocos/editor-support/cocosbuilder/CCBAnimationManager.cpp b/cocos/editor-support/cocosbuilder/CCBAnimationManager.cpp index 431e5453c3..b0daa76b77 100644 --- a/cocos/editor-support/cocosbuilder/CCBAnimationManager.cpp +++ b/cocos/editor-support/cocosbuilder/CCBAnimationManager.cpp @@ -623,7 +623,7 @@ Object* CCBAnimationManager::actionForCallbackChannel(CCBSequenceProperty* chann Vector actions; auto& keyframes = channel->getKeyframes(); - int numKeyframes = keyframes.size(); + ssize_t numKeyframes = keyframes.size(); for (long i = 0; i < numKeyframes; ++i) { @@ -712,7 +712,7 @@ Object* CCBAnimationManager::actionForSoundChannel(CCBSequenceProperty* channel) Vector actions; auto& keyframes = channel->getKeyframes(); - int numKeyframes = keyframes.size(); + ssize_t numKeyframes = keyframes.size(); for (int i = 0; i < numKeyframes; ++i) { @@ -753,7 +753,7 @@ Object* CCBAnimationManager::actionForSoundChannel(CCBSequenceProperty* channel) void CCBAnimationManager::runAction(Node *pNode, CCBSequenceProperty *pSeqProp, float fTweenDuration) { auto& keyframes = pSeqProp->getKeyframes(); - int numKeyframes = keyframes.size(); + ssize_t numKeyframes = keyframes.size(); if (numKeyframes > 1) { @@ -768,7 +768,7 @@ void CCBAnimationManager::runAction(Node *pNode, CCBSequenceProperty *pSeqProp, actions.pushBack(DelayTime::create(timeFirst)); } - for (int i = 0; i < numKeyframes - 1; ++i) + for (ssize_t i = 0; i < numKeyframes - 1; ++i) { CCBKeyframe *kf0 = keyframes.at(i); CCBKeyframe *kf1 = keyframes.at(i+1); diff --git a/cocos/editor-support/cocosbuilder/CCNodeLoader.cpp b/cocos/editor-support/cocosbuilder/CCNodeLoader.cpp index 3dceb6b7dc..895aaaf59d 100644 --- a/cocos/editor-support/cocosbuilder/CCNodeLoader.cpp +++ b/cocos/editor-support/cocosbuilder/CCNodeLoader.cpp @@ -970,9 +970,9 @@ Node * NodeLoader::parsePropTypeCCBFile(Node * pNode, Node * pParent, CCBReader if (!ownerCallbackNames.empty() && !ownerCallbackNodes.empty()) { CCASSERT(ownerCallbackNames.size() == ownerCallbackNodes.size(), ""); - int nCount = ownerCallbackNames.size(); + ssize_t nCount = ownerCallbackNames.size(); - for (int i = 0 ; i < nCount; i++) + for (ssize_t i = 0 ; i < nCount; i++) { pCCBReader->addOwnerCallbackName(ownerCallbackNames[i].asString()); pCCBReader->addOwnerCallbackNode(ownerCallbackNodes.at(i)); @@ -984,9 +984,9 @@ Node * NodeLoader::parsePropTypeCCBFile(Node * pNode, Node * pParent, CCBReader if (!ownerOutletNames.empty() && !ownerOutletNodes.empty()) { CCASSERT(ownerOutletNames.size() == ownerOutletNodes.size(), ""); - int nCount = ownerOutletNames.size(); + ssize_t nCount = ownerOutletNames.size(); - for (int i = 0 ; i < nCount; i++) + for (ssize_t i = 0 ; i < nCount; i++) { pCCBReader->addOwnerOutletName(ownerOutletNames.at(i).asString()); pCCBReader->addOwnerOutletNode(ownerOutletNodes.at(i)); diff --git a/cocos/editor-support/spine/SkeletonJson.cpp b/cocos/editor-support/spine/SkeletonJson.cpp index 9b391ef2db..57aff46a6b 100644 --- a/cocos/editor-support/spine/SkeletonJson.cpp +++ b/cocos/editor-support/spine/SkeletonJson.cpp @@ -61,7 +61,7 @@ void SkeletonJson_dispose (SkeletonJson* self) { void _SkeletonJson_setError (SkeletonJson* self, Json* root, const char* value1, const char* value2) { char message[256]; - int length; + size_t length; FREE(self->error); strcpy(message, value1); length = strlen(value1); diff --git a/cocos/editor-support/spine/extension.cpp b/cocos/editor-support/spine/extension.cpp index 3fa34170b9..48477eb7b0 100644 --- a/cocos/editor-support/spine/extension.cpp +++ b/cocos/editor-support/spine/extension.cpp @@ -50,10 +50,10 @@ void _setFree (void (*free) (void* ptr)) { freeFunc = free; } -char* _readFile (const char* path, int* length) { +char* _readFile (const char* path, ssize_t* length) { char *data; FILE *file = fopen(path, "rb"); - int readBytes = 0; + ssize_t readBytes = 0; if (!file) return 0; fseek(file, 0, SEEK_END); diff --git a/cocos/editor-support/spine/extension.h b/cocos/editor-support/spine/extension.h index a8f64b1b19..e07f18eda4 100644 --- a/cocos/editor-support/spine/extension.h +++ b/cocos/editor-support/spine/extension.h @@ -114,7 +114,7 @@ void _free (void* ptr); void _setMalloc (void* (*_malloc) (size_t size)); void _setFree (void (*_free) (void* ptr)); -char* _readFile (const char* path, int* length); +char* _readFile (const char* path, ssize_t* length); /**/ diff --git a/cocos/network/HttpRequest.h b/cocos/network/HttpRequest.h index 4282193043..7264daeba3 100644 --- a/cocos/network/HttpRequest.h +++ b/cocos/network/HttpRequest.h @@ -129,7 +129,7 @@ public: return nullptr; } /** Get the size of request data back */ - inline int getRequestDataSize() + inline ssize_t getRequestDataSize() { return _requestData.size(); } diff --git a/cocos/network/HttpResponse.h b/cocos/network/HttpResponse.h index ac5fb68b2e..9f4bd10028 100644 --- a/cocos/network/HttpResponse.h +++ b/cocos/network/HttpResponse.h @@ -107,7 +107,7 @@ public: /** Get the http response errorCode * I know that you want to see http 200 :) */ - inline int getResponseCode() + inline long getResponseCode() { return _responseCode; } @@ -150,7 +150,7 @@ public: /** Set the http response errorCode */ - inline void setResponseCode(int value) + inline void setResponseCode(long value) { _responseCode = value; } @@ -172,7 +172,7 @@ protected: bool _succeed; /// to indecate if the http reqeust is successful simply std::vector _responseData; /// the returned raw data. You can also dump it as a string std::vector _responseHeader; /// the returned raw header data. You can also dump it as a string - int _responseCode; /// the status code returned from libcurl, e.g. 200, 404 + long _responseCode; /// the status code returned from libcurl, e.g. 200, 404 std::string _errorBuffer; /// if _responseCode != 200, please read _errorBuffer to find the reason }; diff --git a/extensions/GUI/CCScrollView/CCTableView.cpp b/extensions/GUI/CCScrollView/CCTableView.cpp index b74026cd01..3dc65621f8 100644 --- a/extensions/GUI/CCScrollView/CCTableView.cpp +++ b/extensions/GUI/CCScrollView/CCTableView.cpp @@ -123,7 +123,7 @@ void TableView::reloadData() } } -TableViewCell *TableView::cellAtIndex(long idx) +TableViewCell *TableView::cellAtIndex(ssize_t idx) { if (_indices->find(idx) != _indices->end()) { @@ -139,7 +139,7 @@ TableViewCell *TableView::cellAtIndex(long idx) return nullptr; } -void TableView::updateCellAtIndex(long idx) +void TableView::updateCellAtIndex(ssize_t idx) { if (idx == CC_INVALID_INDEX) { @@ -161,7 +161,7 @@ void TableView::updateCellAtIndex(long idx) this->_addCellIfNecessary(cell); } -void TableView::insertCellAtIndex(long idx) +void TableView::insertCellAtIndex(ssize_t idx) { if (idx == CC_INVALID_INDEX) { @@ -197,7 +197,7 @@ void TableView::insertCellAtIndex(long idx) this->_updateContentSize(); } -void TableView::removeCellAtIndex(long idx) +void TableView::removeCellAtIndex(ssize_t idx) { if (idx == CC_INVALID_INDEX) { @@ -210,7 +210,7 @@ void TableView::removeCellAtIndex(long idx) return; } - unsigned int newIdx = 0; + ssize_t newIdx = 0; TableViewCell* cell = this->cellAtIndex(idx); if (!cell) @@ -226,7 +226,7 @@ void TableView::removeCellAtIndex(long idx) _indices->erase(idx); this->_updateCellPositions(); - for (int i = _cellsUsed.size()-1; i > newIdx; i--) + for (ssize_t i = _cellsUsed.size()-1; i > newIdx; i--) { cell = _cellsUsed.at(i); this->_setIndexForCell(cell->getIdx()-1, cell); @@ -262,7 +262,7 @@ void TableView::_addCellIfNecessary(TableViewCell * cell) void TableView::_updateContentSize() { Size size = Size::ZERO; - unsigned int cellsCount = _dataSource->numberOfCellsInTableView(this); + ssize_t cellsCount = _dataSource->numberOfCellsInTableView(this); if (cellsCount > 0) { @@ -296,7 +296,7 @@ void TableView::_updateContentSize() } -Point TableView::_offsetFromIndex(long index) +Point TableView::_offsetFromIndex(ssize_t index) { Point offset = this->__offsetFromIndex(index); @@ -308,7 +308,7 @@ Point TableView::_offsetFromIndex(long index) return offset; } -Point TableView::__offsetFromIndex(long index) +Point TableView::__offsetFromIndex(ssize_t index) { Point offset; Size cellSize; @@ -409,7 +409,7 @@ void TableView::_moveCellOutOfSight(TableViewCell *cell) } } -void TableView::_setIndexForCell(long index, TableViewCell *cell) +void TableView::_setIndexForCell(ssize_t index, TableViewCell *cell) { cell->setAnchorPoint(Point(0.0f, 0.0f)); cell->setPosition(this->_offsetFromIndex(index)); @@ -464,7 +464,7 @@ void TableView::scrollViewDidScroll(ScrollView* view) _tableViewDelegate->scrollViewDidScroll(this); } - long startIdx = 0, endIdx = 0, idx = 0, maxIdx = 0; + ssize_t startIdx = 0, endIdx = 0, idx = 0, maxIdx = 0; Point offset = this->getContentOffset() * -1; maxIdx = MAX(countOfItems-1, 0); diff --git a/extensions/GUI/CCScrollView/CCTableView.h b/extensions/GUI/CCScrollView/CCTableView.h index 4201a2c1a4..c01b3eb4a2 100644 --- a/extensions/GUI/CCScrollView/CCTableView.h +++ b/extensions/GUI/CCScrollView/CCTableView.h @@ -105,7 +105,7 @@ public: * @param idx the index of a cell to get a size * @return size of a cell at given index */ - virtual Size tableCellSizeForIndex(TableView *table, long idx) { + virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx) { return cellSizeForTable(table); }; /** @@ -123,7 +123,7 @@ public: * @param idx index to search for a cell * @return cell found at idx */ - virtual TableViewCell* tableCellAtIndex(TableView *table, long idx) = 0; + virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx) = 0; /** * Returns number of cells in a given table view. * @@ -228,19 +228,19 @@ public: * * @param idx index to find a cell */ - void updateCellAtIndex(long idx); + void updateCellAtIndex(ssize_t idx); /** * Inserts a new cell at a given index * * @param idx location to insert */ - void insertCellAtIndex(long idx); + void insertCellAtIndex(ssize_t idx); /** * Removes a cell at a given index * * @param idx index to find a cell */ - void removeCellAtIndex(long idx); + void removeCellAtIndex(ssize_t idx); /** * reloads data from data source. the view will be refreshed. */ @@ -258,7 +258,7 @@ public: * @param idx index * @return a cell at a given index */ - TableViewCell *cellAtIndex(long idx); + TableViewCell *cellAtIndex(ssize_t idx); // Overrides virtual void scrollViewDidScroll(ScrollView* view) override; @@ -271,11 +271,11 @@ public: protected: long __indexFromOffset(Point offset); long _indexFromOffset(Point offset); - Point __offsetFromIndex(long index); - Point _offsetFromIndex(long index); + Point __offsetFromIndex(ssize_t index); + Point _offsetFromIndex(ssize_t index); void _moveCellOutOfSight(TableViewCell *cell); - void _setIndexForCell(long index, TableViewCell *cell); + void _setIndexForCell(ssize_t index, TableViewCell *cell); void _addCellIfNecessary(TableViewCell * cell); void _updateCellPositions(); @@ -290,7 +290,7 @@ protected: /** * index set to query the indexes of the cells used. */ - std::set* _indices; + std::set* _indices; /** * vector with all cell positions diff --git a/external/json/json_writer.cpp b/external/json/json_writer.cpp index cdf4188f2e..bcde6089dc 100644 --- a/external/json/json_writer.cpp +++ b/external/json/json_writer.cpp @@ -116,7 +116,7 @@ std::string valueToQuotedString( const char *value ) // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL + size_t maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL std::string result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; From 040c42ebfdb40db18af8a407967b69a36236c442 Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 12 Dec 2013 14:15:08 +0800 Subject: [PATCH 75/98] use ssize_t for index --- cocos/2d/CCEventDispatcher.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.h b/cocos/2d/CCEventDispatcher.h index b8b1aa8efb..5fe81cca95 100644 --- a/cocos/2d/CCEventDispatcher.h +++ b/cocos/2d/CCEventDispatcher.h @@ -136,12 +136,12 @@ private: inline std::vector* getFixedPriorityListeners() const { return _fixedListeners; }; inline std::vector* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; }; - inline int getGt0Index() const { return _gt0Index; }; - inline void setGt0Index(int index) { _gt0Index = index; }; + inline ssize_t getGt0Index() const { return _gt0Index; }; + inline void setGt0Index(ssize_t index) { _gt0Index = index; }; private: std::vector* _fixedListeners; std::vector* _sceneGraphListeners; - int _gt0Index; + ssize_t _gt0Index; }; /** Adds event listener with item */ From 16efe94946440f46d6a14375841815c4c78a57f7 Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 12 Dec 2013 14:45:30 +0800 Subject: [PATCH 76/98] fix compiling error after fixing conflicts --- cocos/base/CCAutoreleasePool.cpp | 2 +- cocos/base/CCVector.h | 225 ++++++++++++------ .../editor-support/cocostudio/CCArmature.cpp | 2 +- cocos/editor-support/cocostudio/CCBone.cpp | 2 +- cocos/physics/CCPhysicsBody.cpp | 2 +- cocos/physics/CCPhysicsWorld.cpp | 4 +- .../GUI/CCControlExtension/CCControl.cpp | 2 +- extensions/GUI/CCScrollView/CCTableView.cpp | 2 +- 8 files changed, 166 insertions(+), 75 deletions(-) diff --git a/cocos/base/CCAutoreleasePool.cpp b/cocos/base/CCAutoreleasePool.cpp index f1619b3746..d829c7bb10 100644 --- a/cocos/base/CCAutoreleasePool.cpp +++ b/cocos/base/CCAutoreleasePool.cpp @@ -51,7 +51,7 @@ void AutoreleasePool::removeObject(Object* object) { for (unsigned int i = 0; i < object->_autoReleaseCount; ++i) { - _managedObjectArray.erase(object, false); + _managedObjectArray.eraseObject(object, false); } } diff --git a/cocos/base/CCVector.h b/cocos/base/CCVector.h index dfe5ef4b88..92077e29f6 100644 --- a/cocos/base/CCVector.h +++ b/cocos/base/CCVector.h @@ -37,13 +37,41 @@ template class CC_DLL Vector { public: + // ------------------------------------------ + // Iterators + // ------------------------------------------ + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; + + typedef typename std::vector::reverse_iterator reverse_iterator; + typedef typename std::vector::const_reverse_iterator const_reverse_iterator; + + iterator begin() { return _data.begin(); } + const_iterator begin() const { return _data.begin(); } + + iterator end() { return _data.end(); } + const_iterator end() const { return _data.end(); } + + const_iterator cbegin() const { return _data.cbegin(); } + const_iterator cend() const { return _data.cend(); } + + reverse_iterator rbegin() { return _data.rbegin(); } + const_reverse_iterator rbegin() const { return _data.rbegin(); } + + reverse_iterator rend() { return _data.rend(); } + const_reverse_iterator rend() const { return _data.rend(); } + + const_reverse_iterator crbegin() const { return _data.crbegin(); } + const_reverse_iterator crend() const { return _data.crend(); } + + /** Constructor */ Vector() : _data() { } - /** creates an emptry Vector */ + /** Constructor with a capacity */ explicit Vector(ssize_t capacity) : _data() { @@ -51,12 +79,14 @@ public: reserve(capacity); } + /** Destructor */ ~Vector() { CCLOGINFO("In the destructor of Vector."); clear(); } + /** Copy constructor */ Vector(const Vector& other) { CCLOGINFO("In the copy constructor!"); @@ -71,6 +101,7 @@ public: _data = std::move(other._data); } + /** Copy assignment operator */ Vector& operator=(const Vector& other) { CCLOGINFO("In the copy assignment operator!"); @@ -80,6 +111,7 @@ public: return *this; } + /** Move assignment operator */ Vector& operator=(Vector&& other) { CCLOGINFO("In the move assignment operator!"); @@ -98,65 +130,93 @@ public: // return _data[index]; // } - /** Sets capacity of current array */ - void reserve(ssize_t capacity) + /** @brief Request a change in capacity + * @param capacity Minimum capacity for the vector. + * If n is greater than the current vector capacity, + * the function causes the container to reallocate its storage increasing its capacity to n (or greater). + */ + void reserve(ssize_t n) { - _data.reserve(capacity); + _data.reserve(n); } - /** Returns capacity of the array */ + /** @brief Returns the size of the storage space currently allocated for the vector, expressed in terms of elements. + * @note This capacity is not necessarily equal to the vector size. + * It can be equal or greater, with the extra space allowing to accommodate for growth without the need to reallocate on each insertion. + * @return The size of the currently allocated storage capacity in the vector, measured in terms of the number elements it can hold. + */ ssize_t capacity() const { return _data.capacity(); } - // Querying an Array - - /** Returns element count of the array */ + /** @brief Returns the number of elements in the vector. + * @note This is the number of actual objects held in the vector, which is not necessarily equal to its storage capacity. + * @return The number of elements in the container. + */ ssize_t size() const { return _data.size(); } + /** @brief Returns whether the vector is empty (i.e. whether its size is 0). + * @note This function does not modify the container in any way. To clear the content of a vector, see Vector::clear. + */ bool empty() const { return _data.empty(); } + /** Returns the maximum number of elements that the vector can hold. */ + ssize_t max_size() const + { + return _data.max_size(); + } + /** Returns index of a certain object, return UINT_MAX if doesn't contain the object */ ssize_t getIndex(T object) const { - ssize_t i = 0; - for (auto it = _data.begin(); it != _data.end(); ++it, ++i) - { - if (*it == object) - { - return i; - } - } - + auto iter = std::find(_data.begin(), _data.end(), object); + if (iter != _data.end()) + return iter - _data.begin(); + return -1; } - /** Returns an element with a certain index */ + /** @brief Find the object in the vector. + * @return Returns an iterator to the first element in the range [first,last) that compares equal to val. + * If no such element is found, the function returns last. + */ + const_iterator find(T object) const + { + return std::find(_data.begin(), _data.end(), object); + } + + iterator find(T object) + { + return std::find(_data.begin(), _data.end(), object); + } + + /** Returns the element at position 'index' in the vector. */ T at(ssize_t index) const { CCASSERT( index >= 0 && index < size(), "index out of range in getObjectAtIndex()"); return _data[index]; } + /** Returns the first element in the vector. */ T front() const { return _data.front(); } - /** Returns the last element of the array */ + /** Returns the last element of the vector. */ T back() const { return _data.back(); } - /** Returns a random element */ + /** Returns a random element of the vector. */ T getRandomObject() const { if (!_data.empty()) @@ -167,13 +227,13 @@ public: return nullptr; } - /** Returns a Boolean value that indicates whether object is present in array. */ + /** Returns a Boolean value that indicates whether object is present in vector. */ bool contains(T object) const { return( std::find(_data.begin(), _data.end(), object) != _data.end() ); } - /** returns true if the the arrays are equal */ + /** Returns true if the two vectors are equal */ bool equals(const Vector &other) { ssize_t s = this->size(); @@ -190,9 +250,13 @@ public: return true; } - // Adding Objects - - /** Add a certain object */ + // Adds objects + + /** @brief Adds a new element at the end of the vector, after its current last element. + * @note This effectively increases the container size by one, + * which causes an automatic reallocation of the allocated storage space + * if -and only if- the new vector size surpasses the current vector capacity. + */ void pushBack(T object) { CCASSERT(object != nullptr, "The object should not be nullptr"); @@ -200,7 +264,7 @@ public: object->retain(); } - /** Add all elements of an existing array */ + /** Inserts all elements of an existing vector */ void insert(const Vector& other) { for( auto it = other.begin(); it != other.end(); ++it ) { @@ -209,7 +273,12 @@ public: } } - /** Insert a certain object at a certain index */ + /** @brief Insert a certain object at a certain index + * @note The vector is extended by inserting new elements before the element at the specified 'index', + * effectively increasing the container size by the number of elements inserted. + * This causes an automatic reallocation of the allocated storage space + * if -and only if- the new vector size surpasses the current vector capacity. + */ void insert(ssize_t index, T object) { CCASSERT(index >= 0 && index <= size(), "Invalid index!"); @@ -218,9 +287,11 @@ public: object->retain(); } - // Removing Objects + // Removes Objects - /** Remove last object */ + /** Removes the last element in the vector, + * effectively reducing the container size by one, decrease the referece count of the deleted object. + */ void popBack() { CCASSERT(!_data.empty(), "no objects added"); @@ -228,9 +299,12 @@ public: _data.pop_back(); last->release(); } - - /** Remove a certain object */ - void removeObject(T object, bool toRelease = true) + + /** @brief Remove a certain object. + * @param object The object to be removed. + * @param toRelease Whether to decrease the referece count of the deleted object. + */ + void eraseObject(T object, bool toRelease = true) { CCASSERT(object != nullptr, "The object should not be nullptr"); auto iter = std::find(_data.begin(), _data.end(), object); @@ -240,16 +314,50 @@ public: object->release(); } - /** Removes an element with a certain index */ - void remove(ssize_t index) + /** @brief Removes from the vector with an iterator. + * @param position Iterator pointing to a single element to be removed from the vector. + * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. + * This is the container end if the operation erased the last element in the sequence. + */ + iterator erase(iterator position) + { + CCASSERT(position >= _data.begin() && position < _data.end(), "Invalid position!"); + (*position)->release(); + return _data.erase(position); + } + + /** @brief Removes from the vector with a range of elements ( [first, last) ). + * @param first The beginning of the range + * @param last The end of the range, the 'last' will not used, it's only for indicating the end of range. + * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. + * This is the container end if the operation erased the last element in the sequence. + */ + iterator erase(const_iterator first, const_iterator last) + { + for (auto iter = first; iter != last; ++iter) + { + (*iter)->release(); + } + + return _data.erase(first, last); + } + + /** @brief Removes from the vector with an index. + * @param index The index of the element to be removed from the vector. + * @return An iterator pointing to the new location of the element that followed the last element erased by the function call. + * This is the container end if the operation erased the last element in the sequence. + */ + iterator erase(ssize_t index) { CCASSERT(!_data.empty() && index >=0 && index < size(), "Invalid index!"); auto it = std::next( begin(), index ); (*it)->release(); - _data.erase(it); + return _data.erase(it); } - /** Removes all objects */ + /** @brief Removes all elements from the vector (which are destroyed), leaving the container with a size of 0. + * @note All the elements in the vector will be released (referece count will be decreased). + */ void clear() { for( auto it = std::begin(_data); it != std::end(_data); ++it ) { @@ -263,8 +371,8 @@ public: /** Swap two elements */ void swap(T object1, T object2) { - auto idx1 = getIndex(object1); - auto idx2 = getIndex(object2); + ssize_t idx1 = getIndex(object1); + ssize_t idx2 = getIndex(object2); CCASSERT(idx1>=0 && idx2>=0, "invalid object index"); @@ -290,18 +398,19 @@ public: object->retain(); } - /** reverses the array */ + /** reverses the vector */ void reverse() { std::reverse( std::begin(_data), std::end(_data) ); } - /** Shrinks the array so the memory footprint corresponds with the number of items */ + /** Shrinks the vector so the memory footprint corresponds with the number of items */ void shrinkToFit() { _data.shrink_to_fit(); } + /** Traverses through the vector and applys the callback function for each element */ void forEach(const std::function& callback) { if (empty()) @@ -312,6 +421,7 @@ public: }); } + /** Traverses through the vector and applys the callback function for each element */ void forEach(const std::function& callback) const { if (empty()) @@ -322,6 +432,7 @@ public: }); } + /** Traverses through the vector in reversed order and applys the callback function for each element */ void forEachReverse(const std::function& callback) { if (empty()) @@ -332,6 +443,7 @@ public: }); } + /** Traverses through the vector in reversed order and applys the callback function for each element */ void forEachReverse(const std::function& callback) const { if (empty()) @@ -342,6 +454,11 @@ public: }); } + /** @brief Sorts all elements in the vector according the binary callback function. + * @param callback Binary function that accepts two elements in the vector as arguments, + * and returns a value convertible to bool. + * The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines. + */ void sort(const std::function& callback) { if (empty()) @@ -352,35 +469,9 @@ public: }); } - // ------------------------------------------ - // Iterators - // ------------------------------------------ - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - - typedef typename std::vector::reverse_iterator reverse_iterator; - typedef typename std::vector::const_reverse_iterator const_reverse_iterator; - - iterator begin() { return _data.begin(); } - const_iterator begin() const { return _data.begin(); } - - iterator end() { return _data.end(); } - const_iterator end() const { return _data.end(); } - - const_iterator cbegin() const { return _data.cbegin(); } - const_iterator cend() const { return _data.cend(); } - - reverse_iterator rbegin() { return _data.rbegin(); } - const_reverse_iterator rbegin() const { return _data.rbegin(); } - - reverse_iterator rend() { return _data.rend(); } - const_reverse_iterator rend() const { return _data.rend(); } - - const_reverse_iterator crbegin() const { return _data.crbegin(); } - const_reverse_iterator crend() const { return _data.crend(); } - protected: + /** Retains all the objects in the vector */ void addRefForAllObjects() { std::for_each(_data.begin(), _data.end(), [](T obj){ diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index 8cecf76105..8078e798d2 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -312,7 +312,7 @@ void Armature::changeBoneParent(Bone *bone, const char *parentName) if(bone->getParentBone()) { - bone->getParentBone()->getChildren().erase(bone); + bone->getParentBone()->getChildren().eraseObject(bone); bone->setParentBone(nullptr); } diff --git a/cocos/editor-support/cocostudio/CCBone.cpp b/cocos/editor-support/cocostudio/CCBone.cpp index 06340bc422..b96ab3fe14 100644 --- a/cocos/editor-support/cocostudio/CCBone.cpp +++ b/cocos/editor-support/cocostudio/CCBone.cpp @@ -334,7 +334,7 @@ void Bone::removeChildBone(Bone *bone, bool recursion) bone->getDisplayManager()->setCurrentDecorativeDisplay(nullptr); - _children.erase(bone); + _children.eraseObject(bone); } } diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index 7fd340b043..3478178610 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -672,7 +672,7 @@ void PhysicsBody::removeShape(PhysicsShape* shape, bool reduceMassAndMoment/* = // set shape->_body = nullptr make the shape->setBody will not trigger the _body->removeShape function call. shape->_body = nullptr; shape->setBody(nullptr); - _shapes.erase(shape); + _shapes.eraseObject(shape); } } diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index f6b7722fb5..8b03021c94 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -714,7 +714,7 @@ void PhysicsWorld::removeBody(PhysicsBody* body) body->_joints.clear(); removeBodyOrDelay(body); - _bodies.erase(body); + _bodies.eraseObject(body); body->_world = nullptr; } @@ -723,7 +723,7 @@ void PhysicsWorld::removeBodyOrDelay(PhysicsBody* body) { if (_delayAddBodies.getIndex(body) != CC_INVALID_INDEX) { - _delayAddBodies.erase(body); + _delayAddBodies.eraseObject(body); return; } diff --git a/extensions/GUI/CCControlExtension/CCControl.cpp b/extensions/GUI/CCControlExtension/CCControl.cpp index 1b7adde712..722b0b74ad 100644 --- a/extensions/GUI/CCControlExtension/CCControl.cpp +++ b/extensions/GUI/CCControlExtension/CCControl.cpp @@ -207,7 +207,7 @@ void Control::removeTargetWithActionForControlEvent(Object* target, Handler acti // Remove the corresponding invocation object if (shouldBeRemoved) { - eventInvocationList.erase(invocation, bDeleteObjects); + eventInvocationList.eraseObject(invocation, bDeleteObjects); } }); } diff --git a/extensions/GUI/CCScrollView/CCTableView.cpp b/extensions/GUI/CCScrollView/CCTableView.cpp index 3dc65621f8..9842bfb836 100644 --- a/extensions/GUI/CCScrollView/CCTableView.cpp +++ b/extensions/GUI/CCScrollView/CCTableView.cpp @@ -397,7 +397,7 @@ void TableView::_moveCellOutOfSight(TableViewCell *cell) } _cellsFreed.pushBack(cell); - _cellsUsed.erase(cell); + _cellsUsed.eraseObject(cell); _isUsedCellsDirty = true; _indices->erase(cell->getIdx()); From 21e2b341f197dfc134eea6feecddda951f8dd47c Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 12 Dec 2013 14:59:33 +0800 Subject: [PATCH 77/98] fix compiling error after fixing conflicts --- cocos/base/CCMap.h | 171 ++++++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 58 deletions(-) diff --git a/cocos/base/CCMap.h b/cocos/base/CCMap.h index 57445c3145..7771a70971 100644 --- a/cocos/base/CCMap.h +++ b/cocos/base/CCMap.h @@ -1,26 +1,26 @@ /**************************************************************************** -Copyright (c) 2012 - 2013 cocos2d-x.org - -http://www.cocos2d-x.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -****************************************************************************/ + Copyright (c) 2012 - 2013 cocos2d-x.org + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ #ifndef __CCMAP_H__ #define __CCMAP_H__ @@ -59,19 +59,22 @@ public: const_iterator cbegin() const { return _data.cbegin(); } const_iterator cend() const { return _data.cend(); } + /** Default constructor */ Map() : _data() { CCLOGINFO("In the default constructor of Map!"); } + /** Contructor with capacity */ explicit Map(ssize_t capacity) : _data() { CCLOGINFO("In the constructor with capacity of Map!"); _data.reserve(capacity); } - + + /** Copy constructor */ Map(const Map& other) { CCLOGINFO("In the copy constructor of Map!"); @@ -79,44 +82,54 @@ public: addRefForAllObjects(); } + /** Move constructor */ Map(Map&& other) { CCLOGINFO("In the move constructor of Map!"); _data = std::move(other._data); } + /** Destructor + * It will release all objects in map. + */ ~Map() { CCLOGINFO("In the destructor of Map!"); clear(); } - - /** Sets capacity of current array */ + + /** Sets capacity of the map */ void reserve(ssize_t capacity) { _data.reserve(capacity); } - /** Returns capacity of the array */ - size_t capacity() const + /** Returns capacity of the map */ + ssize_t capacity() const { return _data.capacity(); } - size_t size() const + /** The number of elements in the map. */ + ssize_t size() const { return _data.size(); } - + + /** Returns a bool value indicating whether the map container is empty, i.e. whether its size is 0. + * @note This function does not modify the content of the container in any way. + * To clear the content of an array object, member function unordered_map::clear exists. + */ bool empty() const { return _data.empty(); } + /** Returns all keys in the map */ std::vector keys() const { std::vector keys; - + if (!_data.empty()) { for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter) @@ -126,7 +139,8 @@ public: } return keys; } - + + /** Returns all keys that matches the object */ std::vector keys(V object) const { std::vector keys; @@ -141,7 +155,12 @@ public: return keys; } - + + /** @brief Returns a reference to the mapped value of the element with key k in the map. + * @note If key does not match the key of any element in the container, the function return nullptr. + * @param key Key value of the element whose mapped value is accessed. + * Member type K is the keys for the elements in the container. defined in Map as an alias of its first template parameter (Key). + */ const V at(const K& key) const { auto iter = _data.find(key); @@ -158,6 +177,13 @@ public: return nullptr; } + /** @brief Searches the container for an element with 'key' as key and returns an iterator to it if found, + * otherwise it returns an iterator to Map::end (the element past the end of the container). + * @param key Key to be searched for. + * Member type 'K' is the type of the keys for the elements in the container, + * defined in Map as an alias of its first template parameter (Key). + * + */ const_iterator find(const K& key) const { return _data.find(key); @@ -168,6 +194,11 @@ public: return _data.find(key); } + /** @brief Inserts new elements in the map. + * @note If the container has already contained the key, this function will erase the old pair(key, object) and insert the new pair. + * @param key The key to be inserted. + * @param object The object to be inserted. + */ void insert(const K& key, V object) { CCASSERT(object != nullptr, "Object is nullptr!"); @@ -175,12 +206,23 @@ public: _data.insert(std::make_pair(key, object)); object->retain(); } - + + /** @brief Removes an element with an iterator from the Map container. + * @param position Iterator pointing to a single element to be removed from the Map. + * Member type const_iterator is a forward iterator type. + */ iterator erase(const_iterator position) { + CCASSERT(position != _data.cend(), "Invalid iterator!"); + position->second->release(); return _data.erase(position); } + /** @brief Removes an element with an iterator from the Map container. + * @param k Key of the element to be erased. + * Member type 'K' is the type of the keys for the elements in the container, + * defined in Map as an alias of its first template parameter (Key). + */ size_t erase(const K& k) { auto iter = _data.find(k); @@ -194,6 +236,9 @@ public: return 0; } + /** @brief Removes some elements with a vector which contains keys in the map. + * @param keys Keys of elements to be erased. + */ void erase(const std::vector& keys) { std::for_each(keys.cbegin(), keys.cend(), [this](const K& key){ @@ -201,6 +246,10 @@ public: }); } + /** All the elements in the Map container are dropped: + * their reference count will be decreased, and they are removed from the container, + * leaving it with a size of 0. + */ void clear() { for (auto iter = _data.cbegin(); iter != _data.cend(); ++iter) @@ -211,41 +260,45 @@ public: _data.clear(); } + /** @brief Gets a random object in the map + * @return Returns the random object if the map isn't empty, otherwise it returns nullptr. + */ V getRandomObject() const { if (!_data.empty()) { - int randIdx = rand() % _data.size(); + ssize_t randIdx = rand() % _data.size(); return (_data.begin() + randIdx)->second; } return nullptr; } -// Don't uses operator since we could not decide whether it needs 'retain'/'release'. -// V& operator[] ( const K& key ) -// { -// CCLOG("copy: [] ref"); -// return _data[key]; -// } -// -// V& operator[] ( K&& key ) -// { -// CCLOG("move [] ref"); -// return _data[key]; -// } + // Don't uses operator since we could not decide whether it needs 'retain'/'release'. + // V& operator[] ( const K& key ) + // { + // CCLOG("copy: [] ref"); + // return _data[key]; + // } + // + // V& operator[] ( K&& key ) + // { + // CCLOG("move [] ref"); + // return _data[key]; + // } -// const V& operator[] ( const K& key ) const -// { -// CCLOG("const copy []"); -// return _data.at(key); -// } -// -// const V& operator[] ( K&& key ) const -// { -// CCLOG("const move []"); -// return _data.at(key); -// } + // const V& operator[] ( const K& key ) const + // { + // CCLOG("const copy []"); + // return _data.at(key); + // } + // + // const V& operator[] ( K&& key ) const + // { + // CCLOG("const move []"); + // return _data.at(key); + // } + /** Copy assignment operator */ Map& operator= ( const Map& other ) { CCLOGINFO("In the copy assignment operator of Map!"); @@ -254,7 +307,8 @@ public: addRefForAllObjects(); return *this; } - + + /** Move assignment operator */ Map& operator= ( Map&& other ) { CCLOGINFO("In the move assignment operator of Map!"); @@ -264,6 +318,7 @@ public: protected: + /** Retains all the objects in the map */ void addRefForAllObjects() { for (auto iter = _data.begin(); iter != _data.end(); ++iter) From 98bd84c436b53d363d5401af1d02a813c0397e37 Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Fri, 13 Dec 2013 15:50:12 +0800 Subject: [PATCH 78/98] =?UTF-8?q?Fix:Add=20lua=20binding=20of=20=E2=80=99r?= =?UTF-8?q?egisterScriptHandler=E2=80=99=E3=80=81=E2=80=99unregisterScript?= =?UTF-8?q?Handler=E2=80=99=20and=20=E2=80=99removeObjectAllHandlers?= =?UTF-8?q?=E2=80=99=20of=20ScriptHandlerMgr=20and=20some=20constants=20de?= =?UTF-8?q?fine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lua/bindings/LuaOpengl.cpp.REMOVED.git-id | 2 +- .../lua/bindings/LuaScriptHandlerMgr.cpp | 99 +++++++++++++++++++ .../lua/bindings/LuaScriptHandlerMgr.h | 3 - .../scripting/lua/script/Cocos2dConstants.lua | 38 +++++++ 4 files changed, 138 insertions(+), 4 deletions(-) diff --git a/cocos/scripting/lua/bindings/LuaOpengl.cpp.REMOVED.git-id b/cocos/scripting/lua/bindings/LuaOpengl.cpp.REMOVED.git-id index 2381b20f37..3271e22a11 100644 --- a/cocos/scripting/lua/bindings/LuaOpengl.cpp.REMOVED.git-id +++ b/cocos/scripting/lua/bindings/LuaOpengl.cpp.REMOVED.git-id @@ -1 +1 @@ -4604aa76ce1cd72165190c09b5eba4faf2efca40 \ No newline at end of file +9104cc5ff14c7548ea6924a2785400db7526c1e1 \ No newline at end of file diff --git a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.cpp b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.cpp index b4476970df..5419de0be7 100644 --- a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.cpp +++ b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.cpp @@ -219,6 +219,7 @@ static void tolua_reg_script_handler_mgr_type(lua_State* tolua_S) tolua_usertype(tolua_S, "ScheduleHandlerDelegate"); tolua_usertype(tolua_S, "ScriptHandlerMgr"); } + /* method: getInstance of class ScriptHandlerMgr */ #ifndef TOLUA_DISABLE_tolua_Cocos2d_ScriptHandlerMgr_getInstance00 static int tolua_Cocos2d_ScriptHandlerMgr_getInstance00(lua_State* tolua_S) @@ -243,6 +244,101 @@ tolua_lerror: } #endif //#ifndef TOLUA_DISABLE +/* method: registerScriptHandler of class ScriptHandlerMgr */ +static int tolua_Cocos2d_ScriptHandlerMgr_registerScriptHandler00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!tolua_isusertype(tolua_S,1,"ScriptHandlerMgr",0,&tolua_err) || + !tolua_isusertype(tolua_S, 2, "Object", 0, &tolua_err) || + !toluafix_isfunction(tolua_S, 3, "LUA_FUNCTION", 0, &tolua_err) || + !tolua_isnumber(tolua_S, 4, 0, &tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) ) + goto tolua_lerror; + else +#endif + { + cocos2d::ScriptHandlerMgr* scriptHanlderMgr = static_cast(tolua_tousertype(tolua_S,1,0)); +#ifndef TOLUA_RELEASE + if (nullptr == scriptHanlderMgr) + { + tolua_error(tolua_S,"invalid 'scriptHanlderMgr' in function 'tolua_Cocos2d_ScriptHandlerMgr_registerScriptHandler00'\n", NULL); + return 0; + } +#endif + LUA_FUNCTION handler = toluafix_ref_function(tolua_S,3,0); + ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType)tolua_tonumber(tolua_S, 4, 0); + scriptHanlderMgr->addObjectHandler(tolua_tousertype(tolua_S, 2, 0), handler,handlerType); + } + return 1; +#ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'registerScriptHandler'.",&tolua_err); + return 0; +#endif +} + +/* method: unregisterScriptHandler of class ScriptHandlerMgr */ +static int tolua_Cocos2d_ScriptHandlerMgr_unregisterScriptHandler00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!tolua_isusertype(tolua_S,1,"ScriptHandlerMgr",0,&tolua_err) || + !tolua_isusertype(tolua_S, 2, "Object", 0, &tolua_err) || + !tolua_isnumber(tolua_S, 3, 0, &tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) + goto tolua_lerror; + else +#endif + { + cocos2d::ScriptHandlerMgr* scriptHanlderMgr = static_cast(tolua_tousertype(tolua_S,1,0)); +#ifndef TOLUA_RELEASE + if (nullptr == scriptHanlderMgr) + { + tolua_error(tolua_S,"invalid 'scriptHanlderMgr' in function 'tolua_Cocos2d_ScriptHandlerMgr_unregisterScriptHandler00'\n", NULL); + return 0; + } +#endif + ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType)tolua_tonumber(tolua_S, 3, 0); + scriptHanlderMgr->removeObjectHandler(tolua_tousertype(tolua_S, 2, 0), handlerType); + } + return 1; +#ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'unregisterScriptHandler'.",&tolua_err); + return 0; +#endif +} + +/* method: removeObjectAllHandlers of class ScriptHandlerMgr */ +static int tolua_Cocos2d_ScriptHandlerMgr_removeObjectAllHandlers00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!tolua_isusertype(tolua_S,1,"ScriptHandlerMgr",0,&tolua_err) || + !tolua_isusertype(tolua_S, 2, "Object", 0, &tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) ) + goto tolua_lerror; + else +#endif + { + cocos2d::ScriptHandlerMgr* scriptHanlderMgr = static_cast(tolua_tousertype(tolua_S,1,0)); +#ifndef TOLUA_RELEASE + if (nullptr == scriptHanlderMgr) + { + tolua_error(tolua_S,"invalid 'scriptHanlderMgr' in function 'tolua_Cocos2d_ScriptHandlerMgr_removeObjectAllHandlers00'\n", NULL); + return 0; + } +#endif + scriptHanlderMgr->removeObjectAllHandlers(tolua_tousertype(tolua_S, 2, 0)); + } + return 1; +#ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'removeObjectAllHandlers'.",&tolua_err); + return 0; +#endif +} TOLUA_API int tolua_script_handler_mgr_open(lua_State* tolua_S) { @@ -253,6 +349,9 @@ TOLUA_API int tolua_script_handler_mgr_open(lua_State* tolua_S) tolua_cclass(tolua_S,"ScriptHandlerMgr","ScriptHandlerMgr","",NULL); tolua_beginmodule(tolua_S, "ScriptHandlerMgr"); tolua_function(tolua_S, "getInstance", tolua_Cocos2d_ScriptHandlerMgr_getInstance00); + tolua_function(tolua_S, "registerScriptHandler", tolua_Cocos2d_ScriptHandlerMgr_registerScriptHandler00); + tolua_function(tolua_S, "unregisterScriptHandler", tolua_Cocos2d_ScriptHandlerMgr_unregisterScriptHandler00); + tolua_function(tolua_S, "removeObjectAllHandlers", tolua_Cocos2d_ScriptHandlerMgr_removeObjectAllHandlers00); tolua_endmodule(tolua_S); tolua_endmodule(tolua_S); return 1; diff --git a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h index 11c138226a..dffe6f3276 100644 --- a/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h +++ b/cocos/scripting/lua/bindings/LuaScriptHandlerMgr.h @@ -134,9 +134,6 @@ private: NS_CC_END -TOLUA_API int tolua_Cocos2d_GLNode_registerScriptDrawHandler00(lua_State* tolua_S); -TOLUA_API int tolua_Cocos2d_GLNode_unregisterScriptDrawHandler00(lua_State* tolua_S); - TOLUA_API int tolua_script_handler_mgr_open(lua_State* tolua_S); #endif //__LUA_SCRIPT_HANDLER_MGR_H__ diff --git a/cocos/scripting/lua/script/Cocos2dConstants.lua b/cocos/scripting/lua/script/Cocos2dConstants.lua index 5cee0d2c94..33b28c9957 100644 --- a/cocos/scripting/lua/script/Cocos2dConstants.lua +++ b/cocos/scripting/lua/script/Cocos2dConstants.lua @@ -288,4 +288,42 @@ cc.ASSETSMANAGER_UNCOMPRESS = 3 cc.ASSETSMANAGER_PROTOCOL_PROGRESS = 0 cc.ASSETSMANAGER_PROTOCOL_SUCCESS = 1 cc.ASSETSMANAGER_PROTOCOL_ERROR = 2 + +cc.HANDLERTYPE_NODE = 0 +cc.HANDLERTYPE_MENU_CLICKED = 1 +cc.HANDLERTYPE_NOTIFICATION = 2 +cc.HANDLERTYPE_CALLFUNC = 3 +cc.HANDLERTYPE_SCHEDULE = 4 +cc.HANDLERTYPE_TOUCHES = 5 +cc.HANDLERTYPE_KEYPAD = 6 +cc.HANDLERTYPE_ACCELEROMETER = 7 +cc.HANDLERTYPE_CONTROL_TOUCH_DOWN = 8 +cc.HANDLERTYPE_CONTROL_TOUCH_DRAG_INSIDE = 9 +cc.HANDLERTYPE_CONTROL_TOUCH_DRAG_OUTSIDE = 10 +cc.HANDLERTYPE_CONTROL_TOUCH_DRAG_ENTER = 11 +cc.HANDLERTYPE_CONTROL_TOUCH_DRAG_EXIT = 12 +cc.HANDLERTYPE_CONTROL_TOUCH_UP_INSIDE = 13 +cc.HANDLERTYPE_CONTROL_TOUCH_UP_OUTSIDE = 14 +cc.HANDLERTYPE_CONTROL_TOUCH_UP_CANCEL = 15 +cc.HANDLERTYPE_CONTROL_VALUE_CHANGED = 16 +cc.HANDLERTYPE_WEBSOCKET_OPEN = 17 +cc.HANDLERTYPE_WEBSOCKET_MESSAGE = 18 +cc.HANDLERTYPE_WEBSOCKET_CLOSE = 19 +cc.HANDLERTYPE_WEBSOCKET_ERROR = 20 +cc.HANDLERTYPE_GL_NODE_DRAW = 21 +cc.HANDLERTYPE_SCROLLVIEW_SCROLL = 22 +cc.HANDLERTYPE_SCROLLVIEW_ZOOM = 23 +cc.HANDLERTYPE_TABLECELL_TOUCHED = 24 +cc.HANDLERTYPE_TABLECELL_HIGHLIGHT = 25 +cc.HANDLERTYPE_TABLECELL_UNHIGHLIGHT = 26 +cc.HANDLERTYPE_TABLECELL_WILL_RECYCLE = 27 +cc.HANDLERTYPE_TABLECELL_SIZE_FOR_INDEX = 28 +cc.HANDLERTYPE_TABLECELL_AT_INDEX = 29 +cc.HANDLERTYPE_TABLEVIEW_NUMS_OF_CELLS = 30 +cc.HANDLERTYPE_XMLHTTPREQUEST_READY_STATE_CHANGE = 31 +cc.HANDLERTYPE_ASSETSMANAGER_PROGRESS = 32 +cc.HANDLERTYPE_ASSETSMANAGER_SUCCESS = 33 +cc.HANDLERTYPE_ASSETSMANAGER_ERROR = 34 +cc.HANDLERTYPE_EVENT_LISTENER = 35 +cc.HANDLERTYPE_ARMATURE_EVENT = 36 \ No newline at end of file From 4befb503070b5c632f5ad430f827884d697b407e Mon Sep 17 00:00:00 2001 From: boyu0 Date: Fri, 13 Dec 2013 16:26:26 +0800 Subject: [PATCH 79/98] issue #2771: add PhysicsWorld function set/getUpdateRate and set/getSpeed. Change name PhysicsQueryRectCallbackFunc and PhysicsPointQueryCallbackFunc to PhysicsRectQueryCallbackFunc and PhysicsQueryPointCallbackFunc --- cocos/physics/CCPhysicsWorld.cpp | 19 +++++++++---- cocos/physics/CCPhysicsWorld.h | 28 +++++++++++++------ .../Classes/PhysicsTest/PhysicsTest.cpp | 5 ++-- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index f6b7722fb5..0414b4854b 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -75,14 +75,14 @@ namespace typedef struct RectQueryCallbackInfo { PhysicsWorld* world; - PhysicsRectQueryCallbackFunc func; + PhysicsQueryRectCallbackFunc func; void* data; }RectQueryCallbackInfo; typedef struct PointQueryCallbackInfo { PhysicsWorld* world; - PhysicsPointQueryCallbackFunc func; + PhysicsQueryPointCallbackFunc func; void* data; }PointQueryCallbackInfo; } @@ -355,7 +355,7 @@ void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, } -void PhysicsWorld::queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data) +void PhysicsWorld::queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data) { CCASSERT(func != nullptr, "func shouldn't be nullptr"); @@ -373,7 +373,7 @@ void PhysicsWorld::queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect } } -void PhysicsWorld::queryPoint(PhysicsPointQueryCallbackFunc func, const Point& point, void* data) +void PhysicsWorld::queryPoint(PhysicsQueryPointCallbackFunc func, const Point& point, void* data) { CCASSERT(func != nullptr, "func shouldn't be nullptr"); @@ -1022,7 +1022,13 @@ void PhysicsWorld::update(float delta) body->update(delta); } - _info->step(delta); + _updateTime += delta; + if (++_updateRateCount >= _updateRate) + { + _info->step(_updateTime * _speed); + _updateRateCount = 0; + _updateTime = 0.0f; + } if (_debugDrawMask != DEBUGDRAW_NONE) { @@ -1033,6 +1039,9 @@ void PhysicsWorld::update(float delta) PhysicsWorld::PhysicsWorld() : _gravity(Point(0.0f, -98.0f)) , _speed(1.0f) +, _updateRate(1) +, _updateRateCount(0) +, _updateTime(0.0f) , _info(nullptr) , _scene(nullptr) , _delayDirty(false) diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index dfd85e5744..23fc5acaf0 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -73,8 +73,8 @@ typedef struct PhysicsRayCastInfo * @return true to continue, false to terminate */ typedef std::function PhysicsRayCastCallbackFunc; -typedef std::function PhysicsRectQueryCallbackFunc; -typedef PhysicsRectQueryCallbackFunc PhysicsPointQueryCallbackFunc; +typedef std::function PhysicsQueryRectCallbackFunc; +typedef PhysicsQueryRectCallbackFunc PhysicsQueryPointCallbackFunc; /** * @brief An PhysicsWorld object simulates collisions and other physical properties. You do not create PhysicsWorld objects directly; instead, you can get it from an Scene object. @@ -101,23 +101,30 @@ public: virtual void removeAllBodies(); void rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data); - void queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data); - void queryPoint(PhysicsPointQueryCallbackFunc func, const Point& point, void* data); + void queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data); + void queryPoint(PhysicsQueryPointCallbackFunc func, const Point& point, void* data); Vector getShapes(const Point& point) const; PhysicsShape* getShape(const Point& point) const; const Vector& getAllBodies() const; PhysicsBody* getBody(int tag) const; - /** Register a listener to receive contact callbacks*/ - //inline void registerContactListener(EventListenerPhysicsContact* delegate) { _listener = delegate; } - /** Unregister a listener. */ - //inline void unregisterContactListener() { _listener = nullptr; } - inline Scene& getScene() const { return *_scene; } /** get the gravity value */ inline Vect getGravity() const { return _gravity; } /** set the gravity value */ void setGravity(const Vect& gravity); + /** Set the speed of physics world, speed is the rate at which the simulation executes. default value is 1.0 */ + inline void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } } + /** get the speed of physics world */ + inline float getSpeed() { return _speed; } + /** + * set the update rate of physics world, update rate is the value of EngineUpdateTimes/PhysicsWorldUpdateTimes. + * set it higher can improve performance, set it lower can improve accuracy of physics world simulation. + * default value is 1.0 + */ + inline void setUpdateRate(int rate) { if(rate > 0) { _updateRate = rate; } } + /** get the update rate */ + inline int getUpdateRate() { return _updateRate; } /** set the debug draw */ void setDebugDrawMask(int mask); @@ -153,6 +160,9 @@ protected: protected: Vect _gravity; float _speed; + int _updateRate; + int _updateRateCount; + float _updateTime; PhysicsWorldInfo* _info; Vector _bodies; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 4865b81352..0572157afd 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -418,6 +418,7 @@ void PhysicsDemoLogoSmash::onEnter() PhysicsDemo::onEnter(); _scene->getPhysicsWorld()->setGravity(Point(0, 0)); + _scene->getPhysicsWorld()->setUpdateRate(5.0f); _ball = SpriteBatchNode::create("Images/ball.png", sizeof(logo_image)/sizeof(logo_image[0])); addChild(_ball); @@ -445,9 +446,9 @@ void PhysicsDemoLogoSmash::onEnter() auto bullet = makeBall(Point(400, 0), 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0)); - bullet->getPhysicsBody()->setVelocity(Point(400, 0)); + bullet->getPhysicsBody()->setVelocity(Point(200, 0)); - bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2)); + bullet->setPosition(Point(-500, VisibleRect::getVisibleRect().size.height/2)); _ball->addChild(bullet); } From 7a8f2ae235e86a7f9aa4938072139c3d7b47b819 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 13 Dec 2013 16:41:03 +0800 Subject: [PATCH 80/98] =?UTF-8?q?size=5Ft=20=E2=80=94>=20ssize=5Ft=20in=20?= =?UTF-8?q?CCTMXLayer.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cocos/2d/CCTMXLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/CCTMXLayer.cpp b/cocos/2d/CCTMXLayer.cpp index fb178a3d55..79b7ae3d65 100644 --- a/cocos/2d/CCTMXLayer.cpp +++ b/cocos/2d/CCTMXLayer.cpp @@ -559,7 +559,7 @@ void TMXLayer::removeChild(Node* node, bool cleanup) CCASSERT(_children.contains(sprite), "Tile does not belong to TMXLayer"); ssize_t atlasIndex = sprite->getAtlasIndex(); - ssize_t zz = (size_t)_atlasIndexArray->arr[atlasIndex]; + ssize_t zz = (ssize_t)_atlasIndexArray->arr[atlasIndex]; _tiles[zz] = 0; ccCArrayRemoveValueAtIndex(_atlasIndexArray, atlasIndex); SpriteBatchNode::removeChild(sprite, cleanup); From ed93c114e50453ccfdf68b894157f4203e65727f Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 13 Dec 2013 16:47:42 +0800 Subject: [PATCH 81/98] Reverts CCSpriteBatchNode.h --- cocos/2d/CCSpriteBatchNode.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cocos/2d/CCSpriteBatchNode.h b/cocos/2d/CCSpriteBatchNode.h index 32f82634e9..73508fe762 100644 --- a/cocos/2d/CCSpriteBatchNode.h +++ b/cocos/2d/CCSpriteBatchNode.h @@ -163,6 +163,7 @@ public: virtual void removeAllChildrenWithCleanup(bool cleanup) override; virtual void sortAllChildren() override; virtual void draw(void) override; + virtual std::string getDescription() const override; protected: /** Inserts a quad at a certain index into the texture atlas. The Sprite won't be added into the children array. From 189cf1a0760e94d91f294e76c409ef9a712826b7 Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 13 Dec 2013 16:51:57 +0800 Subject: [PATCH 82/98] Some fixes for XXX:getDescription. --- cocos/2d/CCLayer.cpp | 2 +- cocos/2d/CCTMXLayer.cpp | 2 +- cocos/2d/CCTMXTiledMap.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 74ca71fda1..e139435fc5 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -1073,7 +1073,7 @@ void LayerMultiplex::switchToAndReleaseMe(int n) std::string LayerMultiplex::getDescription() const { - return StringUtils::format("", (int)_tag,_mapTileSize.width, (int)_mapTileSize.height); + return StringUtils::format("", _tag, (int)_mapTileSize.width, (int)_mapTileSize.height); } diff --git a/cocos/2d/CCTMXTiledMap.cpp b/cocos/2d/CCTMXTiledMap.cpp index d5e30f54c4..e7847b7644 100644 --- a/cocos/2d/CCTMXTiledMap.cpp +++ b/cocos/2d/CCTMXTiledMap.cpp @@ -246,7 +246,7 @@ Value TMXTiledMap::getPropertiesForGID(int GID) const std::string TMXTiledMap::getDescription() const { - return StringUtils::format(" Date: Fri, 13 Dec 2013 09:10:37 +0000 Subject: [PATCH 83/98] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index a9af1cbc15..f4de47ad7f 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit a9af1cbc151fdc39a619e92180e43d1f8cf04f83 +Subproject commit f4de47ad7f5320151933233d3bcba60c8662586f From 2dbb2d496fa9513d761a23c98d63932473adf9b2 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Fri, 13 Dec 2013 17:36:58 +0800 Subject: [PATCH 84/98] issue #2771: add and change some physics API, and add more documents --- cocos/physics/CCPhysicsBody.cpp | 2 +- cocos/physics/CCPhysicsJoint.h | 14 +++++++++ cocos/physics/CCPhysicsShape.cpp | 12 ++++---- cocos/physics/CCPhysicsShape.h | 49 ++++++++++++++++++++++++++------ cocos/physics/CCPhysicsWorld.h | 30 +++++++++++++------ 5 files changed, 83 insertions(+), 24 deletions(-) diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index 7fd340b043..f91012cdfb 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -739,7 +739,7 @@ bool PhysicsBody::isResting() const void PhysicsBody::update(float delta) { // damping compute - if (_dynamic) + if (_dynamic && !isResting()) { _info->getBody()->v.x *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f); _info->getBody()->v.y *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f); diff --git a/cocos/physics/CCPhysicsJoint.h b/cocos/physics/CCPhysicsJoint.h index 701950e6f8..58cc5f83e3 100644 --- a/cocos/physics/CCPhysicsJoint.h +++ b/cocos/physics/CCPhysicsJoint.h @@ -54,13 +54,19 @@ public: inline int getTag() const { return _tag; } inline void setTag(int tag) { _tag = tag; } inline bool isEnabled() const { return _enable; } + /** Enable/Disable the joint */ void setEnable(bool enable); inline bool isCollisionEnabled() const { return _collisionEnable; } + /** Enable/disable the collision between two bodies */ void setCollisionEnable(bool enable); + /** Remove the joint from the world */ void removeFormWorld(); + /** Distory the joint*/ static void destroy(PhysicsJoint* joint); + /** Set the max force between two bodies */ void setMaxForce(float force); + /** Get the max force setting */ float getMaxForce() const; protected: @@ -145,6 +151,7 @@ protected: virtual ~PhysicsJointPin() {} }; +/** Set the fixed distance with two bodies */ class PhysicsJointDistance : public PhysicsJoint { public: @@ -161,6 +168,7 @@ protected: virtual ~PhysicsJointDistance() {} }; +/** Connecting two physics bodies together with a spring. */ class PhysicsJointSpring : public PhysicsJoint { public: @@ -184,6 +192,7 @@ protected: virtual ~PhysicsJointSpring() {} }; +/** Attach body a to a line, and attach body b to a dot */ class PhysicsJointGroove : public PhysicsJoint { public: @@ -204,6 +213,7 @@ protected: virtual ~PhysicsJointGroove() {} }; +/** Likes a spring joint, but works with rotary */ class PhysicsJointRotarySpring : public PhysicsJoint { public: @@ -224,6 +234,7 @@ protected: virtual ~PhysicsJointRotarySpring() {} }; +/** Likes a limit joint, but works with rotary */ class PhysicsJointRotaryLimit : public PhysicsJoint { public: @@ -243,6 +254,7 @@ protected: virtual ~PhysicsJointRotaryLimit() {} }; +/** Works like a socket wrench. */ class PhysicsJointRatchet : public PhysicsJoint { public: @@ -263,6 +275,7 @@ protected: virtual ~PhysicsJointRatchet() {} }; +/** Keeps the angular velocity ratio of a pair of bodies constant. */ class PhysicsJointGear : public PhysicsJoint { public: @@ -281,6 +294,7 @@ protected: virtual ~PhysicsJointGear() {} }; +/** Keeps the relative angular velocity of a pair of bodies constant */ class PhysicsJointMotor : public PhysicsJoint { public: diff --git a/cocos/physics/CCPhysicsShape.cpp b/cocos/physics/CCPhysicsShape.cpp index a77072e9bd..f7e9c524b2 100644 --- a/cocos/physics/CCPhysicsShape.cpp +++ b/cocos/physics/CCPhysicsShape.cpp @@ -306,7 +306,7 @@ bool PhysicsShapeCircle::init(float radius, const PhysicsMaterial& material/* = _info->add(shape); - _area = calculateDefaultArea(); + _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); @@ -331,7 +331,7 @@ float PhysicsShapeCircle::calculateMoment(float mass, float radius, const Point& PhysicsHelper::point2cpv(offset))); } -float PhysicsShapeCircle::calculateDefaultArea() +float PhysicsShapeCircle::calculateArea() { return PhysicsHelper::cpfloat2float(cpAreaForCircle(0, cpCircleShapeGetRadius(_info->getShapes().front()))); } @@ -447,7 +447,7 @@ bool PhysicsShapeBox::init(const Size& size, const PhysicsMaterial& material/* = _info->add(shape); _offset = offset; - _area = calculateDefaultArea(); + _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); @@ -484,7 +484,7 @@ float PhysicsShapeBox::calculateMoment(float mass, const Size& size, const Point PhysicsHelper::point2cpv(offset))); } -float PhysicsShapeBox::calculateDefaultArea() +float PhysicsShapeBox::calculateArea() { cpShape* shape = _info->getShapes().front(); return PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); @@ -539,7 +539,7 @@ bool PhysicsShapePolygon::init(const Point* points, int count, const PhysicsMate _info->add(shape); - _area = calculateDefaultArea(); + _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); _center = PhysicsHelper::cpv2point(cpCentroidForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); @@ -573,7 +573,7 @@ float PhysicsShapePolygon::calculateMoment(float mass, const Point* points, int return moment; } -float PhysicsShapePolygon::calculateDefaultArea() +float PhysicsShapePolygon::calculateArea() { cpShape* shape = _info->getShapes().front(); return PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); diff --git a/cocos/physics/CCPhysicsShape.h b/cocos/physics/CCPhysicsShape.h index 1fb86e14d7..52e765b414 100644 --- a/cocos/physics/CCPhysicsShape.h +++ b/cocos/physics/CCPhysicsShape.h @@ -40,9 +40,9 @@ class PhysicsBodyInfo; typedef struct PhysicsMaterial { - float density; - float restitution; - float friction; + float density; ///< The density of the object. + float restitution; ///< The bounciness of the physics body. + float friction; ///< The roughness of the surface of a shape. PhysicsMaterial() : density(0.0f) @@ -78,35 +78,65 @@ public: }; public: + /** Get the body that this shape attaches */ inline PhysicsBody* getBody() const { return _body; } + /** Return the type of this shape */ inline Type getType() const { return _type; } + /** return the area of this shape */ inline float getArea() const { return _area; } + /** get moment */ inline float getMoment() const { return _moment; } + /** Set moment, it will change the body's moment this shape attaches */ void setMoment(float moment); inline void setTag(int tag) { _tag = tag; } inline int getTag() const { return _tag; } + /** get mass */ inline float getMass() const { return _mass; } + /** Set mass, it will change the body's mass this shape attaches */ void setMass(float mass); inline float getDensity() const { return _material.density; } void setDensity(float density); + inline float getRestitution() const { return _material.restitution; } void setRestitution(float restitution); + inline float getFriction() const { return _material.friction; } void setFriction(float friction); + const PhysicsMaterial& getMaterial() const { return _material; } void setMaterial(const PhysicsMaterial& material); - virtual float calculateDefaultMoment() { return 0; } - virtual float calculateDefaultArea() { return 0; } + /** Calculate the default moment value */ + virtual float calculateDefaultMoment() { return 0.0f; } + /** Get offset */ virtual Point getOffset() { return Point::ZERO; } + /** Get center of this shape */ virtual Point getCenter() { return getOffset(); } + /** Test point is in shape or not */ bool containsPoint(const Point& point) const; + /** move the points to the center */ static Point* recenterPoints(Point* points, int count, const Point& center = Point::ZERO); + /** get center of the polyon points */ static Point getPolyonCenter(const Point* points, int count); + /** + * A mask that defines which categories this physics body belongs to. + * Every physics body in a scene can be assigned to up to 32 different categories, each corresponding to a bit in the bit mask. You define the mask values used in your game. In conjunction with the collisionBitMask and contactTestBitMask properties, you define which physics bodies interact with each other and when your game is notified of these interactions. + * The default value is 0xFFFFFFFF (all bits set). + */ inline void setCategoryBitmask(int bitmask) { _categoryBitmask = bitmask; } inline int getCategoryBitmask() const { return _categoryBitmask; } + /** + * A mask that defines which categories of bodies cause intersection notifications with this physics body. + * When two bodies share the same space, each body’s category mask is tested against the other body’s contact mask by performing a logical AND operation. If either comparison results in a non-zero value, an PhysicsContact object is created and passed to the physics world’s delegate. For best performance, only set bits in the contacts mask for interactions you are interested in. + * The default value is 0x00000000 (all bits cleared). + */ inline void setContactTestBitmask(int bitmask) { _contactTestBitmask = bitmask; } inline int getContactTestBitmask() const { return _contactTestBitmask; } + /** + * A mask that defines which categories of physics bodies can collide with this physics body. + * When two physics bodies contact each other, a collision may occur. This body’s collision mask is compared to the other body’s category mask by performing a logical AND operation. If the result is a non-zero value, then this body is affected by the collision. Each body independently chooses whether it wants to be affected by the other body. For example, you might use this to avoid collision calculations that would make negligible changes to a body’s velocity. + * The default value is 0xFFFFFFFF (all bits set). + */ inline void setCollisionBitmask(int bitmask) { _collisionBitmask = bitmask; } inline int getCollisionBitmask() const { return _collisionBitmask; } @@ -123,6 +153,9 @@ protected: void setBody(PhysicsBody* body); + /** calculate the area of this shape */ + virtual float calculateArea() { return 0.0f; } + protected: PhysicsShape(); virtual ~PhysicsShape() = 0; @@ -155,13 +188,13 @@ public: static float calculateArea(float radius); static float calculateMoment(float mass, float radius, const Point& offset = Point::ZERO); - virtual float calculateDefaultArea() override; virtual float calculateDefaultMoment() override; float getRadius() const; virtual Point getOffset() override; protected: bool init(float radius, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Point& offset = Point::ZERO); + virtual float calculateArea() override; protected: PhysicsShapeCircle(); @@ -176,7 +209,6 @@ public: static float calculateArea(const Size& size); static float calculateMoment(float mass, const Size& size, const Point& offset = Point::ZERO); - virtual float calculateDefaultArea() override; virtual float calculateDefaultMoment() override; void getPoints(Point* outPoints) const; @@ -185,6 +217,7 @@ public: protected: bool init(const Size& size, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Point& offset = Point::ZERO); + virtual float calculateArea() override; protected: PhysicsShapeBox(); @@ -202,7 +235,6 @@ public: static float calculateArea(const Point* points, int count); static float calculateMoment(float mass, const Point* points, int count, const Point& offset = Point::ZERO); - float calculateDefaultArea() override; float calculateDefaultMoment() override; Point getPoint(int i) const; @@ -211,6 +243,7 @@ public: virtual Point getCenter() override; protected: bool init(const Point* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Point& offset = Point::ZERO); + float calculateArea() override; protected: PhysicsShapePolygon(); diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index 23fc5acaf0..80af28d260 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -82,32 +82,43 @@ typedef PhysicsQueryRectCallbackFunc PhysicsQueryPointCallbackFunc; class PhysicsWorld { public: - static const int DEBUGDRAW_NONE; - static const int DEBUGDRAW_SHAPE; - static const int DEBUGDRAW_JOINT; - static const int DEBUGDRAW_CONTACT; - static const int DEBUGDRAW_ALL; + static const int DEBUGDRAW_NONE; ///< draw nothing + static const int DEBUGDRAW_SHAPE; ///< draw shapes + static const int DEBUGDRAW_JOINT; ///< draw joints + static const int DEBUGDRAW_CONTACT; ///< draw contact + static const int DEBUGDRAW_ALL; ///< draw all public: /** Adds a joint to the physics world.*/ virtual void addJoint(PhysicsJoint* joint); - /** Removes a joint from the physics world.*/ + /** Remove a joint from physics world.*/ virtual void removeJoint(PhysicsJoint* joint, bool destroy); - /** Remove all joints from the physics world.*/ + /** Remove all joints from physics world.*/ virtual void removeAllJoints(bool destroy); + /** Remove a body from physics world. */ virtual void removeBody(PhysicsBody* body); + /** Remove body by tag. */ virtual void removeBody(int tag); + /** Remove all bodies from physics world. */ virtual void removeAllBodies(); - void rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data); + /** Searches for physics shapes that intersects the ray. */ + void rayCast(PhysicsRayCastCallbackFunc func, const Point& start, const Point& end, void* data); + /** Searches for physics shapes that contains in the rect. */ void queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data); + /** Searches for physics shapes that contains the point. */ void queryPoint(PhysicsQueryPointCallbackFunc func, const Point& point, void* data); + /** Get phsyics shapes that contains the point. */ Vector getShapes(const Point& point) const; + /** return physics shape that contains the point. */ PhysicsShape* getShape(const Point& point) const; + /** Get all the bodys that in the physics world. */ const Vector& getAllBodies() const; + /** Get body by tag */ PhysicsBody* getBody(int tag) const; + /** Get scene contain this physics world */ inline Scene& getScene() const { return *_scene; } /** get the gravity value */ inline Vect getGravity() const { return _gravity; } @@ -126,8 +137,9 @@ public: /** get the update rate */ inline int getUpdateRate() { return _updateRate; } - /** set the debug draw */ + /** set the debug draw mask */ void setDebugDrawMask(int mask); + /** get the bebug draw mask */ inline int getDebugDrawMask() { return _debugDrawMask; } protected: From 4e2e423615434668341dfb544ce23cdcce36b5f9 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Fri, 13 Dec 2013 17:53:03 +0800 Subject: [PATCH 85/98] fix compile error related to ssize_t. --- cocos/scripting/javascript/bindings/ScriptingCore.cpp | 2 +- .../javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id | 2 +- .../bindings/extension/jsb_cocos2dx_extension_manual.cpp | 4 ++-- extensions/GUI/CCScrollView/CCTableView.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cocos/scripting/javascript/bindings/ScriptingCore.cpp b/cocos/scripting/javascript/bindings/ScriptingCore.cpp index 2a17a90f89..a859a1ed8e 100644 --- a/cocos/scripting/javascript/bindings/ScriptingCore.cpp +++ b/cocos/scripting/javascript/bindings/ScriptingCore.cpp @@ -533,7 +533,7 @@ JSBool ScriptingCore::runScript(const char *path, JSObject* global, JSContext* c // a) check jsc file first std::string byteCodePath = RemoveFileExt(std::string(path)) + BYTE_CODE_FILE_EXT; - long length = 0; + ssize_t length = 0; unsigned char* data = futil->getFileData(byteCodePath.c_str(), "rb", &length); diff --git a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id index 29352b90d5..905d27d360 100644 --- a/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id +++ b/cocos/scripting/javascript/bindings/cocos2d_specifics.cpp.REMOVED.git-id @@ -1 +1 @@ -7a245db1098d7ced5947aca62f43e67f06d1492d \ No newline at end of file +6ea6ffc183c8a15eae0641c73c9886b90172266f \ No newline at end of file diff --git a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp index 963489a41d..beea364b4b 100644 --- a/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp +++ b/cocos/scripting/javascript/bindings/extension/jsb_cocos2dx_extension_manual.cpp @@ -248,7 +248,7 @@ public: } } - virtual Size tableCellSizeForIndex(TableView *table, long idx) + virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx) { jsval ret; bool ok = callJSDelegate(table, idx, "tableCellSizeForIndex", ret); @@ -268,7 +268,7 @@ public: } - virtual TableViewCell* tableCellAtIndex(TableView *table, long idx) + virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx) { jsval ret; bool ok = callJSDelegate(table, idx, "tableCellAtIndex", ret); diff --git a/extensions/GUI/CCScrollView/CCTableView.cpp b/extensions/GUI/CCScrollView/CCTableView.cpp index 9842bfb836..46d38f4615 100644 --- a/extensions/GUI/CCScrollView/CCTableView.cpp +++ b/extensions/GUI/CCScrollView/CCTableView.cpp @@ -51,7 +51,7 @@ bool TableView::initWithViewSize(Size size, Node* container/* = NULL*/) { if (ScrollView::initWithViewSize(size,container)) { - _indices = new std::set(); + _indices = new std::set(); _vordering = VerticalFillOrder::BOTTOM_UP; this->setDirection(Direction::VERTICAL); From 2807e785c06f254fd5a3399dc2074769d65fd28f Mon Sep 17 00:00:00 2001 From: "Lee, Jae-Hong" Date: Sun, 15 Dec 2013 21:07:55 +0900 Subject: [PATCH 86/98] fix CCImage bug on android platform. - android.graphics.Bitmap bytes are aleady RGBA - delete swapAlphaChannel and swapAlpha --- cocos/2d/platform/android/CCImage.cpp | 37 --------------------------- 1 file changed, 37 deletions(-) diff --git a/cocos/2d/platform/android/CCImage.cpp b/cocos/2d/platform/android/CCImage.cpp index ba722d7fad..3a9dcc2f06 100644 --- a/cocos/2d/platform/android/CCImage.cpp +++ b/cocos/2d/platform/android/CCImage.cpp @@ -35,9 +35,6 @@ THE SOFTWARE. #include #include -// prototype -void swapAlphaChannel(unsigned int *pImageMemory, unsigned int numPixels); - NS_CC_BEGIN class BitmapDC @@ -129,12 +126,6 @@ public: return getBitmapFromJavaShadowStroke( text, nWidth, nHeight, eAlignMask, pFontName, fontSize ); } - // ARGB -> RGBA - inline unsigned int swapAlpha(unsigned int value) - { - return ((value << 8 & 0xffffff00) | (value >> 24 & 0x000000ff)); - } - public: int _width; int _height; @@ -228,9 +219,6 @@ bool Image::initWithStringShadowStroke( _renderFormat = Texture2D::PixelFormat::RGBA8888; _dataLen = _width * _height * 4; - // swap the alpha channel (ARGB to RGBA) - swapAlphaChannel((unsigned int *)_data, (_width * _height) ); - // ok bRet = true; @@ -241,19 +229,6 @@ bool Image::initWithStringShadowStroke( NS_CC_END -// swap the alpha channel in an 32 bit image (from ARGB to RGBA) -void swapAlphaChannel(unsigned int *pImageMemory, unsigned int numPixels) -{ - for(int c = 0; c < numPixels; ++c, ++pImageMemory) - { - // copy the current pixel - unsigned int currenPixel = (*pImageMemory); - // swap channels and store back - char *pSource = (char *) ¤Pixel; - *pImageMemory = (pSource[0] << 24) | (pSource[3]<<16) | (pSource[2]<<8) | pSource[1]; - } -} - // this method is called by Cocos2dxBitmap extern "C" { @@ -268,17 +243,5 @@ extern "C" bitmapDC._height = height; bitmapDC._data = new unsigned char[size]; env->GetByteArrayRegion(pixels, 0, size, (jbyte*)bitmapDC._data); - - // swap data - unsigned int *tempPtr = (unsigned int*)bitmapDC._data; - unsigned int tempdata = 0; - for (int i = 0; i < height; ++i) - { - for (int j = 0; j < width; ++j) - { - tempdata = *tempPtr; - *tempPtr++ = bitmapDC.swapAlpha(tempdata); - } - } } }; From f797dea827837335bac76815d603a78a0cfe767f Mon Sep 17 00:00:00 2001 From: xuzhiqiang Date: Mon, 16 Dec 2013 12:27:30 +0800 Subject: [PATCH 87/98] bug fix --- extensions/GUI/CCControlExtension/CCControlUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/GUI/CCControlExtension/CCControlUtils.cpp b/extensions/GUI/CCControlExtension/CCControlUtils.cpp index 476272370a..e660a29d8e 100644 --- a/extensions/GUI/CCControlExtension/CCControlUtils.cpp +++ b/extensions/GUI/CCControlExtension/CCControlUtils.cpp @@ -163,7 +163,7 @@ Rect ControlUtils::RectUnion(const Rect& src1, const Rect& src2) float x2 = MAX(src1.getMaxX(), src2.getMaxX()); float y2 = MAX(src1.getMaxY(), src2.getMaxY()); - result.origin=Point(x1,x2); + result.origin=Point(x1,y1); result.size=Size(x2-x1, y2-y1); return result; } From adb45d3c688e54475d0d2325757b8e1aec5eb4e7 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 12:02:58 +0800 Subject: [PATCH 88/98] Adds conversions for ssize_t. --- .../javascript/bindings/js_manual_conversions.cpp | 10 ++++++++++ .../javascript/bindings/js_manual_conversions.h | 2 ++ cocos/scripting/lua/bindings/LuaBasicConversions.cpp | 5 +++++ cocos/scripting/lua/bindings/LuaBasicConversions.h | 1 + 4 files changed, 18 insertions(+) diff --git a/cocos/scripting/javascript/bindings/js_manual_conversions.cpp b/cocos/scripting/javascript/bindings/js_manual_conversions.cpp index 9cfe63fec7..e171a3f81c 100644 --- a/cocos/scripting/javascript/bindings/js_manual_conversions.cpp +++ b/cocos/scripting/javascript/bindings/js_manual_conversions.cpp @@ -1105,6 +1105,11 @@ JSBool jsval_to_ccvaluevector(JSContext* cx, jsval v, cocos2d::ValueVector* ret) return JS_TRUE; } +JSBool jsval_to_ssize( JSContext *cx, jsval vp, ssize_t* ret) +{ + return jsval_to_long(cx, vp, static_cast(ret)); +} + // native --> jsval jsval ccarray_to_jsval(JSContext* cx, Array *arr) @@ -2021,3 +2026,8 @@ jsval ccvaluevector_to_jsval(JSContext* cx, const cocos2d::ValueVector& v) } return OBJECT_TO_JSVAL(jsretArr); } + +jsval ssize_to_jsval(JSContext *cx, ssize_t v) +{ + return long_to_jsval(cx, v); +} diff --git a/cocos/scripting/javascript/bindings/js_manual_conversions.h b/cocos/scripting/javascript/bindings/js_manual_conversions.h index 57ad197ec7..fc5cb72a18 100644 --- a/cocos/scripting/javascript/bindings/js_manual_conversions.h +++ b/cocos/scripting/javascript/bindings/js_manual_conversions.h @@ -113,6 +113,7 @@ JSBool jsval_to_ccvalue(JSContext* cx, jsval v, cocos2d::Value* ret); JSBool jsval_to_ccvaluemap(JSContext* cx, jsval v, cocos2d::ValueMap* ret); JSBool jsval_to_ccintvaluemap(JSContext* cx, jsval v, cocos2d::IntValueMap* ret); JSBool jsval_to_ccvaluevector(JSContext* cx, jsval v, cocos2d::ValueVector* ret); +JSBool jsval_to_ssize( JSContext *cx, jsval vp, ssize_t* ret); // from native jsval int32_to_jsval( JSContext *cx, int32_t l); @@ -172,6 +173,7 @@ jsval ccvalue_to_jsval(JSContext* cx, const cocos2d::Value& v); jsval ccvaluemap_to_jsval(JSContext* cx, const cocos2d::ValueMap& v); jsval ccintvaluemap_to_jsval(JSContext* cx, const cocos2d::IntValueMap& v); jsval ccvaluevector_to_jsval(JSContext* cx, const cocos2d::ValueVector& v); +jsval ssize_to_jsval(JSContext *cx, ssize_t v); #endif /* __JS_MANUAL_CONVERSIONS_H__ */ diff --git a/cocos/scripting/lua/bindings/LuaBasicConversions.cpp b/cocos/scripting/lua/bindings/LuaBasicConversions.cpp index 021a242b8c..11621b1eff 100644 --- a/cocos/scripting/lua/bindings/LuaBasicConversions.cpp +++ b/cocos/scripting/lua/bindings/LuaBasicConversions.cpp @@ -283,6 +283,11 @@ bool luaval_to_point(lua_State* L,int lo,Point* outValue) return ok; } +bool luaval_to_ssize(lua_State* L,int lo, long* outValue) +{ + return luaval_to_long(L, lo, outValue); +} + bool luaval_to_long(lua_State* L,int lo, long* outValue) { if (NULL == L || NULL == outValue) diff --git a/cocos/scripting/lua/bindings/LuaBasicConversions.h b/cocos/scripting/lua/bindings/LuaBasicConversions.h index d8b2cd45e8..91dd4b0eef 100644 --- a/cocos/scripting/lua/bindings/LuaBasicConversions.h +++ b/cocos/scripting/lua/bindings/LuaBasicConversions.h @@ -32,6 +32,7 @@ extern bool luaval_to_number(lua_State* L,int lo,double* outValue); extern bool luaval_to_long_long(lua_State* L,int lo,long long* outValue); extern bool luaval_to_std_string(lua_State* L, int lo, std::string* outValue); extern bool luaval_to_long(lua_State* L,int lo, long* outValue); +extern bool luaval_to_ssize(lua_State* L,int lo, long* outValue); extern bool luaval_to_point(lua_State* L,int lo,Point* outValue); extern bool luaval_to_size(lua_State* L,int lo,Size* outValue); From e32979592ad148bc727031c88a71438391fcb8ef Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 12:03:29 +0800 Subject: [PATCH 89/98] Skips Texture2D::getPixelFormatInfoMap --- tools/tojs/cocos2dx.ini | 2 +- tools/tolua/cocos2dx.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index bd3f409288..1d85c43665 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -56,7 +56,7 @@ skip = Node::[^setPosition$ setGrid setGLServerState description getUserObject . Label::[getLettersInfo], .*Delegate::[*], PoolManager::[*], - Texture2D::[initWithPVRTCData addPVRTCImage releaseData setTexParameters initWithData keepData], + Texture2D::[initWithPVRTCData addPVRTCImage releaseData setTexParameters initWithData keepData getPixelFormatInfoMap], Set::[begin end acceptVisitor], IMEDispatcher::[*], SAXParser::[*], diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index 36a6a98ed9..47a44a8cd8 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -54,7 +54,7 @@ skip = Node::[setGLServerState description getUserObject .*UserData getGLServerS LabelTextFormatProtocol::[*], .*Delegate::[*], PoolManager::[*], - Texture2D::[initWithPVRTCData addPVRTCImage releaseData setTexParameters initWithData keepData], + Texture2D::[initWithPVRTCData addPVRTCImage releaseData setTexParameters initWithData keepData getPixelFormatInfoMap], Set::[begin end acceptVisitor], IMEDispatcher::[*], SAXParser::[*], From 464054d251a1167cf294c24e8b5476ad26595b84 Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 12:03:50 +0800 Subject: [PATCH 90/98] Updates Bindings-generator. --- tools/bindings-generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bindings-generator b/tools/bindings-generator index 59f96e792a..f9888a85a6 160000 --- a/tools/bindings-generator +++ b/tools/bindings-generator @@ -1 +1 @@ -Subproject commit 59f96e792ab1a1b1a4b01b3ad8a8e7bb1bc281a8 +Subproject commit f9888a85a6a441ab25fd08f0bc2e443a7f99c107 From 3a11dafda7e84ed859334d8fd14b25234fc79e5b Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 14:13:24 +0800 Subject: [PATCH 91/98] Uses reinterpret_cast instead of static_cast for jsval_to_ssize and luaval_to_ssize. --- cocos/scripting/javascript/bindings/js_manual_conversions.cpp | 2 +- cocos/scripting/lua/bindings/LuaBasicConversions.cpp | 4 ++-- cocos/scripting/lua/bindings/LuaBasicConversions.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cocos/scripting/javascript/bindings/js_manual_conversions.cpp b/cocos/scripting/javascript/bindings/js_manual_conversions.cpp index e171a3f81c..a0ad1a1543 100644 --- a/cocos/scripting/javascript/bindings/js_manual_conversions.cpp +++ b/cocos/scripting/javascript/bindings/js_manual_conversions.cpp @@ -1107,7 +1107,7 @@ JSBool jsval_to_ccvaluevector(JSContext* cx, jsval v, cocos2d::ValueVector* ret) JSBool jsval_to_ssize( JSContext *cx, jsval vp, ssize_t* ret) { - return jsval_to_long(cx, vp, static_cast(ret)); + return jsval_to_long(cx, vp, reinterpret_cast(ret)); } // native --> jsval diff --git a/cocos/scripting/lua/bindings/LuaBasicConversions.cpp b/cocos/scripting/lua/bindings/LuaBasicConversions.cpp index 11621b1eff..7f96365a9f 100644 --- a/cocos/scripting/lua/bindings/LuaBasicConversions.cpp +++ b/cocos/scripting/lua/bindings/LuaBasicConversions.cpp @@ -283,9 +283,9 @@ bool luaval_to_point(lua_State* L,int lo,Point* outValue) return ok; } -bool luaval_to_ssize(lua_State* L,int lo, long* outValue) +bool luaval_to_ssize(lua_State* L,int lo, ssize_t* outValue) { - return luaval_to_long(L, lo, outValue); + return luaval_to_long(L, lo, reinterpret_cast(outValue)); } bool luaval_to_long(lua_State* L,int lo, long* outValue) diff --git a/cocos/scripting/lua/bindings/LuaBasicConversions.h b/cocos/scripting/lua/bindings/LuaBasicConversions.h index 91dd4b0eef..771040e368 100644 --- a/cocos/scripting/lua/bindings/LuaBasicConversions.h +++ b/cocos/scripting/lua/bindings/LuaBasicConversions.h @@ -32,7 +32,7 @@ extern bool luaval_to_number(lua_State* L,int lo,double* outValue); extern bool luaval_to_long_long(lua_State* L,int lo,long long* outValue); extern bool luaval_to_std_string(lua_State* L, int lo, std::string* outValue); extern bool luaval_to_long(lua_State* L,int lo, long* outValue); -extern bool luaval_to_ssize(lua_State* L,int lo, long* outValue); +extern bool luaval_to_ssize(lua_State* L,int lo, ssize_t* outValue); extern bool luaval_to_point(lua_State* L,int lo,Point* outValue); extern bool luaval_to_size(lua_State* L,int lo,Size* outValue); From ce96725f835f96e5c5b2b4e668e27786c8630bbc Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 14:14:12 +0800 Subject: [PATCH 92/98] Removes FileUtils::getFileData binding. --- tools/tojs/cocos2dx.ini | 2 +- tools/tolua/cocos2dx.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/tojs/cocos2dx.ini b/tools/tojs/cocos2dx.ini index 1d85c43665..6b993a980d 100644 --- a/tools/tojs/cocos2dx.ini +++ b/tools/tojs/cocos2dx.ini @@ -104,7 +104,7 @@ skip = Node::[^setPosition$ setGrid setGLServerState description getUserObject . TextureCache::[addPVRTCImage], Timer::[getSelector createWithScriptHandler], *::[copyWith.* onEnter.* onExit.* ^description$ getObjectType onTouch.* onAcc.* onKey.* onRegisterTouchListener], - FileUtils::[(g|s)etSearchResolutionsOrder$ (g|s)etSearchPaths$], + FileUtils::[(g|s)etSearchResolutionsOrder$ (g|s)etSearchPaths$ getFileData], Application::[^application.* ^run$], Camera::[getEyeXYZ getCenterXYZ getUpXYZ], ccFontDefinition::[*] diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index 47a44a8cd8..600ae55cc6 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -99,7 +99,7 @@ skip = Node::[setGLServerState description getUserObject .*UserData getGLServerS TextureCache::[addPVRTCImage], Timer::[getSelector createWithScriptHandler], *::[copyWith.* onEnter.* onExit.* ^description$ getObjectType (g|s)etDelegate onTouch.* onAcc.* onKey.* onRegisterTouchListener], - FileUtils::[(g|s)etSearchResolutionsOrder$ (g|s)etSearchPaths$], + FileUtils::[(g|s)etSearchResolutionsOrder$ (g|s)etSearchPaths$ getFileData], Application::[^application.* ^run$], Camera::[getEyeXYZ getCenterXYZ getUpXYZ], ccFontDefinition::[*], From 1e645cfcd5391b89c982df4ab037c7b030c126a5 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Mon, 16 Dec 2013 06:36:50 +0000 Subject: [PATCH 93/98] [AUTO] : updating submodule reference to latest autogenerated bindings --- cocos/scripting/auto-generated | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/scripting/auto-generated b/cocos/scripting/auto-generated index f4de47ad7f..579b1ccb7f 160000 --- a/cocos/scripting/auto-generated +++ b/cocos/scripting/auto-generated @@ -1 +1 @@ -Subproject commit f4de47ad7f5320151933233d3bcba60c8662586f +Subproject commit 579b1ccb7fe2400164d7117436be59fa2b5eb6a5 From d2ded2d780629ea10cb19e09444ddde83b4329d4 Mon Sep 17 00:00:00 2001 From: minggo Date: Mon, 16 Dec 2013 15:28:47 +0800 Subject: [PATCH 94/98] [ci skip] --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c8a8607ac8..c5e79f412d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,7 @@ cocos2d-x-3.0beta0 ?? 2013 [All] [NEW] Upgrated Box2D to 2.3.0 - [NEW] Added ThreadHelper, ThreadHelper::runOnGLThread() simplify invoking engine codes and OpenGL ES commands in a thread other then gl thread. + [NEW] SChedule::performFunctionInCocosThread() [NEW] Added tga format support again. [Android] [NEW] build/android-build.sh: add supporting to generate .apk file From 545000a213ede6a93033e51b7a77a39172cf61d4 Mon Sep 17 00:00:00 2001 From: Nite Luo Date: Mon, 16 Dec 2013 17:40:34 +0800 Subject: [PATCH 95/98] Add mouse scrolling support for extension test --- .../Classes/ExtensionsTest/ExtensionsTest.cpp | 30 +++++++++++++++++++ .../Classes/ExtensionsTest/ExtensionsTest.h | 3 ++ 2 files changed, 33 insertions(+) diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp index 96089e9a2c..3444655173 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.cpp @@ -124,9 +124,15 @@ void ExtensionsMainLayer::onEnter() _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); + auto mouseListener = EventListenerMouse::create(); + mouseListener->onMouseScroll = CC_CALLBACK_1(ExtensionsMainLayer::onMouseScroll, this); + + _eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this); + addChild(_itemMenu); } + void ExtensionsMainLayer::onTouchesBegan(const std::vector& touches, Event *event) { auto touch = static_cast(touches[0]); @@ -161,6 +167,30 @@ void ExtensionsMainLayer::onTouchesMoved(const std::vector& touches, Eve s_tCurPos = nextPos; } +void ExtensionsMainLayer::onMouseScroll(Event* event) +{ + auto mouseEvent = static_cast(event); + float nMoveY = mouseEvent->getScrollY() * 6; + + auto curPos = _itemMenu->getPosition(); + auto nextPos = Point(curPos.x, curPos.y + nMoveY); + + if (nextPos.y < 0.0f) + { + _itemMenu->setPosition(Point::ZERO); + return; + } + + if (nextPos.y > ((g_maxTests + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height)) + { + _itemMenu->setPosition(Point(0, ((g_maxTests + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height))); + return; + } + + _itemMenu->setPosition(nextPos); + s_tCurPos = nextPos; +} + //////////////////////////////////////////////////////// // // ExtensionsTestScene diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h index abf411fbce..d4c1fe905a 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/ExtensionsTest.h @@ -15,6 +15,9 @@ public: Menu* _itemMenu; int _testcount; + +protected: + void onMouseScroll(Event* event); }; class ExtensionsTestScene : public TestScene From 3a1ffca8900be6ad07b27b3436b64759b3fb5e1b Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 17:46:38 +0800 Subject: [PATCH 96/98] Update CHANGELOG [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index c5e79f412d..74875880c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ cocos2d-x-3.0beta0 ?? 2013 [NEW] Upgrated Box2D to 2.3.0 [NEW] SChedule::performFunctionInCocosThread() [NEW] Added tga format support again. + [FIX] A Logic error in ControlUtils::RectUnion. [Android] [NEW] build/android-build.sh: add supporting to generate .apk file [FIX] XMLHttpRequest receives wrong binary array. From 41bb9eb4b8f834f86976f5aa3b7b3d624fe043ee Mon Sep 17 00:00:00 2001 From: James Chen Date: Mon, 16 Dec 2013 17:48:59 +0800 Subject: [PATCH 97/98] Update AUTHORS [ci skip] --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index ce0802b6e3..0a7ef1b315 100644 --- a/AUTHORS +++ b/AUTHORS @@ -666,6 +666,9 @@ Developers: hulefei Added gui namespace before SEL_TouchEvent. + zhiqiangxu + Fixed a logic error in ControlUtils::RectUnion. + Retired Core Developers: WenSheng Yang Author of windows port, CCTextField, From bc868cc004135bb2e08e9424d459306961afe9c5 Mon Sep 17 00:00:00 2001 From: yinkaile Date: Tue, 17 Dec 2013 17:00:01 +0800 Subject: [PATCH 98/98] update armature to new render --- .../editor-support/cocostudio/CCArmature.cpp | 91 ++----------------- cocos/editor-support/cocostudio/CCArmature.h | 15 +-- .../editor-support/cocostudio/CCBatchNode.cpp | 78 ++++------------ cocos/editor-support/cocostudio/CCBatchNode.h | 9 +- cocos/editor-support/cocostudio/CCSkin.cpp | 12 +-- .../CocoStudioArmatureTest/ArmatureScene.cpp | 22 ++--- .../CocoStudioArmatureTest/ArmatureScene.h | 2 +- 7 files changed, 57 insertions(+), 172 deletions(-) diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index 5646dedbd5..3a239d9395 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -28,6 +28,9 @@ THE SOFTWARE. #include "cocostudio/CCDataReaderHelper.h" #include "cocostudio/CCDatas.h" #include "cocostudio/CCSkin.h" +#include "QuadCommand.h" +#include "Renderer.h" +#include "GroupCommand.h" #if ENABLE_PHYSICS_BOX2D_DETECT #include "Box2D/Box2D.h" @@ -80,13 +83,11 @@ Armature *Armature::create(const char *name, Bone *parentBone) Armature::Armature() : _armatureData(nullptr) , _batchNode(nullptr) - , _atlas(nullptr) , _parentBone(nullptr) , _armatureTransformDirty(true) , _boneDic(nullptr) , _topBoneList(nullptr) , _animation(nullptr) - , _textureAtlasDic(nullptr) { } @@ -104,7 +105,6 @@ Armature::~Armature(void) CC_SAFE_DELETE(_topBoneList); } CC_SAFE_DELETE(_animation); - CC_SAFE_RELEASE_NULL(_textureAtlasDic); } @@ -132,9 +132,6 @@ bool Armature::init(const char *name) _topBoneList = new Array(); _topBoneList->init(); - CC_SAFE_DELETE(_textureAtlasDic); - _textureAtlasDic = new Dictionary(); - _blendFunc.src = CC_BLEND_SRC; _blendFunc.dst = CC_BLEND_DST; @@ -468,9 +465,9 @@ void Armature::draw() if (_parentBone == nullptr && _batchNode == nullptr) { CC_NODE_DRAW_SETUP(); - GL::blendFunc(_blendFunc.src, _blendFunc.dst); } + for (auto object : _children) { if (Bone *bone = dynamic_cast(object)) @@ -485,84 +482,37 @@ void Armature::draw() case CS_DISPLAY_SPRITE: { Skin *skin = static_cast(node); - - TextureAtlas *textureAtlas = skin->getTextureAtlas(); - BlendType blendType = bone->getBlendType(); - if(_atlas != textureAtlas || blendType != BLEND_NORMAL) - { - if (_atlas) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } - } - - _atlas = textureAtlas; - if (_atlas->getCapacity() == _atlas->getTotalQuads() && !_atlas->resizeCapacity(_atlas->getCapacity() * 2)) - return; - skin->updateTransform(); - + + BlendType blendType = bone->getBlendType(); + if (blendType != BLEND_NORMAL) { updateBlendType(blendType); - _atlas->drawQuads(); - _atlas->removeAllQuads(); - GL::blendFunc(_blendFunc.src, _blendFunc.dst); + skin->setBlendFunc(_blendFunc); } + skin->draw(); } break; case CS_DISPLAY_ARMATURE: { - Armature *armature = static_cast(node); - - TextureAtlas *textureAtlas = armature->getTextureAtlas(); - if(_atlas != textureAtlas) - { - if (_atlas) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } - } - armature->draw(); - _atlas = armature->getTextureAtlas(); + node->draw(); } break; default: { - if (_atlas) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } node->visit(); - CC_NODE_DRAW_SETUP(); - GL::blendFunc(_blendFunc.src, _blendFunc.dst); } break; } } else if(Node *node = dynamic_cast(object)) { - if (_atlas) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } node->visit(); - CC_NODE_DRAW_SETUP(); - GL::blendFunc(_blendFunc.src, _blendFunc.dst); } } - - if(_atlas && !_batchNode && _parentBone == nullptr) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } } @@ -690,27 +640,6 @@ Bone *Armature::getBoneAtPoint(float x, float y) const return nullptr; } -TextureAtlas *Armature::getTexureAtlasWithTexture(Texture2D *texture) const -{ - int key = texture->getName(); - - if (_parentBone && _parentBone->getArmature()) - { - return _parentBone->getArmature()->getTexureAtlasWithTexture(texture); - } - else if (_batchNode) - { - _batchNode->getTexureAtlasWithTexture(texture); - } - - TextureAtlas *atlas = static_cast(_textureAtlasDic->objectForKey(key)); - if (atlas == nullptr) - { - atlas = TextureAtlas::createWithTexture(texture, 4); - _textureAtlasDic->setObject(atlas, key); - } - return atlas; -} void Armature::setParentBone(Bone *parentBone) { diff --git a/cocos/editor-support/cocostudio/CCArmature.h b/cocos/editor-support/cocostudio/CCArmature.h index 0abd7b528c..0a6b76ca98 100644 --- a/cocos/editor-support/cocostudio/CCArmature.h +++ b/cocos/editor-support/cocostudio/CCArmature.h @@ -184,22 +184,15 @@ public: virtual bool getArmatureTransformDirty() const; - virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture) const; - virtual void setColliderFilter(ColliderFilter *filter); virtual void setArmatureData(ArmatureData *armatureData) { _armatureData = armatureData; } virtual ArmatureData *getArmatureData() const { return _armatureData; } - virtual void setBatchNode(BatchNode *batchNode) { _batchNode = batchNode; } - virtual BatchNode *getBatchNode() const { return _batchNode; } - virtual void setName(const std::string &name) { _name = name; } virtual const std::string &getName() const { return _name; } - virtual void setTextureAtlas(cocos2d::TextureAtlas *atlas) { _atlas = atlas; } - virtual cocos2d::TextureAtlas *getTextureAtlas() const { return _atlas; } virtual void setParentBone(Bone *parentBone); virtual Bone *getParentBone() const; @@ -207,6 +200,9 @@ public: virtual void setVersion(float version) { _version = version; } virtual float getVersion() const { return _version; } + virtual void setBatchNode(BatchNode *batchNode) { _batchNode = batchNode; } + virtual BatchNode *getBatchNode() const { return _batchNode; } + #if ENABLE_PHYSICS_BOX2D_DETECT virtual b2Fixture *getShapeList(); /** @@ -254,9 +250,10 @@ protected: protected: ArmatureData *_armatureData; + BatchNode *_batchNode; + std::string _name; - cocos2d::TextureAtlas *_atlas; Bone *_parentBone; float _version; @@ -272,8 +269,6 @@ protected: ArmatureAnimation *_animation; - cocos2d::Dictionary *_textureAtlasDic; - #if ENABLE_PHYSICS_BOX2D_DETECT b2Body *_body; #elif ENABLE_PHYSICS_CHIPMUNK_DETECT diff --git a/cocos/editor-support/cocostudio/CCBatchNode.cpp b/cocos/editor-support/cocostudio/CCBatchNode.cpp index 844e25f286..1963cdd2fc 100644 --- a/cocos/editor-support/cocostudio/CCBatchNode.cpp +++ b/cocos/editor-support/cocostudio/CCBatchNode.cpp @@ -26,6 +26,8 @@ THE SOFTWARE. #include "cocostudio/CCArmatureDefine.h" #include "cocostudio/CCArmature.h" #include "cocostudio/CCSkin.h" +#include "Renderer.h" +#include "GroupCommand.h" using namespace cocos2d; @@ -44,14 +46,11 @@ BatchNode *BatchNode::create() } BatchNode::BatchNode() - : _atlas(nullptr) - , _textureAtlasDic(nullptr) { } BatchNode::~BatchNode() { - CC_SAFE_RELEASE_NULL(_textureAtlasDic); } bool BatchNode::init() @@ -59,9 +58,6 @@ bool BatchNode::init() bool ret = Node::init(); setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR)); - CC_SAFE_DELETE(_textureAtlasDic); - _textureAtlasDic = new Dictionary(); - return ret; } @@ -82,24 +78,6 @@ void BatchNode::addChild(Node *child, int zOrder, int tag) if (armature != nullptr) { armature->setBatchNode(this); - - const Dictionary *dict = armature->getBoneDic(); - DictElement *element = nullptr; - CCDICT_FOREACH(dict, element) - { - Bone *bone = static_cast(element->getObject()); - - Array *displayList = bone->getDisplayManager()->getDecorativeDisplayList(); - for(auto object : *displayList) - { - DecorativeDisplay *display = static_cast(object); - - if (Skin *skin = dynamic_cast(display->getDisplay())) - { - skin->setTextureAtlas(getTexureAtlasWithTexture(skin->getTexture())); - } - } - } } } @@ -109,24 +87,6 @@ void BatchNode::removeChild(Node* child, bool cleanup) if (armature != nullptr) { armature->setBatchNode(nullptr); - - const Dictionary *dict = armature->getBoneDic(); - DictElement *element = nullptr; - CCDICT_FOREACH(dict, element) - { - Bone *bone = static_cast(element->getObject()); - - Array *displayList = bone->getDisplayManager()->getDecorativeDisplayList(); - for(auto object : *displayList) - { - DecorativeDisplay *display = static_cast(object); - - if (Skin *skin = dynamic_cast(display->getDisplay())) - { - skin->setTextureAtlas(armature->getTexureAtlasWithTexture(skin->getTexture())); - } - } - } } Node::removeChild(child, cleanup); @@ -169,39 +129,41 @@ void BatchNode::draw() } CC_NODE_DRAW_SETUP(); + + generateGroupCommand(); for(auto object : _children) { Armature *armature = dynamic_cast(object); if (armature) { + if (_popGroupCommand) + { + generateGroupCommand(); + } + armature->visit(); - _atlas = armature->getTextureAtlas(); } else { + Renderer::getInstance()->popGroup(); + _popGroupCommand = true; + ((Node *)object)->visit(); } } - - if (_atlas) - { - _atlas->drawQuads(); - _atlas->removeAllQuads(); - } } -TextureAtlas *BatchNode::getTexureAtlasWithTexture(Texture2D *texture) const +void BatchNode::generateGroupCommand() { - int key = texture->getName(); + Renderer* renderer = Renderer::getInstance(); + GroupCommand* groupCommand = GroupCommand::getCommandPool().generateCommand(); + groupCommand->init(0,_vertexZ); + renderer->addCommand(groupCommand); + + renderer->pushGroup(groupCommand->getRenderQueueID()); - TextureAtlas *atlas = static_cast(_textureAtlasDic->objectForKey(key)); - if (atlas == nullptr) - { - atlas = CCTextureAtlas::createWithTexture(texture, 4); - _textureAtlasDic->setObject(atlas, key); - } - return atlas; + _popGroupCommand = false; } } diff --git a/cocos/editor-support/cocostudio/CCBatchNode.h b/cocos/editor-support/cocostudio/CCBatchNode.h index 0d956b5787..a068af5716 100644 --- a/cocos/editor-support/cocostudio/CCBatchNode.h +++ b/cocos/editor-support/cocostudio/CCBatchNode.h @@ -60,11 +60,12 @@ public: * @js NA */ void draw() override; - - virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture) const; + + void setPopGroupCommand(bool pop) { _popGroupCommand = pop; } protected: - cocos2d::TextureAtlas *_atlas; - cocos2d::Dictionary *_textureAtlasDic; + void generateGroupCommand(); + + bool _popGroupCommand; }; } diff --git a/cocos/editor-support/cocostudio/CCSkin.cpp b/cocos/editor-support/cocostudio/CCSkin.cpp index 5886b59850..7b4a100069 100644 --- a/cocos/editor-support/cocostudio/CCSkin.cpp +++ b/cocos/editor-support/cocostudio/CCSkin.cpp @@ -135,11 +135,11 @@ const BaseData &Skin::getSkinData() const void Skin::updateArmatureTransform() { - _transform = TransformConcat(_skinTransform, _bone->getNodeToArmatureTransform()); - if(_armature && _armature->getBatchNode()) - { - _transform = TransformConcat(_transform, _armature->getNodeToParentTransform()); - } + _transform = TransformConcat(_bone->getNodeToArmatureTransform(), _skinTransform); +// if(_armature && _armature->getBatchNode()) +// { +// _transform = TransformConcat(_transform, _armature->getNodeToParentTransform()); +// } } void Skin::updateTransform() @@ -219,8 +219,6 @@ void Skin::setBone(Bone *bone) if(Armature *armature = _bone->getArmature()) { _armature = armature; - TextureAtlas *atlas = armature->getTexureAtlasWithTexture(_texture); - setTextureAtlas(atlas); } } diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp index 8bd9af7a80..cde9468739 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp @@ -33,9 +33,9 @@ Layer *CreateLayer(int index) case TEST_PERFORMANCE: pLayer = new TestPerformance(); break; - case TEST_PERFORMANCE_BATCHNODE: - pLayer = new TestPerformanceBatchNode(); - break; +// case TEST_PERFORMANCE_BATCHNODE: +// pLayer = new TestPerformanceBatchNode(); +// break; case TEST_CHANGE_ZORDER: pLayer = new TestChangeZorder(); break; @@ -597,14 +597,14 @@ void TestFrameEvent::onFrameEvent(Bone *bone, const char *evt, int originFrameIn CCLOG("(%s) emit a frame event (%s) at frame index (%d).", bone->getName().c_str(), evt, currentFrameIndex); - if (!this->getActionByTag(FRAME_EVENT_ACTION_TAG) || this->getActionByTag(FRAME_EVENT_ACTION_TAG)->isDone()) - { - this->stopAllActions(); - - ActionInterval *action = ShatteredTiles3D::create(0.2f, Size(16,12), 5, false); - action->setTag(FRAME_EVENT_ACTION_TAG); - this->runAction(action); - } +// if (!this->getActionByTag(FRAME_EVENT_ACTION_TAG) || this->getActionByTag(FRAME_EVENT_ACTION_TAG)->isDone()) +// { +// this->stopAllActions(); +// +// ActionInterval *action = ShatteredTiles3D::create(0.2f, Size(16,12), 5, false); +// action->setTag(FRAME_EVENT_ACTION_TAG); +// this->runAction(action); +// } } void TestFrameEvent::checkAction(float dt) { diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h index dc0eed2493..ce109b70df 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.h @@ -31,7 +31,7 @@ enum { TEST_COCOSTUDIO_WITH_SKELETON, TEST_DRAGON_BONES_2_0, TEST_PERFORMANCE, - TEST_PERFORMANCE_BATCHNODE, +// TEST_PERFORMANCE_BATCHNODE, TEST_CHANGE_ZORDER, TEST_ANIMATION_EVENT, TEST_FRAME_EVENT,