Merge pull request #9953 from darkdukey/renderFix

Render fix
This commit is contained in:
minggo 2015-01-14 11:06:33 +08:00
commit 0207c22cb6
28 changed files with 905 additions and 544 deletions

View File

@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "2d/CCCamera.h"
#include "CCAtlasNode.h" #include "CCAtlasNode.h"
#include "renderer/CCTextureAtlas.h" #include "renderer/CCTextureAtlas.h"
#include "base/CCDirector.h" #include "base/CCDirector.h"
@ -132,6 +133,22 @@ void AtlasNode::updateAtlasValues()
// AtlasNode - draw // AtlasNode - draw
void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{ {
//Render as 3D object
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_quadCommand.init(
depth,
_textureAtlas->getTexture()->getName(),
getGLProgramState(),
_blendFunc,
_textureAtlas->getQuads(),
_quadsToDraw,
transform);
_quadCommand.set3D(true);
}
else
{
_quadCommand.init( _quadCommand.init(
_globalZOrder, _globalZOrder,
_textureAtlas->getTexture()->getName(), _textureAtlas->getTexture()->getName(),
@ -140,6 +157,7 @@ void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
_textureAtlas->getQuads(), _textureAtlas->getQuads(),
_quadsToDraw, _quadsToDraw,
transform); transform);
}
renderer->addCommand(&_quadCommand); renderer->addCommand(&_quadCommand);

View File

@ -30,7 +30,19 @@ NS_CC_BEGIN
Camera* Camera::_visitingCamera = nullptr; Camera* Camera::_visitingCamera = nullptr;
Camera* Camera::create()
Camera* Camera::getDefaultCamera()
{
auto scene = Director::getInstance()->getRunningScene();
if(scene)
{
return scene->getDefaultCamera();
}
return nullptr;
}
Camera* Camera::create()
{ {
Camera* camera = new (std::nothrow) Camera(); Camera* camera = new (std::nothrow) Camera();
camera->initDefault(); camera->initDefault();
@ -253,9 +265,9 @@ void Camera::unproject(const Size& viewport, Vec3* src, Vec3* dst) const
dst->set(screen.x, screen.y, screen.z); dst->set(screen.x, screen.y, screen.z);
} }
void Camera::enableFrustumCulling(bool enalbe, bool clipZ) void Camera::enableFrustumCulling(bool value, bool clipZ)
{ {
_enableFrustumCulling = enalbe; _enableFrustumCulling = value;
_frustum.setClipZ(clipZ); _frustum.setClipZ(clipZ);
} }
@ -273,6 +285,14 @@ bool Camera::isVisibleInFrustum(const AABB* aabb) const
return true; return true;
} }
float Camera::getDepthInView(const Mat4& transform) const
{
Mat4 camWorldMat = getNodeToWorldTransform();
const Mat4 &viewMat = camWorldMat.getInversed();
float depth = -(viewMat.m[2] * transform.m[12] + viewMat.m[6] * transform.m[13] + viewMat.m[10] * transform.m[14] + viewMat.m[14]);
return depth;
}
void Camera::onEnter() void Camera::onEnter()
{ {
if (_scene == nullptr) if (_scene == nullptr)

View File

@ -35,8 +35,9 @@ class Scene;
* Note: * Note:
* Scene creates a default camera. And the default camera mask of Node is 1, therefore it can be seen by the default camera. * Scene creates a default camera. And the default camera mask of Node is 1, therefore it can be seen by the default camera.
* During rendering the scene, it draws the objects seen by each camera in the added order except default camera. The default camera is the last one being drawn with. * During rendering the scene, it draws the objects seen by each camera in the added order except default camera. The default camera is the last one being drawn with.
* If 3D objects exist, you'd better create a seperate camera for them. And set the 3d camera flag to CameraFlag::USER1 or anything else except DEFAULT. The DEFAULT camera is for UI, because it is rendered at last. * It's usually a good idea to render 3D objects in a separate camera.
* You can change the camera added order to get different result when depth test is not enabled. * And set the 3d camera flag to CameraFlag::USER1 or anything else except DEFAULT. Dedicate The DEFAULT camera for UI, because it is rendered at last.
* You can change the camera order to get different result when depth test is not enabled.
* For each camera, transparent 3d sprite is rendered after opaque 3d sprite and other 2d objects. * For each camera, transparent 3d sprite is rendered after opaque 3d sprite and other 2d objects.
*/ */
enum class CameraFlag enum class CameraFlag
@ -105,15 +106,14 @@ public:
* Sets the position (X, Y, and Z) in its parent's coordinate system * Sets the position (X, Y, and Z) in its parent's coordinate system
*/ */
virtual void setPosition3D(const Vec3& position) override; virtual void setPosition3D(const Vec3& position) override;
/** /**
* Creates a view matrix based on the specified input parameters. * Make Camera looks at target
* *
* @param eyePosition The eye position. * @param target The target camera is point at
* @param targetPosition The target's center position. * @param up The up vector, usually it's Y axis
* @param up The up vector.
* @param dst A matrix to store the result in.
*/ */
virtual void lookAt(const Vec3& target, const Vec3& up); virtual void lookAt(const Vec3& target, const Vec3& up = Vec3::UNIT_Y);
/** /**
* Gets the camera's projection matrix. * Gets the camera's projection matrix.
@ -139,18 +139,24 @@ public:
/** /**
* Enable frustum culling * Enable frustum culling
*/ */
void enableFrustumCulling(bool enalbe, bool clipZ); void enableFrustumCulling(bool value, bool clipZ);
/** /**
* Is this aabb visible in frustum * Is this aabb visible in frustum
*/ */
bool isVisibleInFrustum(const AABB* aabb)const; bool isVisibleInFrustum(const AABB* aabb) const;
/**
* Get object depth towards camera
*/
float getDepthInView(const Mat4& transform) const;
//override //override
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
static const Camera* getVisitingCamera() { return _visitingCamera; } static const Camera* getVisitingCamera() { return _visitingCamera; }
static Camera* getDefaultCamera();
CC_CONSTRUCTOR_ACCESS: CC_CONSTRUCTOR_ACCESS:
Camera(); Camera();

View File

@ -23,6 +23,7 @@
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "2d/CCCamera.h"
#include "2d/CCLabel.h" #include "2d/CCLabel.h"
#include "2d/CCFontAtlasCache.h" #include "2d/CCFontAtlasCache.h"
#include "2d/CCSprite.h" #include "2d/CCSprite.h"
@ -896,8 +897,18 @@ void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
_insideBounds = transformUpdated ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; _insideBounds = transformUpdated ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
if(_insideBounds) { if(_insideBounds) {
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_customCommand.init(depth);
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
}
else
{
_customCommand.init(_globalZOrder); _customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated); _customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
}
renderer->addCommand(&_customCommand); renderer->addCommand(&_customCommand);
} }
} }

View File

@ -108,6 +108,7 @@ public:
enum { enum {
FLAGS_TRANSFORM_DIRTY = (1 << 0), FLAGS_TRANSFORM_DIRTY = (1 << 0),
FLAGS_CONTENT_SIZE_DIRTY = (1 << 1), FLAGS_CONTENT_SIZE_DIRTY = (1 << 1),
FLAGS_RENDER_AS_3D = (1 << 3),
FLAGS_DIRTY_MASK = (FLAGS_TRANSFORM_DIRTY | FLAGS_CONTENT_SIZE_DIRTY), FLAGS_DIRTY_MASK = (FLAGS_TRANSFORM_DIRTY | FLAGS_CONTENT_SIZE_DIRTY),
}; };

View File

@ -29,7 +29,7 @@
*/ */
#include "2d/CCParticleBatchNode.h" #include "2d/CCParticleBatchNode.h"
#include "2d/CCCamera.h"
#include "2d/CCGrid.h" #include "2d/CCGrid.h"
#include "2d/CCParticleSystem.h" #include "2d/CCParticleSystem.h"
#include "renderer/CCTextureCache.h" #include "renderer/CCTextureCache.h"
@ -403,12 +403,25 @@ void ParticleBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t
return; return;
} }
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_batchCommand.init(
depth,
getGLProgram(),
_blendFunc,
_textureAtlas,
_modelViewTransform);
}
else
{
_batchCommand.init( _batchCommand.init(
_globalZOrder, _globalZOrder,
getGLProgram(), getGLProgram(),
_blendFunc, _blendFunc,
_textureAtlas, _textureAtlas,
_modelViewTransform); _modelViewTransform);
}
renderer->addCommand(&_batchCommand); renderer->addCommand(&_batchCommand);
CC_PROFILER_STOP("CCParticleBatchNode - draw"); CC_PROFILER_STOP("CCParticleBatchNode - draw");
} }

View File

@ -31,6 +31,7 @@ THE SOFTWARE.
#include <algorithm> #include <algorithm>
#include "2d/CCCamera.h"
#include "2d/CCSpriteFrame.h" #include "2d/CCSpriteFrame.h"
#include "2d/CCParticleBatchNode.h" #include "2d/CCParticleBatchNode.h"
#include "renderer/CCTextureAtlas.h" #include "renderer/CCTextureAtlas.h"
@ -371,10 +372,19 @@ void ParticleSystemQuad::draw(Renderer *renderer, const Mat4 &transform, uint32_
CCASSERT( _particleIdx == 0 || _particleIdx == _particleCount, "Abnormal error in particle quad"); CCASSERT( _particleIdx == 0 || _particleIdx == _particleCount, "Abnormal error in particle quad");
//quad command //quad command
if(_particleIdx > 0) if(_particleIdx > 0)
{
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_quadCommand.init(depth, _texture->getName(), getGLProgramState(), _blendFunc, _quads, _particleIdx, transform);
renderer->addCommand(&_quadCommand);
}
else
{ {
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _quads, _particleIdx, transform); _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _quads, _particleIdx, transform);
renderer->addCommand(&_quadCommand); renderer->addCommand(&_quadCommand);
} }
}
} }
void ParticleSystemQuad::setTotalParticles(int tp) void ParticleSystemQuad::setTotalParticles(int tp)

View File

@ -73,6 +73,8 @@ public:
/** get all cameras */ /** get all cameras */
const std::vector<Camera*>& getCameras() const { return _cameras; } const std::vector<Camera*>& getCameras() const { return _cameras; }
Camera* getDefaultCamera() const { return _defaultCamera; }
const std::vector<BaseLight*>& getLights() const { return _lights; } const std::vector<BaseLight*>& getLights() const { return _lights; }
/** render the scene */ /** render the scene */

View File

@ -29,6 +29,7 @@ THE SOFTWARE.
#include <algorithm> #include <algorithm>
#include "2d/CCCamera.h"
#include "2d/CCSpriteBatchNode.h" #include "2d/CCSpriteBatchNode.h"
#include "2d/CCAnimationCache.h" #include "2d/CCAnimationCache.h"
#include "2d/CCSpriteFrame.h" #include "2d/CCSpriteFrame.h"
@ -591,9 +592,20 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds; _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
if(_insideBounds) if(_insideBounds)
{
//Render as 3D object
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_quadCommand.init(depth, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
_quadCommand.set3D(true);
}
else
{ {
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform); _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
}
renderer->addCommand(&_quadCommand); renderer->addCommand(&_quadCommand);
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW
_debugDrawNode->clear(); _debugDrawNode->clear();
Vec2 vertices[4] = { Vec2 vertices[4] = {

View File

@ -26,6 +26,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "2d/CCCamera.h"
#include "2d/CCSpriteBatchNode.h" #include "2d/CCSpriteBatchNode.h"
#include "2d/CCSprite.h" #include "2d/CCSprite.h"
#include "base/CCDirector.h" #include "base/CCDirector.h"
@ -378,12 +379,26 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
child->updateTransform(); child->updateTransform();
} }
//Render as 3D object
if (flags & FLAGS_RENDER_AS_3D)
{
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
_batchCommand.init(
depth,
getGLProgram(),
_blendFunc,
_textureAtlas,
transform);
}
else
{
_batchCommand.init( _batchCommand.init(
_globalZOrder, _globalZOrder,
getGLProgram(), getGLProgram(),
_blendFunc, _blendFunc,
_textureAtlas, _textureAtlas,
transform); transform);
}
renderer->addCommand(&_batchCommand); renderer->addCommand(&_batchCommand);
} }

View File

@ -32,8 +32,7 @@
NS_CC_BEGIN NS_CC_BEGIN
BillBoard::BillBoard() BillBoard::BillBoard()
: _zDepthInView(0.0f) : _mode(Mode::VIEW_POINT_ORIENTED)
, _mode(Mode::VIEW_POINT_ORIENTED)
, _modeDirty(false) , _modeDirty(false)
{ {
Node::setAnchorPoint(Vec2(0.5f,0.5f)); Node::setAnchorPoint(Vec2(0.5f,0.5f));
@ -96,15 +95,77 @@ 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);
//Add 3D flag so all the children will be rendered as 3D object
flags |= FLAGS_RENDER_AS_3D;
//Update Billboard transform
bool dirty = calculateBillbaordTransform();
if(dirty)
{
flags |= FLAGS_TRANSFORM_DIRTY;
}
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, _modelViewTransform, flags);
else
break;
}
// self draw
if (visibleByCamera)
this->draw(renderer, _modelViewTransform, flags);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
}
else if (visibleByCamera)
{
this->draw(renderer, _modelViewTransform, flags);
}
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
bool 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 and maintain
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)
{ {
@ -119,19 +180,23 @@ void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
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);
@ -144,25 +209,35 @@ void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
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; Mat4 billboardTransform;
_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[12] = localToWorld.m[12]; _billboardTransform.m[13] = localToWorld.m[13]; _billboardTransform.m[14] = localToWorld.m[14];
_billboardTransform.translate(-anchorPoint); 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[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.translate(-anchorPoint);
_modelViewTransform = billboardTransform;
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;
return true;
} }
return false;
}
void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
//Get depth
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
//FIXME: frustum culling here //FIXME: frustum culling here
{ _quadCommand.init(depth, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _modelViewTransform);
_quadCommand.init(_zDepthInView, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _billboardTransform);
_quadCommand.setTransparent(true); _quadCommand.setTransparent(true);
_quadCommand.setSkipBatching(true);
_quadCommand.set3D(true);
renderer->addCommand(&_quadCommand); renderer->addCommand(&_quadCommand);
}
} }
void BillBoard::setMode( Mode mode ) void BillBoard::setMode( Mode mode )

View File

@ -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;
@ -98,11 +102,9 @@ CC_CONSTRUCTOR_ACCESS:
protected: protected:
Mat4 _camWorldMat; bool calculateBillbaordTransform();
Mat4 _mvTransform;
Mat4 _billboardTransform;
float _zDepthInView; Mat4 _camWorldMat;
Mode _mode; Mode _mode;
bool _modeDirty; bool _modeDirty;

View File

@ -48,10 +48,23 @@ NS_CC_BEGIN
std::string s_attributeNames[] = {GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::ATTRIBUTE_NAME_TEX_COORD1, GLProgram::ATTRIBUTE_NAME_TEX_COORD2,GLProgram::ATTRIBUTE_NAME_TEX_COORD3,GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT, GLProgram::ATTRIBUTE_NAME_BLEND_INDEX}; std::string s_attributeNames[] = {GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::ATTRIBUTE_NAME_TEX_COORD1, GLProgram::ATTRIBUTE_NAME_TEX_COORD2,GLProgram::ATTRIBUTE_NAME_TEX_COORD3,GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT, GLProgram::ATTRIBUTE_NAME_BLEND_INDEX};
Sprite3D* Sprite3D::create()
{
//
auto sprite = new (std::nothrow) Sprite3D();
if (sprite && sprite->init())
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
Sprite3D* Sprite3D::create(const std::string &modelPath) Sprite3D* Sprite3D::create(const std::string &modelPath)
{ {
if (modelPath.length() < 4) if (modelPath.length() < 4)
CCASSERT(false, "improper name specified when creating Sprite3D"); CCASSERT(false, "invalid filename for Sprite3D");
auto sprite = new (std::nothrow) Sprite3D(); auto sprite = new (std::nothrow) Sprite3D();
if (sprite && sprite->initWithFile(modelPath)) if (sprite && sprite->initWithFile(modelPath))
@ -241,6 +254,15 @@ Sprite3D::~Sprite3D()
removeAllAttachNode(); removeAllAttachNode();
} }
bool Sprite3D::init()
{
if(Node::init())
{
return true;
}
return false;
}
bool Sprite3D::initWithFile(const std::string &path) bool Sprite3D::initWithFile(const std::string &path)
{ {
_meshes.clear(); _meshes.clear();
@ -599,6 +621,54 @@ static Texture2D * getDummyTexture()
} }
#endif #endif
void Sprite3D::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4 &parentTransform, uint32_t parentFlags)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
}
uint32_t flags = processParentFlags(parentTransform, parentFlags);
flags &= FLAGS_RENDER_AS_3D;
//
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, _modelViewTransform, flags);
else
break;
}
// self draw
if (visibleByCamera)
this->draw(renderer, _modelViewTransform, flags);
for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
}
else if (visibleByCamera)
{
this->draw(renderer, _modelViewTransform, flags);
}
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{ {
// camera clipping // camera clipping
@ -651,9 +721,11 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
float globalZ = _globalZOrder; float globalZ = _globalZOrder;
bool isTransparent = (mesh->_isTransparent || color.a < 1.f); bool isTransparent = (mesh->_isTransparent || color.a < 1.f);
if (isTransparent && Camera::getVisitingCamera()) if (isTransparent && Camera::getVisitingCamera())
{ // use the view matrix for Applying to recalculating transparent mesh's Z-Order {
// use the view matrix for Applying to recalculating transparent mesh's Z-Order
const auto& viewMat = Camera::getVisitingCamera()->getViewMatrix(); const auto& viewMat = Camera::getVisitingCamera()->getViewMatrix();
globalZ = -(viewMat.m[2] * transform.m[12] + viewMat.m[6] * transform.m[13] + viewMat.m[10] * transform.m[14] + viewMat.m[14]);//fetch the Z from the result matrix //fetch the Z from the result matrix
globalZ = -(viewMat.m[2] * transform.m[12] + viewMat.m[6] * transform.m[13] + viewMat.m[10] * transform.m[14] + viewMat.m[14]);
} }
meshCommand.init(globalZ, textureID, programstate, _blend, mesh->getVertexBuffer(), mesh->getIndexBuffer(), mesh->getPrimitiveType(), mesh->getIndexFormat(), mesh->getIndexCount(), transform); meshCommand.init(globalZ, textureID, programstate, _blend, mesh->getVertexBuffer(), mesh->getIndexBuffer(), mesh->getPrimitiveType(), mesh->getIndexFormat(), mesh->getIndexCount(), transform);

View File

@ -50,6 +50,13 @@ struct NodeData;
class CC_DLL Sprite3D : public Node, public BlendProtocol class CC_DLL Sprite3D : public Node, public BlendProtocol
{ {
public: public:
/**
* Creates an empty sprite3D without 3D model and texture.
*
* @return An autoreleased sprite3D object.
*/
static Sprite3D* create();
/** creates a Sprite3D*/ /** creates a Sprite3D*/
static Sprite3D* create(const std::string &modelPath); static Sprite3D* create(const std::string &modelPath);
@ -138,6 +145,9 @@ CC_CONSTRUCTOR_ACCESS:
Sprite3D(); Sprite3D();
virtual ~Sprite3D(); virtual ~Sprite3D();
bool init();
bool initWithFile(const std::string &path); bool initWithFile(const std::string &path);
bool initFrom(const NodeDatas& nodedatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas); bool initFrom(const NodeDatas& nodedatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas);
@ -148,6 +158,12 @@ CC_CONSTRUCTOR_ACCESS:
/** load file and set it to meshedatas, nodedatas and materialdatas, obj file .mtl file should be at the same directory if exist */ /** load file and set it to meshedatas, nodedatas and materialdatas, obj file .mtl file should be at the same directory if exist */
bool loadFromFile(const std::string& path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas); bool loadFromFile(const std::string& path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas);
/**
* Visits this Sprite3D's children and draw them recursively.
* Note: all its children will rendered as 3D objects
*/
virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
/**draw*/ /**draw*/
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override; virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;

View File

@ -170,12 +170,6 @@ bool Director::init(void)
_console = new (std::nothrow) Console; _console = new (std::nothrow) Console;
// default clear color
_clearColor.r = 0;
_clearColor.g = 0;
_clearColor.b = 0;
_clearColor.a = 1.0;
return true; return true;
} }
@ -258,9 +252,6 @@ void Director::setGLDefaultValues()
// [self setDepthTest: view_.depthFormat]; // [self setDepthTest: view_.depthFormat];
setDepthTest(false); setDepthTest(false);
setProjection(_projection); setProjection(_projection);
// set other opengl default values
glClearColor(_clearColor.r, _clearColor.g, _clearColor.b, _clearColor.a);
} }
// Draw the Scene // Draw the Scene
@ -281,7 +272,7 @@ void Director::drawScene()
_eventDispatcher->dispatchEvent(_eventAfterUpdate); _eventDispatcher->dispatchEvent(_eventAfterUpdate);
} }
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _renderer->clear();
/* to avoid flickr, nextScene MUST be here: after tick and before draw. /* to avoid flickr, nextScene MUST be here: after tick and before draw.
* FIXME: Which bug is this one. It seems that it can't be reproduced with v0.9 * FIXME: Which bug is this one. It seems that it can't be reproduced with v0.9
@ -726,8 +717,7 @@ void Director::setDepthTest(bool on)
void Director::setClearColor(const Color4F& clearColor) void Director::setClearColor(const Color4F& clearColor)
{ {
_clearColor = clearColor; _renderer->setClearColor(clearColor);
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
} }
static void GLToClipTransform(Mat4 *transformOut) static void GLToClipTransform(Mat4 *transformOut)

View File

@ -475,9 +475,6 @@ protected:
unsigned int _totalFrames; unsigned int _totalFrames;
float _secondsPerFrame; float _secondsPerFrame;
/* clear color set outside be used in setGLDefaultValues() */
Color4F _clearColor;
/* The running scene */ /* The running scene */
Scene *_runningScene; Scene *_runningScene;

