This commit is contained in:
lvlong 2014-06-24 13:40:04 +08:00
commit 2de28eea89
10 changed files with 135 additions and 28 deletions

View File

@ -45,17 +45,18 @@ Animate3D* Animate3D::create(Animation3D* animation)
return animate;
}
Animate3D* Animate3D::createSubAnimate3D(Animate3D* animate, float fromTime, float duration)
Animate3D* Animate3D::create(Animation3D* animation, float fromTime, float duration)
{
auto subAnimate = animate->clone();
float fullDuration = animate->getDuration();
auto animate = Animate3D::create(animation);
float fullDuration = animation->getDuration();
if (duration > fullDuration - fromTime)
duration = fullDuration - fromTime;
subAnimate->_start = fromTime / fullDuration;
subAnimate->_last = duration / fullDuration;
animate->_start = fromTime / fullDuration;
animate->_last = duration / fullDuration;
return subAnimate;
return animate;
}
/** returns a clone of action */

View File

@ -49,13 +49,13 @@ public:
static Animate3D* create(Animation3D* animation);
/**
* create sub Animate3D
* @param animate Animate3D used to generate sub animate3D
* create Animate3D
* @param animation used to generate animate3D
* @param formTime
* @param duration Time the Animate3D lasts
* @return Animate3D created using animate
*/
static Animate3D* createSubAnimate3D(Animate3D* animate, float fromTime, float duration);
static Animate3D* create(Animation3D* animation, float fromTime, float duration);
//
// Overrides
//

View File

@ -273,6 +273,8 @@ void Sprite3D::genGLProgramState()
}
setGLProgramState(programstate);
GLuint texID = _texture ? _texture->getName() : 0;
_meshCommand.genMaterialID(texID, programstate, _mesh, _blend);
}
GLProgram* Sprite3D::getDefaultGLProgram(bool textured)
@ -296,11 +298,12 @@ GLProgram* Sprite3D::getDefaultGLProgram(bool textured)
void Sprite3D::setTexture(const std::string& texFile)
{
auto tex = Director::getInstance()->getTextureCache()->addImage(texFile);
if( tex && _texture != tex ) {
CC_SAFE_RETAIN(tex);
CC_SAFE_RELEASE_NULL(_texture);
_texture = tex;
}
// if( tex && _texture != tex ) {
// CC_SAFE_RETAIN(tex);
// CC_SAFE_RELEASE_NULL(_texture);
// _texture = tex;
// }
setTexture(tex);
}
void Sprite3D::setTexture(Texture2D* texture)
@ -309,6 +312,11 @@ void Sprite3D::setTexture(Texture2D* texture)
CC_SAFE_RETAIN(texture);
CC_SAFE_RELEASE_NULL(_texture);
_texture = texture;
if (getGLProgramState() && _mesh)
{
GLuint texID = _texture ? _texture->getName() : 0;
_meshCommand.genMaterialID(texID, getGLProgramState(), _mesh, _blend);
}
}
}

View File

