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.