Merge branch 'v3_migrateFastTMX' into v3_renderPrimitive

This commit is contained in:
Huabing.Xu 2014-08-07 15:36:41 +08:00
commit ba2ae6826c
12 changed files with 315 additions and 255 deletions

View File

@ -1249,6 +1249,7 @@
50ABC0671926664800A911A9 /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF541926664700A911A9 /* CCPlatformDefine.h */; };
50ABC0691926664800A911A9 /* CCStdC.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF551926664700A911A9 /* CCStdC.h */; };
A07A4CAF1783777C0073F6A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1551A342158F2AB200E66CFE /* Foundation.framework */; };
B2165EEA19921124000BE3E6 /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; };
B217703C1977ECB4009EE11B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703B1977ECB4009EE11B /* IOKit.framework */; };
B21770401977ECE6009EE11B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703F1977ECE6009EE11B /* OpenGL.framework */; };
B21770421977ECF8009EE11B /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21770411977ECF8009EE11B /* ApplicationServices.framework */; };
@ -7093,20 +7094,24 @@
1A01C6A518F58F7500EFE3A6 /* CCNotificationCenter.cpp in Sources */,
ED9C6A9518599AD8000A5232 /* CCNodeGrid.cpp in Sources */,
1A01C68F18F57BE800EFE3A6 /* CCDictionary.cpp in Sources */,
B276EF621988D1D500CD400F /* CCVertexIndexData.cpp in Sources */,
50ABBE561925AB6F00A911A9 /* CCEventFocus.cpp in Sources */,
503DD8E11926736A00CD74DD /* CCApplication.mm in Sources */,
50ABC01A1926664800A911A9 /* CCSAXParser.cpp in Sources */,
B2CC507C19776DD10041958E /* CCPhysicsJoint.cpp in Sources */,
B2165EEA19921124000BE3E6 /* CCPrimitiveCommand.cpp in Sources */,
503DD8EE1926736A00CD74DD /* CCImage.mm in Sources */,
3EA47871195478E00068D9D1 /* CCBundleReader.cpp in Sources */,
B37510811823ACA100B3BA6A /* CCPhysicsJointInfo_chipmunk.cpp in Sources */,
46A170FC1807CECB005B8026 /* CCPhysicsBody.cpp in Sources */,
50ABBD941925AB4100A911A9 /* CCGLProgramState.cpp in Sources */,
B257B44F1989D5E800D9A687 /* CCPrimitive.cpp in Sources */,
50ABBE281925AB6F00A911A9 /* CCAutoreleasePool.cpp in Sources */,
46A170FE1807CECB005B8026 /* CCPhysicsContact.cpp in Sources */,
1A570062180BC5A10088DEC7 /* CCAction.cpp in Sources */,
1A570066180BC5A10088DEC7 /* CCActionCamera.cpp in Sources */,
3E9E80F2198639EF00FA95D0 /* CCSubMeshState.cpp in Sources */,
B276EF661988D1D500CD400F /* CCVertexIndexBuffer.cpp in Sources */,
1A57006A180BC5A10088DEC7 /* CCActionCatmullRom.cpp in Sources */,
1A57006E180BC5A10088DEC7 /* CCActionEase.cpp in Sources */,
50ABBD8C1925AB4100A911A9 /* CCGLProgram.cpp in Sources */,
@ -7247,7 +7252,6 @@
50ABBDA41925AB4100A911A9 /* CCQuadCommand.cpp in Sources */,
1AAF5850180E40B9000584C8 /* LocalStorage.cpp in Sources */,
1AAF5854180E40B9000584C8 /* LocalStorageAndroid.cpp in Sources */,
B257B44F1989D5E800D9A687 /* CCPrimitive.cpp in Sources */,
1A9DCA28180E6955007A3AD4 /* CCGLBufferedNode.cpp in Sources */,
50ABBE201925AB6F00A911A9 /* atitc.cpp in Sources */,
50ABBE9A1925AB6F00A911A9 /* CCRef.cpp in Sources */,
@ -7271,14 +7275,12 @@
50ABBEB41925AB6F00A911A9 /* CCUserDefault.mm in Sources */,
1A1645B1191B726C008C7C7F /* ConvertUTF.c in Sources */,
50ABBE3A1925AB6F00A911A9 /* CCData.cpp in Sources */,
B276EF661988D1D500CD400F /* CCVertexIndexBuffer.cpp in Sources */,
1A1645B3191B726C008C7C7F /* ConvertUTFWrapper.cpp in Sources */,
1ABA68AF1888D700007D1BB4 /* CCFontCharMap.cpp in Sources */,
50ABBE7A1925AB6F00A911A9 /* CCEventMouse.cpp in Sources */,
15EFA212198A2BB5000C57D3 /* CCProtectedNode.cpp in Sources */,
50ABBD981925AB4100A911A9 /* CCGLProgramStateCache.cpp in Sources */,
B6B26344193884D60088FE25 /* CCAnimation3D.cpp in Sources */,
B276EF621988D1D500CD400F /* CCVertexIndexData.cpp in Sources */,
B6ACD898193D6693005E0B8A /* CCMeshSkin.cpp in Sources */,
B6ACD89F193DC0CC005E0B8A /* CCAnimate3D.cpp in Sources */,
B6AAF84219404E0D0069DE01 /* CCBundle3D.cpp in Sources */,

