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)
x_rot: TFloatSpinEdit;
ShaderScreen1: TBGLVirtualScreen;
FragMemo: TMemo;
Timer1: TTimer;
VertexMemo: TMemo;
y_rot: TFloatSpinEdit;
shape_num: TFloatSpinEdit;
z_rot: TFloatSpinEdit;
zoom: TFloatSpinEdit;
br: TFloatSpinEdit;
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;
ctx : TBGLContext;
fshader : string ; vshader : string; // fragment and vertex
end;
var
Form1: TForm1;
tt : Single;
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['x_rot'].Value := x_rot.Value;
shader3.UniformSingle['y_rot'].Value := y_rot.Value;
shader3.UniformSingle['z_rot'].Value := z_rot.Value;
shader3.UniformSingle['zoom'].Value := zoom.Value;
shader3.UniformSingle['br'].Value := br.Value;
shader3.UniformSingle['sn'].Value := shape_num.Value;
shader3.UniformSingle['tm'].Value := tt;
tt := tt + 0.02;
ShaderScreen1.Invalidate;
end;
end;
end.