mirror of https://github.com/axmolengine/axmol.git
MeshCommand uses StateBlock
When MeshCommand is used with GLProgramState, it will use the StateBlock internally, instead of the manual and error prone way of keeping state
This commit is contained in:
parent
703852de69
commit
ac54dad9a0
|
@ -49,23 +49,27 @@ NS_CC_BEGIN
|
||||||
MeshCommand::MeshCommand()
|
MeshCommand::MeshCommand()
|
||||||
: _textureID(0)
|
: _textureID(0)
|
||||||
, _glProgramState(nullptr)
|
, _glProgramState(nullptr)
|
||||||
, _blendType(BlendFunc::DISABLE)
|
|
||||||
, _displayColor(1.0f, 1.0f, 1.0f, 1.0f)
|
, _displayColor(1.0f, 1.0f, 1.0f, 1.0f)
|
||||||
, _matrixPalette(nullptr)
|
, _matrixPalette(nullptr)
|
||||||
, _matrixPaletteSize(0)
|
, _matrixPaletteSize(0)
|
||||||
, _materialID(0)
|
, _materialID(0)
|
||||||
, _vao(0)
|
, _vao(0)
|
||||||
, _cullFaceEnabled(false)
|
|
||||||
, _cullFace(GL_BACK)
|
|
||||||
, _depthTestEnabled(false)
|
|
||||||
, _depthWriteEnabled(false)
|
|
||||||
, _forceDepthWrite(false)
|
|
||||||
, _renderStateCullFaceEnabled(false)
|
|
||||||
, _renderStateDepthTest(false)
|
|
||||||
, _renderStateDepthWrite(GL_FALSE)
|
|
||||||
, _material(nullptr)
|
, _material(nullptr)
|
||||||
|
, _stateBlock(nullptr)
|
||||||
|
, _forceDepthWrite(false)
|
||||||
{
|
{
|
||||||
_type = RenderCommand::Type::MESH_COMMAND;
|
_type = RenderCommand::Type::MESH_COMMAND;
|
||||||
|
|
||||||
|
_stateBlock = RenderState::StateBlock::create();
|
||||||
|
CC_SAFE_RETAIN(_stateBlock);
|
||||||
|
|
||||||
|
_stateBlock->setCullFace(false);
|
||||||
|
_stateBlock->setCullFaceSide(RenderState::CULL_FACE_SIDE_BACK);
|
||||||
|
_stateBlock->setDepthTest(false);
|
||||||
|
_stateBlock->setDepthWrite(false);
|
||||||
|
_stateBlock->setBlend(true);
|
||||||
|
|
||||||
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||||
// listen the event that renderer was recreated on Android/WP8
|
// listen the event that renderer was recreated on Android/WP8
|
||||||
_rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCommand::listenRendererRecreated, this));
|
_rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCommand::listenRendererRecreated, this));
|
||||||
|
@ -127,12 +131,12 @@ void MeshCommand::init(float globalZOrder,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
CCASSERT(glProgramState, "GLProgramState cannot be nill");
|
CCASSERT(glProgramState, "GLProgramState cannot be nill");
|
||||||
|
CCASSERT(!_material, "cannot init with GLProgramState if previously inited without GLProgramState");
|
||||||
|
|
||||||
RenderCommand::init(globalZOrder, mv, flags);
|
RenderCommand::init(globalZOrder, mv, flags);
|
||||||
|
|
||||||
_globalOrder = globalZOrder;
|
_globalOrder = globalZOrder;
|
||||||
_textureID = textureID;
|
_textureID = textureID;
|
||||||
_blendType = blendType;
|
|
||||||
_glProgramState = glProgramState;
|
_glProgramState = glProgramState;
|
||||||
|
|
||||||
_vertexBuffer = vertexBuffer;
|
_vertexBuffer = vertexBuffer;
|
||||||
|
@ -143,27 +147,34 @@ void MeshCommand::init(float globalZOrder,
|
||||||
_mv.set(mv);
|
_mv.set(mv);
|
||||||
|
|
||||||
_is3D = true;
|
_is3D = true;
|
||||||
|
|
||||||
|
if (!_stateBlock) {
|
||||||
|
_stateBlock = RenderState::StateBlock::create();
|
||||||
|
CC_SAFE_RETAIN(_stateBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateBlock->setBlendFunc(blendType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::setCullFaceEnabled(bool enable)
|
void MeshCommand::setCullFaceEnabled(bool enable)
|
||||||
{
|
{
|
||||||
CCASSERT(!_material, "If using material, you should call material->setCullFace()");
|
CCASSERT(!_material, "If using material, you should call material->setCullFace()");
|
||||||
|
|
||||||
_cullFaceEnabled = enable;
|
_stateBlock->setCullFace(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::setCullFace(GLenum cullFace)
|
void MeshCommand::setCullFace(GLenum cullFace)
|
||||||
{
|
{
|
||||||
CCASSERT(!_material, "If using material, you should call material->setCullFaceSide()");
|
CCASSERT(!_material, "If using material, you should call material->setCullFaceSide()");
|
||||||
|
|
||||||
_cullFace = cullFace;
|
_stateBlock->setCullFaceSide((RenderState::CullFaceSide)cullFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::setDepthTestEnabled(bool enable)
|
void MeshCommand::setDepthTestEnabled(bool enable)
|
||||||
{
|
{
|
||||||
CCASSERT(!_material, "If using material, you should call material->setDepthTest()");
|
CCASSERT(!_material, "If using material, you should call material->setDepthTest()");
|
||||||
|
|
||||||
_depthTestEnabled = enable;
|
_stateBlock->setDepthTest(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::setDepthWriteEnabled(bool enable)
|
void MeshCommand::setDepthWriteEnabled(bool enable)
|
||||||
|
@ -171,7 +182,7 @@ void MeshCommand::setDepthWriteEnabled(bool enable)
|
||||||
CCASSERT(!_material, "If using material, you should call material->setDepthWrite()");
|
CCASSERT(!_material, "If using material, you should call material->setDepthWrite()");
|
||||||
|
|
||||||
_forceDepthWrite = enable;
|
_forceDepthWrite = enable;
|
||||||
_depthWriteEnabled = enable;
|
_stateBlock->setDepthWrite(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::setDisplayColor(const Vec4& color)
|
void MeshCommand::setDisplayColor(const Vec4& color)
|
||||||
|
@ -205,16 +216,18 @@ void MeshCommand::setTransparent(bool value)
|
||||||
|
|
||||||
if (_isTransparent && !_forceDepthWrite)
|
if (_isTransparent && !_forceDepthWrite)
|
||||||
{
|
{
|
||||||
_depthWriteEnabled = false;
|
_stateBlock->setDepthWrite(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_depthWriteEnabled = true;
|
_stateBlock->setDepthWrite(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshCommand::~MeshCommand()
|
MeshCommand::~MeshCommand()
|
||||||
{
|
{
|
||||||
|
CC_SAFE_RELEASE(_stateBlock);
|
||||||
|
|
||||||
releaseVAO();
|
releaseVAO();
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
||||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener);
|
Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener);
|
||||||
|
@ -227,64 +240,8 @@ void MeshCommand::applyRenderState()
|
||||||
|
|
||||||
// blend and texture
|
// blend and texture
|
||||||
GL::bindTexture2D(_textureID);
|
GL::bindTexture2D(_textureID);
|
||||||
GL::blendFunc(_blendType.src, _blendType.dst);
|
|
||||||
|
|
||||||
// cull face
|
_stateBlock->bind();
|
||||||
_renderStateCullFaceEnabled = glIsEnabled(GL_CULL_FACE) != GL_FALSE;
|
|
||||||
GLint cullface;
|
|
||||||
glGetIntegerv(GL_CULL_FACE_MODE, &cullface);
|
|
||||||
_renderStateCullFace = (GLenum)cullface;
|
|
||||||
|
|
||||||
if (_cullFaceEnabled != _renderStateCullFaceEnabled)
|
|
||||||
{
|
|
||||||
_cullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cullFace != _renderStateCullFace)
|
|
||||||
{
|
|
||||||
glCullFace(_cullFace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// depth
|
|
||||||
_renderStateDepthTest = (glIsEnabled(GL_DEPTH_TEST) != GL_FALSE);
|
|
||||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &_renderStateDepthWrite);
|
|
||||||
|
|
||||||
if (_depthTestEnabled != _renderStateDepthTest)
|
|
||||||
{
|
|
||||||
_depthTestEnabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_depthWriteEnabled != _renderStateDepthWrite)
|
|
||||||
{
|
|
||||||
glDepthMask(_depthWriteEnabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MeshCommand::restoreRenderState()
|
|
||||||
{
|
|
||||||
CCASSERT(!_material, "Must not be called when using Material");
|
|
||||||
|
|
||||||
// cull
|
|
||||||
if (_cullFaceEnabled != _renderStateCullFaceEnabled)
|
|
||||||
{
|
|
||||||
_renderStateCullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cullFace != _renderStateCullFace)
|
|
||||||
{
|
|
||||||
glCullFace(_renderStateCullFace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// depth
|
|
||||||
if (_depthTestEnabled != _renderStateDepthTest)
|
|
||||||
{
|
|
||||||
_renderStateDepthTest ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_depthWriteEnabled != _renderStateDepthWrite)
|
|
||||||
{
|
|
||||||
glDepthMask(_renderStateDepthWrite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, GLuint vertexBuffer, GLuint indexBuffer, BlendFunc blend)
|
void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, GLuint vertexBuffer, GLuint indexBuffer, BlendFunc blend)
|
||||||
|
@ -353,9 +310,6 @@ void MeshCommand::batchDraw()
|
||||||
// Draw
|
// Draw
|
||||||
glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0);
|
glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0);
|
||||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount);
|
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount);
|
||||||
|
|
||||||
//restore render state
|
|
||||||
restoreRenderState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void MeshCommand::postBatchDraw()
|
void MeshCommand::postBatchDraw()
|
||||||
|
@ -404,9 +358,6 @@ void MeshCommand::execute()
|
||||||
glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0);
|
glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0);
|
||||||
|
|
||||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount);
|
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount);
|
||||||
|
|
||||||
//restore render state
|
|
||||||
restoreRenderState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "renderer/CCRenderCommand.h"
|
#include "renderer/CCRenderCommand.h"
|
||||||
#include "renderer/CCGLProgram.h"
|
#include "renderer/CCGLProgram.h"
|
||||||
|
#include "renderer/CCRenderState.h"
|
||||||
#include "math/CCMath.h"
|
#include "math/CCMath.h"
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
@ -93,11 +94,9 @@ protected:
|
||||||
|
|
||||||
// apply renderstate, not used when using material
|
// apply renderstate, not used when using material
|
||||||
void applyRenderState();
|
void applyRenderState();
|
||||||
void restoreRenderState();
|
|
||||||
|
|
||||||
GLuint _textureID;
|
GLuint _textureID;
|
||||||
GLProgramState* _glProgramState;
|
GLProgramState* _glProgramState;
|
||||||
BlendFunc _blendType;
|
|
||||||
|
|
||||||
Vec4 _displayColor; // in order to support tint and fade in fade out
|
Vec4 _displayColor; // in order to support tint and fade in fade out
|
||||||
|
|
||||||
|
@ -116,16 +115,8 @@ protected:
|
||||||
ssize_t _indexCount;
|
ssize_t _indexCount;
|
||||||
|
|
||||||
// States, default value all false
|
// States, default value all false
|
||||||
bool _cullFaceEnabled;
|
|
||||||
GLenum _cullFace;
|
|
||||||
bool _depthTestEnabled;
|
|
||||||
bool _depthWriteEnabled;
|
|
||||||
bool _forceDepthWrite;
|
bool _forceDepthWrite;
|
||||||
|
RenderState::StateBlock* _stateBlock;
|
||||||
bool _renderStateCullFaceEnabled;
|
|
||||||
bool _renderStateDepthTest;
|
|
||||||
GLboolean _renderStateDepthWrite;
|
|
||||||
GLenum _renderStateCullFace;
|
|
||||||
|
|
||||||
// ModelView transform
|
// ModelView transform
|
||||||
Mat4 _mv;
|
Mat4 _mv;
|
||||||
|
|
|
@ -749,26 +749,8 @@ void RenderState::StateBlock::setBlend(bool enabled)
|
||||||
|
|
||||||
void RenderState::StateBlock::setBlendFunc(const BlendFunc& blendFunc)
|
void RenderState::StateBlock::setBlendFunc(const BlendFunc& blendFunc)
|
||||||
{
|
{
|
||||||
if (blendFunc == BlendFunc::DISABLE)
|
setBlendSrc((RenderState::Blend)blendFunc.src);
|
||||||
{
|
setBlendDst((RenderState::Blend)blendFunc.dst);
|
||||||
setBlendSrc(BLEND_ONE);
|
|
||||||
setBlendDst(BLEND_ZERO);
|
|
||||||
}
|
|
||||||
else if (blendFunc == BlendFunc::ALPHA_PREMULTIPLIED)
|
|
||||||
{
|
|
||||||
setBlendSrc(BLEND_ONE);
|
|
||||||
setBlendDst(BLEND_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
|
||||||
else if (blendFunc == BlendFunc::ALPHA_NON_PREMULTIPLIED)
|
|
||||||
{
|
|
||||||
setBlendSrc(BLEND_SRC_ALPHA);
|
|
||||||
setBlendDst(BLEND_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
|
||||||
else if (blendFunc == BlendFunc::ADDITIVE)
|
|
||||||
{
|
|
||||||
setBlendSrc(BLEND_SRC_ALPHA);
|
|
||||||
setBlendDst(BLEND_ONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderState::StateBlock::setBlendSrc(Blend blend)
|
void RenderState::StateBlock::setBlendSrc(Blend blend)
|
||||||
|
|
|
@ -352,6 +352,8 @@ public:
|
||||||
uint32_t getHash() const;
|
uint32_t getHash() const;
|
||||||
bool isDirty() const;
|
bool isDirty() const;
|
||||||
|
|
||||||
|
static StateBlock* _defaultState;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StateBlock();
|
StateBlock();
|
||||||
~StateBlock();
|
~StateBlock();
|
||||||
|
@ -382,8 +384,6 @@ public:
|
||||||
|
|
||||||
long _bits;
|
long _bits;
|
||||||
|
|
||||||
static StateBlock* _defaultState;
|
|
||||||
|
|
||||||
mutable uint32_t _hash;
|
mutable uint32_t _hash;
|
||||||
mutable bool _hashDirty;
|
mutable bool _hashDirty;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
||||||
#include "renderer/ccGLStateCache.h"
|
#include "renderer/ccGLStateCache.h"
|
||||||
|
|
||||||
#include "renderer/CCGLProgram.h"
|
#include "renderer/CCGLProgram.h"
|
||||||
|
#include "renderer/CCRenderState.h"
|
||||||
#include "base/CCDirector.h"
|
#include "base/CCDirector.h"
|
||||||
#include "base/ccConfig.h"
|
#include "base/ccConfig.h"
|
||||||
#include "base/CCConfiguration.h"
|
#include "base/CCConfiguration.h"
|
||||||
|
@ -109,11 +110,16 @@ static void SetBlending(GLenum sfactor, GLenum dfactor)
|
||||||
if (sfactor == GL_ONE && dfactor == GL_ZERO)
|
if (sfactor == GL_ONE && dfactor == GL_ZERO)
|
||||||
{
|
{
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
RenderState::StateBlock::_defaultState->setBlend(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(sfactor, dfactor);
|
glBlendFunc(sfactor, dfactor);
|
||||||
|
|
||||||
|
RenderState::StateBlock::_defaultState->setBlend(true);
|
||||||
|
RenderState::StateBlock::_defaultState->setBlendSrc((RenderState::Blend)sfactor);
|
||||||
|
RenderState::StateBlock::_defaultState->setBlendSrc((RenderState::Blend)dfactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue