unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
Spin, BGRAOpenGL, BGRABitmapTypes, BGRAOpenGL3D, BGLVirtualScreen;
type
{ TForm1 }
TForm1 = class(TForm)
save_btn: TButton;
s_red: TFloatSpinEdit;
ShaderScreen1: TBGLVirtualScreen;
FragMemo: TMemo;
s_brigtness: TFloatSpinEdit;
Timer1: TTimer;
s_green: TFloatSpinEdit;
s_gamma: TFloatSpinEdit;
s_blue: TFloatSpinEdit;
s_staturation: TFloatSpinEdit;
s_contrast: TFloatSpinEdit;
VertexMemo: TMemo;
procedure save_btnClick(Sender: TObject);
procedure ShaderScreen1LoadTextures(Sender: TObject; BGLContext: TBGLContext);
procedure ShaderScreen1Redraw(Sender: TObject; BGLContext: TBGLContext);
procedure ShaderScreen1UnloadTextures(Sender: TObject; BGLContext: TBGLContext);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure InitShader; // init and start shader
private
public
gl_surface : IBGLTexture; shader3 : TBGLShader3D;
final_image : TBGRACustomBitmap; // to save .png
ctx : TBGLContext;
fshader : string ; vshader : string; // fragment and vertex
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
fshader := FragMemo.text;
vshader := VertexMemo.Text;
end;
procedure TForm1.ShaderScreen1Redraw(Sender: TObject; BGLContext: TBGLContext);
begin
if gl_surface <> nil then
BGLContext.Canvas.StretchPutImage(0, 0, ShaderScreen1.Width, ShaderScreen1.Height, gl_surface);
if shader3 <> nil then
begin
BGLContext.Canvas.Lighting.ActiveShader := shader3;
end;
end;
procedure TForm1.ShaderScreen1LoadTextures(Sender: TObject; BGLContext: TBGLContext);
begin
try
gl_surface := BGLTexture(ResourceFile('gl.png')); // your image 128*128 or 256*256, or 512*512
// Create shader
shader3 := TBGLShader3D.Create(
BGLContext.Canvas,
vshader, // Vertex shader
fshader, // Fragment shader
'varying vec2 texCoord;',
'130'); // Version GLSL
ctx := BGLContext;
initShader; // ***** Start Shader
except
on E: Exception do
raise exception.Create('Shader Error : ' + E.Message);
end;
end;
procedure Tform1.InitShader;
begin
try
fshader := FragMemo.Text;
vshader := VertexMemo.Text;
if Assigned(shader3) then
begin
ctx.Canvas.Lighting.ActiveShader := nil;
FreeAndNil(shader3);
end;
shader3 := TBGLShader3D.Create(ctx.Canvas, vshader, fshader, 'varying vec2 texCoord;', '130');
// if shader error, exception raised by BGRAOpenGLD3 nice :);
Timer1.Enabled := True; // timer1
except
on E: Exception do
ShowMessage('Shader Error : ' + E.Message);
end;
end;
procedure TForm1.ShaderScreen1UnloadTextures(Sender: TObject;
BGLContext: TBGLContext);
begin
gl_surface := nil;
FreeAndNil(shader3);
BGLContext.Canvas.Lighting.ActiveShader := nil;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if shader3 <> nil then
begin
shader3.UniformPointF['resolution'].Value := Pointf(Round(ShaderScreen1.Width),Round(ShaderScreen1.Height));
shader3.UniformSingle['rr'].Value := s_red.Value;
shader3.UniformSingle['gg'].Value := s_green.Value;
shader3.UniformSingle['bb'].Value := s_blue.Value;
shader3.UniformSingle['brightness'].Value := s_brigtness.Value;
shader3.UniformSingle['contrast'].Value := s_contrast.Value;
shader3.UniformSingle['gamma'].Value := s_gamma.Value;;
shader3.UniformSingle['saturation'].Value := s_staturation.Value;
ShaderScreen1.Invalidate;
end;
end;
procedure TForm1.save_btnClick(Sender: TObject);
begin
final_image := shaderScreen1.Canvas.GetImage(0,0,ShaderScreen1.Width,ShaderScreen1.Height);
final_image.SaveToFile('my_image.png'); // save the result to .png
end;
end.