Back to index

unity  6.0.0
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Static Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
BackgroundEffectHelper Class Reference

#include <BackgroundEffectHelper.h>

Collaboration diagram for BackgroundEffectHelper:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 BackgroundEffectHelper ()
 ~BackgroundEffectHelper ()
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
GetBlurRegion (nux::Geometry geo, bool force_update=false)
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
GetPixelatedRegion (nux::Rect rect, int pixel_size, bool update)
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
GetRegion (nux::Geometry geo, bool force_update=false)
void DirtyCache ()

Static Public Member Functions

static void ProcessDamage (nux::Geometry geo)
static bool HasDirtyHelpers ()
static bool HasEnabledHelpers ()

Public Attributes

nux::Property< nux::View * > owner
nux::Property< bool > enabled
nux::FxStructure blur_fx_struct_
nux::FxStructure noise_fx_struct_

Static Public Attributes

static nux::Property
< unity::BlurType
blur_type
static nux::Property< float > sigma_high
static nux::Property< float > sigma_med
static nux::Property< float > sigma_low
static nux::Property< bool > updates_enabled
static nux::Property< bool > detecting_occlusions
static nux::Geometry monitor_rect_

Static Protected Member Functions

static void Register (BackgroundEffectHelper *self)
static void Unregister (BackgroundEffectHelper *self)

Private Member Functions

void OnEnabledChanged (bool value)

Private Attributes

nux::BaseTexture * noise_texture_
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
blur_texture_
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
resize_tmp_
nux::ObjectPtr
< nux::IOpenGLBaseTexture > 
noisy_tmp_
nux::Geometry blur_geometry_
bool cache_dirty

Static Private Attributes

static std::list
< BackgroundEffectHelper * > 
registered_list_

Detailed Description

Definition at line 40 of file BackgroundEffectHelper.h.


Constructor & Destructor Documentation

Definition at line 49 of file BackgroundEffectHelper.cpp.

{
  enabled = false;
  cache_dirty = true;
  enabled.changed.connect (sigc::mem_fun(this, &BackgroundEffectHelper::OnEnabledChanged));
  noise_texture_ = nux::CreateTextureFromFile(PKGDATADIR"/dash_noise.png");

  Register(this);
}

Here is the call graph for this function:

Definition at line 59 of file BackgroundEffectHelper.cpp.

{
  noise_texture_->UnReference();
  Unregister(this);
}

Member Function Documentation

Definition at line 117 of file BackgroundEffectHelper.cpp.

{
  if (cache_dirty)
    return;

  cache_dirty = true;
  if (owner)
    owner()->QueueDraw();
}
nux::ObjectPtr< nux::IOpenGLBaseTexture > BackgroundEffectHelper::GetBlurRegion ( nux::Geometry  geo,
bool  force_update = false 
)

Definition at line 127 of file BackgroundEffectHelper.cpp.

{
  bool should_update = force_update || cache_dirty;

  /* Static blur: only update when the size changed */
  if ((blur_type != BLUR_ACTIVE || !should_update)
      && blur_texture_.IsValid()
      && (geo == blur_geometry_))
  {
    return blur_texture_;
  }

  nux::GraphicsEngine* graphics_engine = nux::GetGraphicsDisplay()->GetGraphicsEngine();
  
  int monitor_width = BackgroundEffectHelper::monitor_rect_.width;
  int monitor_height = BackgroundEffectHelper::monitor_rect_.height;

  nux::Geometry temp = geo;
  temp.OffsetPosition(-monitor_rect_.x, -monitor_rect_.y);
  blur_geometry_ =  nux::Geometry(0, 0, monitor_width, monitor_height).Intersect(temp);

  nux::GpuDevice* gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();
  if (blur_geometry_.IsNull() || blur_type == BLUR_NONE || !gpu_device->backup_texture0_.IsValid())
  {
    return nux::ObjectPtr<nux::IOpenGLBaseTexture>();
  }

  int opengl_version = gpu_device->GetOpenGLMajorVersion();
  int sigma = opengl_version >= 3 ? sigma_high : sigma_med;
  int radius = 3 * sigma;

  // Define a larger region of that account for the blur radius
  nux::Geometry larger_blur_geometry;
  larger_blur_geometry.x = std::max(blur_geometry_.x - radius, 0);
  larger_blur_geometry.y = std::max(blur_geometry_.y - radius, 0);
  
  int xx = std::min(blur_geometry_.x + blur_geometry_.width + radius, monitor_width);

  larger_blur_geometry.width = xx - larger_blur_geometry.x;

  int yy = std::min(blur_geometry_.y + blur_geometry_.height + radius, monitor_height);

  larger_blur_geometry.height = yy - larger_blur_geometry.y;

  int dleft     = blur_geometry_.x - larger_blur_geometry.x;
  int dbottom   = (larger_blur_geometry.y + larger_blur_geometry.height) - (blur_geometry_.y + blur_geometry_.height);

  // save the current fbo
  nux::ObjectPtr<nux::IOpenGLFrameBufferObject> current_fbo = gpu_device->GetCurrentFrameBufferObject();
  gpu_device->DeactivateFrameBuffer();

  // Set a viewport to the requested size
  // FIXME: We need to do multiple passes for the dirty region
  // on the underlying backup texture so that we're only updating
  // the bits that we need
  graphics_engine->SetViewport(0, 0, larger_blur_geometry.width, larger_blur_geometry.height);
  graphics_engine->SetScissor(0, 0, larger_blur_geometry.width, larger_blur_geometry.height);
  // Disable nux scissoring
  graphics_engine->GetRenderStates ().EnableScissor (false);

  // The background texture is the same size as the monitor where we are rendering.
  nux::TexCoordXForm texxform__bg;
  texxform__bg.flip_v_coord = false;
  texxform__bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
  texxform__bg.uoffset = ((float) larger_blur_geometry.x) / monitor_width;
  texxform__bg.voffset = ((float) monitor_height - larger_blur_geometry.y - larger_blur_geometry.height) / monitor_height;

  bool support_frag = gpu_device->GetGpuInfo().Support_ARB_Fragment_Shader();
  bool support_vert = gpu_device->GetGpuInfo().Support_ARB_Vertex_Shader();

  if (support_vert && support_frag && opengl_version >= 2)
  {
    float noise_factor = 1.1f;
    float gaussian_sigma = opengl_version >= 3 ? sigma_high : sigma_med;
    int blur_passes = 1;

    nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture = gpu_device->backup_texture0_;
    nux::ObjectPtr<nux::CachedBaseTexture> noise_device_texture = graphics_engine->CacheResource(noise_texture_);

    unsigned int buffer_width = larger_blur_geometry.width;
    unsigned int buffer_height = larger_blur_geometry.height;

    blur_fx_struct_.src_texture = device_texture;
    graphics_engine->QRP_GLSL_GetHQBlurFx(0, 0, buffer_width, buffer_height,
                                                  &blur_fx_struct_, texxform__bg, nux::color::White,
                                                 gaussian_sigma, blur_passes);

    nux::TexCoordXForm texxform;
    nux::TexCoordXForm noise_texxform;

    texxform.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST);

    noise_texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
    noise_texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
    noise_texxform.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST);

    noise_fx_struct_.src_texture = blur_fx_struct_.dst_texture;

    // Add Noise
    nux::Color noise_color(noise_factor * 1.0f/buffer_width,
                           noise_factor * 1.0f/buffer_height,
                           1.0f, 1.0f);

    texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
    texxform.uoffset = (blur_geometry_.x - larger_blur_geometry.x) / (float) buffer_width;
    texxform.voffset = (blur_geometry_.y - larger_blur_geometry.y) / (float) buffer_height;
    graphics_engine->QRP_GLSL_GetDisturbedTextureFx(
      0, 0, blur_geometry_.width, blur_geometry_.height,
      noise_device_texture->m_Texture, noise_texxform, noise_color,
      &noise_fx_struct_, texxform, nux::color::White);
    
    blur_texture_ = noise_fx_struct_.dst_texture;
  }
  else
  {
    // GPUs with only ARB support are treated here

    float gaussian_sigma = sigma_low;
    int blur_passes = 1;

    nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture = gpu_device->backup_texture0_;
    nux::ObjectPtr<nux::CachedBaseTexture> noise_device_texture = graphics_engine->CacheResource(noise_texture_);

    unsigned int offset = 0;
    int quad_width = larger_blur_geometry.width;
    int quad_height = larger_blur_geometry.height;

    int down_size_factor = 4;
    unsigned int buffer_width = quad_width + 2 * offset;
    unsigned int buffer_height = quad_height + 2 * offset;

    int x = (buffer_width - quad_width) / 2;
    int y = (buffer_height - quad_height) / 2;

    unsigned int down_size_width = buffer_width / down_size_factor;
    unsigned int down_size_height = buffer_height / down_size_factor;

    nux::TexCoordXForm texxform;
    nux::TexCoordXForm noise_texxform;

    texxform.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST);

    noise_texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
    noise_texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
    noise_texxform.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST);

    // Copy source texture
    nux::ObjectPtr<nux::IOpenGLBaseTexture> texture_copy;
    graphics_engine->QRP_GetCopyTexture(buffer_width, buffer_height,
                                        texture_copy, device_texture,
                                        texxform__bg, nux::color::White);

    // Down size
    nux::ObjectPtr<nux::IOpenGLBaseTexture> resized_texture;
    graphics_engine->QRP_GetCopyTexture(down_size_width, down_size_height,
                                        resized_texture, texture_copy,
                                        texxform, nux::color::White);

    // Blur at a lower resolution (less pixels to process)
    nux::ObjectPtr<nux::IOpenGLBaseTexture> low_res_blur;
    low_res_blur = graphics_engine->QRP_GetBlurTexture(x, y, down_size_width, down_size_height,
                                                       resized_texture, texxform,
                                                       nux::color::White,
                                                       gaussian_sigma, blur_passes);

    // Up size
    texxform.SetFilter(nux::TEXFILTER_LINEAR, nux::TEXFILTER_LINEAR);
    graphics_engine->QRP_GetCopyTexture(buffer_width, buffer_height, resized_texture,
                                        low_res_blur, texxform, nux::color::White);

    // Returns a smaller blur region (minus blur radius).
    texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
    texxform.flip_v_coord = true;
    texxform.uoffset = dleft / (float) buffer_width;
    texxform.voffset = dbottom / (float) buffer_height;
    graphics_engine->QRP_GetCopyTexture(blur_geometry_.width, blur_geometry_.height,
                                        blur_texture_, resized_texture,
                                        texxform, nux::color::White);
  }

  if (current_fbo.IsValid())
  {
    current_fbo->Activate(true);
    graphics_engine->Push2DWindow(current_fbo->GetWidth(), current_fbo->GetHeight());
    graphics_engine->GetRenderStates ().EnableScissor (true);
  }
  else
  {
    graphics_engine->SetViewport(0, 0, monitor_width, monitor_height);
    graphics_engine->Push2DWindow(monitor_width, monitor_height);

    graphics_engine->ApplyClippingRectangle();
  }

  cache_dirty = false;
  return blur_texture_;
}

Here is the caller graph for this function:

nux::ObjectPtr<nux::IOpenGLBaseTexture> BackgroundEffectHelper::GetPixelatedRegion ( nux::Rect  rect,
int  pixel_size,
bool  update 
)
nux::ObjectPtr< nux::IOpenGLBaseTexture > BackgroundEffectHelper::GetRegion ( nux::Geometry  geo,
bool  force_update = false 
)

Definition at line 325 of file BackgroundEffectHelper.cpp.

{
  bool should_update = force_update || cache_dirty;

  /* Static blur: only update when the size changed */
  if ((!should_update)
      && blur_texture_.IsValid()
      && (geo == blur_geometry_))
  {
    return blur_texture_;
  }

  nux::GraphicsEngine* graphics_engine = nux::GetGraphicsDisplay()->GetGraphicsEngine();
  
  int monitor_width = BackgroundEffectHelper::monitor_rect_.width;
  int monitor_height = BackgroundEffectHelper::monitor_rect_.height;

  nux::Geometry temp = geo;
  temp.OffsetPosition(-monitor_rect_.x, -monitor_rect_.y);
  blur_geometry_ =  nux::Geometry(0, 0, monitor_width, monitor_height).Intersect(temp);

  nux::GpuDevice* gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();
  if (blur_geometry_.IsNull() || !gpu_device->backup_texture0_.IsValid())
  {
    return nux::ObjectPtr<nux::IOpenGLBaseTexture>();
  }

  // save the current fbo
  nux::ObjectPtr<nux::IOpenGLFrameBufferObject> current_fbo = gpu_device->GetCurrentFrameBufferObject();
  gpu_device->DeactivateFrameBuffer();

  // Set a viewport to the requested size
  // FIXME: We need to do multiple passes for the dirty region
  // on the underlying backup texture so that we're only updating
  // the bits that we need
  graphics_engine->SetViewport(0, 0, blur_geometry_.width, blur_geometry_.height);
  graphics_engine->SetScissor(0, 0, blur_geometry_.width, blur_geometry_.height);
  // Disable nux scissoring
  graphics_engine->GetRenderStates ().EnableScissor (false);

  // The background texture is the same size as the monitor where we are rendering.
  nux::TexCoordXForm texxform__bg;
  texxform__bg.flip_v_coord = false;
  texxform__bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
  texxform__bg.uoffset = ((float) blur_geometry_.x) / monitor_width;
  texxform__bg.voffset = ((float) monitor_height - blur_geometry_.y - blur_geometry_.height) / monitor_height;

  {
    nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture = gpu_device->backup_texture0_;
    nux::ObjectPtr<nux::CachedBaseTexture> noise_device_texture = graphics_engine->CacheResource(noise_texture_);

    unsigned int offset = 0;
    int quad_width = blur_geometry_.width;
    int quad_height = blur_geometry_.height;

    unsigned int buffer_width = quad_width + 2 * offset;
    unsigned int buffer_height = quad_height + 2 * offset;

    texxform__bg.SetFilter(nux::TEXFILTER_NEAREST, nux::TEXFILTER_NEAREST);
    texxform__bg.flip_v_coord = true;

    // Copy source texture
    graphics_engine->QRP_GetCopyTexture(buffer_width, buffer_height,
                                        blur_texture_, device_texture,
                                        texxform__bg, nux::color::White);
  }

  if (current_fbo.IsValid())
  {
    current_fbo->Activate(true);
    graphics_engine->Push2DWindow(current_fbo->GetWidth(), current_fbo->GetHeight());
    graphics_engine->GetRenderStates ().EnableScissor (true);
  }
  else
  {
    graphics_engine->SetViewport(0, 0, monitor_width, monitor_height);
    graphics_engine->Push2DWindow(monitor_width, monitor_height);

    graphics_engine->ApplyClippingRectangle();
  }

  cache_dirty = false;
  return blur_texture_;
}

Here is the caller graph for this function:

Definition at line 98 of file BackgroundEffectHelper.cpp.

{
  for (BackgroundEffectHelper * bg_effect_helper : registered_list_)
    if (bg_effect_helper->enabled && bg_effect_helper->cache_dirty)
      return true;

  return false;
}

Here is the caller graph for this function:

Definition at line 85 of file BackgroundEffectHelper.cpp.

{
  for (BackgroundEffectHelper * bg_effect_helper : registered_list_)
  {
    if (bg_effect_helper->enabled)
    {
      return true;
    }
  }

  return false;
}
void BackgroundEffectHelper::OnEnabledChanged ( bool  value) [private]

Definition at line 65 of file BackgroundEffectHelper.cpp.

{
  if (value)
    DirtyCache();
}

Here is the caller graph for this function:

void BackgroundEffectHelper::ProcessDamage ( nux::Geometry  geo) [static]

Definition at line 71 of file BackgroundEffectHelper.cpp.

{
  for (BackgroundEffectHelper * bg_effect_helper : registered_list_)
  {
    if (bg_effect_helper->cache_dirty || !bg_effect_helper->owner || !bg_effect_helper->enabled)
      continue;

    if (!geo.Intersect (bg_effect_helper->blur_geometry_).IsNull())
    {
      bg_effect_helper->DirtyCache();
    }
  }
}

