#include "RenderState.h" #include "Geometry.h" #include "Material.h" #include "ShaderProgram.h" #include "Texture.h" using namespace std; namespace CHCDemoEngine { CGprofile RenderState::sCgFragmentProfile; CGprofile RenderState::sCgVertexProfile; ShaderProgram *RenderState::sCgMrtFragmentProgram = NULL; ShaderProgram *RenderState::sCgMrtFragmentTexProgram = NULL; ShaderProgram *RenderState::sCgMrtVertexProgram = NULL; int RenderState::sTexParam; ///////////////// RenderState::RenderState(): mAlphaTestEnabled(false), mCullFaceEnabled(true), mTexturesEnabled(false), mMode(RENDER), mRenderType(FIXED), mUseAlphaToCoverage(true), mLockCullFaceEnabled(false) { Reset(); } bool RenderState::SetMode(Mode mode) { /////////// //-- just change the modewhen necessary if (mode == mMode) return false; mMode = mode; if (mode == QUERY) { if (mRenderType != DEPTH_PASS) { glDisable(GL_LIGHTING); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); if (mRenderType == DEFERRED) { cgGLDisableProfile(sCgFragmentProfile); cgGLDisableProfile(sCgVertexProfile); } } glDepthMask(GL_FALSE); SetState(false, false, false); } else // mode returns to render { ///////////// //-- restore render state if (mRenderType != DEPTH_PASS) { glEnable(GL_LIGHTING); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); if (mRenderType == DEFERRED) { cgGLEnableProfile(sCgFragmentProfile); cgGLEnableProfile(sCgVertexProfile); } } glDepthMask(GL_TRUE); } return true; } void RenderState::SetState(Texture *tex, bool alphaTest, bool cullFace) { const bool texturing = (tex != NULL); if (!mLockCullFaceEnabled) { if (mCullFaceEnabled && !cullFace) { mCullFaceEnabled = false; glDisable(GL_CULL_FACE); } else if (!mCullFaceEnabled && cullFace) { mCullFaceEnabled = true; glEnable(GL_CULL_FACE); } } if (mAlphaTestEnabled && !alphaTest) { mAlphaTestEnabled = false; if (mUseAlphaToCoverage) glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); else glDisable(GL_ALPHA_TEST); } else if (!mAlphaTestEnabled && alphaTest) { mAlphaTestEnabled = true; if (mUseAlphaToCoverage) glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); else glEnable(GL_ALPHA_TEST); } if (mTexturesEnabled && (!texturing || (mRenderType == DEPTH_PASS) && !mAlphaTestEnabled)) { mTexturesEnabled = false; if (mRenderType == DEFERRED) sCgMrtFragmentProgram->Bind(); else glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } else if (!mTexturesEnabled && texturing) { // support only alpha textures in depth pass if ((mRenderType != DEPTH_PASS) || mAlphaTestEnabled) { mTexturesEnabled = true; if (mRenderType == DEFERRED) sCgMrtFragmentTexProgram->Bind(); else glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } } SetTexture(tex); } void RenderState::Reset() { mCurrentVboId = -1; mCullFaceEnabled = true; glEnable(GL_CULL_FACE); mAlphaTestEnabled = false; glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); glDisable(GL_ALPHA_TEST); mTexturesEnabled = false; glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); SetMode(RENDER); } void RenderState::SetUseAlphaToCoverage(bool useAlphaToCoverage) { mUseAlphaToCoverage = useAlphaToCoverage; } void RenderState::SetRenderPassType(RenderPassType t) { mRenderType = t; } RenderState::RenderPassType RenderState::GetRenderPassType() const { return mRenderType; } void RenderState::LockCullFaceEnabled(bool lockCull) { mLockCullFaceEnabled = lockCull; } void RenderState::SetTexture(Texture *tex) { if (GetRenderPassType() == RenderState::DEFERRED) { if (tex) RenderState::sCgMrtFragmentTexProgram->SetTexture("tex", tex->GetId()); } else { if (tex) tex->Bind(); else glBindTexture(GL_TEXTURE_2D, 0); } } }