// Append a blend (non-interaction) layer void OpenGLShader::appendBlendLayer (const ShaderLayer& layer) { GLTexture* layerTex = layer.getTexture(); OpenGLState& state = appendDefaultPass(); state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_TEXTURE_2D; state.m_depthfunc = GL_LEQUAL; // Set the texture state.m_texture = layerTex->texture_number; // Get the blend function BlendFunc blendFunc = layer.getBlendFunc(); state.m_blend_src = convertBlendFactor(blendFunc.m_src); state.m_blend_dst = convertBlendFactor(blendFunc.m_dst); // Alpha-tested stages or one-over-zero blends should use the depth buffer if (state.m_blend_src == GL_SRC_ALPHA || state.m_blend_dst == GL_SRC_ALPHA || (state.m_blend_src == GL_ONE && state.m_blend_dst == GL_ZERO)) { state.m_state |= RENDER_DEPTHWRITE; } // Colour modulation state.m_colour = Vector4(layer.getColour(), 1.0f); state.m_sort = OpenGLState::eSortOverlayFirst; // Polygon offset state.m_polygonOffset = layer.getPolygonOffset(); }
//----------------------------------------------------------------------- void parseSceneBlend(StringVector::iterator& params, int numParams, MaterialPtr& pMat) { // Should be 1 or 2 params (+ command) if (numParams == 2) { //simple SceneBlendType stype; if (params[1] == "add") stype = SBT_ADD; else if (params[1] == "modulate") stype = SBT_TRANSPARENT_COLOUR; else if (params[1] == "alpha_blend") stype = SBT_TRANSPARENT_ALPHA; else { LogManager::getSingleton().logMessage("Bad scene_blend attribute line in " + pMat->getName() + ", unrecognised parameter '" + params[1] + "'"); return ; } pMat->setSceneBlending(stype); } else if (numParams == 3) { //src/dest SceneBlendFactor src, dest; try { src = convertBlendFactor(params[1]); dest = convertBlendFactor(params[2]); pMat->setSceneBlending(src,dest); } catch (Exception& e) { LogManager::getSingleton().logMessage("Bad scene_blend attribute line in " + pMat->getName() + ", " + e.getFullDescription()); } } else { LogManager::getSingleton().logMessage("Bad scene_blend attribute line in " + pMat->getName() + ", wrong number of parameters (expected 1 or 2)"); } }
//----------------------------------------------------------------------- void parseColourOpFallback(StringVector::iterator& params, int numParams, MaterialPtr& pMat, TextureUnitState* pTex) { if (numParams != 3) { LogManager::getSingleton().logMessage("Bad " + params[0] + " attribute line in " + pMat->getName() + ", wrong number of parameters (expected 2)"); return; } //src/dest SceneBlendFactor src, dest; try { src = convertBlendFactor(params[1]); dest = convertBlendFactor(params[2]); pTex->setColourOpMultipassFallback(src,dest); } catch (Exception& e) { LogManager::getSingleton().logMessage("Bad "+ params[0] +" attribute line in " + pMat->getName() + ", " + e.getFullDescription()); } }
void OpenGLShader::constructNormalShader (const std::string& name) { // construction from IShader m_shader = GlobalShaderSystem().getShaderForName(name); OpenGLState& state = appendDefaultPass(); state.m_texture = m_shader->getTexture()->texture_number; state.m_state = RENDER_FILL | RENDER_TEXTURE_2D | RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_LIGHTING | RENDER_SMOOTH; state.m_state |= RENDER_CULLFACE; if ((m_shader->getFlags() & QER_ALPHATEST) != 0) { state.m_state |= RENDER_ALPHATEST; state.m_colour[3] = 0.25; IShader::EAlphaFunc alphafunc; m_shader->getAlphaFunc(&alphafunc, &state.m_alpharef); switch (alphafunc) { case IShader::eAlways: state.m_alphafunc = GL_ALWAYS; case IShader::eEqual: state.m_alphafunc = GL_EQUAL; case IShader::eLess: state.m_alphafunc = GL_LESS; case IShader::eGreater: state.m_alphafunc = GL_GREATER; case IShader::eLEqual: state.m_alphafunc = GL_LEQUAL; case IShader::eGEqual: state.m_alphafunc = GL_GEQUAL; } } state.m_colour = Vector4(m_shader->getTexture()->color, 1.0); if (isTransparent(m_shader->getName())) { state.m_state |= RENDER_BLEND; state.m_state |= RENDER_DEPTHWRITE; state.m_colour = Vector4(1.0, 1.0, 1.0, 0.4); state.m_sort = OpenGLState::eSortTranslucent; } else if ((m_shader->getFlags() & QER_TRANS) != 0) { state.m_state |= RENDER_BLEND; state.m_colour[3] = m_shader->getTrans(); BlendFunc blendFunc = m_shader->getBlendFunc(); state.m_blend_src = convertBlendFactor(blendFunc.m_src); state.m_blend_dst = convertBlendFactor(blendFunc.m_dst); if (state.m_blend_src == GL_SRC_ALPHA || state.m_blend_dst == GL_SRC_ALPHA) { state.m_state |= RENDER_DEPTHWRITE; } state.m_sort = OpenGLState::eSortTranslucent; } else if (m_shader->getTexture()->hasAlpha) { state.m_state |= RENDER_BLEND; state.m_state |= RENDER_DEPTHWRITE; state.m_sort = OpenGLState::eSortTranslucent; } else { state.m_state |= RENDER_DEPTHWRITE; state.m_sort = OpenGLState::eSortFullbright; } m_shader->forEachLayer(ShaderLayerVisitor(*this)); }