// SPDX-License-Identifier: LGPL-3.0-linking-exception
unit BGRACMapShader;
{$mode objfpc}{$H+}
interface
uses
BGRAOpenGL3D, BGRABitmapTypes, BGRACanvasGL, BGRAOpenGLType;
type
TBGLCMapShader = class(TBGLShader3D)
private
function GetCanvasSize: TPointF;
procedure SetCanvasSize(AValue: TPointF);
protected
// time
FTime: TUniformVariableSingle;
FTimer : Single;
// intensity
Fintensity : TUniformVariableSingle;
FintensityV : Single;
// Color mode
FMode : TUniformVariableSingle;
FModeV : Single;
FImage0: TUniformVariableInteger;
FImage0V : Integer;
FCanvasSize: TUniformVariablePointF;
procedure StartUse; override;
public
constructor Create(ACanvas: TBGLCustomCanvas);
function Render(ATexture: IBGLTexture): IBGLTexture; overload;
procedure RenderOnCanvas;
// propriete ecriture des uniforms
property Time: Single read FTimer write FTimer;
property Intensity : Single read FintensityV write FintensityV;
property Cmode : Single read FModeV write FModeV ;
property Image0: integer read FImage0V write FImage0V;
property CanvasSize: TPointF read GetCanvasSize write SetCanvasSize;
end;
implementation
function TBGLCMapShader.GetCanvasSize: TPointF;
begin
result := FCanvasSize.Value;
end;
procedure TBGLCMapShader.SetCanvasSize(AValue: TPointF);
begin
FCanvasSize.Value := AValue;
end;
{ TBGLCMapShader }
constructor TBGLCMapShader.Create(ACanvas: TBGLCustomCanvas);
begin
// vertex
inherited Create(ACanvas,
'uniform vec2 canvasSize;'#10 +
'void main(void) {'#10 +
' gl_Position = gl_ProjectionMatrix * gl_Vertex ;'#10 +
' // gl_FrontColor = gl_Color;'#10 +
' //texCoord = gl_Vertex.xy / canvasSize;'#10 +
' texCoord = vec2(gl_MultiTexCoord0) ;'#10 +
'}',
// fragment shader
'//out vec4 FragmentColor;'#10 +
'uniform float time;'#10+
'uniform sampler2D tex;'#10+
'uniform float intensity; '#10+
'uniform float c_mode; '#10+
'vec3 find_closest (in vec3 ref) { '#10+
'vec3 old = vec3 (100.0*255.0); '#10+
'#define TRY_COLOR(new) old = mix (new, old, step (length (old-ref), length (new-ref))); '#10+
' '#10+
' '#10+
// TWOBGS
' if(c_mode==1.0){ '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 000.0)); '#10+
' TRY_COLOR (vec3 (103.0, 103.0, 103.0)); '#10+
' TRY_COLOR (vec3 (184.0, 184.0, 184.0)); '#10+
' TRY_COLOR (vec3 (255.0, 255.0, 255.0)); '#10+
' } '#10+
// BW
' if(c_mode==2.0){ '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 000.0)); '#10+
' TRY_COLOR (vec3 (255.0, 255.0, 255.0)); '#10+
' } '#10+
'if(c_mode==3.0){ '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 000.0)); '#10+
' TRY_COLOR (vec3 (255.0, 000.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 255.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 255.0)); '#10+
' TRY_COLOR (vec3 (000.0, 255.0, 255.0)); '#10+
' TRY_COLOR (vec3 (255.0, 000.0, 255.0)); '#10+
' TRY_COLOR (vec3 (255.0, 255.0, 000.0)); '#10+
' TRY_COLOR (vec3 (255.0, 255.0, 255.0)); '#10+
' } '#10+
'if(c_mode==4.0){ '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 000.0)); '#10+
' TRY_COLOR (vec3 (080.0, 048.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 104.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 064.0, 088.0)); '#10+
' TRY_COLOR (vec3 (000.0, 120.0, 000.0)); '#10+
' TRY_COLOR (vec3 (136.0, 020.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 168.0, 000.0)); '#10+
' TRY_COLOR (vec3 (168.0, 016.0, 000.0)); '#10+
' TRY_COLOR (vec3 (168.0, 000.0, 032.0)); '#10+
' TRY_COLOR (vec3 (000.0, 168.0, 068.0)); '#10+
' TRY_COLOR (vec3 (000.0, 184.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 188.0)); '#10+
' TRY_COLOR (vec3 (000.0, 136.0, 136.0)); '#10+
' TRY_COLOR (vec3 (148.0, 000.0, 132.0)); '#10+
' TRY_COLOR (vec3 (068.0, 040.0, 188.0)); '#10+
' TRY_COLOR (vec3 (120.0, 120.0, 120.0)); '#10+
' TRY_COLOR (vec3 (172.0, 124.0, 000.0)); '#10+
' TRY_COLOR (vec3 (124.0, 124.0, 124.0)); '#10+
' TRY_COLOR (vec3 (228.0, 000.0, 088.0)); '#10+
' TRY_COLOR (vec3 (228.0, 092.0, 016.0)); '#10+
' TRY_COLOR (vec3 (088.0, 216.0, 084.0)); '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 252.0)); '#10+
' TRY_COLOR (vec3 (248.0, 056.0, 000.0)); '#10+
' TRY_COLOR (vec3 (000.0, 088.0, 248.0)); '#10+
' TRY_COLOR (vec3 (000.0, 120.0, 248.0)); '#10+
' TRY_COLOR (vec3 (104.0, 068.0, 252.0)); '#10+
' TRY_COLOR (vec3 (248.0, 120.0, 088.0)); '#10+
' TRY_COLOR (vec3 (216.0, 000.0, 204.0)); '#10+
' TRY_COLOR (vec3 (088.0, 248.0, 152.0)); '#10+
' TRY_COLOR (vec3 (248.0, 088.0, 152.0)); '#10+
' TRY_COLOR (vec3 (104.0, 136.0, 252.0)); '#10+
' TRY_COLOR (vec3 (252.0, 160.0, 068.0)); '#10+
' TRY_COLOR (vec3 (248.0, 184.0, 000.0)); '#10+
' TRY_COLOR (vec3 (184.0, 248.0, 024.0)); '#10+
' TRY_COLOR (vec3 (152.0, 120.0, 248.0)); '#10+
' TRY_COLOR (vec3 (000.0, 232.0, 216.0)); '#10+
' TRY_COLOR (vec3 (060.0, 188.0, 252.0)); '#10+
' TRY_COLOR (vec3 (188.0, 188.0, 188.0)); '#10+
' TRY_COLOR (vec3 (216.0, 248.0, 120.0)); '#10+
' TRY_COLOR (vec3 (248.0, 216.0, 120.0)); '#10+
' TRY_COLOR (vec3 (248.0, 164.0, 192.0)); '#10+
' TRY_COLOR (vec3 (000.0, 252.0, 252.0)); '#10+
' TRY_COLOR (vec3 (184.0, 184.0, 248.0)); '#10+
' TRY_COLOR (vec3 (184.0, 248.0, 184.0)); '#10+
' TRY_COLOR (vec3 (240.0, 208.0, 176.0)); '#10+
' TRY_COLOR (vec3 (248.0, 120.0, 248.0)); '#10+
' TRY_COLOR (vec3 (252.0, 224.0, 168.0)); '#10+
' TRY_COLOR (vec3 (184.0, 248.0, 216.0)); '#10+
' TRY_COLOR (vec3 (216.0, 184.0, 248.0)); '#10+
' TRY_COLOR (vec3 (164.0, 228.0, 252.0)); '#10+
' TRY_COLOR (vec3 (248.0, 184.0, 248.0)); '#10+
' TRY_COLOR (vec3 (248.0, 216.0, 248.0)); '#10+
' TRY_COLOR (vec3 (248.0, 248.0, 248.0)); '#10+
' TRY_COLOR (vec3 (252.0, 252.0, 252.0)); '#10+
' } '#10+
' '#10+
'if(c_mode==5.0){ '#10+
' TRY_COLOR (vec3 (156.0, 189.0, 015.0)); '#10+
' TRY_COLOR (vec3 (140.0, 173.0, 015.0)); '#10+
' TRY_COLOR (vec3 (048.0, 098.0, 048.0)); '#10+
' TRY_COLOR (vec3 (000.0, 000.0, 000.0)); '#10+
' } '#10+
' '#10+
'if(c_mode==6.0){ '#10+
' TRY_COLOR (vec3 (000.0,000.0,000.0)); '#10+
' TRY_COLOR (vec3 (255.0,255.0,255.0)); '#10+
' TRY_COLOR (vec3 (255.0, 0.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0,255.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0, 0.0,255.0)); '#10+
' TRY_COLOR (vec3 (255.0,255.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0,255.0,255.0)); '#10+
' TRY_COLOR (vec3 (255.0, 0.0,255.0)); '#10+
' TRY_COLOR (vec3 (128.0, 0.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0,128.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0, 0.0,128.0)); '#10+
' TRY_COLOR (vec3 (128.0,128.0, 0.0)); '#10+
' TRY_COLOR (vec3 ( 0.0,128.0,128.0)); '#10+
' TRY_COLOR (vec3 (128.0, 0.0,128.0)); '#10+
' TRY_COLOR (vec3 (128.0,128.0,128.0)); '#10+
' TRY_COLOR (vec3 (255.0,128.0,128.0)); '#10+
' } '#10+
' '#10+
'if(c_mode==7.0){ '#10+
' TRY_COLOR (vec3 (000.0,000.0,000.0)); '#10+
' TRY_COLOR (vec3 (000.0,170.0,170.0)); '#10+
' TRY_COLOR (vec3 (170.0,000.0,170.0)); '#10+
' TRY_COLOR (vec3 (170.0,170.0,170.0)); '#10+
' } '#10+
' '#10+
'if(c_mode==8.0){ '#10+
' TRY_COLOR ( vec3(000.0,000.0,000.0)); '#10+
' TRY_COLOR ( vec3(000.0,000.0,128.0)); '#10+
' TRY_COLOR ( vec3(000.0,000.0,255.0)); '#10+
' TRY_COLOR ( vec3(128.0,000.0,000.0)); '#10+
' TRY_COLOR ( vec3(128.0,000.0,128.0)); '#10+
' TRY_COLOR ( vec3(128.0,000.0,255.0)); '#10+
' TRY_COLOR ( vec3(255.0,000.0,000.0)); '#10+
' TRY_COLOR ( vec3(255.0,000.0,128.0)); '#10+
' TRY_COLOR ( vec3(255.0,000.0,255.0)); '#10+
' TRY_COLOR ( vec3(000.0,128.0,000.0)); '#10+
' TRY_COLOR ( vec3(000.0,128.0,128.0)); '#10+
' TRY_COLOR ( vec3(000.0,128.0,255.0)); '#10+
' TRY_COLOR ( vec3(128.0,128.0,000.0)); '#10+
' TRY_COLOR ( vec3(128.0,128.0,128.0)); '#10+
' TRY_COLOR ( vec3(128.0,128.0,255.0)); '#10+
' TRY_COLOR ( vec3(255.0,128.0,000.0)); '#10+
' TRY_COLOR ( vec3(255.0,128.0,128.0)); '#10+
' TRY_COLOR ( vec3(255.0,128.0,255.0)); '#10+
' TRY_COLOR ( vec3(000.0,255.0,000.0)); '#10+
' TRY_COLOR ( vec3(000.0,255.0,128.0)); '#10+
' TRY_COLOR ( vec3(000.0,255.0,255.0)); '#10+
' TRY_COLOR ( vec3(128.0,255.0,000.0)); '#10+
' TRY_COLOR ( vec3(128.0,255.0,128.0)); '#10+
' TRY_COLOR ( vec3(128.0,255.0,255.0)); '#10+
' TRY_COLOR ( vec3(255.0,255.0,000.0)); '#10+
' TRY_COLOR ( vec3(255.0,255.0,128.0)); '#10+
' TRY_COLOR ( vec3(255.0,255.0,255.0)); '#10+
' } '#10+
' '#10+
'if(c_mode==9.0){ '#10+
' TRY_COLOR (vec3(0,0,0)); '#10+
' TRY_COLOR ( vec3(85,0,0)); '#10+
' TRY_COLOR ( vec3(170,0,0)); '#10+
' TRY_COLOR ( vec3(255,0,0)); '#10+
' TRY_COLOR ( vec3(0,85,0)); '#10+
' TRY_COLOR ( vec3(85,85,0)); '#10+
' TRY_COLOR ( vec3(170,85,0)); '#10+
' TRY_COLOR ( vec3(255,85,0)); '#10+
' TRY_COLOR ( vec3(0,170,0)); '#10+
' TRY_COLOR ( vec3(85,170,0)); '#10+
' TRY_COLOR ( vec3(170,170,0)); '#10+
' TRY_COLOR ( vec3(255,170,0)); '#10+
' TRY_COLOR ( vec3(0,255,0)); '#10+
' TRY_COLOR ( vec3(85,255,0)); '#10+
' TRY_COLOR ( vec3(170,255,0)); '#10+
' TRY_COLOR ( vec3(255,255,0)); '#10+
' TRY_COLOR ( vec3(0,0,85)); '#10+
' TRY_COLOR ( vec3(85,0,85)); '#10+
' TRY_COLOR ( vec3(170,0,85)); '#10+
' TRY_COLOR ( vec3(255,0,85)); '#10+
' TRY_COLOR ( vec3(0,85,85)); '#10+
' TRY_COLOR ( vec3(85,85,85)); '#10+
' TRY_COLOR ( vec3(170,85,85)); '#10+
' TRY_COLOR ( vec3(255,85,85)); '#10+
' TRY_COLOR ( vec3(0,170,85)); '#10+
' TRY_COLOR ( vec3(85,170,85)); '#10+
' TRY_COLOR ( vec3(170,170,85)); '#10+
' TRY_COLOR ( vec3(255,170,85)); '#10+
' TRY_COLOR ( vec3(0,255,85)); '#10+
' TRY_COLOR ( vec3(85,255,85)); '#10+
' TRY_COLOR ( vec3(170,255,85)); '#10+
' TRY_COLOR ( vec3(255,255,85)); '#10+
' TRY_COLOR ( vec3(0,0,170)); '#10+
' TRY_COLOR ( vec3(85,0,170)); '#10+
' TRY_COLOR ( vec3(170,0,170)); '#10+
' TRY_COLOR ( vec3(255,0,170)); '#10+
' TRY_COLOR ( vec3(0,85,170)); '#10+
' TRY_COLOR ( vec3(85,85,170)); '#10+
' TRY_COLOR ( vec3(170,85,170)); '#10+
' TRY_COLOR ( vec3(255,85,170)); '#10+
' TRY_COLOR ( vec3(0,170,170)); '#10+
' TRY_COLOR ( vec3(85,170,170)); '#10+
' TRY_COLOR ( vec3(170,170,170)); '#10+
' TRY_COLOR ( vec3(255,170,170)); '#10+
' TRY_COLOR ( vec3(0,255,170)); '#10+
' TRY_COLOR ( vec3(85,255,170)); '#10+
' TRY_COLOR ( vec3(170,255,170)); '#10+
' TRY_COLOR ( vec3(255,255,170)); '#10+
' TRY_COLOR ( vec3(0,0,255)); '#10+
' TRY_COLOR ( vec3(85,0,255)); '#10+
' TRY_COLOR ( vec3(170,0,255)); '#10+
' TRY_COLOR ( vec3(255,0,255)); '#10+
' TRY_COLOR ( vec3(0,85,255)); '#10+
' TRY_COLOR ( vec3(85,85,255)); '#10+
' TRY_COLOR ( vec3(170,85,255)); '#10+
' TRY_COLOR ( vec3(255,85,255)); '#10+
' TRY_COLOR ( vec3(0,170,255)); '#10+
' TRY_COLOR ( vec3(85,170,255)); '#10+
' TRY_COLOR ( vec3(170,170,255)); '#10+
' TRY_COLOR ( vec3(255,170,255)); '#10+
' TRY_COLOR ( vec3(0,255,255)); '#10+
' TRY_COLOR ( vec3(85,255,255)); '#10+
' TRY_COLOR ( vec3(170,255,255)); '#10+
' TRY_COLOR ( vec3(255,255,255)); '#10+
' } '#10+
'if(c_mode==10.0){ '#10+
' TRY_COLOR(vec3(0,0,0)*255.0);// black '#10+
' TRY_COLOR(vec3(1,1,1)*255.0);// white '#10+
' TRY_COLOR(vec3(0.41,0.22,0.17)*255.0); '#10+
' TRY_COLOR(vec3(0.44,0.64,0.70)*255.0); '#10+
' TRY_COLOR(vec3(0.44,0.24,0.53)*255.0); '#10+
' TRY_COLOR(vec3(0.35,0.55,0.26)*255.0); '#10+
' TRY_COLOR(vec3(0.21,0.16,0.47)*255.0); '#10+
' TRY_COLOR(vec3(0.72,0.78,0.44)*255.0); '#10+
' TRY_COLOR(vec3(0.44,0.31,0.15)*255.0); '#10+
' TRY_COLOR(vec3(0.26,0.22,0.00)*255.0); '#10+
' TRY_COLOR(vec3(0.60,0.40,0.35)*255.0); '#10+
' TRY_COLOR(vec3(0.27,0.27,0.27)*255.0); '#10+
' TRY_COLOR(vec3(0.42,0.42,0.42)*255.0); '#10+
' TRY_COLOR(vec3(0.60,0.82,0.52)*255.0); '#10+
' TRY_COLOR(vec3(0.42,0.37,0.71)*255.0); '#10+
' TRY_COLOR(vec3(0.58,0.58,0.58)*255.0); '#10+
' } '#10+
'if(c_mode==11.0){ '#10+
' TRY_COLOR(vec3(0,0,0));// black '#10+
' TRY_COLOR(vec3(0,0,255.0));// bluez80 '#10+
' TRY_COLOR(vec3(0,0,192.0));// bluez80 '#10+
' TRY_COLOR(vec3(255.0,0,0)); '#10+
' TRY_COLOR(vec3(192.0,0,0)); '#10+
' TRY_COLOR(vec3(255.0,0,255.0)); '#10+
' TRY_COLOR(vec3(192.0,0,192.0)); '#10+
' TRY_COLOR(vec3(0,255.0,0)); '#10+
' TRY_COLOR(vec3(0,192.0,0)); '#10+
' TRY_COLOR(vec3(0,255.0,255.0)); '#10+
' TRY_COLOR(vec3(0,192.0,192.0)); '#10+
' TRY_COLOR(vec3(255.0,255.0,0)); '#10+
' TRY_COLOR(vec3(192.0,192.0,0)); '#10+
' TRY_COLOR(vec3(255.0,255.0,255.0)); '#10+
' TRY_COLOR(vec3(192.0,192.0,192.0)); '#10+
' '#10+
' } '#10+
' '#10+
'if(c_mode==12.0){ '#10+
' TRY_COLOR(vec3(0,0,0));// black '#10+
' TRY_COLOR(vec3(62.0, 184.0,73.0)); '#10+
' TRY_COLOR(vec3(116.0, 208.0, 125.0)); '#10+
' TRY_COLOR(vec3(89.0, 85.0, 224.0)); '#10+
' TRY_COLOR(vec3(128.0, 118.0, 241.0)); '#10+
' TRY_COLOR(vec3(185.0, 94.0, 81.0)); '#10+
' TRY_COLOR(vec3(101.0, 219.0, 239.0)); '#10+
' TRY_COLOR(vec3(219.0, 101.0, 89.0)); '#10+
' TRY_COLOR(vec3(255.0, 137.0, 125.0)); '#10+
' TRY_COLOR(vec3(204.0, 195.0, 94.0)); '#10+
' TRY_COLOR(vec3(222.0, 208.0, 135.0)); '#10+
' TRY_COLOR(vec3(58.0, 162.0, 65.0)); '#10+
' TRY_COLOR(vec3(183.0, 102.0, 181.0)); '#10+
' TRY_COLOR(vec3(204.0, 204.0, 204.0)); '#10+
' TRY_COLOR(vec3(255.0, 255.0, 255.0)); '#10+
' } '#10+
'return old ; '#10+
'} '#10+
'vec3 dither (vec3 color, vec2 uv) { '#10+
' color *= 255.0 * intensity; '#10+
' //color += dither_matrix (mod (uv.x, 8.0), mod (uv.y, 8.0)) ; '#10+
' color = find_closest (clamp (color, 0.0, 255.0)); '#10+
' return color / 255.0; '#10+
'} '#10+
'void main()'#10 +
'{'#10 +
'vec2 uv = texCoord.xy ; '#10+
// flip y
' uv.y = 1.-uv.y; '#10+
// resolution down
'uv = floor(256.0*uv)/256.0;'#10+
// texture xy_position
//' vec2 xy_pos = vec2(0.09,0.25);'#10+
' vec3 tx = texture(tex, uv ).xyz; '#10+
' if(c_mode>=1.0) '#10+
' gl_FragColor = vec4 (dither (tx, uv ),1.0); '#10+
' else '#10+
' gl_FragColor = vec4 (tx ,1.0)* intensity; '#10+
'}',
'varying vec2 texCoord;', '130');
FTime := UniformSingle['time']; // float uniform
Fintensity := UniformSingle['intensity'];
FMode := UniformSingle['c_mode'];
FImage0 := UniformInteger['tex'];
FCanvasSize := UniformPointF['canvasSize'];
FImage0V := 0;
FTimer := 0;
FintensityV := 1.0;
FModeV := 1.0;
end;
procedure TBGLCMapShader.StartUse;
begin
inherited StartUse;
FTime.Update;
FTime.Value:=FTimer;
FImage0.Update;
FImage0.Value:=FImage0V;
FIntensity.Update;
Fintensity.Value:= FintensityV;
FMode.Update;
FMode.Value:= FModeV;
end;
function TBGLCMapShader.Render(ATexture: IBGLTexture): IBGLTexture;
var previousBuf,buf: TBGLCustomFrameBuffer;
previousShader: TBGLCustomShader;
begin
previousBuf := Canvas.ActiveFrameBuffer;
buf := Canvas.CreateFrameBuffer(ATexture.Width, ATexture.Height);
Canvas.ActiveFrameBuffer := buf;
previousShader := Canvas.Lighting.ActiveShader;
Canvas.Lighting.ActiveShader := self;
ATexture.Draw(0, 0);
Canvas.Lighting.ActiveShader := previousShader;
Canvas.ActiveFrameBuffer := previousBuf;
result := buf.MakeTextureAndFree;
end;
procedure TBGLCMapShader.RenderOnCanvas;
var
previousShader: TBGLCustomShader;
begin
previousShader := Canvas.Lighting.ActiveShader;
Canvas.Lighting.ActiveShader := self;
CanvasSize := PointF(800,600);
Canvas.FillRect(0, 0, 800,600, CSSBlack);
Canvas.Lighting.ActiveShader := previousShader;
end;
end.