/usr/src/castle-game-engine-4.1.1/x3d/opengl/glrenderer_resource.inc is in castle-game-engine-src 4.1.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | {$ifdef read_interface}
{ Base class for TGLRenderer helper. Such helper is associated
with a given VRML node, and has methods like Prepare, Enable
(their exact semantics depends on descendant) and Unprepare. }
TResourceRenderer = class
private
FRenderer: TGLRenderer;
FNode: TX3DNode;
public
constructor Create(ARenderer: TGLRenderer; ANode: TX3DNode); virtual;
property Renderer: TGLRenderer read FRenderer;
{ Reference to handled VRML node.
Never @nil. }
property Node: TX3DNode read FNode;
{ Release all resources allocated by Prepare method. }
procedure Unprepare; virtual; abstract;
end;
TResourceRendererList = class(specialize TFPGObjectList<TResourceRenderer>)
private
InsideUnprepareAll: Cardinal;
public
{ Looks for item with given Node.
Returns -1 if not found. }
function NodeIndex(ANode: TX3DNode): Integer;
{ Looks for item with given Node.
Returns @nil if not found. }
function Node(ANode: TX3DNode): TResourceRenderer;
{ If resources for this Node were created (and possibly prepared),
unprepare and remove them.
Note: for complicated reasons, this is ignored if called during
UnprepareAll call on the same list. E.g. it may happen when
your TResourceRenderer calls Unprepare on it's own list from it's
own Unprepare (like TGLMultiTextureNode). Although it's ignored
in this case, you still can be sure ANode will be unprepared (as UnprepareAll
will eventually unprepare, well, all). Just be aware that effect may
be delayed in this case. }
procedure Unprepare(ANode: TX3DNode);
{ Unprepare and free and nodes. Clears the list. }
procedure UnprepareAll;
end;
{$endif read_interface}
{$ifdef read_implementation}
{ TResourceRenderer ---------------------------------------------------------- }
constructor TResourceRenderer.Create(ARenderer: TGLRenderer;
ANode: TX3DNode);
begin
inherited Create;
FRenderer := ARenderer;
FNode := ANode;
end;
{ TResourceRendererList ----------------------------------------------------- }
function TResourceRendererList.NodeIndex(ANode: TX3DNode): Integer;
begin
for Result := 0 to Count - 1 do
if Items[Result].Node = ANode then Exit;
Result := -1;
end;
function TResourceRendererList.Node(ANode: TX3DNode): TResourceRenderer;
var
I: Integer;
begin
for I := 0 to Count - 1 do
begin
Result := Items[I];
if Result.Node = ANode then Exit;
end;
Result := nil;
end;
procedure TResourceRendererList.Unprepare(ANode: TX3DNode);
var
I: integer;
begin
{ If we're already inside UnprepareAll on the same instance, prevent
Unprepare call.
This may happen if some TResourceRenderer overrides
Unprepare, and calls Unprepare *on the same list it's on* in it's own
Unprepare. For example, TGLMultiTextureNode.Unprepare unprepares also
it's own items.
In this case, the list is half-destroyed (some items freed, so invalid
pointers), so Unprepare cannot work correctly on it. Moreover, it would
actually break UnprepareAll if Unprepare would modify the list contents
(UnprepareAll loops over the list, assuming nothing else will change the
list during this time.) Solution --- simply ignore Unprepare in this case.
It's safe --- we know that all items on the list will eventually get
unprepared. }
if InsideUnprepareAll > 0 then Exit;
{ Call Unprepare and release related instance. }
I := NodeIndex(ANode);
if I >= 0 then
begin
Items[I].Unprepare;
Items[I].Free;
Delete(I);
end;
end;
procedure TResourceRendererList.UnprepareAll;
var
I: Integer;
begin
Inc(InsideUnprepareAll);
try
for I := 0 to Count - 1 do
begin
Items[I].Unprepare;
Items[I].Free;
end;
Count := 0;
finally Dec(InsideUnprepareAll) end;
end;
{$endif}
|