View File

@ -121,8 +121,10 @@ TMXLayer::TMXLayer()
, _useAutomaticVertexZ(false)
, _dirty(true)
, _quadsDirty(true)
, _vertexBuffer(nullptr)
, _vData(nullptr)
, _indexBuffer(nullptr)
{
_buffersVBO[0] = _buffersVBO[1] = 0;
}
TMXLayer::~TMXLayer()
@ -130,15 +132,10 @@ TMXLayer::~TMXLayer()
CC_SAFE_RELEASE(_tileSet);
CC_SAFE_RELEASE(_texture);
CC_SAFE_DELETE_ARRAY(_tiles);
if(glIsBuffer(_buffersVBO[0]))
{
glDeleteBuffers(1, &_buffersVBO[0]);
}
CC_SAFE_RELEASE(_vData);
CC_SAFE_RELEASE(_vertexBuffer);
CC_SAFE_RELEASE(_indexBuffer);
if(glIsBuffer(_buffersVBO[1]))
{
glDeleteBuffers(1, &_buffersVBO[1]);
}
}
void TMXLayer::draw(Renderer *renderer, const Mat4& transform, uint32_t flags)
@ -156,43 +153,47 @@ void TMXLayer::draw(Renderer *renderer, const Mat4& transform, uint32_t flags)
updateTiles(rect);
updateIndexBuffer();
updatePrimitives();
_dirty = false;
}
if(_renderCommands.size() < _indicesVertexZNumber.size())
if(_renderCommands.size() < _primitives.size())
{
_renderCommands.resize(_indicesVertexZNumber.size());
_renderCommands.resize(_primitives.size());
}
int index = 0;
for(const auto& iter : _indicesVertexZNumber)
// for(const auto& iter : _indicesVertexZNumber)
// {
// auto& cmd = _renderCommands[index++];
//
// cmd.init(iter.first);
// cmd.func = CC_CALLBACK_0(TMXLayer::onDraw, this, _indicesVertexZOffsets[iter.first], iter.second);
// renderer->addCommand(&cmd);
// }
for(const auto& iter : _primitives)
{
auto& cmd = _renderCommands[index++];
cmd.init(iter.first);
cmd.func = CC_CALLBACK_0(TMXLayer::onDraw, this, _indicesVertexZOffsets[iter.first], iter.second);
renderer->addCommand(&cmd);
if(iter.second->getCount() > 0)
{
auto& cmd = _renderCommands[index++];
//cmd.init(iter.first);
//cmd.func = CC_CALLBACK_0(TMXLayer::onDraw, this, iter.second);
cmd.init(iter.first, _texture->getName(), getGLProgramState(), BlendFunc::ALPHA_NON_PREMULTIPLIED, iter.second, _modelViewTransform);
renderer->addCommand(&cmd);
}
}
}
void TMXLayer::onDraw(int offset, int count)
void TMXLayer::onDraw(Primitive *primitive)
{
GL::bindTexture2D(_texture->getName());
getGLProgramState()->apply(_modelViewTransform);
GL::bindVAO(0);
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*)0);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_T2F, colors));
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_T2F, texCoords));
glDrawElements(GL_TRIANGLES, (GLsizei)count * 6, GL_UNSIGNED_INT, (GLvoid*)(offset * 6 * sizeof(int)));
primitive->draw();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, count * 4);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, primitive->getCount() * 4);
}
void TMXLayer::updateTiles(const Rect& culledRect)
@ -291,25 +292,32 @@ void TMXLayer::updateTiles(const Rect& culledRect)
void TMXLayer::updateVertexBuffer()
{
GL::bindVAO(0);
if(!glIsBuffer(_buffersVBO[0]))
if(nullptr == _vData)
{
glGenBuffers(1, &_buffersVBO[0]);
_vertexBuffer = VertexBuffer::create(sizeof(V3F_C4B_T2F), (int)_totalQuads.size() * 4);
_vData = VertexData::create();
_vData->setStream(_vertexBuffer, VertexStreamAttribute(0, GLProgram::VERTEX_ATTRIB_POSITION, GL_FLOAT, 3));
_vData->setStream(_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, GL_UNSIGNED_BYTE, 4, true));
_vData->setStream(_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, GL_FLOAT, 2));
CC_SAFE_RETAIN(_vData);
CC_SAFE_RETAIN(_vertexBuffer);
}
if(_vertexBuffer)
{
_vertexBuffer->updateVertices((void*)&_totalQuads[0], (int)_totalQuads.size() * 4, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_T2F_Quad) * _totalQuads.size(), (GLvoid*)&_totalQuads[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void TMXLayer::updateIndexBuffer()
{
if(!glIsBuffer(_buffersVBO[1]))
if(nullptr == _indexBuffer)
{
glGenBuffers(1, &_buffersVBO[1]);
_indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_UINT_32, (int)_indices.size());
CC_SAFE_RETAIN(_indexBuffer);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * _indices.size(), &_indices[0], GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_indexBuffer->updateIndices(&_indices[0], (int)_indices.size(), 0);
}
// FastTMXLayer - setup Tiles
@ -405,6 +413,29 @@ Mat4 TMXLayer::tileToNodeTransform()
}
void TMXLayer::updatePrimitives()
{
for(const auto& iter : _indicesVertexZNumber)
{
int start = _indicesVertexZOffsets.at(iter.first);
auto primitiveIter= _primitives.find(iter.first);
if(primitiveIter == _primitives.end())
{
auto primitive = Primitive::create(_vData, _indexBuffer, GL_TRIANGLES);
primitive->setCount(iter.second * 6);
primitive->setStart(start * 6);
_primitives.insert(iter.first, primitive);
}
else
{
primitiveIter->second->setCount(iter.second * 6);
primitiveIter->second->setStart(start * 6);
}
}
}
void TMXLayer::updateTotalQuads()
{
if(_quadsDirty)

View File

@ -32,6 +32,7 @@ THE SOFTWARE.
#include "CCNode.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCQuadCommand.h"
#include "renderer/CCPrimitiveCommand.h"
#include <map>
#include <unordered_map>
@ -199,12 +200,12 @@ protected:
//
void updateTotalQuads();
void onDraw(int offset, int count);
void onDraw(Primitive* primitive);
inline int getTileIndexByPos(int x, int y) const { return x + y * (int) _layerSize.width; }
void updateVertexBuffer();
void updateIndexBuffer();
void updatePrimitives();
protected:
//! name of the layer
@ -228,7 +229,7 @@ protected:
/** container for sprite children. map<index, pair<sprite, gid> > */
std::map<int, std::pair<Sprite*, int> > _spriteContainer;
GLuint _buffersVBO[2]; //0: vertex, 1: indices
//GLuint _buffersVBO; //0: vertex, 1: indices
Size _screenGridSize;
Rect _screenGridRect;
@ -246,9 +247,17 @@ protected:
std::vector<int> _indices;
std::map<int/*vertexZ*/, int/*offset to _indices by quads*/> _indicesVertexZOffsets;
std::unordered_map<int/*vertexZ*/, int/*number to quads*/> _indicesVertexZNumber;
std::vector<CustomCommand> _renderCommands;
std::vector<PrimitiveCommand> _renderCommands;
bool _dirty;
VertexBuffer* _vertexBuffer;
VertexData* _vData;
IndexBuffer* _indexBuffer;
Map<int , Primitive*> _primitives;
public:
/** Possible orientations of the TMX map */
static const int FAST_TMX_ORIENTATION_ORTHO;

View File

@ -166,6 +166,10 @@ renderer/CCTextureAtlas.cpp \
renderer/CCTextureCache.cpp \
renderer/ccGLStateCache.cpp \
renderer/ccShaders.cpp \
renderer/CCVertexIndexBuffer.cpp \
renderer/CCVertexIndexData.cpp \
renderer/CCPrimitive.cpp \
renderer/CCPrimitiveCommand.cpp \
deprecated/CCArray.cpp \
deprecated/CCSet.cpp \
deprecated/CCString.cpp \

View File

@ -29,7 +29,7 @@
NS_CC_BEGIN
Primitive* Primitive::create(VertexData* verts, IndexData* indices, PrimitiveType type)
Primitive* Primitive::create(VertexData* verts, IndexBuffer* indices, int type)
{
auto result = new (std::nothrow) Primitive();
if( result && result->init(verts, indices, type))
@ -47,7 +47,7 @@ VertexData* Primitive::getVertexData()
return _verts;
}
IndexData* Primitive::getIndexData()
IndexBuffer* Primitive::getIndexData()
{
return _indices;
}
@ -55,7 +55,7 @@ IndexData* Primitive::getIndexData()
Primitive::Primitive()
: _verts(nullptr)
, _indices(nullptr)
, _type(PrimitiveType::POINTS)
, _type(GL_POINTS)
{
}
@ -65,9 +65,9 @@ Primitive::~Primitive()
CC_SAFE_RELEASE_NULL(_indices);
}
bool Primitive::init(VertexData* verts, IndexData* indices, PrimitiveType type)
bool Primitive::init(VertexData* verts, IndexBuffer* indices, int type)
{
if(nullptr == verts || nullptr == indices) return false;
if( nullptr == verts ) return false;
if(verts != _verts)
{
CC_SAFE_RELEASE(_verts);
@ -92,47 +92,19 @@ 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;
if(_indices!= nullptr)
{
GLenum type = (_indices->getType() == IndexBuffer::IndexType::INDEX_TYPE_SHORT_16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indices->getVBO());
glDrawElements((GLenum)_type, _count, type, (GLvoid*)(_start * _indices->getSizePerIndex()));
}
else
{
glDrawArrays((GLenum)_type, _count, _start);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}

View File

@ -31,36 +31,38 @@
#include "renderer/CCVertexIndexData.h"
NS_CC_BEGIN
enum class PrimitiveType
{
POINTS,
LINES,
TRIANGLES
};
class Primitive : public Ref
{
public:
static Primitive* create(VertexData* verts, IndexData* indices, PrimitiveType type);
static Primitive* create(VertexData* verts, IndexBuffer* indices, int type);
VertexData* getVertexData();
IndexData* getIndexData();
IndexBuffer* getIndexData();
PrimitiveType getType() const { return _type; }
int getType() const { return _type; }
//called by rendering framework
void draw();
int getStart() const { return _start; }
int getCount() const { return _count; }
void setStart(int start) { _start = start; }
void setCount(int count) { _count = count; }
protected:
Primitive();
virtual ~Primitive();
bool init(VertexData* verts, IndexData* indices, PrimitiveType type);
bool init(VertexData* verts, IndexBuffer* indices, int type);
protected:
VertexData* _verts;
IndexData* _indices;
PrimitiveType _type;
IndexBuffer* _indices;
int _start;
int _count;
int _type;
};
NS_CC_END

View File

@ -25,7 +25,7 @@
THE SOFTWARE.
****************************************************************************/
#include "CCPrimitiveCommand.h"
#include "renderer/CCPrimitiveCommand.h"
#include "renderer/ccGLStateCache.h"
#include "renderer/CCGLProgram.h"

View File

@ -30,6 +30,7 @@
#include "renderer/CCBatchCommand.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCGroupCommand.h"
#include "renderer/CCPrimitiveCommand.h"
#include "renderer/CCGLProgramCache.h"
#include "renderer/ccGLStateCache.h"
#include "renderer/CCMeshCommand.h"
@ -321,6 +322,12 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
auto cmd = static_cast<BatchCommand*>(command);
cmd->execute();
}
else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType)
{
flush();
auto cmd = static_cast<PrimitiveCommand*>(command);
cmd->execute();
}
else if (RenderCommand::Type::MESH_COMMAND == commandType)
{
flush2D();

View File

@ -25,10 +25,24 @@
THE SOFTWARE.
****************************************************************************/
#include "CCVertexIndexBuffer.h"
#include "renderer/CCVertexIndexBuffer.h"
#include "base/CCEventType.h"
#include "base/CCEventListenerCustom.h"
NS_CC_BEGIN
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
bool VertexBuffer::_enableShadowCopy = true;
#else
bool VertexBuffer::_enableShadowCopy = false;
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
bool IndexBuffer::_enableShadowCopy = true;
#else
bool IndexBuffer::_enableShadowCopy = false;
#endif
VertexBuffer* VertexBuffer::create(int sizePerVertex, int vertexNumber)
{
auto result = new (std::nothrow) VertexBuffer();
@ -47,6 +61,11 @@ VertexBuffer::VertexBuffer()
, _vertexNumber(0)
, _sizePerVertex(0)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_COME_TO_BACKGROUND, CC_CALLBACK_1(VertexBuffer::listenToBackground, this));
#endif
}
VertexBuffer::~VertexBuffer()
@ -65,9 +84,14 @@ bool VertexBuffer::init(int sizePerVertex, int vertexNumber)
_sizePerVertex = sizePerVertex;
_vertexNumber = vertexNumber;
if(isShadowCopyEnabled())
{
_shadowCopy.resize(sizePerVertex * _vertexNumber);
}
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _sizePerVertex * _vertexNumber, nullptr, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, getSize(), nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
@ -98,6 +122,11 @@ bool VertexBuffer::updateVertices(const void* verts, int count, int begin)
count = _vertexNumber - begin;
}
if(isShadowCopyEnabled())
{
memcpy(&_shadowCopy[begin * _sizePerVertex], verts, count * _sizePerVertex);
}
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferSubData(GL_ARRAY_BUFFER, begin * _sizePerVertex, count * _sizePerVertex, verts);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -105,6 +134,43 @@ bool VertexBuffer::updateVertices(const void* verts, int count, int begin)
return true;
}
void VertexBuffer::listenToBackground(EventCustom *event)
{
if(glIsBuffer(_vbo))
{
glDeleteBuffers(1, &_vbo);
_vbo = 0;
}
}
GLuint VertexBuffer::getVBO() const
{
if(0 == _vbo)
{
recreateVBO();
}
return _vbo;
}
void VertexBuffer::recreateVBO() const
{
CCLOG("come to foreground of VertexBuffer");
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
const void* buffer = nullptr;
if(isShadowCopyEnabled())
{
buffer = &_shadowCopy[0];
}
glBufferData(GL_ARRAY_BUFFER, _sizePerVertex * _vertexNumber, buffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
if(!glIsBuffer(_vbo))
{
CCLOGERROR("recreate VertexBuffer Error");
}
}
//bool VertexBuffer::getVertices(void* verts, int count, int begin) const
//{
// if(count <= 0 || nullptr == verts) return false;
@ -151,6 +217,10 @@ IndexBuffer::IndexBuffer()
, _type(IndexType::INDEX_TYPE_SHORT_16)
, _indexNumber(0)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_COME_TO_BACKGROUND, CC_CALLBACK_1(IndexBuffer::listenToBackground, this));
#endif
}
IndexBuffer::~IndexBuffer()
@ -171,9 +241,14 @@ bool IndexBuffer::init(IndexBuffer::IndexType type, int number)
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, getSizePerIndex() * _indexNumber, nullptr, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, getSize(), nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if(isShadowCopyEnabled())
{
_shadowCopy.resize(getSize());
}
return true;
}
@ -212,6 +287,11 @@ bool IndexBuffer::updateIndices(const void* indices, int count, int begin)
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, begin * getSizePerIndex(), count * getSizePerIndex(), indices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if(isShadowCopyEnabled())
{
memcpy(&_shadowCopy[begin * getSizePerIndex()], indices, count * getSizePerIndex());
}
return true;
}
@ -244,4 +324,42 @@ int IndexBuffer::getSize() const
return getSizePerIndex() * _indexNumber;
}
void IndexBuffer::listenToBackground(EventCustom *event)
{
if(glIsBuffer(_vbo))
{
glDeleteBuffers(1, &_vbo);
_vbo = 0;
}
}
GLuint IndexBuffer::getVBO() const
{
if(0 == _vbo)
{
recreateVBO();
}
return _vbo;
}
void IndexBuffer::recreateVBO() const
{
CCLOG("come to foreground of IndexBuffer");
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
const void* buffer = nullptr;
if(isShadowCopyEnabled())
{
buffer = &_shadowCopy[0];
}
glBufferData(GL_ARRAY_BUFFER, getSize(), buffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
if(!glIsBuffer(_vbo))
{
CCLOGERROR("recreate IndexBuffer Error");
}
}
NS_CC_END

View File

@ -45,18 +45,28 @@ public:
int getSize() const;
GLuint getVBO() const { return _vbo; }
GLuint getVBO() const;
protected:
VertexBuffer();
virtual ~VertexBuffer();
bool init(int sizePerVertex, int vertexNumber);
protected:
GLuint _vbo;
//event listener for foreground and background
void listenToBackground(EventCustom *event);
void recreateVBO() const;
protected:
mutable GLuint _vbo;
int _sizePerVertex;
int _vertexNumber;
//buffer used for shadow copy
std::vector<unsigned char> _shadowCopy;
protected:
static bool _enableShadowCopy;
public:
static bool isShadowCopyEnabled() { return _enableShadowCopy; }
static void enableShadowCopy(bool enabled) { _enableShadowCopy = enabled; }
};
class IndexBuffer : public Ref
@ -79,7 +89,7 @@ public:
int getSize() const;
GLuint getVBO() const { return _vbo; }
GLuint getVBO() const;
protected:
IndexBuffer();
@ -88,9 +98,22 @@ protected:
bool init(IndexType type, int number);
protected:
GLuint _vbo;
mutable GLuint _vbo;
IndexType _type;
int _indexNumber;
protected:
//event listener for foreground and background
void listenToBackground(EventCustom *event);
void recreateVBO() const;
//buffer used for shadow copy
std::vector<unsigned char> _shadowCopy;
protected:
static bool _enableShadowCopy;
public:
static bool isShadowCopyEnabled() { return _enableShadowCopy; }
static void enableShadowCopy(bool enabled) { _enableShadowCopy = enabled; }
};