Here is the caller graph for this function:

void BackgroundEffectHelper::Register ( BackgroundEffectHelper self) [static, protected]

Definition at line 107 of file BackgroundEffectHelper.cpp.

{
  registered_list_.push_back(self);
}
void BackgroundEffectHelper::Unregister ( BackgroundEffectHelper self) [static, protected]

Definition at line 112 of file BackgroundEffectHelper.cpp.

{
  registered_list_.remove(self);
}

Member Data Documentation

Definition at line 70 of file BackgroundEffectHelper.h.

nux::Geometry BackgroundEffectHelper::blur_geometry_ [private]

Definition at line 84 of file BackgroundEffectHelper.h.

nux::ObjectPtr<nux::IOpenGLBaseTexture> BackgroundEffectHelper::blur_texture_ [private]

Definition at line 81 of file BackgroundEffectHelper.h.

nux::Property< BlurType > BackgroundEffectHelper::blur_type [static]

Definition at line 61 of file BackgroundEffectHelper.h.

Definition at line 86 of file BackgroundEffectHelper.h.

nux::Property< bool > BackgroundEffectHelper::detecting_occlusions [static]

Definition at line 66 of file BackgroundEffectHelper.h.

nux::Property<bool> BackgroundEffectHelper::enabled

Definition at line 47 of file BackgroundEffectHelper.h.

nux::Geometry BackgroundEffectHelper::monitor_rect_ [static]

Definition at line 68 of file BackgroundEffectHelper.h.

Definition at line 71 of file BackgroundEffectHelper.h.

nux::BaseTexture* BackgroundEffectHelper::noise_texture_ [private]

Definition at line 80 of file BackgroundEffectHelper.h.

nux::ObjectPtr<nux::IOpenGLBaseTexture> BackgroundEffectHelper::noisy_tmp_ [private]

Definition at line 83 of file BackgroundEffectHelper.h.

nux::Property<nux::View*> BackgroundEffectHelper::owner

Definition at line 46 of file BackgroundEffectHelper.h.

Definition at line 88 of file BackgroundEffectHelper.h.

nux::ObjectPtr<nux::IOpenGLBaseTexture> BackgroundEffectHelper::resize_tmp_ [private]

Definition at line 82 of file BackgroundEffectHelper.h.

nux::Property< float > BackgroundEffectHelper::sigma_high [static]

Definition at line 62 of file BackgroundEffectHelper.h.

nux::Property< float > BackgroundEffectHelper::sigma_low [static]

Definition at line 64 of file BackgroundEffectHelper.h.

nux::Property< float > BackgroundEffectHelper::sigma_med [static]

Definition at line 63 of file BackgroundEffectHelper.h.

nux::Property< bool > BackgroundEffectHelper::updates_enabled [static]

Definition at line 65 of file BackgroundEffectHelper.h.


The documentation for this class was generated from the following files: