Merge pull request #11705 from ricardoquesada/material_cleanup

cleanup Material Code
This commit is contained in:
Ricardo Quesada 2015-05-05 16:59:29 -07:00
commit deeaf992cd
8 changed files with 35 additions and 228 deletions

View File

@ -108,7 +108,6 @@ Node::Node(void)
, _userData(nullptr) , _userData(nullptr)
, _userObject(nullptr) , _userObject(nullptr)
, _glProgramState(nullptr) , _glProgramState(nullptr)
, _material(nullptr)
, _orderOfArrival(0) , _orderOfArrival(0)
, _running(false) , _running(false)
, _visible(true) , _visible(true)
@ -820,25 +819,6 @@ void Node::setUserObject(Ref *userObject)
_userObject = userObject; _userObject = userObject;
} }
Material* Node::getMaterial() const
{
return _material;
}
void Node::setMaterial(Material* material)
{
if (_material != material)
{
if (_material)
_material->setTarget(nullptr);
CC_SAFE_RELEASE(_material);
_material = material;
CC_SAFE_RETAIN(_material);
_material->setTarget(this);
}
}
GLProgramState* Node::getGLProgramState() const GLProgramState* Node::getGLProgramState() const
{ {
return _glProgramState; return _glProgramState;

View File

@ -1811,7 +1811,6 @@ protected:
Ref *_userObject; ///< A user assigned Object Ref *_userObject; ///< A user assigned Object
GLProgramState *_glProgramState; ///< OpenGL Program State GLProgramState *_glProgramState; ///< OpenGL Program State
Material* _material;
int _orderOfArrival; ///< used to preserve sequence while sorting children with the same localZOrder int _orderOfArrival; ///< used to preserve sequence while sorting children with the same localZOrder

View File

@ -598,11 +598,7 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
if(_insideBounds) if(_insideBounds)
#endif #endif
{ {
if (_material) { _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform, flags);
_quadCommand.init(_globalZOrder, _material, &_quad, 1, transform, flags);
} else {
_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform, flags);
}
renderer->addCommand(&_quadCommand); renderer->addCommand(&_quadCommand);
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW

View File

@ -39,8 +39,6 @@
#include "renderer/CCRenderer.h" #include "renderer/CCRenderer.h"
#include "math/Mat4.h" #include "math/Mat4.h"
#define USE_MATERIAL 1
using namespace std; using namespace std;
NS_CC_BEGIN NS_CC_BEGIN
@ -270,8 +268,6 @@ void Mesh::setTexture(const std::string& texPath)
void Mesh::setTexture(Texture2D* tex) void Mesh::setTexture(Texture2D* tex)
{ {
#if USE_MATERIAL
// Texture must be saved for future use // Texture must be saved for future use
// it doesn't matter if the material is already set or not // it doesn't matter if the material is already set or not
// This functionality is added for compatibility issues // This functionality is added for compatibility issues
@ -291,15 +287,6 @@ void Mesh::setTexture(Texture2D* tex)
} }
bindMeshCommand(); bindMeshCommand();
#else
if (tex != _texture)
{
CC_SAFE_RETAIN(tex);
CC_SAFE_RELEASE(_texture);
_texture = tex;
bindMeshCommand();
}
#endif
} }
Texture2D* Mesh::getTexture() const Texture2D* Mesh::getTexture() const
@ -332,7 +319,6 @@ void Mesh::draw(Renderer* renderer, float globalZOrder, const Mat4& transform, u
flags |= Node::FLAGS_RENDER_AS_3D; flags |= Node::FLAGS_RENDER_AS_3D;
#if USE_MATERIAL
_meshCommand.init(globalZ, _meshCommand.init(globalZ,
_material, _material,
getVertexBuffer(), getVertexBuffer(),
@ -367,48 +353,6 @@ void Mesh::draw(Renderer* renderer, float globalZOrder, const Mat4& transform, u
if (scene && scene->getLights().size() > 0) if (scene && scene->getLights().size() > 0)
setLightUniforms(programState, scene, color, lightMask); setLightUniforms(programState, scene, color, lightMask);
} }
#else
if(!_texture)
{
//let the mesh use a dummy texture instead of the missing or crashing texture file
setTexture(getDummyTexture());
}
GLuint textureID = _texture->getName();
_meshCommand.init(globalZ,
textureID,
_glProgramState,
_blend,
getVertexBuffer(),
getIndexBuffer(),
getPrimitiveType(),
getIndexFormat(),
getIndexCount(),
transform,
flags);
if (forceDepthWrite)
{
_meshCommand.setDepthWriteEnabled(true);
}
_meshCommand.setTransparent(isTransparent);
//support tint and fade
_meshCommand.setDisplayColor(color);
if (_skin)
{
_meshCommand.setMatrixPaletteSize((int)_skin->getMatrixPaletteSize());
_meshCommand.setMatrixPalette(_skin->getMatrixPalette());
}
_meshCommand.setLightMask(lightMask);
#endif // !MATERIAL
renderer->addCommand(&_meshCommand); renderer->addCommand(&_meshCommand);
} }
@ -439,7 +383,6 @@ void Mesh::setMeshIndexData(MeshIndexData* subMesh)
void Mesh::setGLProgramState(GLProgramState* glProgramState) void Mesh::setGLProgramState(GLProgramState* glProgramState)
{ {
// XXX create dummy texture // XXX create dummy texture
#if USE_MATERIAL
auto material = Material::createWithGLStateProgram(glProgramState); auto material = Material::createWithGLStateProgram(glProgramState);
setMaterial(material); setMaterial(material);
@ -451,25 +394,13 @@ void Mesh::setGLProgramState(GLProgramState* glProgramState)
setBlendFunc(_blend); setBlendFunc(_blend);
bindMeshCommand(); bindMeshCommand();
#else
if (_glProgramState != glProgramState)
{
CC_SAFE_RETAIN(glProgramState);
CC_SAFE_RELEASE(_glProgramState);
_glProgramState = glProgramState;
bindMeshCommand();
}
#endif
} }
GLProgramState* Mesh::getGLProgramState() const GLProgramState* Mesh::getGLProgramState() const
{ {
#if USE_MATERIAL return _material ?
return _material ? _material->_currentTechnique->_passes.at(0)->getGLProgramState() _material->_currentTechnique->_passes.at(0)->getGLProgramState()
: nullptr; : nullptr;
#else
return _glProgramState;
#endif
} }
void Mesh::calculateAABB() void Mesh::calculateAABB()
@ -511,7 +442,6 @@ void Mesh::calculateAABB()
void Mesh::bindMeshCommand() void Mesh::bindMeshCommand()
{ {
#if USE_MATERIAL
if (_material && _meshIndexData) if (_material && _meshIndexData)
{ {
auto pass = _material->_currentTechnique->_passes.at(0); auto pass = _material->_currentTechnique->_passes.at(0);
@ -526,15 +456,6 @@ void Mesh::bindMeshCommand()
_material->getStateBlock()->setCullFace(true); _material->getStateBlock()->setCullFace(true);
_material->getStateBlock()->setDepthTest(true); _material->getStateBlock()->setDepthTest(true);
} }
#else
if (_glProgramState && _meshIndexData && _texture)
{
GLuint texID = _texture ? _texture->getName() : 0;
_meshCommand.genMaterialID(texID, _glProgramState, _meshIndexData->getVertexBuffer()->getVBO(), _meshIndexData->getIndexBuffer()->getVBO(), _blend);
_meshCommand.setCullFaceEnabled(true);
_meshCommand.setDepthTestEnabled(true);
}
#endif
} }
void Mesh::setLightUniforms(GLProgramState* glProgramState, Scene* scene, const Vec4& color, unsigned int lightmask) void Mesh::setLightUniforms(GLProgramState* glProgramState, Scene* scene, const Vec4& color, unsigned int lightmask)
@ -680,7 +601,6 @@ void Mesh::setLightUniforms(GLProgramState* glProgramState, Scene* scene, const
void Mesh::setBlendFunc(const BlendFunc &blendFunc) void Mesh::setBlendFunc(const BlendFunc &blendFunc)
{ {
#if USE_MATERIAL
// Blend must be saved for future use // Blend must be saved for future use
// it doesn't matter if the material is already set or not // it doesn't matter if the material is already set or not
// This functionality is added for compatibility issues // This functionality is added for compatibility issues
@ -694,22 +614,12 @@ void Mesh::setBlendFunc(const BlendFunc &blendFunc)
_material->getStateBlock()->setBlendFunc(blendFunc); _material->getStateBlock()->setBlendFunc(blendFunc);
bindMeshCommand(); bindMeshCommand();
} }
#else
if(_blend.src != blendFunc.src || _blend.dst != blendFunc.dst)
{
_blend = blendFunc;
bindMeshCommand();
}
#endif
} }
const BlendFunc& Mesh::getBlendFunc() const const BlendFunc& Mesh::getBlendFunc() const
{ {
#if USE_MATERIAL
// return _material->_currentTechnique->_passes.at(0)->getBlendFunc(); // return _material->_currentTechnique->_passes.at(0)->getBlendFunc();
return _blend; return _blend;
#else
return _blend;
#endif
} }
GLenum Mesh::getPrimitiveType() const GLenum Mesh::getPrimitiveType() const

View File

@ -44,8 +44,6 @@ QuadCommand::QuadCommand()
,_blendType(BlendFunc::DISABLE) ,_blendType(BlendFunc::DISABLE)
,_quads(nullptr) ,_quads(nullptr)
,_quadsCount(0) ,_quadsCount(0)
,_material(nullptr)
,_multiplePass(false)
{ {
_type = RenderCommand::Type::QUAD_COMMAND; _type = RenderCommand::Type::QUAD_COMMAND;
} }
@ -73,24 +71,6 @@ void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* shad
} }
} }
void QuadCommand::init(float globalOrder, Material* material, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, const Mat4& mv, uint32_t flags)
{
CCASSERT(material, "Invalid Material");
RenderCommand::init(globalOrder, mv, flags);
_quadsCount = quadCount;
_quads = quads;
_mv = mv;
if (_material != material) {
_material = material;
generateMaterialID();
}
}
void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, const Mat4 &mv) void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, const Mat4 &mv)
{ {
init(globalOrder, textureID, shader, blendType, quads, quadCount, mv, 0); init(globalOrder, textureID, shader, blendType, quads, quadCount, mv, 0);
@ -98,70 +78,36 @@ void QuadCommand::init(float globalOrder, GLuint textureID, GLProgramState* shad
QuadCommand::~QuadCommand() QuadCommand::~QuadCommand()
{ {
CC_SAFE_RELEASE(_material);
} }
void QuadCommand::generateMaterialID() void QuadCommand::generateMaterialID()
{ {
_skipBatching = false; _skipBatching = false;
_multiplePass = false;
if (_material)
{
auto technique = _material->getTechnique();
auto count = technique->getPassCount();
// multiple pass: no batching if(_glProgramState->getUniformCount() == 0)
if (count > 1) { {
_materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH; int glProgram = (int)_glProgramState->getGLProgram()->getProgram();
_skipBatching = true; int intArray[4] = { glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst};
_multiplePass = true;
} _materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
// count == 1. Ok for batching
else if (technique->getPassByIndex(0)->getGLProgramState()->getUniformCount() == 0)
{
_materialID = technique->getPassByIndex(0)->getHash();
}
// count == 1 + custom uniforms. No batching
else
{
_materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH;
_skipBatching = true;
}
} }
else else
{ {
if(_glProgramState->getUniformCount() == 0) _materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH;
{ _skipBatching = true;
int glProgram = (int)_glProgramState->getGLProgram()->getProgram();
int intArray[4] = { glProgram, (int)_textureID, (int)_blendType.src, (int)_blendType.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}
else
{
_materialID = Renderer::MATERIAL_ID_DO_NOT_BATCH;
_skipBatching = true;
}
} }
} }
void QuadCommand::useMaterial() const void QuadCommand::useMaterial() const
{ {
CCASSERT(!_multiplePass, "Material with multiple passes cannot be bound"); //Set texture
GL::bindTexture2D(_textureID);
if (!_material) {
//Set texture //set blend mode
GL::bindTexture2D(_textureID); GL::blendFunc(_blendType.src, _blendType.dst);
//set blend mode _glProgramState->applyGLProgram(_mv);
GL::blendFunc(_blendType.src, _blendType.dst); _glProgramState->applyUniforms();
_glProgramState->applyGLProgram(_mv);
_glProgramState->applyUniforms();
} else {
_material->getTechnique()->getPassByIndex(0)->bind(_mv);
}
} }
NS_CC_END NS_CC_END

View File

@ -35,8 +35,6 @@
NS_CC_BEGIN NS_CC_BEGIN
class Material;
/** /**
Command used to render one or more Quads, similar to TrianglesCommand. Command used to render one or more Quads, similar to TrianglesCommand.
Every QuadCommand will have generate material ID by give textureID, glProgramState, Blend function Every QuadCommand will have generate material ID by give textureID, glProgramState, Blend function
@ -63,8 +61,6 @@ public:
void init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, void init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv, uint32_t flags); const Mat4& mv, uint32_t flags);
void init(float globalOrder, Material* material, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, const Mat4& mv, uint32_t flags);
/**Deprecated function, the params is similar as the upper init function, with flags equals 0.*/ /**Deprecated function, the params is similar as the upper init function, with flags equals 0.*/
CC_DEPRECATED_ATTRIBUTE void init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, CC_DEPRECATED_ATTRIBUTE void init(float globalOrder, GLuint textureID, GLProgramState* shader, const BlendFunc& blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount,
const Mat4& mv); const Mat4& mv);
@ -84,9 +80,6 @@ public:
inline BlendFunc getBlendType() const { return _blendType; } inline BlendFunc getBlendType() const { return _blendType; }
/**Get the model view matrix.*/ /**Get the model view matrix.*/
inline const Mat4& getModelView() const { return _mv; } inline const Mat4& getModelView() const { return _mv; }
Material* getMaterial() const { return _material; }
bool isMultiplePass() const { return _multiplePass; }
protected: protected:
/**Generate the material ID by textureID, glProgramState, and blend function.*/ /**Generate the material ID by textureID, glProgramState, and blend function.*/
@ -106,10 +99,6 @@ protected:
ssize_t _quadsCount; ssize_t _quadsCount;
/**Model view matrix when rendering the triangles.*/ /**Model view matrix when rendering the triangles.*/
Mat4 _mv; Mat4 _mv;
// weak ref
Material* _material;
bool _multiplePass;
}; };
NS_CC_END NS_CC_END

View File

@ -695,6 +695,8 @@ void Renderer::clear()
glDepthMask(true); glDepthMask(true);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(false); glDepthMask(false);
RenderState::StateBlock::_defaultState->setDepthWrite(false);
} }
void Renderer::setDepthTest(bool enable) void Renderer::setDepthTest(bool enable)
@ -886,10 +888,10 @@ void Renderer::drawBatchedQuads()
glBindBuffer(GL_ARRAY_BUFFER, _quadbuffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, _quadbuffersVBO[0]);
// option 1: subdata // option 1: subdata
// glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); // glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] );
// option 2: data // option 2: data
// glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW);
// option 3: orphaning + glMapBuffer // option 3: orphaning + glMapBuffer
glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4, nullptr, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4, nullptr, GL_DYNAMIC_DRAW);
@ -947,27 +949,7 @@ void Renderer::drawBatchedQuads()
//Use new material //Use new material
_lastMaterialID = newMaterialID; _lastMaterialID = newMaterialID;
if (cmd->isMultiplePass()) { cmd->useMaterial();
indexToDraw = cmd->getQuadCount() * 6;
for(auto& pass : cmd->getMaterial()->_currentTechnique->_passes) {
pass->bind(cmd->getModelView());
glDrawElements(GL_TRIANGLES, (GLsizei) indexToDraw, GL_UNSIGNED_SHORT, (GLvoid*) (startIndex*sizeof(_indices[0])) );
_drawnBatches++;
_drawnVertices += indexToDraw;
pass->unbind();
}
indexToDraw = 0;
commandQueued = false;
} else {
cmd->useMaterial();
}
} }
if (commandQueued) if (commandQueued)

