Commit 0130f3fa authored by Christopher Tenter's avatar Christopher Tenter
Browse files

separate blend functions on snapshot with state locking refs #2506

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20981 383ad7c9-94d9-4d36-a494-682f7c89f535
parent b1a39559
......@@ -76,7 +76,7 @@ const float GLState::default_shininess(100.f);
bool GLState::depthFuncLock_ = false;
bool GLState::depthRangeLock_ = false;
bool GLState::blendFuncLock_ = false;
bool GLState::blendFuncSeparateLock_[2] = { false };
bool GLState::blendEquationLock_ = false;
bool GLState::blendColorLock_ = false;
bool GLState::alphaFuncLock_ = false;
......@@ -1335,11 +1335,26 @@ void GLState::syncFromGL()
}
GLint getparam;
#ifdef GL_VERSION_1_4
glGetIntegerv(GL_BLEND_SRC_RGB, &getparam);
stateStack_.back().blendFuncState_[0] = getparam;
glGetIntegerv(GL_BLEND_DST_ALPHA, &getparam);
stateStack_.back().blendFuncState_[1] = getparam;
glGetIntegerv(GL_BLEND_SRC_ALPHA, &getparam);
stateStack_.back().blendFuncState_[2] = getparam;
glGetIntegerv(GL_BLEND_DST_ALPHA, &getparam);
stateStack_.back().blendFuncState_[3] = getparam;
#else
glGetIntegerv(GL_BLEND_SRC, &getparam);
stateStack_.back().blendFuncState_[0] = getparam;
glGetIntegerv(GL_BLEND_DST, &getparam);
stateStack_.back().blendFuncState_[1] = getparam;
#endif
glGetIntegerv(GL_BLEND_EQUATION_RGB, &getparam);
......@@ -1583,25 +1598,55 @@ bool GLState::isClientStateEnabled(GLenum _cap)
//-----------------------------------------------------------------------------
// blending functions
void GLState::blendFunc(GLenum _sfactor, GLenum _dfactor)
void GLState::blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
{
if (!blendFuncLock_)
// fix parameters according to lock status
if (blendFuncSeparateLock_[0])
{
_srcRGB = stateStack_.back().blendFuncState_[0];
_dstRGB = stateStack_.back().blendFuncState_[1];
}
if (blendFuncSeparateLock_[1])
{
_srcAlpha = stateStack_.back().blendFuncState_[2];
_dstAlpha = stateStack_.back().blendFuncState_[3];
}
if (!blendFuncSeparateLock_[0] || !blendFuncSeparateLock_[1])
{
#ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
if (stateStack_.back().blendFuncState_[0] != _sfactor || stateStack_.back().blendFuncState_[1] != _dfactor)
if (stateStack_.back().blendFuncState_[0] != _srcRGB || stateStack_.back().blendFuncState_[1] != _dstRGB ||
stateStack_.back().blendFuncState_[2] != _srcAlpha || stateStack_.back().blendFuncState_[3] != _dstAlpha)
#endif
{
glBlendFunc(_sfactor, _dfactor);
stateStack_.back().blendFuncState_[0] = _sfactor;
stateStack_.back().blendFuncState_[1] = _dfactor;
#ifdef GL_VERSION_1_4
// check if glew has loaded glBlendFuncSeparate already
if (glBlendFuncSeparate)
glBlendFuncSeparate(_srcRGB, _dstRGB, _srcAlpha, _dstAlpha);
else
glBlendFunc(_srcRGB, _dstRGB);
stateStack_.back().blendFuncState_[0] = _srcRGB;
stateStack_.back().blendFuncState_[1] = _dstRGB;
stateStack_.back().blendFuncState_[2] = _srcAlpha;
stateStack_.back().blendFuncState_[3] = _dstAlpha;
#else
glBlendFunc(_srcRGB, _dstRGB);
stateStack_.back().blendFuncState_[0] = _srcRGB;
stateStack_.back().blendFuncState_[1] = _dstRGB;
stateStack_.back().blendFuncState_[2] = _srcRGB;
stateStack_.back().blendFuncState_[3] = _dstRGB;
#endif
}
}
}
void GLState::getBlendFunc(GLenum* _sfactor, GLenum* _dfactor)
void GLState::getBlendFuncSeparate(GLenum* _srcRGB, GLenum* _dstRGB, GLenum* _srcAlpha, GLenum* _dstAlpha)
{
if (_sfactor) *_sfactor = stateStack_.back().blendFuncState_[0];
if (_dfactor) *_dfactor = stateStack_.back().blendFuncState_[1];
if (_srcRGB) *_srcRGB = stateStack_.back().blendFuncState_[0];
if (_dstRGB) *_dstRGB = stateStack_.back().blendFuncState_[1];
if (_srcAlpha) *_srcAlpha = stateStack_.back().blendFuncState_[2];
if (_dstAlpha) *_dstAlpha = stateStack_.back().blendFuncState_[3];
}
void GLState::blendEquation(GLenum _mode)
......
......@@ -125,8 +125,8 @@ public:
// iff a bit is set for a state, it is enabled in OpenGL
std::bitset<0xFFFF+1> glStateEnabled_;
// element 0: sfactor, 1: dfactor
GLenum blendFuncState_[2];
// element 0: sfactor, 1: dfactor, 2 : alpha_sfactor, 3 : alpha_dfactor
GLenum blendFuncState_[4];
GLenum blendEquationState_;
......@@ -287,17 +287,35 @@ public:
/// replaces glBlendFunc, supports locking
static void blendFunc(GLenum _sfactor, GLenum _dfactor);
static void blendFunc(GLenum _sfactor, GLenum _dfactor) { blendFuncSeparate(_sfactor, _dfactor, _sfactor, _dfactor); }
/// get blend function, null-ptr safe
static void getBlendFunc(GLenum* _sfactor, GLenum* _dfactor);
static void getBlendFunc(GLenum* _sfactor, GLenum* _dfactor) { getBlendFuncSeparate(_sfactor, _dfactor, 0, 0); }
/// lock blend func
static void lockBlendFunc() {blendFuncLock_ = true;}
static void lockBlendFunc() { lockBlendFuncSeparate(); }
/// unlock blend func
static void unlockBlendFunc() {blendFuncLock_ = false;}
static void unlockBlendFunc() { unlockBlendFuncSeparate(); }
/// get blend func locking state
static bool isBlendFuncLocked() {return blendFuncLock_;}
static bool isBlendFuncLocked() {return isBlendFuncSeparateLocked();}
/// replaces glBlendFuncSeparate, supports locking
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha);
/// get blend function, null-ptr safe
static void getBlendFuncSeparate(GLenum* _srcRGB, GLenum* _dstRGB, GLenum* _srcAlpha, GLenum* _dstAlpha);
/// lock blend func
static void lockBlendFuncSeparate(bool _rgb = true, bool _alpha = true) { blendFuncSeparateLock_[0] = _rgb; blendFuncSeparateLock_[1] = _alpha; }
/// unlock blend func
static void unlockBlendFuncSeparate() { lockBlendFuncSeparate(false, false); }
/// get blend func locking state
static bool isBlendFuncSeparateLocked() { return blendFuncSeparateLock_[0] || blendFuncSeparateLock_[1]; }
static bool isBlendFuncSeparateColorLocked() { return blendFuncSeparateLock_[0]; }
static bool isBlendFuncSeparateAlphaLocked() { return blendFuncSeparateLock_[1]; }
/// replaces glBlendEquation, supports locking
static void blendEquation(GLenum _mode);
......@@ -1197,7 +1215,7 @@ private: //--------------------------------------------------------------------
// iff a bit is set for a state, it is locked
static std::bitset<0xFFFF+1> glStateLock_;
static bool blendFuncLock_;
static bool blendFuncSeparateLock_[2];
static bool blendEquationLock_;
static bool blendColorLock_;
static bool alphaFuncLock_;
......
......@@ -922,7 +922,7 @@ void IRenderer::bindObjectRenderStates(ACG::RenderObject* _obj)
// ACG::GLState::shadeModel(_obj->shadeModel);
glBlendFunc(_obj->blendSrc, _obj->blendDest);
ACG::GLState::blendFunc(_obj->blendSrc, _obj->blendDest);
}
void IRenderer::drawObject(ACG::RenderObject* _obj)
......@@ -1518,7 +1518,7 @@ void IRenderer::renderLineThicknessGL42()
// enable alpha blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ACG::GLState::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLSL::Program* shaderComposite = ShaderCache::getInstance()->getProgram("ScreenQuad/screenquad.glsl", "Wireframe/gl42/composite.glsl", &macros);
......
......@@ -668,11 +668,11 @@ void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, G
ro.setMaterial(_mat);
ro.shaderDesc.vertexTemplateFile = ""; //QString(props->vertexShader().c_str());
ro.shaderDesc.geometryTemplateFile = ""; //QString(props->geometryShader().c_str());
ro.shaderDesc.fragmentTemplateFile = ""; //QString(props->fragmentShader().c_str());
ro.shaderDesc.vertexTemplateFile.clear(); //QString(props->vertexShader().c_str());
ro.shaderDesc.geometryTemplateFile.clear(); //QString(props->geometryShader().c_str());
ro.shaderDesc.fragmentTemplateFile.clear(); //QString(props->fragmentShader().c_str());
ro.shaderDesc.vertexColorsInterpolator = "";
ro.shaderDesc.vertexColorsInterpolator.clear();
// ------------------------
// 1. setup drawMesh based on property source
......@@ -894,7 +894,7 @@ void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, G
add_face_RenderObjects(_renderer, &ro, useNonIndexed);
ro.shaderDesc.vertexColorsInterpolator = "";
ro.shaderDesc.vertexColorsInterpolator.clear();
} break;
default: break;
}
......
......@@ -2316,10 +2316,16 @@ void glViewer::snapshot(QImage& _image, int _width, int _height, bool _alpha, bo
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// adjust blend function for alpha channel
ACG::GLState::blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
ACG::GLState::lockBlendFuncSeparate(false, true);
glEnable(GL_MULTISAMPLE);
paintGL();
glFinish();
ACG::GLState::unlockBlendFuncSeparate();
glDisable(GL_MULTISAMPLE);
//Qt FrameBuffer "toImage" function returns QImage::Format_ARGB32_Premultiplied. not desired
......@@ -2342,26 +2348,6 @@ void glViewer::snapshot(QImage& _image, int _width, int _height, bool _alpha, bo
glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,reinterpret_cast<void*>(_image.bits()));
_image = _image.mirrored(false,true);//convert from opengl to qt coordinates
if (_alpha)
{
QRgb backRGBA = qRgba(int(newBack[0] * 255.0f), int(newBack[1] * 255.0f), int(newBack[2] * 255.0f), 0);
// fix alpha channel
for (int i = 0; i < _image.width(); ++i)
{
for (int k = 0; k < _image.height(); ++k)
{
QRgb pix = _image.pixel(i, k);
// snap alpha channel to 255 for pixels different from the background color
if (pix != backRGBA)
pix |= 0xff000000;
_image.setPixel(i, k, pix);
}
}
}
//cleanup
ACG::GLState::bindFramebuffer(GL_FRAMEBUFFER_EXT, prevFbo);
......
......@@ -390,7 +390,7 @@ void DepthPeeling::renderFrontPeeling(ACG::GLState* _glState,
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE,
ACG::GLState::blendFuncSeparate(GL_DST_ALPHA, GL_ONE,
GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
......@@ -651,7 +651,7 @@ void DepthPeeling::renderDualPeeling(ACG::GLState* _glState, Viewer::ViewerPrope
glDrawBuffer(colorBlendTarget);
glBlendEquationEXT(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ACG::GLState::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// bind back color texture to slot 0
glActiveTexture(GL_TEXTURE0);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment