-
Notifications
You must be signed in to change notification settings - Fork 12
/
Mundus.Shader.pas
120 lines (96 loc) · 3.21 KB
/
Mundus.Shader.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
unit Mundus.Shader;
interface
uses
Classes,
Types,
Graphics,
Mundus.Types,
Mundus.Math,
Mundus.ValueBuffer;
type
TPointF = record
X: Single;
Y: Single;
end;
TVertexShaderInput = record
VertexID: Integer;
end;
TNoAttributes = record
end;
TShader = class(TObject)
private
FPixelBuffer: TBitmap;
FPixel: TPoint;
FLineLength: Integer;
FFirstLine: PRGB32Array;
FMinX: Cardinal;
FMinY: Cardinal;
procedure SetPixelBuffer(const Value: TBitmap);
public
constructor Create(); virtual;
procedure VertexShader(const AWorld, AProjection: TMatrix4x4; var AVertex: TFloat4; const AVInput: TVertexShaderInput; const AAttributeBuffer: Pointer); virtual; abstract;
procedure BindBuffer(const ABuffer: PValueBuffers); virtual;
class function GetRasterizer: TRasterizer; virtual; abstract;
class function GetAttributeBufferSize: Integer; virtual; abstract;
property Pixel: TPoint read FPixel write FPixel;
property LineLength: Integer read FLineLength;
property FirstLine: PRGB32Array read FFirstLine;
property MinX: Cardinal read FMinX write FMinX;
property MinY: Cardinal read FMinY write FMinY;
property PixelBuffer: TBitmap read FPixelBuffer write SetPixelBuffer;
end;
TShader<T: record> = class(TShader)
public
type
PAttributeType = ^T;
class function GetRasterizer: TRasterizer; override;
class function GetAttributeBufferSize: Integer; override;
procedure VertexShader(const AWorld, AProjection: TMatrix4x4; var AVertex: TFloat4; const AVInput: TVertexShaderInput; const AAttributeBuffer: Pointer); override;
procedure Vertex(const AWorld, AProjection: TMatrix4x4; var AVertex: TFloat4; const AVInput: TVertexShaderInput; const AAttributeBuffer: PAttributeType); virtual;
procedure Fragment(const APixel: PRGB32; const PSInput: PAttributeType); virtual; abstract;
end;
TShaderClass = class of TShader;
function PointF(X, Y: Single): TPointF;
implementation
uses
Mundus.Rasterizer;
function PointF(X, Y: Single): TPointF;
begin
Result.X := X;
Result.Y := Y;
end;
{ TShader }
procedure TShader.BindBuffer(const ABuffer: PValueBuffers);
begin
end;
constructor TShader.Create();
begin
inherited;
end;
procedure TShader.SetPixelBuffer(const Value: TBitmap);
begin
FPixelBuffer := Value;
if Assigned(FPixelBuffer) then
begin
FFirstLine := FPixelBuffer.ScanLine[0];
FLineLength := (LongInt(FPixelBuffer.Scanline[1]) - LongInt(FFirstLine)) div SizeOf(TRGB32);
end;
end;
{ TSHader<T> }
class function TShader<T>.GetAttributeBufferSize: Integer;
begin
Result := SizeOf(T);
end;
class function TShader<T>.GetRasterizer: TRasterizer;
begin
Result := TRasterizer(@TRasterizerFactory.RasterizeTriangle<T, TShader<T>, TNoDepth>);
end;
procedure TShader<T>.Vertex(const AWorld, AProjection: TMatrix4x4; var AVertex: TFloat4; const AVInput: TVertexShaderInput; const AAttributeBuffer: PAttributeType);
begin
AVertex := AProjection.Transform(AVertex);
end;
procedure TShader<T>.VertexShader(const AWorld, AProjection: TMatrix4x4; var AVertex: TFloat4; const AVInput: TVertexShaderInput; const AAttributeBuffer: Pointer);
begin
Vertex(AWorld, AProjection, AVertex, AVInput, AAttributeBuffer);
end;
end.