nux-1.16.0
GraphicsEngine.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "NuxCore/NuxCore.h"
00024 
00025 #include "NuxImage/ImageSurface.h"
00026 
00027 #include "GpuDevice.h"
00028 #include "GLDeviceObjects.h"
00029 #include "GLResourceManager.h"
00030 
00031 #include "GLTextureResourceManager.h"
00032 #include "GLVertexResourceManager.h"
00033 
00034 #include "FontTexture.h"
00035 #include "FontRenderer.h"
00036 #include "GraphicsEngine.h"
00037 
00038 namespace nux
00039 {
00040 
00041   BlendOperator::BlendOperator ()
00042   {
00043     _enable = true;
00044     _src_blend = GL_ONE;
00045     _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00046   }
00047 
00048   BlendOperator::~BlendOperator ()
00049   {
00050     _enable = true;
00051     _src_blend = GL_ONE;
00052     _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00053   }
00054 
00055   void BlendOperator::EnableBlending (bool enable)
00056   {
00057     _enable = enable;
00058   }
00059 
00060   void BlendOperator::SetPorterDuffOperator (PorterDuffOperator op)
00061   {
00062     switch (op)
00063     {
00064     case CLEAR:
00065       _src_blend = GL_ZERO;
00066       _dst_blend = GL_ZERO;
00067       break;
00068     case SRC:
00069       _src_blend = GL_ONE;
00070       _dst_blend = GL_ZERO;
00071       break;
00072     case DST:
00073       _src_blend = GL_ZERO;
00074       _dst_blend = GL_ONE;
00075       break;
00076     case SRC_OVER:
00077       _src_blend = GL_ONE;
00078       _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00079       break;
00080     case DST_OVER:
00081       _src_blend = GL_ONE_MINUS_DST_ALPHA;
00082       _dst_blend = GL_ONE;
00083       break;
00084     case SRC_IN:
00085       _src_blend = GL_DST_ALPHA;
00086       _dst_blend = GL_ZERO;
00087       break;
00088     case DST_IN:
00089       _src_blend = GL_ZERO;
00090       _dst_blend = GL_SRC_ALPHA;
00091       break;
00092     case SRC_OUT:
00093       _src_blend = GL_ONE_MINUS_DST_ALPHA;
00094       _dst_blend = GL_ZERO;
00095       break;
00096     case DST_OUT:
00097       _src_blend = GL_ZERO;
00098       _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00099       break;
00100     case SRC_ATOP:
00101       _src_blend = GL_DST_ALPHA;
00102       _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00103       break;
00104     case DST_ATOP:
00105       _src_blend = GL_ONE_MINUS_DST_ALPHA;
00106       _dst_blend = GL_SRC_ALPHA;
00107       break;
00108     case XOR:
00109       _src_blend = GL_ONE_MINUS_DST_ALPHA;
00110       _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00111       break;
00112     case PLUS:
00113       _src_blend = GL_ONE;
00114       _dst_blend = GL_ONE;
00115       break;
00116     default:
00117       // Use SRC_OVER
00118       _src_blend = GL_ONE;
00119       _dst_blend = GL_ONE_MINUS_SRC_ALPHA;
00120       break;
00121     }
00122   }
00123 
00124   void BlendOperator::SetCustomBlendOperator (unsigned int src_blend, unsigned int dst_blend)
00125   {
00126 
00127   }
00128 
00129 
00130   ROPConfig ROPConfig::Default;
00131   ROPConfig::ROPConfig()
00132   {
00133     Blend = false;
00134     SrcBlend = GL_SRC_ALPHA;
00135     DstBlend = GL_ONE_MINUS_SRC_ALPHA;
00136   }
00137   ROPConfig::~ROPConfig()
00138   {
00139   }
00140 
00141 
00142   FxStructure::FxStructure()
00143   {
00144     src_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8);
00145     dst_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8);
00146     temp_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture(1, 1, 1, nux::BITFMT_R8G8B8A8);
00147   }
00148 
00149   FxStructure::~FxStructure()
00150   {
00151   }
00152 
00153   GraphicsEngine::GraphicsEngine (GraphicsDisplay &GlWindow, bool create_rendering_data)
00154     :   _graphics_display (GlWindow)
00155   {
00156     _scissor.x = 0;
00157     _scissor.y = 0;
00158     _clip_offset_x = 0;
00159     _clip_offset_y = 0;
00160 
00161     _font_renderer = 0;
00162 
00163     _use_glsl_shaders = false;
00164     _global_clipping_enabled = false;
00165 
00166     // Evaluate the features provided by the GPU.
00167     EvaluateGpuCaps ();
00168 
00169     GlWindow.m_GraphicsContext = this;
00170     ResetStats();
00171 
00172     _projection_matrix.Identity();
00173     _model_view_matrix.Identity();
00174 
00175     ResourceCache.InitializeResourceFactories();
00176 
00177     m_CurrrentContext.x = 0;
00178     m_CurrrentContext.y = 0;
00179     m_CurrrentContext.width = _graphics_display.GetWindowWidth();
00180     m_CurrrentContext.height = _graphics_display.GetWindowHeight();
00181 
00182     SetViewport (0, 0, _graphics_display.GetWindowWidth(), _graphics_display.GetWindowHeight() );
00183     SetScissor (0, 0, _graphics_display.GetWindowWidth(), _graphics_display.GetWindowHeight() );
00184     EnableScissoring (true);
00185 
00186 
00187     bool opengl_14_support = true;
00188 
00189     if ((_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion () == 1) &&
00190       (_graphics_display.GetGpuDevice()->GetOpenGLMinorVersion () < 4))
00191     {
00192       // OpenGL version is less than OpenGL 1.4
00193       opengl_14_support = false;
00194     }
00195 
00196     if (create_rendering_data)
00197     {
00198 #ifndef NUX_OPENGLES_20
00199       if (UsingGLSLCodePath () &&
00200         _graphics_display.GetGpuDevice()->GetGpuInfo ().Support_ARB_Fragment_Shader () &&
00201         _graphics_display.GetGpuDevice()->GetGpuInfo ().Support_ARB_Vertex_Shader () &&
00202         opengl_14_support)
00203       {
00204         InitSlColorShader ();
00205         InitSlTextureShader ();
00206         InitSlPixelateShader ();
00207         InitSlColorModTexMaskAlpha ();
00208         InitSl2TextureAdd ();
00209         InitSl2TextureMod ();
00210         InitSl4TextureAdd ();
00211 
00212         InitSLPower ();
00213         InitSLAlphaReplicate ();
00214         InitSLHorizontalGaussFilter ();
00215         InitSLVerticalGaussFilter ();
00216         InitSLColorMatrixFilter ();
00217 
00218         InitSl2TextureDepRead ();
00219 
00220         InitSLHorizontalHQGaussFilter (1);
00221         InitSLVerticalHQGaussFilter (1);
00222       }
00223       else if (_graphics_display.GetGpuDevice()->GetGpuInfo ().Support_ARB_Fragment_Shader () &&
00224         _graphics_display.GetGpuDevice()->GetGpuInfo ().Support_ARB_Vertex_Program () &&
00225         opengl_14_support)
00226       {
00227         InitAsmColorShader ();
00228         InitAsmTextureShader ();
00229         InitAsmPixelateShader ();
00230         InitAsmColorModTexMaskAlpha ();
00231         InitAsm2TextureAdd ();
00232         InitAsm2TextureMod ();
00233         InitAsm4TextureAdd ();
00234         InitAsmBlendModes ();
00235 
00236         InitAsmPower ();
00237         InitAsmAlphaReplicate ();
00238         InitAsmSeparableGaussFilter ();
00239         InitAsmColorMatrixFilter ();
00240 
00241         //InitAsm2TextureDepRead (); // NUXTODO: fix the shader
00242       }
00243 #else
00244       InitSlColorShader ();
00245       InitSlTextureShader ();
00246       InitSlPixelateShader ();
00247       InitSlColorModTexMaskAlpha ();
00248       InitSl2TextureAdd ();
00249       InitSl2TextureMod ();
00250       InitSl4TextureAdd ();
00251 
00252       InitSLPower ();
00253       InitSLAlphaReplicate ();
00254       InitSLHorizontalGaussFilter ();
00255       InitSLVerticalGaussFilter ();
00256       InitSLColorMatrixFilter ();
00257 #endif
00258 
00259 #if defined (NUX_OS_WINDOWS)
00260       if (_normal_font.IsNull())
00261       {
00262         FontTexture* fnt = new FontTexture (GNuxGraphicsResources.FindResourceLocation (TEXT ("Fonts/Tahoma_size_8.txt"), true).GetTCharPtr(), NUX_TRACKER_LOCATION);
00263         _normal_font = ObjectPtr<FontTexture> (fnt);
00264         fnt->UnReference ();
00265       }
00266 
00267       if (_bold_font.IsNull())
00268       {
00269         FontTexture* fnt = new FontTexture (GNuxGraphicsResources.FindResourceLocation (TEXT ("Fonts/Tahoma_size_8_bold.txt"), true).GetTCharPtr(), NUX_TRACKER_LOCATION);
00270         _bold_font = ObjectPtr<FontTexture> (fnt);
00271         fnt->UnReference ();
00272       }
00273 #else
00274       if (_normal_font.IsNull())
00275       {
00276         FontTexture* fnt = new FontTexture (GNuxGraphicsResources.FindResourceLocation (TEXT ("Fonts/Ubuntu_size_10.txt"), true).GetTCharPtr(), NUX_TRACKER_LOCATION);
00277         _normal_font = ObjectPtr<FontTexture> (fnt);
00278         fnt->UnReference ();
00279       }
00280 
00281       if (_bold_font.IsNull())
00282       {
00283         FontTexture* fnt = new FontTexture (GNuxGraphicsResources.FindResourceLocation (TEXT ("Fonts/Ubuntu_size_10_bold.txt"), true).GetTCharPtr(), NUX_TRACKER_LOCATION);
00284         _bold_font = ObjectPtr<FontTexture> (fnt);
00285         fnt->UnReference ();
00286       }
00287 #endif
00288 
00289       GpuInfo& gpu_info = _graphics_display.GetGpuDevice ()->GetGpuInfo ();
00290 
00291       if ((gpu_info.Support_ARB_Vertex_Program () && gpu_info.Support_ARB_Fragment_Program ())
00292           || (gpu_info.Support_ARB_Vertex_Shader () && gpu_info.Support_ARB_Fragment_Shader ()))
00293       {
00294         _font_renderer = new FontRenderer (*this);
00295       }
00296 
00297       if (gpu_info.Support_EXT_Framebuffer_Object ())
00298         _offscreen_fbo = _graphics_display.GetGpuDevice()->CreateFrameBufferObject ();
00299 
00300       _offscreen_color_rt0  = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8);
00301       _offscreen_color_rt1  = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8);
00302       _offscreen_color_rt2  = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8);
00303       _offscreen_color_rt3  = _graphics_display.GetGpuDevice()->CreateTexture(2, 2, 1, BITFMT_R8G8B8A8);
00304     }
00305   }
00306 
00307   GraphicsEngine::~GraphicsEngine()
00308   {
00309     _offscreen_color_rt0.Release ();
00310     _offscreen_color_rt1.Release ();
00311     _offscreen_depth_rt0.Release ();
00312     _offscreen_depth_rt1.Release ();
00313     _offscreen_fbo.Release ();
00314 
00315     ResourceCache.Flush();
00316     NUX_SAFE_DELETE (_font_renderer);
00317   }
00318 
00319   void GraphicsEngine::EvaluateGpuCaps ()
00320   {
00321 #ifdef NUX_OS_WINDOWS
00322     if (_graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Vertex_Shader() &&
00323       _graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Fragment_Shader())
00324 #else
00325     if (_graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Vertex_Shader() &&
00326       _graphics_display.GetGpuDevice()->GetGpuInfo().Support_ARB_Fragment_Shader() &&
00327       (_graphics_display.GetGpuDevice()->GetOpenGLMajorVersion() >= 2))
00328 #endif
00329     {
00330       NString renderer_string = ANSI_TO_TCHAR (NUX_REINTERPRET_CAST (const char *, glGetString (GL_RENDERER)));
00331       CHECKGL_MSG (glGetString (GL_RENDERER));
00332 
00333       // Exclude Geforce FX from using GLSL
00334       if (renderer_string.FindFirstOccurence (TEXT ("GeForce FX")) != tstring::npos)
00335       {
00336         _use_glsl_shaders = false;
00337         return;
00338       }
00339 
00340       // Exclude Geforce FX Go from using GLSL: this case is not needed since it is detected by the one above.
00341       if (renderer_string.FindFirstOccurence (TEXT ("GeForce FX Go")) != tstring::npos)
00342       {
00343         _use_glsl_shaders = false;
00344         return;
00345       }
00346 
00347       _use_glsl_shaders = true;
00348     }
00349     else
00350     {
00351       _use_glsl_shaders = false;
00352     }
00353   }
00354 
00355   bool GraphicsEngine::UsingGLSLCodePath ()
00356   {
00357     return _use_glsl_shaders;
00358   }
00359 
00360   bool GraphicsEngine::UsingARBProgramCodePath ()
00361   {
00362     return !_use_glsl_shaders;
00363   }
00364 
00365   ObjectPtr<FontTexture> GraphicsEngine::GetFont()
00366   {
00367     return _normal_font;
00368   }
00369 
00370   ObjectPtr<FontTexture> GraphicsEngine::GetBoldFont()
00371   {
00372     return _bold_font;
00373   }
00374 
00375   void GraphicsEngine::SetContext (int x, int y, int width, int height)
00376   {
00377     m_CurrrentContext.x = x;
00378     m_CurrrentContext.y = y;
00379 
00380     if (width <= 0 || height <= 0)
00381     {
00382       //nuxAssertMsg(0, TEXT("[GraphicsEngine::SetContext] Incorrect context size.") );
00383       if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid() )
00384       {
00385         m_CurrrentContext.width = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetWidth();
00386         m_CurrrentContext.height = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetHeight();
00387       }
00388       else
00389       {
00390         m_CurrrentContext.width = GetWindowWidth();
00391         m_CurrrentContext.height = GetWindowHeight();
00392       }
00393     }
00394     else
00395     {
00396       m_CurrrentContext.width = width;
00397       m_CurrrentContext.height = height;
00398     }
00399   }
00400 
00401   void GraphicsEngine::GetContextSize (int &w, int &h) const
00402   {
00403     w = m_CurrrentContext.width;
00404     h = m_CurrrentContext.height;
00405   }
00406 
00407   int GraphicsEngine::GetContextWidth() const
00408   {
00409     return m_CurrrentContext.width;
00410   }
00411 
00412   int GraphicsEngine::GetContextHeight() const
00413   {
00414     return m_CurrrentContext.height;
00415   }
00416 
00417   int GraphicsEngine::GetContextX() const
00418   {
00419     return m_CurrrentContext.x;
00420   }
00421 
00422   int GraphicsEngine::GetContextY() const
00423   {
00424     return m_CurrrentContext.y;
00425   }
00426 
00427   void GraphicsEngine::GetWindowSize (int &w, int &h) const
00428   {
00429     _graphics_display.GetWindowSize (w, h);
00430   }
00431 
00432   int GraphicsEngine::GetWindowWidth() const
00433   {
00434     return _graphics_display.GetWindowWidth();
00435   }
00436 
00437   int GraphicsEngine::GetWindowHeight() const
00438   {
00439     return _graphics_display.GetWindowHeight();
00440   }
00441 
00442   int GraphicsEngine::RenderColorText (ObjectPtr<FontTexture> Font, int x, int y, const NString &Str,
00443                                         const Color &TextColor,
00444                                         bool WriteAlphaChannel,
00445                                         int NumCharacter)
00446   {
00447     if (_font_renderer)
00448       return _font_renderer->RenderColorText (Font, x, y, Str, TextColor, WriteAlphaChannel, NumCharacter);
00449 
00450     return 0;
00451   }
00452 
00453   int GraphicsEngine::RenderColorTextLineStatic (ObjectPtr<FontTexture> Font, const PageBBox &pageSize, const NString &Str,
00454       const Color &TextColor,
00455       bool WriteAlphaChannel,
00456       TextAlignment alignment)
00457   {
00458     if (_font_renderer)
00459       return _font_renderer->RenderColorTextLineStatic (Font, pageSize, Str, TextColor, WriteAlphaChannel, alignment);
00460 
00461     return 0;
00462   }
00463 
00464   int GraphicsEngine::RenderColorTextLineEdit (ObjectPtr<FontTexture> Font, const PageBBox &pageSize, const NString &Str,
00465       const Color &TextColor,
00466       bool WriteAlphaChannel,
00467       const Color &SelectedTextColor,
00468       const Color &SelectedTextBackgroundColor,
00469       const Color &TextBlinkColor,
00470       const Color &CursorColor,
00471       bool ShowCursor, unsigned int CursorPosition, int offset, int selection_start, int selection_end)
00472   {
00473     if (_font_renderer)
00474       return _font_renderer->RenderColorTextLineEdit (Font, pageSize, Str,
00475              TextColor,
00476              WriteAlphaChannel,
00477              SelectedTextColor,
00478              SelectedTextBackgroundColor,
00479              TextBlinkColor,
00480              CursorColor,
00481              ShowCursor, CursorPosition, offset, selection_start, selection_end);
00482 
00483     return 0;
00484   }
00485 
00486   void GraphicsEngine::SetTexture (int TextureUnit, BaseTexture *Texture)
00487   {
00488     nuxAssertMsg (Texture != 0, TEXT ("[GraphicsEngine::SetTexture] Texture is NULL.") );
00489 
00490     if ( (TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31) )
00491       return;
00492 
00493     ObjectPtr <CachedBaseTexture> CachedTexture = ResourceCache.GetCachedResource (Texture);
00494     SetTexture (TextureUnit, CachedTexture->m_Texture);
00495   }
00496 
00497   void GraphicsEngine::SetTexture (int TextureUnit, ObjectPtr< IOpenGLBaseTexture > DeviceTexture)
00498   {
00499     NUX_RETURN_IF_FALSE (DeviceTexture.IsValid() );
00500 
00501     CHECKGL ( glActiveTextureARB (TextureUnit) );
00502     DeviceTexture->BindTextureToUnit (TextureUnit);
00503   }
00504 
00505   void GraphicsEngine::EnableTextureMode (int TextureUnit, int TextureMode)
00506   {
00507     if ( (TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31) )
00508       return;
00509 
00510     CHECKGL ( glActiveTextureARB (TextureUnit) );
00511     CHECKGL ( glEnable (TextureMode) );
00512   }
00513 
00514   void GraphicsEngine::DisableTextureMode (int TextureUnit, int TextureMode)
00515   {
00516     if ( (TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31) )
00517       return;
00518 
00519     CHECKGL ( glActiveTextureARB (TextureUnit) );
00520     CHECKGL ( glDisable (TextureMode) );
00521     CHECKGL ( glBindTexture (TextureMode, 0) );
00522   }
00523 
00524   void GraphicsEngine::DisableAllTextureMode (int TextureUnit)
00525   {
00526     if ((TextureUnit < GL_TEXTURE0) || (TextureUnit > GL_TEXTURE31))
00527       return;
00528 
00529     _graphics_display.GetGpuDevice()->InvalidateTextureUnit(TextureUnit);
00530   }
00531 
00533 // DRAW CLIPPING    //
00535   void GraphicsEngine::PushClippingRectangle(Rect rect)
00536   {
00537     if(_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
00538     {
00539       // There is an active framebuffer set. Push the clipping rectangles to that fbo clipping stack.
00540       _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->PushClippingRegion (rect);
00541       return;
00542     }
00543 
00544     Rect r0 = ModelViewXFormRect(rect);
00545 
00546     Rect r1;
00547     unsigned int stacksize = (unsigned int) ClippingRect.size();
00548     int x0, y0, x1, y1;
00549 
00550     int window_width, window_height;
00551     window_width = _viewport.width;
00552     window_height = _viewport.height;
00553 
00554     if (stacksize == 0)
00555     {
00556       r1 = Rect (0, 0, window_width, window_height);
00557     }
00558     else
00559     {
00560       r1 = ClippingRect[stacksize-1];
00561     }
00562 
00563 //    http://www.codecomments.com/archive263-2004-12-350347.html
00564 //    If your rectangles are given in 2D as Top,Left,Bottom,Right coordinates, as typical for GUI programming, then it's simply:
00565 //        intersect.Left = max(a.Left, b.Left);
00566 //        intersect.Top = max(a.Top, b.Top);
00567 //        intersect.Right = min(a.Right, b.Right );
00568 //        intersect.Bottom = min(a.Bottom, b.Bottom);
00569 //    And the intersection is empty unless intersect.Right > intersect.Left && intersect.Bottom > intersect.Top
00570 
00571     x0 = Max (r0.x, r1.x);
00572     y0 = Max (r0.y, r1.y);
00573     x1 = Min (r0.x + r0.width, r1.x + r1.width);
00574     y1 = Min (r0.y + r0.height, r1.y + r1.height);
00575 
00576     Rect r = r0.Intersect (r1);
00577 
00578     if ( (x1 > x0) && (y1 > y0) )
00579     {
00580       _clipping_rect = Rect (x0, y0, x1 - x0, y1 - y0);
00581       ClippingRect.push_back (Rect (x0, y0, x1 - x0, y1 - y0) );
00582 
00583       EnableScissoring (true);
00584       SetOpenGLClippingRectangle (x0, window_height - y0 - (y1 - y0), x1 - x0, y1 - y0);
00585     }
00586     else
00587     {
00588       _clipping_rect = Rect (0, 0, 0, 0);
00589       ClippingRect.push_back (_clipping_rect);
00590       EnableScissoring (true);
00591       SetOpenGLClippingRectangle (0, 0, 0, 0);
00592     }
00593   }
00594 
00595   void GraphicsEngine::PopClippingRectangle()
00596   {
00597     if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid() )
00598     {
00599       _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->PopClippingRegion();
00600       return;
00601     }
00602 
00603     ClippingRect.pop_back();
00604     unsigned int stacksize = (unsigned int) ClippingRect.size();
00605 
00606     if (stacksize == 0)
00607     {
00608       _clipping_rect = Rect (0, 0, _viewport.width, _viewport.height);
00609       EnableScissoring (true);
00610       SetOpenGLClippingRectangle (0, 0, _viewport.width, _viewport.height);
00611     }
00612     else
00613     {
00614       _clipping_rect = ClippingRect [stacksize-1];
00615       Rect B = _clipping_rect;
00616       EnableScissoring (true);
00617       SetOpenGLClippingRectangle (B.x, _viewport.height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight() );
00618     }
00619   }
00620 
00621   void GraphicsEngine::ApplyClippingRectangle ()
00622   {
00623     if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid() )
00624     {
00625       _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->ApplyClippingRegion();
00626       return;
00627     }
00628 
00629     unsigned int stacksize = (unsigned int) ClippingRect.size();
00630 
00631     if (stacksize == 0)
00632     {
00633       _clipping_rect = Rect (0, 0, _viewport.width, _viewport.height);
00634       EnableScissoring (true);
00635       SetOpenGLClippingRectangle (0, 0, _viewport.width, _viewport.height);
00636     }
00637     else
00638     {
00639       _clipping_rect = ClippingRect[stacksize-1];
00640       Rect B = _clipping_rect;
00641       EnableScissoring (true);
00642       SetOpenGLClippingRectangle (B.x, _viewport.height - B.y - B.GetHeight(), B.GetWidth(), B.GetHeight() );
00643     }
00644   }
00645 
00646   void GraphicsEngine::EmptyClippingRegion ()
00647   {
00648     if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
00649     {
00650       _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->EmptyClippingRegion ();
00651       return;
00652     }
00653 
00654     ClippingRect.clear();
00655     {
00656       _clipping_rect = Rect (0, 0, _viewport.width, _viewport.height);
00657       EnableScissoring (true);
00658       SetOpenGLClippingRectangle (0, 0, _viewport.width, _viewport.height);
00659     }
00660   }
00661   
00662   void GraphicsEngine::SetGlobalClippingRectangle (Rect rect)
00663   {
00664     _global_clipping_enabled = true;
00665     _global_clipping_rect = Rect (rect.x, _viewport.height - rect.y - rect.height, rect.width, rect.height);
00666     ApplyClippingRectangle ();
00667   }
00668   
00669   void GraphicsEngine::DisableGlobalClippingRectangle ()
00670   {
00671     _global_clipping_enabled = false;
00672     _global_clipping_rect = Rect (0, 0, _viewport.width, _viewport.height);
00673     ApplyClippingRectangle ();
00674   }
00675 
00676   Rect GraphicsEngine::GetClippingRegion () const
00677   {
00678     if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
00679     {
00680       Rect r = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetClippingRegion ();
00681       return r;      
00682     }
00683 
00684     return _clipping_rect;
00685 
00686 //     unsigned int stacksize = (unsigned int) ClippingRect.size();
00687 // 
00688 //     if (stacksize == 0)
00689 //     {
00690 //       return Rect (0, 0, _viewport.width, _viewport.height);
00691 //     }
00692 //     else
00693 //     {
00694 //       Rect r = ClippingRect[stacksize-1];
00695 //       return r;
00696 //     }
00697   }
00698 
00699   void GraphicsEngine::SetClippingRectangle (const Rect &rect)
00700   {
00701     _clipping_rect = rect;
00702     SetOpenGLClippingRectangle (rect.x, _viewport.height - rect.y - rect.height, rect.width, rect.height);
00703   }
00704 
00705   void GraphicsEngine::SetOpenGLClippingRectangle (int x, int y, unsigned int width, unsigned int height)
00706   {
00707     if (!_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
00708     {
00709       if (_global_clipping_enabled)
00710       {
00711         Rect intersection = Rect (x, y, width, height).Intersect (_global_clipping_rect);
00712         SetScissor (intersection.x, intersection.y, intersection.width, intersection.height);
00713       }
00714       else
00715       {
00716         SetScissor (x, y, width, height);
00717       }
00718     }
00719     else
00720     {
00721       SetScissor (x, y, width, height);
00722     }
00723   }
00724 
00725   int GraphicsEngine::GetNumberOfClippingRegions () const
00726   {
00727     if (_graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject().IsValid())
00728     {
00729       int n = _graphics_display.m_DeviceFactory->GetCurrentFrameBufferObject()->GetNumberOfClippingRegions ();
00730       return n;
00731     }
00732 
00733     return (int) ClippingRect.size();
00734   }
00735 
00736   void GraphicsEngine::AddClipOffset (int x, int y)
00737   {
00738     PushClipOffset (x, y);
00739   }
00740 
00741   void GraphicsEngine::PushClipOffset (int x, int y)
00742   {
00743     _clip_offset_stack.push_back (Point (x, y));
00744 
00745     _clip_offset_x = 0;
00746     _clip_offset_y = 0;
00747 
00748     std::list<Point>::iterator it;
00749     for (it = _clip_offset_stack.begin (); it != _clip_offset_stack.end (); it++)
00750     {
00751       _clip_offset_x += (*it).x;
00752       _clip_offset_y += (*it).y;
00753     }
00754   }
00755 
00756   void GraphicsEngine::PopClipOffset ()
00757   {
00758     if (_clip_offset_stack.size () == 0)
00759     {
00760       _clip_offset_x = 0;
00761       _clip_offset_y = 0;
00762     }
00763 
00764     _clip_offset_stack.pop_back();
00765 
00766     _clip_offset_x = 0;
00767     _clip_offset_y = 0;
00768 
00769     std::list<Point>::iterator it;
00770     for (it = _clip_offset_stack.begin (); it != _clip_offset_stack.end (); it++)
00771     {
00772       _clip_offset_x += (*it).x;
00773       _clip_offset_y += (*it).y;
00774     }
00775   }
00776 
00778 // DRAW TEXTURE  //
00780 
00782 // Rendering calls
00783 
00784 //
00785 //    From "OpenGL Programming Guide.pdf"
00786 //
00787 //    If exact two-dimensional rasterization is desired, you must carefully specify both the orthographic
00788 //    projection and the vertices of primitives that are to be rasterized. The orthographic projection
00789 //    should be specified with integer coordinates, as shown in the following example:
00790 //    gluOrtho2D(0, width, 0, height);
00791 //    where width and height are the dimensions of the viewport. Given this projection matrix, polygon
00792 //    vertices and pixel image positions should be placed at integer coordinates to rasterize predictably.
00793 //    For example, glRecti(0, 0, 1, 1) reliably fills the lower left pixel of the viewport, and glRasterPos2i(0,
00794 //    0) reliably positions an unzoomed image at the lower left of the viewport. Point vertices, line
00795 //    vertices, and bitmap positions should be placed at half-integer locations, however. For example, a
00796 //    line drawn from (x1, 0.5) to (x2, 0.5) will be reliably rendered along the bottom row of pixels int the
00797 //    viewport, and a point drawn at (0.5, 0.5) will reliably fill the same pixel as glRecti(0, 0, 1, 1).
00798 //    An optimum compromise that allows all primitives to be specified at integer positions, while still
00799 //    ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code
00800 //    fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of
00801 //    pixels, while moving line vertices close enough to the pixel centers.
00802 //    glViewport(0, 0, width, height);
00803 //    glMatrixMode(GL_PROJECTION);
00804 //    glLoadIdentity();
00805 //    gluOrtho2D(0, width, 0, height);
00806 //    glMatrixMode(GL_MODELVIEW);
00807 //    glLoadIdentity();
00808 //    glTranslatef(0.375, 0.375, 0.0);
00809   /* render all primitives at integer positions */
00810 
00811   const float RASTERIZATION_OFFSET = 0.375f;
00812   void GraphicsEngine::Push2DWindow (int w, int h)
00813   {
00814 #ifndef NUX_OPENGLES_20
00815     {
00816       _model_view_matrix.Translate (m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
00817       Matrix4 temp;
00818       std::list<Matrix4>::iterator it;
00819 
00820       for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
00821       {
00822         temp = _model_view_matrix;
00823         _model_view_matrix = temp * (*it);
00824       }
00825 
00826     }
00827 
00828     {
00829       _projection_matrix.Orthographic (0, w, h, 0, -1.0f, 1.0f);
00830     }
00831 #else
00832     // ModelView
00833     {
00834       _model_view_matrix.Translate (m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
00835       Matrix4 temp;
00836       std::list<Matrix4>::iterator it;
00837 
00838       for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
00839       {
00840         temp = _model_view_matrix;
00841         _model_view_matrix = temp * (*it);
00842       }
00843 
00844     }
00845 
00846     // Projection
00847     {
00848       _projection_matrix.Orthographic (0, w, h, 0, -1.0f, 1.0f);
00849     }
00850 #endif
00851   }
00852 
00853   void GraphicsEngine::Pop2DWindow()
00854   {
00855 #ifndef NUX_OPENGLES_20
00856     CHECKGL ( glMatrixMode (GL_PROJECTION) );
00857     CHECKGL ( glLoadIdentity() );
00858     CHECKGL ( glMatrixMode (GL_MODELVIEW) );
00859     CHECKGL ( glLoadIdentity() );
00860     CHECKGL ( glFrustum (
00861                 -1.0,     // left
00862                 1.0,      // right
00863                 -1.0,     // bottom
00864                 1.0,      // top
00865                 0.1,    // near,
00866                 2000.0  // far
00867               ) );
00868 #endif
00869   }
00870 
00871   void GraphicsEngine::Push2DModelViewMatrix (Matrix4 mat)
00872   {
00873     m_2DModelViewMatricesStack.push_back (mat);
00874     {
00875       _model_view_matrix.Translate (m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
00876       Matrix4 temp;
00877       std::list<Matrix4>::iterator it;
00878 
00879       for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
00880       {
00881         temp = _model_view_matrix;
00882         _model_view_matrix = (*it) * temp;
00883       }
00884 
00885     }
00886   }
00887 
00888   Matrix4 GraphicsEngine::Pop2DModelViewMatrix()
00889   {
00890     Matrix4 Mat;
00891     Mat.Zero();
00892 
00893     if (m_2DModelViewMatricesStack.size() <= 0)
00894       return Mat;
00895 
00896     std::list<Matrix4>::iterator it;
00897     it = m_2DModelViewMatricesStack.end();
00898     --it;
00899     Mat = (*it);
00900     m_2DModelViewMatricesStack.pop_back();
00901 
00902     {
00903       _model_view_matrix.Translate (m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
00904       Matrix4 temp;
00905       std::list<Matrix4>::iterator it;
00906 
00907       for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
00908       {
00909         temp = _model_view_matrix;
00910         _model_view_matrix = temp * (*it);
00911       }
00912     }
00913     return Mat;
00914   }
00915 
00916   void GraphicsEngine::Clear2DModelViewMatrix()
00917   {
00918     m_2DModelViewMatricesStack.clear();
00919 
00920     {
00921       _model_view_matrix.Translate (m_CurrrentContext.x + RASTERIZATION_OFFSET, m_CurrrentContext.y + RASTERIZATION_OFFSET, 0);
00922       Matrix4 temp;
00923       std::list<Matrix4>::iterator it;
00924 
00925       for (it = m_2DModelViewMatricesStack.begin(); it != m_2DModelViewMatricesStack.end(); it++)
00926       {
00927         temp = _model_view_matrix;
00928         _model_view_matrix = temp * (*it);
00929       }
00930     }
00931   }
00932 
00933   void GraphicsEngine::PushIdentityModelViewMatrix ()
00934   {
00935     PushModelViewMatrix (Matrix4::IDENTITY());
00936   }
00937 
00938   void GraphicsEngine::PushModelViewMatrix (const Matrix4 &matrix)
00939   {
00940     if (_model_view_stack.empty())
00941       _model_view_matrix = matrix;
00942     else
00943       _model_view_matrix = matrix * _model_view_stack.back();
00944 
00945     _model_view_stack.push_back (_model_view_matrix);
00946   }
00947 
00948   void GraphicsEngine::Push2DTranslationModelViewMatrix (float tx, float ty, float tz)
00949   {
00950     Matrix4 temp;
00951     temp.Translate (tx, ty, tz);
00952 
00953     PushModelViewMatrix (temp);
00954   }
00955 
00956   bool GraphicsEngine::PopModelViewMatrix ()
00957   {
00958     if (!_model_view_stack.empty())
00959       _model_view_stack.pop_back();
00960 
00961     if (_model_view_stack.empty())
00962     {
00963       _model_view_matrix = Matrix4::IDENTITY ();
00964       return false;
00965     }
00966 
00967     _model_view_matrix = _model_view_stack.back();
00968 
00969     return true;
00970   }
00971 
00972   void GraphicsEngine::ResetModelViewMatrixStack ()
00973   {
00974     _model_view_stack.clear ();
00975     _model_view_matrix = Matrix4::IDENTITY ();
00976   }
00977 
00978   void GraphicsEngine::SetModelViewMatrix (const Matrix4 &matrix)
00979   {
00980     _model_view_matrix = matrix;
00981   }
00982 
00983   void GraphicsEngine::ApplyModelViewMatrix ()
00984   {
00985     if (_model_view_stack.empty())
00986       _model_view_matrix = Matrix4::IDENTITY ();
00987     else
00988       _model_view_matrix = _model_view_stack.back();
00989   }
00990 
00991   Rect GraphicsEngine::ModelViewXFormRect (const Rect& rect)
00992   {
00993     Vector4 v0 (rect.x, rect.y, 0.0f, 1.0f);
00994     Vector4 v1 = _model_view_matrix * v0;
00995     Rect r (v1.x, v1.y, rect.width, rect.height);
00996     return r;
00997   }
00998 
00999   int GraphicsEngine::ModelViewStackDepth ()
01000   {
01001     return (int)_model_view_stack.size ();
01002   }
01003 
01004   void GraphicsEngine::PushPorterDuffBlend (const PorterDuffOperator &porter_duff_op)
01005   {
01006     BlendOperator blend_op;
01007     blend_op.SetPorterDuffOperator (porter_duff_op);
01008 
01009     _blend_stack.push_front (blend_op);
01010 
01011     GetRenderStates ().SetBlend (blend_op._enable, blend_op._src_blend, blend_op._dst_blend);
01012   }
01013 
01014   void GraphicsEngine::PushDisableBlend ()
01015   {
01016     BlendOperator blend_op;
01017     blend_op.EnableBlending (false);
01018 
01019     _blend_stack.push_front (blend_op);
01020 
01021     GetRenderStates ().SetBlend (blend_op._enable);
01022   }
01023 
01024   bool GraphicsEngine::PopBlend ()
01025   {
01026     if (_blend_stack.size () == 0)
01027     {
01028       GetRenderStates ().SetBlend (false, GL_ONE, GL_ZERO);
01029       return false;
01030     }
01031 
01032     _blend_stack.pop_front ();
01033     
01034     BlendOperator blend_op = (*_blend_stack.begin ());
01035     GetRenderStates ().SetBlend (blend_op._enable, blend_op._src_blend, blend_op._dst_blend);
01036 
01037     return true;
01038   }
01039 
01040   int GraphicsEngine::BlendStackDepth ()
01041   {
01042     return (int) _blend_stack.size ();
01043   }
01044 
01045   Matrix4 GraphicsEngine::GetProjectionMatrix ()
01046   {
01047     return _projection_matrix;
01048   }
01049 
01050   Matrix4 GraphicsEngine::GetOpenGLProjectionMatrix ()
01051   {
01052     Matrix4 mat = GetProjectionMatrix ();
01053     mat.Transpose ();
01054     return mat;
01055   }
01056 
01057   void GraphicsEngine::SetProjectionMatrix (const Matrix4 &matrix)
01058   {
01059     _projection_matrix = matrix;
01060   }
01061 
01062   void GraphicsEngine::SetOrthographicProjectionMatrix (int viewport_width, int viewport_height)
01063   {
01064     _projection_matrix.Orthographic (0, viewport_width, viewport_height, 0, -1.0f, 1.0f);
01065   }
01066 
01067   void GraphicsEngine::ResetProjectionMatrix ()
01068   {
01069     _projection_matrix = Matrix4::IDENTITY ();
01070   }
01071 
01072   Matrix4 GraphicsEngine::GetModelViewMatrix ()
01073   {
01074     return _model_view_matrix;
01075   }
01076 
01077   Matrix4 GraphicsEngine::GetOpenGLModelViewMatrix ()
01078   {
01079     Matrix4 mat = _model_view_matrix;
01080     mat.Transpose ();
01081     return mat;
01082   }
01083 
01084   Matrix4 GraphicsEngine::GetModelViewProjectionMatrix ()
01085   {
01086     return _projection_matrix * _model_view_matrix;
01087   }
01088 
01089   Matrix4 GraphicsEngine::GetOpenGLModelViewProjectionMatrix ()
01090   {
01091     // This matrix is the transposed version of GetModelViewProjectionMatrix.
01092     Matrix4 mat = _projection_matrix * _model_view_matrix;
01093     mat.Transpose();
01094     return mat;
01095   }
01096 
01097   void GraphicsEngine::SetViewport (int origin_x, int origin_y, int w, int h)
01098   {
01099     nuxAssert (w >= 0);
01100     nuxAssert (h >= 0);
01101 
01102     _viewport.x = origin_x;
01103     _viewport.y = origin_y;
01104     _viewport.width = w;
01105     _viewport.height = h;
01106 
01107     if (_viewport.width < 0)
01108     {
01109       nuxAssertMsg (0, TEXT ("[GraphicsEngine::SetViewport] Incorrect context size.") );
01110       _viewport.width = 1;
01111     }
01112 
01113     if (_viewport.height < 0)
01114     {
01115       nuxAssertMsg (0, TEXT ("[GraphicsEngine::SetViewport] Incorrect context size.") );
01116       _viewport.height = 1;
01117     }
01118 
01119     CHECKGL ( glViewport (origin_x, origin_y, _viewport.width, _viewport.height) );
01120   }
01121 
01122 //   Rect GraphicsEngine::GetViewportRect()
01123 //   {
01124 //     return Rect (_viewport.x, _viewport.y, _viewport.width, _viewport.height);
01125 //   }
01126   
01127   Rect GraphicsEngine::GetViewportRect () const
01128   {
01129     return _viewport;
01130   }
01131 
01132   int  GraphicsEngine::GetViewportWidth () const
01133   {
01134     return _viewport.width;
01135   }
01136 
01137   int  GraphicsEngine::GetViewportHeight () const
01138   {
01139     return _viewport.height;
01140   }
01141 
01142   int GraphicsEngine::GetViewportX () const
01143   {
01144     return _viewport.x;
01145   }
01146 
01147   int GraphicsEngine::GetViewportY () const
01148   {
01149     return _viewport.y;
01150   }
01151 
01152   void  GraphicsEngine::GetViewportSize (int &viewport_width, int &viewport_height) const
01153   {
01154     viewport_width = _viewport.width;
01155     viewport_height = _viewport.height;
01156   }
01157 
01158   void GraphicsEngine::SetScissorOffset (int x, int y)
01159   {
01160     nuxAssertMsg (0, TEXT("[GraphicsEngine::SetScissorOffset] SetScissorOffset is deprecated."));
01161 //     m_ScissorXOffset = x;
01162 //     m_ScissorYOffset = y;
01163   }
01164 
01165   void GraphicsEngine::SetScissor (int x, int y, int w, int h)
01166   {
01167     nuxAssert (w >= 0);
01168     nuxAssert (h >= 0);
01169 
01170     NUX_RETURN_IF_FALSE (w >= 0);
01171     NUX_RETURN_IF_FALSE (h >= 0);
01172 
01173     _scissor.x = x;
01174     _scissor.y = y;
01175     _scissor.width = w;
01176     _scissor.height = h;
01177 
01178     if (_scissor.x < 0)
01179     {
01180       _scissor.width += _scissor.x;
01181       _scissor.x = 0;
01182     }
01183     
01184     if (_scissor.y < 0)
01185     {
01186       _scissor.height += _scissor.y;
01187       _scissor.y = 0;
01188     }
01189 
01190     if (_scissor.width <= 0)
01191     {
01192       // jaytaoko: This is a hack for what looks like a bug (#726033) in the radeon opensource driver
01193       // on R300/400/500. Rather than passing a null region to glScissor, we give the clip area a 1 pixel width.
01194       //_scissor.width = 1;
01195       CHECKGL (glScissor (0, 0, 1, 1));
01196       return;
01197     }
01198 
01199     if (_scissor.height <= 0)
01200     {
01201       // jaytaoko: This is a hack for what looks like a bug (#726033) in the radeon opensource driver
01202       // on R300/400/500. Rather than passing a null region to glScissor, we give the clip area a 1 pixel height.
01203       //_scissor.height = 1;
01204       CHECKGL (glScissor (0, 0, 1, 1));
01205       return;
01206     }
01207 
01208     CHECKGL (glScissor (_scissor.x, _scissor.y, _scissor.width, _scissor.height));
01209   }
01210 
01211   Rect GraphicsEngine::GetScissorRect()
01212   {
01213     return Rect (_scissor.x, _scissor.y, _scissor.width, _scissor.height);
01214   }
01215 
01216   void GraphicsEngine::EnableScissoring (bool b)
01217   {
01218     GetRenderStates().EnableScissor (b);
01219   }
01220 
01222   // 2D Area Clear Color Depth Stencil   //
01224 
01225   void GraphicsEngine::ClearAreaColorDepthStencil (int x, int y, int width, int height, Color clear_color, float cleardepth, int clearstencil)
01226   {
01227     // enable stencil buffer
01228     CHECKGL ( glEnable (GL_STENCIL_TEST) );
01229     // write a one to the stencil buffer everywhere we are about to draw
01230     CHECKGL ( glStencilFunc (GL_ALWAYS, clearstencil, 0xFFFFFFFF) );
01231     // this is to always pass a one to the stencil buffer where we draw
01232     CHECKGL ( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) );
01233 
01234     //CHECKGL( glEnable(GL_DEPTH_TEST) );
01235     //CHECKGL( glDepthFunc(GL_ALWAYS) );
01236 
01237     QRP_Color(x, y, width, height, clear_color);
01238 
01239     //CHECKGL( glDepthFunc(GL_LESS) );
01240     //CHECKGL( glDisable(GL_DEPTH_TEST) );
01241     CHECKGL ( glDisable (GL_STENCIL_TEST) );
01242   }
01243 
01244   void GraphicsEngine::ClearAreaColor (int x, int y, int width, int height, Color clear_color)
01245   {
01246     QRP_Color(x, y, width, height, clear_color);
01247   }
01248 
01249   void GraphicsEngine::ClearAreaDepthStencil (int x, int y, int width, int height, float cleardepth, int clearstencil)
01250   {
01251     // enable stencil buffer
01252     CHECKGL (glEnable (GL_STENCIL_TEST));
01253     // write a one to the stencil buffer everywhere we are about to draw
01254     CHECKGL (glStencilFunc (GL_ALWAYS, clearstencil, 0xFFFFFFFF));
01255     // this is to always pass a one to the stencil buffer where we draw
01256     CHECKGL (glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE));
01257 
01258     CHECKGL (glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
01259     //CHECKGL (glEnable(GL_DEPTH_TEST));
01260     //CHECKGL (glDepthFunc(GL_ALWAYS));
01261 
01262     QRP_Color(x, y, width, height, color::Black);
01263 
01264     //CHECKGL( glDepthFunc(GL_LESS) );
01265     //CHECKGL( glDisable(GL_DEPTH_TEST) );
01266     CHECKGL (glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
01267     CHECKGL (glDisable (GL_STENCIL_TEST));
01268 
01269   }
01270 
01271 //Statistics
01272   void GraphicsEngine::ResetStats()
01273   {
01274     m_quad_stats            = 0;
01275     m_quad_tex_stats        = 0;
01276     m_triangle_stats        = 0;
01277     m_triangle_tex_stats    = 0;
01278     m_line_stats            = 0;
01279   }
01280 
01281   ObjectPtr< CachedResourceData > GraphicsEngine::CacheResource (ResourceData *Resource)
01282   {
01283     return ResourceCache.GetCachedResource (Resource);
01284   }
01285 
01286   bool GraphicsEngine::FlushCachedResourceData (ResourceData *Resource)
01287   {
01288     if (!IsResourceCached(Resource))
01289       return false;
01290 
01291     ResourceCache.FlushResourceId (Resource->GetResourceIndex());
01292     return true;
01293   }
01294 
01295   void GraphicsEngine::UpdateResource (ResourceData *Resource)
01296   {
01297     ObjectPtr< CachedResourceData > GLResource = ResourceCache.FindCachedResourceById (Resource->GetResourceIndex() ); //(CachedResourceData*)(*(ResourceCache.ResourceMap.find(Resource->ResourceIndex))).second;
01298 
01299     if (GLResource.IsValid() )
01300     {
01301       // Iterate through all resource updater types (list is sorted by subclass depth).
01302       for (t_u32 i = 0; i < ResourceCache.GetResourceUpdaters().size(); ++i)
01303       {
01304         NResourceUpdater *ResourceUpdater = ResourceCache.GetResourceUpdaters() [i];
01305         nuxAssert (ResourceUpdater);
01306 
01307         // Check if the updater is valid for updating the resource.
01308         if ( ResourceUpdater->UpdatesThisResource (Resource) )
01309         {
01310           ResourceUpdater->UpdateResource(GLResource, Resource);
01311           break;
01312         }
01313       }
01314     }
01315   }
01316 
01317   bool GraphicsEngine::IsResourceCached (ResourceData *Resource)
01318   {
01319     return ResourceCache.IsCachedResource (Resource);
01320   }
01321 
01322   void GraphicsEngine::SetFrameBufferHelper (
01323     ObjectPtr<IOpenGLFrameBufferObject>& fbo,
01324     ObjectPtr<IOpenGLBaseTexture>& colorbuffer,
01325     ObjectPtr<IOpenGLBaseTexture>& depthbuffer,
01326     int width, int height)
01327   {
01328     if ((colorbuffer.IsValid() == false) || (colorbuffer->GetWidth() != width) || (colorbuffer->GetHeight() != height))
01329     {
01330       colorbuffer = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, BITFMT_R8G8B8A8);
01331     }
01332 
01333     if ((depthbuffer.IsValid()) && ((depthbuffer->GetWidth() != width) || (depthbuffer->GetHeight() != height)))
01334     {
01335       // Generate a new depth texture only if a valid one was passed to this function.
01336       depthbuffer = _graphics_display.GetGpuDevice()->CreateTexture(width, height, 1, BITFMT_D24S8);
01337     }
01338 
01339     fbo->FormatFrameBufferObject(width, height, BITFMT_R8G8B8A8);
01340     fbo->SetRenderTarget(0, colorbuffer->GetSurfaceLevel(0));
01341     
01342     if (depthbuffer.IsValid())
01343       fbo->SetDepthSurface(depthbuffer->GetSurfaceLevel(0));
01344     else
01345       fbo->SetDepthSurface(ObjectPtr<IOpenGLSurface>(NULL));
01346 
01347     fbo->Activate();
01348     fbo->EmptyClippingRegion();
01349     SetContext(0, 0, width, height);
01350     SetViewport(0, 0, width, height);
01351     Push2DWindow(width, height);
01352   }
01353 
01354   void GraphicsEngine::GaussianWeights(float **weights, float sigma, unsigned int num_tap)
01355   {
01356     *weights = new float[num_tap];
01357     float sum = 0.0f;
01358     unsigned int i = 0;
01359 
01360     unsigned int half = (num_tap-1)/2;
01361 
01362     (*weights)[half] = (1.0f/(sqrt(2.0f*3.14159265358f)*sigma)) * exp(-0.0f/(2.0f*sigma*sigma));
01363     sum += (*weights)[half];
01364     for(i = 0; i < half; i++)
01365     {
01366       float X = (i + 1)*(i + 1);
01367       (*weights)[half - i - 1] = (*weights)[half + i + 1] = (1.0f/(sqrt(2.0f*3.14159265358f)*sigma)) * exp(-X/(2.0f*sigma*sigma));
01368       sum += 2.0f * ((*weights)[half - i - 1]);
01369     }
01370 
01371     /* normalization */
01372     for(i = 0; i < num_tap; i++)
01373     {
01374       (*weights)[i] = (*weights)[i] / sum;
01375     }
01376   }
01377 
01378   ObjectPtr <IOpenGLBaseTexture> GraphicsEngine::CreateTextureFromBackBuffer (int x, int y, int width, int height)
01379   {
01380     ObjectPtr<IOpenGLFrameBufferObject> fbo = _graphics_display.GetGpuDevice ()->GetCurrentFrameBufferObject ();
01381 
01382     int X, Y, W, H;
01383     if (fbo.IsValid())
01384     {
01385       int fbo_width = fbo->GetWidth ();
01386       int fbo_height = fbo->GetHeight ();
01387 
01388       X = Clamp<int> (x, 0, fbo_width);
01389       Y = Clamp<int> (y, 0, fbo_height);
01390       W = Min<int> (fbo_width - x, width);
01391       H = Min<int> (fbo_height - y, height);
01392 
01393 
01394       if ((W <= 0) || (H <= 0))
01395       {
01396         nuxAssertMsg (0, TEXT("[GraphicsEngine::CreateTextureFromBackBuffer] Invalid request."));
01397         return ObjectPtr<IOpenGLBaseTexture> (0);
01398       }
01399       
01400       // Inverse Y because of OpenGL upside-down nature
01401       Y = fbo_height - Y - H;
01402     }
01403     else
01404     {
01405       // There is no fbo. Reading directly from the back-buffer.
01406       int bb_width = _graphics_display.GetWindowWidth ();
01407       int bb_height = _graphics_display.GetWindowHeight ();
01408 
01409       X = Clamp<int> (x, 0, bb_width);
01410       Y = Clamp<int> (y, 0, bb_height);
01411       W = Min<int> (bb_width - x, width);
01412       H = Min<int> (bb_height - y, height);
01413 
01414       if ((W <= 0) || (H <= 0))
01415       {
01416         nuxAssertMsg (0, TEXT("[GraphicsEngine::CreateTextureFromBackBuffer] Invalid request."));
01417         return ObjectPtr<IOpenGLBaseTexture> (0);
01418       }
01419 
01420       // Inverse Y because of OpenGL upside-down nature
01421       Y = bb_height - Y - H;
01422     }
01423 
01424     ObjectPtr <IOpenGLBaseTexture> device_texture = _graphics_display.GetGpuDevice ()->CreateSystemCapableDeviceTexture (W, H, 1, BITFMT_R8G8B8A8);
01425     ObjectPtr <IOpenGLSurface> sfc = device_texture->GetSurfaceLevel (0);
01426 
01427     sfc->CopyRenderTarget (X, Y, W, H);
01428 
01429     return device_texture;
01430   }
01431 
01432 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends