nux-1.16.0
|
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 }