View File

@ -123,7 +123,7 @@ void MeshCommand::init(float globalOrder,
_indexFormat = indexFormat; _indexFormat = indexFormat;
_indexCount = indexCount; _indexCount = indexCount;
_mv.set(mv); _mv.set(mv);
_is3D = true;
} }
void MeshCommand::setCullFaceEnabled(bool enable) void MeshCommand::setCullFaceEnabled(bool enable)
@ -151,6 +151,14 @@ void MeshCommand::setDisplayColor(const Vec4& color)
_displayColor = color; _displayColor = color;
} }
void MeshCommand::setTransparent(bool value)
{
_isTransparent = value;
//Skip batching for transparent mesh
_skipBatching = value;
setDepthWriteEnabled(!_isTransparent);
}
MeshCommand::~MeshCommand() MeshCommand::~MeshCommand()
{ {
releaseVAO(); releaseVAO();

View File

@ -64,6 +64,8 @@ public:
void setLightMask(unsigned int lightmask) { _lightMask = lightmask; } void setLightMask(unsigned int lightmask) { _lightMask = lightmask; }
void setTransparent(bool value);
void execute(); void execute();
//used for bath //used for bath

View File

@ -30,7 +30,9 @@ NS_CC_BEGIN
RenderCommand::RenderCommand() RenderCommand::RenderCommand()
: _type(RenderCommand::Type::UNKNOWN_COMMAND) : _type(RenderCommand::Type::UNKNOWN_COMMAND)
, _globalOrder(0) , _globalOrder(0)
, _isTransparent(false) , _isTransparent(true)
, _skipBatching(false)
, _is3D(false)
{ {
} }

View File

@ -65,6 +65,14 @@ public:
/** set transparent flag */ /** set transparent flag */
inline void setTransparent(bool isTransparent) { _isTransparent = isTransparent; } inline void setTransparent(bool isTransparent) { _isTransparent = isTransparent; }
inline bool isSkipBatching() const { return _skipBatching; }
inline void setSkipBatching(bool value) { _skipBatching = value; }
inline bool is3D() const { return _is3D; }
inline void set3D(bool value) { _is3D = value; }
protected: protected:
RenderCommand(); RenderCommand();
virtual ~RenderCommand(); virtual ~RenderCommand();
@ -79,6 +87,12 @@ protected:
// transparent flag // transparent flag
bool _isTransparent; bool _isTransparent;
// skip auto batching
bool _skipBatching;
// is the command been rendered on 3D pass
bool _is3D;
}; };
NS_CC_END NS_CC_END

View File

@ -51,12 +51,28 @@ static bool compareRenderCommand(RenderCommand* a, RenderCommand* b)
return a->getGlobalOrder() < b->getGlobalOrder(); return a->getGlobalOrder() < b->getGlobalOrder();
} }
static bool compare3DCommand(RenderCommand* a, RenderCommand* b)
{
return a->getGlobalOrder() > b->getGlobalOrder();
}
// queue // queue
void RenderQueue::push_back(RenderCommand* command) void RenderQueue::push_back(RenderCommand* command)
{ {
float z = command->getGlobalOrder(); float z = command->getGlobalOrder();
if(z < 0) if(command->is3D())
{
if(command->isTransparent())
{
_queue3DTransparent.push_back(command);
}
else
{
_queue3DOpaque.push_back(command);
}
}
else if(z < 0)
_queueNegZ.push_back(command); _queueNegZ.push_back(command);
else if(z > 0) else if(z > 0)
_queuePosZ.push_back(command); _queuePosZ.push_back(command);
@ -66,18 +82,29 @@ void RenderQueue::push_back(RenderCommand* command)
ssize_t RenderQueue::size() const ssize_t RenderQueue::size() const
{ {
return _queueNegZ.size() + _queue0.size() + _queuePosZ.size(); return _queue3DOpaque.size() + _queue3DTransparent.size() + _queueNegZ.size() + _queue0.size() + _queuePosZ.size();
} }
void RenderQueue::sort() void RenderQueue::sort()
{ {
// Don't sort _queue0, it already comes sorted // Don't sort _queue0, it already comes sorted
std::sort(std::begin(_queue3DTransparent), std::end(_queue3DTransparent), compare3DCommand);
std::sort(std::begin(_queueNegZ), std::end(_queueNegZ), compareRenderCommand); std::sort(std::begin(_queueNegZ), std::end(_queueNegZ), compareRenderCommand);
std::sort(std::begin(_queuePosZ), std::end(_queuePosZ), compareRenderCommand); std::sort(std::begin(_queuePosZ), std::end(_queuePosZ), compareRenderCommand);
} }
RenderCommand* RenderQueue::operator[](ssize_t index) const RenderCommand* RenderQueue::operator[](ssize_t index) const
{ {
if(index < static_cast<ssize_t>(_queue3DOpaque.size()))
return _queue3DOpaque[index];
index -= _queue3DOpaque.size();
if(index < static_cast<ssize_t>(_queue3DTransparent.size()))
return _queue3DTransparent[index];
index -= _queue3DTransparent.size();
if(index < static_cast<ssize_t>(_queueNegZ.size())) if(index < static_cast<ssize_t>(_queueNegZ.size()))
return _queueNegZ[index]; return _queueNegZ[index];
@ -97,37 +124,13 @@ RenderCommand* RenderQueue::operator[](ssize_t index) const
void RenderQueue::clear() void RenderQueue::clear()
{ {
_queue3DOpaque.clear();
_queue3DTransparent.clear();
_queueNegZ.clear(); _queueNegZ.clear();
_queue0.clear(); _queue0.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();
}
// //
// //
// //
@ -155,6 +158,9 @@ Renderer::Renderer()
RenderQueue defaultRenderQueue; RenderQueue defaultRenderQueue;
_renderGroups.push_back(defaultRenderQueue); _renderGroups.push_back(defaultRenderQueue);
_batchedCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE); _batchedCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
// default clear color
_clearColor = Color4F::BLACK;
} }
Renderer::~Renderer() Renderer::~Renderer()
@ -344,26 +350,20 @@ int Renderer::createRenderQueue()
return (int)_renderGroups.size() - 1; return (int)_renderGroups.size() - 1;
} }
void Renderer::visitRenderQueue(const RenderQueue& queue) void Renderer::processRenderCommand(RenderCommand* command)
{ {
ssize_t size = queue.size();
for (ssize_t index = 0; index < size; ++index)
{
auto command = queue[index];
auto commandType = command->getType(); auto commandType = command->getType();
if( RenderCommand::Type::TRIANGLES_COMMAND == commandType) if( RenderCommand::Type::TRIANGLES_COMMAND == commandType)
{ {
//Draw if we have batched other commands which are not triangle command
flush3D(); flush3D();
if(_numberQuads > 0) flushQuads();
{
drawBatchedQuads();
_lastMaterialID = 0;
}
//Process triangle command
auto cmd = static_cast<TrianglesCommand*>(command); auto cmd = static_cast<TrianglesCommand*>(command);
//Batch Triangles
if( _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE) //Draw batched Triangles if necessary
if(cmd->isSkipBatching() || _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE)
{ {
CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getVertexCount()>= 0 && cmd->getVertexCount() < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command");
CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command");
@ -371,32 +371,68 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
drawBatchedTriangles(); drawBatchedTriangles();
} }
//Batch Triangles
_batchedCommands.push_back(cmd); _batchedCommands.push_back(cmd);
fillVerticesAndIndices(cmd); fillVerticesAndIndices(cmd);
if(cmd->isSkipBatching())
{
drawBatchedTriangles();
}
} }
else if ( RenderCommand::Type::QUAD_COMMAND == commandType ) else if ( RenderCommand::Type::QUAD_COMMAND == commandType )
{ {
//Draw if we have batched other commands which are not quad command
flush3D(); flush3D();
if(_filledIndex > 0) flushTriangles();
{
drawBatchedTriangles(); //Process quad command
_lastMaterialID = 0;
}
auto cmd = static_cast<QuadCommand*>(command); auto cmd = static_cast<QuadCommand*>(command);
//Batch quads
if( (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) //Draw batched quads if necessary
if(cmd->isSkipBatching()|| (_numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE )
{ {
CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command");
//Draw batched quads if VBO is full //Draw batched quads if VBO is full
drawBatchedQuads(); drawBatchedQuads();
} }
//Batch Quads
_batchQuadCommands.push_back(cmd); _batchQuadCommands.push_back(cmd);
fillQuads(cmd); fillQuads(cmd);
if(cmd->isSkipBatching())
{
drawBatchedQuads();
}
}
else if (RenderCommand::Type::MESH_COMMAND == commandType)
{
flush2D();
auto cmd = static_cast<MeshCommand*>(command);
if (cmd->isSkipBatching() || _lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID())
{
flush3D();
if(cmd->isSkipBatching())
{
cmd->execute();
}
else
{
cmd->preBatchDraw();
cmd->batchDraw();
_lastBatchedMeshCommand = cmd;
}
}
else
{
cmd->batchDraw();
}
} }
else if(RenderCommand::Type::GROUP_COMMAND == commandType) else if(RenderCommand::Type::GROUP_COMMAND == commandType)
{ {
@ -422,86 +458,48 @@ void Renderer::visitRenderQueue(const RenderQueue& queue)
auto cmd = static_cast<PrimitiveCommand*>(command); auto cmd = static_cast<PrimitiveCommand*>(command);
cmd->execute(); cmd->execute();
} }
else if (RenderCommand::Type::MESH_COMMAND == commandType)
{
flush2D();
auto cmd = static_cast<MeshCommand*>(command);
if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID())
{
flush3D();
cmd->preBatchDraw();
cmd->batchDraw();
_lastBatchedMeshCommand = cmd;
}
else
{
cmd->batchDraw();
}
}
else else
{ {
CCLOGERROR("Unknown commands in renderQueue"); CCLOGERROR("Unknown commands in renderQueue");
} }
}
} }
void Renderer::visitTransparentRenderQueue(const TransparentRenderQueue& queue) void Renderer::visitRenderQueue(const RenderQueue& queue)
{ {
// do not batch for transparent objects
ssize_t size = queue.size(); ssize_t size = queue.size();
_batchedCommands.clear(); //Process Opaque Object
_filledVertex = 0; const std::vector<RenderCommand*>& opaqueQueue = queue.getOpaqueCommands();
_filledIndex = 0; if (opaqueQueue.size() > 0)
{
glDepthMask(true);
glEnable(GL_DEPTH_TEST);
for (ssize_t index = 0; index < size; ++index) for (auto it = opaqueQueue.cbegin(); it != opaqueQueue.cend(); ++it) {
{ processRenderCommand(*it);
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)
{ glDisable(GL_DEPTH_TEST);
auto cmd = static_cast<QuadCommand*>(command); glDepthMask(false);
_batchQuadCommands.push_back(cmd);
fillQuads(cmd);
drawBatchedQuads();
} }
else if(RenderCommand::Type::GROUP_COMMAND == commandType) flush();
//Setup Transparent rendering
if (opaqueQueue.size() > 0)
{ {
int renderQueueID = (static_cast<GroupCommand*>(command))->getRenderQueueID(); glEnable(GL_DEPTH_TEST);
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 else
{ {
CCLOGERROR("Unknown commands in renderQueue"); glDisable(GL_DEPTH_TEST);
} }
//Process Transparent Object
for (ssize_t index = queue.getOpaqueQueueSize(); index < size; ++index)
{
processRenderCommand(queue[index]);
} }
flush();
} }
void Renderer::render() void Renderer::render()
@ -521,17 +519,6 @@ void Renderer::render()
renderqueue.sort(); renderqueue.sort();
} }
visitRenderQueue(_renderGroups[0]); visitRenderQueue(_renderGroups[0]);
flush();
//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;
@ -558,8 +545,14 @@ void Renderer::clean()
_numberQuads = 0; _numberQuads = 0;
_lastMaterialID = 0; _lastMaterialID = 0;
_lastBatchedMeshCommand = nullptr; _lastBatchedMeshCommand = nullptr;
}
_transparentRenderGroups.clear(); void Renderer::clear()
{
//Enable Depth mask to make sure glClear clear the depth buffer correctly
glDepthMask(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(false);
} }
void Renderer::fillVerticesAndIndices(const TrianglesCommand* cmd) void Renderer::fillVerticesAndIndices(const TrianglesCommand* cmd)
@ -819,23 +812,8 @@ void Renderer::flush()
void Renderer::flush2D() void Renderer::flush2D()
{ {
//Check depth write flushQuads();
GLboolean depthWirte; flushTriangles();
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWirte);
//Turn depth write off if necessary
if(depthWirte)
{
glDepthMask(false);
}
drawBatchedQuads();
_lastMaterialID = 0;
drawBatchedTriangles();
_lastMaterialID = 0;
//Turn depth write on if necessary
if(depthWirte)
{
glDepthMask(true);
}
} }
void Renderer::flush3D() void Renderer::flush3D()
@ -847,8 +825,25 @@ void Renderer::flush3D()
} }
} }
// helpers void Renderer::flushQuads()
{
if(_numberQuads > 0)
{
drawBatchedQuads();
_lastMaterialID = 0;
}
}
void Renderer::flushTriangles()
{
if(_filledIndex > 0)
{
drawBatchedTriangles();
_lastMaterialID = 0;
}
}
// helpers
bool Renderer::checkVisibility(const Mat4 &transform, const Size &size) bool Renderer::checkVisibility(const Mat4 &transform, const Size &size)
{ {
auto scene = Director::getInstance()->getRunningScene(); auto scene = Director::getInstance()->getRunningScene();
@ -884,4 +879,11 @@ bool Renderer::checkVisibility(const Mat4 &transform, const Size &size)
return ret; return ret;
} }
void Renderer::setClearColor(const Color4F &clearColor)
{
_clearColor = clearColor;
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
}
NS_CC_END NS_CC_END

View File

@ -54,29 +54,17 @@ public:
void sort(); void sort();
RenderCommand* operator[](ssize_t index) const; RenderCommand* operator[](ssize_t index) const;
void clear(); void clear();
ssize_t getOpaqueQueueSize() const { return _queue3DOpaque.size(); }
const std::vector<RenderCommand*>& getOpaqueCommands() const { return _queue3DOpaque; }
protected: protected:
std::vector<RenderCommand*> _queue3DOpaque;
std::vector<RenderCommand*> _queue3DTransparent;
std::vector<RenderCommand*> _queueNegZ; std::vector<RenderCommand*> _queueNegZ;
std::vector<RenderCommand*> _queue0; std::vector<RenderCommand*> _queue0;
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;
@ -125,6 +113,11 @@ public:
/** Cleans all `RenderCommand`s in the queue */ /** Cleans all `RenderCommand`s in the queue */
void clean(); void clean();
/** Clear GL buffer and screen */
void clear();
/** set color for clear screen */
void setClearColor(const Color4F& clearColor);
/* returns the number of drawn batches in the last frame */ /* returns the number of drawn batches in the last frame */
ssize_t getDrawnBatches() const { return _drawnBatches; } ssize_t getDrawnBatches() const { return _drawnBatches; }
/* RenderCommands (except) QuadCommand should update this value */ /* RenderCommands (except) QuadCommand should update this value */
@ -158,17 +151,21 @@ protected:
void flush3D(); void flush3D();
void visitRenderQueue(const RenderQueue& queue); void flushQuads();
void flushTriangles();
void visitTransparentRenderQueue(const TransparentRenderQueue& queue); void processRenderCommand(RenderCommand* command);
void visitRenderQueue(const RenderQueue& queue);
void fillVerticesAndIndices(const TrianglesCommand* cmd); void fillVerticesAndIndices(const TrianglesCommand* cmd);
void fillQuads(const QuadCommand* cmd); void fillQuads(const QuadCommand* cmd);
/* clear color set outside be used in setGLDefaultValues() */
Color4F _clearColor;
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;
@ -176,7 +173,6 @@ protected:
std::vector<TrianglesCommand*> _batchedCommands; std::vector<TrianglesCommand*> _batchedCommands;
std::vector<QuadCommand*> _batchQuadCommands; std::vector<QuadCommand*> _batchQuadCommands;
//for TrianglesCommand //for TrianglesCommand
V3F_C4B_T2F _verts[VBO_SIZE]; V3F_C4B_T2F _verts[VBO_SIZE];
GLushort _indices[INDEX_VBO_SIZE]; GLushort _indices[INDEX_VBO_SIZE];

View File

@ -606,15 +606,6 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
if(!numberOfQuads) if(!numberOfQuads)
return; return;
//Check depth write
GLboolean depthWirte;
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthWirte);
//Turn depth write off if necessary
if(depthWirte)
{
glDepthMask(false);
}
GL::bindTexture2D(_texture->getName()); GL::bindTexture2D(_texture->getName());
if (Configuration::getInstance()->supportsShareableVAO()) if (Configuration::getInstance()->supportsShareableVAO())
@ -695,12 +686,6 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,numberOfQuads*6); CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,numberOfQuads*6);
//Turn depth write on if necessary
if(depthWirte)
{
glDepthMask(true);
}
CHECK_GL_ERROR_DEBUG(); CHECK_GL_ERROR_DEBUG();
} }

View File