View File

@ -68,7 +68,7 @@ bool VertexData::setStream(VertexBuffer* buffer, const VertexStreamAttribute& st
return true;
}
void VertexData::removeStream(VertexSemantic semantic)
void VertexData::removeStream(int semantic)
{
auto iter = _vertexStreams.find(semantic);
if(iter != _vertexStreams.end())
@ -78,21 +78,21 @@ void VertexData::removeStream(VertexSemantic semantic)
}
}
const VertexStreamAttribute* VertexData::getStreamAttribute(VertexSemantic semantic) const
const VertexStreamAttribute* VertexData::getStreamAttribute(int semantic) const
{
auto iter = _vertexStreams.find(semantic);
if(iter == _vertexStreams.end()) return nullptr;
else return &iter->second._stream;
}
VertexStreamAttribute* VertexData::getStreamAttribute(VertexSemantic semantic)
VertexStreamAttribute* VertexData::getStreamAttribute(int semantic)
{
auto iter = _vertexStreams.find(semantic);
if(iter == _vertexStreams.end()) return nullptr;
else return &iter->second._stream;
}
VertexBuffer* VertexData::getStreamBuffer(VertexSemantic semantic) const
VertexBuffer* VertexData::getStreamBuffer(int semantic) const
{
auto iter = _vertexStreams.find(semantic);
if(iter == _vertexStreams.end()) return nullptr;
@ -113,96 +113,23 @@ 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()
{
uint32_t flags;
for(auto& element : _vertexStreams)
{
glEnableVertexAttribArray(getGLSemanticBinding(element.second._stream._semantic));
flags = flags | (1 << element.second._stream._semantic);
}
GL::enableVertexAttribs(flags);
for(auto& element : _vertexStreams)
{
//glEnableVertexAttribArray((GLint)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);
glVertexAttribPointer(GLint(element.second._stream._semantic),element.second._stream._size,
element.second._stream._type,element.second._stream._normalize, element.second._buffer->getSizePerVertex(), (GLvoid*)element.second._stream._offset);
}
}
IndexData* IndexData::create(IndexBuffer* buffer, int start, int count)
{
IndexData* result = new (std::nothrow) IndexData();
if(result && result->init(buffer, start, count))
{
result->autorelease();
return result;
}
else
{
CC_SAFE_DELETE(result);
return nullptr;
}
}
IndexData::IndexData()
: _buffer(nullptr)
, _start(0)
, _count(0)
{
}
IndexData::~IndexData()
{
CC_SAFE_RELEASE_NULL(_buffer);
}
bool IndexData::init(IndexBuffer* buffer, int start, int count)
{
if(count == 0) return false;
if(_buffer != buffer)
{
CC_SAFE_RELEASE_NULL(_buffer);
CC_SAFE_RETAIN(buffer);
_buffer = buffer;
}
_start = start;
_count = count;
return false;
}
NS_CC_END

View File

@ -37,39 +37,28 @@ NS_CC_BEGIN
class VertexBuffer;
enum VertexSemantic
{
UNKNOWN = -1,
POSITION,
COLOR,
NORMAL,
BLEND_WEIGHT,
BLEND_INDEX,
TEXTURECOORD0,
TEXTURECOORD1,
TEXTURECOORD2,
TEXTURECOORD3
};
enum class VertexType
{
UNKNOWN,
FLOAT1,
FLOAT2,
FLOAT3,
FLOAT4,
BYTE4
};
struct VertexStreamAttribute
{
VertexStreamAttribute()
: _offset(0),_semantic(VertexSemantic::UNKNOWN),_type(VertexType::UNKNOWN)
: _offset(0),_semantic(0),_type(0),_size(0), _normalize(false)
{
}
VertexStreamAttribute(int offset, int semantic, int type, int size)
: _offset(offset),_semantic(semantic),_type(type),_size(size), _normalize(false)
{
}
VertexStreamAttribute(int offset, int semantic, int type, int size, bool normalize)
: _offset(offset),_semantic(semantic),_type(type),_size(size), _normalize(normalize)
{
}
bool _normalize;
int _offset;
VertexSemantic _semantic;
VertexType _type;
int _semantic;
int _type;
int _size;
};
class VertexData : public Ref
@ -79,11 +68,11 @@ public:
size_t getVertexStreamCount() const;
bool setStream(VertexBuffer* buffer, const VertexStreamAttribute& stream);
void removeStream(VertexSemantic semantic);
const VertexStreamAttribute* getStreamAttribute(VertexSemantic semantic) const;
VertexStreamAttribute* getStreamAttribute(VertexSemantic semantic);
void removeStream(int semantic);
const VertexStreamAttribute* getStreamAttribute(int semantic) const;
VertexStreamAttribute* getStreamAttribute(int semantic);
VertexBuffer* getStreamBuffer(VertexSemantic semantic) const;
VertexBuffer* getStreamBuffer(int semantic) const;
void use();
protected:
@ -96,31 +85,7 @@ protected:
VertexStreamAttribute _stream;
};
std::map<VertexSemantic, BufferAttribute> _vertexStreams;
protected:
static GLint getGLSize(VertexType type);
static GLenum getGLType(VertexType type);
static GLint getGLSemanticBinding(VertexSemantic semantic);
};
class IndexData : public Ref
{
public:
static IndexData* create(IndexBuffer* buffer, int start, int count);
IndexBuffer* getIndexBuffer() const { return _buffer; }
int getStart() const { return _start; }
int getCount() const { return _count; }
protected:
IndexData();
virtual ~IndexData();
bool init(IndexBuffer* buffer, int start, int count);
protected:
IndexBuffer* _buffer;
int _start;
int _count;
std::map<int, BufferAttribute> _vertexStreams;
};
NS_CC_END