View File

@ -35,8 +35,10 @@ USING_NS_CC;
MaterialSystemTest::MaterialSystemTest() MaterialSystemTest::MaterialSystemTest()
{ {
ADD_TEST_CASE(Material_MultipleSprite3D); ADD_TEST_CASE(Material_MultipleSprite3D);
ADD_TEST_CASE(Material_SpriteTest);
ADD_TEST_CASE(Material_Sprite3DTest); ADD_TEST_CASE(Material_Sprite3DTest);
// ADD_TEST_CASE(Material_SpriteTest);
} }
// MARK: // MARK:
@ -50,6 +52,9 @@ std::string MaterialSystemBaseTest::title() const
void Material_SpriteTest::onEnter() void Material_SpriteTest::onEnter()
{ {
// Material remove from Sprite since it is hacking.
// Sprite (or Node) should have "Effect" instead of "Material"
MaterialSystemBaseTest::onEnter(); MaterialSystemBaseTest::onEnter();
auto layer = LayerColor::create(Color4B::BLUE); auto layer = LayerColor::create(Color4B::BLUE);
this->addChild(layer); this->addChild(layer);
@ -59,14 +64,14 @@ void Material_SpriteTest::onEnter()
sprite->setNormalizedPosition(Vec2(0.5, 0.5)); sprite->setNormalizedPosition(Vec2(0.5, 0.5));
this->addChild(sprite); this->addChild(sprite);
auto material = Material::createWithFilename("Materials/effects.material"); // auto material = Material::createWithFilename("Materials/effects.material");
sprite->setMaterial(material); // sprite->setMaterial(material);
// material->setTechnique("blur"); // material->setTechnique("blur");
// material->setTechnique("outline"); // material->setTechnique("outline");
// material->setTechnique("noise"); // material->setTechnique("noise");
// material->setTechnique("edge detect"); // material->setTechnique("edge detect");
material->setTechnique("gray+blur"); // material->setTechnique("gray+blur");
} }
std::string Material_SpriteTest::subtitle() const std::string Material_SpriteTest::subtitle() const