-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathApus.Engine.Types.pas
More file actions
204 lines (177 loc) · 6.9 KB
/
Apus.Engine.Types.pas
File metadata and controls
204 lines (177 loc) · 6.9 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// This is the lowest level unit of the Apus Game Engine.
// It should not use any other Engine's units.
//
unit Apus.Engine.Types;
interface
uses Types, Apus.Core, Apus.Geom2D, Apus.Geom3D,
Apus.Colors, Apus.VertexLayout;
type
// 2D geometry
TVec2d = Apus.Geom2D.TVec2d;
PVec2d = Apus.Geom2D.PVec2d;
TVec2 = Apus.Geom2D.TVec2;
PVec2 = Apus.Geom2D.PVec2;
TVec2Array = Apus.Geom2D.TVec2Array;
TRect2 = Apus.Geom2D.TRect2;
PRect2 = Apus.Geom2D.PRect2;
TMat2d = Apus.Geom2D.TMat2d;
TMat32d = Apus.Geom2D.TMat32d;
TMat32 = Apus.Geom2D.TMat32;
// 3D geometry
TVec3d = Apus.Geom3D.TVec3d;
PVec3d = Apus.Geom3D.PVec3d;
TVec3 = Apus.Geom3D.TVec3;
PVec3 = Apus.Geom3D.PVec3;
TVec3Array = Apus.Geom3D.TVec3Array;
TVec4d = Apus.Geom3D.TVec4d;
TVec4 = Apus.Geom3D.TVec4;
PVec4 = Apus.Geom3D.PVec4;
TQuatd = Apus.Geom3D.TQuatd;
TQuat = Apus.Geom3D.TQuat;
TMat3d = Apus.Geom3D.TMat3d;
TMat3 = Apus.Geom3D.TMat3;
PMat3 = Apus.Geom3D.PMat3;
TMat34d = Apus.Geom3D.TMat34d;
TMat34 = Apus.Geom3D.TMat34;
PMat34 = Apus.Geom3D.PMat34;
TMat4d = Apus.Geom3D.TMat4d;
TMat4 = Apus.Geom3D.TMat4;
PMat4 = Apus.Geom3D.PMat4;
TPlane = Apus.Geom3D.TPlane;
TAsyncProc = function(param:UIntPtr):integer;
TVertexComponent = Apus.VertexLayout.TVertexComponent;
TVertexLayout = Apus.VertexLayout.TVertexLayout;
TIndices=WordArray;
TTextAlignment=(taLeft, // normal output
taCenter, // output point indicates the text center
taRight, // output point indicates the right edge
taJustify); // output point indicates the left edge, while spacing is the line width
// (falls back to left-aligned output when actual width is too small or the line ends with #10/#13)
// Display mode
TDisplayMode=(dmNone, //< not specified
dmSwitchResolution, //< Fullscreen: switch to desired display mode (change screen resolution)
dmFullScreen, //< Use current resolution with fullscreen window
dmFixedWindow, //< Use fixed-size window
dmWindow, //< Use resizeable window
dmBorderless); //< Use borderless window (non-fullscreen), app should manually resize it if needed
// How the rendered image should appear in the output window (display)
TDisplayFitMode=(dfmCenter, //< image is centered in the output window rect (1:1) (DisplayScaleMode is ignored)
dfmFullSize, //< image is stretched to fill the whole output window
dfmKeepAspectRatio); //< image is stretched to fill the output window while keeping it's original aspect ratio (black padding)
// How rendering is processed if the backbuffer size doesn't match the output area
TDisplayScaleMode=(dsmDontScale, //< Backbuffer size is updated to match the output area
dsmStretch, //< Stretch rendered image to the output rect
dsmScale); //< Use scale transformation matrix to map render area to the output rect (scaled rendering)
// Note that scaled rendering produces error in clipping due to rounding
// Display settings
TDisplaySettings=record
displayMode:TDisplayMode;
displayFitMode:TDisplayFitMode;
displayScaleMode:TDisplayScaleMode;
end;
// Runtime display/window configuration.
TGameSettings=record
title:string; // window/program title
width,height:integer; // backbuffer size and desired output area
colorDepth:integer; // requested backbuffer format (16/24/32)
refresh:integer; // display refresh rate (0 - default)
vSync:integer; // 0 - max FPS, N - FPS = refresh/N
mode,altMode:TDisplaySettings; // primary and alternate display mode (Alt+Enter)
showSystemCursor:boolean; // draw system cursor instead of engine cursor
zbuffer:byte; // desired precision for a depth buffer (0 - don't use depth buffer)
stencil:boolean; // request a stencil-buffer (at least 8-bit)
multisampling:byte; // full-screen anti-aliasing samples (<2 - disabled)
slowmotion:boolean; // hint: prefer redraw optimizations for low/unstable frame rates
end;
// Packed ARGB color
TARGBColor=Apus.Colors.TARGBColor;
PARGBColor=Apus.Colors.PARGBColor;
// Primitive types
TPrimitiveType=(
LINE_LIST,
LINE_STRIP,
TRG_FAN,
TRG_STRIP,
TRG_LIST);
TFontHandle=cardinal;
TMonoGradient=record
base,dx,dy:single;
procedure Init(v1,v2,angle,scale:single);
function ValueAt(x,y:single):single; inline;
end;
// Linear gradient
TColorGradient=record
red,green,blue,alpha:TMonoGradient;
procedure Init(color1,color2:cardinal;angle,scale:single);
function ColorAt(x,y:single):cardinal;
end;
TDisplayModeHelper = record helper for TDisplayMode
function ToString:string;
end;
TDisplayFitModeHelper = record helper for TDisplayFitMode
function ToString:string;
end;
TDisplayScaleModeHelper = record helper for TDisplayScaleMode
function ToString:string;
end;
TPointCompatHelper = record helper for TPoint
function Equals(const p:TPoint):boolean; inline;
function IsNear(x,y,radius:single):boolean; inline;
end;
implementation
uses Apus.Utils;
{$EXCESSPRECISION OFF}
// TODO: trim this unit to engine-specific types only and move Base-type re-exports
// to explicit imports or a dedicated facade, as documented in engine_work_ahead.md.
{ TGradient }
const
k255 = 1/255;
minGradientScale = 1E-6;
function TDisplayModeHelper.ToString:string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayMode),ord(self));
end;
function TDisplayFitModeHelper.ToString: string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayFitMode),ord(self));
end;
function TDisplayScaleModeHelper.ToString: string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayScaleMode),ord(self));
end;
function TPointCompatHelper.Equals(const p:TPoint):boolean;
begin
result:=(x=p.x) and (y=p.y);
end;
function TPointCompatHelper.IsNear(x,y,radius:single):boolean;
begin
result:=Sqr(self.x-x)+Sqr(self.y-y)<=sqr(radius);
end;
function TColorGradient.ColorAt(x,y:single):cardinal;
begin
result:=MyColorF(alpha.ValueAt(x,y),red.valueAt(x,y),green.ValueAt(x,y),blue.ValueAt(x,y));
end;
procedure TColorGradient.Init(color1,color2:cardinal;angle,scale:single);
begin
alpha.Init(PARGBColor(@color1).a*k255,PARGBColor(@color2).a*k255,angle,scale);
red.Init(PARGBColor(@color1).r*k255,PARGBColor(@color2).r*k255,angle,scale);
green.Init(PARGBColor(@color1).g*k255,PARGBColor(@color2).g*k255,angle,scale);
blue.Init(PARGBColor(@color1).b*k255,PARGBColor(@color2).b*k255,angle,scale);
end;
{ TMonoGradient }
procedure TMonoGradient.Init(v1,v2,angle,scale:single);
begin
base:=(v1+v2)/2;
if abs(scale)<=minGradientScale then begin
dx:=0;
dy:=0;
end else begin
dx:=(v2-v1)*cos(angle)/scale;
dy:=(v2-v1)*sin(angle)/scale;
end;
end;
function TMonoGradient.ValueAt(x,y:single):single;
begin
result:=Clamp(base+(x*2-1)*dx+(y*2-1)*dy,0,1);
end;
end.