@ -32,6 +32,7 @@
#include "renderer/CCTextureAtlas.h"
#include "renderer/CCTexture2D.h"
#include "renderer/ccGLStateCache.h"
#include "xxhash.h"
NS_CC_BEGIN
@ -46,6 +47,7 @@ MeshCommand::MeshCommand()
, _displayColor(1.0f, 1.0f, 1.0f, 1.0f)
, _matrixPalette(nullptr)
, _matrixPaletteSize(0)
, _materialID(0)
{
_type = RenderCommand::Type::MESH_COMMAND;
}
@ -107,6 +109,8 @@ MeshCommand::~MeshCommand()
void MeshCommand::applyRenderState()
{
if (_cullFaceEnabled)
{
glEnable(GL_CULL_FACE);
@ -138,16 +142,69 @@ void MeshCommand::restoreRenderState()
}
}
void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend)
{
int* intstate = static_cast<int*>(glProgramState);
int* intmesh = static_cast<int*>(mesh);
int statekey[] = {intstate[0], 0}, meshkey[] = {intmesh[0], 0};
if (sizeof(void*) > sizeof(int))
{
statekey[1] = intstate[1];
meshkey[1] = intmesh[1];
}
int intArray[] = {(int)texID, statekey[0], statekey[1], meshkey[0], meshkey[1], (int)blend.src, (int)blend.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}
void MeshCommand::MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform)
{
glProgram->setUniformLocationWith4fv(uniform->location, (const float*)_matrixPalette, _matrixPaletteSize);
}
void MeshCommand::preDraw()
{
// set render state
applyRenderState();
// Set material
GL::bindTexture2D(_textureID);
GL::blendFunc(_blendType.src, _blendType.dst);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
//
//_glProgramState->apply(_mv);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
}
void MeshCommand::draw()
{
auto glProgram = _glProgramState->getGLProgram();
_glProgramState->setUniformVec4("u_color", _displayColor);
if (_matrixPaletteSize && _matrixPalette)
{
_glProgramState->setUniformCallback("u_matrixPalette", CC_CALLBACK_2(MeshCommand::MatrixPalleteCallBack, this));
}
_glProgramState->apply(_mv);
// Draw
glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount);
}
void MeshCommand::postDraw()
{
//restore render state
restoreRenderState();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void MeshCommand::execute()
{
// set render state
applyRenderState();
// Set material
GL::bindTexture2D(_textureID);
GL::blendFunc(_blendType.src, _blendType.dst);
@ -172,7 +229,6 @@ void MeshCommand::execute()
//restore render state
restoreRenderState();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

View File

@ -59,8 +59,17 @@ public:
void setMatrixPalette(const Vec4* matrixPalette) { _matrixPalette = matrixPalette; }
void setMatrixPaletteSize(int size) { _matrixPaletteSize = size; }
void execute();
//used for bath
void preDraw();
void draw();
void postDraw();
void genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend);
uint32_t getMaterialID() const { return _materialID; }
protected:
// apply renderstate
@ -83,6 +92,8 @@ protected:
const Vec4* _matrixPalette;
int _matrixPaletteSize;
uint32_t _materialID; //material ID
GLuint _vertexBuffer;
GLuint _indexBuffer;
GLenum _primitive;

View File

@ -108,6 +108,7 @@ static const int DEFAULT_RENDER_QUEUE = 0;
//
Renderer::Renderer()
:_lastMaterialID(0)
,_lastBatchedMeshCommand(nullptr)
,_numQuads(0)
,_glViewAssigned(false)
,_isRendering(false)
@ -277,12 +278,14 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
{
ssize_t size = queue.size();
uint32_t material3DID = 0; //last material 3d ID
for (ssize_t index = 0; index < size; ++index)
{
auto command = queue[index];
auto commandType = command->getType();
if(RenderCommand::Type::QUAD_COMMAND == commandType)
{
flush3D();
auto cmd = static_cast<QuadCommand*>(command);
//Batch quads
if(_numQuads + cmd->getQuadCount() > VBO_SIZE)
@ -321,9 +324,20 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
}
else if (RenderCommand::Type::MESH_COMMAND == commandType)
{
flush();
flush2D();
auto cmd = static_cast<MeshCommand*>(command);
cmd->execute();
if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID())
{
flush3D();
cmd->preDraw();
cmd->draw();
}
else
{
cmd->draw();
}
_lastBatchedMeshCommand = cmd;
// cmd->execute();
}
else
{
@ -376,6 +390,7 @@ void Renderer::clean()
_numQuads = 0;
_lastMaterialID = 0;
_lastBatchedMeshCommand = nullptr;
}
void Renderer::convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Mat4& modelView)
@ -505,11 +520,26 @@ void Renderer::drawBatchedQuads()
}
void Renderer::flush()
{
flush2D();
flush3D();
}
void Renderer::flush2D()
{
drawBatchedQuads();
_lastMaterialID = 0;
}
void Renderer::flush3D()
{
if (_lastBatchedMeshCommand)
{
_lastBatchedMeshCommand->postDraw();
_lastBatchedMeshCommand = nullptr;
}
}
// helpers
bool Renderer::checkVisibility(const Mat4 &transform, const Size &size)

View File

@ -38,6 +38,7 @@ NS_CC_BEGIN
class EventListenerCustom;
class QuadCommand;
class MeshCommand;
/** Class that knows how to sort `RenderCommand` objects.
Since the commands that have `z == 0` are "pushed back" in
@ -132,6 +133,10 @@ protected:
//Draw the previews queued quads and flush previous context
void flush();
void flush2D();
void flush3D();
void visitRenderQueue(const RenderQueue& queue);
void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Mat4& modelView);
@ -142,6 +147,7 @@ protected:
uint32_t _lastMaterialID;
MeshCommand* _lastBatchedMeshCommand;
std::vector<QuadCommand*> _batchedQuadCommands;
V3F_C4B_T2F_Quad _quads[VBO_SIZE];

View File

@ -33,15 +33,11 @@ vec4 _skinnedPosition;
vec4 getPosition()
{
vec4 matrixPalette1 = vec4(0.0);
vec4 matrixPalette2 = vec4(0.0);
vec4 matrixPalette3 = vec4(0.0);
float blendWeight = a_blendWeight[0];
int matrixIndex = int (a_blendIndex[0]) * 3;
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
vec4 matrixPalette1 = u_matrixPalette[matrixIndex] * blendWeight;
vec4 matrixPalette2 = u_matrixPalette[matrixIndex + 1] * blendWeight;
vec4 matrixPalette3 = u_matrixPalette[matrixIndex + 2] * blendWeight;
blendWeight = a_blendWeight[1];
matrixIndex = int(a_blendIndex[1]) * 3;

View File

@ -541,7 +541,7 @@ std::string Sprite3DWithSkinTest::subtitle() const
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
{
std::string fileName = "Sprite3DTest/girl.c3t";
std::string fileName = "Sprite3DTest/girl.c3b";
auto sprite = Sprite3D::create(fileName);
addChild(sprite);
sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f));

@ -1 +0,0 @@
Subproject commit 417bfcdce1633a4f00de1ddb1084c2d7c33a33ce