mirror of https://github.com/axmolengine/axmol.git
Remove Transparent Queue, Move transform calculation of Billboard to visit
This commit is contained in:
parent
7741daf091
commit
fee8bc1b28
|
@ -96,42 +96,102 @@ BillBoard* BillBoard::create(Mode mode)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
void BillBoard::visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags)
|
||||||
{
|
{
|
||||||
|
// quick return if not visible. children won't be drawn.
|
||||||
|
if (!_visible)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t flags = processParentFlags(parentTransform, parentFlags);
|
||||||
|
|
||||||
|
//Update Billboard transform
|
||||||
|
calculateBillbaordTransform();
|
||||||
|
|
||||||
|
Director* director = Director::getInstance();
|
||||||
|
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||||
|
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
||||||
|
|
||||||
|
bool visibleByCamera = isVisitableByVisitingCamera();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if(!_children.empty())
|
||||||
|
{
|
||||||
|
sortAllChildren();
|
||||||
|
// draw children zOrder < 0
|
||||||
|
for( ; i < _children.size(); i++ )
|
||||||
|
{
|
||||||
|
auto node = _children.at(i);
|
||||||
|
|
||||||
|
if (node && node->getLocalZOrder() < 0)
|
||||||
|
node->visit(renderer, _billboardTransform, flags);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// self draw
|
||||||
|
if (visibleByCamera)
|
||||||
|
this->draw(renderer, _billboardTransform, flags);
|
||||||
|
|
||||||
|
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
|
||||||
|
(*it)->visit(renderer, _billboardTransform, flags);
|
||||||
|
}
|
||||||
|
else if (visibleByCamera)
|
||||||
|
{
|
||||||
|
this->draw(renderer, _billboardTransform, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillBoard::calculateBillbaordTransform()
|
||||||
|
{
|
||||||
|
//Get camera world position
|
||||||
auto camera = Camera::getVisitingCamera();
|
auto camera = Camera::getVisitingCamera();
|
||||||
const Mat4& camWorldMat = camera->getNodeToWorldTransform();
|
const Mat4& camWorldMat = camera->getNodeToWorldTransform();
|
||||||
if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_mvTransform.m, transform.m, sizeof(float) * 16) != 0 || _modeDirty)
|
|
||||||
|
//TODO: use math lib to calculate math lib
|
||||||
|
//Make it easier to read
|
||||||
|
if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || _transformDirty || _modeDirty)
|
||||||
{
|
{
|
||||||
|
//Rotate based on anchor point
|
||||||
Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f);
|
Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f);
|
||||||
Mat4 localToWorld = transform;
|
Mat4 localToWorld = _modelViewTransform;
|
||||||
localToWorld.translate(anchorPoint);
|
localToWorld.translate(anchorPoint);
|
||||||
|
|
||||||
|
//Decide billboard mode
|
||||||
Vec3 camDir;
|
Vec3 camDir;
|
||||||
switch (_mode)
|
switch (_mode)
|
||||||
{
|
{
|
||||||
case Mode::VIEW_POINT_ORIENTED:
|
case Mode::VIEW_POINT_ORIENTED:
|
||||||
camDir = Vec3(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]);
|
camDir = Vec3(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]);
|
||||||
break;
|
break;
|
||||||
case Mode::VIEW_PLANE_ORIENTED:
|
case Mode::VIEW_PLANE_ORIENTED:
|
||||||
camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
|
camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CCASSERT(false, "invalid billboard mode");
|
CCASSERT(false, "invalid billboard mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_modeDirty = false;
|
_modeDirty = false;
|
||||||
|
|
||||||
if (camDir.length() < MATH_TOLERANCE)
|
if (camDir.length() < MATH_TOLERANCE)
|
||||||
{
|
{
|
||||||
camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
|
camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
|
||||||
}
|
}
|
||||||
camDir.normalize();
|
camDir.normalize();
|
||||||
|
|
||||||
Quaternion rotationQuaternion;
|
Quaternion rotationQuaternion;
|
||||||
this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
|
this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
|
||||||
|
|
||||||
// fetch the rotation angle of z
|
// fetch the rotation angle of z
|
||||||
float rotationZ = atan2(2*(rotationQuaternion.w*rotationQuaternion.z + rotationQuaternion.x*rotationQuaternion.y),
|
float rotationZ = atan2(2*(rotationQuaternion.w*rotationQuaternion.z + rotationQuaternion.x*rotationQuaternion.y),
|
||||||
(1 - 2* (rotationQuaternion.y*rotationQuaternion.y + rotationQuaternion.z *rotationQuaternion.z)));
|
(1 - 2* (rotationQuaternion.y*rotationQuaternion.y + rotationQuaternion.z *rotationQuaternion.z)));
|
||||||
Mat4 rotationMatrix;
|
Mat4 rotationMatrix;
|
||||||
rotationMatrix.setIdentity();
|
rotationMatrix.setIdentity();
|
||||||
rotationMatrix.rotateZ(rotationZ);
|
rotationMatrix.rotateZ(rotationZ);
|
||||||
|
|
||||||
Vec3 upAxis = Vec3(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
|
Vec3 upAxis = Vec3(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
|
||||||
Vec3 x, y;
|
Vec3 x, y;
|
||||||
camWorldMat.transformVector(upAxis, &y);
|
camWorldMat.transformVector(upAxis, &y);
|
||||||
|
@ -139,23 +199,26 @@ void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||||
x.normalize();
|
x.normalize();
|
||||||
Vec3::cross(x, camDir, &y);
|
Vec3::cross(x, camDir, &y);
|
||||||
y.normalize();
|
y.normalize();
|
||||||
|
|
||||||
float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]);
|
float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]);
|
||||||
float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]);
|
float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]);
|
||||||
float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.m[10]);
|
float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.m[10]);
|
||||||
|
|
||||||
_billboardTransform.m[0] = x.x * xlen; _billboardTransform.m[1] = x.y * xlen; _billboardTransform.m[2] = x.z * xlen;
|
_billboardTransform.m[0] = x.x * xlen; _billboardTransform.m[1] = x.y * xlen; _billboardTransform.m[2] = x.z * xlen;
|
||||||
_billboardTransform.m[4] = y.x * ylen; _billboardTransform.m[5] = y.y * ylen; _billboardTransform.m[6] = y.z * ylen;
|
_billboardTransform.m[4] = y.x * ylen; _billboardTransform.m[5] = y.y * ylen; _billboardTransform.m[6] = y.z * ylen;
|
||||||
_billboardTransform.m[8] = -camDir.x * zlen; _billboardTransform.m[9] = -camDir.y * zlen; _billboardTransform.m[10] = -camDir.z * zlen;
|
_billboardTransform.m[8] = -camDir.x * zlen; _billboardTransform.m[9] = -camDir.y * zlen; _billboardTransform.m[10] = -camDir.z * zlen;
|
||||||
_billboardTransform.m[12] = localToWorld.m[12]; _billboardTransform.m[13] = localToWorld.m[13]; _billboardTransform.m[14] = localToWorld.m[14];
|
_billboardTransform.m[12] = localToWorld.m[12]; _billboardTransform.m[13] = localToWorld.m[13]; _billboardTransform.m[14] = localToWorld.m[14];
|
||||||
|
|
||||||
_billboardTransform.translate(-anchorPoint);
|
_billboardTransform.translate(-anchorPoint);
|
||||||
|
|
||||||
const Mat4 &viewMat = camWorldMat.getInversed();
|
|
||||||
_zDepthInView = -(viewMat.m[2] * _billboardTransform.m[12] + viewMat.m[6] * _billboardTransform.m[13] + viewMat.m[10] * _billboardTransform.m[14] + viewMat.m[14]);
|
|
||||||
_mvTransform = transform;
|
|
||||||
_camWorldMat = camWorldMat;
|
_camWorldMat = camWorldMat;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||||
|
{
|
||||||
|
const Mat4 &viewMat = _camWorldMat.getInversed();
|
||||||
|
_zDepthInView = -(viewMat.m[2] * _billboardTransform.m[12] + viewMat.m[6] * _billboardTransform.m[13] + viewMat.m[10] * _billboardTransform.m[14] + viewMat.m[14]);
|
||||||
|
|
||||||
//FIXME: frustum culling here
|
//FIXME: frustum culling here
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,10 @@ public:
|
||||||
Mode getMode() const;
|
Mode getMode() const;
|
||||||
|
|
||||||
//override
|
//override
|
||||||
|
|
||||||
|
/** update billboard's transform and turn it towards camera */
|
||||||
|
virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags);
|
||||||
|
|
||||||
/** draw BillBoard object */
|
/** draw BillBoard object */
|
||||||
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
|
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
|
||||||
|
|
||||||
|
@ -101,8 +105,9 @@ CC_CONSTRUCTOR_ACCESS:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void calculateBillbaordTransform();
|
||||||
|
|
||||||
Mat4 _camWorldMat;
|
Mat4 _camWorldMat;
|
||||||
Mat4 _mvTransform;
|
|
||||||
Mat4 _billboardTransform;
|
Mat4 _billboardTransform;
|
||||||
|
|
||||||
float _zDepthInView;
|
float _zDepthInView;
|
||||||
|
|
|
@ -131,32 +131,6 @@ void RenderQueue::clear()
|
||||||
_queuePosZ.clear();
|
_queuePosZ.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper
|
|
||||||
static bool compareTransparentRenderCommand(RenderCommand* a, RenderCommand* b)
|
|
||||||
{
|
|
||||||
return a->getGlobalOrder() > b->getGlobalOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransparentRenderQueue::push_back(RenderCommand* command)
|
|
||||||
{
|
|
||||||
_queueCmd.push_back(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransparentRenderQueue::sort()
|
|
||||||
{
|
|
||||||
std::sort(std::begin(_queueCmd), std::end(_queueCmd), compareTransparentRenderCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderCommand* TransparentRenderQueue::operator[](ssize_t index) const
|
|
||||||
{
|
|
||||||
return _queueCmd[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransparentRenderQueue::clear()
|
|
||||||
{
|
|
||||||
_queueCmd.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -531,65 +505,6 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::visitTransparentRenderQueue(const TransparentRenderQueue& queue)
|
|
||||||
{
|
|
||||||
// do not batch for transparent objects
|
|
||||||
ssize_t size = queue.size();
|
|
||||||
|
|
||||||
_batchedCommands.clear();
|
|
||||||
_filledVertex = 0;
|
|
||||||
_filledIndex = 0;
|
|
||||||
|
|
||||||
for (ssize_t index = 0; index < size; ++index)
|
|
||||||
{
|
|
||||||
auto command = queue[index];
|
|
||||||
auto commandType = command->getType();
|
|
||||||
if( RenderCommand::Type::TRIANGLES_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<TrianglesCommand*>(command);
|
|
||||||
_batchedCommands.push_back(cmd);
|
|
||||||
fillVerticesAndIndices(cmd);
|
|
||||||
drawBatchedTriangles();
|
|
||||||
}
|
|
||||||
else if(RenderCommand::Type::QUAD_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<QuadCommand*>(command);
|
|
||||||
_batchQuadCommands.push_back(cmd);
|
|
||||||
fillQuads(cmd);
|
|
||||||
drawBatchedQuads();
|
|
||||||
}
|
|
||||||
else if(RenderCommand::Type::GROUP_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
int renderQueueID = (static_cast<GroupCommand*>(command))->getRenderQueueID();
|
|
||||||
visitRenderQueue(_renderGroups[renderQueueID]);
|
|
||||||
}
|
|
||||||
else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<CustomCommand*>(command);
|
|
||||||
cmd->execute();
|
|
||||||
}
|
|
||||||
else if(RenderCommand::Type::BATCH_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<BatchCommand*>(command);
|
|
||||||
cmd->execute();
|
|
||||||
}
|
|
||||||
else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<PrimitiveCommand*>(command);
|
|
||||||
cmd->execute();
|
|
||||||
}
|
|
||||||
else if (RenderCommand::Type::MESH_COMMAND == commandType)
|
|
||||||
{
|
|
||||||
auto cmd = static_cast<MeshCommand*>(command);
|
|
||||||
cmd->execute();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CCLOGERROR("Unknown commands in renderQueue");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::render()
|
void Renderer::render()
|
||||||
{
|
{
|
||||||
//Uncomment this once everything is rendered by new renderer
|
//Uncomment this once everything is rendered by new renderer
|
||||||
|
@ -607,16 +522,6 @@ void Renderer::render()
|
||||||
renderqueue.sort();
|
renderqueue.sort();
|
||||||
}
|
}
|
||||||
visitRenderQueue(_renderGroups[0]);
|
visitRenderQueue(_renderGroups[0]);
|
||||||
|
|
||||||
//Process render commands
|
|
||||||
//draw transparent objects here, do not batch for transparent objects
|
|
||||||
if (0 < _transparentRenderGroups.size())
|
|
||||||
{
|
|
||||||
_transparentRenderGroups.sort();
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
visitTransparentRenderQueue(_transparentRenderGroups);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
clean();
|
clean();
|
||||||
_isRendering = false;
|
_isRendering = false;
|
||||||
|
@ -643,8 +548,6 @@ void Renderer::clean()
|
||||||
_numberQuads = 0;
|
_numberQuads = 0;
|
||||||
_lastMaterialID = 0;
|
_lastMaterialID = 0;
|
||||||
_lastBatchedMeshCommand = nullptr;
|
_lastBatchedMeshCommand = nullptr;
|
||||||
|
|
||||||
_transparentRenderGroups.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::clear()
|
void Renderer::clear()
|
||||||
|
|
|
@ -65,22 +65,6 @@ protected:
|
||||||
std::vector<RenderCommand*> _queuePosZ;
|
std::vector<RenderCommand*> _queuePosZ;
|
||||||
};
|
};
|
||||||
|
|
||||||
//render queue for transparency object, NOTE that the _globalOrder of RenderCommand is the distance to the camera when added to the transparent queue
|
|
||||||
class TransparentRenderQueue {
|
|
||||||
public:
|
|
||||||
void push_back(RenderCommand* command);
|
|
||||||
ssize_t size() const
|
|
||||||
{
|
|
||||||
return _queueCmd.size();
|
|
||||||
}
|
|
||||||
void sort();
|
|
||||||
RenderCommand* operator[](ssize_t index) const;
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<RenderCommand*> _queueCmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RenderStackElement
|
struct RenderStackElement
|
||||||
{
|
{
|
||||||
int renderQueueID;
|
int renderQueueID;
|
||||||
|
@ -172,8 +156,6 @@ protected:
|
||||||
|
|
||||||
void processRenderCommand(RenderCommand* command);
|
void processRenderCommand(RenderCommand* command);
|
||||||
void visitRenderQueue(const RenderQueue& queue);
|
void visitRenderQueue(const RenderQueue& queue);
|
||||||
|
|
||||||
void visitTransparentRenderQueue(const TransparentRenderQueue& queue);
|
|
||||||
|
|
||||||
void fillVerticesAndIndices(const TrianglesCommand* cmd);
|
void fillVerticesAndIndices(const TrianglesCommand* cmd);
|
||||||
void fillQuads(const QuadCommand* cmd);
|
void fillQuads(const QuadCommand* cmd);
|
||||||
|
@ -184,7 +166,6 @@ protected:
|
||||||
std::stack<int> _commandGroupStack;
|
std::stack<int> _commandGroupStack;
|
||||||
|
|
||||||
std::vector<RenderQueue> _renderGroups;
|
std::vector<RenderQueue> _renderGroups;
|
||||||
TransparentRenderQueue _transparentRenderGroups; //transparency objects
|
|
||||||
|
|
||||||
uint32_t _lastMaterialID;
|
uint32_t _lastMaterialID;
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ BillBoardTest::BillBoardTest()
|
||||||
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
|
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
|
||||||
billboard->setScale(0.5f);
|
billboard->setScale(0.5f);
|
||||||
billboard->setPosition3D(Vec3(0.0f, 0.0f, CCRANDOM_MINUS1_1() * 150.0f));
|
billboard->setPosition3D(Vec3(0.0f, 0.0f, CCRANDOM_MINUS1_1() * 150.0f));
|
||||||
billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
|
||||||
billboard->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
billboard->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
||||||
_billboards.push_back(billboard);
|
_billboards.push_back(billboard);
|
||||||
layer->addChild(billboard);
|
layer->addChild(billboard);
|
||||||
|
@ -204,7 +203,6 @@ void BillBoardTest::addNewBillBoradWithCoords(Vec3 p)
|
||||||
auto billborad = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
|
auto billborad = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1() * 1 + 0.5)]);
|
||||||
billborad->setScale(0.5f);
|
billborad->setScale(0.5f);
|
||||||
billborad->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
|
billborad->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
|
||||||
billborad->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
|
||||||
billborad->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
billborad->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
||||||
|
|
||||||
_layerBillBorad->addChild(billborad);
|
_layerBillBorad->addChild(billborad);
|
||||||
|
@ -233,7 +231,6 @@ void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)
|
||||||
|
|
||||||
auto action = Animate::create(animation);
|
auto action = Animate::create(animation);
|
||||||
billboardAni->runAction(RepeatForever::create(action));
|
billboardAni->runAction(RepeatForever::create(action));
|
||||||
billboardAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
|
||||||
billboardAni->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
billboardAni->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
||||||
_billboards.push_back(billboardAni);
|
_billboards.push_back(billboardAni);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue