void GL::EnableBlending(GLenum aSourceFactorRGB, GLenum aDestFactorRGB, GLenum aSourceFactorAlpha, GLenum aDestFactorAlpha) { MOZ_ASSERT(IsCurrent()); if (!mBlendingEnabled) { Enable(GL_BLEND); mBlendingEnabled = true; } if (mSourceBlendFactorRGB != aSourceFactorRGB || mDestBlendFactorRGB != aDestFactorRGB || mSourceBlendFactorAlpha != aSourceFactorAlpha || mDestBlendFactorAlpha != aDestFactorAlpha) { if (aSourceFactorRGB == aSourceFactorAlpha && aDestFactorRGB == aDestFactorAlpha) { BlendFunc(aSourceFactorRGB, aDestFactorRGB); } else { BlendFuncSeparate(aSourceFactorRGB, aDestFactorRGB, aSourceFactorAlpha, aDestFactorAlpha); } mSourceBlendFactorRGB = aSourceFactorRGB; mDestBlendFactorRGB = aDestFactorRGB; mSourceBlendFactorAlpha = aSourceFactorAlpha; mDestBlendFactorAlpha = aDestFactorAlpha; } }
void nuiGLPainter::StartRendering() { BeginSession(); //NUI_RETURN_IF_RENDERING_DISABLED; nuiCheckForGLErrors(); mScissorX = -1; mScissorY = -1; mScissorW = -1; mScissorH = -1; mScissorOn = false; nuiPainter::StartRendering(); SetViewport(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); glDisable(GL_TEXTURE_2D); #ifndef _OPENGL_ES_ if (mCanRectangleTexture == 2) { glDisable(GL_TEXTURE_RECTANGLE_ARB); } #endif glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); BlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); nuiCheckForGLErrors(); }
void nuiGLPainter::DrawArray(nuiRenderArray* pArray) { mRenderOperations++; mBatches++; //glEnable(GL_TEXTURE_2D); //glEnable(GL_TEXTURE_2D); if (!mEnableDrawArray) { pArray->Release(); return; } static uint32 ops = 0; static uint32 skipped_ops = 0; ops++; const nuiMatrix& rM(mMatrixStack.top()); float bounds[6]; pArray->GetBounds(bounds); if (rM.Elt.M11 == 1.0f && rM.Elt.M22 == 1.0f && rM.Elt.M33 == 1.0f && rM.Elt.M44 == 1.0f && rM.Elt.M12 == 0.0f && rM.Elt.M13 == 0.0f //&& rM.Elt.M14 == 0.0f && rM.Elt.M21 == 0.0f && rM.Elt.M23 == 0.0f //&& rM.Elt.M24 == 0.0f && rM.Elt.M31 == 0.0f && rM.Elt.M32 == 0.0f && rM.Elt.M34 == 0.0f && rM.Elt.M41 == 0.0f && rM.Elt.M42 == 0.0f && rM.Elt.M43 == 0.0f) { bounds[0] += rM.Elt.M14; bounds[1] += rM.Elt.M24; //bounds[2] += rM.Elt.M34; bounds[3] += rM.Elt.M14; bounds[4] += rM.Elt.M24; //bounds[5] += rM.Elt.M34; if ( (bounds[0] > mClip.Right()) || (bounds[1] > mClip.Bottom()) || (bounds[3] < mClip.Left()) || (bounds[4] < mClip.Top()) ) { skipped_ops++; // #ifdef _DEBUG // if (!(skipped_ops % 100)) // printf("optim (%d / %d) - %2.2f%%\n", skipped_ops, ops, (float)skipped_ops * 100.0f / (float)ops); // #endif return; } } // else // { // nglVectorf v1(bounds[0], bounds[1], 0); // topleft(x, y) // nglVectorf v2(bounds[3], bounds[4], 0); // bottomright(x, y) // v1 = rM * v1; // v2 = rM * v2; // // if ( // (v1[0] > mClip.Right()) || // (v1[1] > mClip.Bottom()) || // (v2[0] < mClip.Left()) || // (v2[1] < mClip.Top()) // ) // { // return; // } // } uint32 s = pArray->GetSize(); total += s; totalinframe += s; mins = MIN(mins, s); maxs = MAX(maxs, s); //printf("DA (%d) min = %d max = %d\n", s, mins, maxs); if (!s) { pArray->Release(); return; } if (mClip.GetWidth() <= 0 || mClip.GetHeight() <= 0) { pArray->Release(); return; } mVertices += s; GLenum mode = pArray->GetMode(); //NGL_OUT(_T("GL Array Mode: %d vertice count %d\n"), mode, size); /* switch (pArray->GetMode()) { LOGENUM(GL_POINTS); LOGENUM(GL_LINES); LOGENUM(GL_LINE_LOOP); LOGENUM(GL_LINE_STRIP); //LOGENUM(GL_TRIANGLES); LOGENUM(GL_TRIANGLE_STRIP); LOGENUM(GL_TRIANGLE_FAN); //LOGENUM(GL_QUADS); LOGENUM(GL_QUAD_STRIP); LOGENUM(GL_POLYGON); } */ NUI_RETURN_IF_RENDERING_DISABLED; bool NeedTranslateHack = pArray->IsShape() || ((mode == GL_POINTS || mode == GL_LINES || mode == GL_LINE_LOOP || mode == GL_LINE_STRIP) && !pArray->Is3DMesh()); float hackX; float hackY; if (NeedTranslateHack) { const float ratio=0.5f; #ifdef _UIKIT_ hackX = ratio; hackY = ratio; #else if (mAngle == 0) { hackX = ratio; hackY = ratio; } else if (mAngle == 90) { hackX = 0; hackY = ratio; } else if (mAngle == 180) { hackX = 0; hackY = 0; } else/*mAngle == 270*/ { hackX = ratio; hackY = 0; } #endif glTranslatef(hackX, hackY, 0); } #ifdef NUI_USE_ANTIALIASING if (mState.mAntialiasing) { #ifdef NUI_USE_MULTISAMPLE_AA glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); glEnable(GL_MULTISAMPLE_ARB); nuiCheckForGLErrors(); #else glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); BlendFuncSeparate(GL_SRC_ALPHA_SATURATE, GL_ONE); nuiCheckForGLErrors(); #endif } #endif // NUI_USE_ANTIALIASING if (pArray->IsArrayEnabled(nuiRenderArray::eVertex)) { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(nuiRenderArray::Vertex), &pArray->GetVertices()[0].mX); nuiCheckForGLErrors(); } else glDisableClientState(GL_VERTEX_ARRAY); if (pArray->IsArrayEnabled(nuiRenderArray::eColor)) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(nuiRenderArray::Vertex), &pArray->GetVertices()[0].mR); nuiCheckForGLErrors(); } else { glDisableClientState(GL_COLOR_ARRAY); nuiColor c; switch (pArray->GetMode()) { case GL_POINTS: case GL_LINES: case GL_LINE_LOOP: case GL_LINE_STRIP: c = mState.mStrokeColor; break; case GL_TRIANGLES: case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: #ifndef _OPENGL_ES_ case GL_QUADS: case GL_QUAD_STRIP: case GL_POLYGON: #endif c = mState.mFillColor; break; } glColor4f(c.Red(), c.Green(), c.Blue(), c.Alpha()); nuiCheckForGLErrors(); } if (pArray->IsArrayEnabled(nuiRenderArray::eTexCoord)) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(nuiRenderArray::Vertex), &pArray->GetVertices()[0].mTX); nuiCheckForGLErrors(); } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } //glDisableClientState(GL_COLOR_ARRAY); //glColor4f(0.5,0.5,0.5,0.5); /* if (pArray->IsArrayEnabled(nuiRenderArray::eNormal)) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(nuiRenderArray::Vertex)-12, &pArray->GetVertices()[0].mNX); nuiCheckForGLErrors(); } else glDisableClientState(GL_NORMAL_ARRAY); */ /* if (pArray->IsArrayEnabled(nuiRenderArray::eEdgeFlag)) { glEnableClientState(GL_EDGE_FLAG_ARRAY); glEdgeFlagPointer(sizeof(nuiRenderArray::Vertex), &pArray->GetVertices()[0].mEdgeFlag); nuiCheckForGLErrors(); } else glDisableClientState(GL_EDGE_FLAG_ARRAY); */ nuiCheckForGLErrors(); if (mpSurface && mTwoPassBlend) { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); uint32 arraycount = pArray->GetIndexArrayCount(); if (!arraycount) { glDrawArrays(mode, 0, s); } else { for (uint32 i = 0; i < arraycount; i++) { nuiRenderArray::IndexArray& array(pArray->GetIndexArray(i)); #ifdef _UIKIT_ glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_SHORT, &(array.mIndices[0])); #else glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_INT, &(array.mIndices[0])); #endif } } nuiCheckForGLErrors(); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glBlendFunc(mSrcAlpha, mDstAlpha); if (!arraycount) { glDrawArrays(mode, 0, s); } else { for (uint32 i = 0; i < arraycount; i++) { nuiRenderArray::IndexArray& array(pArray->GetIndexArray(i)); #ifdef _UIKIT_ glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_SHORT, &(array.mIndices[0])); #else glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_INT, &(array.mIndices[0])); #endif } } glBlendFunc(mSrcColor, mDstColor); nuiCheckForGLErrors(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } else { uint32 arraycount = pArray->GetIndexArrayCount(); if (!arraycount) { glDrawArrays(mode, 0, s); } else { for (uint32 i = 0; i < arraycount; i++) { nuiRenderArray::IndexArray& array(pArray->GetIndexArray(i)); #ifdef _UIKIT_ glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_SHORT, &(array.mIndices[0])); #else glDrawElements(array.mMode, array.mIndices.size(), GL_UNSIGNED_INT, &(array.mIndices[0])); #endif } } nuiCheckForGLErrors(); } #ifdef NUI_USE_ANTIALIASING if (mState.mAntialiasing) { #ifdef NUI_USE_MULTISAMPLE_AA glDisable(GL_MULTISAMPLE_ARB); #else glDisable(GL_POLYGON_SMOOTH); glDisable(GL_BLEND); BlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); #endif nuiCheckForGLErrors(); } else #endif // NUI_USE_ANTIALIASING { //#TEST meeloo disabling AA texture // if (pArray->UseGLAATexture()) // { // glMatrixMode(GL_TEXTURE); // glPopMatrix(); // glMatrixMode(GL_MODELVIEW); // glPopMatrix(); // // if (mState.mpTexture && mState.mTexturing) // { // if (mTextureTarget != GL_TEXTURE_2D) // { // glDisable(GL_TEXTURE_2D); // glEnable(mTextureTarget); // } // // UploadTexture(mState.mpTexture); // } // else // { // glDisable(GL_TEXTURE_2D); // } // // if (!mState.mBlending) // glDisable(GL_BLEND); // if (mState.mBlendFunc != nuiBlendTransp) // { // GLenum src, dst; // nuiGetBlendFuncFactors(mState.mBlendFunc, src, dst); // glBlendFunc(src, dst); // } // //ApplyTexture(mState, true); // } // else if (NeedTranslateHack) glTranslatef(-hackX, -hackY, 0); } // glColor3f(1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); pArray->Release(); nuiCheckForGLErrors(); }
void nuiGLPainter::SetState(const nuiRenderState& rState, bool ForceApply) { //TEST_FBO_CREATION(); NUI_RETURN_IF_RENDERING_DISABLED; nuiCheckForGLErrors(); // blending if (ForceApply || mState.mBlending != rState.mBlending) { mState.mBlending = rState.mBlending; if (mState.mBlending) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } } if (ForceApply || mState.mBlendFunc != rState.mBlendFunc) { mState.mBlendFunc = rState.mBlendFunc; GLenum src, dst; nuiGetBlendFuncFactors(rState.mBlendFunc, src, dst); BlendFuncSeparate(src, dst); nuiCheckForGLErrors(); } if (ForceApply || mState.mDepthTest != rState.mDepthTest) { mState.mDepthTest = rState.mDepthTest; if (mState.mDepthTest) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); } if (ForceApply || mState.mDepthWrite != rState.mDepthWrite) { mState.mDepthWrite = rState.mDepthWrite; glDepthMask(mState.mDepthWrite); } // We don't care about the font in the lower layer of rendering //nuiFont* mpFont; // ApplyTexture(rState, ForceApply); // Rendering buffers: if (ForceApply || mState.mColorBuffer != rState.mColorBuffer) { mState.mColorBuffer = rState.mColorBuffer; GLboolean m = mState.mColorBuffer ? GL_TRUE : GL_FALSE; glColorMask(m, m, m, m); nuiCheckForGLErrors(); } if (mClip.mEnabled || ForceApply) { uint32 width = mWidth; uint32 height = mHeight; if (mpSurface) { width = mpSurface->GetWidth(); height = mpSurface->GetHeight(); } nuiRect clip(mClip); int x,y,w,h; uint angle = (mpSurface && mpSurface->GetRenderToTexture()) ? 0 : mAngle; if (angle == 90) { x = ToBelow(clip.Top()); y = ToBelow(clip.Left()); w = ToBelow(clip.GetHeight()); h = ToBelow(clip.GetWidth()); } else if (angle == 180) { w = ToBelow(clip.GetWidth()); h = ToBelow(clip.GetHeight()); x = ToBelow(width - w - clip.Left()); y = ToBelow(clip.Top()); } else if (angle == 270) { w = ToBelow(clip.GetHeight()); h = ToBelow(clip.GetWidth()); x = ToBelow(height - clip.Top() - w); y = ToBelow(width - clip.Left() - h); } else { NGL_ASSERT(!angle); x = ToBelow(clip.Left()); y = ToBelow(height - clip.Bottom()); w = ToBelow(clip.GetWidth()); h = ToBelow(clip.GetHeight()); } //NGL_OUT(_T("To Screen Clip {%d, %d, %d, %d}\n"), x,y,w,h); if (!mScissorOn || ForceApply) { glEnable(GL_SCISSOR_TEST); mScissorOn = true; } if (mScissorX != x || mScissorY != y || mScissorW != w || mScissorH != h || ForceApply) { mScissorX = x; mScissorY = y; mScissorW = w; mScissorH = h; x *= NUI_SCALE_FACTOR; y *= NUI_SCALE_FACTOR; w *= NUI_SCALE_FACTOR; h *= NUI_SCALE_FACTOR; glScissor(x, y, w, h); } nuiCheckForGLErrors(); } else { if (mScissorOn || ForceApply) { glDisable(GL_SCISSOR_TEST); mScissorOn = false; } } mState.mClearColor = rState.mClearColor; mState.mStrokeColor = rState.mStrokeColor; mState.mFillColor = rState.mFillColor; nuiCheckForGLErrors(); }