//----------------------------------------------------------------------- bool FFPTransform::createCpuSubPrograms(ProgramSet* programSet) { //! [param_resolve] Program* vsProgram = programSet->getCpuVertexProgram(); Function* vsEntry = vsProgram->getEntryPointFunction(); // Resolve World View Projection Matrix. UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); // Resolve input position parameter. ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); // Resolve output position parameter. ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); if (!wvpMatrix || !positionIn || !positionOut) { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Not all parameters could be constructed for the sub-render state.", "FFPTransform::createCpuSubPrograms" ); } //! [param_resolve] // Add dependency. vsProgram->addDependency(FFP_LIB_TRANSFORM); FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); transformFunc->pushOperand(positionIn, Operand::OPS_IN); transformFunc->pushOperand(positionOut, Operand::OPS_OUT); vsEntry->addAtomInstance(transformFunc); return true; }
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const { // Check the function names first if (lhs.getFunctionName() < rhs.getFunctionName()) return true; // Next check the return type if (lhs.getReturnType() < rhs.getReturnType()) return true; // Check the number of operands if (lhs.mOperands.size() < rhs.mOperands.size()) return true; // Now that we've gotten past the two quick tests, iterate over operands // Check the semantic and type. The operands must be in the same order as well. OperandVector::const_iterator itLHSOps = lhs.mOperands.begin(); OperandVector::const_iterator itRHSOps = rhs.mOperands.begin(); for ( ; itLHSOps != lhs.mOperands.end(), itRHSOps != rhs.mOperands.end(); ++itLHSOps, ++itRHSOps) { if (itLHSOps->getSemantic() < itRHSOps->getSemantic()) return true; if (itLHSOps->getParameter()->getType() < itRHSOps->getParameter()->getType()) return true; } return false; }
//----------------------------------------------------------------------------- void ProgramProcessor::buildParameterReferenceMap(FunctionAtomInstanceList& funcAtomList, ParameterOperandMap& paramsRefMap) { FunctionAtomInstanceIterator it = funcAtomList.begin(); FunctionAtomInstanceIterator itEnd = funcAtomList.end(); for (; it != itEnd; ++it) { FunctionAtom* curAtom = *it; // Deal only with function invocations. if (curAtom->getFunctionAtomType() == FunctionInvocation::Type) { FunctionInvocation* curFuncInvocation = static_cast<FunctionInvocation*>(curAtom); FunctionInvocation::OperandVector& funcOperands = curFuncInvocation->getOperandList(); for (unsigned int op=0; op < funcOperands.size(); ++op) { Operand& curOperand = funcOperands[op]; paramsRefMap[curOperand.getParameter().get()].push_back(&curOperand); } } } }
ArrayVariable* ArrayVariable::rnd_mutate(void) { assert(0 && "invalid call to rnd_mutate"); bool use_existing = rnd_flipcoin(20); ERROR_GUARD(NULL); size_t i; if (use_existing) { vector<Variable*> ok_vars; for (i=0; i<parent->local_vars.size(); i++) { if (is_variant(parent->local_vars[i])) { ok_vars.push_back(parent->local_vars[i]); } } Variable* v = VariableSelector::choose_ok_var(ok_vars); ERROR_GUARD(NULL); if (v) { ArrayVariable* av = dynamic_cast<ArrayVariable*>(v); return av; } } vector<const Expression*> new_indices; vector<bool> mutate_flags; bool no_mutate = true; for (i=0; i<get_dimension(); i++) { bool mutate = rnd_flipcoin(10); ERROR_GUARD(0); mutate_flags.push_back(mutate); if (mutate) { no_mutate = false; } } // if no mutation, return self if (no_mutate) { return this; } for (i=0; i<get_dimension(); i++) { if (mutate_flags[i]) { const Expression* e = indices[i]; assert(e->term_type == eVariable); const ExpressionVariable* ev = dynamic_cast<const ExpressionVariable*>(e); // create a mutated index from the original by adding an constant offset FunctionInvocation* fi = new FunctionInvocationBinary(eAdd, 0); fi->add_operand(new ExpressionVariable(*(ev->get_var()))); int offset = rnd_upto(sizes[i]); if (offset == 0) offset = 1; // give offset 1 more chance ERROR_GUARD(NULL); ostringstream oss; oss << offset; fi->add_operand(new Constant(get_int_type(), oss.str())); Expression* mutated_e = new ExpressionFuncall(*fi); new_indices.push_back(mutated_e); } else { new_indices.push_back(indices[i]->clone()); } } // if index of at least one dimension mutated, return the new variable return VariableSelector::create_mutated_array_var(this, new_indices); }
bool FunctionInvocation::FunctionInvocationCompare::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const { // Check the function names first if (lhs.getFunctionName() != rhs.getFunctionName()) return false; // Next check the return type if (lhs.getReturnType() != rhs.getReturnType()) return false; // Check the number of operands if (lhs.mOperands.size() != rhs.mOperands.size()) return false; // Now that we've gotten past the two quick tests, iterate over operands // Check the semantic and type. The operands must be in the same order as well. OperandVector::const_iterator itLHSOps = lhs.mOperands.begin(); OperandVector::const_iterator itRHSOps = rhs.mOperands.begin(); for ( ; ((itLHSOps != lhs.mOperands.end()) && (itRHSOps != rhs.mOperands.end())); ++itLHSOps, ++itRHSOps) { if (itLHSOps->getSemantic() != itRHSOps->getSemantic()) return false; GpuConstantType leftType = itLHSOps->getParameter()->getType(); GpuConstantType rightType = itRHSOps->getParameter()->getType(); if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos) { if (leftType == GCT_SAMPLER1D) leftType = GCT_SAMPLER2D; if (rightType == GCT_SAMPLER1D) rightType = GCT_SAMPLER2D; } // If a swizzle mask is being applied to the parameter, generate the GpuConstantType to // perform the parameter type comparison the way that the compiler will see it. if ((itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) || (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0)) { if (itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) { leftType = (GpuConstantType)((itLHSOps->getParameter()->getType() - itLHSOps->getParameter()->getType()) + itLHSOps->getFloatCount(itLHSOps->getMask())); } if (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0) { rightType = (GpuConstantType)((itRHSOps->getParameter()->getType() - itRHSOps->getParameter()->getType()) + itRHSOps->getFloatCount(itRHSOps->getMask())); } } if (leftType != rightType) return false; } // Passed all tests, they are the same return true; }
//----------------------------------------------------------------------- void DualQuaternionSkinning::addIndexedPositionWeight(Function* vsMain, int index, ParameterPtr& pWorldMatrix, ParameterPtr& pPositionTempParameter, ParameterPtr& pPositionRelatedOutputParam, int& funcCounter) { Operand::OpMask indexMask = indexToMask(index); FunctionInvocation* curFuncInvocation; //multiply position with world matrix and put into temporary param curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BLEND_WEIGHT, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); curFuncInvocation->pushOperand(pWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); //check if on first iteration if (index == 0) { //set the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //add the local param as the value of the world param curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const { // Check the function names first // Adding an exception to std::string sorting. I feel that functions beginning with an underscore should be placed before // functions beginning with an alphanumeric character. By default strings are sorted based on the ASCII value of each character. // Underscores have an ASCII value in between capital and lowercase characters. This is why the exception is needed. if (lhs.getFunctionName() < rhs.getFunctionName()) { if(rhs.getFunctionName().at(0) == '_') return false; else return true; } if (lhs.getFunctionName() > rhs.getFunctionName()) { if(lhs.getFunctionName().at(0) == '_') return true; else return false; } // Next check the return type if (lhs.getReturnType() < rhs.getReturnType()) return true; if (lhs.getReturnType() > rhs.getReturnType()) return false; // Check the number of operands if (lhs.mOperands.size() < rhs.mOperands.size()) return true; if (lhs.mOperands.size() > rhs.mOperands.size()) return false; // Now that we've gotten past the two quick tests, iterate over operands // Check the semantic and type. The operands must be in the same order as well. OperandVector::const_iterator itLHSOps = lhs.mOperands.begin(); OperandVector::const_iterator itRHSOps = rhs.mOperands.begin(); for ( ; itLHSOps != lhs.mOperands.end(), itRHSOps != rhs.mOperands.end(); ++itLHSOps, ++itRHSOps) { if (itLHSOps->getSemantic() < itRHSOps->getSemantic()) return true; if (itLHSOps->getSemantic() > itRHSOps->getSemantic()) return false; if (itLHSOps->getParameter()->getType() < itRHSOps->getParameter()->getType()) return true; if (itLHSOps->getParameter()->getType() > itRHSOps->getParameter()->getType()) return false; } return true; }
//----------------------------------------------------------------------- void LayeredBlending::addPSBlendInvocations(Function* psMain, ParameterPtr arg1, ParameterPtr arg2, ParameterPtr texel, int samplerIndex, const LayerBlendModeEx& blendMode, const int groupOrder, int& internalCounter, int targetChannels) { // // Add the modifier invocation // addPSModifierInvocation(psMain, samplerIndex, arg1, arg2, groupOrder, internalCounter, targetChannels); // // Add the blending function invocations // BlendMode mode = getBlendMode(samplerIndex); if ((LB_FFPBlend == mode) || (LB_Invalid == mode)) { FFPTexturing::addPSBlendInvocations(psMain, arg1, arg2, texel, samplerIndex, blendMode, groupOrder, internalCounter, targetChannels); } else { //find the function name for the blend mode String funcName; for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) { if (_blendModes[i].type == mode) { funcName = _blendModes[i].funcName; break; } } //add the function of the blend mode if (funcName.empty() == false) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); psMain->addAtomInstance(curFuncInvocation); } } }
//----------------------------------------------------------------------- bool ShaderExInstancedViewports::addPSInvocations( Function* psMain, const int groupOrder ) { FunctionInvocation* funcInvocation = NULL; int internalCounter = 0; funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS, groupOrder, internalCounter++); funcInvocation->pushOperand(mPSInMonitorsCount, Operand::OPS_IN); funcInvocation->pushOperand(mPSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mPSInPositionProjectiveSpace, Operand::OPS_IN); psMain->addAtomInstance(funcInvocation); return true; }
//----------------------------------------------------------------------- void LayeredBlending::addPSModifierInvocation(Function* psMain, int samplerIndex, ParameterPtr arg1, ParameterPtr arg2, const int groupOrder, int& internalCounter, int targetChannels) { SourceModifier modType; int customNum; if (getSourceModifier(samplerIndex, modType, customNum) == true) { ParameterPtr modifiedParam; String funcName; switch (modType) { case SM_Source1Modulate: funcName = "SGX_src_mod_modulate"; modifiedParam = arg1; break; case SM_Source2Modulate: funcName = "SGX_src_mod_modulate"; modifiedParam = arg2; break; case SM_Source1InvModulate: funcName = "SGX_src_mod_inv_modulate"; modifiedParam = arg1; break; case SM_Source2InvModulate: funcName = "SGX_src_mod_inv_modulate"; modifiedParam = arg2; break; default: break; } //add the function of the blend mode if (funcName.empty() == false) { ParameterPtr& controlParam = mTextureBlends[samplerIndex].modControlParam; FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(controlParam, Operand::OPS_IN, targetChannels); curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_OUT, targetChannels); psMain->addAtomInstance(curFuncInvocation); } } }
//----------------------------------------------------------------------- void FFPTexturing::addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain, const ParameterPtr& texel, int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); else curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN); curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); }
bool FFPAlphaTest::addFunctionInvocations( ProgramSet* programSet ) { Program* psProgram = programSet->getCpuFragmentProgram(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation *curFuncInvocation; //Fragment shader invocations curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ALPHA_TEST, FFP_PS_ALPHA_TEST, 0); curFuncInvocation->pushOperand(mPSAlphaFunc, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSAlphaRef, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); psMain->addAtomInstance(curFuncInvocation); return true; }
//----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; if (mVSInNormal.get() != NULL) { // Transform normal in world space. curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } // Transform world space position if need to. if (mVSOutWorldPos.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutWorldPos, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } return true; }
//----------------------------------------------------------------------- bool IntegratedPSSM3::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation; // Output the vertex depth in camera space. curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mVSOutPos, Operand::OPS_IN, Operand::OPM_Z); curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); // Compute world space position. ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); while(it != mShadowTextureParamsList.end()) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, groupOrder, internalCounter++); curFuncInvocation->pushOperand(it->mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(it->mVSOutLightPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); ++it; } return true; }
//----------------------------------------------------------------------- void HardwareSkinning::addNormalRelatedCalculations(Function* vsMain, ParameterPtr& pNormalRelatedParam, ParameterPtr& pNormalWorldRelatedParam, int& funcCounter) { FunctionInvocation* curFuncInvocation; if (mDoBoneCalculations == true) { //set functions to calculate world normal for(int i = 0 ; i < getWeightCount() ; ++i) { addIndexedNormalRelatedWeight(vsMain, pNormalRelatedParam, pNormalWorldRelatedParam, i, funcCounter); } //update back the original position relative to the object curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else { //update from object to world space curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- bool FFPTransform::createCpuSubPrograms(ProgramSet* programSet) { Program* vsProgram = programSet->getCpuVertexProgram(); // Resolve World View Projection Matrix. UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); if (wvpMatrix.get() == NULL) return false; Function* vsEntry = vsProgram->getEntryPointFunction(); assert(vsEntry != NULL); // Resolve input position parameter. ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); if (positionIn.get() == NULL) return false; // Resolve output position parameter. ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); if (positionOut.get() == NULL) return false; // Add dependency. vsProgram->addDependency(FFP_LIB_TRANSFORM); FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); transformFunc->pushOperand(positionIn, Operand::OPS_IN); transformFunc->pushOperand(positionOut, Operand::OPS_OUT); vsEntry->addAtomInstace(transformFunc); return true; }
//----------------------------------------------------------------------- bool ShaderExReflectionMap::addPSInvocations( Function* psMain, const int groupOrder ) { FunctionInvocation* funcInvoaction = NULL; int internalCounter = 0; funcInvoaction = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLY_REFLECTION_MAP, groupOrder, internalCounter++); funcInvoaction->pushOperand(mMaskMapSampler, Operand::OPS_IN); funcInvoaction->pushOperand(mPSInMaskTexcoord, Operand::OPS_IN); funcInvoaction->pushOperand(mReflectionMapSampler, Operand::OPS_IN); funcInvoaction->pushOperand(mPSInReflectionTexcoord, Operand::OPS_IN); funcInvoaction->pushOperand(mPSOutDiffuse, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); funcInvoaction->pushOperand(mReflectionPower, Operand::OPS_IN); funcInvoaction->pushOperand(mPSOutDiffuse, Operand::OPS_OUT,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); psMain->addAtomInstace(funcInvoaction); return true; }
//----------------------------------------------------------------------------- void ProgramProcessor::generateLocalSplitParameters(Function* func, GpuProgramType progType, MergeParameterList& mergedParams, ShaderParameterList& splitParams, LocalParameterMap& localParamsMap) { // No split params created. if (splitParams.size() == 0) return; // Create the local parameters + map from source to local. for (unsigned int i=0; i < splitParams.size(); ++i) { ParameterPtr srcParameter = splitParams[i]; ParameterPtr localParameter = func->resolveLocalParameter(srcParameter->getSemantic(), srcParameter->getIndex(), "lsplit_" + srcParameter->getName(), srcParameter->getType()); localParamsMap[srcParameter.get()] = localParameter; } int invocationCounter = 0; // Establish link between the local parameter to the merged parameter. for (unsigned int i=0; i < mergedParams.size(); ++i) { MergeParameter& curMergeParameter = mergedParams[i]; for (unsigned int p=0; p < curMergeParameter.getSourceParameterCount(); ++p) { ParameterPtr srcMergedParameter = curMergeParameter.getSourceParameter(p); LocalParameterMap::iterator itFind = localParamsMap.find(srcMergedParameter.get()); // Case the source parameter is split parameter. if (itFind != localParamsMap.end()) { // Case it is the vertex shader -> assign the local parameter to the output merged parameter. if (progType == GPT_VERTEX_PROGRAM) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_POST_PROCESS, invocationCounter++); curFuncInvocation->pushOperand(itFind->second, Operand::OPS_IN, curMergeParameter.getSourceParameterMask(p)); curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_OUT, i), Operand::OPS_OUT, curMergeParameter.getDestinationParameterMask(p)); func->addAtomInstance(curFuncInvocation); } else if (progType == GPT_FRAGMENT_PROGRAM) { FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS, invocationCounter++); curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_IN, i), Operand::OPS_IN, curMergeParameter.getDestinationParameterMask(p)); curFuncInvocation->pushOperand(itFind->second, Operand::OPS_OUT, curMergeParameter.getSourceParameterMask(p)); func->addAtomInstance(curFuncInvocation); } } } } }
//----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSFinalAssignmentInvocation( Function* psMain, const int groupOrder, int& internalCounter ) { FunctionInvocation* curFuncInvocation; curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); } return true; }
//----------------------------------------------------------------------- void DualQuaternionSkinning::adjustForCorrectAntipodality(Function* vsMain, int index, int& funcCounter, const ParameterPtr& pTempWorldMatrix) { FunctionInvocation* curFuncInvocation; //Antipodality doesn't need to be adjusted for dq0 on itself (used as the basis of antipodality calculations) if(index > 0) { curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ANTIPODALITY_ADJUSTMENT, FFP_VS_TRANSFORM, funcCounter++); //This is the base dual quaternion dq0, which the antipodality calculations are based on curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); curFuncInvocation->pushOperand(pTempWorldMatrix, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } else if(index == 0) { //Set the first dual quaternion as the initial dq curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); } }
//----------------------------------------------------------------------- bool FFPFog::addFunctionInvocations(ProgramSet* programSet) { if (mFogMode == FOG_NONE) return true; Program* vsProgram = programSet->getCpuVertexProgram(); Program* psProgram = programSet->getCpuFragmentProgram(); Function* vsMain = vsProgram->getEntryPointFunction(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation* curFuncInvocation = NULL; int internalCounter; // Per pixel fog. if (mCalcMode == CM_PER_PIXEL) { internalCounter = 0; curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_DEPTH, FFP_VS_FOG, internalCounter++); curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); internalCounter = 0; switch (mFogMode) { case FOG_LINEAR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); break; case FOG_EXP: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); break; case FOG_EXP2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); break; case FOG_NONE: default: break; } curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Per vertex fog. else { internalCounter = 0; switch (mFogMode) { case FOG_LINEAR: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_LINEAR, FFP_VS_FOG, internalCounter++); break; case FOG_EXP: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP, FFP_VS_FOG, internalCounter++); break; case FOG_EXP2: curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP2, FFP_VS_FOG, internalCounter++); break; case FOG_NONE: default: break; } curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutFogFactor, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); internalCounter = 0; curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, FFP_PS_FOG, internalCounter++); curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInFogFactor, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } return true; }
//----------------------------------------------------------------------- bool ShaderExInstancedViewports::addVSInvocations( Function* vsMain, const int groupOrder ) { FunctionInvocation* funcInvocation = NULL; int internalCounter = 0; funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); funcInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); funcInvocation->pushOperand(mProjectionMatrix, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR0, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR1, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR2, Operand::OPS_IN); funcInvocation->pushOperand(mVSInViewportOffsetMatrixR3, Operand::OPS_IN); funcInvocation->pushOperand(mVSInMonitorsCount, Operand::OPS_IN); funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); // Output position in projective space. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); // Output monitor index. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutMonitorIndex, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); return true; }
//----------------------------------------------------------------------- void GLSLProgramWriter::writeSourceCode(std::ostream& os, Program* program) { GpuProgramType gpuType = program->getType(); if(gpuType == GPT_GEOMETRY_PROGRAM) { OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "Geometry Program not supported in GLSL writer ", "GLSLProgramWriter::writeSourceCode" ); } // Clear out old input params mFragInputParams.clear(); const ShaderFunctionList& functionList = program->getFunctions(); ShaderFunctionConstIterator itFunction; const UniformParameterList& parameterList = program->getParameters(); UniformParameterConstIterator itUniformParam = parameterList.begin(); // Write the current version (this force the driver to more fulfill the glsl standard) os << "#version "<< mGLSLVersion << std::endl; // Generate source code header. writeProgramTitle(os, program); os<< std::endl; // Write forward declarations writeForwardDeclarations(os, program); os<< std::endl; // Generate global variable code. writeUniformParametersTitle(os, program); os << std::endl; // Write the uniforms for (itUniformParam = parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) { ParameterPtr pUniformParam = *itUniformParam; os << "uniform\t"; os << mGpuConstTypeMap[pUniformParam->getType()]; os << "\t"; os << pUniformParam->getName(); if (pUniformParam->isArray() == true) { os << "[" << pUniformParam->getSize() << "]"; } os << ";" << std::endl; } os << std::endl; // Write program function(s). for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) { Function* curFunction = *itFunction; writeFunctionTitle(os, curFunction); // Clear output mapping this map is used when we use // glsl built in types like gl_Color for example mInputToGLStatesMap.clear(); // Write inout params and fill mInputToGLStatesMap writeInputParameters(os, curFunction, gpuType); writeOutParameters(os, curFunction, gpuType); // The function name must always main. os << "void main(void) {" << std::endl; // Write local parameters. const ShaderParameterList& localParams = curFunction->getLocalParameters(); ShaderParameterConstIterator itParam = localParams.begin(); ShaderParameterConstIterator itParamEnd = localParams.end(); for (; itParam != itParamEnd; ++itParam) { os << "\t"; writeLocalParameter(os, *itParam); os << ";" << std::endl; } os << std::endl; // Sort function atoms. curFunction->sortAtomInstances(); const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); for (; itAtom != itAtomEnd; ++itAtom) { FunctionInvocation* pFuncInvoc = (FunctionInvocation*)*itAtom; FunctionInvocation::OperandVector::iterator itOperand = pFuncInvoc->getOperandList().begin(); FunctionInvocation::OperandVector::iterator itOperandEnd = pFuncInvoc->getOperandList().end(); // Local string stream StringStream localOs; // Write function name localOs << "\t" << pFuncInvoc->getFunctionName() << "("; ushort curIndLevel = 0; for (; itOperand != itOperandEnd; ) { Operand op = *itOperand; Operand::OpSemantic opSemantic = op.getSemantic(); String paramName = op.getParameter()->getName(); Parameter::Content content = op.getParameter()->getContent(); if (opSemantic == Operand::OPS_OUT || opSemantic == Operand::OPS_INOUT) { // Is the written parameter a varying bool isVarying = false; // Check if we write to an varying because the are only readable in fragment programs if (gpuType == GPT_FRAGMENT_PROGRAM) { StringVector::iterator itFound = std::find(mFragInputParams.begin(), mFragInputParams.end(), paramName); if(itFound != mFragInputParams.end()) { // Declare the copy variable String newVar = "local_" + paramName; String tempVar = paramName; isVarying = true; // We stored the original values in the mFragInputParams thats why we have to replace the first var with o // because all vertex output vars are prefixed with o in glsl the name has to match in the fragment program. tempVar.replace(tempVar.begin(), tempVar.begin() + 1, "o"); // Declare the copy variable and assign the original os << "\t" << mGpuConstTypeMap[op.getParameter()->getType()] << " " << newVar << " = " << tempVar << ";\n" << std::endl; // From now on we replace it automatic mInputToGLStatesMap[paramName] = newVar; // Remove the param because now it is replaced automatic with the local variable // (which could be written). mFragInputParams.erase(itFound++); } } // If its not a varying param check if a uniform is written if(!isVarying) { UniformParameterList::const_iterator itFound = std::find_if( parameterList.begin(), parameterList.end(), std::bind2nd( CompareUniformByName(), paramName ) ); if(itFound != parameterList.end()) { // Declare the copy variable String newVar = "local_" + paramName; // now we check if we already declared a uniform redirector var if(mInputToGLStatesMap.find(newVar) == mInputToGLStatesMap.end()) { // Declare the copy variable and assign the original os << "\t" << mGpuConstTypeMap[itFound->get()->getType()] << " " << newVar << " = " << paramName << ";\n" << std::endl; // From now on we replace it automatic mInputToGLStatesMap[paramName] = newVar; } } } } if(mInputToGLStatesMap.find(paramName) != mInputToGLStatesMap.end()) { int mask = op.getMask(); // our swizzle mask // Here we insert the renamed param name localOs << mInputToGLStatesMap[paramName]; if(mask != Operand::OPM_ALL) { localOs << "." << Operand::getMaskAsString(mask); } // Now that every texcoord is a vec4 (passed as vertex attributes) we // have to swizzle them according the desired type. else if(gpuType == GPT_VERTEX_PROGRAM && (content == Parameter::SPC_TEXTURE_COORDINATE0 || content == Parameter::SPC_TEXTURE_COORDINATE1 || content == Parameter::SPC_TEXTURE_COORDINATE2 || content == Parameter::SPC_TEXTURE_COORDINATE3 || content == Parameter::SPC_TEXTURE_COORDINATE4 || content == Parameter::SPC_TEXTURE_COORDINATE5 || content == Parameter::SPC_TEXTURE_COORDINATE6 || content == Parameter::SPC_TEXTURE_COORDINATE7) ) { // Now generate the swizzel mask according // the type. switch(op.getParameter()->getType()) { case GCT_FLOAT1: localOs << ".x"; break; case GCT_FLOAT2: localOs << ".xy"; break; case GCT_FLOAT3: localOs << ".xyz"; break; case GCT_FLOAT4: localOs << ".xyzw"; break; default: break; } } } else { localOs << op.toString(); } ++itOperand; // Prepare for the next operand ushort opIndLevel = 0; if (itOperand != itOperandEnd) { opIndLevel = itOperand->getIndirectionLevel(); } if (curIndLevel != 0) { localOs << ")"; } if (curIndLevel < opIndLevel) { while (curIndLevel < opIndLevel) { ++curIndLevel; localOs << "["; } } else //if (curIndLevel >= opIndLevel) { while (curIndLevel > opIndLevel) { --curIndLevel; localOs << "]"; } if (opIndLevel != 0) { localOs << "]["; } else if (itOperand != itOperandEnd) { localOs << ", "; } } if (curIndLevel != 0) { localOs << "int("; } } // Write function call closer. localOs << ");" << std::endl; localOs << std::endl; os << localOs.str(); } os << "}" << std::endl; } os << std::endl; }
//----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; switch (curLightParams->mType) { case Light::LT_DIRECTIONAL: if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } break; case Light::LT_POINT: case Light::LT_SPOTLIGHT: { curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_AMBIENT_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } break; } return true; }
//----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSGlobalIlluminationInvocationEnd(Function* psMain, const int groupOrder, int& internalCounter) { FunctionInvocation* curFuncInvocation = NULL; // Merge diffuse colour with vertex colour if need to. if (mTrackVertexColourType & TVC_DIFFUSE) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } // Merge specular colour with vertex colour if need to. if ((mSpecularEnable == true) && (mTrackVertexColourType & TVC_SPECULAR)) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && (mTrackVertexColourType & TVC_EMISSIVE) == 0) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN, (Operand::OPM_XYZ)); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, (Operand::OPM_XYZ)); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } else { if (mTrackVertexColourType & TVC_AMBIENT) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } if (mTrackVertexColourType & TVC_EMISSIVE) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } else { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); } } if (mSpecularEnable) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); psMain->addAtomInstance(curFuncInvocation); } return true; }
StatementAssign * StatementAssign::make_possible_compound_assign(CGContext &cg_context, const Lhs &l, eAssignOps op, const Expression &e) { eBinaryOps bop = compound_to_binary_ops(op); const Expression *rhs = NULL; SafeOpFlags *fs = NULL; std::string tmp1; std::string tmp2; if (bop != MAX_BINARY_OP) { //SafeOpFlags *local_fs = SafeOpFlags::make_random(sOpAssign, true); SafeOpFlags *local_fs = NULL; FunctionInvocation* fi = NULL; if (safe_assign(op)) { local_fs = SafeOpFlags::make_dummy_flags(); fi = new FunctionInvocationBinary(bop, local_fs); } else { local_fs = SafeOpFlags::make_random(sOpAssign); fi = FunctionInvocationBinary::CreateFunctionInvocationBinary(cg_context, bop, local_fs); tmp1 = dynamic_cast<FunctionInvocationBinary*>(fi)->get_tmp_var1(); tmp2 = dynamic_cast<FunctionInvocationBinary*>(fi)->get_tmp_var2(); } fs = local_fs->clone(); fi->add_operand(new ExpressionVariable(*(l.get_var()), &l.get_type())); fi->add_operand(e.clone()); rhs = new ExpressionFuncall(*fi); } else { rhs = &e; #if 0 if (e.term_type == eFunction) { const ExpressionFuncall* func = dynamic_cast<const ExpressionFuncall*>(&e); if (!func->get_invoke().safe_invocation()) { fs = SafeOpFlags::make_dummy_flags(); fs = NULL; } } #endif if (op != eSimpleAssign) { fs = SafeOpFlags::make_random(sOpAssign); bool op1 = fs->get_op1_sign(); bool op2 = fs->get_op2_sign(); enum SafeOpSize size = fs->get_op_size(); eSimpleType type1 = SafeOpFlags::flags_to_type(op1, size); eSimpleType type2 = SafeOpFlags::flags_to_type(op2, size); const Block *blk = cg_context.get_current_block(); assert(blk); tmp1 = blk->create_new_tmp_var(type1); tmp2 = blk->create_new_tmp_var(type2); } } StatementAssign *sa = new StatementAssign(cg_context.get_current_block(), l, op, e, rhs, fs, tmp1, tmp2); return sa; }
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const { // Check the function names first // Adding an exception to std::string sorting. I feel that functions beginning with an underscore should be placed before // functions beginning with an alphanumeric character. By default strings are sorted based on the ASCII value of each character. // Underscores have an ASCII value in between capital and lowercase characters. This is why the exception is needed. if (lhs.getFunctionName() < rhs.getFunctionName()) { if(rhs.getFunctionName().at(0) == '_') return false; else return true; } if (lhs.getFunctionName() > rhs.getFunctionName()) { if(lhs.getFunctionName().at(0) == '_') return true; else return false; } // Next check the return type if (lhs.getReturnType() < rhs.getReturnType()) return true; if (lhs.getReturnType() > rhs.getReturnType()) return false; // Check the number of operands if (lhs.mOperands.size() < rhs.mOperands.size()) return true; if (lhs.mOperands.size() > rhs.mOperands.size()) return false; // Now that we've gotten past the two quick tests, iterate over operands // Check the semantic and type. The operands must be in the same order as well. OperandVector::const_iterator itLHSOps = lhs.mOperands.begin(); OperandVector::const_iterator itRHSOps = rhs.mOperands.begin(); for ( ; ((itLHSOps != lhs.mOperands.end()) && (itRHSOps != rhs.mOperands.end())); ++itLHSOps, ++itRHSOps) { if (itLHSOps->getSemantic() < itRHSOps->getSemantic()) return true; if (itLHSOps->getSemantic() > itRHSOps->getSemantic()) return false; GpuConstantType leftType = itLHSOps->getParameter()->getType(); GpuConstantType rightType = itRHSOps->getParameter()->getType(); if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos) { if (leftType == GCT_SAMPLER1D) leftType = GCT_SAMPLER2D; if (rightType == GCT_SAMPLER1D) rightType = GCT_SAMPLER2D; } // If a swizzle mask is being applied to the parameter, generate the GpuConstantType to // perform the parameter type comparison the way that the compiler will see it. if ((itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) || (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0)) { if (itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) { leftType = (GpuConstantType)((itLHSOps->getParameter()->getType() - itLHSOps->getParameter()->getType()) + itLHSOps->getFloatCount(itLHSOps->getMask())); } if (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0) { rightType = (GpuConstantType)((itRHSOps->getParameter()->getType() - itRHSOps->getParameter()->getType()) + itRHSOps->getFloatCount(itRHSOps->getMask())); } } if (leftType < rightType) return true; if (leftType > rightType) return false; } return false; }
//----------------------------------------------------------------------- void GLSLProgramWriter::writeForwardDeclarations(std::ostream& os, Program* program) { os << "//-----------------------------------------------------------------------------" << std::endl; os << "// FORWARD DECLARATIONS" << std::endl; os << "//-----------------------------------------------------------------------------" << std::endl; StringVector forwardDecl; // holds all generated function declarations const ShaderFunctionList& functionList = program->getFunctions(); ShaderFunctionConstIterator itFunction; // Iterate over all functions in the current program (in our case this is always the main() function) for ( itFunction = functionList.begin(); itFunction != functionList.end(); ++itFunction) { Function* curFunction = *itFunction; const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); // Now iterate over all function atoms for ( ; itAtom != itAtomEnd; ++itAtom) { // Skip non function invocation atoms. if ((*itAtom)->getFunctionAtomType() != FunctionInvocation::Type) continue; FunctionInvocation* pFuncInvoc = static_cast<FunctionInvocation*>(*itAtom); FunctionInvocation::OperandVector::iterator itOperator = pFuncInvoc->getOperandList().begin(); FunctionInvocation::OperandVector::iterator itOperatorEnd = pFuncInvoc->getOperandList().end(); // Start with function declaration String funcDecl = pFuncInvoc->getReturnType() + " " + pFuncInvoc->getFunctionName() + "("; // Now iterate overall operands for (; itOperator != itOperatorEnd; ) { ParameterPtr pParam = (*itOperator).getParameter(); Operand::OpSemantic opSemantic = (*itOperator).getSemantic(); int opMask = (*itOperator).getMask(); GpuConstantType gpuType = GCT_UNKNOWN; // Write the semantic in, out, inout switch(opSemantic) { case Operand::OPS_IN: funcDecl += "in "; break; case Operand::OPS_OUT: funcDecl += "out "; break; case Operand::OPS_INOUT: funcDecl += "inout "; break; default: break; } // Swizzle masks are only defined for types like vec2, vec3, vec4. if (opMask == Operand::OPM_ALL) { gpuType = pParam->getType(); } else { // Now we have to convert the mask to operator gpuType = Operand::getGpuConstantType(opMask); } // We need a valid type otherwise glsl compilation will not work if (gpuType == GCT_UNKNOWN) { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can not convert Operand::OpMask to GpuConstantType", "GLSLProgramWriter::writeForwardDeclarations" ); } // Write the operand type. funcDecl += mGpuConstTypeMap[gpuType]; ++itOperator; //move over all operators with indirection while ((itOperator != itOperatorEnd) && (itOperator->getIndirectionLevel() != 0)) { ++itOperator; } // Prepare for the next operand if (itOperator != itOperatorEnd) { funcDecl += ", "; } } // Write function call closer. funcDecl += ");\n"; // Push the generated declaration into the vector // duplicate declarations will be removed later. forwardDecl.push_back(funcDecl); } } // Now remove duplicate declaration, first we have to sort the vector. std::sort(forwardDecl.begin(), forwardDecl.end()); StringVector::iterator endIt = std::unique(forwardDecl.begin(), forwardDecl.end()); // Finally write all function declarations to the shader file for (StringVector::iterator it = forwardDecl.begin(); it != endIt; it++) { os << *it; } }
bool RTShaderSRSSegmentedLights::addPSSegmentedTextureLightInvocation(Function* psMain, const int groupOrder, int& internalCounter) { float invWidth = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureWidth(); float invHeight = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureHeight(); ParameterPtr paramInvWidth = ParameterFactory::createConstParamFloat(invWidth); ParameterPtr paramInvHeight = ParameterFactory::createConstParamFloat(invHeight); FunctionInvocation* curFuncInvocation = NULL; curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_TEXTURE_AMBIENT_DIFFUSE, groupOrder, internalCounter++); curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); curFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); curFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); psMain->addAtomInstance(curFuncInvocation); if (SegmentedDynamicLightManager::getSingleton().isDebugMode()) { ParameterPtr psOutColor = psMain->resolveOutputParameter(Parameter::SPS_COLOR, -1, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); FunctionInvocation* curDebugFuncInvocation = NULL; curDebugFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_DEBUG, FFP_PS_COLOUR_END + 1, internalCounter++); curDebugFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); curDebugFuncInvocation->pushOperand(psOutColor, Operand::OPS_INOUT, Operand::OPM_XYZ); psMain->addAtomInstance(curDebugFuncInvocation); } return true; }
//----------------------------------------------------------------------- bool FFPColour::addFunctionInvocations(ProgramSet* programSet) { Program* vsProgram = programSet->getCpuVertexProgram(); Program* psProgram = programSet->getCpuFragmentProgram(); Function* vsMain = vsProgram->getEntryPointFunction(); Function* psMain = psProgram->getEntryPointFunction(); FunctionInvocation* curFuncInvocation = NULL; int internalCounter; // Create vertex shader colour invocations. ParameterPtr vsDiffuse; ParameterPtr vsSpecular; internalCounter = 0; if (mVSInputDiffuse.get() != NULL) { vsDiffuse = mVSInputDiffuse; } else { vsDiffuse = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSOutputDiffuse.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutputDiffuse, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSInputSpecular.get() != NULL) { vsSpecular = mVSInputSpecular; } else { vsSpecular = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } if (mVSOutputSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(mVSOutputSpecular, Operand::OPS_OUT); vsMain->addAtomInstace(curFuncInvocation); } // Create fragment shader colour invocations. ParameterPtr psDiffuse; ParameterPtr psSpecular; internalCounter = 0; // Handle diffuse colour. if (mPSInputDiffuse.get() != NULL) { psDiffuse = mPSInputDiffuse; } else { psDiffuse = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Handle specular colour. if (mPSInputSpecular.get() != NULL) { psSpecular = mPSInputSpecular; } else { psSpecular = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Assign diffuse colour. if (mPSOutputDiffuse.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Assign specular colour. if (mPSOutputSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutputSpecular, Operand::OPS_OUT); psMain->addAtomInstace(curFuncInvocation); } // Add specular to out colour. internalCounter = 0; if (mPSOutputDiffuse.get() != NULL && psSpecular.get() != NULL) { curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_PS_COLOUR_END, internalCounter++); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT,(Operand::OPM_X | Operand::OPM_Y | Operand::OPM_Z)); psMain->addAtomInstace(curFuncInvocation); } return true; }