mirror of https://github.com/axmolengine/axmol.git
Merge pull request #13780 from super626/material
Sprite3D Material refactor
This commit is contained in:
commit
0c782c84c9
|
@ -310,6 +310,14 @@ void Mesh::setMaterial(Material* material)
|
|||
}
|
||||
}
|
||||
}
|
||||
// Was the texture set before teh GLProgramState ? Set it
|
||||
if (_texture)
|
||||
setTexture(_texture);
|
||||
|
||||
if (_blendDirty)
|
||||
setBlendFunc(_blend);
|
||||
|
||||
bindMeshCommand();
|
||||
}
|
||||
|
||||
Material* Mesh::getMaterial() const
|
||||
|
@ -397,15 +405,6 @@ void Mesh::setGLProgramState(GLProgramState* glProgramState)
|
|||
// XXX create dummy texture
|
||||
auto material = Material::createWithGLStateProgram(glProgramState);
|
||||
setMaterial(material);
|
||||
|
||||
// Was the texture set before teh GLProgramState ? Set it
|
||||
if (_texture)
|
||||
setTexture(_texture);
|
||||
|
||||
if (_blendDirty)
|
||||
setBlendFunc(_blend);
|
||||
|
||||
bindMeshCommand();
|
||||
}
|
||||
|
||||
GLProgramState* Mesh::getGLProgramState() const
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "3d/CCSprite3DMaterial.h"
|
||||
#include "3d/CCAttachNode.h"
|
||||
#include "3d/CCMesh.h"
|
||||
#include "3d/CCSprite3DMaterial.h"
|
||||
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCAsyncTaskPool.h"
|
||||
|
@ -49,7 +50,7 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
static GLProgramState* getGLProgramStateForAttribs(MeshVertexData* meshVertexData, bool usesLight);
|
||||
static Sprite3DMaterial* getSprite3DMaterialForAttribs(MeshVertexData* meshVertexData, bool usesLight);
|
||||
|
||||
Sprite3D* Sprite3D::create()
|
||||
{
|
||||
|
@ -351,7 +352,7 @@ bool Sprite3D::initFrom(const NodeDatas& nodeDatas, const MeshDatas& meshdatas,
|
|||
createAttachSprite3DNode(it,materialdatas);
|
||||
}
|
||||
}
|
||||
genGLProgramState();
|
||||
genMaterial();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -404,7 +405,7 @@ Sprite3D* Sprite3D::createSprite3DNode(NodeData* nodedata,ModelData* modeldata,c
|
|||
|
||||
sprite->addMesh(mesh);
|
||||
sprite->autorelease();
|
||||
sprite->genGLProgramState();
|
||||
sprite->genMaterial();
|
||||
}
|
||||
return sprite;
|
||||
}
|
||||
|
@ -461,26 +462,25 @@ Material* Sprite3D::getMaterial(int meshIndex) const
|
|||
}
|
||||
|
||||
|
||||
void Sprite3D::genGLProgramState(bool useLight)
|
||||
void Sprite3D::genMaterial(bool useLight)
|
||||
{
|
||||
_shaderUsingLight = useLight;
|
||||
|
||||
std::unordered_map<const MeshVertexData*, GLProgramState*> glProgramestates;
|
||||
std::unordered_map<const MeshVertexData*, Sprite3DMaterial*> materials;
|
||||
for(auto meshVertexData : _meshVertexDatas)
|
||||
{
|
||||
auto glprogramstate = getGLProgramStateForAttribs(meshVertexData, useLight);
|
||||
glProgramestates[meshVertexData] = glprogramstate;
|
||||
auto material = getSprite3DMaterialForAttribs(meshVertexData, useLight);
|
||||
materials[meshVertexData] = material;
|
||||
}
|
||||
|
||||
for (auto& mesh: _meshes)
|
||||
{
|
||||
auto glProgramState = glProgramestates[mesh->getMeshIndexData()->getMeshVertexData()];
|
||||
auto material = materials[mesh->getMeshIndexData()->getMeshVertexData()];
|
||||
|
||||
// hack to prevent cloning the very first time
|
||||
if (glProgramState->getReferenceCount() == 1)
|
||||
mesh->setGLProgramState(glProgramState);
|
||||
if (material->getReferenceCount() == 1)
|
||||
mesh->setMaterial(material);
|
||||
else
|
||||
mesh->setGLProgramState(glProgramState->clone());
|
||||
mesh->setMaterial(material->clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,7 +736,7 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
}
|
||||
if (usingLight != _shaderUsingLight)
|
||||
{
|
||||
genGLProgramState(usingLight);
|
||||
genMaterial(usingLight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,45 +954,23 @@ Sprite3DCache::~Sprite3DCache()
|
|||
//
|
||||
// MARK: Helpers
|
||||
//
|
||||
static GLProgramState* getGLProgramStateForAttribs(MeshVertexData* meshVertexData, bool usesLight)
|
||||
static Sprite3DMaterial* getSprite3DMaterialForAttribs(MeshVertexData* meshVertexData, bool usesLight)
|
||||
{
|
||||
bool textured = meshVertexData->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD);
|
||||
bool hasSkin = meshVertexData->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX)
|
||||
&& meshVertexData->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT);
|
||||
bool hasNormal = meshVertexData->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL);
|
||||
|
||||
const char* shader = nullptr;
|
||||
Sprite3DMaterial::MaterialType type;
|
||||
if(textured)
|
||||
{
|
||||
if (hasSkin)
|
||||
{
|
||||
if (hasNormal && usesLight)
|
||||
shader = GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE;
|
||||
else
|
||||
shader = GLProgram::SHADER_3D_SKINPOSITION_TEXTURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasNormal && usesLight)
|
||||
shader = GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE;
|
||||
else
|
||||
shader = GLProgram::SHADER_3D_POSITION_TEXTURE;
|
||||
}
|
||||
type = hasNormal && usesLight ? Sprite3DMaterial::MaterialType::DIFFUSE : Sprite3DMaterial::MaterialType::UNLIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasNormal && usesLight)
|
||||
shader = GLProgram::SHADER_3D_POSITION_NORMAL;
|
||||
else
|
||||
shader = GLProgram::SHADER_3D_POSITION;
|
||||
type = hasNormal && usesLight ? Sprite3DMaterial::MaterialType::DIFFUSE_NOTEX : Sprite3DMaterial::MaterialType::UNLIT_NOTEX;
|
||||
}
|
||||
|
||||
CCASSERT(shader, "Couldn't find shader for sprite");
|
||||
|
||||
auto glProgram = GLProgramCache::getInstance()->getGLProgram(shader);
|
||||
auto glprogramstate = GLProgramState::create(glProgram);
|
||||
|
||||
return glprogramstate;
|
||||
|
||||
return Sprite3DMaterial::createBuiltInMaterial(type, hasSkin);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -223,8 +223,8 @@ CC_CONSTRUCTOR_ACCESS:
|
|||
*/
|
||||
virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
|
||||
|
||||
/**generate default GLProgramState*/
|
||||
void genGLProgramState(bool useLight = false);
|
||||
/**generate default material*/
|
||||
void genMaterial(bool useLight = false);
|
||||
|
||||
void createNode(NodeData* nodedata, Node* root, const MaterialDatas& matrialdatas, bool singleSprite);
|
||||
void createAttachSprite3DNode(NodeData* nodedata,const MaterialDatas& matrialdatas);
|
||||
|
|
|
@ -23,13 +23,216 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "3d/CCSprite3DMaterial.h"
|
||||
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/CCGLProgramState.h"
|
||||
#include "renderer/CCGLProgramStateCache.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCEventType.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
Sprite3DMaterialCache* Sprite3DMaterialCache::_cacheInstance = nullptr;
|
||||
|
||||
std::unordered_map<std::string, Sprite3DMaterial*> Sprite3DMaterial::_materials;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_unLitMaterial = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_unLitNoTexMaterial = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_vertexLitMaterial = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_diffuseMaterial = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_diffuseNoTexMaterial = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_bumpedDiffuseMaterial = nullptr;
|
||||
|
||||
Sprite3DMaterial* Sprite3DMaterial::_unLitMaterialSkin = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_vertexLitMaterialSkin = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_diffuseMaterialSkin = nullptr;
|
||||
Sprite3DMaterial* Sprite3DMaterial::_bumpedDiffuseMaterialSkin = nullptr;
|
||||
|
||||
void Sprite3DMaterial::createBuiltInMaterial()
|
||||
{
|
||||
releaseBuiltInMaterial();
|
||||
|
||||
auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE);
|
||||
auto glprogramstate = GLProgramState::create(glProgram);
|
||||
_unLitMaterialSkin = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_unLitMaterialSkin && _unLitMaterialSkin->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_unLitMaterialSkin->_type = Sprite3DMaterial::MaterialType::UNLIT;
|
||||
}
|
||||
|
||||
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE);
|
||||
glprogramstate = GLProgramState::create(glProgram);
|
||||
_diffuseMaterialSkin = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_diffuseMaterialSkin && _diffuseMaterialSkin->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_diffuseMaterialSkin->_type = Sprite3DMaterial::MaterialType::DIFFUSE;
|
||||
}
|
||||
|
||||
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE);
|
||||
glprogramstate = GLProgramState::create(glProgram);
|
||||
_diffuseMaterial = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_diffuseMaterial && _diffuseMaterial->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_diffuseMaterial->_type = Sprite3DMaterial::MaterialType::DIFFUSE;
|
||||
}
|
||||
|
||||
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_TEXTURE);
|
||||
glprogramstate = GLProgramState::create(glProgram);
|
||||
_unLitMaterial = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_unLitMaterial && _unLitMaterial->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_unLitMaterial->_type = Sprite3DMaterial::MaterialType::UNLIT;
|
||||
}
|
||||
|
||||
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION);
|
||||
glprogramstate = GLProgramState::create(glProgram);
|
||||
_unLitNoTexMaterial = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_unLitNoTexMaterial && _unLitNoTexMaterial->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_unLitNoTexMaterial->_type = Sprite3DMaterial::MaterialType::UNLIT_NOTEX;
|
||||
}
|
||||
|
||||
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_NORMAL);
|
||||
glprogramstate = GLProgramState::create(glProgram);
|
||||
_diffuseNoTexMaterial = new (std::nothrow) Sprite3DMaterial();
|
||||
if (_diffuseNoTexMaterial && _diffuseNoTexMaterial->initWithGLProgramState(glprogramstate))
|
||||
{
|
||||
_diffuseNoTexMaterial->_type = Sprite3DMaterial::MaterialType::DIFFUSE_NOTEX;
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite3DMaterial::releaseBuiltInMaterial()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_unLitMaterial);
|
||||
CC_SAFE_RELEASE_NULL(_unLitMaterialSkin);
|
||||
|
||||
CC_SAFE_RELEASE_NULL(_unLitNoTexMaterial);
|
||||
CC_SAFE_RELEASE_NULL(_vertexLitMaterial);
|
||||
CC_SAFE_RELEASE_NULL(_diffuseMaterial);
|
||||
CC_SAFE_RELEASE_NULL(_diffuseNoTexMaterial);
|
||||
CC_SAFE_RELEASE_NULL(_bumpedDiffuseMaterial);
|
||||
|
||||
CC_SAFE_RELEASE_NULL(_vertexLitMaterialSkin);
|
||||
CC_SAFE_RELEASE_NULL(_diffuseMaterialSkin);
|
||||
CC_SAFE_RELEASE_NULL(_bumpedDiffuseMaterialSkin);
|
||||
}
|
||||
|
||||
void Sprite3DMaterial::releaseCachedMaterial()
|
||||
{
|
||||
for (auto& it : _materials) {
|
||||
if (it.second)
|
||||
it.second->release();
|
||||
}
|
||||
_materials.clear();
|
||||
}
|
||||
|
||||
Material* Sprite3DMaterial::clone() const
|
||||
{
|
||||
auto material = new (std::nothrow) Sprite3DMaterial();
|
||||
if (material)
|
||||
{
|
||||
RenderState::cloneInto(material);
|
||||
|
||||
for (const auto& technique: _techniques)
|
||||
{
|
||||
auto t = technique->clone();
|
||||
t->setParent(material);
|
||||
for (ssize_t i = 0; i < t->getPassCount(); i++) {
|
||||
t->getPassByIndex(i)->setParent(t);
|
||||
}
|
||||
material->_techniques.pushBack(t);
|
||||
}
|
||||
|
||||
// current technique
|
||||
auto name = _currentTechnique->getName();
|
||||
material->_currentTechnique = material->getTechniqueByName(name);
|
||||
material->_type = _type;
|
||||
material->autorelease();
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
Sprite3DMaterial* Sprite3DMaterial::createBuiltInMaterial(MaterialType type, bool skinned)
|
||||
{
|
||||
/////
|
||||
if (_diffuseMaterial == nullptr)
|
||||
createBuiltInMaterial();
|
||||
|
||||
Sprite3DMaterial* material = nullptr;
|
||||
switch (type) {
|
||||
case Sprite3DMaterial::MaterialType::UNLIT:
|
||||
material = skinned ? _unLitMaterialSkin : _unLitMaterial;
|
||||
break;
|
||||
|
||||
case Sprite3DMaterial::MaterialType::UNLIT_NOTEX:
|
||||
material = _unLitNoTexMaterial;
|
||||
break;
|
||||
|
||||
case Sprite3DMaterial::MaterialType::VERTEX_LIT:
|
||||
CCASSERT(0, "not implement");
|
||||
break;
|
||||
|
||||
case Sprite3DMaterial::MaterialType::DIFFUSE:
|
||||
material = skinned ? _diffuseMaterialSkin : _diffuseMaterial;
|
||||
break;
|
||||
|
||||
case Sprite3DMaterial::MaterialType::DIFFUSE_NOTEX:
|
||||
material = _diffuseNoTexMaterial;
|
||||
break;
|
||||
|
||||
case Sprite3DMaterial::MaterialType::BUMPED_DIFFUSE:
|
||||
CCASSERT(0, "not implement");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (material)
|
||||
return (Sprite3DMaterial*)material->clone();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Sprite3DMaterial* Sprite3DMaterial::createWithFilename(const std::string& path)
|
||||
{
|
||||
auto validfilename = FileUtils::getInstance()->fullPathForFilename(path);
|
||||
if (validfilename.size() > 0) {
|
||||
auto it = _materials.find(validfilename);
|
||||
if (it != _materials.end())
|
||||
return (Sprite3DMaterial*)it->second->clone();
|
||||
|
||||
auto material = new (std::nothrow) Sprite3DMaterial();
|
||||
if (material->initWithFile(path))
|
||||
{
|
||||
material->_type = Sprite3DMaterial::MaterialType::CUSTOM;
|
||||
_materials[validfilename] = material;
|
||||
|
||||
return (Sprite3DMaterial*)material->clone();
|
||||
}
|
||||
CC_SAFE_DELETE(material);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Sprite3DMaterial* Sprite3DMaterial::createWithGLStateProgram(GLProgramState* programState)
|
||||
{
|
||||
CCASSERT(programState, "Invalid GL Program State");
|
||||
|
||||
auto mat = new (std::nothrow) Sprite3DMaterial();
|
||||
if (mat && mat->initWithGLProgramState(programState))
|
||||
{
|
||||
mat->_type = Sprite3DMaterial::MaterialType::CUSTOM;
|
||||
mat->autorelease();
|
||||
return mat;
|
||||
|
||||
}
|
||||
CC_SAFE_DELETE(mat);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Sprite3DMaterialCache::Sprite3DMaterialCache()
|
||||
{
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "base/ccTypes.h"
|
||||
#include "renderer/CCMaterial.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -38,6 +39,94 @@ NS_CC_BEGIN
|
|||
|
||||
class Texture2D;
|
||||
|
||||
/**
|
||||
* @brief Sprite3DMaterial: Material for Sprite3D.
|
||||
*/
|
||||
class CC_DLL Sprite3DMaterial : public Material
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Material type, there are mainly two types of materials. Built in materials and Custom material
|
||||
*/
|
||||
enum class MaterialType
|
||||
{
|
||||
//Built in material
|
||||
UNLIT, //unlit material
|
||||
UNLIT_NOTEX, //unlit material without texture
|
||||
VERTEX_LIT, // vertex lit
|
||||
DIFFUSE, // diffuse (pixel lighting)
|
||||
DIFFUSE_NOTEX, //diffuse (without texture)
|
||||
BUMPED_DIFFUSE, //bumped diffuse
|
||||
|
||||
//Custom material
|
||||
CUSTOM, //Create from material file
|
||||
};
|
||||
|
||||
/**
|
||||
* Get material type
|
||||
* @return Material type
|
||||
*/
|
||||
MaterialType getMaterialType() const { return _type; }
|
||||
|
||||
/**
|
||||
* Create built in material from material type
|
||||
* @param type Material type
|
||||
* @param skinned Has skin?
|
||||
* @return Created material
|
||||
*/
|
||||
static Sprite3DMaterial* createBuiltInMaterial(MaterialType type, bool skinned);
|
||||
|
||||
/**
|
||||
* Create material with file name, it creates material from cache if it is previously loaded
|
||||
* @param path Path of material file
|
||||
* @return Created material
|
||||
*/
|
||||
static Sprite3DMaterial* createWithFilename(const std::string& path);
|
||||
|
||||
/**
|
||||
* Create material with GLProgramState
|
||||
* @param programState GLProgramState instance
|
||||
* @return Created material
|
||||
*/
|
||||
static Sprite3DMaterial* createWithGLStateProgram(GLProgramState* programState);
|
||||
|
||||
/**
|
||||
* Create all build in materials
|
||||
*/
|
||||
static void createBuiltInMaterial();
|
||||
|
||||
/**
|
||||
* Release all built in materials
|
||||
*/
|
||||
static void releaseBuiltInMaterial();
|
||||
|
||||
/**
|
||||
* Release all cached materials
|
||||
*/
|
||||
static void releaseCachedMaterial();
|
||||
|
||||
/**
|
||||
* Clone material
|
||||
*/
|
||||
virtual Material* clone() const override;
|
||||
|
||||
protected:
|
||||
|
||||
MaterialType _type;
|
||||
static std::unordered_map<std::string, Sprite3DMaterial*> _materials; //cached material
|
||||
static Sprite3DMaterial* _unLitMaterial;
|
||||
static Sprite3DMaterial* _unLitNoTexMaterial;
|
||||
static Sprite3DMaterial* _vertexLitMaterial;
|
||||
static Sprite3DMaterial* _diffuseMaterial;
|
||||
static Sprite3DMaterial* _diffuseNoTexMaterial;
|
||||
static Sprite3DMaterial* _bumpedDiffuseMaterial;
|
||||
|
||||
static Sprite3DMaterial* _unLitMaterialSkin;
|
||||
static Sprite3DMaterial* _vertexLitMaterialSkin;
|
||||
static Sprite3DMaterial* _diffuseMaterialSkin;
|
||||
static Sprite3DMaterial* _bumpedDiffuseMaterialSkin;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief the sprite3D material is only texture for now
|
||||
* @js NA
|
||||
|
|
|
@ -119,7 +119,7 @@ public:
|
|||
void setTechnique(const std::string& techniqueName);
|
||||
|
||||
/** returns a clone (deep-copy) of the material */
|
||||
Material* clone() const;
|
||||
virtual Material* clone() const;
|
||||
|
||||
protected:
|
||||
Material();
|
||||
|
@ -137,8 +137,8 @@ protected:
|
|||
bool parseSampler(GLProgramState* glProgramState, Properties* properties);
|
||||
bool parseUniform(GLProgramState* programState, Properties* properties, const char* uniformName);
|
||||
bool parseRenderState(RenderState* renderState, Properties* properties);
|
||||
|
||||
|
||||
|
||||
|
||||
// material name
|
||||
std::string _name;
|
||||
|
||||
|
|
|
@ -84,6 +84,8 @@ public:
|
|||
* Returns the topmost RenderState in the hierarchy below the given RenderState.
|
||||
*/
|
||||
RenderState* getTopmost(RenderState* below);
|
||||
|
||||
void setParent(RenderState* parent) { _parent = parent; }
|
||||
|
||||
enum Blend
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Sprite3DTest.h"
|
||||
#include "DrawNode3D.h"
|
||||
#include "2d/CCCameraBackgroundBrush.h"
|
||||
#include "3d/CCSprite3DMaterial.h"
|
||||
#include "3d/CCMotionStreak3D.h"
|
||||
|
||||
#include "extensions/Particle3D/PU/CCPUParticleSystem3D.h"
|
||||
|
@ -64,6 +65,7 @@ Sprite3DTests::Sprite3DTests()
|
|||
ADD_TEST_CASE(Sprite3DTestMeshLight);
|
||||
ADD_TEST_CASE(Animate3DCallbackTest);
|
||||
ADD_TEST_CASE(CameraBackgroundClearTest);
|
||||
ADD_TEST_CASE(Sprite3DVertexColorTest);
|
||||
ADD_TEST_CASE(MotionStreak3DTest);
|
||||
};
|
||||
|
||||
|
@ -78,6 +80,11 @@ std::string Sprite3DTestDemo::title() const
|
|||
return "No title";
|
||||
}
|
||||
|
||||
Sprite3DTestDemo::~Sprite3DTestDemo()
|
||||
{
|
||||
Sprite3DMaterial::releaseCachedMaterial();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
// Sprite3DForceDepthTest
|
||||
|
@ -235,42 +242,12 @@ Sprite3DUVAnimationTest::Sprite3DUVAnimationTest()
|
|||
|
||||
//create cylinder
|
||||
auto cylinder = Sprite3D::create("Sprite3DTest/cylinder.c3b");
|
||||
|
||||
//create and set our custom shader
|
||||
auto shader =GLProgram::createWithFilenames("Sprite3DTest/cylinder.vert","Sprite3DTest/cylinder.frag");
|
||||
_state = GLProgramState::create(shader);
|
||||
cylinder->setGLProgramState(_state);
|
||||
|
||||
_state->setUniformFloat("offset",_cylinder_texture_offset);
|
||||
_state->setUniformFloat("duration",_shining_duraion);
|
||||
//pass mesh's attribute to shader
|
||||
long offset = 0;
|
||||
auto attributeCount = cylinder->getMesh()->getMeshVertexAttribCount();
|
||||
for (auto i = 0; i < attributeCount; i++) {
|
||||
auto meshattribute = cylinder->getMesh()->getMeshVertexAttribute(i);
|
||||
_state->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
cylinder->getMesh()->getVertexSizeInBytes(),
|
||||
(GLvoid*)offset);
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
|
||||
//create the second texture for cylinder
|
||||
auto shining_texture = Director::getInstance()->getTextureCache()->addImage("Sprite3DTest/caustics.png");
|
||||
Texture2D::TexParams tRepeatParams;//set texture parameters
|
||||
tRepeatParams.magFilter = GL_NEAREST;
|
||||
tRepeatParams.minFilter = GL_NEAREST;
|
||||
tRepeatParams.wrapS = GL_REPEAT;
|
||||
tRepeatParams.wrapT = GL_REPEAT;
|
||||
shining_texture->setTexParameters(tRepeatParams);
|
||||
//pass the texture sampler to our custom shader
|
||||
_state->setUniformTexture("caustics",shining_texture);
|
||||
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/UVAnimation.material");
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
cylinder->setMaterial(mat);
|
||||
|
||||
this->addChild(cylinder);
|
||||
this->setCameraMask(2);
|
||||
this->setCameraMask(2);
|
||||
this->addChild(camera);
|
||||
|
||||
//adjust cylinder's position & rotation
|
||||
|
@ -282,24 +259,12 @@ Sprite3DUVAnimationTest::Sprite3DUVAnimationTest()
|
|||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
[=](EventCustom*)
|
||||
{
|
||||
auto glProgram = _state->getGLProgram();
|
||||
glProgram->reset();
|
||||
glProgram->initWithFilenames("Sprite3DTest/cylinder.vert", "Sprite3DTest/cylinder.frag");
|
||||
glProgram->link();
|
||||
glProgram->updateUniforms();
|
||||
auto shining_texture = Director::getInstance()->getTextureCache()->addImage("Sprite3DTest/caustics.png");
|
||||
Texture2D::TexParams tRepeatParams;//set texture parameters
|
||||
tRepeatParams.magFilter = GL_NEAREST;
|
||||
tRepeatParams.minFilter = GL_NEAREST;
|
||||
tRepeatParams.wrapS = GL_REPEAT;
|
||||
tRepeatParams.wrapT = GL_REPEAT;
|
||||
shining_texture->setTexParameters(tRepeatParams);
|
||||
//pass the texture sampler to our custom shader
|
||||
_state->setUniformTexture("caustics",shining_texture);
|
||||
_state->setUniformFloat("offset",_cylinder_texture_offset);
|
||||
_state->setUniformFloat("duration",_shining_duraion);
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/UVAnimation.material");
|
||||
|
||||
cylinder->setMaterial(mat);
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
|
@ -372,35 +337,11 @@ Sprite3DFakeShadowTest::Sprite3DFakeShadowTest()
|
|||
_plane = Sprite3D::create("Sprite3DTest/plane.c3t");
|
||||
_plane->setRotation3D(Vec3(90,0,0));
|
||||
|
||||
// use custom shader
|
||||
auto shader =GLProgram::createWithFilenames("Sprite3DTest/simple_shadow.vert","Sprite3DTest/simple_shadow.frag");
|
||||
_state = GLProgramState::create(shader);
|
||||
_plane->setGLProgramState(_state);
|
||||
|
||||
//pass mesh's attribute to shader
|
||||
long offset = 0;
|
||||
auto attributeCount = _plane->getMesh()->getMeshVertexAttribCount();
|
||||
for (auto i = 0; i < attributeCount; i++) {
|
||||
auto meshattribute = _plane->getMesh()->getMeshVertexAttribute(i);
|
||||
_state->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
_plane->getMesh()->getVertexSizeInBytes(),
|
||||
(GLvoid*)offset);
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/FakeShadow.material");
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
_plane->setMaterial(mat);
|
||||
_state->setUniformMat4("u_model_matrix",_plane->getNodeToWorldTransform());
|
||||
|
||||
//create shadow texture
|
||||
auto shadowTexture = Director::getInstance()->getTextureCache()->addImage("Sprite3DTest/shadowCircle.png");
|
||||
Texture2D::TexParams tRepeatParams;//set texture parameters
|
||||
tRepeatParams.magFilter = GL_LINEAR;
|
||||
tRepeatParams.minFilter = GL_LINEAR;
|
||||
tRepeatParams.wrapS = GL_CLAMP_TO_EDGE;
|
||||
tRepeatParams.wrapT = GL_CLAMP_TO_EDGE;
|
||||
shadowTexture->setTexParameters(tRepeatParams);
|
||||
_state->setUniformTexture("u_shadowTexture",shadowTexture);
|
||||
layer->addChild(_plane);
|
||||
|
||||
//create the orc
|
||||
|
@ -409,7 +350,7 @@ Sprite3DFakeShadowTest::Sprite3DFakeShadowTest()
|
|||
_orc->setRotation3D(Vec3(0,180,0));
|
||||
_orc->setPosition3D(Vec3(0,0,10));
|
||||
_targetPos = _orc->getPosition3D();
|
||||
_plane->getGLProgramState()->setUniformVec3("u_target_pos",_orc->getPosition3D());
|
||||
_state->setUniformVec3("u_target_pos", _orc->getPosition3D());
|
||||
layer->addChild(_orc);
|
||||
layer->addChild(_camera);
|
||||
layer->setCameraMask(2);
|
||||
|
@ -420,23 +361,11 @@ Sprite3DFakeShadowTest::Sprite3DFakeShadowTest()
|
|||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
{
|
||||
auto glProgram = _state->getGLProgram();
|
||||
glProgram->reset();
|
||||
glProgram->initWithFilenames("Sprite3DTest/simple_shadow.vert","Sprite3DTest/simple_shadow.frag");
|
||||
glProgram->link();
|
||||
glProgram->updateUniforms();
|
||||
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/FakeShadow.material");
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
_plane->setMaterial(mat);
|
||||
_state->setUniformMat4("u_model_matrix",_plane->getNodeToWorldTransform());
|
||||
|
||||
//create shadow texture
|
||||
auto shadowTexture = Director::getInstance()->getTextureCache()->addImage("Sprite3DTest/shadowCircle.png");
|
||||
Texture2D::TexParams tRepeatParams;//set texture parameters
|
||||
tRepeatParams.magFilter = GL_LINEAR;
|
||||
tRepeatParams.minFilter = GL_LINEAR;
|
||||
tRepeatParams.wrapS = GL_CLAMP_TO_EDGE;
|
||||
tRepeatParams.wrapT = GL_CLAMP_TO_EDGE;
|
||||
shadowTexture->setTexParameters(tRepeatParams);
|
||||
_state->setUniformTexture("u_shadowTexture",shadowTexture);
|
||||
_state->setUniformVec3("u_target_pos", _orc->getPosition3D());
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
|
@ -524,7 +453,7 @@ void Sprite3DFakeShadowTest::move3D(float elapsedTime)
|
|||
offset.x=offset.x;
|
||||
offset.z=offset.z;
|
||||
//pass the newest orc position
|
||||
_plane->getGLProgramState()->setUniformVec3("u_target_pos",_orc->getPosition3D());
|
||||
_state->setUniformVec3("u_target_pos",_orc->getPosition3D());
|
||||
}
|
||||
|
||||
void Sprite3DFakeShadowTest::updateState(float elapsedTime)
|
||||
|
@ -620,40 +549,24 @@ Sprite3DBasicToonShaderTest::Sprite3DBasicToonShaderTest()
|
|||
_camera->setCameraFlag(CameraFlag::USER1);
|
||||
// create a teapot
|
||||
auto teapot = Sprite3D::create("Sprite3DTest/teapot.c3b");
|
||||
//create and set our custom shader
|
||||
auto shader =GLProgram::createWithFilenames("Sprite3DTest/toon.vert","Sprite3DTest/toon.frag");
|
||||
_state = GLProgramState::create(shader);
|
||||
teapot->setGLProgramState(_state);
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/BasicToon.material");
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
teapot->setMaterial(mat);
|
||||
|
||||
teapot->setPosition3D(Vec3(0,-5,-20));
|
||||
teapot->setRotation3D(Vec3(-90,180,0));
|
||||
auto rotate_action = RotateBy::create(1.5,Vec3(0,30,0));
|
||||
teapot->runAction(RepeatForever::create(rotate_action));
|
||||
//pass mesh's attribute to shader
|
||||
long offset = 0;
|
||||
auto attributeCount = teapot->getMesh()->getMeshVertexAttribCount();
|
||||
for (auto i = 0; i < attributeCount; i++) {
|
||||
auto meshattribute = teapot->getMesh()->getMeshVertexAttribute(i);
|
||||
_state->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
teapot->getMesh()->getVertexSizeInBytes(),
|
||||
(GLvoid*)offset);
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
addChild(teapot);
|
||||
addChild(_camera);
|
||||
setCameraMask(2);
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
[=](EventCustom*)
|
||||
{
|
||||
auto glProgram = _state->getGLProgram();
|
||||
glProgram->reset();
|
||||
glProgram->initWithFilenames("Sprite3DTest/toon.vert","Sprite3DTest/toon.frag");
|
||||
glProgram->link();
|
||||
glProgram->updateUniforms();
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/BasicToon.material");
|
||||
_state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
teapot->setMaterial(mat);
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
|
@ -822,299 +735,6 @@ std::string Sprite3DHitTest::subtitle() const
|
|||
return "Tap Sprite3D and Drag";
|
||||
}
|
||||
|
||||
static int tuple_sort( const std::tuple<ssize_t,Effect3D*,CustomCommand> &tuple1, const std::tuple<ssize_t,Effect3D*,CustomCommand> &tuple2 )
|
||||
{
|
||||
return std::get<0>(tuple1) < std::get<0>(tuple2);
|
||||
}
|
||||
|
||||
EffectSprite3D* EffectSprite3D::createFromObjFileAndTexture(const std::string &objFilePath, const std::string &textureFilePath)
|
||||
{
|
||||
auto sprite = new (std::nothrow) EffectSprite3D();
|
||||
if (sprite && sprite->initWithFile(objFilePath))
|
||||
{
|
||||
sprite->autorelease();
|
||||
if(textureFilePath.size() > 0)
|
||||
sprite->setTexture(textureFilePath);
|
||||
return sprite;
|
||||
}
|
||||
CC_SAFE_DELETE(sprite);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EffectSprite3D* EffectSprite3D::create(const std::string &path)
|
||||
{
|
||||
if (path.length() < 4)
|
||||
CCASSERT(false, "improper name specified when creating Sprite3D");
|
||||
|
||||
auto sprite = new (std::nothrow) EffectSprite3D();
|
||||
if (sprite && sprite->initWithFile(path))
|
||||
{
|
||||
sprite->autorelease();
|
||||
return sprite;
|
||||
}
|
||||
CC_SAFE_DELETE(sprite);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EffectSprite3D::EffectSprite3D()
|
||||
: _defaultEffect(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EffectSprite3D::~EffectSprite3D()
|
||||
{
|
||||
for(auto effect : _effects)
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(std::get<1>(effect));
|
||||
}
|
||||
CC_SAFE_RELEASE(_defaultEffect);
|
||||
}
|
||||
|
||||
void EffectSprite3D::setEffect3D(Effect3D *effect)
|
||||
{
|
||||
if(_defaultEffect == effect) return;
|
||||
CC_SAFE_RETAIN(effect);
|
||||
CC_SAFE_RELEASE(_defaultEffect);
|
||||
_defaultEffect = effect;
|
||||
}
|
||||
|
||||
void EffectSprite3D::addEffect(Effect3DOutline* effect, ssize_t order)
|
||||
{
|
||||
if(nullptr == effect) return;
|
||||
effect->retain();
|
||||
effect->setTarget(this);
|
||||
|
||||
_effects.push_back(std::make_tuple(order,effect,CustomCommand()));
|
||||
|
||||
std::sort(std::begin(_effects), std::end(_effects), tuple_sort);
|
||||
}
|
||||
|
||||
const std::string Effect3DOutline::_vertShaderFile = "Shaders3D/OutLine.vert";
|
||||
const std::string Effect3DOutline::_fragShaderFile = "Shaders3D/OutLine.frag";
|
||||
const std::string Effect3DOutline::_keyInGLProgramCache = "Effect3DLibrary_Outline";
|
||||
|
||||
const std::string Effect3DOutline::_vertSkinnedShaderFile = "Shaders3D/SkinnedOutline.vert";
|
||||
const std::string Effect3DOutline::_fragSkinnedShaderFile = "Shaders3D/OutLine.frag";
|
||||
const std::string Effect3DOutline::_keySkinnedInGLProgramCache = "Effect3DLibrary_Outline";
|
||||
GLProgram* Effect3DOutline::getOrCreateProgram(bool isSkinned /* = false */ )
|
||||
{
|
||||
if(isSkinned)
|
||||
{
|
||||
auto program = GLProgramCache::getInstance()->getGLProgram(_keySkinnedInGLProgramCache);
|
||||
if(program == nullptr)
|
||||
{
|
||||
program = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile);
|
||||
GLProgramCache::getInstance()->addGLProgram(program, _keySkinnedInGLProgramCache);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto program = GLProgramCache::getInstance()->getGLProgram(_keyInGLProgramCache);
|
||||
if(program == nullptr)
|
||||
{
|
||||
program = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile);
|
||||
GLProgramCache::getInstance()->addGLProgram(program, _keyInGLProgramCache);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Effect3DOutline* Effect3DOutline::create()
|
||||
{
|
||||
Effect3DOutline* effect = new (std::nothrow) Effect3DOutline();
|
||||
if(effect && effect->init())
|
||||
{
|
||||
effect->autorelease();
|
||||
return effect;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC_SAFE_DELETE(effect);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Effect3DOutline::init()
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Effect3DOutline::Effect3DOutline()
|
||||
: _outlineColor(1, 1, 1)
|
||||
, _outlineWidth(1.0f)
|
||||
, _sprite(nullptr)
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
{
|
||||
auto glProgram = _glProgramState->getGLProgram();
|
||||
glProgram->reset();
|
||||
if(!_sprite->getMesh()->getSkin())
|
||||
glProgram->initWithFilenames(_vertShaderFile, _fragShaderFile);
|
||||
else
|
||||
glProgram->initWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile);
|
||||
glProgram->link();
|
||||
glProgram->updateUniforms();
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
Effect3DOutline::~Effect3DOutline()
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Effect3DOutline::setOutlineColor(const Vec3& color)
|
||||
{
|
||||
if(_outlineColor != color)
|
||||
{
|
||||
_outlineColor = color;
|
||||
if(_glProgramState)
|
||||
_glProgramState->setUniformVec3("OutLineColor", _outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
void Effect3DOutline::setOutlineWidth(float width)
|
||||
{
|
||||
if(_outlineWidth != width)
|
||||
{
|
||||
_outlineWidth = width;
|
||||
if(_glProgramState)
|
||||
_glProgramState->setUniformFloat("OutlineWidth", _outlineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void Effect3DOutline::setTarget(EffectSprite3D *sprite)
|
||||
{
|
||||
CCASSERT(nullptr != sprite && nullptr != sprite->getMesh(),"Error: Setting a null pointer or a null mesh EffectSprite3D to Effect3D");
|
||||
|
||||
if(sprite != _sprite)
|
||||
{
|
||||
GLProgram* glprogram;
|
||||
if(!sprite->getMesh()->getSkin())
|
||||
glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile);
|
||||
else
|
||||
glprogram = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile);
|
||||
|
||||
_glProgramState = GLProgramState::create(glprogram);
|
||||
|
||||
_glProgramState->retain();
|
||||
_glProgramState->setUniformVec3("OutLineColor", _outlineColor);
|
||||
_glProgramState->setUniformFloat("OutlineWidth", _outlineWidth);
|
||||
|
||||
|
||||
_sprite = sprite;
|
||||
|
||||
auto mesh = sprite->getMesh();
|
||||
long offset = 0;
|
||||
for (auto i = 0; i < mesh->getMeshVertexAttribCount(); i++)
|
||||
{
|
||||
auto meshvertexattrib = mesh->getMeshVertexAttribute(i);
|
||||
|
||||
_glProgramState->setVertexAttribPointer(s_attributeNames[meshvertexattrib.vertexAttrib],
|
||||
meshvertexattrib.size,
|
||||
meshvertexattrib.type,
|
||||
GL_FALSE,
|
||||
mesh->getVertexSizeInBytes(),
|
||||
(void*)offset);
|
||||
offset += meshvertexattrib.attribSizeBytes;
|
||||
}
|
||||
|
||||
Color4F color(_sprite->getDisplayedColor());
|
||||
color.a = _sprite->getDisplayedOpacity() / 255.0f;
|
||||
_glProgramState->setUniformVec4("u_color", Vec4(color.r, color.g, color.b, color.a));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Effect3DOutline::draw(const Mat4 &transform)
|
||||
{
|
||||
//draw
|
||||
Color4F color(_sprite->getDisplayedColor());
|
||||
color.a = _sprite->getDisplayedOpacity() / 255.0f;
|
||||
_glProgramState->setUniformVec4("u_color", Vec4(color.r, color.g, color.b, color.a));
|
||||
if(_sprite && _sprite->getMesh())
|
||||
{
|
||||
GLenum cullFace = GL_FRONT;
|
||||
if ((_sprite->getScaleX() * _sprite->getScaleY() * _sprite->getScaleZ()) < 0.0f)
|
||||
cullFace = GL_BACK;
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(cullFace);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
auto mesh = _sprite->getMesh();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBuffer());
|
||||
|
||||
auto skin = _sprite->getMesh()->getSkin();
|
||||
if(_sprite && skin)
|
||||
{
|
||||
_glProgramState->setUniformVec4v("u_matrixPalette", skin->getMatrixPaletteSize(), skin->getMatrixPalette());
|
||||
}
|
||||
|
||||
if(_sprite)
|
||||
_glProgramState->apply(transform);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->getIndexBuffer());
|
||||
glDrawElements(mesh->getPrimitiveType(), (GLsizei)mesh->getIndexCount(), mesh->getIndexFormat(), 0);
|
||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, mesh->getIndexCount());
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// Since cocos2d-x v3.7, users should avoid calling GL directly because it will break the internal GL state
|
||||
// But if users must call GL directly, they should update the state manually,
|
||||
RenderState::StateBlock::_defaultState->setDepthTest(false);
|
||||
RenderState::StateBlock::_defaultState->setCullFaceSide(RenderState::CULL_FACE_SIDE_BACK);
|
||||
RenderState::StateBlock::_defaultState->setCullFace(false);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectSprite3D::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
|
||||
{
|
||||
for(auto &effect : _effects)
|
||||
{
|
||||
if(std::get<0>(effect) >=0)
|
||||
break;
|
||||
CustomCommand &cc = std::get<2>(effect);
|
||||
cc.func = CC_CALLBACK_0(Effect3D::draw,std::get<1>(effect),transform);
|
||||
renderer->addCommand(&cc);
|
||||
|
||||
}
|
||||
|
||||
if(!_defaultEffect)
|
||||
{
|
||||
Sprite3D::draw(renderer, transform, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
_command.init(_globalZOrder, transform, flags);
|
||||
_command.func = CC_CALLBACK_0(Effect3D::draw, _defaultEffect, transform);
|
||||
renderer->addCommand(&_command);
|
||||
}
|
||||
|
||||
for(auto &effect : _effects)
|
||||
{
|
||||
if(std::get<0>(effect) <=0)
|
||||
continue;
|
||||
CustomCommand &cc = std::get<2>(effect);
|
||||
cc.func = CC_CALLBACK_0(Effect3D::draw,std::get<1>(effect),transform);
|
||||
renderer->addCommand(&cc);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Sprite3DEffectTest::Sprite3DEffectTest()
|
||||
{
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
|
@ -1123,6 +743,27 @@ Sprite3DEffectTest::Sprite3DEffectTest()
|
|||
auto listener = EventListenerTouchAllAtOnce::create();
|
||||
listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DEffectTest::onTouchesEnded, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
{
|
||||
auto material = Sprite3DMaterial::createWithFilename("Sprite3DTest/outline.material");
|
||||
material->setTechnique("outline_noneskinned");
|
||||
for(auto& sprite : _sprites)
|
||||
{
|
||||
sprite->setMaterial(material->clone());
|
||||
}
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
Sprite3DEffectTest::~Sprite3DEffectTest()
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Sprite3DEffectTest::title() const
|
||||
|
@ -1137,16 +778,10 @@ std::string Sprite3DEffectTest::subtitle() const
|
|||
void Sprite3DEffectTest::addNewSpriteWithCoords(Vec2 p)
|
||||
{
|
||||
//option 2: load obj and assign the texture
|
||||
auto sprite = EffectSprite3D::createFromObjFileAndTexture("Sprite3DTest/boss1.obj", "Sprite3DTest/boss.png");
|
||||
Effect3DOutline* effect = Effect3DOutline::create();
|
||||
sprite->addEffect(effect, -1);
|
||||
effect->setOutlineColor(Vec3(1,0,0));
|
||||
effect->setOutlineWidth(0.01f);
|
||||
|
||||
Effect3DOutline* effect2 = Effect3DOutline::create();
|
||||
sprite->addEffect(effect2, -2);
|
||||
effect2->setOutlineWidth(0.02f);
|
||||
effect2->setOutlineColor(Vec3(1,1,0));
|
||||
auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
|
||||
auto material = Sprite3DMaterial::createWithFilename("Sprite3DTest/outline.material");
|
||||
material->setTechnique("outline_noneskinned");
|
||||
sprite->setMaterial(material);
|
||||
sprite->setScale(6.f);
|
||||
|
||||
//add to scene
|
||||
|
@ -1171,6 +806,7 @@ void Sprite3DEffectTest::addNewSpriteWithCoords(Vec2 p)
|
|||
auto seq = Sequence::create( action, action_back, nullptr );
|
||||
|
||||
sprite->runAction( RepeatForever::create(seq) );
|
||||
_sprites.push_back(sprite);
|
||||
}
|
||||
|
||||
void Sprite3DEffectTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
|
||||
|
@ -1284,7 +920,7 @@ std::string Sprite3DWithSkinTest::subtitle() const
|
|||
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
|
||||
{
|
||||
std::string fileName = "Sprite3DTest/orc.c3b";
|
||||
auto sprite = EffectSprite3D::create(fileName);
|
||||
auto sprite = Sprite3D::create(fileName);
|
||||
sprite->setScale(3);
|
||||
sprite->setRotation3D(Vec3(0,180,0));
|
||||
sprite->setPosition( Vec2( p.x, p.y) );
|
||||
|
@ -1362,6 +998,27 @@ Sprite3DWithSkinOutlineTest::Sprite3DWithSkinOutlineTest()
|
|||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) );
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
{
|
||||
auto material = Sprite3DMaterial::createWithFilename("Sprite3DTest/outline.material");
|
||||
material->setTechnique("outline_skinned");
|
||||
for(auto& sprite : _sprites)
|
||||
{
|
||||
sprite->setMaterial(material->clone());
|
||||
}
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1);
|
||||
#endif
|
||||
}
|
||||
Sprite3DWithSkinOutlineTest::~Sprite3DWithSkinOutlineTest()
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
std::string Sprite3DWithSkinOutlineTest::title() const
|
||||
{
|
||||
|
@ -1376,19 +1033,11 @@ void Sprite3DWithSkinOutlineTest::addNewSpriteWithCoords(Vec2 p)
|
|||
{
|
||||
|
||||
std::string fileName = "Sprite3DTest/orc.c3b";
|
||||
auto sprite = EffectSprite3D::create(fileName);
|
||||
auto sprite = Sprite3D::create(fileName);
|
||||
|
||||
Effect3DOutline* effect = Effect3DOutline::create();
|
||||
effect->setOutlineColor(Vec3(1,0,0));
|
||||
effect->setOutlineWidth(0.01f);
|
||||
sprite->addEffect(effect, -1);
|
||||
|
||||
|
||||
Effect3DOutline* effect2 = Effect3DOutline::create();
|
||||
effect2->setOutlineWidth(0.02f);
|
||||
effect2->setOutlineColor(Vec3(1,1,0));
|
||||
sprite->addEffect(effect2, -2);
|
||||
|
||||
auto material = Sprite3DMaterial::createWithFilename("Sprite3DTest/outline.material");
|
||||
material->setTechnique("outline_skinned");
|
||||
sprite->setMaterial(material);
|
||||
|
||||
sprite->setScale(3);
|
||||
sprite->setRotation3D(Vec3(0,180,0));
|
||||
|
@ -2437,10 +2086,6 @@ void Sprite3DCubeMapTest::addNewSpriteWithCoords(Vec2 p)
|
|||
_teapot = Sprite3D::create("Sprite3DTest/teapot.c3b");
|
||||
_teapot->retain();
|
||||
|
||||
//create and set our custom shader
|
||||
auto shader = GLProgram::createWithFilenames("Sprite3DTest/cube_map.vert", "Sprite3DTest/cube_map.frag");
|
||||
auto state = GLProgramState::create(shader);
|
||||
|
||||
// create the second texture for cylinder
|
||||
_textureCube = TextureCube::create("Sprite3DTest/skybox/left.jpg", "Sprite3DTest/skybox/right.jpg",
|
||||
"Sprite3DTest/skybox/top.jpg", "Sprite3DTest/skybox/bottom.jpg",
|
||||
|
@ -2456,31 +2101,18 @@ void Sprite3DCubeMapTest::addNewSpriteWithCoords(Vec2 p)
|
|||
tRepeatParams.wrapT = GL_CLAMP_TO_EDGE;
|
||||
_textureCube->setTexParameters(tRepeatParams);
|
||||
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/CubeMap.material");
|
||||
auto state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
_teapot->setMaterial(mat);
|
||||
// pass the texture sampler to our custom shader
|
||||
state->setUniformTexture("u_cubeTex", _textureCube);
|
||||
|
||||
_teapot->setGLProgramState(state);
|
||||
_teapot->setPosition3D(Vec3(0, -5, 0));
|
||||
_teapot->setRotation3D(Vec3(-90, 180, 0));
|
||||
|
||||
auto rotate_action = RotateBy::create(1.5, Vec3(0, 30, 0));
|
||||
_teapot->runAction(RepeatForever::create(rotate_action));
|
||||
|
||||
//pass mesh's attribute to shader
|
||||
long offset = 0;
|
||||
auto attributeCount = _teapot->getMesh()->getMeshVertexAttribCount();
|
||||
for (auto i = 0; i < attributeCount; i++)
|
||||
{
|
||||
auto meshattribute = _teapot->getMesh()->getMeshVertexAttribute(i);
|
||||
state->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
_teapot->getMesh()->getVertexSizeInBytes(),
|
||||
(GLvoid*)offset);
|
||||
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
addChild(_teapot);
|
||||
|
||||
{
|
||||
|
@ -2494,31 +2126,32 @@ void Sprite3DCubeMapTest::addNewSpriteWithCoords(Vec2 p)
|
|||
|
||||
addChild(_camera);
|
||||
setCameraMask(2);
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[this](EventCustom*)
|
||||
{
|
||||
auto state = _teapot->getGLProgramState();
|
||||
auto glProgram = state->getGLProgram();
|
||||
glProgram->reset();
|
||||
glProgram->initWithFilenames("Sprite3DTest/cube_map.vert", "Sprite3DTest/cube_map.frag");
|
||||
glProgram->link();
|
||||
glProgram->updateUniforms();
|
||||
|
||||
_textureCube->reloadTexture();
|
||||
|
||||
Texture2D::TexParams tRepeatParams;
|
||||
tRepeatParams.magFilter = GL_NEAREST;
|
||||
tRepeatParams.minFilter = GL_NEAREST;
|
||||
tRepeatParams.wrapS = GL_CLAMP_TO_EDGE;
|
||||
tRepeatParams.wrapT = GL_CLAMP_TO_EDGE;
|
||||
_textureCube->setTexParameters(tRepeatParams);
|
||||
state->setUniformTexture("u_cubeTex", _textureCube);
|
||||
|
||||
_skyBox->reload();
|
||||
_skyBox->setTexture(_textureCube);
|
||||
});
|
||||
[this](EventCustom*)
|
||||
{
|
||||
CC_SAFE_RELEASE(_textureCube);
|
||||
_textureCube = TextureCube::create("Sprite3DTest/skybox/left.jpg", "Sprite3DTest/skybox/right.jpg",
|
||||
"Sprite3DTest/skybox/top.jpg", "Sprite3DTest/skybox/bottom.jpg",
|
||||
"Sprite3DTest/skybox/front.jpg", "Sprite3DTest/skybox/back.jpg");
|
||||
|
||||
_textureCube->retain();
|
||||
//set texture parameters
|
||||
Texture2D::TexParams tRepeatParams;
|
||||
tRepeatParams.magFilter = GL_LINEAR;
|
||||
tRepeatParams.minFilter = GL_LINEAR;
|
||||
tRepeatParams.wrapS = GL_CLAMP_TO_EDGE;
|
||||
tRepeatParams.wrapT = GL_CLAMP_TO_EDGE;
|
||||
_textureCube->setTexParameters(tRepeatParams);
|
||||
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/CubeMap.material");
|
||||
auto state = mat->getTechniqueByIndex(0)->getPassByIndex(0)->getGLProgramState();
|
||||
_teapot->setMaterial(mat);
|
||||
_skyBox->setTexture(_textureCube);
|
||||
// pass the texture sampler to our custom shader
|
||||
state->setUniformTexture("u_cubeTex", _textureCube);
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1);
|
||||
#endif
|
||||
}
|
||||
|
@ -2672,6 +2305,7 @@ Animate3DCallbackTest::Animate3DCallbackTest()
|
|||
node->setPosition3D(Vec3(mat.m[12] + 100, mat.m[13], mat.m[14]));
|
||||
((PUParticleSystem3D*)node)->startParticleSystem();
|
||||
}
|
||||
|
||||
|
||||
cocos2d::log("frame %d", info->frame);
|
||||
});
|
||||
|
@ -2725,6 +2359,56 @@ std::string Sprite3DTestMeshLight::subtitle() const
|
|||
return "";
|
||||
}
|
||||
|
||||
Sprite3DVertexColorTest::Sprite3DVertexColorTest()
|
||||
{
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
|
||||
auto sprite = Sprite3D::create("Sprite3DTest/box_VertexCol.c3t");
|
||||
sprite->setPosition(Vec2(0, 0));
|
||||
sprite->setScale(1.0f);
|
||||
sprite->setCameraMask(2);
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/VertexColor.material");
|
||||
sprite->setMaterial(mat);
|
||||
sprite->runAction(RepeatForever::create(RotateBy::create(1.0f, Vec3(10.0f, 50.0f, 10.0f))));
|
||||
|
||||
this->addChild(sprite);
|
||||
|
||||
//setup camera
|
||||
auto camera = Camera::createPerspective(40, s.width / s.height, 0.01f, 1000.f);
|
||||
camera->setCameraFlag(CameraFlag::USER1);
|
||||
camera->setPosition3D(Vec3(0.0f, 0.0f, 10.f));
|
||||
camera->lookAt(Vec3(0.f, 0.f, 0.f));
|
||||
addChild(camera);
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
_backToForegroundListener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND,
|
||||
[=](EventCustom*)
|
||||
{
|
||||
auto mat = Sprite3DMaterial::createWithFilename("Sprite3DTest/VertexColor.material");
|
||||
sprite->setMaterial(mat);
|
||||
}
|
||||
);
|
||||
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
Sprite3DVertexColorTest::~Sprite3DVertexColorTest()
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Sprite3DVertexColorTest::title() const
|
||||
{
|
||||
return "Testing Vertex Color";
|
||||
}
|
||||
|
||||
std::string Sprite3DVertexColorTest::subtitle() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
CameraBackgroundClearTest::CameraBackgroundClearTest()
|
||||
{
|
||||
TTFConfig ttfConfig("fonts/arial.ttf", 20);
|
||||
|
@ -2783,6 +2467,7 @@ std::string CameraBackgroundClearTest::title() const
|
|||
{
|
||||
return "Camera Background Clear Brush";
|
||||
}
|
||||
|
||||
std::string CameraBackgroundClearTest::subtitle() const
|
||||
{
|
||||
return "";
|
||||
|
|
|
@ -45,6 +45,8 @@ class Sprite3DTestDemo : public TestCase
|
|||
public:
|
||||
// overrides
|
||||
virtual std::string title() const override;
|
||||
|
||||
virtual ~Sprite3DTestDemo();
|
||||
};
|
||||
|
||||
class Sprite3DForceDepthTest : public Sprite3DTestDemo
|
||||
|
@ -164,60 +166,6 @@ protected:
|
|||
#endif
|
||||
|
||||
};
|
||||
class EffectSprite3D;
|
||||
|
||||
class Effect3D : public cocos2d::Ref
|
||||
{
|
||||
public:
|
||||
virtual void draw(const cocos2d::Mat4 &transform) = 0;
|
||||
virtual void setTarget(EffectSprite3D *sprite) = 0;
|
||||
protected:
|
||||
Effect3D() : _glProgramState(nullptr) {}
|
||||
virtual ~Effect3D()
|
||||
{
|
||||
CC_SAFE_RELEASE(_glProgramState);
|
||||
}
|
||||
protected:
|
||||
cocos2d::GLProgramState* _glProgramState;
|
||||
};
|
||||
|
||||
class Effect3DOutline: public Effect3D
|
||||
{
|
||||
public:
|
||||
static Effect3DOutline* create();
|
||||
|
||||
void setOutlineColor(const cocos2d::Vec3& color);
|
||||
|
||||
void setOutlineWidth(float width);
|
||||
|
||||
virtual void draw(const cocos2d::Mat4 &transform) override;
|
||||
virtual void setTarget(EffectSprite3D *sprite) override;
|
||||
protected:
|
||||
|
||||
Effect3DOutline();
|
||||
virtual ~Effect3DOutline();
|
||||
|
||||
bool init();
|
||||
|
||||
cocos2d::Vec3 _outlineColor;
|
||||
float _outlineWidth;
|
||||
//weak reference
|
||||
EffectSprite3D* _sprite;
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
cocos2d::EventListenerCustom* _backToForegroundListener;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static const std::string _vertShaderFile;
|
||||
static const std::string _fragShaderFile;
|
||||
static const std::string _keyInGLProgramCache;
|
||||
|
||||
static const std::string _vertSkinnedShaderFile;
|
||||
static const std::string _fragSkinnedShaderFile;
|
||||
static const std::string _keySkinnedInGLProgramCache;
|
||||
|
||||
static cocos2d::GLProgram* getOrCreateProgram(bool isSkinned = false);
|
||||
};
|
||||
|
||||
class Sprite3DHitTest : public Sprite3DTestDemo
|
||||
{
|
||||
|
@ -228,35 +176,25 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class EffectSprite3D : public cocos2d::Sprite3D
|
||||
{
|
||||
public:
|
||||
static EffectSprite3D* createFromObjFileAndTexture(const std::string& objFilePath, const std::string& textureFilePath);
|
||||
static EffectSprite3D* create(const std::string& path);
|
||||
|
||||
void setEffect3D(Effect3D* effect);
|
||||
void addEffect(Effect3DOutline* effect, ssize_t order);
|
||||
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
|
||||
protected:
|
||||
EffectSprite3D();
|
||||
virtual ~EffectSprite3D();
|
||||
|
||||
std::vector<std::tuple<ssize_t,Effect3D*, cocos2d::CustomCommand>> _effects;
|
||||
Effect3D* _defaultEffect;
|
||||
cocos2d::CustomCommand _command;
|
||||
};
|
||||
|
||||
class Sprite3DEffectTest : public Sprite3DTestDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Sprite3DEffectTest);
|
||||
Sprite3DEffectTest();
|
||||
virtual ~Sprite3DEffectTest();
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
void addNewSpriteWithCoords(cocos2d::Vec2 p);
|
||||
|
||||
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
|
||||
|
||||
protected:
|
||||
std::vector<cocos2d::Sprite3D*> _sprites;
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
cocos2d::EventListenerCustom* _backToForegroundListener;
|
||||
#endif
|
||||
};
|
||||
|
||||
class AsyncLoadSprite3DTest : public Sprite3DTestDemo
|
||||
|
@ -301,12 +239,20 @@ class Sprite3DWithSkinOutlineTest : public Sprite3DTestDemo
|
|||
public:
|
||||
CREATE_FUNC(Sprite3DWithSkinOutlineTest);
|
||||
Sprite3DWithSkinOutlineTest();
|
||||
virtual ~Sprite3DWithSkinOutlineTest();
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
void addNewSpriteWithCoords(cocos2d::Vec2 p);
|
||||
|
||||
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
|
||||
|
||||
protected:
|
||||
std::vector<cocos2d::Sprite3D*> _sprites;
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
cocos2d::EventListenerCustom* _backToForegroundListener;
|
||||
#endif
|
||||
};
|
||||
|
||||
class Animate3DTest : public Sprite3DTestDemo
|
||||
|
@ -607,6 +553,22 @@ protected:
|
|||
cocos2d::Label* _label;
|
||||
};
|
||||
|
||||
class Sprite3DVertexColorTest : public Sprite3DTestDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Sprite3DVertexColorTest);
|
||||
Sprite3DVertexColorTest();
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
virtual ~Sprite3DVertexColorTest();
|
||||
protected:
|
||||
cocos2d::Sprite3D* _sprite;
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
cocos2d::EventListenerCustom* _backToForegroundListener;
|
||||
#endif
|
||||
};
|
||||
|
||||
class MotionStreak3DTest : public Sprite3DTestDemo
|
||||
{
|
||||
public:
|
||||
|
@ -620,4 +582,5 @@ protected:
|
|||
cocos2d::Sprite3D* _sprite;
|
||||
cocos2d::MotionStreak3D* _streak;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material BasicToon
|
||||
{
|
||||
technique normal
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Sprite3DTest/toon.vert
|
||||
fragmentShader = Sprite3DTest/toon.frag
|
||||
|
||||
sampler u_sampler0
|
||||
{
|
||||
path = Sprite3DTest/teapot.png
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material CubeMap
|
||||
{
|
||||
technique normal
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Sprite3DTest/cube_map.vert
|
||||
fragmentShader = Sprite3DTest/cube_map.frag
|
||||
// sampler:
|
||||
// responsible for setting the texture and its parameters
|
||||
// the Id of the sampler is the uniform name
|
||||
sampler u_cubeTex
|
||||
{
|
||||
path = Sprite3DTest/skybox/left.jpg
|
||||
wrapS = GL_CLAMP_TO_EDGE
|
||||
wrapT = GL_CLAMP_TO_EDGE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material FakeShadow
|
||||
{
|
||||
technique normal
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Sprite3DTest/simple_shadow.vert
|
||||
fragmentShader = Sprite3DTest/simple_shadow.frag
|
||||
// sampler:
|
||||
// responsible for setting the texture and its parameters
|
||||
// the Id of the sampler is the uniform name
|
||||
sampler u_sampler0
|
||||
{
|
||||
path = Sprite3DTest/plane.png
|
||||
wrapS = REPEAT
|
||||
wrapT = REPEAT
|
||||
}
|
||||
|
||||
sampler u_sampler1
|
||||
{
|
||||
path = Sprite3DTest/shadowCircle.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material UVAnimation
|
||||
{
|
||||
technique normal
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Sprite3DTest/cylinder.vert
|
||||
fragmentShader = Sprite3DTest/cylinder.frag
|
||||
// sampler:
|
||||
// responsible for setting the texture and its parameters
|
||||
// the Id of the sampler is the uniform name
|
||||
sampler u_sampler0
|
||||
{
|
||||
path = Sprite3DTest/dragon.png
|
||||
wrapS = REPEAT
|
||||
wrapT = REPEAT
|
||||
}
|
||||
|
||||
sampler u_sampler1
|
||||
{
|
||||
path = Sprite3DTest/caustics.png
|
||||
wrapS = REPEAT
|
||||
wrapT = REPEAT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifdef GL_ES
|
||||
precision lowp float;
|
||||
#endif
|
||||
|
||||
varying vec4 v_fragmentColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = v_fragmentColor;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material VertexColor
|
||||
{
|
||||
technique normal
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
depthTest = true
|
||||
depthWrite = true
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Sprite3DTest/VertexColor.vert
|
||||
fragmentShader = Sprite3DTest/VertexColor.frag
|
||||
// sampler:
|
||||
// responsible for setting the texture and its parameters
|
||||
// the Id of the sampler is the uniform name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec4 a_color;
|
||||
|
||||
#ifdef GL_ES
|
||||
varying lowp vec4 v_fragmentColor;
|
||||
#else
|
||||
varying vec4 v_fragmentColor;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = CC_MVPMatrix * a_position;
|
||||
v_fragmentColor = a_color;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
"version": "0.7",
|
||||
"id": "",
|
||||
"meshes": [
|
||||
{
|
||||
"attributes": [{
|
||||
"size": 3,
|
||||
"type": "GL_FLOAT",
|
||||
"attribute": "VERTEX_ATTRIB_POSITION"
|
||||
}, {
|
||||
"size": 3,
|
||||
"type": "GL_FLOAT",
|
||||
"attribute": "VERTEX_ATTRIB_NORMAL"
|
||||
}, {
|
||||
"size": 4,
|
||||
"type": "GL_FLOAT",
|
||||
"attribute": "VERTEX_ATTRIB_COLOR"
|
||||
}],
|
||||
"vertices": [
|
||||
0.500000, -0.500000, -0.500000, 0.000000, 0.000000, -1.000000, 1.000000, 0.000016, 0.000016, 1.000000,
|
||||
-0.500000, -0.500000, -0.500000, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 0.000000, 1.000000,
|
||||
0.500000, 0.500000, -0.500000, 0.000000, 0.000000, -1.000000, 1.000000, 0.000054, 1.000000, 1.000000,
|
||||
-0.500000, 0.500000, -0.500000, 0.000000, 0.000000, -1.000000, 0.000047, 0.000047, 1.000000, 1.000000,
|
||||
0.500000, 0.500000, 0.500000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
-0.500000, 0.500000, 0.500000, 0.000000, 0.000000, 1.000000, 0.000207, 1.000000, 1.000000, 1.000000,
|
||||
-0.500000, -0.500000, 0.500000, 0.000000, 0.000000, 1.000000, 0.000001, 1.000000, 0.000001, 1.000000,
|
||||
0.500000, -0.500000, 0.500000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000, 0.000064, 1.000000,
|
||||
0.500000, -0.500000, 0.500000, 0.000000, -1.000000, 0.000000, 1.000000, 1.000000, 0.000064, 1.000000,
|
||||
-0.500000, -0.500000, 0.500000, 0.000000, -1.000000, 0.000000, 0.000001, 1.000000, 0.000001, 1.000000,
|
||||
-0.500000, -0.500000, -0.500000, 0.000000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000,
|
||||
0.500000, -0.500000, -0.500000, 0.000000, -1.000000, 0.000000, 1.000000, 0.000016, 0.000016, 1.000000,
|
||||
0.500000, 0.500000, 0.500000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
0.500000, -0.500000, 0.500000, 1.000000, 0.000000, 0.000000, 1.000000, 1.000000, 0.000064, 1.000000,
|
||||
0.500000, -0.500000, -0.500000, 1.000000, 0.000000, 0.000000, 1.000000, 0.000016, 0.000016, 1.000000,
|
||||
0.500000, 0.500000, -0.500000, 1.000000, 0.000000, 0.000000, 1.000000, 0.000054, 1.000000, 1.000000,
|
||||
-0.500000, 0.500000, 0.500000, 0.000000, 1.000000, 0.000000, 0.000207, 1.000000, 1.000000, 1.000000,
|
||||
0.500000, 0.500000, 0.500000, 0.000000, 1.000000, 0.000000, 1.000000, 1.000000, 1.000000, 1.000000,
|
||||
0.500000, 0.500000, -0.500000, 0.000000, 1.000000, 0.000000, 1.000000, 0.000054, 1.000000, 1.000000,
|
||||
-0.500000, 0.500000, -0.500000, 0.000000, 1.000000, 0.000000, 0.000047, 0.000047, 1.000000, 1.000000,
|
||||
-0.500000, -0.500000, 0.500000, -1.000000, 0.000000, 0.000000, 0.000001, 1.000000, 0.000001, 1.000000,
|
||||
-0.500000, 0.500000, 0.500000, -1.000000, 0.000000, 0.000000, 0.000207, 1.000000, 1.000000, 1.000000,
|
||||
-0.500000, 0.500000, -0.500000, -1.000000, 0.000000, 0.000000, 0.000047, 0.000047, 1.000000, 1.000000,
|
||||
-0.500000, -0.500000, -0.500000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000
|
||||
],
|
||||
"parts": [
|
||||
{
|
||||
"id": "shape1_part1",
|
||||
"type": "TRIANGLES",
|
||||
"indices": [
|
||||
0, 1, 2, 1, 3, 2, 4, 5, 6, 4, 6, 7,
|
||||
8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15,
|
||||
16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23
|
||||
],
|
||||
"aabb": [-0.500000, -0.500000, -0.500000, 0.500000, 0.500000, 0.500000]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"id": "01 - Default",
|
||||
"ambient": [ 0.588235, 0.588235, 0.588235],
|
||||
"diffuse": [ 0.588235, 0.588235, 0.588235],
|
||||
"emissive": [ 0.000000, 0.000000, 0.000000],
|
||||
"opacity": 1.000000,
|
||||
"specular": [ 0.900000, 0.900000, 0.900000],
|
||||
"shininess": 2.000000,
|
||||
"textures": [
|
||||
{
|
||||
"id": "Map #1",
|
||||
"filename": "win",
|
||||
"type": "DIFFUSE",
|
||||
"wrapModeU": "REPEAT",
|
||||
"wrapModeV": "REPEAT"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "Box001",
|
||||
"skeleton": false,
|
||||
"transform": [ 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, -1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000],
|
||||
"parts": [
|
||||
{
|
||||
"meshpartid": "shape1_part1",
|
||||
"materialid": "01 - Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"animations": []
|
||||
}
|
|
@ -7,10 +7,11 @@ varying vec2 v_texture_coord;
|
|||
uniform vec4 u_color;
|
||||
uniform float offset;
|
||||
uniform float duration;
|
||||
uniform sampler2D caustics;
|
||||
uniform sampler2D u_sampler0;
|
||||
uniform sampler2D u_sampler1;
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = duration*vec4(0,0.8,0.4,1.0);
|
||||
//blend two texture
|
||||
gl_FragColor = u_color*texture2D(CC_Texture0, vec2(v_texture_coord.x- 2.0 * offset,v_texture_coord.y)) * vec4(0.3,0.3,0.3,1)+texture2D(caustics,vec2(v_texture_coord.x-offset,v_texture_coord.y)).r*color;
|
||||
gl_FragColor = u_color*texture2D(u_sampler0, vec2(v_texture_coord.x- 2.0 * offset,v_texture_coord.y)) * vec4(0.3,0.3,0.3,1)+texture2D(u_sampler1,vec2(v_texture_coord.x-offset,v_texture_coord.y)).r*color;
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
// A "Material" file can contain one or more materials
|
||||
material
|
||||
{
|
||||
|
||||
// This is another technique. It "outlines" the model without skin
|
||||
technique outline_noneskinned
|
||||
{
|
||||
// 1st pass:
|
||||
// creates a yellow outline of only the hull
|
||||
pass outline
|
||||
{
|
||||
renderState
|
||||
{
|
||||
cullFace = true
|
||||
cullFaceSide = FRONT
|
||||
depthTest = true
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/OutLine.vert
|
||||
fragmentShader = Shaders3D/OutLine.frag
|
||||
// Uniforms
|
||||
OutLineColor = 1,1,0
|
||||
OutlineWidth = 0.02
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd pass:
|
||||
// creates a blue outline of the borders
|
||||
pass outline thick
|
||||
{
|
||||
renderState
|
||||
{
|
||||
cullFace = true
|
||||
cullFaceSide = FRONT
|
||||
depthTest = true
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/OutLine.vert
|
||||
fragmentShader = Shaders3D/OutLine.frag
|
||||
// Uniforms
|
||||
OutLineColor = 1,0,0
|
||||
OutlineWidth = 0.01
|
||||
}
|
||||
}
|
||||
// 3rd pass
|
||||
// Renders the model "normally"
|
||||
// When a 'renderState' is not present it will use the default renderState
|
||||
pass normal
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/3d_position_tex.vert
|
||||
fragmentShader = Shaders3D/3d_color_tex.frag
|
||||
sampler u_sampler0
|
||||
{
|
||||
path = Sprite3DTest/boss.png
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is another technique. It "outlines" the model with skin
|
||||
technique outline_skinned
|
||||
{
|
||||
// 1st pass:
|
||||
// creates a yellow outline of only the hull
|
||||
pass outline
|
||||
{
|
||||
renderState
|
||||
{
|
||||
cullFace = true
|
||||
cullFaceSide = FRONT
|
||||
depthTest = true
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/SkinnedOutline.vert
|
||||
fragmentShader = Shaders3D/OutLine.frag
|
||||
// Uniforms
|
||||
OutLineColor = 1,1,0
|
||||
OutlineWidth = 0.02
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd pass:
|
||||
// creates a blue outline of the borders
|
||||
pass outline thick
|
||||
{
|
||||
renderState
|
||||
{
|
||||
cullFace = true
|
||||
cullFaceSide = FRONT
|
||||
depthTest = true
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/SkinnedOutline.vert
|
||||
fragmentShader = Shaders3D/OutLine.frag
|
||||
// Uniforms
|
||||
OutLineColor = 1,0,0
|
||||
OutlineWidth = 0.01
|
||||
}
|
||||
}
|
||||
// 3rd pass
|
||||
// Renders the model "normally"
|
||||
// When a 'renderState' is not present it will use the default renderState
|
||||
pass normal
|
||||
{
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders3D/3d_position_skin_tex.vert
|
||||
fragmentShader = Shaders3D/3d_color_tex.frag
|
||||
sampler u_sampler0
|
||||
{
|
||||
path = Sprite3DTest/monguger.tga
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ varying mediump vec4 v_position;
|
|||
varying vec2 v_texture_coord;
|
||||
varying vec4 v_position;
|
||||
#endif
|
||||
uniform sampler2D u_shadowTexture;
|
||||
uniform sampler2D u_sampler0;
|
||||
uniform sampler2D u_sampler1;
|
||||
uniform vec3 u_target_pos;
|
||||
uniform vec4 u_color;
|
||||
void main(void)
|
||||
|
@ -18,5 +19,5 @@ void main(void)
|
|||
coord.x = dot(v_position.xyz - u_target_pos, UVector) + 0.5;
|
||||
coord.y = dot(v_position.xyz - u_target_pos, VVector) + 0.5;
|
||||
|
||||
gl_FragColor = u_color*texture2D(CC_Texture0,v_texture_coord)*texture2D(u_shadowTexture,coord);
|
||||
gl_FragColor = u_color*texture2D(u_sampler0,v_texture_coord)*texture2D(u_sampler1,coord);
|
||||
}
|
|
@ -4,6 +4,7 @@ varying mediump vec2 v_texture_coord;
|
|||
varying vec2 v_texture_coord;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
uniform sampler2D u_sampler0;
|
||||
varying vec3 v_normal;
|
||||
void main(void)
|
||||
{
|
||||
|
@ -12,7 +13,7 @@ void main(void)
|
|||
vec3 light_color = vec3(1,1,1);
|
||||
vec3 normal = normalize(v_normal);
|
||||
float diffuse_factor = dot(normal,-light_direction);
|
||||
vec4 diffuse_color = texture2D(CC_Texture0,v_texture_coord);
|
||||
vec4 diffuse_color = texture2D(u_sampler0,v_texture_coord);
|
||||
|
||||
if (diffuse_factor > 0.95) diffuse_factor=1.0;
|
||||
else if (diffuse_factor > 0.75) diffuse_factor = 0.8;
|
||||
|
|
Loading…
Reference in New Issue