@ -75,9 +75,11 @@ static Layer* restartSpriteTestAction()
BillBoardTest::BillBoardTest() BillBoardTest::BillBoardTest()
: _camera(nullptr) : _camera(nullptr)
{ {
//Create touch listener
auto listener = EventListenerTouchAllAtOnce::create(); auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesMoved = CC_CALLBACK_2(BillBoardTest::onTouchesMoved, this); listener->onTouchesMoved = CC_CALLBACK_2(BillBoardTest::onTouchesMoved, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
auto layer3D=Layer::create(); auto layer3D=Layer::create();
addChild(layer3D,0); addChild(layer3D,0);
_layerBillBorad=layer3D; _layerBillBorad=layer3D;
@ -89,6 +91,7 @@ BillBoardTest::BillBoardTest()
_layerBillBorad->addChild(_camera); _layerBillBorad->addChild(_camera);
} }
//Create rotating billboards
std::string imgs[3] = {"Images/Icon.png", "Images/r2.png"}; std::string imgs[3] = {"Images/Icon.png", "Images/r2.png"};
for (unsigned int i = 0; i < 4; ++i) for (unsigned int i = 0; i < 4; ++i)
{ {
@ -96,12 +99,11 @@ 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);
_layerBillBorad->addChild(layer); _layerBillBorad->addChild(layer);
layer->runAction( RepeatForever::create( RotateBy::create( CCRANDOM_0_1(), Vec3(0.0f, 45.0f, 0.0f) ) ) ); layer->runAction( RepeatForever::create( RotateBy::create( CCRANDOM_0_1() * 10, Vec3(0.0f, 45.0f, 0.0f) ) ) );
} }
{ {
@ -127,11 +129,13 @@ BillBoardTest::BillBoardTest()
addNewBillBoradWithCoords(Vec3(100,5,0)); addNewBillBoradWithCoords(Vec3(100,5,0));
addNewBillBoradWithCoords(Vec3(140,5,0)); addNewBillBoradWithCoords(Vec3(140,5,0));
addNewBillBoradWithCoords(Vec3(180,5,0)); addNewBillBoradWithCoords(Vec3(180,5,0));
addNewAniBillBoradWithCoords(Vec3(-20,0,0)); addNewAniBillBoradWithCoords(Vec3(-20,0,0));
addNewAniBillBoradWithCoords(Vec3(-60,0,0)); addNewAniBillBoradWithCoords(Vec3(-60,0,0));
addNewAniBillBoradWithCoords(Vec3(-100,0,0)); addNewAniBillBoradWithCoords(Vec3(-100,0,0));
addNewAniBillBoradWithCoords(Vec3(-140,0,0)); addNewAniBillBoradWithCoords(Vec3(-140,0,0));
addNewAniBillBoradWithCoords(Vec3(-180,0,0)); addNewAniBillBoradWithCoords(Vec3(-180,0,0));
_camera->setPosition3D(Vec3(0, 100, 230)); _camera->setPosition3D(Vec3(0, 100, 230));
_camera->lookAt(Vec3(0,0,0), Vec3(0,1,0)); _camera->lookAt(Vec3(0,0,0), Vec3(0,1,0));
@ -158,6 +162,8 @@ BillBoardTest::BillBoardTest()
menu->setPosition(Vec2(0,0)); menu->setPosition(Vec2(0,0));
this->addChild(menu, 10); this->addChild(menu, 10);
menuCallback_orientedPoint(nullptr); menuCallback_orientedPoint(nullptr);
schedule(schedule_selector(BillBoardTest::update));
} }
void BillBoardTest::menuCallback_orientedPoint(Ref* sender) void BillBoardTest::menuCallback_orientedPoint(Ref* sender)
@ -183,7 +189,7 @@ BillBoardTest::~BillBoardTest()
} }
std::string BillBoardTest::title() const std::string BillBoardTest::title() const
{ {
return "Testing BillBoard"; return "BillBoard Test";
} }
std::string BillBoardTest::subtitle() const std::string BillBoardTest::subtitle() const
{ {
@ -197,8 +203,8 @@ 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);
_billboards.push_back(billborad); _billboards.push_back(billborad);
} }
@ -207,10 +213,10 @@ void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)
{ {
for (unsigned int i = 0; i < 10; ++i) for (unsigned int i = 0; i < 10; ++i)
{ {
auto billboradAni = BillBoard::create("Images/grossini.png"); auto billboardAni = BillBoard::create("Images/grossini.png");
billboradAni->setScale(0.5f); billboardAni->setScale(0.5f);
billboradAni->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i)); billboardAni->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
_layerBillBorad->addChild(billboradAni); _layerBillBorad->addChild(billboardAni);
auto animation = Animation::create(); auto animation = Animation::create();
for( int i=1;i<15;i++) for( int i=1;i<15;i++)
@ -224,15 +230,13 @@ void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)
animation->setRestoreOriginalFrame(true); animation->setRestoreOriginalFrame(true);
auto action = Animate::create(animation); auto action = Animate::create(animation);
billboradAni->runAction(RepeatForever::create(action)); billboardAni->runAction(RepeatForever::create(action));
billboradAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED); billboardAni->setOpacity(CCRANDOM_0_1() * 128 + 128);
billboradAni->setOpacity(CCRANDOM_0_1() * 128 + 128); _billboards.push_back(billboardAni);
_billboards.push_back(billboradAni);
} }
} }
void BillBoardTest::update(float dt) void BillBoardTest::update(float dt)
{ {
} }
void BillBoardTest::onTouchesMoved(const std::vector<Touch*>& touches, Event* event) void BillBoardTest::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
{ {

View File

@ -24,8 +24,6 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "Camera3DTest.h" #include "Camera3DTest.h"
#include <algorithm>
#include "../testResource.h"
enum enum
{ {
@ -38,18 +36,18 @@ static int sceneIdx = -1;
static std::function<Layer*()> createFunctions[] = static std::function<Layer*()> createFunctions[] =
{ {
CL(CameraRotationTest),
CL(Camera3DTestDemo), CL(Camera3DTestDemo),
CL(CameraClippingDemo), CL(CameraCullingDemo),
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) #if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
// 3DEffect use custom shader which is not supported on WP8/WinRT yet. // 3DEffect use custom shader which is not supported on WP8/WinRT yet.
CL(FogTestDemo), CL(FogTestDemo),
#endif #endif
CL(CameraArcBallDemo) CL(CameraArcBallDemo)
}; };
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
static Layer* nextSpriteTestAction() static Layer*nextTest()
{ {
sceneIdx++; sceneIdx++;
sceneIdx = sceneIdx % MAX_LAYER; sceneIdx = sceneIdx % MAX_LAYER;
@ -57,7 +55,7 @@ static Layer* nextSpriteTestAction()
return layer; return layer;
} }
static Layer* backSpriteTestAction() static Layer*backTest()
{ {
sceneIdx--; sceneIdx--;
int total = MAX_LAYER; int total = MAX_LAYER;
@ -68,21 +66,163 @@ static Layer* backSpriteTestAction()
return layer; return layer;
} }
static Layer* restartSpriteTestAction() static Layer* restartTest()
{ {
auto layer = (createFunctions[sceneIdx])(); auto layer = (createFunctions[sceneIdx])();
return layer; return layer;
} }
void Camera3DTestScene::runThisTest()
{
auto layer = nextTest();
addChild(layer);
Director::getInstance()->replaceScene(this);
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// //
// SpriteTestDemo // CameraBaseTest
// //
//------------------------------------------------------------------ //------------------------------------------------------------------
void CameraBaseTest::restartCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartTest());
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraBaseTest::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(nextTest());
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraBaseTest::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(backTest());
Director::getInstance()->replaceScene(s);
s->release();
}
//------------------------------------------------------------------
//
// Camera Rotation Test
//
//------------------------------------------------------------------
CameraRotationTest::CameraRotationTest()
{
auto s = Director::getInstance()->getWinSize();
_camControlNode = Node::create();
_camControlNode->setNormalizedPosition(Vec2(.5,.5));
addChild(_camControlNode);
_camNode = Node::create();
_camNode->setPositionZ(Camera::getDefaultCamera()->getPosition3D().z);
_camControlNode->addChild(_camNode);
//Billboards
//Yellow is at the back
bill1 = BillBoard::create("Images/Icon.png");
bill1->setPosition3D(Vec3(s.width/2 + 50, s.height/2 + 10, -10));
bill1->setColor(Color3B::YELLOW);
bill1->setScale(0.6);
addChild(bill1);
l1 = Label::create();
l1->setPosition(Vec2(0,-10));
l1->setString("Billboard1");
l1->setColor(Color3B::WHITE);
l1->setScale(3);
bill1->addChild(l1);
bill2 = BillBoard::create("Images/Icon.png");
bill2->setPosition3D(Vec3(s.width/2 - 50, s.height/2 - 10, 10));
bill2->setScale(0.6);
addChild(bill2);
l2 = Label::create();
l2->setString("Billboard2");
l2->setPosition(Vec2(0,-10));
l2->setColor(Color3B::WHITE);
l2->setScale(3);
bill2->addChild(l2);
//3D models
auto model = Sprite3D::create("Sprite3DTest/boss1.obj");
model->setScale(4);
model->setTexture("Sprite3DTest/boss.png");
model->setPosition3D(Vec3(s.width/2, s.height/2, 0));
addChild(model);
//Listener
_lis = EventListenerTouchOneByOne::create();
_lis->onTouchBegan = [this](Touch* t, Event* e) {
return true;
};
_lis->onTouchMoved = [this](Touch* t, Event* e) {
float dx = t->getDelta().x;
Vec3 rot = _camControlNode->getRotation3D();
rot.y += dx;
_camControlNode->setRotation3D(rot);
Vec3 worldPos;
_camNode->getNodeToWorldTransform().getTranslation(&worldPos);
Camera::getDefaultCamera()->setPosition3D(worldPos);
Camera::getDefaultCamera()->lookAt(_camControlNode->getPosition3D());
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(_lis, this);
schedule(schedule_selector(CameraRotationTest::update));
}
CameraRotationTest::~CameraRotationTest()
{
Director::getInstance()->getEventDispatcher()->removeEventListener(_lis);
}
std::string CameraRotationTest::title() const
{
return "Camera Rotation Test";
}
std::string CameraRotationTest::subtitle() const
{
return "Slide to rotate";
}
void CameraRotationTest::onEnter()
{
BaseTest::onEnter();
}
void CameraRotationTest::onExit()
{
BaseTest::onExit();
}
void CameraRotationTest::update(float dt)
{
}
//------------------------------------------------------------------
//
// Camera3DTestDemo
//
//------------------------------------------------------------------
Camera3DTestDemo::Camera3DTestDemo(void) Camera3DTestDemo::Camera3DTestDemo(void)
: BaseTest() : _incRot(nullptr)
, _incRot(nullptr)
, _camera(nullptr) , _camera(nullptr)
, _decRot(nullptr) , _decRot(nullptr)
, _bZoomOut(false) , _bZoomOut(false)
@ -102,13 +242,9 @@ std::string Camera3DTestDemo::title() const
return "Testing Camera"; return "Testing Camera";
} }
std::string Camera3DTestDemo::subtitle() const
{
return "";
}
void Camera3DTestDemo::scaleCameraCallback(Ref* sender,float value) void Camera3DTestDemo::scaleCameraCallback(Ref* sender,float value)
{ {
if(_camera&& _cameraType!=CameraType::FirstCamera) if(_camera&& _cameraType!=CameraType::FirstPerson)
{ {
Vec3 cameraPos= _camera->getPosition3D(); Vec3 cameraPos= _camera->getPosition3D();
cameraPos+= cameraPos.getNormalized()*value; cameraPos+= cameraPos.getNormalized()*value;
@ -117,7 +253,7 @@ void Camera3DTestDemo::scaleCameraCallback(Ref* sender,float value)
} }
void Camera3DTestDemo::rotateCameraCallback(Ref* sender,float value) void Camera3DTestDemo::rotateCameraCallback(Ref* sender,float value)
{ {
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
{ {
Vec3 rotation3D= _camera->getRotation3D(); Vec3 rotation3D= _camera->getRotation3D();
rotation3D.y+= value; rotation3D.y+= value;
@ -131,33 +267,33 @@ void Camera3DTestDemo::SwitchViewCallback(Ref* sender, CameraType cameraType)
return ; return ;
} }
_cameraType = cameraType; _cameraType = cameraType;
if(_cameraType==CameraType::FreeCamera) if(_cameraType==CameraType::Free)
{ {
_camera->setPosition3D(Vec3(0, 130, 130) + _sprite3D->getPosition3D()); _camera->setPosition3D(Vec3(0, 130, 130) + _sprite3D->getPosition3D());
_camera->lookAt(_sprite3D->getPosition3D(), Vec3(0,1,0)); _camera->lookAt(_sprite3D->getPosition3D());
_RotateRightlabel->setColor(Color3B::WHITE); _RotateRightlabel->setColor(Color3B::WHITE);
_RotateLeftlabel->setColor(Color3B::WHITE); _RotateLeftlabel->setColor(Color3B::WHITE);
_ZoomInlabel->setColor(Color3B::WHITE); _ZoomInlabel->setColor(Color3B::WHITE);
_ZoomOutlabel->setColor(Color3B::WHITE); _ZoomOutlabel->setColor(Color3B::WHITE);
} }
else if(_cameraType==CameraType::FirstCamera) else if(_cameraType==CameraType::FirstPerson)
{ {
Vec3 newFaceDir; Vec3 newFaceDir;
_sprite3D->getWorldToNodeTransform().getForwardVector(&newFaceDir); _sprite3D->getWorldToNodeTransform().getForwardVector(&newFaceDir);
newFaceDir.normalize(); newFaceDir.normalize();
_camera->setPosition3D(Vec3(0,35,0) + _sprite3D->getPosition3D()); _camera->setPosition3D(Vec3(0,35,0) + _sprite3D->getPosition3D());
_camera->lookAt(_sprite3D->getPosition3D() + newFaceDir*50, Vec3(0, 1, 0)); _camera->lookAt(_sprite3D->getPosition3D() + newFaceDir*50);
_RotateRightlabel->setColor(Color3B::WHITE); _RotateRightlabel->setColor(Color3B::WHITE);
_RotateLeftlabel->setColor(Color3B::WHITE); _RotateLeftlabel->setColor(Color3B::WHITE);
_ZoomInlabel->setColor(Color3B::GRAY); _ZoomInlabel->setColor(Color3B::GRAY);
_ZoomOutlabel->setColor(Color3B::GRAY); _ZoomOutlabel->setColor(Color3B::GRAY);
} }
else if(_cameraType==CameraType::ThirdCamera) else if(_cameraType==CameraType::ThirdPerson)
{ {
_camera->setPosition3D(Vec3(0, 130, 130) + _sprite3D->getPosition3D()); _camera->setPosition3D(Vec3(0, 130, 130) + _sprite3D->getPosition3D());
_camera->lookAt(_sprite3D->getPosition3D(), Vec3(0,1,0)); _camera->lookAt(_sprite3D->getPosition3D());
_RotateRightlabel->setColor(Color3B::GRAY); _RotateRightlabel->setColor(Color3B::GRAY);
_RotateLeftlabel->setColor(Color3B::GRAY); _RotateLeftlabel->setColor(Color3B::GRAY);
@ -239,11 +375,11 @@ void Camera3DTestDemo::onEnter()
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener4, _RotateRightlabel); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener4, _RotateRightlabel);
auto label1 = Label::createWithTTF(ttfConfig,"free "); auto label1 = Label::createWithTTF(ttfConfig,"free ");
auto menuItem1 = MenuItemLabel::create(label1, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::FreeCamera)); auto menuItem1 = MenuItemLabel::create(label1, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::Free));
auto label2 = Label::createWithTTF(ttfConfig,"third person"); auto label2 = Label::createWithTTF(ttfConfig,"third person");
auto menuItem2 = MenuItemLabel::create(label2, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::ThirdCamera)); auto menuItem2 = MenuItemLabel::create(label2, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::ThirdPerson));
auto label3 = Label::createWithTTF(ttfConfig,"first person"); auto label3 = Label::createWithTTF(ttfConfig,"first person");
auto menuItem3 = MenuItemLabel::create(label3, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::FirstCamera)); auto menuItem3 = MenuItemLabel::create(label3, CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,this,CameraType::FirstPerson));
auto menu = Menu::create(menuItem1, menuItem2, menuItem3, nullptr); auto menu = Menu::create(menuItem1, menuItem2, menuItem3, nullptr);
menu->setPosition(Vec2::ZERO); menu->setPosition(Vec2::ZERO);
@ -259,7 +395,7 @@ void Camera3DTestDemo::onEnter()
_camera->setCameraFlag(CameraFlag::USER1); _camera->setCameraFlag(CameraFlag::USER1);
_layer3D->addChild(_camera); _layer3D->addChild(_camera);
} }
SwitchViewCallback(this,CameraType::ThirdCamera); SwitchViewCallback(this,CameraType::ThirdPerson);
DrawNode3D* line =DrawNode3D::create(); DrawNode3D* line =DrawNode3D::create();
//draw x //draw x
for( int j =-20; j<=20 ;j++) for( int j =-20; j<=20 ;j++)
@ -287,30 +423,6 @@ void Camera3DTestDemo::onExit()
} }
} }
void Camera3DTestDemo::restartCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartSpriteTestAction());
Director::getInstance()->replaceScene(s);
s->release();
}
void Camera3DTestDemo::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( nextSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void Camera3DTestDemo::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( backSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void Camera3DTestDemo::addNewSpriteWithCoords(Vec3 p,std::string fileName,bool playAnimation,float scale,bool bindCamera) void Camera3DTestDemo::addNewSpriteWithCoords(Vec3 p,std::string fileName,bool playAnimation,float scale,bool bindCamera)
{ {
auto sprite = Sprite3D::create(fileName); auto sprite = Sprite3D::create(fileName);
@ -348,7 +460,7 @@ void Camera3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2
auto touch = touches[0]; auto touch = touches[0];
auto location = touch->getLocation(); auto location = touch->getLocation();
Point newPos = touch->getPreviousLocation()-location; Point newPos = touch->getPreviousLocation()-location;
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
{ {
Vec3 cameraDir; Vec3 cameraDir;
Vec3 cameraRightDir; Vec3 cameraRightDir;
@ -362,7 +474,7 @@ void Camera3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2
cameraPos+=cameraDir*newPos.y*0.1f; cameraPos+=cameraDir*newPos.y*0.1f;
cameraPos+=cameraRightDir*newPos.x*0.1f; cameraPos+=cameraRightDir*newPos.x*0.1f;
_camera->setPosition3D(cameraPos); _camera->setPosition3D(cameraPos);
if(_sprite3D && _cameraType==CameraType::FirstCamera) if(_sprite3D && _cameraType==CameraType::FirstPerson)
{ {
_sprite3D->setPosition3D(Vec3(_camera->getPositionX(),0,_camera->getPositionZ())); _sprite3D->setPosition3D(Vec3(_camera->getPositionX(),0,_camera->getPositionZ()));
_targetPos=_sprite3D->getPosition3D(); _targetPos=_sprite3D->getPosition3D();
@ -383,7 +495,7 @@ void Camera3DTestDemo::move3D(float elapsedTime)
_sprite3D->setPosition3D(curPos); _sprite3D->setPosition3D(curPos);
offset.x=offset.x; offset.x=offset.x;
offset.z=offset.z; offset.z=offset.z;
if(_cameraType==CameraType::ThirdCamera) if(_cameraType==CameraType::ThirdPerson)
{ {
Vec3 cameraPos= _camera->getPosition3D(); Vec3 cameraPos= _camera->getPosition3D();
cameraPos.x+=offset.x; cameraPos.x+=offset.x;
@ -430,7 +542,7 @@ void Camera3DTestDemo::onTouchesEnded(const std::vector<Touch*>& touches, cocos2
auto location = touch->getLocationInView(); auto location = touch->getLocationInView();
if(_camera) if(_camera)
{ {
if(_sprite3D && _cameraType==CameraType::ThirdCamera && _bZoomOut == false && _bZoomIn == false && _bRotateLeft == false && _bRotateRight == false) if(_sprite3D && _cameraType==CameraType::ThirdPerson && _bZoomOut == false && _bZoomIn == false && _bRotateLeft == false && _bRotateRight == false)
{ {
Vec3 nearP(location.x, location.y, -1.0f), farP(location.x, location.y, 1.0f); Vec3 nearP(location.x, location.y, -1.0f), farP(location.x, location.y, 1.0f);
@ -467,7 +579,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
{ {
if(_sprite3D) if(_sprite3D)
{ {
if( _cameraType==CameraType::ThirdCamera) if( _cameraType==CameraType::ThirdPerson)
{ {
updateState(fDelta); updateState(fDelta);
if(isState(_curState,State_Move)) if(isState(_curState,State_Move))
@ -515,7 +627,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
{ {
if(_camera) if(_camera)
{ {
if(_cameraType == CameraType::ThirdCamera) if(_cameraType == CameraType::ThirdPerson)
{ {
Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D(); Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D();
Vec3 cameraPos = _camera->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D();
@ -525,7 +637,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
_camera->setPosition3D(cameraPos); _camera->setPosition3D(cameraPos);
} }
} }
else if(_cameraType == CameraType::FreeCamera) else if(_cameraType == CameraType::Free)
{ {
Vec3 cameraPos = _camera->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D();
if(cameraPos.length() <= 300) if(cameraPos.length() <= 300)
@ -540,7 +652,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
{ {
if(_camera) if(_camera)
{ {
if(_cameraType == CameraType::ThirdCamera) if(_cameraType == CameraType::ThirdPerson)
{ {
Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D(); Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D();
Vec3 cameraPos = _camera->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D();
@ -550,7 +662,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
_camera->setPosition3D(cameraPos); _camera->setPosition3D(cameraPos);
} }
} }
else if(_cameraType == CameraType::FreeCamera) else if(_cameraType == CameraType::Free)
{ {
Vec3 cameraPos = _camera->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D();
if(cameraPos.length() >= 50) if(cameraPos.length() >= 50)
@ -563,7 +675,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
} }
if(_bRotateLeft == true) if(_bRotateLeft == true)
{ {
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
{ {
Vec3 rotation3D= _camera->getRotation3D(); Vec3 rotation3D= _camera->getRotation3D();
rotation3D.y+= 1; rotation3D.y+= 1;
@ -572,7 +684,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
} }
if(_bRotateRight == true) if(_bRotateRight == true)
{ {
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
{ {
Vec3 rotation3D= _camera->getRotation3D(); Vec3 rotation3D= _camera->getRotation3D();
rotation3D.y-= 1; rotation3D.y-= 1;
@ -663,11 +775,10 @@ void Camera3DTestDemo::onTouchesRotateRightEnd(Touch* touch, Event* event)
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// CameraClippingDemo // CameraCullingDemo
CameraClippingDemo::CameraClippingDemo(void) CameraCullingDemo::CameraCullingDemo(void)
: BaseTest() : _layer3D(nullptr)
, _layer3D(nullptr) , _cameraType(CameraType::FirstPerson)
, _cameraType(CameraType::FirstCamera)
, _cameraFirst(nullptr) , _cameraFirst(nullptr)
, _cameraThird(nullptr) , _cameraThird(nullptr)
, _moveAction(nullptr) , _moveAction(nullptr)
@ -676,49 +787,26 @@ CameraClippingDemo::CameraClippingDemo(void)
, _row(3) , _row(3)
{ {
} }
CameraClippingDemo::~CameraClippingDemo(void) CameraCullingDemo::~CameraCullingDemo(void)
{ {
} }
std::string CameraClippingDemo::title() const std::string CameraCullingDemo::title() const
{ {
return "Camera Frustum Clipping"; return "Camera Frustum Clipping";
} }
void CameraClippingDemo::restartCallback(Ref* sender) void CameraCullingDemo::onEnter()
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartSpriteTestAction());
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( nextSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( backSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::onEnter()
{ {
BaseTest::onEnter(); BaseTest::onEnter();
schedule(schedule_selector(CameraClippingDemo::update), 0.0f);
schedule(schedule_selector(CameraCullingDemo::update), 0.0f);
auto s = Director::getInstance()->getWinSize(); auto s = Director::getInstance()->getWinSize();
auto listener = EventListenerTouchAllAtOnce::create(); auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(CameraClippingDemo::onTouchesBegan, this); listener->onTouchesBegan = CC_CALLBACK_2(CameraCullingDemo::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(CameraClippingDemo::onTouchesMoved, this); listener->onTouchesMoved = CC_CALLBACK_2(CameraCullingDemo::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(CameraClippingDemo::onTouchesEnded, this); listener->onTouchesEnded = CC_CALLBACK_2(CameraCullingDemo::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
auto layer3D=Layer::create(); auto layer3D=Layer::create();
addChild(layer3D,0); addChild(layer3D,0);
@ -728,7 +816,7 @@ void CameraClippingDemo::onEnter()
MenuItemFont::setFontName("fonts/arial.ttf"); MenuItemFont::setFontName("fonts/arial.ttf");
MenuItemFont::setFontSize(20); MenuItemFont::setFontSize(20);
auto menuItem1 = MenuItemFont::create("Switch Camera", CC_CALLBACK_1(CameraClippingDemo::switchViewCallback,this)); auto menuItem1 = MenuItemFont::create("Switch Camera", CC_CALLBACK_1(CameraCullingDemo::switchViewCallback,this));
menuItem1->setColor(Color3B(0,200,20)); menuItem1->setColor(Color3B(0,200,20));
auto menu = Menu::create(menuItem1,NULL); auto menu = Menu::create(menuItem1,NULL);
menu->setPosition(Vec2::ZERO); menu->setPosition(Vec2::ZERO);
@ -737,9 +825,9 @@ void CameraClippingDemo::onEnter()
// + - // + -
MenuItemFont::setFontSize(40); MenuItemFont::setFontSize(40);
auto decrease = MenuItemFont::create(" - ", CC_CALLBACK_1(CameraClippingDemo::delSpriteCallback, this)); auto decrease = MenuItemFont::create(" - ", CC_CALLBACK_1(CameraCullingDemo::delSpriteCallback, this));
decrease->setColor(Color3B(0,200,20)); decrease->setColor(Color3B(0,200,20));
auto increase = MenuItemFont::create(" + ", CC_CALLBACK_1(CameraClippingDemo::addSpriteCallback, this)); auto increase = MenuItemFont::create(" + ", CC_CALLBACK_1(CameraCullingDemo::addSpriteCallback, this));
increase->setColor(Color3B(0,200,20)); increase->setColor(Color3B(0,200,20));
menu = Menu::create(decrease, increase, nullptr); menu = Menu::create(decrease, increase, nullptr);
@ -770,7 +858,7 @@ void CameraClippingDemo::onEnter()
addSpriteCallback(nullptr); addSpriteCallback(nullptr);
} }
void CameraClippingDemo::onExit() void CameraCullingDemo::onExit()
{ {
BaseTest::onExit(); BaseTest::onExit();
if (_cameraFirst) if (_cameraFirst)
@ -783,11 +871,11 @@ void CameraClippingDemo::onExit()
} }
} }
void CameraClippingDemo::update(float dt) void CameraCullingDemo::update(float dt)
{ {
_drawAABB->clear(); _drawAABB->clear();
if(_cameraType == CameraType::ThirdCamera) if(_cameraType == CameraType::ThirdPerson)
drawCameraFrustum(); drawCameraFrustum();
Vector<Node*>& children = _layer3D->getChildren(); Vector<Node*>& children = _layer3D->getChildren();
@ -804,7 +892,7 @@ void CameraClippingDemo::update(float dt)
} }
} }
void CameraClippingDemo::reachEndCallBack() void CameraCullingDemo::reachEndCallBack()
{ {
_cameraFirst->stopActionByTag(100); _cameraFirst->stopActionByTag(100);
auto inverse = (MoveTo*)_moveAction->reverse(); auto inverse = (MoveTo*)_moveAction->reverse();
@ -812,12 +900,12 @@ void CameraClippingDemo::reachEndCallBack()
_moveAction->release(); _moveAction->release();
_moveAction = inverse; _moveAction = inverse;
auto rot = RotateBy::create(1.f, Vec3(0.f, 180.f, 0.f)); auto rot = RotateBy::create(1.f, Vec3(0.f, 180.f, 0.f));
auto seq = Sequence::create(rot, _moveAction, CallFunc::create(CC_CALLBACK_0(CameraClippingDemo::reachEndCallBack, this)), nullptr); auto seq = Sequence::create(rot, _moveAction, CallFunc::create(CC_CALLBACK_0(CameraCullingDemo::reachEndCallBack, this)), nullptr);
seq->setTag(100); seq->setTag(100);
_cameraFirst->runAction(seq); _cameraFirst->runAction(seq);
} }
void CameraClippingDemo::switchViewCallback(Ref* sender) void CameraCullingDemo::switchViewCallback(Ref* sender)
{ {
auto s = Director::getInstance()->getWinSize(); auto s = Director::getInstance()->getWinSize();
@ -826,10 +914,10 @@ void CameraClippingDemo::switchViewCallback(Ref* sender)
_cameraFirst = Camera::createPerspective(30, (GLfloat)s.width/s.height, 10, 200); _cameraFirst = Camera::createPerspective(30, (GLfloat)s.width/s.height, 10, 200);
_cameraFirst->setCameraFlag(CameraFlag::USER8); _cameraFirst->setCameraFlag(CameraFlag::USER8);
_cameraFirst->setPosition3D(Vec3(-100,0,0)); _cameraFirst->setPosition3D(Vec3(-100,0,0));
_cameraFirst->lookAt(Vec3(1000,0,0), Vec3(0, 1, 0)); _cameraFirst->lookAt(Vec3(1000,0,0));
_moveAction = MoveTo::create(4.f, Vec2(100, 0)); _moveAction = MoveTo::create(4.f, Vec2(100, 0));
_moveAction->retain(); _moveAction->retain();
auto seq = Sequence::create(_moveAction, CallFunc::create(CC_CALLBACK_0(CameraClippingDemo::reachEndCallBack, this)), nullptr); auto seq = Sequence::create(_moveAction, CallFunc::create(CC_CALLBACK_0(CameraCullingDemo::reachEndCallBack, this)), nullptr);
seq->setTag(100); seq->setTag(100);
_cameraFirst->runAction(seq); _cameraFirst->runAction(seq);
addChild(_cameraFirst); addChild(_cameraFirst);
@ -840,20 +928,20 @@ void CameraClippingDemo::switchViewCallback(Ref* sender)
_cameraThird = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000); _cameraThird = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000);
_cameraThird->setCameraFlag(CameraFlag::USER8); _cameraThird->setCameraFlag(CameraFlag::USER8);
_cameraThird->setPosition3D(Vec3(0, 130, 130)); _cameraThird->setPosition3D(Vec3(0, 130, 130));
_cameraThird->lookAt(Vec3(0,0,0), Vec3(0, 1, 0)); _cameraThird->lookAt(Vec3(0,0,0));
addChild(_cameraThird); addChild(_cameraThird);
} }
if(_cameraType == CameraType::FirstCamera) if(_cameraType == CameraType::FirstPerson)
{ {
_cameraType = CameraType::ThirdCamera; _cameraType = CameraType::ThirdPerson;
_cameraThird->setCameraFlag(CameraFlag::USER1); _cameraThird->setCameraFlag(CameraFlag::USER1);
_cameraThird->enableFrustumCulling(false, false); _cameraThird->enableFrustumCulling(false, false);
_cameraFirst->setCameraFlag(CameraFlag::USER8); _cameraFirst->setCameraFlag(CameraFlag::USER8);
} }
else if(_cameraType == CameraType::ThirdCamera) else if(_cameraType == CameraType::ThirdPerson)
{ {
_cameraType = CameraType::FirstCamera; _cameraType = CameraType::FirstPerson;
_cameraFirst->setCameraFlag(CameraFlag::USER1); _cameraFirst->setCameraFlag(CameraFlag::USER1);
_cameraFirst->enableFrustumCulling(true, true); _cameraFirst->enableFrustumCulling(true, true);
_cameraThird->setCameraFlag(CameraFlag::USER8); _cameraThird->setCameraFlag(CameraFlag::USER8);
@ -861,7 +949,7 @@ void CameraClippingDemo::switchViewCallback(Ref* sender)
} }
} }
void CameraClippingDemo::addSpriteCallback(Ref* sender) void CameraCullingDemo::addSpriteCallback(Ref* sender)
{ {
_layer3D->removeAllChildren(); _layer3D->removeAllChildren();
_objects.clear(); _objects.clear();
@ -889,7 +977,7 @@ void CameraClippingDemo::addSpriteCallback(Ref* sender)
_labelSprite3DCount->setString(szText); _labelSprite3DCount->setString(szText);
} }
void CameraClippingDemo::delSpriteCallback(Ref* sender) void CameraCullingDemo::delSpriteCallback(Ref* sender)
{ {
if (_row == 0) return; if (_row == 0) return;
@ -917,7 +1005,7 @@ void CameraClippingDemo::delSpriteCallback(Ref* sender)
_labelSprite3DCount->setString(szText); _labelSprite3DCount->setString(szText);
} }
void CameraClippingDemo::drawCameraFrustum() void CameraCullingDemo::drawCameraFrustum()
{ {
_drawFrustum->clear(); _drawFrustum->clear();
auto size = Director::getInstance()->getWinSize(); auto size = Director::getInstance()->getWinSize();
@ -971,9 +1059,9 @@ void CameraClippingDemo::drawCameraFrustum()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// CameraArcBallDemo // CameraArcBallDemo
CameraArcBallDemo::CameraArcBallDemo(void) CameraArcBallDemo::CameraArcBallDemo(void)
: BaseTest() : CameraBaseTest()
, _layer3D(nullptr) , _layer3D(nullptr)
, _cameraType(CameraType::FreeCamera) , _cameraType(CameraType::Free)
, _camera(nullptr) , _camera(nullptr)
,_drawGrid(nullptr) ,_drawGrid(nullptr)
,_sprite3D1(nullptr) ,_sprite3D1(nullptr)
@ -994,31 +1082,6 @@ std::string CameraArcBallDemo::title() const
return "Camera ArcBall Moving"; return "Camera ArcBall Moving";
} }
void CameraArcBallDemo::restartCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartSpriteTestAction());
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraArcBallDemo::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( nextSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraArcBallDemo::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( backSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraArcBallDemo::onEnter() void CameraArcBallDemo::onEnter()
{ {
BaseTest::onEnter(); BaseTest::onEnter();
@ -1219,9 +1282,9 @@ void CameraArcBallDemo::update(float dt)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// FogTestDemo // FogTestDemo
FogTestDemo::FogTestDemo(void) FogTestDemo::FogTestDemo(void)
: BaseTest() : CameraBaseTest()
, _layer3D(nullptr) , _layer3D(nullptr)
, _cameraType(CameraType::FreeCamera) , _cameraType(CameraType::Free)
, _camera(nullptr) , _camera(nullptr)
, _shader(nullptr) , _shader(nullptr)
, _state(nullptr) , _state(nullptr)
@ -1236,31 +1299,6 @@ std::string FogTestDemo::title() const
return "Fog Test Demo"; return "Fog Test Demo";
} }
void FogTestDemo::restartCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartSpriteTestAction());
Director::getInstance()->replaceScene(s);
s->release();
}
void FogTestDemo::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( nextSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void FogTestDemo::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( backSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void FogTestDemo::onEnter() void FogTestDemo::onEnter()
{ {
BaseTest::onEnter(); BaseTest::onEnter();
@ -1436,7 +1474,7 @@ void FogTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Ev
Vec2 prelocation = touches[0]->getPreviousLocationInView(); Vec2 prelocation = touches[0]->getPreviousLocationInView();
Vec2 location = touches[0]->getLocationInView(); Vec2 location = touches[0]->getLocationInView();
Vec2 newPos = prelocation - location; Vec2 newPos = prelocation - location;
if(_cameraType==CameraType::FreeCamera) if(_cameraType==CameraType::Free)
{ {
Vec3 cameraDir; Vec3 cameraDir;
Vec3 cameraRightDir; Vec3 cameraRightDir;
@ -1453,10 +1491,3 @@ void FogTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Ev
} }
} }
} }
void Camera3DTestScene::runThisTest()
{
auto layer = nextSpriteTestAction();
addChild(layer);
Director::getInstance()->replaceScene(this);
}

View File

@ -48,9 +48,9 @@ enum State
}; };
enum class CameraType enum class CameraType
{ {
FreeCamera=0, Free = 0,
FirstCamera=1, FirstPerson = 1,
ThirdCamera=2, ThirdPerson = 2,
}; };
enum class OperateCamType enum class OperateCamType
@ -59,21 +59,60 @@ enum class OperateCamType
RotateCamera=1, RotateCamera=1,
}; };
class Camera3DTestDemo : public BaseTest class Camera3DTestScene : public TestScene
{
public:
virtual void runThisTest();
};
class CameraBaseTest : public BaseTest
{
public:
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
protected:
BillBoard* bill1;
BillBoard* bill2;
Label* l1;
Label* l2;
};
class CameraRotationTest : public CameraBaseTest {
public:
CREATE_FUNC(CameraRotationTest);
CameraRotationTest(void);
virtual ~CameraRotationTest(void);
virtual void onEnter() override;
virtual void onExit() override;
virtual void update(float dt) override;
// overrides
virtual std::string title() const override;
virtual std::string subtitle() const override;
protected:
Node* _camControlNode;
Node* _camNode;
EventListenerTouchOneByOne* _lis;
};
class Camera3DTestDemo : public CameraBaseTest
{ {
public: public:
CREATE_FUNC(Camera3DTestDemo); CREATE_FUNC(Camera3DTestDemo);
Camera3DTestDemo(void); Camera3DTestDemo(void);
virtual ~Camera3DTestDemo(void); virtual ~Camera3DTestDemo(void);
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
// overrides // overrides
virtual std::string title() const override; virtual std::string title() const override;
virtual std::string subtitle() const override;
void addNewSpriteWithCoords(Vec3 p,std::string fileName,bool playAnimation=false,float scale=1.0f,bool bindCamera=false); void addNewSpriteWithCoords(Vec3 p,std::string fileName,bool playAnimation=false,float scale=1.0f,bool bindCamera=false);
void onTouchesBegan(const std::vector<Touch*>& touches, cocos2d::Event *event); void onTouchesBegan(const std::vector<Touch*>& touches, cocos2d::Event *event);
void onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Event *event); void onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Event *event);
@ -117,16 +156,12 @@ protected:
Label* _ZoomOutlabel; Label* _ZoomOutlabel;
}; };
class CameraClippingDemo : public BaseTest class CameraCullingDemo : public CameraBaseTest
{ {
public: public:
CREATE_FUNC(CameraClippingDemo); CREATE_FUNC(CameraCullingDemo);
CameraClippingDemo(void); CameraCullingDemo(void);
virtual ~CameraClippingDemo(void); virtual ~CameraCullingDemo(void);
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
@ -155,17 +190,13 @@ protected:
int _row; int _row;
}; };
class CameraArcBallDemo : public BaseTest class CameraArcBallDemo : public CameraBaseTest
{ {
public: public:
CREATE_FUNC(CameraArcBallDemo); CREATE_FUNC(CameraArcBallDemo);
CameraArcBallDemo(void); CameraArcBallDemo(void);
virtual ~CameraArcBallDemo(void); virtual ~CameraArcBallDemo(void);
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
@ -196,17 +227,13 @@ protected:
Sprite3D* _sprite3D2; Sprite3D* _sprite3D2;
}; };
class FogTestDemo : public BaseTest class FogTestDemo : public CameraBaseTest
{ {
public: public:
CREATE_FUNC(FogTestDemo); CREATE_FUNC(FogTestDemo);
FogTestDemo(void); FogTestDemo(void);
virtual ~FogTestDemo(void); virtual ~FogTestDemo(void);
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
virtual void onEnter() override; virtual void onEnter() override;
virtual void onExit() override; virtual void onExit() override;
@ -233,9 +260,5 @@ protected:
#endif #endif
}; };
class Camera3DTestScene : public TestScene
{
public:
virtual void runThisTest();
};
#endif #endif

View File

@ -68,7 +68,8 @@ static std::function<Layer*()> createFunctions[] =
CL(Sprite3DReskinTest), CL(Sprite3DReskinTest),
CL(Sprite3DWithOBBPerfromanceTest), CL(Sprite3DWithOBBPerfromanceTest),
CL(Sprite3DMirrorTest), CL(Sprite3DMirrorTest),
CL(QuaternionTest) CL(QuaternionTest),
CL(Sprite3DEmptyTest)
}; };
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -154,6 +155,30 @@ void Sprite3DTestDemo::backCallback(Ref* sender)
s->release(); s->release();
} }
//------------------------------------------------------------------
//
// Sprite3DEmptyTest
//
//------------------------------------------------------------------
Sprite3DEmptyTest::Sprite3DEmptyTest()
{
auto s = Sprite3D::create();
s->setNormalizedPosition(Vec2(.5,.5));
auto l = Label::create();
l->setString("Test");
s->addChild(l);
addChild(s);
}
std::string Sprite3DEmptyTest::title() const
{
return "Testing Sprite3D Container";
}
std::string Sprite3DEmptyTest::subtitle() const
{
return "Sprite3D can act as containers for 2D objects";
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// //

View File

@ -54,6 +54,15 @@ public:
virtual void onEnter() override; virtual void onEnter() override;
}; };
class Sprite3DEmptyTest : public Sprite3DTestDemo
{
public:
CREATE_FUNC(Sprite3DEmptyTest);
Sprite3DEmptyTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class Sprite3DBasicTest : public Sprite3DTestDemo class Sprite3DBasicTest : public Sprite3DTestDemo
{ {
public: public: