|
@@ -1,12 +1,11 @@
|
|
//
|
|
//
|
|
// This unit is part of the GLScene Engine, http://glscene.org
|
|
// This unit is part of the GLScene Engine, http://glscene.org
|
|
//
|
|
//
|
|
-{
|
|
|
|
- Class for managing a ROAM (square) patch.
|
|
|
|
-}
|
|
|
|
|
|
|
|
unit GLROAMPatch;
|
|
unit GLROAMPatch;
|
|
|
|
|
|
|
|
+(* Class for managing a ROAM (square) patch *)
|
|
|
|
+
|
|
interface
|
|
interface
|
|
|
|
|
|
{$I GLScene.inc}
|
|
{$I GLScene.inc}
|
|
@@ -21,7 +20,8 @@ uses
|
|
GLVectorLists,
|
|
GLVectorLists,
|
|
GLContext,
|
|
GLContext,
|
|
GLVectorTypes,
|
|
GLVectorTypes,
|
|
- GLIsolines;
|
|
|
|
|
|
+ GLIsolines,
|
|
|
|
+ GLS.Strings;
|
|
|
|
|
|
type
|
|
type
|
|
|
|
|
|
@@ -29,7 +29,6 @@ type
|
|
EGLROAMException = class(Exception);
|
|
EGLROAMException = class(Exception);
|
|
|
|
|
|
PROAMTriangleNode = ^TROAMTriangleNode;
|
|
PROAMTriangleNode = ^TROAMTriangleNode;
|
|
-
|
|
|
|
TROAMTriangleNode = packed record
|
|
TROAMTriangleNode = packed record
|
|
Base, Left, Right: PROAMTriangleNode;
|
|
Base, Left, Right: PROAMTriangleNode;
|
|
LeftChild, RightChild: PROAMTriangleNode;
|
|
LeftChild, RightChild: PROAMTriangleNode;
|
|
@@ -45,7 +44,7 @@ type
|
|
FID: Integer;
|
|
FID: Integer;
|
|
FHeightData: TGLHeightData; // Referred, not owned
|
|
FHeightData: TGLHeightData; // Referred, not owned
|
|
FHeightRaster: PSmallIntRaster;
|
|
FHeightRaster: PSmallIntRaster;
|
|
- FTLNode, FBRNode: Integer;
|
|
|
|
|
|
+ FTLNode, FBRNode: PROAMTriangleNode;
|
|
FTLVariance, FBRVariance: array of cardinal;
|
|
FTLVariance, FBRVariance: array of cardinal;
|
|
FPatchSize, FTriangleCount: Integer;
|
|
FPatchSize, FTriangleCount: Integer;
|
|
FListHandle: TGLListHandle;
|
|
FListHandle: TGLListHandle;
|
|
@@ -76,31 +75,29 @@ type
|
|
procedure ResetTessellation;
|
|
procedure ResetTessellation;
|
|
procedure ConnectToTheWest(WestPatch: TGLROAMPatch);
|
|
procedure ConnectToTheWest(WestPatch: TGLROAMPatch);
|
|
procedure ConnectToTheNorth(NorthPatch: TGLROAMPatch);
|
|
procedure ConnectToTheNorth(NorthPatch: TGLROAMPatch);
|
|
- // Returns false if MaxCLODTriangles limit is reached(Lin)
|
|
|
|
|
|
+ // Returns false if MaxCLODTriangles limit is reached
|
|
function Tesselate: Boolean;
|
|
function Tesselate: Boolean;
|
|
- { AV free version of Tesselate.
|
|
|
|
|
|
+ (* AV free version of Tesselate.
|
|
When IncreaseTrianglesCapacity is called, all PROAMTriangleNode
|
|
When IncreaseTrianglesCapacity is called, all PROAMTriangleNode
|
|
values in higher function became invalid due to the memory shifting.
|
|
values in higher function became invalid due to the memory shifting.
|
|
Recursivity is the main problem, that's why SafeTesselate is calling
|
|
Recursivity is the main problem, that's why SafeTesselate is calling
|
|
- Tesselate in a try..except . }
|
|
|
|
|
|
+ Tesselate in a try..except . *)
|
|
function SafeTesselate: Boolean;
|
|
function SafeTesselate: Boolean;
|
|
- { Render the patch in high-resolution.
|
|
|
|
|
|
+ (* Render the patch in high-resolution.
|
|
The lists are assumed to have enough capacity to allow AddNC calls
|
|
The lists are assumed to have enough capacity to allow AddNC calls
|
|
(additions without capacity check). High-resolution renders use
|
|
(additions without capacity check). High-resolution renders use
|
|
- display lists, and are assumed to be made together. }
|
|
|
|
|
|
+ display lists, and are assumed to be made together. *)
|
|
procedure RenderHighRes(Vertices: TAffineVectorList;
|
|
procedure RenderHighRes(Vertices: TAffineVectorList;
|
|
- VertexIndices: TIntegerList; TexCoords: TTexPointList;
|
|
|
|
- ForceROAM: Boolean);
|
|
|
|
- { Render the patch by accumulating triangles.
|
|
|
|
|
|
+ VertexIndices: TIntegerList; TexCoords: TTexPointList; ForceROAM: Boolean);
|
|
|
|
+ (* Render the patch by accumulating triangles.
|
|
The lists are assumed to have enough capacity to allow AddNC calls
|
|
The lists are assumed to have enough capacity to allow AddNC calls
|
|
(additions without capacity check).
|
|
(additions without capacity check).
|
|
Once at least autoFlushVertexCount vertices have been accumulated,
|
|
Once at least autoFlushVertexCount vertices have been accumulated,
|
|
- perform a FlushAccum }
|
|
|
|
|
|
+ perform a FlushAccum *)
|
|
procedure RenderAccum(Vertices: TAffineVectorList;
|
|
procedure RenderAccum(Vertices: TAffineVectorList;
|
|
VertexIndices: TIntegerList; TexCoords: TTexPointList;
|
|
VertexIndices: TIntegerList; TexCoords: TTexPointList;
|
|
AutoFlushVertexCount: Integer);
|
|
AutoFlushVertexCount: Integer);
|
|
- { Render all vertices accumulated in the arrays and set their count
|
|
|
|
- back to zero. }
|
|
|
|
|
|
+ // Render all vertices accumulated in the arrays and set their count back to zero.
|
|
class procedure FlushAccum(Vertices: TAffineVectorList;
|
|
class procedure FlushAccum(Vertices: TAffineVectorList;
|
|
VertexIndices: TIntegerList; TexCoords: TTexPointList);
|
|
VertexIndices: TIntegerList; TexCoords: TTexPointList);
|
|
property HeightData: TGLHeightData read FHeightData write SetHeightData;
|
|
property HeightData: TGLHeightData read FHeightData write SetHeightData;
|
|
@@ -110,29 +107,27 @@ type
|
|
property TextureScale: TAffineVector read FTextureScale write FTextureScale;
|
|
property TextureScale: TAffineVector read FTextureScale write FTextureScale;
|
|
property TextureOffset: TAffineVector read FTextureOffset write FTextureOffset;
|
|
property TextureOffset: TAffineVector read FTextureOffset write FTextureOffset;
|
|
property HighRes: Boolean read FHighRes write FHighRes;
|
|
property HighRes: Boolean read FHighRes write FHighRes;
|
|
- { Number of frames to skip after an occlusion test returned zero pixels. }
|
|
|
|
|
|
+ // Number of frames to skip after an occlusion test returned zero pixels.
|
|
property OcclusionSkip: Integer read FOcclusionSkip write SetOcclusionSkip;
|
|
property OcclusionSkip: Integer read FOcclusionSkip write SetOcclusionSkip;
|
|
- { Number of frames remaining to next occlusion test. }
|
|
|
|
|
|
+ // Number of frames remaining to next occlusion test.
|
|
property OcclusionCounter: Integer read FOcclusionCounter write FOcclusionCounter;
|
|
property OcclusionCounter: Integer read FOcclusionCounter write FOcclusionCounter;
|
|
- { Result for the last occlusion test.
|
|
|
|
|
|
+ (* Result for the last occlusion test.
|
|
Note that this value is updated upon rendering the tile in
|
|
Note that this value is updated upon rendering the tile in
|
|
- non-high-res mode only. }
|
|
|
|
|
|
+ non-high-res mode only. *)
|
|
property LastOcclusionTestPassed: Boolean read FLastOcclusionTestPassed;
|
|
property LastOcclusionTestPassed: Boolean read FLastOcclusionTestPassed;
|
|
property ID: Integer read FID;
|
|
property ID: Integer read FID;
|
|
property TriangleCount: Integer read FTriangleCount;
|
|
property TriangleCount: Integer read FTriangleCount;
|
|
property Tag: Integer read FTag write FTag;
|
|
property Tag: Integer read FTag write FTag;
|
|
- { Distance between contours - zero (default) for no contours }
|
|
|
|
- property ContourInterval: Integer read FContourInterval
|
|
|
|
- write FContourInterval default 0;
|
|
|
|
- { Width of Isolines }
|
|
|
|
- property ContourWidth: Integer read FContourWidth
|
|
|
|
- write FContourWidth default 1;
|
|
|
|
|
|
+ // Distance between contours - zero (default) for no contours
|
|
|
|
+ property ContourInterval: Integer read FContourInterval write FContourInterval default 0;
|
|
|
|
+ // Width of contours
|
|
|
|
+ property ContourWidth: Integer read FContourWidth write FContourWidth default 1;
|
|
end;
|
|
end;
|
|
|
|
|
|
-{ Specifies the maximum number of ROAM triangles that may be allocated. }
|
|
|
|
|
|
+// Specifies the maximum number of ROAM triangles that may be allocated.
|
|
procedure SetROAMTrianglesCapacity(nb: Integer);
|
|
procedure SetROAMTrianglesCapacity(nb: Integer);
|
|
function GetROAMTrianglesCapacity: Integer;
|
|
function GetROAMTrianglesCapacity: Integer;
|
|
-{ Draw contours on rendering terrain patches }
|
|
|
|
|
|
+// Draw contours on rendering terrain patches
|
|
procedure DrawContours(Vertices: TAffineVectorList; VertexIndices: TIntegerList;
|
|
procedure DrawContours(Vertices: TAffineVectorList; VertexIndices: TIntegerList;
|
|
ContourInterval: Integer; ContourWidth: Integer; DecVal: Integer);
|
|
ContourInterval: Integer; ContourWidth: Integer; DecVal: Integer);
|
|
|
|
|
|
@@ -153,8 +148,8 @@ var
|
|
RenderVertices: TAffineVectorList;
|
|
RenderVertices: TAffineVectorList;
|
|
RenderTexCoords: TTexPointList;
|
|
RenderTexCoords: TTexPointList;
|
|
|
|
|
|
- TessMaxVariance: cardinal;
|
|
|
|
- TessMaxDepth: cardinal;
|
|
|
|
|
|
+ TessMaxVariance: Cardinal;
|
|
|
|
+ TessMaxDepth: Cardinal;
|
|
TessCurrentVariance: PIntegerArray;
|
|
TessCurrentVariance: PIntegerArray;
|
|
TessObserverPosX, TessObserverPosY: Integer;
|
|
TessObserverPosX, TessObserverPosY: Integer;
|
|
|
|
|
|
@@ -182,7 +177,7 @@ procedure DrawContours(Vertices: TAffineVectorList; VertexIndices: TIntegerList;
|
|
ContourInterval: Integer; ContourWidth: Integer; DecVal: Integer);
|
|
ContourInterval: Integer; ContourWidth: Integer; DecVal: Integer);
|
|
var
|
|
var
|
|
i: Integer;
|
|
i: Integer;
|
|
- Isolines: TAffineVectorList;
|
|
|
|
|
|
+ Contours: TAffineVectorList;
|
|
CurColor: TVector;
|
|
CurColor: TVector;
|
|
|
|
|
|
begin
|
|
begin
|
|
@@ -191,12 +186,12 @@ begin
|
|
gl.PolygonOffset(1, 1);
|
|
gl.PolygonOffset(1, 1);
|
|
gl.Enable(GL_POLYGON_OFFSET_FILL);
|
|
gl.Enable(GL_POLYGON_OFFSET_FILL);
|
|
i := VertexIndices.Count - 3;
|
|
i := VertexIndices.Count - 3;
|
|
- Isolines := TAffineVectorList.Create;
|
|
|
|
|
|
+ Contours := TAffineVectorList.Create;
|
|
while i >= 0 do
|
|
while i >= 0 do
|
|
begin
|
|
begin
|
|
TriangleElevationSegments(Vertices[VertexIndices[i]],
|
|
TriangleElevationSegments(Vertices[VertexIndices[i]],
|
|
Vertices[VertexIndices[i + 1]], Vertices[VertexIndices[i + 2]],
|
|
Vertices[VertexIndices[i + 1]], Vertices[VertexIndices[i + 2]],
|
|
- ContourInterval, Isolines);
|
|
|
|
|
|
+ ContourInterval, Contours);
|
|
Dec(i, DecVal);
|
|
Dec(i, DecVal);
|
|
end;
|
|
end;
|
|
gl.PushAttrib(GL_ENABLE_BIT or GL_CURRENT_BIT);
|
|
gl.PushAttrib(GL_ENABLE_BIT or GL_CURRENT_BIT);
|
|
@@ -205,12 +200,12 @@ begin
|
|
gl.GetFloatv(GL_CURRENT_COLOR, @CurColor);
|
|
gl.GetFloatv(GL_CURRENT_COLOR, @CurColor);
|
|
gl.Color4f(0, 0, 0, 1);
|
|
gl.Color4f(0, 0, 0, 1);
|
|
gl.Begin_(GL_LINES);
|
|
gl.Begin_(GL_LINES);
|
|
- for i := 0 to Isolines.Count - 1 do
|
|
|
|
- gl.Vertex3fv(@Isolines.List[i]);
|
|
|
|
|
|
+ for i := 0 to Contours.Count - 1 do
|
|
|
|
+ gl.Vertex3fv(@Contours.List[i]);
|
|
gl.End_;
|
|
gl.End_;
|
|
gl.Color4fv(@CurColor);
|
|
gl.Color4fv(@CurColor);
|
|
gl.PopAttrib;
|
|
gl.PopAttrib;
|
|
- Isolines.Free;
|
|
|
|
|
|
+ Contours.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -257,17 +252,17 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function AllocTriangleNode: Integer;
|
|
|
|
|
|
+function AllocTriangleNode: PROAMTriangleNode;
|
|
var
|
|
var
|
|
nilNode: PROAMTriangleNode;
|
|
nilNode: PROAMTriangleNode;
|
|
begin
|
|
begin
|
|
if vNbTris >= vTriangleNodesCapacity then
|
|
if vNbTris >= vTriangleNodesCapacity then
|
|
begin
|
|
begin
|
|
// grow by 50%
|
|
// grow by 50%
|
|
- IncreaseTrianglesCapacity(vTriangleNodesCapacity + (vTriangleNodesCapacity shr 1));
|
|
|
|
|
|
+ IncreaseTrianglesCapacity(vTriangleNodesCapacity + (vTriangleNodesCapacity shr 1));
|
|
end;
|
|
end;
|
|
- Result := vNbTris;
|
|
|
|
- with vTriangleNodes[vNbTris] do
|
|
|
|
|
|
+ Result := @vTriangleNodes[vNbTris]; ///Result := vNbTris;
|
|
|
|
+ with Result^ do
|
|
begin
|
|
begin
|
|
nilNode := nil;
|
|
nilNode := nil;
|
|
Left := nilNode;
|
|
Left := nilNode;
|
|
@@ -411,8 +406,8 @@ begin
|
|
begin
|
|
begin
|
|
if not(WestPatch.HighRes or HighRes) then
|
|
if not(WestPatch.HighRes or HighRes) then
|
|
begin
|
|
begin
|
|
- vTriangleNodes[FTLNode].Left := @vTriangleNodes[WestPatch.FBRNode];
|
|
|
|
- vTriangleNodes[WestPatch.FBRNode].Left := @vTriangleNodes[FTLNode];
|
|
|
|
|
|
+ FTLNode.left := westPatch.FBRNode;
|
|
|
|
+ westPatch.FBRNode.left := FTLNode;
|
|
end;
|
|
end;
|
|
FWest := WestPatch;
|
|
FWest := WestPatch;
|
|
WestPatch.FEast := Self;
|
|
WestPatch.FEast := Self;
|
|
@@ -425,8 +420,8 @@ begin
|
|
begin
|
|
begin
|
|
if not(NorthPatch.HighRes or HighRes) then
|
|
if not(NorthPatch.HighRes or HighRes) then
|
|
begin
|
|
begin
|
|
- vTriangleNodes[FTLNode].Right := @vTriangleNodes[NorthPatch.FBRNode];
|
|
|
|
- vTriangleNodes[NorthPatch.FBRNode].Right := @vTriangleNodes[FTLNode];
|
|
|
|
|
|
+ FTLNode.right := northPatch.FBRNode;
|
|
|
|
+ northPatch.FBRNode.right := FTLNode;
|
|
end;
|
|
end;
|
|
FNorth := NorthPatch;
|
|
FNorth := NorthPatch;
|
|
NorthPatch.FSouth := Self;
|
|
NorthPatch.FSouth := Self;
|
|
@@ -534,17 +529,21 @@ procedure TGLROAMPatch.ResetTessellation;
|
|
begin
|
|
begin
|
|
FTLNode := AllocTriangleNode;
|
|
FTLNode := AllocTriangleNode;
|
|
FBRNode := AllocTriangleNode;
|
|
FBRNode := AllocTriangleNode;
|
|
- vTriangleNodes[FTLNode].Base := @vTriangleNodes[FBRNode];
|
|
|
|
- vTriangleNodes[FBRNode].Base := @vTriangleNodes[FTLNode];
|
|
|
|
|
|
+ FTLNode.Base := FBRNode;
|
|
|
|
+ FTLNode.Left := nil;
|
|
|
|
+ FTLNode.Right := nil;
|
|
|
|
+ FBRNode.Base := FTLNode;
|
|
|
|
+ FBRNode.Left := nil;
|
|
|
|
+ FBRNode.Right := nil;
|
|
FNorth := nil;
|
|
FNorth := nil;
|
|
FSouth := nil;
|
|
FSouth := nil;
|
|
FWest := nil;
|
|
FWest := nil;
|
|
FEast := nil;
|
|
FEast := nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function RecursTessellate(tri: PROAMTriangleNode; n: cardinal;
|
|
|
|
- const Left, Right, apex: cardinal): Boolean;
|
|
|
|
// returns false if tessellation failed due to MaxCLODTriangles limit
|
|
// returns false if tessellation failed due to MaxCLODTriangles limit
|
|
|
|
+function RecursTessellate(tri: PROAMTriangleNode; n: Cardinal;
|
|
|
|
+ const Left, Right, apex: Cardinal): Boolean;
|
|
var
|
|
var
|
|
d: Integer;
|
|
d: Integer;
|
|
begin
|
|
begin
|
|
@@ -558,15 +557,14 @@ begin
|
|
n := n shl 1;
|
|
n := n shl 1;
|
|
if n < TessMaxVariance then
|
|
if n < TessMaxVariance then
|
|
begin
|
|
begin
|
|
- RecursTessellate(tri.LeftChild, n, apex, Left, d);
|
|
|
|
- Result := RecursTessellate(tri.RightChild, n + 1, Right, apex, d);
|
|
|
|
|
|
+ RecursTessellate(Tri.LeftChild, n, apex, Left, d);
|
|
|
|
+ Result := RecursTessellate(Tri.RightChild, n + 1, Right, apex, d);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TGLROAMPatch.Tesselate: Boolean;
|
|
function TGLROAMPatch.Tesselate: Boolean;
|
|
-// Returns false if MaxCLODTriangles limit is reached.
|
|
|
|
var
|
|
var
|
|
tessFrameVarianceDelta: Integer;
|
|
tessFrameVarianceDelta: Integer;
|
|
|
|
|
|
@@ -628,22 +626,22 @@ begin
|
|
|
|
|
|
if HighRes then
|
|
if HighRes then
|
|
begin
|
|
begin
|
|
- FullRightTess(@vTriangleNodes[FTLNode], 1);
|
|
|
|
- FullRightTess(@vTriangleNodes[FBRNode], 1);
|
|
|
|
- FullLeftTess(@vTriangleNodes[FBRNode], 1);
|
|
|
|
- FullLeftTess(@vTriangleNodes[FTLNode], 1);
|
|
|
|
|
|
+ FullRightTess(FTLNode, 1);
|
|
|
|
+ FullRightTess(FBRNode, 1);
|
|
|
|
+ FullLeftTess(FBRNode, 1);
|
|
|
|
+ FullLeftTess(FTLNode, 1);
|
|
tessFrameVarianceDelta := 0;
|
|
tessFrameVarianceDelta := 0;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
if Assigned(FNorth) and FNorth.HighRes then
|
|
if Assigned(FNorth) and FNorth.HighRes then
|
|
- FullRightTess(@vTriangleNodes[FTLNode], 1);
|
|
|
|
|
|
+ FullRightTess(FTLNode, 1);
|
|
if Assigned(FSouth) and FSouth.HighRes then
|
|
if Assigned(FSouth) and FSouth.HighRes then
|
|
- FullRightTess(@vTriangleNodes[FBRNode], 1);
|
|
|
|
|
|
+ FullRightTess(FBRNode, 1);
|
|
if Assigned(FEast) and FEast.HighRes then
|
|
if Assigned(FEast) and FEast.HighRes then
|
|
- FullLeftTess(@vTriangleNodes[FBRNode], 1);
|
|
|
|
|
|
+ FullLeftTess(FBRNode, 1);
|
|
if Assigned(FWest) and FWest.HighRes then
|
|
if Assigned(FWest) and FWest.HighRes then
|
|
- FullLeftTess(@vTriangleNodes[FTLNode], 1);
|
|
|
|
|
|
+ FullLeftTess(FTLNode, 1);
|
|
if FObserverPosition.Z > 0 then
|
|
if FObserverPosition.Z > 0 then
|
|
tessFrameVarianceDelta := Round(Sqr(FObserverPosition.Z * (1 / 16)))
|
|
tessFrameVarianceDelta := Round(Sqr(FObserverPosition.Z * (1 / 16)))
|
|
else
|
|
else
|
|
@@ -652,13 +650,11 @@ begin
|
|
s := FPatchSize;
|
|
s := FPatchSize;
|
|
TessCurrentVariance := @FTLVariance[0];
|
|
TessCurrentVariance := @FTLVariance[0];
|
|
TessMaxVariance := FMaxTLVarianceDepth;
|
|
TessMaxVariance := FMaxTLVarianceDepth;
|
|
- Result := RecursTessellate(@vTriangleNodes[FTLNode], 1, VertexDist(0, s),
|
|
|
|
- VertexDist(s, 0), VertexDist(0, 0));
|
|
|
|
|
|
+ Result := RecursTessellate(FTLNode, 1, VertexDist(0, s), VertexDist(s, 0), VertexDist(0, 0));
|
|
TessCurrentVariance := @FBRVariance[0];
|
|
TessCurrentVariance := @FBRVariance[0];
|
|
TessMaxVariance := FMaxBRVarianceDepth;
|
|
TessMaxVariance := FMaxBRVarianceDepth;
|
|
if Result then
|
|
if Result then
|
|
- Result := RecursTessellate(@vTriangleNodes[FBRNode], 1, VertexDist(s, 0),
|
|
|
|
- VertexDist(0, s), VertexDist(s, s));
|
|
|
|
|
|
+ Result := RecursTessellate(FBRNode, 1, VertexDist(s, 0), VertexDist(0, s), VertexDist(s, s));
|
|
end;
|
|
end;
|
|
|
|
|
|
function TGLROAMPatch.SafeTesselate: Boolean;
|
|
function TGLROAMPatch.SafeTesselate: Boolean;
|
|
@@ -669,7 +665,6 @@ begin
|
|
Fail := True;
|
|
Fail := True;
|
|
repeat
|
|
repeat
|
|
try
|
|
try
|
|
- // ResetTessellation; // <- caused gaps between tiles
|
|
|
|
Result := Tesselate;
|
|
Result := Tesselate;
|
|
Fail := False;
|
|
Fail := False;
|
|
except
|
|
except
|
|
@@ -695,6 +690,7 @@ begin
|
|
// either use brute-force strips or a high-res static tesselation
|
|
// either use brute-force strips or a high-res static tesselation
|
|
if ForceROAM then
|
|
if ForceROAM then
|
|
begin
|
|
begin
|
|
|
|
+ ResetTessellation;
|
|
SafeTesselate;
|
|
SafeTesselate;
|
|
RenderROAM(Vertices, VertexIndices, TexCoords);
|
|
RenderROAM(Vertices, VertexIndices, TexCoords);
|
|
Primitive := GL_TRIANGLES;
|
|
Primitive := GL_TRIANGLES;
|
|
@@ -716,8 +712,7 @@ begin
|
|
|
|
|
|
FListHandle.AllocateHandle;
|
|
FListHandle.AllocateHandle;
|
|
gl.NewList(FListHandle.Handle, GL_COMPILE);
|
|
gl.NewList(FListHandle.Handle, GL_COMPILE);
|
|
- gl.DrawElements(Primitive, VertexIndices.Count, GL_UNSIGNED_INT,
|
|
|
|
- VertexIndices.List);
|
|
|
|
|
|
+ gl.DrawElements(Primitive, VertexIndices.Count, GL_UNSIGNED_INT, VertexIndices.List);
|
|
gl.EndList;
|
|
gl.EndList;
|
|
|
|
|
|
DrawContours(Vertices, VertexIndices, FContourInterval, FContourWidth, 1);
|
|
DrawContours(Vertices, VertexIndices, FContourInterval, FContourWidth, 1);
|
|
@@ -745,8 +740,7 @@ begin
|
|
FOcclusionQuery.AllocateHandle;
|
|
FOcclusionQuery.AllocateHandle;
|
|
FOcclusionCounter := -(ID mod (FOcclusionSkip));
|
|
FOcclusionCounter := -(ID mod (FOcclusionSkip));
|
|
end;
|
|
end;
|
|
- OcclusionPassed := (FOcclusionCounter <= 0) or
|
|
|
|
- (FOcclusionQuery.PixelCount > 0);
|
|
|
|
|
|
+ OcclusionPassed := (FOcclusionCounter <= 0) or (FOcclusionQuery.PixelCount > 0);
|
|
Dec(FOcclusionCounter);
|
|
Dec(FOcclusionCounter);
|
|
if OcclusionPassed then
|
|
if OcclusionPassed then
|
|
begin
|
|
begin
|
|
@@ -768,7 +762,6 @@ begin
|
|
Vertices.Translate(VertexOffset, n, nb);
|
|
Vertices.Translate(VertexOffset, n, nb);
|
|
TexCoords.ScaleAndTranslate(PTexPoint(@TextureScale)^,
|
|
TexCoords.ScaleAndTranslate(PTexPoint(@TextureScale)^,
|
|
PTexPoint(@TextureOffset)^, n, nb);
|
|
PTexPoint(@TextureOffset)^, n, nb);
|
|
-
|
|
|
|
DrawContours(Vertices, VertexIndices, FContourInterval, FContourWidth, 3);
|
|
DrawContours(Vertices, VertexIndices, FContourInterval, FContourWidth, 3);
|
|
if FOcclusionQuery.Active then
|
|
if FOcclusionQuery.Active then
|
|
begin
|
|
begin
|
|
@@ -822,26 +815,25 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure RecursRender(const tri: PROAMTriangleNode;
|
|
procedure RecursRender(const tri: PROAMTriangleNode;
|
|
- const Left, Right, apex: TROAMRenderPoint);
|
|
|
|
|
|
+ const Left, Right, Apex: TROAMRenderPoint);
|
|
var
|
|
var
|
|
- half: TROAMRenderPoint;
|
|
|
|
|
|
+ Half: TROAMRenderPoint;
|
|
LocalIndices: PIntegerArray;
|
|
LocalIndices: PIntegerArray;
|
|
begin
|
|
begin
|
|
if Assigned(tri.LeftChild) then
|
|
if Assigned(tri.LeftChild) then
|
|
begin // = if node is split
|
|
begin // = if node is split
|
|
- half.X := (Left.X + Right.X) shr 1;
|
|
|
|
- half.Y := (Left.Y + Right.Y) shr 1;
|
|
|
|
-
|
|
|
|
|
|
+ Half.X := (Left.X + Right.X) shr 1;
|
|
|
|
+ Half.Y := (Left.Y + Right.Y) shr 1;
|
|
RenderTexCoords.AddNC(@half.X);
|
|
RenderTexCoords.AddNC(@half.X);
|
|
- half.Idx := RenderVertices.AddNC(@half.X, RenderRaster[half.Y][half.X]);
|
|
|
|
- RecursRender(tri.LeftChild, apex, Left, half);
|
|
|
|
- RecursRender(tri.RightChild, Right, apex, half);
|
|
|
|
|
|
+ Half.Idx := RenderVertices.AddNC(@half.X, RenderRaster[half.Y][half.X]);
|
|
|
|
+ RecursRender(Tri.LeftChild, Apex, Left, Half);
|
|
|
|
+ RecursRender(Tri.RightChild, Right, Apex, Half);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
LocalIndices := RenderIndices;
|
|
LocalIndices := RenderIndices;
|
|
LocalIndices[0] := Left.Idx;
|
|
LocalIndices[0] := Left.Idx;
|
|
- LocalIndices[1] := apex.Idx;
|
|
|
|
|
|
+ LocalIndices[1] := Apex.Idx;
|
|
LocalIndices[2] := Right.Idx;
|
|
LocalIndices[2] := Right.Idx;
|
|
RenderIndices := PIntegerArray(@LocalIndices[3]);
|
|
RenderIndices := PIntegerArray(@LocalIndices[3]);
|
|
end;
|
|
end;
|
|
@@ -875,11 +867,10 @@ begin
|
|
ROAMRenderPoint(rbl, 0, FPatchSize);
|
|
ROAMRenderPoint(rbl, 0, FPatchSize);
|
|
ROAMRenderPoint(rbr, FPatchSize, FPatchSize);
|
|
ROAMRenderPoint(rbr, FPatchSize, FPatchSize);
|
|
|
|
|
|
- RecursRender(@vTriangleNodes[FTLNode], rbl, rtr, rtl);
|
|
|
|
- RecursRender(@vTriangleNodes[FBRNode], rtr, rbl, rbr);
|
|
|
|
|
|
+ RecursRender(FTLNode, rbl, rtr, rtl);
|
|
|
|
+ RecursRender(FBRNode, rtr, rbl, rbr);
|
|
|
|
|
|
- VertexIndices.Count := (Cardinal(RenderIndices) - Cardinal(VertexIndices.List))
|
|
|
|
- div SizeOf(Integer);
|
|
|
|
|
|
+ VertexIndices.Count := (Cardinal(RenderIndices) - Cardinal(VertexIndices.List)) div SizeOf(Integer);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TGLROAMPatch.RenderAsStrips(Vertices: TAffineVectorList;
|
|
procedure TGLROAMPatch.RenderAsStrips(Vertices: TAffineVectorList;
|
|
@@ -962,7 +953,9 @@ FVBOVertHandle := TGLVBOArrayBufferHandle.Create;
|
|
FVBOTexHandle := TGLVBOArrayBufferHandle.Create;
|
|
FVBOTexHandle := TGLVBOArrayBufferHandle.Create;
|
|
FVBOIndicesHandle := TGLVBOElementArrayHandle.Create;
|
|
FVBOIndicesHandle := TGLVBOElementArrayHandle.Create;
|
|
|
|
|
|
|
|
+//---------------------------------------
|
|
finalization
|
|
finalization
|
|
|
|
+//---------------------------------------
|
|
|
|
|
|
FVBOVertHandle.Free;
|
|
FVBOVertHandle.Free;
|
|
FVBOTexHandle.Free;
|
|
FVBOTexHandle.Free;
|