mirror of https://github.com/axmolengine/axmol.git
Merge pull request #11789 from ricardoquesada/material_properties
Material uses new file format
This commit is contained in:
commit
17265fe9e6
|
@ -1452,6 +1452,10 @@
|
|||
503DD8F81926B0DB00CD74DD /* CCIMEDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8F31926B0DB00CD74DD /* CCIMEDispatcher.cpp */; };
|
||||
503DD8F91926B0DB00CD74DD /* CCIMEDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */; };
|
||||
503DD8FA1926B0DB00CD74DD /* CCIMEDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */; };
|
||||
505385021B01887A00793096 /* CCProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 505385001B01887A00793096 /* CCProperties.h */; };
|
||||
505385031B01887A00793096 /* CCProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 505385001B01887A00793096 /* CCProperties.h */; };
|
||||
505385041B01887A00793096 /* CCProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505385011B01887A00793096 /* CCProperties.cpp */; };
|
||||
505385051B01887A00793096 /* CCProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505385011B01887A00793096 /* CCProperties.cpp */; };
|
||||
50643BD419BFAECF00EF68ED /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD319BFAECF00EF68ED /* CCGL.h */; };
|
||||
50643BD519BFAECF00EF68ED /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD319BFAECF00EF68ED /* CCGL.h */; };
|
||||
50643BD619BFAEDA00EF68ED /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5091A7A219BFABA800AC8789 /* CCPlatformDefine.h */; };
|
||||
|
@ -4238,6 +4242,8 @@
|
|||
503DD8F21926B0DB00CD74DD /* CCIMEDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCIMEDelegate.h; path = ../base/CCIMEDelegate.h; sourceTree = "<group>"; };
|
||||
503DD8F31926B0DB00CD74DD /* CCIMEDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCIMEDispatcher.cpp; path = ../base/CCIMEDispatcher.cpp; sourceTree = "<group>"; };
|
||||
503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCIMEDispatcher.h; path = ../base/CCIMEDispatcher.h; sourceTree = "<group>"; };
|
||||
505385001B01887A00793096 /* CCProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCProperties.h; path = ../base/CCProperties.h; sourceTree = "<group>"; };
|
||||
505385011B01887A00793096 /* CCProperties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCProperties.cpp; path = ../base/CCProperties.cpp; sourceTree = "<group>"; };
|
||||
50643BD319BFAECF00EF68ED /* CCGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGL.h; sourceTree = "<group>"; };
|
||||
50643BD719BFAF4400EF68ED /* CCApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCApplication.h; sourceTree = "<group>"; };
|
||||
50643BD819BFAF4400EF68ED /* CCStdC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCStdC.h; sourceTree = "<group>"; };
|
||||
|
@ -5606,6 +5612,8 @@
|
|||
1A5700A2180BC5E60088DEC7 /* base */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
505385001B01887A00793096 /* CCProperties.h */,
|
||||
505385011B01887A00793096 /* CCProperties.cpp */,
|
||||
B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */,
|
||||
B63990CB1A490AFE00B07923 /* CCAsyncTaskPool.h */,
|
||||
D0FD03391A3B51AA00825BB5 /* allocator */,
|
||||
|
@ -9245,6 +9253,7 @@
|
|||
B6CAB5451AF9AA1A00B9B856 /* MiniCLTask.h in Headers */,
|
||||
15AE1A2F19AAD3D500C27E9E /* b2TimeOfImpact.h in Headers */,
|
||||
15AE18F319AAD35000C27E9E /* CCArmatureDataManager.h in Headers */,
|
||||
505385021B01887A00793096 /* CCProperties.h in Headers */,
|
||||
B665E2C01AA80A6500DDB1C5 /* CCPUGeometryRotator.h in Headers */,
|
||||
50ABBE471925AB6F00A911A9 /* CCEvent.h in Headers */,
|
||||
5012169C1AC473A3009A4BEA /* CCTechnique.h in Headers */,
|
||||
|
@ -10117,6 +10126,7 @@
|
|||
B6CAB3FA1AF9AA1A00B9B856 /* btMultiBody.h in Headers */,
|
||||
15AE1BA619AADFDF00C27E9E /* UIHBox.h in Headers */,
|
||||
B6CAB2881AF9AA1A00B9B856 /* btBvhTriangleMeshShape.h in Headers */,
|
||||
505385031B01887A00793096 /* CCProperties.h in Headers */,
|
||||
15AE1A9519AAD40300C27E9E /* b2BlockAllocator.h in Headers */,
|
||||
5034CA48191D591100CE6051 /* ccShader_Label_normal.frag in Headers */,
|
||||
B6CAB30A1AF9AA1A00B9B856 /* btTriangleMesh.h in Headers */,
|
||||
|
@ -10635,6 +10645,7 @@
|
|||
B665E2761AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp in Sources */,
|
||||
1A570081180BC5A10088DEC7 /* CCActionManager.cpp in Sources */,
|
||||
15AE1A6119AAD40300C27E9E /* b2Fixture.cpp in Sources */,
|
||||
505385041B01887A00793096 /* CCProperties.cpp in Sources */,
|
||||
1A570085180BC5A10088DEC7 /* CCActionPageTurn3D.cpp in Sources */,
|
||||
B6CAB2B71AF9AA1A00B9B856 /* btConvexTriangleMeshShape.cpp in Sources */,
|
||||
382384441A25915C002C4610 /* SpriteReader.cpp in Sources */,
|
||||
|
@ -11655,6 +11666,7 @@
|
|||
382384141A259092002C4610 /* NodeReaderProtocol.cpp in Sources */,
|
||||
50ABBD511925AB0000A911A9 /* Quaternion.cpp in Sources */,
|
||||
1A5701FC180BCBAD0088DEC7 /* CCMenuItem.cpp in Sources */,
|
||||
505385051B01887A00793096 /* CCProperties.cpp in Sources */,
|
||||
B6CAB4201AF9AA1A00B9B856 /* btMLCPSolver.cpp in Sources */,
|
||||
B665E2A71AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp in Sources */,
|
||||
B6CAB4341AF9AA1A00B9B856 /* btGpu3DGridBroadphase.cpp in Sources */,
|
||||
|
|
|
@ -164,7 +164,7 @@ bool ParticleSystem::initWithFile(const std::string& plistFile)
|
|||
{
|
||||
bool ret = false;
|
||||
_plistFile = FileUtils::getInstance()->fullPathForFilename(plistFile);
|
||||
ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(_plistFile.c_str());
|
||||
ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(_plistFile);
|
||||
|
||||
CCASSERT( !dict.empty(), "Particles: file not found");
|
||||
|
||||
|
|
|
@ -430,6 +430,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClCompile Include="..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="..\base\CCNS.cpp" />
|
||||
<ClCompile Include="..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="..\base\CCProperties.cpp" />
|
||||
<ClCompile Include="..\base\ccRandom.cpp" />
|
||||
<ClCompile Include="..\base\CCRef.cpp" />
|
||||
<ClCompile Include="..\base\CCScheduler.cpp" />
|
||||
|
@ -991,6 +992,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClInclude Include="..\base\CCMap.h" />
|
||||
<ClInclude Include="..\base\CCNS.h" />
|
||||
<ClInclude Include="..\base\CCProfiling.h" />
|
||||
<ClInclude Include="..\base\CCProperties.h" />
|
||||
<ClInclude Include="..\base\CCProtocols.h" />
|
||||
<ClInclude Include="..\base\ccRandom.h" />
|
||||
<ClInclude Include="..\base\CCRef.h" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="physics">
|
||||
|
@ -1866,6 +1866,9 @@
|
|||
<ClCompile Include="..\renderer\CCMaterial.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\CCProperties.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h">
|
||||
|
@ -3650,6 +3653,9 @@
|
|||
<ClInclude Include="..\renderer\CCMaterial.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\CCProperties.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\math\Mat4.inl">
|
||||
|
|
|
@ -284,6 +284,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProtocols.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccRandom.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCRef.h" />
|
||||
|
@ -883,6 +884,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccRandom.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCRef.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCScheduler.cpp" />
|
||||
|
|
|
@ -1785,6 +1785,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\renderer\CCPass.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\cocos2d.cpp" />
|
||||
|
@ -3393,6 +3396,9 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\renderer\CCPass.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="2d">
|
||||
|
|
|
@ -49,7 +49,20 @@
|
|||
|
||||
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};
|
||||
static GLProgramState* getGLProgramStateForAttribs(MeshVertexData* meshVertexData, bool usesLight);
|
||||
static void setVertexAttribForGLProgramState(GLProgramState* glprogramstate, const MeshVertexData* meshVertexData);
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -249,6 +262,7 @@ Sprite3D::Sprite3D()
|
|||
, _lightMask(-1)
|
||||
, _shaderUsingLight(false)
|
||||
, _forceDepthWrite(false)
|
||||
, _usingAutogeneratedGLProgram(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -425,76 +439,68 @@ void Sprite3D::setMaterial(Material *material, int meshIndex)
|
|||
CCASSERT(material, "Invalid Material");
|
||||
CCASSERT(meshIndex == -1 || (meshIndex >=0 && meshIndex < _meshes.size()), "Invalid meshIndex");
|
||||
|
||||
|
||||
if (meshIndex == -1)
|
||||
{
|
||||
for(auto& mesh: _meshes)
|
||||
for (auto mesh: _meshes)
|
||||
{
|
||||
mesh->setMaterial(material);
|
||||
|
||||
// set the vertex attribs
|
||||
for (auto technique: material->getTechniques())
|
||||
{
|
||||
for (auto pass: technique->getPasses())
|
||||
{
|
||||
auto meshVertexData = mesh->getMeshIndexData()->getMeshVertexData();
|
||||
auto glProgramState = pass->getGLProgramState();
|
||||
setVertexAttribForGLProgramState(glProgramState, meshVertexData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_meshes.at(meshIndex)->setMaterial(material);
|
||||
auto mesh = _meshes.at(meshIndex);
|
||||
mesh->setMaterial(material);
|
||||
|
||||
// set the vertex attribs
|
||||
for (auto technique: material->getTechniques())
|
||||
{
|
||||
for (auto pass: technique->getPasses())
|
||||
{
|
||||
auto meshVertexData = mesh->getMeshIndexData()->getMeshVertexData();
|
||||
auto glProgramState = pass->getGLProgramState();
|
||||
setVertexAttribForGLProgramState(glProgramState, meshVertexData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_usingAutogeneratedGLProgram = false;
|
||||
}
|
||||
|
||||
Material* Sprite3D::getMaterial(int meshIndex) const
|
||||
{
|
||||
CCASSERT(meshIndex >=0 && meshIndex < _meshes.size(), "Invalid meshIndex");
|
||||
return _meshes.at(meshIndex)->getMaterial();
|
||||
}
|
||||
|
||||
|
||||
void Sprite3D::genGLProgramState(bool useLight)
|
||||
{
|
||||
_shaderUsingLight = useLight;
|
||||
|
||||
std::unordered_map<const MeshVertexData*, GLProgramState*> glProgramestates;
|
||||
for(auto& meshVertexData : _meshVertexDatas)
|
||||
for(auto meshVertexData : _meshVertexDatas)
|
||||
{
|
||||
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;
|
||||
if(textured)
|
||||
{
|
||||
if (hasSkin)
|
||||
{
|
||||
if (hasNormal && _shaderUsingLight)
|
||||
shader = GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE;
|
||||
else
|
||||
shader = GLProgram::SHADER_3D_SKINPOSITION_TEXTURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasNormal && _shaderUsingLight)
|
||||
shader = GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE;
|
||||
else
|
||||
shader = GLProgram::SHADER_3D_POSITION_TEXTURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = GLProgram::SHADER_3D_POSITION;
|
||||
}
|
||||
|
||||
CCASSERT(shader, "Couldn't find shader for sprite");
|
||||
|
||||
auto glProgram = GLProgramCache::getInstance()->getGLProgram(shader);
|
||||
auto glprogramstate = GLProgramState::create(glProgram);
|
||||
|
||||
long offset = 0;
|
||||
auto attributeCount = meshVertexData->getMeshVertexAttribCount();
|
||||
for (auto k = 0; k < attributeCount; k++) {
|
||||
auto meshattribute = meshVertexData->getMeshVertexAttrib(k);
|
||||
glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
meshVertexData->getVertexBuffer()->getSizePerVertex(),
|
||||
(GLvoid*)offset);
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
auto glprogramstate = getGLProgramStateForAttribs(meshVertexData, useLight);
|
||||
setVertexAttribForGLProgramState(glprogramstate, meshVertexData);
|
||||
|
||||
glProgramestates[meshVertexData] = glprogramstate;
|
||||
}
|
||||
|
||||
for (auto& mesh : _meshes) {
|
||||
for (auto& mesh: _meshes)
|
||||
{
|
||||
auto glProgramState = glProgramestates[mesh->getMeshIndexData()->getMeshVertexData()];
|
||||
|
||||
// hack to prevent cloning the very first time
|
||||
|
@ -745,7 +751,9 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
|
||||
//check light and determine the shader used
|
||||
const auto& scene = Director::getInstance()->getRunningScene();
|
||||
if (scene)
|
||||
|
||||
// Don't override GLProgramState if using manually set Material
|
||||
if (_usingAutogeneratedGLProgram && scene)
|
||||
{
|
||||
const auto& lights = scene->getLights();
|
||||
bool usingLight = false;
|
||||
|
@ -755,8 +763,10 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
|
|||
break;
|
||||
}
|
||||
if (usingLight != _shaderUsingLight)
|
||||
{
|
||||
genGLProgramState(usingLight);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& mesh : _meshes)
|
||||
{
|
||||
|
@ -973,4 +983,62 @@ Sprite3DCache::~Sprite3DCache()
|
|||
removeAllSprite3DData();
|
||||
}
|
||||
|
||||
//
|
||||
// MARK: Helpers
|
||||
//
|
||||
static GLProgramState* getGLProgramStateForAttribs(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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = GLProgram::SHADER_3D_POSITION;
|
||||
}
|
||||
|
||||
CCASSERT(shader, "Couldn't find shader for sprite");
|
||||
|
||||
auto glProgram = GLProgramCache::getInstance()->getGLProgram(shader);
|
||||
auto glprogramstate = GLProgramState::create(glProgram);
|
||||
|
||||
return glprogramstate;
|
||||
}
|
||||
|
||||
static void setVertexAttribForGLProgramState(GLProgramState* glprogramstate, const MeshVertexData* meshVertexData)
|
||||
{
|
||||
long offset = 0;
|
||||
auto attributeCount = meshVertexData->getMeshVertexAttribCount();
|
||||
for (auto k = 0; k < attributeCount; k++)
|
||||
{
|
||||
auto meshattribute = meshVertexData->getMeshVertexAttrib(k);
|
||||
glprogramstate->setVertexAttribPointer(
|
||||
s_attributeNames[meshattribute.vertexAttrib],
|
||||
meshattribute.size,
|
||||
meshattribute.type,
|
||||
GL_FALSE,
|
||||
meshVertexData->getVertexBuffer()->getSizePerVertex(),
|
||||
(GLvoid*)offset);
|
||||
offset += meshattribute.attribSizeBytes;
|
||||
}
|
||||
}
|
||||
NS_CC_END
|
||||
|
|
|
@ -189,6 +189,12 @@ public:
|
|||
*/
|
||||
void setMaterial(Material* material, int meshIndex);
|
||||
|
||||
/** Adds a new material to a particular mesh of the sprite.
|
||||
meshIndex is the mesh that will be applied to.
|
||||
if meshIndex == -1, then it will be applied to all the meshes that belong to the sprite.
|
||||
*/
|
||||
Material* getMaterial(int meshIndex) const;
|
||||
|
||||
CC_CONSTRUCTOR_ACCESS:
|
||||
|
||||
Sprite3D();
|
||||
|
@ -246,6 +252,7 @@ protected:
|
|||
unsigned int _lightMask;
|
||||
bool _shaderUsingLight; // is current shader using light ?
|
||||
bool _forceDepthWrite; // Always write to depth buffer
|
||||
bool _usingAutogeneratedGLProgram;
|
||||
|
||||
struct AsyncLoadParam
|
||||
{
|
||||
|
|
|
@ -132,6 +132,7 @@ base/CCEventTouch.cpp \
|
|||
base/CCIMEDispatcher.cpp \
|
||||
base/CCNS.cpp \
|
||||
base/CCProfiling.cpp \
|
||||
base/CCProperties.cpp \
|
||||
base/CCRef.cpp \
|
||||
base/CCScheduler.cpp \
|
||||
base/CCScriptSupport.cpp \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,616 @@
|
|||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2015 Chukong Technologies
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __cocos2d_libs__CCProperties__
|
||||
#define __cocos2d_libs__CCProperties__
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "platform/CCPlatformMacros.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCVector.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class Properties;
|
||||
class Vec2;
|
||||
class Vec3;
|
||||
class Vec4;
|
||||
class Mat4;
|
||||
class Data;
|
||||
class Data;
|
||||
|
||||
|
||||
/**
|
||||
* Defines a properties file for loading text files.
|
||||
*
|
||||
* A properties file has very simple syntax and can contain only namespaces and
|
||||
* name/value pairs (the properties of a namespace).
|
||||
* The file can have any file extension a user specifies.
|
||||
*
|
||||
* Here's an example of a simple
|
||||
* file that uses all the available features of the markup language:
|
||||
|
||||
@verbatim
|
||||
// This is a comment.
|
||||
|
||||
// This property is in the default namespace:
|
||||
integerProperty = 5
|
||||
|
||||
// This line defines a namespace of type "mynamespace" without an ID:
|
||||
mynamespace
|
||||
{
|
||||
// This namespace can be retrieved by searching for its ID, "spriteTexture",
|
||||
// or by its name "texture":
|
||||
texture spriteTexture
|
||||
{
|
||||
fileName = sprite.png
|
||||
width = 64
|
||||
height = 64
|
||||
}
|
||||
|
||||
// This property is in the "space" namespace:
|
||||
booleanProperty = true
|
||||
|
||||
// It's legal to have a name without a value if you leave out the '=' character:
|
||||
foo
|
||||
|
||||
// In fact, the '=' character is optional if you'd rather write:
|
||||
bar 23
|
||||
|
||||
// But don't write this or you'll get an error:
|
||||
// illegalProperty =
|
||||
|
||||
// Or this:
|
||||
// = 15
|
||||
|
||||
// Properties objects let you retrieve values as various types.
|
||||
floatProperty = 3.333
|
||||
stringProperty = This is a string.
|
||||
vector3Property = 1.0, 5.0, 3.55
|
||||
colorProperty = 1.0, 0.4, 0.0, 1.0
|
||||
}
|
||||
@endverbatim
|
||||
|
||||
* Retrieving information out of a file like this could be done in two ways. If the
|
||||
* available namespaces and name/value pairs are known in advance they can be queried by ID or name.
|
||||
* For example, if the namespace "spriteTexture" and its properties are required then they can
|
||||
* be retrieved with a call to getNamespace() followed by calls to getString() and getInt().
|
||||
* A namespace is stored and retrieved as a Properties object.
|
||||
* Reading the spriteTexture properties out of the file above in this way could be done with the following code:
|
||||
|
||||
@verbatim
|
||||
// Create the top-level Properties object.
|
||||
Properties* properties = Properties::create("example.properties");
|
||||
// Retrieve the "spriteTexture" namespace.
|
||||
Properties* spriteTexture = properties->getNamespace("spriteTexture");
|
||||
|
||||
// Get the values of known texture properties out of the namespace.
|
||||
const char* fileName = spriteTexture->getString("fileName");
|
||||
int width = spriteTexture->getInt("width");
|
||||
int height = spriteTexture->getInt("height");
|
||||
|
||||
// Deleting the top-level Properties object will clean up all nested namespaces.
|
||||
SAFE_DELETE(properties);
|
||||
@endverbatim
|
||||
|
||||
* On the other hand, if the structure of the file is not known in advance its
|
||||
* namespaces and name/value pairs can be retrieved one by one using the getNextNamespace()
|
||||
* and getNextProperty() methods. The following method prints the contents of any properties file
|
||||
* to the console:
|
||||
|
||||
@verbatim
|
||||
void printProperties(Properties* properties)
|
||||
{
|
||||
// Print the name and ID of the current namespace.
|
||||
const char* spacename = properties->getNamespace();
|
||||
const char* id = properties->getId();
|
||||
GP_WARN("Namespace: %s ID: %s\n{", spacename, id);
|
||||
|
||||
// Print all properties in this namespace.
|
||||
const char* name = properties->getNextProperty();
|
||||
const char* value = NULL;
|
||||
while (name != NULL)
|
||||
{
|
||||
value = properties->getString(name);
|
||||
GP_WARN("%s = %s", name, value);
|
||||
name = properties->getNextProperty();
|
||||
}
|
||||
GP_WARN("}\n");
|
||||
|
||||
// Print the properties of every namespace within this one.
|
||||
Properties* space = properties->getNextNamespace();
|
||||
while (space != NULL)
|
||||
{
|
||||
printProperties(space);
|
||||
space = properties->getNextNamespace();
|
||||
}
|
||||
}
|
||||
@endverbatim
|
||||
|
||||
* Note that this method does not keep track of the namespace hierarchy, but could be
|
||||
* modified to do so. Also note that nothing in a properties file indicates the type
|
||||
* of a property. If the type is unknown, its string can be retrieved and interpreted
|
||||
* as necessary.
|
||||
*/
|
||||
class CC_DLL Properties
|
||||
{
|
||||
friend class Game;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Data types supported by the properties class.
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
NONE,
|
||||
STRING,
|
||||
NUMBER,
|
||||
VECTOR2,
|
||||
VECTOR3,
|
||||
VECTOR4,
|
||||
MATRIX
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Properties runtime settings from the specified URL, where the URL is of
|
||||
* the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
|
||||
* (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
|
||||
*
|
||||
* @param url The URL to create the properties from.
|
||||
*
|
||||
* @return The created Properties or NULL if there was an error.
|
||||
* @script{create}
|
||||
*/
|
||||
static Properties* create(const std::string& url);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Properties();
|
||||
|
||||
/**
|
||||
* Get the name of the next property.
|
||||
*
|
||||
* If a valid next property is returned, the value of the property can be
|
||||
* retrieved using any of the get methods in this class, passing NULL for
|
||||
// the property name.
|
||||
*
|
||||
* @return The name of the next property, or NULL if there are no properties remaining.
|
||||
*/
|
||||
const char* getNextProperty();
|
||||
|
||||
/**
|
||||
* Get the next namespace.
|
||||
*/
|
||||
Properties* getNextNamespace();
|
||||
|
||||
/**
|
||||
* Rewind the getNextProperty() and getNextNamespace() iterators
|
||||
* to the beginning of the file.
|
||||
*/
|
||||
void rewind();
|
||||
|
||||
/**
|
||||
* Get a specific namespace by ID or name. This method will optionally
|
||||
* perform a depth-first search on all namespaces and inner namespaces
|
||||
* within this Property.
|
||||
*
|
||||
* @param id The ID or name of the namespace to find.
|
||||
* @param searchNames If true, namespace names are used in the search,
|
||||
* instead of namespace IDs. By default this parameter is false
|
||||
* and namespace IDs are searched.
|
||||
* @param recurse If true, perform a depth-first search, otherwise search
|
||||
* only the immediate child namespaces.
|
||||
*
|
||||
* @return A properties object with the given ID or name.
|
||||
*/
|
||||
Properties* getNamespace(const char* id, bool searchNames = false, bool recurse = true) const;
|
||||
|
||||
/**
|
||||
* Get the name of this Property's namespace.
|
||||
*
|
||||
* @return The name of this Property's namespace.
|
||||
*/
|
||||
const char* getNamespace() const;
|
||||
|
||||
/**
|
||||
* Get the ID of this Property's namespace. The ID should be a unique identifier,
|
||||
* but its uniqueness is not enforced.
|
||||
*
|
||||
* @return The ID of this Property's namespace.
|
||||
*/
|
||||
const char* getId() const;
|
||||
|
||||
/**
|
||||
* Check if a property with the given name is specified in this Properties object.
|
||||
*
|
||||
* @param name The name of the property to query.
|
||||
*
|
||||
* @return True if the property exists, false otherwise.
|
||||
*/
|
||||
bool exists(const char* name) const;
|
||||
|
||||
/**
|
||||
* Returns the type of a property.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's type.
|
||||
*
|
||||
* @return The type of the property.
|
||||
*/
|
||||
Type getType(const char* name = NULL) const;
|
||||
|
||||
/**
|
||||
* Get the value of the given property as a string. This can always be retrieved,
|
||||
* whatever the intended type of the property.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param defaultValue The default value to return if the specified property does not exist.
|
||||
*
|
||||
* @return The value of the given property as a string, or the empty string if no property with that name exists.
|
||||
*/
|
||||
const char* getString(const char* name = NULL, const char* defaultValue = NULL) const;
|
||||
|
||||
/**
|
||||
* Sets the value of the property with the specified name.
|
||||
*
|
||||
* If there is no property in this namespace with the current name,
|
||||
* one is added. Otherwise, the value of the first property with the
|
||||
* specified name is updated.
|
||||
*
|
||||
* If name is NULL, the value current property (see getNextProperty) is
|
||||
* set, unless there is no current property, in which case false
|
||||
* is returned.
|
||||
*
|
||||
* @param name The name of the property to set.
|
||||
* @param value The property value.
|
||||
*
|
||||
* @return True if the property was set, false otherwise.
|
||||
*/
|
||||
bool setString(const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a boolean.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param defaultValue the default value to return if the specified property does not exist within the properties file.
|
||||
*
|
||||
* @return true if the property exists and its value is "true", otherwise false.
|
||||
*/
|
||||
bool getBool(const char* name = NULL, bool defaultValue = false) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as an integer.
|
||||
* If the property does not exist, zero will be returned.
|
||||
* If the property exists but could not be scanned, an error will be logged and zero will be returned.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
*
|
||||
* @return The value of the given property interpreted as an integer.
|
||||
* Zero if the property does not exist or could not be scanned.
|
||||
*/
|
||||
int getInt(const char* name = NULL) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a floating-point number.
|
||||
* If the property does not exist, zero will be returned.
|
||||
* If the property exists but could not be scanned, an error will be logged and zero will be returned.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
*
|
||||
* @return The value of the given property interpreted as a float.
|
||||
* Zero if the property does not exist or could not be scanned.
|
||||
*/
|
||||
float getFloat(const char* name = NULL) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a long integer.
|
||||
* If the property does not exist, zero will be returned.
|
||||
* If the property exists but could not be scanned, an error will be logged and zero will be returned.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
*
|
||||
* @return The value of the given property interpreted as a long.
|
||||
* Zero if the property does not exist or could not be scanned.
|
||||
*/
|
||||
long getLong(const char* name = NULL) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a Matrix.
|
||||
* If the property does not exist, out will be set to the identity matrix.
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to the identity matrix.
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The matrix to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getMat4(const char* name, Mat4* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a Vector2.
|
||||
* If the property does not exist, out will be set to Vector2(0.0f, 0.0f).
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Vector2(0.0f, 0.0f).
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The vector to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getVec2(const char* name, Vec2* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a Vector3.
|
||||
* If the property does not exist, out will be set to Vector3(0.0f, 0.0f, 0.0f).
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Vector3(0.0f, 0.0f, 0.0f).
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The vector to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getVec3(const char* name, Vec3* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a Vector4.
|
||||
* If the property does not exist, out will be set to Vector4(0.0f, 0.0f, 0.0f, 0.0f).
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Vector4(0.0f, 0.0f, 0.0f, 0.0f).
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The vector to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getVec4(const char* name, Vec4* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as a Quaternion specified as an axis angle.
|
||||
* If the property does not exist, out will be set to Quaternion().
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Quaternion().
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The quaternion to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getQuaternionFromAxisAngle(const char* name, Quaternion* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as an RGB color in hex and write this color to a Vector3.
|
||||
* E.g. 0xff0000 represents red and sets the vector to (1, 0, 0).
|
||||
* If the property does not exist, out will be set to Vector3(0.0f, 0.0f, 0.0f).
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Vector3(0.0f, 0.0f, 0.0f).
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The vector to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getColor(const char* name, Vec3* out) const;
|
||||
|
||||
/**
|
||||
* Interpret the value of the given property as an RGBA color in hex and write this color to a Vector4.
|
||||
* E.g. 0xff0000ff represents opaque red and sets the vector to (1, 0, 0, 1).
|
||||
* If the property does not exist, out will be set to Vector4(0.0f, 0.0f, 0.0f, 0.0f).
|
||||
* If the property exists but could not be scanned, an error will be logged and out will be set
|
||||
* to Vector4(0.0f, 0.0f, 0.0f, 0.0f).
|
||||
*
|
||||
* @param name The name of the property to interpret, or NULL to return the current property's value.
|
||||
* @param out The vector to set to this property's interpreted value.
|
||||
*
|
||||
* @return True on success, false if the property does not exist or could not be scanned.
|
||||
*/
|
||||
bool getColor(const char* name, Vec4* out) const;
|
||||
|
||||
/**
|
||||
* Gets the file path for the given property if the file exists.
|
||||
*
|
||||
* This method will first search for the file relative to the working directory.
|
||||
* If the file is not found then it will search relative to the directory the bundle file is in.
|
||||
*
|
||||
* @param name The name of the property.
|
||||
* @param path The string to copy the path to if the file exists.
|
||||
*
|
||||
* @return True if the property exists and the file exists, false otherwise.
|
||||
*
|
||||
* @script{ignore}
|
||||
*/
|
||||
bool getPath(const char* name, std::string* path) const;
|
||||
|
||||
/**
|
||||
* Returns the value of a variable that is set in this Properties object.
|
||||
*
|
||||
* Variables take on the format ${name} and are inherited from parent Property objects.
|
||||
*
|
||||
* @param name Name of the variable to get.
|
||||
* @param defaultValue Value to return if the variable is not found.
|
||||
*
|
||||
* @return The value of the specified variable, or defaultValue if not found.
|
||||
*/
|
||||
const char* getVariable(const char* name, const char* defaultValue = NULL) const;
|
||||
|
||||
/**
|
||||
* Sets the value of the specified variable.
|
||||
*
|
||||
* @param name Name of the variable to set.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
void setVariable(const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Attempts to parse the specified string as a Vector2 value.
|
||||
*
|
||||
* On error, false is returned and the output is set to all zero values.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out The value to populate if successful.
|
||||
*
|
||||
* @return True if a valid Vector2 was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseVec2(const char* str, Vec2* out);
|
||||
|
||||
/**
|
||||
* Attempts to parse the specified string as a Vector3 value.
|
||||
*
|
||||
* On error, false is returned and the output is set to all zero values.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out The value to populate if successful.
|
||||
*
|
||||
* @return True if a valid Vector3 was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseVec3(const char* str, Vec3* out);
|
||||
|
||||
/**
|
||||
* Attempts to parse the specified string as a Vector4 value.
|
||||
*
|
||||
* On error, false is returned and the output is set to all zero values.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out The value to populate if successful.
|
||||
*
|
||||
* @return True if a valid Vector4 was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseVec4(const char* str, Vec4* out);
|
||||
|
||||
/**
|
||||
* Attempts to parse the specified string as an axis-angle value.
|
||||
*
|
||||
* The specified string is expected to contain four comma-separated
|
||||
* values, where the first three values represents the axis and the
|
||||
* fourth value represents the angle, in degrees.
|
||||
*
|
||||
* On error, false is returned and the output is set to all zero values.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out A Quaternion populated with the orientation of the axis-angle, if successful.
|
||||
*
|
||||
* @return True if a valid axis-angle was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseAxisAngle(const char* str, Quaternion* out);
|
||||
|
||||
/**
|
||||
* Atempts to parse the specified string as an RGB color value.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out The value to populate if successful.
|
||||
*
|
||||
* @return True if a valid RGB color was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseColor(const char* str, Vec3* out);
|
||||
|
||||
/**
|
||||
* Atempts to parse the specified string as an RGBA color value.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param out The value to populate if successful.
|
||||
*
|
||||
* @return True if a valid RGBA color was parsed, false otherwise.
|
||||
*/
|
||||
static bool parseColor(const char* str, Vec4* out);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Internal structure containing a single property.
|
||||
*/
|
||||
struct Property
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
Property(const std::string& aname, const std::string& avalue) : name(aname), value(avalue) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
Properties();
|
||||
|
||||
/**
|
||||
* Constructs the Properties class from a file.
|
||||
*
|
||||
* @param stream The stream used for reading the properties from file.
|
||||
*/
|
||||
Properties(Data* data, ssize_t* dataIdx);
|
||||
Properties(const Properties& copy);
|
||||
|
||||
/**
|
||||
* Constructor. Read from the beginning of namespace specified.
|
||||
*/
|
||||
Properties(Data* data, ssize_t* dataIdx, const std::string& name, const char* id, const char* parentID, Properties* parent);
|
||||
|
||||
// Data manipulation methods
|
||||
void readProperties();
|
||||
void skipWhiteSpace();
|
||||
char* trimWhiteSpace(char* str);
|
||||
signed char readChar();
|
||||
char* readLine(char* output, int num);
|
||||
bool seekFromCurrent(int offset);
|
||||
bool eof();
|
||||
|
||||
// Called after create(); copies info from parents into derived namespaces.
|
||||
void resolveInheritance(const char* id = NULL);
|
||||
|
||||
// Called by resolveInheritance().
|
||||
void mergeWith(Properties* overrides);
|
||||
|
||||
// Clones the Properties object.
|
||||
Properties* clone();
|
||||
|
||||
void setDirectoryPath(const std::string* path);
|
||||
void setDirectoryPath(const std::string& path);
|
||||
|
||||
/**
|
||||
* Reads the next character from the Data. Returns EOF if the end of the Data is reached.
|
||||
*/
|
||||
|
||||
// XXX: hack in order to simulate GamePlay's Stream with Cocos2d's Data
|
||||
ssize_t *_dataIdx;
|
||||
Data *_data;
|
||||
|
||||
std::string _namespace;
|
||||
std::string _id;
|
||||
std::string _parentID;
|
||||
std::list<Property> _properties;
|
||||
std::list<Property>::iterator _propertiesItr;
|
||||
std::vector<Properties*> _namespaces;
|
||||
std::vector<Properties*>::const_iterator _namespacesItr;
|
||||
std::vector<Property>* _variables;
|
||||
std::string* _dirPath;
|
||||
Properties* _parent;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cocos2d_libs__CCProperties__
|
|
@ -8,10 +8,6 @@ endif()
|
|||
# todo: also base/CCController-android.cpp
|
||||
|
||||
set(COCOS_BASE_SRC
|
||||
base/allocator/CCAllocatorDiagnostics.cpp
|
||||
base/allocator/CCAllocatorGlobal.cpp
|
||||
base/allocator/CCAllocatorGlobalNewDelete.cpp
|
||||
base/ccFPSImages.c
|
||||
base/CCAsyncTaskPool.cpp
|
||||
base/CCAutoreleasePool.cpp
|
||||
base/CCConfiguration.cpp
|
||||
|
@ -40,6 +36,7 @@ set(COCOS_BASE_SRC
|
|||
base/CCIMEDispatcher.cpp
|
||||
base/CCNS.cpp
|
||||
base/CCProfiling.cpp
|
||||
base/CCProperties.cpp
|
||||
base/CCRef.cpp
|
||||
base/CCScheduler.cpp
|
||||
base/CCScriptSupport.cpp
|
||||
|
@ -49,9 +46,13 @@ set(COCOS_BASE_SRC
|
|||
base/ObjectFactory.cpp
|
||||
base/TGAlib.cpp
|
||||
base/ZipUtils.cpp
|
||||
base/allocator/CCAllocatorDiagnostics.cpp
|
||||
base/allocator/CCAllocatorGlobal.cpp
|
||||
base/allocator/CCAllocatorGlobalNewDelete.cpp
|
||||
base/atitc.cpp
|
||||
base/base64.cpp
|
||||
base/ccCArray.cpp
|
||||
base/ccFPSImages.c
|
||||
base/ccRandom.cpp
|
||||
base/ccTypes.cpp
|
||||
base/ccUTF8.cpp
|
||||
|
|
|
@ -31,7 +31,7 @@ NS_CC_BEGIN
|
|||
|
||||
CC_DLL const char* cocos2dVersion()
|
||||
{
|
||||
return "cocos2d-x 3.7-pre";
|
||||
return "cocos2d-x 3.7-github";
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
194
cocos/cocos2d.h
194
cocos/cocos2d.h
|
@ -38,108 +38,108 @@ THE SOFTWARE.
|
|||
#include "base/ccConfig.h"
|
||||
|
||||
// base
|
||||
#include "base/CCAsyncTaskPool.h"
|
||||
#include "base/CCAutoreleasePool.h"
|
||||
#include "base/CCConfiguration.h"
|
||||
#include "base/CCConsole.h"
|
||||
#include "base/CCData.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCIMEDelegate.h"
|
||||
#include "base/CCIMEDispatcher.h"
|
||||
#include "base/CCMap.h"
|
||||
#include "base/CCNS.h"
|
||||
#include "base/CCProfiling.h"
|
||||
#include "base/CCProperties.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "base/CCRefPtr.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCMap.h"
|
||||
#include "base/CCAutoreleasePool.h"
|
||||
#include "base/CCNS.h"
|
||||
#include "base/CCData.h"
|
||||
#include "base/CCScheduler.h"
|
||||
#include "base/CCUserDefault.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/ZipUtils.h"
|
||||
#include "base/base64.h"
|
||||
#include "base/ccConfig.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCConfiguration.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "base/CCScheduler.h"
|
||||
#include "base/base64.h"
|
||||
#include "base/ZipUtils.h"
|
||||
#include "base/CCProfiling.h"
|
||||
#include "base/CCConsole.h"
|
||||
#include "base/ccUTF8.h"
|
||||
#include "base/CCUserDefault.h"
|
||||
#include "base/CCIMEDelegate.h"
|
||||
#include "base/CCIMEDispatcher.h"
|
||||
#include "base/ccUtils.h"
|
||||
#include "base/CCAsyncTaskPool.h"
|
||||
|
||||
// EventDispatcher
|
||||
#include "base/CCEventType.h"
|
||||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventListenerTouch.h"
|
||||
#include "base/CCEventTouch.h"
|
||||
#include "base/CCEventListenerKeyboard.h"
|
||||
#include "base/CCEventKeyboard.h"
|
||||
#include "base/CCEventListenerMouse.h"
|
||||
#include "base/CCEventMouse.h"
|
||||
#include "base/CCEventAcceleration.h"
|
||||
#include "base/CCEventListenerAcceleration.h"
|
||||
#include "base/CCEventCustom.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventFocus.h"
|
||||
#include "base/CCEventKeyboard.h"
|
||||
#include "base/CCEventListenerAcceleration.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/CCEventListenerFocus.h"
|
||||
#include "base/CCEventListenerKeyboard.h"
|
||||
#include "base/CCEventListenerMouse.h"
|
||||
#include "base/CCEventListenerTouch.h"
|
||||
#include "base/CCEventMouse.h"
|
||||
#include "base/CCEventTouch.h"
|
||||
#include "base/CCEventType.h"
|
||||
|
||||
// math
|
||||
#include "math/CCAffineTransform.h"
|
||||
#include "math/CCGeometry.h"
|
||||
#include "math/CCVertex.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Vec2.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "math/CCVertex.h"
|
||||
|
||||
// actions
|
||||
#include "2d/CCAction.h"
|
||||
#include "2d/CCActionInterval.h"
|
||||
#include "2d/CCActionCamera.h"
|
||||
#include "2d/CCActionManager.h"
|
||||
#include "2d/CCActionEase.h"
|
||||
#include "2d/CCActionPageTurn3D.h"
|
||||
#include "2d/CCActionGrid.h"
|
||||
#include "2d/CCActionProgressTimer.h"
|
||||
#include "2d/CCActionGrid3D.h"
|
||||
#include "2d/CCActionTiledGrid.h"
|
||||
#include "2d/CCActionInstant.h"
|
||||
#include "2d/CCActionTween.h"
|
||||
#include "2d/CCActionCatmullRom.h"
|
||||
#include "2d/CCActionEase.h"
|
||||
#include "2d/CCActionGrid.h"
|
||||
#include "2d/CCActionGrid3D.h"
|
||||
#include "2d/CCActionInstant.h"
|
||||
#include "2d/CCActionInterval.h"
|
||||
#include "2d/CCActionManager.h"
|
||||
#include "2d/CCActionPageTurn3D.h"
|
||||
#include "2d/CCActionProgressTimer.h"
|
||||
#include "2d/CCActionTiledGrid.h"
|
||||
#include "2d/CCActionTween.h"
|
||||
#include "2d/CCTweenFunction.h"
|
||||
|
||||
// 2d nodes
|
||||
#include "2d/CCNode.h"
|
||||
#include "2d/CCProtectedNode.h"
|
||||
#include "2d/CCAtlasNode.h"
|
||||
#include "2d/CCDrawingPrimitives.h"
|
||||
#include "2d/CCClippingNode.h"
|
||||
#include "2d/CCClippingRectangleNode.h"
|
||||
#include "2d/CCDrawNode.h"
|
||||
#include "2d/CCLabelAtlas.h"
|
||||
#include "2d/CCLabelTTF.h"
|
||||
#include "2d/CCLabelBMFont.h"
|
||||
#include "2d/CCLabel.h"
|
||||
#include "2d/CCDrawingPrimitives.h"
|
||||
#include "2d/CCFontFNT.h"
|
||||
#include "2d/CCLabel.h"
|
||||
#include "2d/CCLabelAtlas.h"
|
||||
#include "2d/CCLabelBMFont.h"
|
||||
#include "2d/CCLabelTTF.h"
|
||||
#include "2d/CCLayer.h"
|
||||
#include "2d/CCMenu.h"
|
||||
#include "2d/CCMenuItem.h"
|
||||
#include "2d/CCMotionStreak.h"
|
||||
#include "2d/CCNode.h"
|
||||
#include "2d/CCNodeGrid.h"
|
||||
#include "2d/CCParticleBatchNode.h"
|
||||
#include "2d/CCParticleExamples.h"
|
||||
#include "2d/CCParticleSystem.h"
|
||||
#include "2d/CCParticleSystemQuad.h"
|
||||
#include "2d/CCProgressTimer.h"
|
||||
#include "2d/CCProtectedNode.h"
|
||||
#include "2d/CCRenderTexture.h"
|
||||
#include "2d/CCScene.h"
|
||||
#include "2d/CCTransition.h"
|
||||
#include "2d/CCTransitionPageTurn.h"
|
||||
#include "2d/CCTransitionProgress.h"
|
||||
#include "2d/CCMenu.h"
|
||||
#include "2d/CCMenuItem.h"
|
||||
#include "2d/CCClippingNode.h"
|
||||
#include "2d/CCClippingRectangleNode.h"
|
||||
#include "2d/CCMotionStreak.h"
|
||||
#include "2d/CCProgressTimer.h"
|
||||
#include "2d/CCRenderTexture.h"
|
||||
#include "2d/CCNodeGrid.h"
|
||||
#include "2d/CCParticleBatchNode.h"
|
||||
#include "2d/CCParticleSystem.h"
|
||||
#include "2d/CCParticleExamples.h"
|
||||
#include "2d/CCParticleSystemQuad.h"
|
||||
|
||||
// 2d utils
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCGrabber.h"
|
||||
#include "2d/CCGrid.h"
|
||||
|
||||
#include "2d/CCCamera.h"
|
||||
#include "2d/CCLight.h"
|
||||
|
||||
// include
|
||||
|
@ -147,44 +147,44 @@ THE SOFTWARE.
|
|||
|
||||
// renderer
|
||||
#include "renderer/CCCustomCommand.h"
|
||||
#include "renderer/CCGroupCommand.h"
|
||||
#include "renderer/CCQuadCommand.h"
|
||||
#include "renderer/CCRenderCommand.h"
|
||||
#include "renderer/CCRenderCommandPool.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/CCGLProgramCache.h"
|
||||
#include "renderer/CCGLProgramState.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/ccShaders.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
#include "renderer/CCVertexIndexBuffer.h"
|
||||
#include "renderer/CCVertexIndexData.h"
|
||||
#include "renderer/CCGroupCommand.h"
|
||||
#include "renderer/CCMaterial.h"
|
||||
#include "renderer/CCPass.h"
|
||||
#include "renderer/CCPrimitive.h"
|
||||
#include "renderer/CCPrimitiveCommand.h"
|
||||
#include "renderer/CCTrianglesCommand.h"
|
||||
#include "renderer/CCMaterial.h"
|
||||
#include "renderer/CCTechnique.h"
|
||||
#include "renderer/CCPass.h"
|
||||
#include "renderer/CCQuadCommand.h"
|
||||
#include "renderer/CCRenderCommand.h"
|
||||
#include "renderer/CCRenderCommandPool.h"
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "renderer/CCTechnique.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
#include "renderer/CCTrianglesCommand.h"
|
||||
#include "renderer/CCVertexIndexBuffer.h"
|
||||
#include "renderer/CCVertexIndexData.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/ccShaders.h"
|
||||
|
||||
// physics
|
||||
#include "physics/CCPhysicsBody.h"
|
||||
#include "physics/CCPhysicsContact.h"
|
||||
#include "physics/CCPhysicsShape.h"
|
||||
#include "physics/CCPhysicsJoint.h"
|
||||
#include "physics/CCPhysicsShape.h"
|
||||
#include "physics/CCPhysicsWorld.h"
|
||||
|
||||
// platform
|
||||
#include "platform/CCDevice.h"
|
||||
#include "platform/CCCommon.h"
|
||||
#include "platform/CCDevice.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "platform/CCImage.h"
|
||||
#include "platform/CCSAXParser.h"
|
||||
#include "platform/CCThread.h"
|
||||
#include "platform/CCPlatformConfig.h"
|
||||
#include "platform/CCPlatformMacros.h"
|
||||
#include "platform/CCSAXParser.h"
|
||||
#include "platform/CCThread.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
#include "platform/ios/CCApplication-ios.h"
|
||||
|
@ -253,14 +253,14 @@ THE SOFTWARE.
|
|||
#include "renderer/CCTextureAtlas.h"
|
||||
|
||||
// tilemap_parallax_nodes
|
||||
#include "2d/CCFastTMXLayer.h"
|
||||
#include "2d/CCFastTMXTiledMap.h"
|
||||
#include "2d/CCParallaxNode.h"
|
||||
#include "2d/CCTMXLayer.h"
|
||||
#include "2d/CCTMXObjectGroup.h"
|
||||
#include "2d/CCTMXTiledMap.h"
|
||||
#include "2d/CCTMXXMLParser.h"
|
||||
#include "2d/CCTileMapAtlas.h"
|
||||
#include "2d/CCFastTMXTiledMap.h"
|
||||
#include "2d/CCFastTMXLayer.h"
|
||||
|
||||
// component
|
||||
#include "2d/CCComponent.h"
|
||||
|
@ -268,34 +268,34 @@ THE SOFTWARE.
|
|||
|
||||
//3d
|
||||
#include "3d/CCAABB.h"
|
||||
#include "3d/CCOBB.h"
|
||||
#include "3d/CCRay.h"
|
||||
#include "3d/CCSprite3D.h"
|
||||
#include "3d/CCMesh.h"
|
||||
#include "3d/CCMeshSkin.h"
|
||||
#include "3d/CCAnimate3D.h"
|
||||
#include "3d/CCAnimation3D.h"
|
||||
#include "3d/CCSprite3DMaterial.h"
|
||||
#include "3d/CCAttachNode.h"
|
||||
#include "3d/CCMeshVertexIndexData.h"
|
||||
#include "3d/CCSkeleton3D.h"
|
||||
#include "3d/CCBillBoard.h"
|
||||
#include "3d/CCFrustum.h"
|
||||
#include "3d/CCMesh.h"
|
||||
#include "3d/CCMeshSkin.h"
|
||||
#include "3d/CCMeshVertexIndexData.h"
|
||||
#include "3d/CCOBB.h"
|
||||
#include "3d/CCPlane.h"
|
||||
#include "3d/CCTextureCube.h"
|
||||
#include "3d/CCRay.h"
|
||||
#include "3d/CCSkeleton3D.h"
|
||||
#include "3d/CCSkybox.h"
|
||||
#include "3d/CCSprite3D.h"
|
||||
#include "3d/CCSprite3DMaterial.h"
|
||||
#include "3d/CCTerrain.h"
|
||||
#include "3d/CCTextureCube.h"
|
||||
|
||||
// Deprecated include
|
||||
#include "deprecated/CCDictionary.h"
|
||||
#include "deprecated/CCArray.h"
|
||||
#include "deprecated/CCSet.h"
|
||||
#include "deprecated/CCInteger.h"
|
||||
#include "deprecated/CCFloat.h"
|
||||
#include "deprecated/CCDouble.h"
|
||||
#include "deprecated/CCBool.h"
|
||||
#include "deprecated/CCString.h"
|
||||
#include "deprecated/CCDictionary.h"
|
||||
#include "deprecated/CCDouble.h"
|
||||
#include "deprecated/CCFloat.h"
|
||||
#include "deprecated/CCInteger.h"
|
||||
#include "deprecated/CCNotificationCenter.h"
|
||||
#include "deprecated/CCSet.h"
|
||||
#include "deprecated/CCString.h"
|
||||
// CCDeprecated.h must be included at the end
|
||||
#include "deprecated/CCDeprecated.h"
|
||||
|
||||
|
|
|
@ -34,25 +34,21 @@
|
|||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/CCGLProgramState.h"
|
||||
|
||||
#include "base/CCProperties.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
|
||||
#include "json/document.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
static const float MATERIAL_FORMAT_VERSION = 1.0;
|
||||
static const char* MATERIAL_TYPE = "material";
|
||||
NS_CC_BEGIN
|
||||
|
||||
// Helpers declaration
|
||||
static const char* getOptionalString(const rapidjson::GenericValue<rapidjson::UTF8<> >& json, const char* key, const char* defaultValue);
|
||||
static const char* getOptionalString(Properties* properties, const char* key, const char* defaultValue);
|
||||
static bool isValidUniform(const char* name);
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
Material* Material::createWithFilename(const std::string& filepath)
|
||||
{
|
||||
auto validfilename = FileUtils::getInstance()->fullPathForFilename(filepath);
|
||||
|
@ -68,6 +64,17 @@ Material* Material::createWithFilename(const std::string& filepath)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Material* Material::createWithProperties(Properties* materialProperties)
|
||||
{
|
||||
auto mat = new (std::nothrow) Material();
|
||||
if (mat && mat->initWithProperties(materialProperties))
|
||||
{
|
||||
mat->autorelease();
|
||||
return mat;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Material* Material::createWithGLStateProgram(GLProgramState* programState)
|
||||
{
|
||||
CCASSERT(programState, "Invalid GL Program State");
|
||||
|
@ -102,68 +109,42 @@ bool Material::initWithFile(const std::string& validfilename)
|
|||
char* bytes = (char*)data.getBytes();
|
||||
bytes[data.getSize()-1]='\0';
|
||||
|
||||
rapidjson::Document document;
|
||||
document.ParseInsitu<0>(bytes);
|
||||
Properties* properties = Properties::create(validfilename);
|
||||
|
||||
if (document.HasParseError())
|
||||
{
|
||||
CCLOG("GetParseError %s\n", document.GetParseError());
|
||||
return false;
|
||||
}
|
||||
|
||||
CCASSERT(document.IsObject(), "Invalid JSON file");
|
||||
|
||||
if (! parseMetadata(document)) {
|
||||
CCLOG("Error parsing Material metadata");
|
||||
return false;
|
||||
}
|
||||
|
||||
parseProperties(document);
|
||||
// get the first material
|
||||
parseProperties((strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Material::initWithProperties(Properties* materialProperties)
|
||||
{
|
||||
return parseProperties(materialProperties);
|
||||
}
|
||||
|
||||
void Material::setTarget(cocos2d::Node *target)
|
||||
{
|
||||
_target = target;
|
||||
}
|
||||
|
||||
bool Material::parseMetadata(const rapidjson::Document& jsonDocument)
|
||||
bool Material::parseProperties(Properties* materialProperties)
|
||||
{
|
||||
bool broken = false;
|
||||
|
||||
const auto& metadata = jsonDocument["metadata"];
|
||||
if (metadata.IsObject())
|
||||
setName(materialProperties->getId());
|
||||
auto space = materialProperties->getNextNamespace();
|
||||
while (space)
|
||||
{
|
||||
auto version = metadata["version"].GetDouble();
|
||||
broken |= std::floor(version) != std::floor(MATERIAL_FORMAT_VERSION);
|
||||
|
||||
auto type = metadata["type"].GetString();
|
||||
broken |= strcmp(type, MATERIAL_TYPE) != 0;
|
||||
const char* name = space->getNamespace();
|
||||
if (strcmp(name, "technique") == 0) {
|
||||
parseTechnique(space);
|
||||
}
|
||||
|
||||
return !broken;
|
||||
space = materialProperties->getNextNamespace();
|
||||
|
||||
}
|
||||
|
||||
bool Material::parseProperties(const rapidjson::Document& jsonDocument)
|
||||
{
|
||||
auto name = jsonDocument["name"].GetString();
|
||||
setName(name);
|
||||
|
||||
auto& techniquesJSON = jsonDocument["techniques"];
|
||||
CCASSERT(techniquesJSON.IsArray(), "Invalid Techniques");
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < techniquesJSON.Size(); i++) {
|
||||
auto& techniqueJSON = techniquesJSON[i];
|
||||
parseTechnique(techniqueJSON);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Material::parseTechnique(const rapidjson::GenericValue<rapidjson::UTF8<> >& techniqueJSON)
|
||||
bool Material::parseTechnique(Properties* techniqueProperties)
|
||||
{
|
||||
CCASSERT(techniqueJSON.IsObject(), "Invalid type for Technique. It must be an object");
|
||||
|
||||
auto technique = Technique::create(this);
|
||||
_techniques.pushBack(technique);
|
||||
|
||||
|
@ -172,56 +153,60 @@ bool Material::parseTechnique(const rapidjson::GenericValue<rapidjson::UTF8<> >&
|
|||
_currentTechnique = technique;
|
||||
|
||||
// name
|
||||
if (techniqueJSON.HasMember("name"))
|
||||
technique->setName(techniqueJSON["name"].GetString());
|
||||
technique->setName(techniqueProperties->getId());
|
||||
|
||||
|
||||
// passes
|
||||
auto& passesJSON = techniqueJSON["passes"];
|
||||
CCASSERT(passesJSON.IsArray(), "Invalid type for 'passes'");
|
||||
auto space = techniqueProperties->getNextNamespace();
|
||||
while (space)
|
||||
{
|
||||
const char* name = space->getNamespace();
|
||||
if (strcmp(name, "pass") == 0) {
|
||||
parsePass(technique, space);
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < passesJSON.Size(); i++) {
|
||||
auto& passJSON = passesJSON[i];
|
||||
parsePass(technique, passJSON);
|
||||
space = techniqueProperties->getNextNamespace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Material::parsePass(Technique* technique, const rapidjson::GenericValue<rapidjson::UTF8<> >& passJSON)
|
||||
bool Material::parsePass(Technique* technique, Properties* passProperties)
|
||||
{
|
||||
auto pass = Pass::create(technique);
|
||||
technique->addPass(pass);
|
||||
|
||||
// Textures
|
||||
if (passJSON.HasMember("textures")) {
|
||||
auto& texturesJSON = passJSON["textures"];
|
||||
CCASSERT(texturesJSON.IsArray(), "Invalid type for 'textures'");
|
||||
// Pass can have 3 different namespaces:
|
||||
// - one or more "sampler"
|
||||
// - one "renderState"
|
||||
// - one "shader"
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < texturesJSON.Size(); i++) {
|
||||
auto& textureJSON = texturesJSON[i];
|
||||
parseTexture(pass, textureJSON);
|
||||
}
|
||||
auto space = passProperties->getNextNamespace();
|
||||
while (space)
|
||||
{
|
||||
const char* name = space->getNamespace();
|
||||
if (strcmp(name, "sampler") == 0)
|
||||
parseSampler(pass, space);
|
||||
else if (strcmp(name, "shader") == 0)
|
||||
parseShader(pass, space);
|
||||
else if (strcmp(name, "renderState") == 0)
|
||||
parseRenderState(pass, space);
|
||||
else {
|
||||
CCASSERT(false, "Invalid namespace");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Render State
|
||||
if (passJSON.HasMember("renderState")) {
|
||||
parseRenderState(pass, passJSON["renderState"]);
|
||||
}
|
||||
|
||||
// Shaders
|
||||
if (passJSON.HasMember("shader")) {
|
||||
parseShader(pass, passJSON["shader"]);
|
||||
space = passProperties->getNextNamespace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& textureJSON)
|
||||
// cocos2d-x doesn't support Samplers yet. But will be added soon
|
||||
bool Material::parseSampler(Pass* pass, Properties* textureProperties)
|
||||
{
|
||||
CCASSERT(textureJSON.IsObject(), "Invalid type for Texture. It must be an object");
|
||||
|
||||
// required
|
||||
auto filename = textureJSON["path"].GetString();
|
||||
auto filename = textureProperties->getString("path");
|
||||
|
||||
auto texture = Director::getInstance()->getTextureCache()->addImage(filename);
|
||||
if (!texture) {
|
||||
|
@ -236,14 +221,14 @@ bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson:
|
|||
|
||||
// mipmap
|
||||
bool usemipmap = false;
|
||||
const char* mipmap = getOptionalString(textureJSON, "mipmap", "false");
|
||||
const char* mipmap = getOptionalString(textureProperties, "mipmap", "false");
|
||||
if (mipmap && strcasecmp(mipmap, "true")==0) {
|
||||
texture->generateMipmap();
|
||||
usemipmap = true;
|
||||
}
|
||||
|
||||
// valid options: REPEAT, CLAMP
|
||||
const char* wrapS = getOptionalString(textureJSON, "wrapS", "CLAMP_TO_EDGE");
|
||||
const char* wrapS = getOptionalString(textureProperties, "wrapS", "CLAMP_TO_EDGE");
|
||||
if (strcasecmp(wrapS, "REPEAT")==0)
|
||||
texParams.wrapS = GL_REPEAT;
|
||||
else if(strcasecmp(wrapS, "CLAMP_TO_EDGE")==0)
|
||||
|
@ -253,7 +238,7 @@ bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson:
|
|||
|
||||
|
||||
// valid options: REPEAT, CLAMP
|
||||
const char* wrapT = getOptionalString(textureJSON, "wrapT", "CLAMP_TO_EDGE");
|
||||
const char* wrapT = getOptionalString(textureProperties, "wrapT", "CLAMP_TO_EDGE");
|
||||
if (strcasecmp(wrapT, "REPEAT")==0)
|
||||
texParams.wrapT = GL_REPEAT;
|
||||
else if(strcasecmp(wrapT, "CLAMP_TO_EDGE")==0)
|
||||
|
@ -263,7 +248,7 @@ bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson:
|
|||
|
||||
|
||||
// valid options: NEAREST, LINEAR, NEAREST_MIPMAP_NEAREST, LINEAR_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_LINEAR
|
||||
const char* minFilter = getOptionalString(textureJSON, "minFilter", mipmap ? "LINEAR_MIPMAP_NEAREST" : "LINEAR");
|
||||
const char* minFilter = getOptionalString(textureProperties, "minFilter", mipmap ? "LINEAR_MIPMAP_NEAREST" : "LINEAR");
|
||||
if (strcasecmp(minFilter, "NEAREST")==0)
|
||||
texParams.minFilter = GL_NEAREST;
|
||||
else if(strcasecmp(minFilter, "LINEAR")==0)
|
||||
|
@ -280,7 +265,7 @@ bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson:
|
|||
CCLOG("Invalid minFilter: %s", minFilter);
|
||||
|
||||
// valid options: NEAREST, LINEAR
|
||||
const char* magFilter = getOptionalString(textureJSON, "magFilter", "LINEAR");
|
||||
const char* magFilter = getOptionalString(textureProperties, "magFilter", "LINEAR");
|
||||
if (strcasecmp(magFilter, "NEAREST")==0)
|
||||
texParams.magFilter = GL_NEAREST;
|
||||
else if(strcasecmp(magFilter, "LINEAR")==0)
|
||||
|
@ -295,19 +280,16 @@ bool Material::parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Material::parseShader(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& shaderJSON)
|
||||
bool Material::parseShader(Pass* pass, Properties* shaderProperties)
|
||||
{
|
||||
|
||||
CCASSERT(shaderJSON.IsObject(), "Invalid type for 'shader'. It must be an object");
|
||||
|
||||
// vertexShader
|
||||
const char* vertShader = getOptionalString(shaderJSON, "vertexShader", nullptr);
|
||||
const char* vertShader = getOptionalString(shaderProperties, "vertexShader", nullptr);
|
||||
|
||||
// fragmentShader
|
||||
const char* fragShader = getOptionalString(shaderJSON, "fragmentShader", nullptr);
|
||||
const char* fragShader = getOptionalString(shaderProperties, "fragmentShader", nullptr);
|
||||
|
||||
// compileTimeDefines
|
||||
const char* compileTimeDefines = getOptionalString(shaderJSON, "defines", "");
|
||||
const char* compileTimeDefines = getOptionalString(shaderProperties, "defines", "");
|
||||
|
||||
if (vertShader && fragShader)
|
||||
{
|
||||
|
@ -315,11 +297,15 @@ bool Material::parseShader(Pass* pass, const rapidjson::GenericValue<rapidjson::
|
|||
pass->setGLProgramState(glProgramState);
|
||||
|
||||
// Parse uniforms only if the GLProgramState was created
|
||||
for( auto it = shaderJSON.MemberonBegin(); it != shaderJSON.MemberonEnd(); it++)
|
||||
auto property = shaderProperties->getNextProperty();
|
||||
while (property)
|
||||
{
|
||||
// skip "defines", "vertexShader", "fragmentShader"
|
||||
if (isValidUniform(it->name.GetString()))
|
||||
parseUniform(glProgramState, it);
|
||||
if (isValidUniform(property))
|
||||
{
|
||||
parseUniform(glProgramState, shaderProperties, property);
|
||||
}
|
||||
|
||||
property = shaderProperties->getNextProperty();
|
||||
}
|
||||
|
||||
// glProgramState->updateUniformsAndAttributes();
|
||||
|
@ -328,107 +314,75 @@ bool Material::parseShader(Pass* pass, const rapidjson::GenericValue<rapidjson::
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Material::parseUniform(GLProgramState* programState, const rapidjson::Value::ConstMemberIterator& iterator)
|
||||
bool Material::parseUniform(GLProgramState* programState, Properties* properties, const char* uniformName)
|
||||
{
|
||||
const char* key = iterator->name.GetString();
|
||||
auto& value = iterator->value;
|
||||
auto type = properties->getType(uniformName);
|
||||
|
||||
if (value.IsNumber()) {
|
||||
float v = value.GetDouble();
|
||||
programState->setUniformFloat(key, v);
|
||||
switch (type) {
|
||||
case Properties::Type::NUMBER:
|
||||
{
|
||||
auto f = properties->getFloat(uniformName);
|
||||
programState->setUniformFloat(uniformName, f);
|
||||
break;
|
||||
}
|
||||
else if (value.IsArray()) {
|
||||
|
||||
int size = value.Size();
|
||||
switch (size) {
|
||||
case 1:
|
||||
case Properties::Type::STRING:
|
||||
CCASSERT(false, "invalid type for a uniform");
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Properties::Type::VECTOR2:
|
||||
{
|
||||
rapidjson::SizeType idx = 0;
|
||||
float v = value[idx].GetDouble();
|
||||
programState->setUniformFloat(key, v);
|
||||
Vec2 v2;
|
||||
properties->getVec2(uniformName, &v2);
|
||||
programState->setUniformVec2(uniformName, v2);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
|
||||
case Properties::Type::VECTOR3:
|
||||
{
|
||||
Vec2 vect = parseUniformVec2(value);
|
||||
programState->setUniformVec2(key, vect);
|
||||
Vec3 v3;
|
||||
properties->getVec3(uniformName, &v3);
|
||||
programState->setUniformVec3(uniformName, v3);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
|
||||
case Properties::Type::VECTOR4:
|
||||
{
|
||||
Vec3 vect = parseUniformVec3(value);
|
||||
programState->setUniformVec3(key, vect);
|
||||
Vec4 v4;
|
||||
properties->getVec4(uniformName, &v4);
|
||||
programState->setUniformVec4(uniformName, v4);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
|
||||
case Properties::Type::MATRIX:
|
||||
{
|
||||
Vec4 vect = parseUniformVec4(value);
|
||||
programState->setUniformVec4(key, vect);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
Mat4 mat = parseUniformMat4(value);
|
||||
programState->setUniformMat4(key, mat);
|
||||
Mat4 m4;
|
||||
properties->getMat4(uniformName, &m4);
|
||||
programState->setUniformMat4(uniformName, m4);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Vec2 Material::parseUniformVec2(const rapidjson::GenericValue<rapidjson::UTF8<> >& value)
|
||||
{
|
||||
Vec2 ret;
|
||||
rapidjson::SizeType idx = 0;
|
||||
ret.x = value[idx++].GetDouble();
|
||||
ret.y = value[idx++].GetDouble();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Vec3 Material::parseUniformVec3(const rapidjson::GenericValue<rapidjson::UTF8<> >& value)
|
||||
{
|
||||
Vec3 ret;
|
||||
rapidjson::SizeType idx = 0;
|
||||
ret.x = value[idx++].GetDouble();
|
||||
ret.y = value[idx++].GetDouble();
|
||||
ret.z = value[idx++].GetDouble();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Vec4 Material::parseUniformVec4(const rapidjson::GenericValue<rapidjson::UTF8<> >& value)
|
||||
{
|
||||
Vec4 ret;
|
||||
rapidjson::SizeType idx = 0;
|
||||
ret.x = value[idx++].GetDouble();
|
||||
ret.y = value[idx++].GetDouble();
|
||||
ret.z = value[idx++].GetDouble();
|
||||
ret.w = value[idx++].GetDouble();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Mat4 Material::parseUniformMat4(const rapidjson::GenericValue<rapidjson::UTF8<> >& value)
|
||||
{
|
||||
Mat4 ret;
|
||||
|
||||
for(rapidjson::SizeType i= 0; i<16; i++)
|
||||
ret.m[i] = value[i].GetDouble();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Material::parseRenderState(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& renderState)
|
||||
bool Material::parseRenderState(Pass* pass, Properties* properties)
|
||||
{
|
||||
auto state = pass->getStateBlock();
|
||||
|
||||
// Parse uniforms only if the GLProgramState was created
|
||||
for( auto it = renderState.MemberonBegin(); it != renderState.MemberonEnd(); it++)
|
||||
auto property = properties->getNextProperty();
|
||||
while (property)
|
||||
{
|
||||
// Render state only can have "strings" or numbers as values. No objects or lists
|
||||
state->setState(it->name.GetString(), it->value.GetString());
|
||||
// Parse uniforms only if the GLProgramState was created
|
||||
// Render state only can have "strings" or numbers as values. No new namespaces
|
||||
state->setState(property, properties->getString(property));
|
||||
|
||||
property = properties->getNextProperty();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -459,10 +413,15 @@ Technique* Material::getTechnique() const
|
|||
{
|
||||
return _currentTechnique;
|
||||
}
|
||||
|
||||
const Vector<Technique*>& Material::getTechniques() const
|
||||
{
|
||||
return _techniques;
|
||||
}
|
||||
|
||||
Technique* Material::getTechniqueByName(const std::string& name)
|
||||
{
|
||||
for(const auto& technique : _techniques) {
|
||||
CCLOG("technique name: %s", technique->getName().c_str());
|
||||
if (technique->getName().compare(name)==0)
|
||||
return technique;
|
||||
}
|
||||
|
@ -493,7 +452,6 @@ ssize_t Material::getTechniqueCount() const
|
|||
return _techniques.size();
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
// Helpers implementation
|
||||
static bool isValidUniform(const char* name)
|
||||
|
@ -503,11 +461,14 @@ static bool isValidUniform(const char* name)
|
|||
strcmp(name, "fragmentShader")==0);
|
||||
}
|
||||
|
||||
static const char* getOptionalString(const rapidjson::GenericValue<rapidjson::UTF8<> >& json, const char* key, const char* defaultValue)
|
||||
static const char* getOptionalString(Properties* properties, const char* key, const char* defaultValue)
|
||||
{
|
||||
if (json.HasMember(key)) {
|
||||
return json[key].GetString();
|
||||
}
|
||||
return defaultValue;
|
||||
|
||||
const char* ret = properties->getString(key);
|
||||
if (!ret)
|
||||
ret = defaultValue;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#define __cocos2d_libs__CCMaterial__
|
||||
|
||||
#include <string>
|
||||
#include "json/document.h"
|
||||
|
||||
#include "renderer/CCRenderState.h"
|
||||
#include "renderer/CCTechnique.h"
|
||||
|
@ -50,6 +49,7 @@ class Technique;
|
|||
class Pass;
|
||||
class GLProgramState;
|
||||
class Node;
|
||||
class Properties;
|
||||
|
||||
/// Material
|
||||
class CC_DLL Material : public RenderState
|
||||
|
@ -62,7 +62,14 @@ class CC_DLL Material : public RenderState
|
|||
friend class Mesh;
|
||||
|
||||
public:
|
||||
/** Creates a Material with a JSON file containing the definition of the material.
|
||||
/**
|
||||
* Creates a Material using the data from the Properties object defined at the specified URL,
|
||||
* where the URL is of the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
|
||||
* (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
|
||||
*
|
||||
* @param url The URL pointing to the Properties object defining the material.
|
||||
*
|
||||
* @return A new Material or NULL if there was an error.
|
||||
*/
|
||||
static Material* createWithFilename(const std::string& path);
|
||||
|
||||
|
@ -72,6 +79,15 @@ public:
|
|||
*/
|
||||
static Material* createWithGLStateProgram(GLProgramState* programState);
|
||||
|
||||
/**
|
||||
* Creates a material from the specified properties object.
|
||||
*
|
||||
* @param materialProperties The properties object defining the
|
||||
* material (must have namespace equal to 'material').
|
||||
* @return A new Material.
|
||||
*/
|
||||
static Material* createWithProperties(Properties* materialProperties);
|
||||
|
||||
/// returns the material name
|
||||
std::string getName() const;
|
||||
/// sets the material name
|
||||
|
@ -87,38 +103,38 @@ public:
|
|||
*/
|
||||
Technique* getTechniqueByIndex(ssize_t index);
|
||||
|
||||
/** Returns the Technique used by the Material */
|
||||
Technique* getTechnique() const;
|
||||
|
||||
/** Returns the list of Techniques */
|
||||
const Vector<Technique*>& getTechniques() const;
|
||||
|
||||
/** Returns the number of Techniques in the Material. */
|
||||
ssize_t getTechniqueCount() const;
|
||||
|
||||
/** Adds a Technique into the Material */
|
||||
void addTechnique(Technique* technique);
|
||||
|
||||
/** Sets the current technique */
|
||||
void setTechnique(const std::string& techniqueName);
|
||||
|
||||
/** Returns the number of Techniques in the Material. */
|
||||
ssize_t getTechniqueCount() const;
|
||||
|
||||
/** Returns the Technique used by the Material */
|
||||
Technique* getTechnique() const;
|
||||
|
||||
protected:
|
||||
Material();
|
||||
~Material();
|
||||
bool initWithGLProgramState(GLProgramState* state);
|
||||
bool initWithFile(const std::string& file);
|
||||
bool initWithProperties(Properties* materialProperties);
|
||||
|
||||
void setTarget(Node* target);
|
||||
|
||||
bool parseMetadata(const rapidjson::Document& json);
|
||||
bool parseProperties(const rapidjson::Document& json);
|
||||
bool parseTechnique(const rapidjson::GenericValue<rapidjson::UTF8<> >& techniqueJSON);
|
||||
bool parsePass(Technique* technique, const rapidjson::GenericValue<rapidjson::UTF8<> >& passJSON);
|
||||
bool parseTexture(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& textureJSON);
|
||||
bool parseShader(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& shaderJSON);
|
||||
bool parseUniform(GLProgramState* programState, const rapidjson::Value::ConstMemberIterator& iterator);
|
||||
Vec2 parseUniformVec2(const rapidjson::GenericValue<rapidjson::UTF8<> >& uniformJSON);
|
||||
Vec3 parseUniformVec3(const rapidjson::GenericValue<rapidjson::UTF8<> >& uniformJSON);
|
||||
Vec4 parseUniformVec4(const rapidjson::GenericValue<rapidjson::UTF8<> >& uniformJSON);
|
||||
Mat4 parseUniformMat4(const rapidjson::GenericValue<rapidjson::UTF8<> >& uniformJSON);
|
||||
bool parseRenderState(Pass* pass, const rapidjson::GenericValue<rapidjson::UTF8<> >& renderState);
|
||||
bool parseProperties(Properties* properties);
|
||||
bool parseTechnique(Properties* properties);
|
||||
bool parsePass(Technique* technique, Properties* properties);
|
||||
bool parseSampler(Pass* pass, Properties* properties);
|
||||
bool parseShader(Pass* pass, Properties* properties);
|
||||
bool parseUniform(GLProgramState* programState, Properties* properties, const char* uniformName);
|
||||
bool parseRenderState(Pass* pass, Properties* properties);
|
||||
|
||||
|
||||
// material name
|
||||
|
|
|
@ -100,4 +100,9 @@ ssize_t Technique::getPassCount() const
|
|||
return _passes.size();
|
||||
}
|
||||
|
||||
const Vector<Pass*>& Technique::getPasses() const
|
||||
{
|
||||
return _passes;
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -73,6 +73,9 @@ public:
|
|||
/** Returns the number of Passes in the Technique */
|
||||
ssize_t getPassCount() const;
|
||||
|
||||
/** Returns the list of passes */
|
||||
const Vector<Pass*>& getPasses() const;
|
||||
|
||||
protected:
|
||||
Technique();
|
||||
~Technique();
|
||||
|
|
|
@ -30,16 +30,50 @@
|
|||
|
||||
USING_NS_CC;
|
||||
|
||||
MaterialSystemTest::MaterialSystemTest()
|
||||
// MARK: Helper functions
|
||||
|
||||
static void printProperties(Properties* properties, int indent)
|
||||
{
|
||||
ADD_TEST_CASE(Material_MultipleSprite3D);
|
||||
ADD_TEST_CASE(Material_Sprite3DTest);
|
||||
// Print the name and ID of the current namespace.
|
||||
const char* spacename = properties->getNamespace();
|
||||
const char* id = properties->getId();
|
||||
char chindent[64];
|
||||
int i=0;
|
||||
for(i=0; i<indent*2;i++)
|
||||
chindent[i] = ' ';
|
||||
chindent[i] = '\0';
|
||||
|
||||
// ADD_TEST_CASE(Material_SpriteTest);
|
||||
CCLOG("%sNamespace: %s ID: %s\n%s{", chindent, spacename, id, chindent);
|
||||
|
||||
// Print all properties in this namespace.
|
||||
const char* name = properties->getNextProperty();
|
||||
const char* value = NULL;
|
||||
while (name != NULL)
|
||||
{
|
||||
value = properties->getString(name);
|
||||
CCLOG("%s%s = %s", chindent, name, value);
|
||||
name = properties->getNextProperty();
|
||||
}
|
||||
|
||||
// MARK:
|
||||
Properties* space = properties->getNextNamespace();
|
||||
while (space != NULL)
|
||||
{
|
||||
printProperties(space, indent+1);
|
||||
space = properties->getNextNamespace();
|
||||
}
|
||||
|
||||
CCLOG("%s}\n",chindent);
|
||||
}
|
||||
|
||||
// MARK: Tests
|
||||
|
||||
MaterialSystemTest::MaterialSystemTest()
|
||||
{
|
||||
ADD_TEST_CASE(Material_2DEffects);
|
||||
ADD_TEST_CASE(Material_3DEffects);
|
||||
ADD_TEST_CASE(Material_MultipleSprite3D);
|
||||
ADD_TEST_CASE(Material_Sprite3DTest);
|
||||
}
|
||||
|
||||
std::string MaterialSystemBaseTest::title() const
|
||||
{
|
||||
|
@ -48,36 +82,6 @@ std::string MaterialSystemBaseTest::title() const
|
|||
|
||||
// MARK: Tests start here
|
||||
|
||||
void Material_SpriteTest::onEnter()
|
||||
{
|
||||
// Material remove from Sprite since it is hacking.
|
||||
// Sprite (or Node) should have "Effect" instead of "Material"
|
||||
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
auto layer = LayerColor::create(Color4B::BLUE);
|
||||
this->addChild(layer);
|
||||
|
||||
|
||||
auto sprite = Sprite::create("Images/grossini.png");
|
||||
sprite->setNormalizedPosition(Vec2(0.5, 0.5));
|
||||
this->addChild(sprite);
|
||||
|
||||
// auto material = Material::createWithFilename("Materials/effects.material");
|
||||
// sprite->setMaterial(material);
|
||||
|
||||
// material->setTechnique("blur");
|
||||
// material->setTechnique("outline");
|
||||
// material->setTechnique("noise");
|
||||
// material->setTechnique("edge detect");
|
||||
// material->setTechnique("gray+blur");
|
||||
}
|
||||
|
||||
std::string Material_SpriteTest::subtitle() const
|
||||
{
|
||||
return "Material System on Sprite";
|
||||
}
|
||||
|
||||
|
||||
void Material_Sprite3DTest::onEnter()
|
||||
{
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
|
@ -87,9 +91,6 @@ void Material_Sprite3DTest::onEnter()
|
|||
sprite->setTexture("Sprite3DTest/boss.png");
|
||||
this->addChild(sprite);
|
||||
sprite->setNormalizedPosition(Vec2(0.5,0.5));
|
||||
|
||||
// auto material = Material::createWithFilename("Materials/spaceship.material");
|
||||
// sprite->setMaterial(material);
|
||||
}
|
||||
|
||||
std::string Material_Sprite3DTest::subtitle() const
|
||||
|
@ -97,10 +98,6 @@ std::string Material_Sprite3DTest::subtitle() const
|
|||
return "Material System on Sprite3D";
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
void Material_MultipleSprite3D::onEnter()
|
||||
{
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
|
@ -134,3 +131,102 @@ std::string Material_MultipleSprite3D::subtitle() const
|
|||
return "Sprites with multiple meshes";
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
void Material_2DEffects::onEnter()
|
||||
{
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
|
||||
auto properties = Properties::create("Materials/2d_effects.material#sample");
|
||||
|
||||
// Print the properties of every namespace within this one.
|
||||
printProperties(properties, 0);
|
||||
|
||||
Material *mat1 = Material::createWithProperties(properties);
|
||||
|
||||
auto spriteBlur = Sprite::create("Images/grossini.png");
|
||||
spriteBlur->setNormalizedPosition(Vec2(0.2, 0.5));
|
||||
this->addChild(spriteBlur);
|
||||
spriteBlur->setGLProgramState(mat1->getTechniqueByName("blur")->getPassByIndex(0)->getGLProgramState());
|
||||
|
||||
auto spriteOutline = Sprite::create("Images/grossini.png");
|
||||
spriteOutline->setNormalizedPosition(Vec2(0.4, 0.5));
|
||||
this->addChild(spriteOutline);
|
||||
spriteOutline->setGLProgramState(mat1->getTechniqueByName("outline")->getPassByIndex(0)->getGLProgramState());
|
||||
|
||||
auto spriteNoise = Sprite::create("Images/grossini.png");
|
||||
spriteNoise->setNormalizedPosition(Vec2(0.6, 0.5));
|
||||
this->addChild(spriteNoise);
|
||||
spriteNoise->setGLProgramState(mat1->getTechniqueByName("noise")->getPassByIndex(0)->getGLProgramState());
|
||||
|
||||
auto spriteEdgeDetect = Sprite::create("Images/grossini.png");
|
||||
spriteEdgeDetect->setNormalizedPosition(Vec2(0.8, 0.5));
|
||||
this->addChild(spriteEdgeDetect);
|
||||
spriteEdgeDetect->setGLProgramState(mat1->getTechniqueByName("edge_detect")->getPassByIndex(0)->getGLProgramState());
|
||||
}
|
||||
|
||||
std::string Material_2DEffects::subtitle() const
|
||||
{
|
||||
return "Testing effects on Sprite";
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
void Material_3DEffects::onEnter()
|
||||
{
|
||||
MaterialSystemBaseTest::onEnter();
|
||||
|
||||
auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
|
||||
sprite->setScale(8.f);
|
||||
// sprite->setTexture("Sprite3DTest/boss.png");
|
||||
this->addChild(sprite);
|
||||
sprite->setNormalizedPosition(Vec2(0.5,0.5));
|
||||
_sprite = sprite;
|
||||
|
||||
auto rot = RotateBy::create(5, Vec3(30,60,270));
|
||||
auto repeat = RepeatForever::create(rot);
|
||||
sprite->runAction(repeat);
|
||||
|
||||
Material *mat = Material::createWithFilename("Materials/3d_effects.material");
|
||||
mat->setTechnique("lit");
|
||||
sprite->setMaterial(mat);
|
||||
|
||||
// lights
|
||||
auto light1 = AmbientLight::create(Color3B::RED);
|
||||
addChild(light1);
|
||||
|
||||
auto light2 = DirectionLight::create(Vec3(-1,1,0), Color3B::GREEN);
|
||||
addChild(light2);
|
||||
|
||||
this->schedule(CC_CALLBACK_1(Material_3DEffects::changeMaterial, this), 3, "cookie");
|
||||
|
||||
_techniqueState = 0;
|
||||
}
|
||||
|
||||
std::string Material_3DEffects::subtitle() const
|
||||
{
|
||||
return "Testing effects on Sprite3D";
|
||||
}
|
||||
|
||||
void Material_3DEffects::changeMaterial(float dt)
|
||||
{
|
||||
// get it from Mesh 0
|
||||
switch (_techniqueState)
|
||||
{
|
||||
case 0:
|
||||
_sprite->getMaterial(0)->setTechnique("lit");
|
||||
break;
|
||||
case 1:
|
||||
_sprite->getMaterial(0)->setTechnique("unlit");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_techniqueState++;
|
||||
if (_techniqueState>1)
|
||||
_techniqueState = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,15 +35,6 @@ public:
|
|||
virtual std::string title() const override;
|
||||
};
|
||||
|
||||
class Material_SpriteTest : public MaterialSystemBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Material_SpriteTest);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class Material_Sprite3DTest : public MaterialSystemBaseTest
|
||||
{
|
||||
public:
|
||||
|
@ -62,4 +53,28 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class Material_2DEffects : public MaterialSystemBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Material_2DEffects);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class Material_3DEffects : public MaterialSystemBaseTest
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(Material_3DEffects);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
private:
|
||||
void changeMaterial(float dt);
|
||||
|
||||
cocos2d::Sprite3D* _sprite;
|
||||
int _techniqueState;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
material sample
|
||||
{
|
||||
technique blur
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines = THIS_IS_AN_EXAMPLE 1;TOMORROW_IS_HOLIDAY 2
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_Blur.fsh
|
||||
blurRadius = 10
|
||||
sampleNum = 5
|
||||
resolution = 100,100
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
technique outline
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_outline.fsh
|
||||
u_outlineColor = 0.1, 0.2, 0.3
|
||||
u_radius = 0.01
|
||||
u_threshold = 1.75
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
technique noise {
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_Noisy.fsh
|
||||
resolution = 100,100
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
technique edge_detect
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines =
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_edgeDetection.fsh
|
||||
resolution = 100, 100
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
technique gray+blur
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines = TEXTURE_REPEAT
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_Blur.fsh
|
||||
blurRadius = 10
|
||||
sampleNum = 5
|
||||
resolution = 100, 100
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
pass 1
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE_MINUS_SRC_ALPHA
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines =
|
||||
vertexShader = Shaders/example_simple.vsh
|
||||
fragmentShader = Shaders/example_greyScale.fsh
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Images/grossinis_sister1.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
material spaceship
|
||||
{
|
||||
technique unlit
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines = THIS_IS_AN_EXAMPLE 1;TOMORROW_IS_HOLIDAY 2
|
||||
vertexShader = Shaders3D/3d_position_tex.vert
|
||||
fragmentShader = Shaders3D/3d_color_tex.frag
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Sprite3DTest/boss.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
technique lit
|
||||
{
|
||||
pass 0
|
||||
{
|
||||
renderState
|
||||
{
|
||||
blend = true
|
||||
blendSrc = ONE
|
||||
blendDst = ONE_MINUS_SRC_ALPHA
|
||||
}
|
||||
shader
|
||||
{
|
||||
defines = MAX_POINT_LIGHT_NUM 1;MAX_SPOT_LIGHT_NUM 1;MAX_DIRECTIONAL_LIGHT_NUM 1
|
||||
vertexShader = Shaders3D/3d_position_normal_tex.vert
|
||||
fragmentShader = Shaders3D/3d_color_normal_tex.frag
|
||||
}
|
||||
sampler 0
|
||||
{
|
||||
path = Sprite3DTest/boss.png
|
||||
wrapS = CLAMP_TO_EDGE
|
||||
wrapT = CLAMP_TO_EDGE
|
||||
minFilter = LINEAR
|
||||
magFilter = LINEAR
|
||||
mipmap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
{
|
||||
"metadata" : {
|
||||
"version" : 1,
|
||||
"type" : "material"
|
||||
},
|
||||
"name" : "simple effects",
|
||||
"techniques" : [
|
||||
{
|
||||
"name": "blur",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "THIS_IS_AN_EXAMPLE 1;TOMORROW_IS_HOLIDAY 2",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_Blur.fsh",
|
||||
"blurRadius": 10,
|
||||
"sampleNum": 5,
|
||||
"resolution": [100,100]
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "outline",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_outline.fsh",
|
||||
"u_outlineColor": [0.1, 0.2, 0.3],
|
||||
"u_radius": 0.01,
|
||||
"u_threshold": 1.75
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "noise",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_Noisy.fsh",
|
||||
"resolution": [100,100]
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "edge detect",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_edgeDetection.fsh",
|
||||
"resolution": [100,100]
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gray+blur",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "TEXTURE_REPEAT",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_Blur.fsh",
|
||||
"blurRadius": 10,
|
||||
"sampleNum": 5,
|
||||
"resolution": [100,100]
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE_MINUS_SRC_ALPHA",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "",
|
||||
"vertexShader": "Shaders/example_simple.vsh",
|
||||
"fragmentShader": "Shaders/example_greyScale.fsh"
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Images/grossinis_sister1.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"metadata" : {
|
||||
"version" : 1,
|
||||
"type" : "material"
|
||||
},
|
||||
"name" : "spaceship",
|
||||
"techniques" : [
|
||||
{
|
||||
"name": "simple",
|
||||
"passes": [
|
||||
{
|
||||
"renderState": {
|
||||
"blend": "true",
|
||||
"blendSrc": "ONE_MINUS_SRC_ALPHA",
|
||||
"blendDst": "ONE_MINUS_SRC_ALPHA"
|
||||
},
|
||||
"shader" : {
|
||||
"defines": "",
|
||||
"vertexShader": "Shaders/example_3D_PositionTex.vsh",
|
||||
"fragmentShader": "Shaders/example_3D_PositionTex.fsh",
|
||||
"u_color": [1,1,1,1]
|
||||
},
|
||||
"textures": [
|
||||
{
|
||||
"path": "Sprite3DTest/boss.png",
|
||||
"wrapS": "CLAMP_TO_EDGE",
|
||||
"wrapT": "CLAMP_TO_EDGE",
|
||||
"minFilter": "LINEAR",
|
||||
"magFilter": "LINEAR",
|
||||
"mipmap": "false"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#if (MAX_DIRECTIONAL_LIGHT_NUM > 0)
|
||||
uniform vec3 u_DirLightSourceColor[MAX_DIRECTIONAL_LIGHT_NUM];
|
||||
uniform vec3 u_DirLightSourceDirection[MAX_DIRECTIONAL_LIGHT_NUM];
|
||||
#endif
|
||||
#if (MAX_POINT_LIGHT_NUM > 0)
|
||||
uniform vec3 u_PointLightSourceColor[MAX_POINT_LIGHT_NUM];
|
||||
uniform float u_PointLightSourceRangeInverse[MAX_POINT_LIGHT_NUM];
|
||||
#endif
|
||||
#if (MAX_SPOT_LIGHT_NUM > 0)
|
||||
uniform vec3 u_SpotLightSourceColor[MAX_SPOT_LIGHT_NUM];
|
||||
uniform vec3 u_SpotLightSourceDirection[MAX_SPOT_LIGHT_NUM];
|
||||
uniform float u_SpotLightSourceInnerAngleCos[MAX_SPOT_LIGHT_NUM];
|
||||
uniform float u_SpotLightSourceOuterAngleCos[MAX_SPOT_LIGHT_NUM];
|
||||
uniform float u_SpotLightSourceRangeInverse[MAX_SPOT_LIGHT_NUM];
|
||||
#endif
|
||||
uniform vec3 u_AmbientLightSourceColor;
|
||||
|
||||
#ifdef GL_ES
|
||||
varying mediump vec2 TextureCoordOut;
|
||||
#if MAX_POINT_LIGHT_NUM
|
||||
varying mediump vec3 v_vertexToPointLightDirection[MAX_POINT_LIGHT_NUM];
|
||||
#endif
|
||||
#if MAX_SPOT_LIGHT_NUM
|
||||
varying mediump vec3 v_vertexToSpotLightDirection[MAX_SPOT_LIGHT_NUM];
|
||||
#endif
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
varying mediump vec3 v_normal;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
varying vec2 TextureCoordOut;
|
||||
#if MAX_POINT_LIGHT_NUM
|
||||
varying vec3 v_vertexToPointLightDirection[MAX_POINT_LIGHT_NUM];
|
||||
#endif
|
||||
#if MAX_SPOT_LIGHT_NUM
|
||||
varying vec3 v_vertexToSpotLightDirection[MAX_SPOT_LIGHT_NUM];
|
||||
#endif
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
varying vec3 v_normal;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
uniform vec4 u_color;
|
||||
|
||||
vec3 computeLighting(vec3 normalVector, vec3 lightDirection, vec3 lightColor, float attenuation)
|
||||
{
|
||||
float diffuse = max(dot(normalVector, lightDirection), 0.0);
|
||||
vec3 diffuseColor = lightColor * diffuse * attenuation;
|
||||
|
||||
return diffuseColor;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
vec3 normal = normalize(v_normal);
|
||||
#endif
|
||||
|
||||
vec4 combinedColor = vec4(u_AmbientLightSourceColor, 1.0);
|
||||
|
||||
// Directional light contribution
|
||||
#if (MAX_DIRECTIONAL_LIGHT_NUM > 0)
|
||||
for (int i = 0; i < MAX_DIRECTIONAL_LIGHT_NUM; ++i)
|
||||
{
|
||||
vec3 lightDirection = normalize(u_DirLightSourceDirection[i] * 2.0);
|
||||
combinedColor.xyz += computeLighting(normal, -lightDirection, u_DirLightSourceColor[i], 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Point light contribution
|
||||
#if (MAX_POINT_LIGHT_NUM > 0)
|
||||
for (int i = 0; i < MAX_POINT_LIGHT_NUM; ++i)
|
||||
{
|
||||
vec3 ldir = v_vertexToPointLightDirection[i] * u_PointLightSourceRangeInverse[i];
|
||||
float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0);
|
||||
combinedColor.xyz += computeLighting(normal, normalize(v_vertexToPointLightDirection[i]), u_PointLightSourceColor[i], attenuation);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Spot light contribution
|
||||
#if (MAX_SPOT_LIGHT_NUM > 0)
|
||||
for (int i = 0; i < MAX_SPOT_LIGHT_NUM; ++i)
|
||||
{
|
||||
// Compute range attenuation
|
||||
vec3 ldir = v_vertexToSpotLightDirection[i] * u_SpotLightSourceRangeInverse[i];
|
||||
float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0);
|
||||
vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection[i]);
|
||||
|
||||
vec3 spotLightDirection = normalize(u_SpotLightSourceDirection[i] * 2.0);
|
||||
|
||||
// "-lightDirection" is used because light direction points in opposite direction to spot direction.
|
||||
float spotCurrentAngleCos = dot(spotLightDirection, -vertexToSpotLightDirection);
|
||||
|
||||
// Apply spot attenuation
|
||||
attenuation *= smoothstep(u_SpotLightSourceOuterAngleCos[i], u_SpotLightSourceInnerAngleCos[i], spotCurrentAngleCos);
|
||||
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||
combinedColor.xyz += computeLighting(normal, vertexToSpotLightDirection, u_SpotLightSourceColor[i], attenuation);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color * combinedColor;
|
||||
#else
|
||||
gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color;
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifdef GL_ES
|
||||
varying mediump vec2 TextureCoordOut;
|
||||
#else
|
||||
varying vec2 TextureCoordOut;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#if (MAX_POINT_LIGHT_NUM > 0)
|
||||
uniform vec3 u_PointLightSourcePosition[MAX_POINT_LIGHT_NUM];
|
||||
#endif
|
||||
#if (MAX_SPOT_LIGHT_NUM > 0)
|
||||
uniform vec3 u_SpotLightSourcePosition[MAX_SPOT_LIGHT_NUM];
|
||||
#endif
|
||||
|
||||
attribute vec4 a_position;
|
||||
attribute vec2 a_texCoord;
|
||||
attribute vec3 a_normal;
|
||||
varying vec2 TextureCoordOut;
|
||||
|
||||
#if MAX_POINT_LIGHT_NUM
|
||||
varying vec3 v_vertexToPointLightDirection[MAX_POINT_LIGHT_NUM];
|
||||
#endif
|
||||
#if MAX_SPOT_LIGHT_NUM
|
||||
varying vec3 v_vertexToSpotLightDirection[MAX_SPOT_LIGHT_NUM];
|
||||
#endif
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
varying vec3 v_normal;
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 ePosition = CC_MVMatrix * a_position;
|
||||
#if (MAX_POINT_LIGHT_NUM > 0)
|
||||
for (int i = 0; i < MAX_POINT_LIGHT_NUM; ++i)
|
||||
{
|
||||
v_vertexToPointLightDirection[i] = u_PointLightSourcePosition[i].xyz - ePosition.xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (MAX_SPOT_LIGHT_NUM > 0)
|
||||
for (int i = 0; i < MAX_SPOT_LIGHT_NUM; ++i)
|
||||
{
|
||||
v_vertexToSpotLightDirection[i] = u_SpotLightSourcePosition[i] - ePosition.xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((MAX_DIRECTIONAL_LIGHT_NUM > 0) || (MAX_POINT_LIGHT_NUM > 0) || (MAX_SPOT_LIGHT_NUM > 0))
|
||||
v_normal = CC_NormalMatrix * a_normal;
|
||||
#endif
|
||||
|
||||
TextureCoordOut = a_texCoord;
|
||||
TextureCoordOut.y = 1.0 - TextureCoordOut.y;
|
||||
gl_Position = CC_PMatrix * ePosition;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
attribute vec3 a_position;
|
||||
|
||||
attribute vec4 a_blendWeight;
|
||||
attribute vec4 a_blendIndex;
|
||||
|
||||
attribute vec2 a_texCoord;
|
||||
|
||||
const int SKINNING_JOINT_COUNT = 60;
|
||||
// Uniforms
|
||||
uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
|
||||
|
||||
// Varyings
|
||||
varying vec2 TextureCoordOut;
|
||||
|
||||
vec4 getPosition()
|
||||
{
|
||||
float blendWeight = a_blendWeight[0];
|
||||
|
||||
int matrixIndex = int (a_blendIndex[0]) * 3;
|
||||
vec4 matrixPalette1 = u_matrixPalette[matrixIndex] * blendWeight;
|
||||
vec4 matrixPalette2 = u_matrixPalette[matrixIndex + 1] * blendWeight;
|
||||
vec4 matrixPalette3 = u_matrixPalette[matrixIndex + 2] * blendWeight;
|
||||
|
||||
|
||||
blendWeight = a_blendWeight[1];
|
||||
if (blendWeight > 0.0)
|
||||
{
|
||||
matrixIndex = int(a_blendIndex[1]) * 3;
|
||||
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
|
||||
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
|
||||
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
|
||||
|
||||
blendWeight = a_blendWeight[2];
|
||||
if (blendWeight > 0.0)
|
||||
{
|
||||
matrixIndex = int(a_blendIndex[2]) * 3;
|
||||
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
|
||||
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
|
||||
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
|
||||
|
||||
blendWeight = a_blendWeight[3];
|
||||
if (blendWeight > 0.0)
|
||||
{
|
||||
matrixIndex = int(a_blendIndex[3]) * 3;
|
||||
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
|
||||
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
|
||||
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec4 _skinnedPosition;
|
||||
vec4 postion = vec4(a_position, 1.0);
|
||||
_skinnedPosition.x = dot(postion, matrixPalette1);
|
||||
_skinnedPosition.y = dot(postion, matrixPalette2);
|
||||
_skinnedPosition.z = dot(postion, matrixPalette3);
|
||||
_skinnedPosition.w = postion.w;
|
||||
|
||||
return _skinnedPosition;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 position = getPosition();
|
||||
gl_Position = CC_MVPMatrix * position;
|
||||
|
||||
TextureCoordOut = a_texCoord;
|
||||
TextureCoordOut.y = 1.0 - TextureCoordOut.y;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec2 a_texCoord;
|
||||
|
||||
varying vec2 TextureCoordOut;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = CC_MVPMatrix * a_position;
|
||||
TextureCoordOut = a_texCoord;
|
||||
TextureCoordOut.y = 1.0 - TextureCoordOut.y;
|
||||
}
|
Loading…
Reference in New Issue