Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

unit app_glscene_blur;

interface

uses OpenGL, GLaux, glExt, sux_constant, sux_object, app_constant,
     resource_texture, resource_shader, resource_list;

type
  TSettings=record
    textures: SRList;
    currenttexture:SXInt;
    maxtexture:SXInt;
    timer:SXFloat;
    blurintensity:SXFloat;
    npottextures: SXBool;
  end;
  SAGLSBlur=class(SUXObject)
    settings:TSettings;

    procedure setBlurIntensity(intensity:SXFloat);
    procedure createTextureArray;
    procedure addFrameTexture;
    function getTexture(const index: SXInt): SRTexture;

    procedure renderTextures;
    procedure onTimer;

    procedure initialize;
    constructor Create(parent:TObject);
    destructor Destroy; override;
  end;

implementation

uses gl_main, main, gl_textureengine;


// --- SAGLSBlur


procedure SAGLSBlur.setBlurIntensity(intensity:SXFloat);
begin
  if (settings.blurintensity < intensity) then settings.blurintensity := intensity;
end;


procedure SAGLSBlur.createTextureArray;
var t: SXInt;
    texture: SRTexture;
begin
  with settings do
  begin
    for t := 0 to app.ini.settings.display.motionblurframes - 1 do
    begin
      if (npottextures) then
      begin
        texture := SRTexture.Create(self);

        glGenTextures(1, texture.texture.index);
        glBindTexture(GL_TEXTURE_2D, texture.texture.index);
        glTexImage2D(GL_TEXTURE_2D, 0, 4, gl.getCurrentRenderingContext.screen.width,
          gl.getCurrentRenderingContext.screen.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);

        texture.texture.displayindex := texture.texture.index;
        texture.texture.width := gl.getCurrentRenderingContext.screen.width;
        texture.texture.height := gl.getCurrentRenderingContext.screen.height;
        texture.texture.format := SX_TEXTURE_FORMAT_RGBA;
        texture.setTextureClamp(true, true);
        texture.setTextureCompression(SX_GLTEXTURE_COMPRESSION_NONE);
        texture.setTextureFilter(SX_GLTEXTURE_FILTER_NONE);
      end else
      begin
        texture := nil;
        app.scene.r2t.generateScreenGrabTexture(texture);
      end;
     
      textures.addObject(texture);
    end;

    maxtexture := SX_NONE;
    currenttexture := SX_NONE;
  end;
end;


procedure SAGLSBlur.addFrameTexture;
begin
  with settings do
  begin
    inc(currenttexture);
    if (currenttexture >= app.ini.settings.display.motionblurframes) then currenttexture := 0;
    if (currenttexture > maxtexture) then maxtexture := currenttexture;

    // Now grab frame to current texture
    app.scene.r2t.grabScreenToTexture(getTexture(currenttexture));
  end;
end;


function SAGLSBlur.getTexture(const index: SXInt): SRTexture;
begin
  result := SRTexture(settings.textures.getObject(index));
end;




procedure SAGLSBlur.renderTextures;
var t,displayt:SXInt;
    intensity:SXFloat;
    width,height:SXFloat;
    incr, changeincr: SXFloat;
begin
  with settings do
  begin
    if (blurintensity<=0) and (not (app.game.settings.effects.slowmotion > 0)) then exit;
    if (currenttexture=SX_NONE) or (maxtexture<0) then exit;
    t := currenttexture - (app.ini.settings.display.motionblurframes - 1);
    intensity:=0;

    incr:=40;
    changeincr := -4;
    if (app.game.settings.effects.slowmotion > 0) then
    begin
      blurintensity := app.game.settings.effects.slowmotion;
      if (blurintensity > 1.1) then blurintensity := 1.1;
      incr := 1;
      changeincr := 0;
    end;

    if (settings.npottextures) then
    begin
      width := 1;
      height := 1;
    end else
    begin
      width:=gl.getCurrentRenderingContext.screen.width/app.scene.scene.framebuffer.texture.width;
      height:=gl.getCurrentRenderingContext.screen.height/app.scene.scene.framebuffer.texture.height;
    end;

    repeat
      inc(t);
      intensity := intensity + 0.02 * settings.blurintensity;
      displayt := t;
      while (displayt < 0) do displayt := displayt + app.ini.settings.display.motionblurframes;

      gl.material.resetMaterial;
      gl.material.setMaterial2D;
      gl.material.setMaterialBlending(SX_GL_BLEND_ADDITIVE,sx.convert.ColorRGBOf(1,1,1),intensity);
      gl.material.setMaterialTexture(getTexture(displayt));
      gl.material.renderMaterial;

      glBegin(GL_QUADS);
        glTexCoord2f(0,0); glVertex2f(0-incr,480+incr);
        glTexCoord2f(width,0); glVertex2f(640+incr,480+incr);
        glTexCoord2f(width,height); glVertex2f(640+incr,0-incr);
        glTexCoord2f(0, height); glVertex2f(0-incr,0-incr);
      glEnd;
      incr := incr + changeincr;
      //gl.gl2D.screen.renderFrameBufferTextureOnScreen(textures[displayt],SX_GL_BLEND_ADDITIVE,sx.convert.ColorRGBOf(1,1,1),intensity);
    until (t=currenttexture);

    sx.timer.decTimer(blurintensity);
  end;
end;


procedure SAGLSBlur.onTimer;
begin
  if (not app.ini.settings.display.motionblur) then exit;
  if (app.ini.settings.display.motionblurframes < 1) then exit;
  if (app.ini.settings.display.motionblurframes > 10) then app.ini.settings.display.motionblurframes := 10;

  // Add a new texture to the blur array
  sx.timer.incTimer(settings.timer);
  if (settings.timer>=SX_GLBLUR_FRAMEINTENSITY) then
  begin
    settings.timer:=settings.timer-SX_GLBLUR_FRAMEINTENSITY;
    addFrameTexture;
  end;

  // Blur all textures together to create motion blur effect
  renderTextures;
end;




procedure SAGLSBlur.initialize;
begin
  if (not app.ini.settings.display.motionblur) then exit;
  if (app.ini.settings.display.motionblurframes < 1) then exit;

  settings.npottextures := glExt.isSupported('GL_ARB_texture_non_power_of_two');

  createTextureArray;
end;


constructor SAGLSBlur.Create(parent:TObject);
begin
  inherited Create(parent,'GL Blur');

  settings.textures := SRList.Create(self, true, true, true);
  settings.blurintensity:=0;
end;


destructor SAGLSBlur.Destroy;
begin
  settings.textures.Free;

  inherited;
end;


end.