2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Code to generate triangle strips and fans for polygons.
8
23/08/10 - Yar - Added OpenGLTokens to uses, replaced OpenGL1x functions to OpenGLAdapter
9
06/06/10 - Yar - Fixed warnings
10
26/11/09 - DaStr - Improved Lazarus compatibility (BugtrackerID = 2893580)
11
10/03/09 - DanB - DoTesselate now accepts TGLBaseMesh instead of
12
TGLFreeform, so can now use TGLActor with it too
13
29/05/08 - DaStr - Added $I GLScene.inc
14
08/09/03 - Jaj - Added single outline polygon support
20
Contributed to GLScene.
33
{ Tesselates the polygon outlined by the Vertexes. And addeds them to the first facegroup of the Mesh. }
34
procedure DoTesselate(Vertexes: TAffineVectorList; Mesh: TGLBaseMesh; normal: PAffineVector = nil; invertNormals: Boolean = False);
45
TessMesh: TGLMeshObject;
46
TessFace: TFGIndexTexCoordList;
47
TessExtraVertices: Integer;
48
TessVertices: PAffineVectorArray;
50
procedure DoTessBegin(mode: TGLEnum);
51
{$IFDEF Win32} stdcall;
52
{$ENDIF}{$IFDEF UNIX} cdecl;
55
TessFace := TFGIndexTexCoordList.CreateOwned(TessMesh.FaceGroups);
57
GL_TRIANGLES: TessFace.Mode := fgmmTriangles;
58
GL_TRIANGLE_STRIP: TessFace.Mode := fgmmTriangleStrip;
59
GL_TRIANGLE_FAN: TessFace.Mode := fgmmTriangleFan;
63
procedure DoTessVertex3fv(v: PAffineVector);
64
{$IFDEF Win32} stdcall;
65
{$ENDIF}{$IFDEF UNIX} cdecl;
68
TessFace.Add(TessMesh.Vertices.Add(v^), 0, 0);
72
{$IFDEF Win32} stdcall;
73
{$ENDIF}{$IFDEF UNIX} cdecl;
78
procedure DoTessError(errno: TGLEnum);
79
{$IFDEF Win32} stdcall;
80
{$ENDIF}{$IFDEF UNIX} cdecl;
83
Assert(False, IntToStr(errno) + ': ' + string(gluErrorString(errno)));
86
function AllocNewVertex: PAffineVector;
88
Inc(TessExtraVertices);
89
Result := @TessVertices[TessExtraVertices - 1];
92
procedure DoTessCombine(coords: PDoubleVector; vertex_data: Pointer; weight: PGLFloat; var outData: Pointer);
93
{$IFDEF Win32} stdcall;
94
{$ENDIF}{$IFDEF UNIX} cdecl;
97
outData := AllocNewVertex;
98
SetVector(PAffineVector(outData)^, coords[0], coords[1], coords[2]);
101
procedure DoTesselate(Vertexes: TAffineVectorList; Mesh: TGLBaseMesh; normal: PAffineVector = nil; invertNormals: Boolean = False);
103
Tess: PGLUTesselator;
105
dblVector: TAffineDblVector;
107
// Select or Create FaceGroup
108
if Mesh.MeshObjects.Count = 0 then
110
TessMesh := TGLMeshObject.CreateOwned(Mesh.MeshObjects);
111
Mesh.MeshObjects[0].Mode := momFaceGroups;
114
TessMesh := Mesh.MeshObjects[0];
116
// allocate extra buffer used by GLU in complex polygons.
117
GetMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));
119
// make a Tessellation GLU object.
122
// set up callback events
123
gluTessCallback(Tess, GLU_TESS_BEGIN, @DoTessBegin);
124
gluTessCallback(tess, GLU_TESS_VERTEX, @DoTessVertex3fv);
125
gluTessCallback(tess, GLU_TESS_END, @DoTessEnd);
126
gluTessCallback(tess, GLU_TESS_ERROR, @DoTessError);
127
gluTessCallback(tess, GLU_TESS_COMBINE, @DoTessCombine);
129
if Assigned(normal) then
130
gluTessNormal(tess, normal^.V[0], normal^.V[1], normal^.V[2])
132
gluTessNormal(tess, 0, 1, 0);
134
// start tesselation of polygon
135
gluTessBeginPolygon(tess, nil);
137
// build outline, a polygon can have multiple outlines.
138
gluTessBeginContour(tess);
139
TessExtraVertices := 0;
140
if invertNormals then
142
for i := Vertexes.Count - 1 downto 0 do
144
SetVector(dblVector, Vertexes.Items[i]);
145
gluTessVertex(tess, dblVector, Vertexes.ItemAddress[i]);
150
for i := 0 to Vertexes.Count - 1 do
152
SetVector(dblVector, Vertexes.Items[i]);
153
gluTessVertex(tess, dblVector, Vertexes.ItemAddress[i]);
156
gluTessEndContour(tess);
158
// End Tesselation of polygon, THIS is where the data is processed! (And all the events triggered!)
159
gluTessEndPolygon(tess);
161
// Destroy the Tessellation GLU object.
164
// deallocate extra buffer used by GLU in complex polygons.
165
FreeMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));