void RegisterCombinersChunk::activate( DrawActionBase *action, UInt32 ) { Window *win = action->getWindow(); if(! win->hasExtension(_nvRegisterCombiners)) return; // setup register combiners // functions void (OSG_APIENTRY*CombinerParameterfv)(GLenum pname, GLfloat *params) = reinterpret_cast<void (OSG_APIENTRY*)(GLenum pname, GLfloat *params)>( win->getFunction(_funcCombinerParameterfv)); void (OSG_APIENTRY*CombinerStageParameterfv)(GLenum stage, GLenum pname, GLfloat *params) = reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage, GLenum pname, GLfloat *params)>( win->getFunction(_funcCombinerStageParameterfv)); void (OSG_APIENTRY*CombinerInput)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum component) = reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum component)>( win->getFunction(_funcCombinerInput)); void (OSG_APIENTRY*CombinerOutput)(GLenum stage, GLenum portion, GLenum abOut, GLenum cdOut, GLenum sumOut, GLenum scale, GLenum bias, GLboolean abdot, GLboolean cddot, GLboolean muxSum) = reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage, GLenum portion, GLenum abOut, GLenum cdOut, GLenum sumOut, GLenum scale, GLenum bias, GLboolean abdot, GLboolean cddot, GLboolean muxSum)>( win->getFunction(_funcCombinerOutput)); void (OSG_APIENTRY*FinalCombinerInput)(GLenum variable, GLenum input, GLenum mapping, GLenum component) = reinterpret_cast<void (OSG_APIENTRY*)(GLenum variable, GLenum input, GLenum mapping, GLenum component)>( win->getFunction(_funcFinalCombinerInput)); // how many combiners do we need? Int32 ncomb; for(ncomb = OSG_NUM_COMBINERS - 1; ncomb >= 0; ncomb--) { if(getVariableArgb(ncomb * 3) != unused) break; } if(ncomb < 0) { // no combiner active, return glDisable(GL_REGISTER_COMBINERS_NV); return; } ncomb++; GLfloat dummy = GLfloat(ncomb); CombinerParameterfv(GL_NUM_GENERAL_COMBINERS_NV, &dummy); CombinerParameterfv(GL_CONSTANT_COLOR0_NV, const_cast<GLfloat *>(getColor0().getValuesRGBA())); CombinerParameterfv(GL_CONSTANT_COLOR1_NV, const_cast<GLfloat*>(getColor1().getValuesRGBA())); dummy = getColorSumClamp(); CombinerParameterfv(GL_COLOR_SUM_CLAMP_NV, &dummy); // setup the general combiners bool hasRC2 = win->hasExtension(_nvRegisterCombiners2); for(UInt16 i = 0; i < ncomb; i++) { if(getVariableArgb(i * 3) != unused) { // RGB inputs CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_A_NV, getVariableArgb(i * 3), getVariableArgb(i * 3 + 1), getVariableArgb(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_B_NV, getVariableBrgb(i * 3), getVariableBrgb(i * 3 + 1), getVariableBrgb(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_C_NV, getVariableCrgb(i * 3), getVariableCrgb(i * 3 + 1), getVariableCrgb(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_D_NV, getVariableDrgb(i * 3), getVariableDrgb(i * 3 + 1), getVariableDrgb(i * 3 + 2) ); // RGB output CombinerOutput(GL_COMBINER0_NV + i, GL_RGB, getOutputABrgb (i), getOutputCDrgb (i), getOutputSumrgb (i), getScalergb (i), getBiasrgb (i), getDotABrgb (i), getDotCDrgb (i), getMuxSumrgb (i) ); } else { CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_A_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); CombinerOutput(GL_COMBINER0_NV + i, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); } if(getVariableAalpha(i * 3) != unused) { // Alpha inputs CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_A_NV, getVariableAalpha(i * 3), getVariableAalpha(i * 3 + 1), getVariableAalpha(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_B_NV, getVariableBalpha(i * 3), getVariableBalpha(i * 3 + 1), getVariableBalpha(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_C_NV, getVariableCalpha(i * 3), getVariableCalpha(i * 3 + 1), getVariableCalpha(i * 3 + 2) ); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_D_NV, getVariableDalpha(i * 3), getVariableDalpha(i * 3 + 1), getVariableDalpha(i * 3 + 2) ); // ALPHA output CombinerOutput(GL_COMBINER0_NV + i, GL_ALPHA, getOutputABalpha (i), getOutputCDalpha (i), getOutputSumalpha (i), getScalealpha (i), getBiasalpha (i), GL_FALSE, GL_FALSE, getMuxSumalpha (i) ); } else { CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_A_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); CombinerOutput(GL_COMBINER0_NV + i, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE ); } if(getPerStageConstants()) { if(hasRC2) { CombinerStageParameterfv( GL_COMBINER0_NV + i, GL_CONSTANT_COLOR0_NV, const_cast<GLfloat*>( getCombinerColor0(i).getValuesRGBA())); CombinerStageParameterfv( GL_COMBINER0_NV + i, GL_CONSTANT_COLOR1_NV, const_cast<GLfloat*>( getCombinerColor1(i).getValuesRGBA())); } else { FWARNING(("RegisterCombinersChunk::register_combiners2 not" "supported, constant colors ignored!!\n")); } } } if(hasRC2) { if(getPerStageConstants()) { glEnable(GL_PER_STAGE_CONSTANTS_NV); } else { glDisable(GL_PER_STAGE_CONSTANTS_NV); } } glErr("RegisterCombinersChunk::general combiners setup"); // setup the final combiner FinalCombinerInput(GL_VARIABLE_A_NV, getVariableArgb(OSG_NUM_COMBINERS * 3), getVariableArgb(OSG_NUM_COMBINERS * 3 + 1), getVariableArgb(OSG_NUM_COMBINERS * 3 + 2)); glErr("RegisterCombinersChunk::final combiner var a setup"); FinalCombinerInput(GL_VARIABLE_B_NV, getVariableBrgb(OSG_NUM_COMBINERS * 3), getVariableBrgb(OSG_NUM_COMBINERS * 3 + 1), getVariableBrgb(OSG_NUM_COMBINERS * 3 + 2)); glErr("RegisterCombinersChunk::final combiner var b setup"); FinalCombinerInput(GL_VARIABLE_C_NV, getVariableCrgb(OSG_NUM_COMBINERS * 3), getVariableCrgb(OSG_NUM_COMBINERS * 3 + 1), getVariableCrgb(OSG_NUM_COMBINERS * 3 + 2)); glErr("RegisterCombinersChunk::final combiner var c setup"); FinalCombinerInput(GL_VARIABLE_D_NV, getVariableDrgb(OSG_NUM_COMBINERS * 3), getVariableDrgb(OSG_NUM_COMBINERS * 3 + 1), getVariableDrgb(OSG_NUM_COMBINERS * 3 + 2)); glErr("RegisterCombinersChunk::final combiner var d setup"); FinalCombinerInput(GL_VARIABLE_E_NV, getVariableE(0), getVariableE(1), getVariableE(2)); glErr("RegisterCombinersChunk::final combiner var e setup"); FinalCombinerInput(GL_VARIABLE_F_NV, getVariableF(0), getVariableF(1), getVariableF(2)); glErr("RegisterCombinersChunk::final combiner var f setup"); FinalCombinerInput(GL_VARIABLE_G_NV, getVariableG(0), getVariableG(1), getVariableG(2)); glErr("RegisterCombinersChunk::final combiner setup"); // and activate everything glEnable(GL_REGISTER_COMBINERS_NV); glErr("RegisterCombinersChunk::activate"); }
void DeferredContainer::draw() const { //"The Screen". It may not be actually the screen since a upper container might be postprocessing const RenderTargetBase* screen = RenderTargetBase::getCurrent(); GL_ASSERT(glEnable(GL_DEPTH_TEST)); GL_ASSERT(glDisable(GL_BLEND)); //Deferred pass Debugger::pushMark("Deferred Pass", "Time spent rendering geometry to the g-buffer"); drawMode = Deferred; RenderTargetBase::bind(gBuffer); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); ContainerObject::draw(); Debugger::popMark(); //deferred //Shadowmap pass Debugger::pushMark("Shadowmap Pass", "Time spent rendering geometry to the layered shadowmap"); glEnable(GL_DEPTH_CLAMP); drawMode = ShadowMap; RenderTargetBase::bind(sunTarget); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT)); ContainerObject::draw(); glDisable(GL_DEPTH_CLAMP); Debugger::popMark(); //shadow //Transparent shadowmap pass Debugger::pushMark("Transparent ShadowMap Pass", "Time spent rendering transparent geometry to the layered shadowmap"); glEnable(GL_DEPTH_CLAMP); drawMode = TransShadowMap; RenderTargetBase::bind(sunTargetTrans); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT)); ContainerObject::draw(); glDisable(GL_DEPTH_CLAMP); Debugger::popMark(); //transparent shadow Debugger::pushMark("Light Pass", "Time spent rendering deferred lights"); //bind output texture (screen) RenderTargetBase::bind(screen); GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); //Light pass GL_ASSERT(glEnable(GL_BLEND)); GL_ASSERT(glBlendFunc(GL_ONE, GL_ONE)); //additive GL_ASSERT(glDepthMask(GL_FALSE)); GL_ASSERT(glDepthFunc(GL_ALWAYS)); drawMode = Light; ContainerObject::draw(); Debugger::popMark(); //lights //Ambient+Visibility pass Debugger::pushMark("Ambient+Visibility Pass", "Time spent rendering ambient light and sunlight contribution to the scene"); GL_ASSERT(glDepthMask(GL_TRUE)); const Camera* cam = (Camera*)getGame()->getObjectByName("playerCam"); Sun* sun = (Sun*)getGame()->getObjectByName("sun"); glm::mat4 biasMatrix( //gets coords from [-1..1] to [0..1] 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); //compute each of the cascaded cameras's matrices std::vector<mat4f> depthMVP(NUM_SUN_CASCADES); for(int i = 0; i < NUM_SUN_CASCADES; ++i) depthMVP[i] = biasMatrix*(sun->getVPMatrices()[i]*fullTransform); Programs.get("ambientPass").uniform("MVP")->set(mat4f(1.0f)); Programs.get("ambientPass").uniform("camMV")->set(cam->getView()*fullTransform); Programs.get("ambientPass").uniform("color0")->set(getColor0()); Programs.get("ambientPass").uniform("color1")->set(getColor1()); Programs.get("ambientPass").uniform("invResolution")->set(vec2f(1.0f/screen->getSize().x, 1.0f/screen->getSize().y)); Programs.get("ambientPass").uniform("invCamProj")->set(glm::inverse(cam->projection)); Programs.get("ambientPass").uniform("invCamView")->set(glm::inverse(cam->getView())); Programs.get("ambientPass").uniform("lightDir")->set(sun->getCam(0)->getForward()); Programs.get("ambientPass").uniform("worldsize")->set(WORLDSIZE); Programs.get("ambientPass").uniform("depthMVP")->set(depthMVP); Programs.get("ambientPass").uniform("depthPlanes")->set(sun->getDepthPlanes()); Programs.get("ambientPass").uniform("depth")->set(gBuffer.getTexture(RenderTargetBase::DEPTH)); Programs.get("ambientPass").uniform("sunDepth")->set(sunTarget.getTexture(RenderTargetBase::DEPTH)); Programs.get("ambientPass").uniform("sunDepthTrans")->set(sunTargetTrans.getTexture(RenderTargetBase::DEPTH)); quad->draw(Programs.get("ambientPass")); Debugger::popMark(); //ambient+shadowmap //Forward pass Debugger::pushMark("Forward Pass", "Time spent rendering forward-render stuff"); GL_ASSERT(glDepthMask(GL_TRUE)); GL_ASSERT(glDepthFunc(GL_LEQUAL)); GL_ASSERT(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //forward rendering blending drawMode = Forward; ContainerObject::draw(); Debugger::popMark(); }