From f269d7345e2733374294448a5131cc94a8545410 Mon Sep 17 00:00:00 2001 From: "Huabing.Xu" Date: Fri, 1 Aug 2014 14:46:35 +0800 Subject: [PATCH] original version of PrimitiveCommand --- build/cocos2d_libs.xcodeproj/project.pbxproj | 8 ++ cocos/renderer/CCPrimitive.cpp | 49 +++++++++++ cocos/renderer/CCPrimitive.h | 3 + cocos/renderer/CCPrimitiveCommand.cpp | 85 ++++++++++++++++++++ cocos/renderer/CCPrimitiveCommand.h | 63 +++++++++++++++ cocos/renderer/CCRenderCommand.h | 1 + cocos/renderer/CCVertexIndexBuffer.h | 4 + cocos/renderer/CCVertexIndexData.cpp | 74 ++++++++++++++--- cocos/renderer/CCVertexIndexData.h | 26 +++--- 9 files changed, 289 insertions(+), 24 deletions(-) create mode 100644 cocos/renderer/CCPrimitiveCommand.cpp create mode 100644 cocos/renderer/CCPrimitiveCommand.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 89970df4a0..f3a0e45d24 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1256,6 +1256,8 @@ B257B44F1989D5E800D9A687 /* CCPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */; }; B257B4501989D5E800D9A687 /* CCPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B44D1989D5E800D9A687 /* CCPrimitive.h */; }; B257B4511989D5E800D9A687 /* CCPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B44D1989D5E800D9A687 /* CCPrimitive.h */; }; + B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; }; + B257B461198A353E00D9A687 /* CCPrimitiveCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B45F198A353E00D9A687 /* CCPrimitiveCommand.h */; }; B276EF5F1988D1D500CD400F /* CCVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */; }; B276EF601988D1D500CD400F /* CCVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */; }; B276EF611988D1D500CD400F /* CCVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5C1988D1D500CD400F /* CCVertexIndexData.cpp */; }; @@ -2992,6 +2994,8 @@ B24EEA8619775EF3004493CC /* libnetwork iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libnetwork iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPrimitive.cpp; sourceTree = ""; }; B257B44D1989D5E800D9A687 /* CCPrimitive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPrimitive.h; sourceTree = ""; }; + B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPrimitiveCommand.cpp; sourceTree = ""; }; + B257B45F198A353E00D9A687 /* CCPrimitiveCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPrimitiveCommand.h; sourceTree = ""; }; B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCVertexIndexData.h; sourceTree = ""; }; B276EF5C1988D1D500CD400F /* CCVertexIndexData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCVertexIndexData.cpp; sourceTree = ""; }; B276EF5D1988D1D500CD400F /* CCVertexIndexBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCVertexIndexBuffer.h; sourceTree = ""; }; @@ -4922,6 +4926,8 @@ 50ABBD821925AB4100A911A9 /* CCTextureCache.h */, B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */, B257B44D1989D5E800D9A687 /* CCPrimitive.h */, + B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */, + B257B45F198A353E00D9A687 /* CCPrimitiveCommand.h */, 5034CA5D191D591900CE6051 /* shaders */, ); name = renderer; @@ -5379,6 +5385,7 @@ 5034CA35191D591100CE6051 /* ccShader_PositionTexture.frag in Headers */, 50ABBE6F1925AB6F00A911A9 /* CCEventListenerKeyboard.h in Headers */, 50ABBE9D1925AB6F00A911A9 /* CCRefPtr.h in Headers */, + B257B461198A353E00D9A687 /* CCPrimitiveCommand.h in Headers */, 5034CA31191D591100CE6051 /* ccShader_PositionTexture_uColor.vert in Headers */, 50ABBE7B1925AB6F00A911A9 /* CCEventMouse.h in Headers */, 503DD8F91926B0DB00CD74DD /* CCIMEDispatcher.h in Headers */, @@ -6753,6 +6760,7 @@ 50ABBEBF1925AB6F00A911A9 /* CCValue.cpp in Sources */, 1A570098180BC5C10088DEC7 /* CCAtlasNode.cpp in Sources */, 1A57009E180BC5D20088DEC7 /* CCNode.cpp in Sources */, + B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */, 50ABBE651925AB6F00A911A9 /* CCEventListenerCustom.cpp in Sources */, B37510781823AC9F00B3BA6A /* CCPhysicsShapeInfo_chipmunk.cpp in Sources */, 50ABBE391925AB6F00A911A9 /* CCData.cpp in Sources */, diff --git a/cocos/renderer/CCPrimitive.cpp b/cocos/renderer/CCPrimitive.cpp index 7f7656ea7b..4ca169a2d7 100644 --- a/cocos/renderer/CCPrimitive.cpp +++ b/cocos/renderer/CCPrimitive.cpp @@ -87,4 +87,53 @@ bool Primitive::init(VertexData* verts, IndexData* indices, PrimitiveType type) return true; } +void Primitive::draw() +{ + if(_verts && _indices) + { + _verts->use(); + switch (_type) { + case PrimitiveType::POINTS: + if(_indices->getIndexBuffer() != nullptr) + { + GLenum type = (_indices->getIndexBuffer()->getType() == IndexBuffer::IndexType::INDEX_TYPE_SHORT_16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indices->getIndexBuffer()->getVBO()); + glDrawElements(GL_POINTS, _indices->getCount(), type, (GLvoid*)_indices->getStart()); + } + else + { + glDrawArrays(GL_POINTS, _indices->getStart(), _indices->getCount()); + } + break; + case PrimitiveType::LINES: + if(_indices->getIndexBuffer() != nullptr) + { + GLenum type = (_indices->getIndexBuffer()->getType() == IndexBuffer::IndexType::INDEX_TYPE_SHORT_16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indices->getIndexBuffer()->getVBO()); + glDrawElements(GL_LINES, _indices->getCount(), type, (GLvoid*)_indices->getStart()); + } + else + { + glDrawArrays(GL_LINES, _indices->getStart(), _indices->getCount()); + } + break; + case PrimitiveType::TRIANGLES: + if(_indices->getIndexBuffer() != nullptr) + { + GLenum type = (_indices->getIndexBuffer()->getType() == IndexBuffer::IndexType::INDEX_TYPE_SHORT_16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indices->getIndexBuffer()->getVBO()); + glDrawElements(GL_TRIANGLES, _indices->getCount(), type, (GLvoid*)_indices->getStart()); + } + else + { + glDrawArrays(GL_TRIANGLES, _indices->getStart(), _indices->getCount()); + } + break; + default: + CC_ASSERT(0); + break; + } + } +} + NS_CC_END diff --git a/cocos/renderer/CCPrimitive.h b/cocos/renderer/CCPrimitive.h index 9da609d803..c9ef6f5e50 100644 --- a/cocos/renderer/CCPrimitive.h +++ b/cocos/renderer/CCPrimitive.h @@ -48,6 +48,9 @@ public: IndexData* getIndexData(); PrimitiveType getType() const { return _type; } + + //called by rendering framework + void draw(); protected: Primitive(); virtual ~Primitive(); diff --git a/cocos/renderer/CCPrimitiveCommand.cpp b/cocos/renderer/CCPrimitiveCommand.cpp new file mode 100644 index 0000000000..84d9f89f8d --- /dev/null +++ b/cocos/renderer/CCPrimitiveCommand.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** + Copyright (c) 2008-2010 Ricardo Quesada + Copyright (c) 2010-2012 cocos2d-x.org + Copyright (c) 2011 Zynga Inc. + Copyright (c) 2013-2014 Chukong Technologies Inc. + + 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 "CCPrimitiveCommand.h" + +#include "renderer/ccGLStateCache.h" +#include "renderer/CCGLProgram.h" +#include "renderer/CCGLProgramState.h" +#include "xxhash.h" + +NS_CC_BEGIN + +PrimitiveCommand::PrimitiveCommand() +: _materialID(0) +, _textureID(0) +, _glProgramState(nullptr) +, _blendType(BlendFunc::DISABLE) +, _primitive(nullptr) +{ + _type = RenderCommand::Type::PRIMITIVE_COMMAND; +} + +PrimitiveCommand::~PrimitiveCommand() +{ +} + +void PrimitiveCommand::init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, Primitive* primitive,const Mat4& mv) +{ + CCASSERT(glProgramState, "Invalid GLProgramState"); + CCASSERT(glProgramState->getVertexAttribsFlags() == 0, "No custom attributes are supported in PrimitiveCommand"); + CCASSERT(primitive != nullptr, "Could not render null primitive"); + + _globalOrder = globalOrder; + + _primitive = primitive; + + _mv = mv; + + if( _textureID != textureID || _blendType.src != blendType.src || _blendType.dst != blendType.dst || _glProgramState != glProgramState) { + + _textureID = textureID; + _blendType = blendType; + _glProgramState = glProgramState; + + } +} + +void PrimitiveCommand::execute() const +{ + //Set texture + GL::bindTexture2D(_textureID); + + //set blend mode + GL::blendFunc(_blendType.src, _blendType.dst); + + _glProgramState->apply(_mv); + + _primitive->draw(); +} + +NS_CC_END diff --git a/cocos/renderer/CCPrimitiveCommand.h b/cocos/renderer/CCPrimitiveCommand.h new file mode 100644 index 0000000000..2240246c75 --- /dev/null +++ b/cocos/renderer/CCPrimitiveCommand.h @@ -0,0 +1,63 @@ +/**************************************************************************** + Copyright (c) 2008-2010 Ricardo Quesada + Copyright (c) 2010-2012 cocos2d-x.org + Copyright (c) 2011 Zynga Inc. + Copyright (c) 2013-2014 Chukong Technologies Inc. + + 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 _CC_PRIMITIVE_COMMAND_H__ +#define _CC_PRIMITIVE_COMMAND_H__ + +#include "renderer/CCPrimitive.h" +#include "renderer/CCRenderCommand.h" + +NS_CC_BEGIN +class GLProgramState; +class PrimitiveCommand : public RenderCommand +{ +public: + PrimitiveCommand(); + ~PrimitiveCommand(); + + void init(float globalOrder, GLuint textureID, GLProgramState* glProgramState, BlendFunc blendType, Primitive* primitive,const Mat4& mv); + + inline uint32_t getMaterialID() const { return _materialID; } + inline GLuint getTextureID() const { return _textureID; } + inline GLProgramState* getGLProgramState() const { return _glProgramState; } + inline BlendFunc getBlendType() const { return _blendType; } + inline const Mat4& getModelView() const { return _mv; } + + void execute() const; +protected: + + uint32_t _materialID; + GLuint _textureID; + GLProgramState* _glProgramState; + BlendFunc _blendType; + Primitive* _primitive; + Mat4 _mv; +}; + +NS_CC_END + +#endif //_CC_PRIMITIVE_COMMAND_H__ diff --git a/cocos/renderer/CCRenderCommand.h b/cocos/renderer/CCRenderCommand.h index 22ebd6095f..77332e01b0 100644 --- a/cocos/renderer/CCRenderCommand.h +++ b/cocos/renderer/CCRenderCommand.h @@ -49,6 +49,7 @@ public: BATCH_COMMAND, GROUP_COMMAND, MESH_COMMAND, + PRIMITIVE_COMMAND, }; /** Get Render Command Id */ diff --git a/cocos/renderer/CCVertexIndexBuffer.h b/cocos/renderer/CCVertexIndexBuffer.h index 22b2279c63..093ea3e123 100644 --- a/cocos/renderer/CCVertexIndexBuffer.h +++ b/cocos/renderer/CCVertexIndexBuffer.h @@ -45,6 +45,8 @@ public: int getSize() const; + GLuint getVBO() const { return _vbo; } + protected: VertexBuffer(); virtual ~VertexBuffer(); @@ -76,6 +78,8 @@ public: //bool getIndices(void* indices, int count, int begin); int getSize() const; + + GLuint getVBO() const { return _vbo; } protected: IndexBuffer(); diff --git a/cocos/renderer/CCVertexIndexData.cpp b/cocos/renderer/CCVertexIndexData.cpp index a962de5f09..14a169b6fe 100644 --- a/cocos/renderer/CCVertexIndexData.cpp +++ b/cocos/renderer/CCVertexIndexData.cpp @@ -46,15 +46,14 @@ size_t VertexData::getVertexStreamCount() const return _vertexStreams.size(); } -bool VertexData::setStream(int index, VertexBuffer* buffer, const VertexStreamAttribute& stream) +bool VertexData::setStream(VertexBuffer* buffer, const VertexStreamAttribute& stream) { if( buffer == nullptr ) return false; - - auto iter = _vertexStreams.find(index); + auto iter = _vertexStreams.find(stream._semantic); if(iter == _vertexStreams.end()) { buffer->retain(); - auto& bufferAttribute = _vertexStreams[index]; + auto& bufferAttribute = _vertexStreams[stream._semantic]; bufferAttribute._buffer = buffer; bufferAttribute._stream = stream; } @@ -69,9 +68,9 @@ bool VertexData::setStream(int index, VertexBuffer* buffer, const VertexStreamAt return true; } -void VertexData::removeStream(int index) +void VertexData::removeStream(VertexSemantic semantic) { - auto iter = _vertexStreams.find(index); + auto iter = _vertexStreams.find(semantic); if(iter != _vertexStreams.end()) { iter->second._buffer->release(); @@ -79,23 +78,23 @@ void VertexData::removeStream(int index) } } -const VertexStreamAttribute* VertexData::getStreamAttribute(int index) const +const VertexStreamAttribute* VertexData::getStreamAttribute(VertexSemantic semantic) const { - auto iter = _vertexStreams.find(index); + auto iter = _vertexStreams.find(semantic); if(iter == _vertexStreams.end()) return nullptr; else return &iter->second._stream; } -VertexStreamAttribute* VertexData::getStreamAttribute(int index) +VertexStreamAttribute* VertexData::getStreamAttribute(VertexSemantic semantic) { - auto iter = _vertexStreams.find(index); + auto iter = _vertexStreams.find(semantic); if(iter == _vertexStreams.end()) return nullptr; else return &iter->second._stream; } -VertexBuffer* VertexData::getStreamBuffer(int index) const +VertexBuffer* VertexData::getStreamBuffer(VertexSemantic semantic) const { - auto iter = _vertexStreams.find(index); + auto iter = _vertexStreams.find(semantic); if(iter == _vertexStreams.end()) return nullptr; else return iter->second._buffer; } @@ -114,6 +113,55 @@ VertexData::~VertexData() _vertexStreams.clear(); } +GLint VertexData::getGLSize(VertexType type) +{ + if(VertexType::FLOAT1 == type) + { + return 1; + } + else if(VertexType::FLOAT2 == type) + { + return 2; + } + else if(VertexType::FLOAT3 == type) + { + return 3; + } + else + { + return 4; + } +} + +GLenum VertexData::getGLType(VertexType type) +{ + if(VertexType::BYTE4 == type) + { + return GL_UNSIGNED_BYTE; + } + else + { + return GL_FLOAT; + } +} + +GLint VertexData::getGLSemanticBinding(VertexSemantic semantic) +{ + return GLint(semantic); +} + +void VertexData::use() +{ + for(auto& element : _vertexStreams) + { + glEnableVertexAttribArray(getGLSemanticBinding(element.second._stream._semantic)); + glBindBuffer(GL_ARRAY_BUFFER, element.second._buffer->getVBO()); + glVertexAttribPointer(getGLSemanticBinding(element.second._stream._semantic),getGLSize(element.second._stream._type), + getGLType(element.second._stream._type),false, element.second._buffer->getSizePerVertex(), (GLvoid*)element.second._stream._offset); + + } +} + IndexData* IndexData::create(IndexBuffer* buffer, int start, int count) { IndexData* result = new (std::nothrow) IndexData(); @@ -143,7 +191,7 @@ IndexData::~IndexData() bool IndexData::init(IndexBuffer* buffer, int start, int count) { - if(count == 0)return false; + if(count == 0) return false; if(_buffer != buffer) { CC_SAFE_RELEASE_NULL(_buffer); diff --git a/cocos/renderer/CCVertexIndexData.h b/cocos/renderer/CCVertexIndexData.h index 1610d3a0e2..c4e15afb83 100644 --- a/cocos/renderer/CCVertexIndexData.h +++ b/cocos/renderer/CCVertexIndexData.h @@ -37,9 +37,9 @@ NS_CC_BEGIN class VertexBuffer; -enum class VertexSemantic +enum VertexSemantic { - UNKNOWN, + UNKNOWN = -1, POSITION, COLOR, NORMAL, @@ -64,10 +64,9 @@ enum class VertexType struct VertexStreamAttribute { VertexStreamAttribute() - : _index(-1), _offset(0),_semantic(VertexSemantic::UNKNOWN),_type(VertexType::UNKNOWN) + : _offset(0),_semantic(VertexSemantic::UNKNOWN),_type(VertexType::UNKNOWN) { } - int _index; int _offset; VertexSemantic _semantic; VertexType _type; @@ -79,13 +78,14 @@ public: static VertexData* create(); size_t getVertexStreamCount() const; - bool setStream(int index, VertexBuffer* buffer, const VertexStreamAttribute& stream); - void removeStream(int index); - const VertexStreamAttribute* getStreamAttribute(int index) const; - VertexStreamAttribute* getStreamAttribute(int index); + bool setStream(VertexBuffer* buffer, const VertexStreamAttribute& stream); + void removeStream(VertexSemantic semantic); + const VertexStreamAttribute* getStreamAttribute(VertexSemantic semantic) const; + VertexStreamAttribute* getStreamAttribute(VertexSemantic semantic); - VertexBuffer* getStreamBuffer(int index) const; + VertexBuffer* getStreamBuffer(VertexSemantic semantic) const; + void use(); protected: VertexData(); virtual ~VertexData(); @@ -96,8 +96,11 @@ protected: VertexStreamAttribute _stream; }; - std::map _vertexStreams; - + std::map _vertexStreams; +protected: + static GLint getGLSize(VertexType type); + static GLenum getGLType(VertexType type); + static GLint getGLSemanticBinding(VertexSemantic semantic); }; class IndexData : public Ref @@ -108,6 +111,7 @@ public: IndexBuffer* getIndexBuffer() const { return _buffer; } int getStart() const { return _start; } int getCount() const { return _count; } + protected: IndexData(); virtual ~IndexData();