mirror of https://github.com/axmolengine/axmol.git
commit
0207c22cb6
|
@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "CCAtlasNode.h"
|
||||
#include "renderer/CCTextureAtlas.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
@ -132,15 +133,32 @@ void AtlasNode::updateAtlasValues()
|
|||
// AtlasNode - draw
|
||||
void AtlasNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
||||
{
|
||||
_quadCommand.init(
|
||||
_globalZOrder,
|
||||
_textureAtlas->getTexture()->getName(),
|
||||
getGLProgramState(),
|
||||
_blendFunc,
|
||||
_textureAtlas->getQuads(),
|
||||
_quadsToDraw,
|
||||
transform);
|
||||
|
||||
//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(
|
||||
_globalZOrder,
|
||||
_textureAtlas->getTexture()->getName(),
|
||||
getGLProgramState(),
|
||||
_blendFunc,
|
||||
_textureAtlas->getQuads(),
|
||||
_quadsToDraw,
|
||||
transform);
|
||||
}
|
||||
|
||||
renderer->addCommand(&_quadCommand);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,19 @@ NS_CC_BEGIN
|
|||
|
||||
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->initDefault();
|
||||
|
@ -253,9 +265,9 @@ void Camera::unproject(const Size& viewport, Vec3* src, Vec3* dst) const
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -273,6 +285,14 @@ bool Camera::isVisibleInFrustum(const AABB* aabb) const
|
|||
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()
|
||||
{
|
||||
if (_scene == nullptr)
|
||||
|
|
|
@ -35,8 +35,9 @@ class Scene;
|
|||
* Note:
|
||||
* 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.
|
||||
* 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.
|
||||
* You can change the camera added order to get different result when depth test is not enabled.
|
||||
* It's usually a good idea to render 3D objects in a separate camera.
|
||||
* 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.
|
||||
*/
|
||||
enum class CameraFlag
|
||||
|
@ -76,7 +77,7 @@ public:
|
|||
* @param nearPlane The near plane distance.
|
||||
* @param farPlane The far plane distance.
|
||||
*/
|
||||
static Camera* createPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane);
|
||||
static Camera* createPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane);
|
||||
/**
|
||||
* Creates an orthographic camera.
|
||||
*
|
||||
|
@ -86,7 +87,7 @@ public:
|
|||
* @param nearPlane The near plane distance.
|
||||
* @param farPlane The far plane distance.
|
||||
*/
|
||||
static Camera* createOrthographic(float zoomX, float zoomY, float nearPlane, float farPlane);
|
||||
static Camera* createOrthographic(float zoomX, float zoomY, float nearPlane, float farPlane);
|
||||
|
||||
/** create default camera, the camera type depends on Director::getProjection */
|
||||
static Camera* create();
|
||||
|
@ -96,7 +97,7 @@ public:
|
|||
*
|
||||
* @return The camera type.
|
||||
*/
|
||||
Camera::Type getType() const { return _type; }
|
||||
Camera::Type getType() const { return _type; }
|
||||
|
||||
/**get & set Camera flag*/
|
||||
CameraFlag getCameraFlag() const { return (CameraFlag)_cameraFlag; }
|
||||
|
@ -105,15 +106,14 @@ public:
|
|||
* Sets the position (X, Y, and Z) in its parent's coordinate system
|
||||
*/
|
||||
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 targetPosition The target's center position.
|
||||
* @param up The up vector.
|
||||
* @param dst A matrix to store the result in.
|
||||
* @param target The target camera is point at
|
||||
* @param up The up vector, usually it's Y axis
|
||||
*/
|
||||
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.
|
||||
|
@ -139,18 +139,24 @@ public:
|
|||
/**
|
||||
* Enable frustum culling
|
||||
*/
|
||||
void enableFrustumCulling(bool enalbe, bool clipZ);
|
||||
void enableFrustumCulling(bool value, bool clipZ);
|
||||
|
||||
/**
|
||||
* 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
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
static const Camera* getVisitingCamera() { return _visitingCamera; }
|
||||
static Camera* getDefaultCamera();
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
Camera();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCLabel.h"
|
||||
#include "2d/CCFontAtlasCache.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;
|
||||
|
||||
if(_insideBounds) {
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
|
||||
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.func = CC_CALLBACK_0(Label::onDraw, this, transform, transformUpdated);
|
||||
}
|
||||
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
enum {
|
||||
FLAGS_TRANSFORM_DIRTY = (1 << 0),
|
||||
FLAGS_CONTENT_SIZE_DIRTY = (1 << 1),
|
||||
FLAGS_RENDER_AS_3D = (1 << 3),
|
||||
|
||||
FLAGS_DIRTY_MASK = (FLAGS_TRANSFORM_DIRTY | FLAGS_CONTENT_SIZE_DIRTY),
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include "2d/CCParticleBatchNode.h"
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCGrid.h"
|
||||
#include "2d/CCParticleSystem.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
|
@ -403,12 +403,25 @@ void ParticleBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t
|
|||
return;
|
||||
}
|
||||
|
||||
_batchCommand.init(
|
||||
if (flags & FLAGS_RENDER_AS_3D)
|
||||
{
|
||||
float depth = Camera::getVisitingCamera()->getDepthInView(transform);
|
||||
_batchCommand.init(
|
||||
depth,
|
||||
getGLProgram(),
|
||||
_blendFunc,
|
||||
_textureAtlas,
|
||||
_modelViewTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_batchCommand.init(
|
||||
_globalZOrder,
|
||||
getGLProgram(),
|
||||
_blendFunc,
|
||||
_textureAtlas,
|
||||
_modelViewTransform);
|
||||
}
|
||||
renderer->addCommand(&_batchCommand);
|
||||
CC_PROFILER_STOP("CCParticleBatchNode - draw");
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ THE SOFTWARE.
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCSpriteFrame.h"
|
||||
#include "2d/CCParticleBatchNode.h"
|
||||
#include "renderer/CCTextureAtlas.h"
|
||||
|
@ -372,8 +373,17 @@ void ParticleSystemQuad::draw(Renderer *renderer, const Mat4 &transform, uint32_
|
|||
//quad command
|
||||
if(_particleIdx > 0)
|
||||
{
|
||||
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _quads, _particleIdx, transform);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
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);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ public:
|
|||
/** get all cameras */
|
||||
const std::vector<Camera*>& getCameras() const { return _cameras; }
|
||||
|
||||
Camera* getDefaultCamera() const { return _defaultCamera; }
|
||||
|
||||
const std::vector<BaseLight*>& getLights() const { return _lights; }
|
||||
|
||||
/** render the scene */
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCSpriteBatchNode.h"
|
||||
#include "2d/CCAnimationCache.h"
|
||||
#include "2d/CCSpriteFrame.h"
|
||||
|
@ -592,8 +593,19 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
|
||||
if(_insideBounds)
|
||||
{
|
||||
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
|
||||
//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);
|
||||
}
|
||||
renderer->addCommand(&_quadCommand);
|
||||
|
||||
#if CC_SPRITE_DEBUG_DRAW
|
||||
_debugDrawNode->clear();
|
||||
Vec2 vertices[4] = {
|
||||
|
|
|
@ -26,6 +26,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCSpriteBatchNode.h"
|
||||
#include "2d/CCSprite.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
@ -378,12 +379,26 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
|
|||
child->updateTransform();
|
||||
}
|
||||
|
||||
_batchCommand.init(
|
||||
//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(
|
||||
_globalZOrder,
|
||||
getGLProgram(),
|
||||
_blendFunc,
|
||||
_textureAtlas,
|
||||
transform);
|
||||
}
|
||||
renderer->addCommand(&_batchCommand);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
NS_CC_BEGIN
|
||||
|
||||
BillBoard::BillBoard()
|
||||
: _zDepthInView(0.0f)
|
||||
, _mode(Mode::VIEW_POINT_ORIENTED)
|
||||
: _mode(Mode::VIEW_POINT_ORIENTED)
|
||||
, _modeDirty(false)
|
||||
{
|
||||
Node::setAnchorPoint(Vec2(0.5f,0.5f));
|
||||
|
@ -96,42 +95,108 @@ BillBoard* BillBoard::create(Mode mode)
|
|||
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();
|
||||
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);
|
||||
Mat4 localToWorld = transform;
|
||||
Mat4 localToWorld = _modelViewTransform;
|
||||
localToWorld.translate(anchorPoint);
|
||||
|
||||
//Decide billboard mode
|
||||
Vec3 camDir;
|
||||
switch (_mode)
|
||||
{
|
||||
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]);
|
||||
break;
|
||||
case Mode::VIEW_PLANE_ORIENTED:
|
||||
camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
|
||||
break;
|
||||
default:
|
||||
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]);
|
||||
break;
|
||||
case Mode::VIEW_PLANE_ORIENTED:
|
||||
camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
|
||||
break;
|
||||
default:
|
||||
CCASSERT(false, "invalid billboard mode");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
_modeDirty = false;
|
||||
|
||||
if (camDir.length() < MATH_TOLERANCE)
|
||||
{
|
||||
camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
|
||||
}
|
||||
camDir.normalize();
|
||||
|
||||
Quaternion rotationQuaternion;
|
||||
this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
|
||||
|
||||
// fetch the rotation angle of z
|
||||
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;
|
||||
rotationMatrix.setIdentity();
|
||||
rotationMatrix.rotateZ(rotationZ);
|
||||
|
||||
Vec3 upAxis = Vec3(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
|
||||
Vec3 x, y;
|
||||
camWorldMat.transformVector(upAxis, &y);
|
||||
|
@ -139,30 +204,40 @@ void BillBoard::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
x.normalize();
|
||||
Vec3::cross(x, camDir, &y);
|
||||
y.normalize();
|
||||
|
||||
|
||||
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 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[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);
|
||||
|
||||
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;
|
||||
|
||||
Mat4 billboardTransform;
|
||||
|
||||
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;
|
||||
|
||||
_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
|
||||
{
|
||||
_quadCommand.init(_zDepthInView, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _billboardTransform);
|
||||
_quadCommand.setTransparent(true);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
}
|
||||
_quadCommand.init(depth, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, _modelViewTransform);
|
||||
_quadCommand.setTransparent(true);
|
||||
_quadCommand.setSkipBatching(true);
|
||||
_quadCommand.set3D(true);
|
||||
renderer->addCommand(&_quadCommand);
|
||||
}
|
||||
|
||||
void BillBoard::setMode( Mode mode )
|
||||
|
|
|
@ -88,6 +88,10 @@ public:
|
|||
Mode getMode() const;
|
||||
|
||||
//override
|
||||
|
||||
/** update billboard's transform and turn it towards camera */
|
||||
virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags);
|
||||
|
||||
/** draw BillBoard object */
|
||||
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
|
||||
|
||||
|
@ -98,11 +102,9 @@ CC_CONSTRUCTOR_ACCESS:
|
|||
|
||||
protected:
|
||||
|
||||
Mat4 _camWorldMat;
|
||||
Mat4 _mvTransform;
|
||||
Mat4 _billboardTransform;
|
||||
bool calculateBillbaordTransform();
|
||||
|
||||
float _zDepthInView;
|
||||
Mat4 _camWorldMat;
|
||||
|
||||
Mode _mode;
|
||||
bool _modeDirty;
|
||||
|
|
|
@ -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};
|
||||
|
||||
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)
|
||||
{
|
||||
if (modelPath.length() < 4)
|
||||
CCASSERT(false, "improper name specified when creating Sprite3D");
|
||||
CCASSERT(false, "invalid filename for Sprite3D");
|
||||
|
||||
auto sprite = new (std::nothrow) Sprite3D();
|
||||
if (sprite && sprite->initWithFile(modelPath))
|
||||
|
@ -241,6 +254,15 @@ Sprite3D::~Sprite3D()
|
|||
removeAllAttachNode();
|
||||
}
|
||||
|
||||
bool Sprite3D::init()
|
||||
{
|
||||
if(Node::init())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sprite3D::initWithFile(const std::string &path)
|
||||
{
|
||||
_meshes.clear();
|
||||
|
@ -599,6 +621,54 @@ static Texture2D * getDummyTexture()
|
|||
}
|
||||
#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)
|
||||
{
|
||||
// camera clipping
|
||||
|
@ -651,9 +721,11 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
float globalZ = _globalZOrder;
|
||||
bool isTransparent = (mesh->_isTransparent || color.a < 1.f);
|
||||
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();
|
||||
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);
|
||||
|
||||
|
|
|
@ -50,6 +50,13 @@ struct NodeData;
|
|||
class CC_DLL Sprite3D : public Node, public BlendProtocol
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates an empty sprite3D without 3D model and texture.
|
||||
*
|
||||
* @return An autoreleased sprite3D object.
|
||||
*/
|
||||
static Sprite3D* create();
|
||||
|
||||
/** creates a Sprite3D*/
|
||||
static Sprite3D* create(const std::string &modelPath);
|
||||
|
||||
|
@ -138,6 +145,9 @@ CC_CONSTRUCTOR_ACCESS:
|
|||
|
||||
Sprite3D();
|
||||
virtual ~Sprite3D();
|
||||
|
||||
bool init();
|
||||
|
||||
bool initWithFile(const std::string &path);
|
||||
|
||||
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 */
|
||||
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*/
|
||||
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
|
||||
|
||||
|
|
|
@ -169,12 +169,6 @@ bool Director::init(void)
|
|||
_renderer = new (std::nothrow) Renderer;
|
||||
|
||||
_console = new (std::nothrow) Console;
|
||||
|
||||
// default clear color
|
||||
_clearColor.r = 0;
|
||||
_clearColor.g = 0;
|
||||
_clearColor.b = 0;
|
||||
_clearColor.a = 1.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -258,9 +252,6 @@ void Director::setGLDefaultValues()
|
|||
// [self setDepthTest: view_.depthFormat];
|
||||
setDepthTest(false);
|
||||
setProjection(_projection);
|
||||
|
||||
// set other opengl default values
|
||||
glClearColor(_clearColor.r, _clearColor.g, _clearColor.b, _clearColor.a);
|
||||
}
|
||||
|
||||
// Draw the Scene
|
||||
|
@ -281,7 +272,7 @@ void Director::drawScene()
|
|||
_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.
|
||||
* 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)
|
||||
{
|
||||
_clearColor = clearColor;
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
_renderer->setClearColor(clearColor);
|
||||
}
|
||||
|
||||
static void GLToClipTransform(Mat4 *transformOut)
|
||||
|
|
|
@ -475,9 +475,6 @@ protected:
|
|||
unsigned int _totalFrames;
|
||||
float _secondsPerFrame;
|
||||
|
||||
/* clear color set outside be used in setGLDefaultValues() */
|
||||
Color4F _clearColor;
|
||||
|
||||
/* The running scene */
|
||||
Scene *_runningScene;
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ void MeshCommand::init(float globalOrder,
|
|||
_indexFormat = indexFormat;
|
||||
_indexCount = indexCount;
|
||||
_mv.set(mv);
|
||||
|
||||
_is3D = true;
|
||||
}
|
||||
|
||||
void MeshCommand::setCullFaceEnabled(bool enable)
|
||||
|
@ -151,6 +151,14 @@ void MeshCommand::setDisplayColor(const Vec4& color)
|
|||
_displayColor = color;
|
||||
}
|
||||
|
||||
void MeshCommand::setTransparent(bool value)
|
||||
{
|
||||
_isTransparent = value;
|
||||
//Skip batching for transparent mesh
|
||||
_skipBatching = value;
|
||||
setDepthWriteEnabled(!_isTransparent);
|
||||
}
|
||||
|
||||
MeshCommand::~MeshCommand()
|
||||
{
|
||||
releaseVAO();
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
|
||||
void setLightMask(unsigned int lightmask) { _lightMask = lightmask; }
|
||||
|
||||
void setTransparent(bool value);
|
||||
|
||||
void execute();
|
||||
|
||||
//used for bath
|
||||
|
|
|
@ -30,7 +30,9 @@ NS_CC_BEGIN
|
|||
RenderCommand::RenderCommand()
|
||||
: _type(RenderCommand::Type::UNKNOWN_COMMAND)
|
||||
, _globalOrder(0)
|
||||
, _isTransparent(false)
|
||||
, _isTransparent(true)
|
||||
, _skipBatching(false)
|
||||
, _is3D(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,14 @@ public:
|
|||
/** set transparent flag */
|
||||
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:
|
||||
RenderCommand();
|
||||
virtual ~RenderCommand();
|
||||
|
@ -79,6 +87,12 @@ protected:
|
|||
|
||||
// transparent flag
|
||||
bool _isTransparent;
|
||||
|
||||
// skip auto batching
|
||||
bool _skipBatching;
|
||||
|
||||
// is the command been rendered on 3D pass
|
||||
bool _is3D;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -51,12 +51,28 @@ static bool compareRenderCommand(RenderCommand* a, RenderCommand* b)
|
|||
return a->getGlobalOrder() < b->getGlobalOrder();
|
||||
}
|
||||
|
||||
static bool compare3DCommand(RenderCommand* a, RenderCommand* b)
|
||||
{
|
||||
return a->getGlobalOrder() > b->getGlobalOrder();
|
||||
}
|
||||
|
||||
// queue
|
||||
|
||||
void RenderQueue::push_back(RenderCommand* command)
|
||||
{
|
||||
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);
|
||||
else if(z > 0)
|
||||
_queuePosZ.push_back(command);
|
||||
|
@ -66,18 +82,29 @@ void RenderQueue::push_back(RenderCommand* command)
|
|||
|
||||
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()
|
||||
{
|
||||
// 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(_queuePosZ), std::end(_queuePosZ), compareRenderCommand);
|
||||
}
|
||||
|
||||
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()))
|
||||
return _queueNegZ[index];
|
||||
|
||||
|
@ -97,37 +124,13 @@ RenderCommand* RenderQueue::operator[](ssize_t index) const
|
|||
|
||||
void RenderQueue::clear()
|
||||
{
|
||||
_queue3DOpaque.clear();
|
||||
_queue3DTransparent.clear();
|
||||
_queueNegZ.clear();
|
||||
_queue0.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;
|
||||
_renderGroups.push_back(defaultRenderQueue);
|
||||
_batchedCommands.reserve(BATCH_QUADCOMMAND_RESEVER_SIZE);
|
||||
|
||||
// default clear color
|
||||
_clearColor = Color4F::BLACK;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
|
@ -344,164 +350,156 @@ int Renderer::createRenderQueue()
|
|||
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 commandType = command->getType();
|
||||
if( RenderCommand::Type::TRIANGLES_COMMAND == commandType)
|
||||
{
|
||||
auto command = queue[index];
|
||||
auto commandType = command->getType();
|
||||
if( RenderCommand::Type::TRIANGLES_COMMAND == commandType)
|
||||
//Draw if we have batched other commands which are not triangle command
|
||||
flush3D();
|
||||
flushQuads();
|
||||
|
||||
//Process triangle command
|
||||
auto cmd = static_cast<TrianglesCommand*>(command);
|
||||
|
||||
//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->getIndexCount()>= 0 && cmd->getIndexCount() < INDEX_VBO_SIZE, "VBO for index is not big enough, please break the data down or use customized render command");
|
||||
//Draw batched Triangles if VBO is full
|
||||
drawBatchedTriangles();
|
||||
}
|
||||
|
||||
//Batch Triangles
|
||||
_batchedCommands.push_back(cmd);
|
||||
|
||||
fillVerticesAndIndices(cmd);
|
||||
|
||||
if(cmd->isSkipBatching())
|
||||
{
|
||||
drawBatchedTriangles();
|
||||
}
|
||||
|
||||
}
|
||||
else if ( RenderCommand::Type::QUAD_COMMAND == commandType )
|
||||
{
|
||||
//Draw if we have batched other commands which are not quad command
|
||||
flush3D();
|
||||
flushTriangles();
|
||||
|
||||
//Process quad command
|
||||
auto cmd = static_cast<QuadCommand*>(command);
|
||||
|
||||
//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");
|
||||
//Draw batched quads if VBO is full
|
||||
drawBatchedQuads();
|
||||
}
|
||||
|
||||
//Batch Quads
|
||||
_batchQuadCommands.push_back(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(_numberQuads > 0)
|
||||
|
||||
if(cmd->isSkipBatching())
|
||||
{
|
||||
drawBatchedQuads();
|
||||
_lastMaterialID = 0;
|
||||
cmd->execute();
|
||||
}
|
||||
|
||||
auto cmd = static_cast<TrianglesCommand*>(command);
|
||||
//Batch Triangles
|
||||
if( _filledVertex + cmd->getVertexCount() > VBO_SIZE || _filledIndex + cmd->getIndexCount() > INDEX_VBO_SIZE)
|
||||
else
|
||||
{
|
||||
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");
|
||||
//Draw batched Triangles if VBO is full
|
||||
drawBatchedTriangles();
|
||||
}
|
||||
|
||||
_batchedCommands.push_back(cmd);
|
||||
|
||||
fillVerticesAndIndices(cmd);
|
||||
|
||||
}
|
||||
else if ( RenderCommand::Type::QUAD_COMMAND == commandType )
|
||||
{
|
||||
flush3D();
|
||||
if(_filledIndex > 0)
|
||||
{
|
||||
drawBatchedTriangles();
|
||||
_lastMaterialID = 0;
|
||||
}
|
||||
auto cmd = static_cast<QuadCommand*>(command);
|
||||
//Batch quads
|
||||
if( (_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");
|
||||
//Draw batched quads if VBO is full
|
||||
drawBatchedQuads();
|
||||
}
|
||||
|
||||
_batchQuadCommands.push_back(cmd);
|
||||
|
||||
fillQuads(cmd);
|
||||
|
||||
}
|
||||
else if(RenderCommand::Type::GROUP_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();
|
||||
visitRenderQueue(_renderGroups[renderQueueID]);
|
||||
}
|
||||
else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<CustomCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else if(RenderCommand::Type::BATCH_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<BatchCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<PrimitiveCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else if (RenderCommand::Type::MESH_COMMAND == commandType)
|
||||
{
|
||||
flush2D();
|
||||
auto cmd = static_cast<MeshCommand*>(command);
|
||||
if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID())
|
||||
{
|
||||
flush3D();
|
||||
cmd->preBatchDraw();
|
||||
cmd->batchDraw();
|
||||
_lastBatchedMeshCommand = cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->batchDraw();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOGERROR("Unknown commands in renderQueue");
|
||||
cmd->batchDraw();
|
||||
}
|
||||
}
|
||||
else if(RenderCommand::Type::GROUP_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();
|
||||
visitRenderQueue(_renderGroups[renderQueueID]);
|
||||
}
|
||||
else if(RenderCommand::Type::CUSTOM_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<CustomCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else if(RenderCommand::Type::BATCH_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<BatchCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else if(RenderCommand::Type::PRIMITIVE_COMMAND == commandType)
|
||||
{
|
||||
flush();
|
||||
auto cmd = static_cast<PrimitiveCommand*>(command);
|
||||
cmd->execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
|
||||
_batchedCommands.clear();
|
||||
_filledVertex = 0;
|
||||
_filledIndex = 0;
|
||||
|
||||
for (ssize_t index = 0; index < size; ++index)
|
||||
//Process Opaque Object
|
||||
const std::vector<RenderCommand*>& opaqueQueue = queue.getOpaqueCommands();
|
||||
if (opaqueQueue.size() > 0)
|
||||
{
|
||||
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");
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
for (auto it = opaqueQueue.cbegin(); it != opaqueQueue.cend(); ++it) {
|
||||
processRenderCommand(*it);
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
}
|
||||
flush();
|
||||
|
||||
//Setup Transparent rendering
|
||||
if (opaqueQueue.size() > 0)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
//Process Transparent Object
|
||||
for (ssize_t index = queue.getOpaqueQueueSize(); index < size; ++index)
|
||||
{
|
||||
processRenderCommand(queue[index]);
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
void Renderer::render()
|
||||
|
@ -521,17 +519,6 @@ void Renderer::render()
|
|||
renderqueue.sort();
|
||||
}
|
||||
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();
|
||||
_isRendering = false;
|
||||
|
@ -558,8 +545,14 @@ void Renderer::clean()
|
|||
_numberQuads = 0;
|
||||
_lastMaterialID = 0;
|
||||
_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)
|
||||
|
@ -819,23 +812,8 @@ void Renderer::flush()
|
|||
|
||||
void Renderer::flush2D()
|
||||
{
|
||||
//Check depth write
|
||||
GLboolean depthWirte;
|
||||
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);
|
||||
}
|
||||
flushQuads();
|
||||
flushTriangles();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
auto scene = Director::getInstance()->getRunningScene();
|
||||
|
@ -884,4 +879,11 @@ bool Renderer::checkVisibility(const Mat4 &transform, const Size &size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Renderer::setClearColor(const Color4F &clearColor)
|
||||
{
|
||||
_clearColor = clearColor;
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -54,29 +54,17 @@ public:
|
|||
void sort();
|
||||
RenderCommand* operator[](ssize_t index) const;
|
||||
void clear();
|
||||
ssize_t getOpaqueQueueSize() const { return _queue3DOpaque.size(); }
|
||||
const std::vector<RenderCommand*>& getOpaqueCommands() const { return _queue3DOpaque; }
|
||||
|
||||
protected:
|
||||
std::vector<RenderCommand*> _queue3DOpaque;
|
||||
std::vector<RenderCommand*> _queue3DTransparent;
|
||||
std::vector<RenderCommand*> _queueNegZ;
|
||||
std::vector<RenderCommand*> _queue0;
|
||||
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
|
||||
{
|
||||
int renderQueueID;
|
||||
|
@ -125,6 +113,11 @@ public:
|
|||
/** Cleans all `RenderCommand`s in the queue */
|
||||
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 */
|
||||
ssize_t getDrawnBatches() const { return _drawnBatches; }
|
||||
/* RenderCommands (except) QuadCommand should update this value */
|
||||
|
@ -157,26 +150,29 @@ protected:
|
|||
void flush2D();
|
||||
|
||||
void flush3D();
|
||||
|
||||
|
||||
void flushQuads();
|
||||
void flushTriangles();
|
||||
|
||||
void processRenderCommand(RenderCommand* command);
|
||||
void visitRenderQueue(const RenderQueue& queue);
|
||||
|
||||
void visitTransparentRenderQueue(const TransparentRenderQueue& queue);
|
||||
|
||||
void fillVerticesAndIndices(const TrianglesCommand* cmd);
|
||||
void fillQuads(const QuadCommand* cmd);
|
||||
|
||||
|
||||
/* clear color set outside be used in setGLDefaultValues() */
|
||||
Color4F _clearColor;
|
||||
|
||||
std::stack<int> _commandGroupStack;
|
||||
|
||||
std::vector<RenderQueue> _renderGroups;
|
||||
TransparentRenderQueue _transparentRenderGroups; //transparency objects
|
||||
|
||||
uint32_t _lastMaterialID;
|
||||
|
||||
MeshCommand* _lastBatchedMeshCommand;
|
||||
std::vector<TrianglesCommand*> _batchedCommands;
|
||||
std::vector<QuadCommand*> _batchQuadCommands;
|
||||
|
||||
|
||||
|
||||
//for TrianglesCommand
|
||||
V3F_C4B_T2F _verts[VBO_SIZE];
|
||||
GLushort _indices[INDEX_VBO_SIZE];
|
||||
|
|
|
@ -606,15 +606,6 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
|
|||
if(!numberOfQuads)
|
||||
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());
|
||||
|
||||
if (Configuration::getInstance()->supportsShareableVAO())
|
||||
|
@ -694,12 +685,6 @@ void TextureAtlas::drawNumberOfQuads(ssize_t numberOfQuads, ssize_t start)
|
|||
}
|
||||
|
||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,numberOfQuads*6);
|
||||
|
||||
//Turn depth write on if necessary
|
||||
if(depthWirte)
|
||||
{
|
||||
glDepthMask(true);
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
|
|
|
@ -75,9 +75,11 @@ static Layer* restartSpriteTestAction()
|
|||
BillBoardTest::BillBoardTest()
|
||||
: _camera(nullptr)
|
||||
{
|
||||
//Create touch listener
|
||||
auto listener = EventListenerTouchAllAtOnce::create();
|
||||
listener->onTouchesMoved = CC_CALLBACK_2(BillBoardTest::onTouchesMoved, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||
|
||||
auto layer3D=Layer::create();
|
||||
addChild(layer3D,0);
|
||||
_layerBillBorad=layer3D;
|
||||
|
@ -89,6 +91,7 @@ BillBoardTest::BillBoardTest()
|
|||
_layerBillBorad->addChild(_camera);
|
||||
}
|
||||
|
||||
//Create rotating billboards
|
||||
std::string imgs[3] = {"Images/Icon.png", "Images/r2.png"};
|
||||
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)]);
|
||||
billboard->setScale(0.5f);
|
||||
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);
|
||||
_billboards.push_back(billboard);
|
||||
layer->addChild(billboard);
|
||||
_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(140,5,0));
|
||||
addNewBillBoradWithCoords(Vec3(180,5,0));
|
||||
|
||||
addNewAniBillBoradWithCoords(Vec3(-20,0,0));
|
||||
addNewAniBillBoradWithCoords(Vec3(-60,0,0));
|
||||
addNewAniBillBoradWithCoords(Vec3(-100,0,0));
|
||||
addNewAniBillBoradWithCoords(Vec3(-140,0,0));
|
||||
addNewAniBillBoradWithCoords(Vec3(-180,0,0));
|
||||
|
||||
_camera->setPosition3D(Vec3(0, 100, 230));
|
||||
_camera->lookAt(Vec3(0,0,0), Vec3(0,1,0));
|
||||
|
||||
|
@ -158,6 +162,8 @@ BillBoardTest::BillBoardTest()
|
|||
menu->setPosition(Vec2(0,0));
|
||||
this->addChild(menu, 10);
|
||||
menuCallback_orientedPoint(nullptr);
|
||||
|
||||
schedule(schedule_selector(BillBoardTest::update));
|
||||
}
|
||||
|
||||
void BillBoardTest::menuCallback_orientedPoint(Ref* sender)
|
||||
|
@ -183,7 +189,7 @@ BillBoardTest::~BillBoardTest()
|
|||
}
|
||||
std::string BillBoardTest::title() const
|
||||
{
|
||||
return "Testing BillBoard";
|
||||
return "BillBoard Test";
|
||||
}
|
||||
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)]);
|
||||
billborad->setScale(0.5f);
|
||||
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);
|
||||
|
||||
_layerBillBorad->addChild(billborad);
|
||||
_billboards.push_back(billborad);
|
||||
}
|
||||
|
@ -207,10 +213,10 @@ void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)
|
|||
{
|
||||
for (unsigned int i = 0; i < 10; ++i)
|
||||
{
|
||||
auto billboradAni = BillBoard::create("Images/grossini.png");
|
||||
billboradAni->setScale(0.5f);
|
||||
billboradAni->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
|
||||
_layerBillBorad->addChild(billboradAni);
|
||||
auto billboardAni = BillBoard::create("Images/grossini.png");
|
||||
billboardAni->setScale(0.5f);
|
||||
billboardAni->setPosition3D(Vec3(p.x, p.y, -150.0f + 30 * i));
|
||||
_layerBillBorad->addChild(billboardAni);
|
||||
|
||||
auto animation = Animation::create();
|
||||
for( int i=1;i<15;i++)
|
||||
|
@ -224,15 +230,13 @@ void BillBoardTest::addNewAniBillBoradWithCoords(Vec3 p)
|
|||
animation->setRestoreOriginalFrame(true);
|
||||
|
||||
auto action = Animate::create(animation);
|
||||
billboradAni->runAction(RepeatForever::create(action));
|
||||
billboradAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
||||
billboradAni->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
||||
_billboards.push_back(billboradAni);
|
||||
billboardAni->runAction(RepeatForever::create(action));
|
||||
billboardAni->setOpacity(CCRANDOM_0_1() * 128 + 128);
|
||||
_billboards.push_back(billboardAni);
|
||||
}
|
||||
}
|
||||
void BillBoardTest::update(float dt)
|
||||
{
|
||||
|
||||
}
|
||||
void BillBoardTest::onTouchesMoved(const std::vector<Touch*>& touches, Event* event)
|
||||
{
|
||||
|
|
|
@ -24,8 +24,6 @@ THE SOFTWARE.
|
|||
****************************************************************************/
|
||||
|
||||
#include "Camera3DTest.h"
|
||||
#include <algorithm>
|
||||
#include "../testResource.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -38,18 +36,18 @@ static int sceneIdx = -1;
|
|||
|
||||
static std::function<Layer*()> createFunctions[] =
|
||||
{
|
||||
CL(CameraRotationTest),
|
||||
CL(Camera3DTestDemo),
|
||||
CL(CameraClippingDemo),
|
||||
CL(CameraCullingDemo),
|
||||
#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.
|
||||
CL(FogTestDemo),
|
||||
#endif
|
||||
CL(CameraArcBallDemo)
|
||||
|
||||
};
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
||||
static Layer* nextSpriteTestAction()
|
||||
static Layer*nextTest()
|
||||
{
|
||||
sceneIdx++;
|
||||
sceneIdx = sceneIdx % MAX_LAYER;
|
||||
|
@ -57,7 +55,7 @@ static Layer* nextSpriteTestAction()
|
|||
return layer;
|
||||
}
|
||||
|
||||
static Layer* backSpriteTestAction()
|
||||
static Layer*backTest()
|
||||
{
|
||||
sceneIdx--;
|
||||
int total = MAX_LAYER;
|
||||
|
@ -68,21 +66,163 @@ static Layer* backSpriteTestAction()
|
|||
return layer;
|
||||
}
|
||||
|
||||
static Layer* restartSpriteTestAction()
|
||||
static Layer* restartTest()
|
||||
{
|
||||
auto layer = (createFunctions[sceneIdx])();
|
||||
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)
|
||||
: BaseTest()
|
||||
, _incRot(nullptr)
|
||||
: _incRot(nullptr)
|
||||
, _camera(nullptr)
|
||||
, _decRot(nullptr)
|
||||
, _bZoomOut(false)
|
||||
|
@ -102,13 +242,9 @@ std::string Camera3DTestDemo::title() const
|
|||
return "Testing Camera";
|
||||
}
|
||||
|
||||
std::string Camera3DTestDemo::subtitle() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
void Camera3DTestDemo::scaleCameraCallback(Ref* sender,float value)
|
||||
{
|
||||
if(_camera&& _cameraType!=CameraType::FirstCamera)
|
||||
if(_camera&& _cameraType!=CameraType::FirstPerson)
|
||||
{
|
||||
Vec3 cameraPos= _camera->getPosition3D();
|
||||
cameraPos+= cameraPos.getNormalized()*value;
|
||||
|
@ -117,7 +253,7 @@ void Camera3DTestDemo::scaleCameraCallback(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();
|
||||
rotation3D.y+= value;
|
||||
|
@ -131,33 +267,33 @@ void Camera3DTestDemo::SwitchViewCallback(Ref* sender, CameraType cameraType)
|
|||
return ;
|
||||
}
|
||||
_cameraType = cameraType;
|
||||
if(_cameraType==CameraType::FreeCamera)
|
||||
if(_cameraType==CameraType::Free)
|
||||
{
|
||||
_camera->setPosition3D(Vec3(0, 130, 130) + _sprite3D->getPosition3D());
|
||||
_camera->lookAt(_sprite3D->getPosition3D(), Vec3(0,1,0));
|
||||
_camera->lookAt(_sprite3D->getPosition3D());
|
||||
|
||||
_RotateRightlabel->setColor(Color3B::WHITE);
|
||||
_RotateLeftlabel->setColor(Color3B::WHITE);
|
||||
_ZoomInlabel->setColor(Color3B::WHITE);
|
||||
_ZoomOutlabel->setColor(Color3B::WHITE);
|
||||
}
|
||||
else if(_cameraType==CameraType::FirstCamera)
|
||||
else if(_cameraType==CameraType::FirstPerson)
|
||||
{
|
||||
Vec3 newFaceDir;
|
||||
_sprite3D->getWorldToNodeTransform().getForwardVector(&newFaceDir);
|
||||
newFaceDir.normalize();
|
||||
_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);
|
||||
_RotateLeftlabel->setColor(Color3B::WHITE);
|
||||
_ZoomInlabel->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->lookAt(_sprite3D->getPosition3D(), Vec3(0,1,0));
|
||||
_camera->lookAt(_sprite3D->getPosition3D());
|
||||
|
||||
_RotateRightlabel->setColor(Color3B::GRAY);
|
||||
_RotateLeftlabel->setColor(Color3B::GRAY);
|
||||
|
@ -239,11 +375,11 @@ void Camera3DTestDemo::onEnter()
|
|||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener4, _RotateRightlabel);
|
||||
|
||||
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 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 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);
|
||||
|
||||
menu->setPosition(Vec2::ZERO);
|
||||
|
@ -259,7 +395,7 @@ void Camera3DTestDemo::onEnter()
|
|||
_camera->setCameraFlag(CameraFlag::USER1);
|
||||
_layer3D->addChild(_camera);
|
||||
}
|
||||
SwitchViewCallback(this,CameraType::ThirdCamera);
|
||||
SwitchViewCallback(this,CameraType::ThirdPerson);
|
||||
DrawNode3D* line =DrawNode3D::create();
|
||||
//draw x
|
||||
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)
|
||||
{
|
||||
auto sprite = Sprite3D::create(fileName);
|
||||
|
@ -348,7 +460,7 @@ void Camera3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2
|
|||
auto touch = touches[0];
|
||||
auto location = touch->getLocation();
|
||||
Point newPos = touch->getPreviousLocation()-location;
|
||||
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera)
|
||||
if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
|
||||
{
|
||||
Vec3 cameraDir;
|
||||
Vec3 cameraRightDir;
|
||||
|
@ -362,7 +474,7 @@ void Camera3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2
|
|||
cameraPos+=cameraDir*newPos.y*0.1f;
|
||||
cameraPos+=cameraRightDir*newPos.x*0.1f;
|
||||
_camera->setPosition3D(cameraPos);
|
||||
if(_sprite3D && _cameraType==CameraType::FirstCamera)
|
||||
if(_sprite3D && _cameraType==CameraType::FirstPerson)
|
||||
{
|
||||
_sprite3D->setPosition3D(Vec3(_camera->getPositionX(),0,_camera->getPositionZ()));
|
||||
_targetPos=_sprite3D->getPosition3D();
|
||||
|
@ -383,7 +495,7 @@ void Camera3DTestDemo::move3D(float elapsedTime)
|
|||
_sprite3D->setPosition3D(curPos);
|
||||
offset.x=offset.x;
|
||||
offset.z=offset.z;
|
||||
if(_cameraType==CameraType::ThirdCamera)
|
||||
if(_cameraType==CameraType::ThirdPerson)
|
||||
{
|
||||
Vec3 cameraPos= _camera->getPosition3D();
|
||||
cameraPos.x+=offset.x;
|
||||
|
@ -430,7 +542,7 @@ void Camera3DTestDemo::onTouchesEnded(const std::vector<Touch*>& touches, cocos2
|
|||
auto location = touch->getLocationInView();
|
||||
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);
|
||||
|
||||
|
@ -467,7 +579,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
{
|
||||
if(_sprite3D)
|
||||
{
|
||||
if( _cameraType==CameraType::ThirdCamera)
|
||||
if( _cameraType==CameraType::ThirdPerson)
|
||||
{
|
||||
updateState(fDelta);
|
||||
if(isState(_curState,State_Move))
|
||||
|
@ -515,7 +627,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
{
|
||||
if(_camera)
|
||||
{
|
||||
if(_cameraType == CameraType::ThirdCamera)
|
||||
if(_cameraType == CameraType::ThirdPerson)
|
||||
{
|
||||
Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D();
|
||||
Vec3 cameraPos = _camera->getPosition3D();
|
||||
|
@ -525,7 +637,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
_camera->setPosition3D(cameraPos);
|
||||
}
|
||||
}
|
||||
else if(_cameraType == CameraType::FreeCamera)
|
||||
else if(_cameraType == CameraType::Free)
|
||||
{
|
||||
Vec3 cameraPos = _camera->getPosition3D();
|
||||
if(cameraPos.length() <= 300)
|
||||
|
@ -540,7 +652,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
{
|
||||
if(_camera)
|
||||
{
|
||||
if(_cameraType == CameraType::ThirdCamera)
|
||||
if(_cameraType == CameraType::ThirdPerson)
|
||||
{
|
||||
Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D();
|
||||
Vec3 cameraPos = _camera->getPosition3D();
|
||||
|
@ -550,7 +662,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
_camera->setPosition3D(cameraPos);
|
||||
}
|
||||
}
|
||||
else if(_cameraType == CameraType::FreeCamera)
|
||||
else if(_cameraType == CameraType::Free)
|
||||
{
|
||||
Vec3 cameraPos = _camera->getPosition3D();
|
||||
if(cameraPos.length() >= 50)
|
||||
|
@ -563,7 +675,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
}
|
||||
if(_bRotateLeft == true)
|
||||
{
|
||||
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera)
|
||||
if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
|
||||
{
|
||||
Vec3 rotation3D= _camera->getRotation3D();
|
||||
rotation3D.y+= 1;
|
||||
|
@ -572,7 +684,7 @@ void Camera3DTestDemo::updateCamera(float fDelta)
|
|||
}
|
||||
if(_bRotateRight == true)
|
||||
{
|
||||
if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera)
|
||||
if(_cameraType==CameraType::Free || _cameraType==CameraType::FirstPerson)
|
||||
{
|
||||
Vec3 rotation3D= _camera->getRotation3D();
|
||||
rotation3D.y-= 1;
|
||||
|
@ -663,11 +775,10 @@ void Camera3DTestDemo::onTouchesRotateRightEnd(Touch* touch, Event* event)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// CameraClippingDemo
|
||||
CameraClippingDemo::CameraClippingDemo(void)
|
||||
: BaseTest()
|
||||
, _layer3D(nullptr)
|
||||
, _cameraType(CameraType::FirstCamera)
|
||||
// CameraCullingDemo
|
||||
CameraCullingDemo::CameraCullingDemo(void)
|
||||
: _layer3D(nullptr)
|
||||
, _cameraType(CameraType::FirstPerson)
|
||||
, _cameraFirst(nullptr)
|
||||
, _cameraThird(nullptr)
|
||||
, _moveAction(nullptr)
|
||||
|
@ -676,49 +787,26 @@ CameraClippingDemo::CameraClippingDemo(void)
|
|||
, _row(3)
|
||||
{
|
||||
}
|
||||
CameraClippingDemo::~CameraClippingDemo(void)
|
||||
CameraCullingDemo::~CameraCullingDemo(void)
|
||||
{
|
||||
}
|
||||
|
||||
std::string CameraClippingDemo::title() const
|
||||
std::string CameraCullingDemo::title() const
|
||||
{
|
||||
return "Camera Frustum Clipping";
|
||||
}
|
||||
|
||||
void CameraClippingDemo::restartCallback(Ref* sender)
|
||||
{
|
||||
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()
|
||||
void CameraCullingDemo::onEnter()
|
||||
{
|
||||
BaseTest::onEnter();
|
||||
schedule(schedule_selector(CameraClippingDemo::update), 0.0f);
|
||||
|
||||
schedule(schedule_selector(CameraCullingDemo::update), 0.0f);
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
auto listener = EventListenerTouchAllAtOnce::create();
|
||||
listener->onTouchesBegan = CC_CALLBACK_2(CameraClippingDemo::onTouchesBegan, this);
|
||||
listener->onTouchesMoved = CC_CALLBACK_2(CameraClippingDemo::onTouchesMoved, this);
|
||||
listener->onTouchesEnded = CC_CALLBACK_2(CameraClippingDemo::onTouchesEnded, this);
|
||||
listener->onTouchesBegan = CC_CALLBACK_2(CameraCullingDemo::onTouchesBegan, this);
|
||||
listener->onTouchesMoved = CC_CALLBACK_2(CameraCullingDemo::onTouchesMoved, this);
|
||||
listener->onTouchesEnded = CC_CALLBACK_2(CameraCullingDemo::onTouchesEnded, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||
auto layer3D=Layer::create();
|
||||
addChild(layer3D,0);
|
||||
|
@ -728,7 +816,7 @@ void CameraClippingDemo::onEnter()
|
|||
MenuItemFont::setFontName("fonts/arial.ttf");
|
||||
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));
|
||||
auto menu = Menu::create(menuItem1,NULL);
|
||||
menu->setPosition(Vec2::ZERO);
|
||||
|
@ -737,9 +825,9 @@ void CameraClippingDemo::onEnter()
|
|||
|
||||
// + -
|
||||
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));
|
||||
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));
|
||||
|
||||
menu = Menu::create(decrease, increase, nullptr);
|
||||
|
@ -770,7 +858,7 @@ void CameraClippingDemo::onEnter()
|
|||
addSpriteCallback(nullptr);
|
||||
}
|
||||
|
||||
void CameraClippingDemo::onExit()
|
||||
void CameraCullingDemo::onExit()
|
||||
{
|
||||
BaseTest::onExit();
|
||||
if (_cameraFirst)
|
||||
|
@ -783,11 +871,11 @@ void CameraClippingDemo::onExit()
|
|||
}
|
||||
}
|
||||
|
||||
void CameraClippingDemo::update(float dt)
|
||||
void CameraCullingDemo::update(float dt)
|
||||
{
|
||||
_drawAABB->clear();
|
||||
|
||||
if(_cameraType == CameraType::ThirdCamera)
|
||||
if(_cameraType == CameraType::ThirdPerson)
|
||||
drawCameraFrustum();
|
||||
|
||||
Vector<Node*>& children = _layer3D->getChildren();
|
||||
|
@ -804,7 +892,7 @@ void CameraClippingDemo::update(float dt)
|
|||
}
|
||||
}
|
||||
|
||||
void CameraClippingDemo::reachEndCallBack()
|
||||
void CameraCullingDemo::reachEndCallBack()
|
||||
{
|
||||
_cameraFirst->stopActionByTag(100);
|
||||
auto inverse = (MoveTo*)_moveAction->reverse();
|
||||
|
@ -812,12 +900,12 @@ void CameraClippingDemo::reachEndCallBack()
|
|||
_moveAction->release();
|
||||
_moveAction = inverse;
|
||||
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);
|
||||
_cameraFirst->runAction(seq);
|
||||
}
|
||||
|
||||
void CameraClippingDemo::switchViewCallback(Ref* sender)
|
||||
void CameraCullingDemo::switchViewCallback(Ref* sender)
|
||||
{
|
||||
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->setCameraFlag(CameraFlag::USER8);
|
||||
_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->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);
|
||||
_cameraFirst->runAction(seq);
|
||||
addChild(_cameraFirst);
|
||||
|
@ -840,20 +928,20 @@ void CameraClippingDemo::switchViewCallback(Ref* sender)
|
|||
_cameraThird = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000);
|
||||
_cameraThird->setCameraFlag(CameraFlag::USER8);
|
||||
_cameraThird->setPosition3D(Vec3(0, 130, 130));
|
||||
_cameraThird->lookAt(Vec3(0,0,0), Vec3(0, 1, 0));
|
||||
_cameraThird->lookAt(Vec3(0,0,0));
|
||||
addChild(_cameraThird);
|
||||
}
|
||||
|
||||
if(_cameraType == CameraType::FirstCamera)
|
||||
if(_cameraType == CameraType::FirstPerson)
|
||||
{
|
||||
_cameraType = CameraType::ThirdCamera;
|
||||
_cameraType = CameraType::ThirdPerson;
|
||||
_cameraThird->setCameraFlag(CameraFlag::USER1);
|
||||
_cameraThird->enableFrustumCulling(false, false);
|
||||
_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->enableFrustumCulling(true, true);
|
||||
_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();
|
||||
_objects.clear();
|
||||
|
@ -889,7 +977,7 @@ void CameraClippingDemo::addSpriteCallback(Ref* sender)
|
|||
_labelSprite3DCount->setString(szText);
|
||||
}
|
||||
|
||||
void CameraClippingDemo::delSpriteCallback(Ref* sender)
|
||||
void CameraCullingDemo::delSpriteCallback(Ref* sender)
|
||||
{
|
||||
if (_row == 0) return;
|
||||
|
||||
|
@ -917,7 +1005,7 @@ void CameraClippingDemo::delSpriteCallback(Ref* sender)
|
|||
_labelSprite3DCount->setString(szText);
|
||||
}
|
||||
|
||||
void CameraClippingDemo::drawCameraFrustum()
|
||||
void CameraCullingDemo::drawCameraFrustum()
|
||||
{
|
||||
_drawFrustum->clear();
|
||||
auto size = Director::getInstance()->getWinSize();
|
||||
|
@ -971,9 +1059,9 @@ void CameraClippingDemo::drawCameraFrustum()
|
|||
////////////////////////////////////////////////////////////
|
||||
// CameraArcBallDemo
|
||||
CameraArcBallDemo::CameraArcBallDemo(void)
|
||||
: BaseTest()
|
||||
: CameraBaseTest()
|
||||
, _layer3D(nullptr)
|
||||
, _cameraType(CameraType::FreeCamera)
|
||||
, _cameraType(CameraType::Free)
|
||||
, _camera(nullptr)
|
||||
,_drawGrid(nullptr)
|
||||
,_sprite3D1(nullptr)
|
||||
|
@ -994,31 +1082,6 @@ std::string CameraArcBallDemo::title() const
|
|||
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()
|
||||
{
|
||||
BaseTest::onEnter();
|
||||
|
@ -1219,9 +1282,9 @@ void CameraArcBallDemo::update(float dt)
|
|||
////////////////////////////////////////////////////////////
|
||||
// FogTestDemo
|
||||
FogTestDemo::FogTestDemo(void)
|
||||
: BaseTest()
|
||||
: CameraBaseTest()
|
||||
, _layer3D(nullptr)
|
||||
, _cameraType(CameraType::FreeCamera)
|
||||
, _cameraType(CameraType::Free)
|
||||
, _camera(nullptr)
|
||||
, _shader(nullptr)
|
||||
, _state(nullptr)
|
||||
|
@ -1236,31 +1299,6 @@ std::string FogTestDemo::title() const
|
|||
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()
|
||||
{
|
||||
BaseTest::onEnter();
|
||||
|
@ -1436,7 +1474,7 @@ void FogTestDemo::onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Ev
|
|||
Vec2 prelocation = touches[0]->getPreviousLocationInView();
|
||||
Vec2 location = touches[0]->getLocationInView();
|
||||
Vec2 newPos = prelocation - location;
|
||||
if(_cameraType==CameraType::FreeCamera)
|
||||
if(_cameraType==CameraType::Free)
|
||||
{
|
||||
Vec3 cameraDir;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -48,9 +48,9 @@ enum State
|
|||
};
|
||||
enum class CameraType
|
||||
{
|
||||
FreeCamera=0,
|
||||
FirstCamera=1,
|
||||
ThirdCamera=2,
|
||||
Free = 0,
|
||||
FirstPerson = 1,
|
||||
ThirdPerson = 2,
|
||||
};
|
||||
|
||||
enum class OperateCamType
|
||||
|
@ -59,21 +59,60 @@ enum class OperateCamType
|
|||
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:
|
||||
CREATE_FUNC(Camera3DTestDemo);
|
||||
Camera3DTestDemo(void);
|
||||
virtual ~Camera3DTestDemo(void);
|
||||
|
||||
void restartCallback(Ref* sender);
|
||||
void nextCallback(Ref* sender);
|
||||
void backCallback(Ref* sender);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
// overrides
|
||||
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 onTouchesBegan(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;
|
||||
};
|
||||
|
||||
class CameraClippingDemo : public BaseTest
|
||||
class CameraCullingDemo : public CameraBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(CameraClippingDemo);
|
||||
CameraClippingDemo(void);
|
||||
virtual ~CameraClippingDemo(void);
|
||||
|
||||
void restartCallback(Ref* sender);
|
||||
void nextCallback(Ref* sender);
|
||||
void backCallback(Ref* sender);
|
||||
CREATE_FUNC(CameraCullingDemo);
|
||||
CameraCullingDemo(void);
|
||||
virtual ~CameraCullingDemo(void);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
@ -155,17 +190,13 @@ protected:
|
|||
int _row;
|
||||
};
|
||||
|
||||
class CameraArcBallDemo : public BaseTest
|
||||
class CameraArcBallDemo : public CameraBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(CameraArcBallDemo);
|
||||
CameraArcBallDemo(void);
|
||||
virtual ~CameraArcBallDemo(void);
|
||||
|
||||
void restartCallback(Ref* sender);
|
||||
void nextCallback(Ref* sender);
|
||||
void backCallback(Ref* sender);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
|
@ -196,17 +227,13 @@ protected:
|
|||
Sprite3D* _sprite3D2;
|
||||
};
|
||||
|
||||
class FogTestDemo : public BaseTest
|
||||
class FogTestDemo : public CameraBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(FogTestDemo);
|
||||
FogTestDemo(void);
|
||||
virtual ~FogTestDemo(void);
|
||||
|
||||
void restartCallback(Ref* sender);
|
||||
void nextCallback(Ref* sender);
|
||||
void backCallback(Ref* sender);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
||||
|
@ -233,9 +260,5 @@ protected:
|
|||
#endif
|
||||
};
|
||||
|
||||
class Camera3DTestScene : public TestScene
|
||||
{
|
||||
public:
|
||||
virtual void runThisTest();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -68,7 +68,8 @@ static std::function<Layer*()> createFunctions[] =
|
|||
CL(Sprite3DReskinTest),
|
||||
CL(Sprite3DWithOBBPerfromanceTest),
|
||||
CL(Sprite3DMirrorTest),
|
||||
CL(QuaternionTest)
|
||||
CL(QuaternionTest),
|
||||
CL(Sprite3DEmptyTest)
|
||||
};
|
||||
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
@ -154,6 +155,30 @@ void Sprite3DTestDemo::backCallback(Ref* sender)
|
|||
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";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -54,6 +54,15 @@ public:
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue