void GradientField::setup(float w, float h) { setSize(w, h); initParams(); allocateFbo(); createHexagonModel(); setHexagonModelColors(); createTriangleModel(); setTriangleModelColors(); renderShader.load("shaders/gradientfield_render"); plane.mapTexCoords(0, 0, 1, 1); plane.setWidth(getWidth()); plane.setHeight(getHeight()); bModelColorsDirty = true; bFboDirty = true; bIgnoreParamChange = false; }
/** * Sets up and binds the FBO. * 1: Set element according to fields. * 2: Let children manipulate setup. * 3: Allocate/deallocate if need be. * 4: Set element according to finished Fbo */ void SoXipFbo::GLRender(SoGLRenderAction* action) { //SoDebugError::postInfo(__FUNCTION__, "(1) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (autoSize.getValue()) { const SbVec2s &viewportSize = action->getViewportRegion().getViewportSizePixels(); if (viewportSize != SbVec2s(width.getValue(), height.getValue())) { SoDebugError::postInfo("SoXipFbo", "Autosetting FBO size to (%d, %d)", viewportSize[0], viewportSize[1]); width.setValue(viewportSize[0]); height.setValue(viewportSize[1]); mNeedsUpdate = true; } } // Can't use sensors if fields are changed while traversing tree, such as by parent size changing if (width.getValue() != mFboIn.width || height.getValue() != mFboIn.height) mNeedsUpdate = true; if (mNeedsUpdate) { // Check number of buffers checkMaxNumBuffers(); // Dealloc if allocated if (mIsAllocated) deallocate(); mFboIn.clear(); mFboMod.clear(); mFboOut.clear(); int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); allocateFbo(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); //SoDebugError::postInfo(__FUNCTION__, "Allocated new Fbo (dirty)"); mNeedsUpdate = false; } else mFboIn.isDirty = false; mFboMod.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(2) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Send to element and render children to allow modification mFboIn.isOpen = true; SoXipFboElement::set(action->getState(), this, mFboIn); SoXipFboElement::bind(action->getState(), this); int currentFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, ¤tFbo); if (!glIsFramebufferEXT(mFboIn.fboHandle) || mFboIn.fboHandle != currentFbo) { SoDebugError::postWarning("SoXipFbo", "Error in the setup, fbo not guaranteed to be bound"); mNeedsUpdate = true; return; } ////////// /// Traverse children SoGroup::GLRender(action); /// Traverse children ////////// FboSetup * fbo = SoXipFboElement::getActive(action->getState(), this); // Detect any change in fbo handle if (mFboIn.fboHandle != fbo->fboHandle) SoDebugError::postWarning("SoXipFbo", "Keep Fbo bound during traversal (%d %d)", mFboIn.fboHandle, fbo->fboHandle); //SoDebugError::postInfo(__FUNCTION__, "(3) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Reflect changes if change since last run if (mFboMod != *fbo) { mFboMod = *fbo; mFboOut = *fbo; int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); processColorMods(); processDepthMods(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); mErrorInSetup = false; } else mFboOut.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(4) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); SoXipDrawBuffersElement::set(action->getState(), this, mFboOut.numColorAttachments); // Everything is now attached so test completeness if (!mErrorInSetup) mFboOut.isComplete = checkFramebufferStatus(); if (!mFboOut.isComplete) mErrorInSetup = true; // Activate FBO element (also sets draw buffer element) mFboOut.isOpen = false; SoXipFboElement::set(action->getState(), this, mFboOut); //SoDebugError::postInfo(__FUNCTION__, "(5) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (!mFboOut.isComplete) SoXipDrawBuffersElement::set(action->getState(), this, 0); }