LZScene

Форк
0
/
GLGLUTesselation.pas 
168 строк · 4.6 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
    Code to generate triangle strips and fans for polygons.
6

7
  History :  
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
15

16
    
17

18
  License: 
19

20
    Contributed to GLScene.
21
}
22
unit GLGLUTesselation;
23

24
interface
25

26
{$I GLScene.inc}
27

28
uses
29
  GLVectorFileObjects,
30
  GLVectorLists,
31
  GLVectorGeometry;
32

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);
35

36
implementation
37

38
uses
39
  SysUtils,
40
  OpenGLAdapter,
41
  OpenGLTokens,
42
  GLVectorTypes;
43

44
var
45
  TessMesh: TGLMeshObject;
46
  TessFace: TFGIndexTexCoordList;
47
  TessExtraVertices: Integer;
48
  TessVertices: PAffineVectorArray;
49

50
procedure DoTessBegin(mode: TGLEnum);
51
{$IFDEF Win32} stdcall;
52
{$ENDIF}{$IFDEF UNIX} cdecl;
53
{$ENDIF}
54
begin
55
  TessFace := TFGIndexTexCoordList.CreateOwned(TessMesh.FaceGroups);
56
  case mode of
57
    GL_TRIANGLES: TessFace.Mode := fgmmTriangles;
58
    GL_TRIANGLE_STRIP: TessFace.Mode := fgmmTriangleStrip;
59
    GL_TRIANGLE_FAN: TessFace.Mode := fgmmTriangleFan;
60
  end;
61
end;
62

63
procedure DoTessVertex3fv(v: PAffineVector);
64
{$IFDEF Win32} stdcall;
65
{$ENDIF}{$IFDEF UNIX} cdecl;
66
{$ENDIF}
67
begin
68
  TessFace.Add(TessMesh.Vertices.Add(v^), 0, 0);
69
end;
70

71
procedure DoTessEnd;
72
{$IFDEF Win32} stdcall;
73
{$ENDIF}{$IFDEF UNIX} cdecl;
74
{$ENDIF}
75
begin
76
end;
77

78
procedure DoTessError(errno: TGLEnum);
79
{$IFDEF Win32} stdcall;
80
{$ENDIF}{$IFDEF UNIX} cdecl;
81
{$ENDIF}
82
begin
83
  Assert(False, IntToStr(errno) + ': ' + string(gluErrorString(errno)));
84
end;
85

86
function AllocNewVertex: PAffineVector;
87
begin
88
  Inc(TessExtraVertices);
89
  Result := @TessVertices[TessExtraVertices - 1];
90
end;
91

92
procedure DoTessCombine(coords: PDoubleVector; vertex_data: Pointer; weight: PGLFloat; var outData: Pointer);
93
{$IFDEF Win32} stdcall;
94
{$ENDIF}{$IFDEF UNIX} cdecl;
95
{$ENDIF}
96
begin
97
  outData := AllocNewVertex;
98
  SetVector(PAffineVector(outData)^, coords[0], coords[1], coords[2]);
99
end;
100

101
procedure DoTesselate(Vertexes: TAffineVectorList; Mesh: TGLBaseMesh; normal: PAffineVector = nil; invertNormals: Boolean = False);
102
var
103
  Tess: PGLUTesselator;
104
  i: Integer;
105
  dblVector: TAffineDblVector;
106
begin
107
  // Select or Create FaceGroup
108
  if Mesh.MeshObjects.Count = 0 then
109
  begin
110
    TessMesh := TGLMeshObject.CreateOwned(Mesh.MeshObjects);
111
    Mesh.MeshObjects[0].Mode := momFaceGroups;
112
  end
113
  else
114
    TessMesh := Mesh.MeshObjects[0];
115

116
  // allocate extra buffer used by GLU in complex polygons.
117
  GetMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));
118

119
  // make a Tessellation GLU object.
120
  Tess := gluNewTess;
121

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);
128

129
  if Assigned(normal) then
130
    gluTessNormal(tess, normal^.V[0], normal^.V[1], normal^.V[2])
131
  else
132
    gluTessNormal(tess, 0, 1, 0);
133

134
  // start tesselation of polygon
135
  gluTessBeginPolygon(tess, nil);
136

137
  // build outline, a polygon can have multiple outlines.
138
  gluTessBeginContour(tess);
139
  TessExtraVertices := 0;
140
  if invertNormals then
141
  begin
142
    for i := Vertexes.Count - 1 downto 0 do
143
    begin
144
      SetVector(dblVector, Vertexes.Items[i]);
145
      gluTessVertex(tess, dblVector, Vertexes.ItemAddress[i]);
146
    end;
147
  end
148
  else
149
  begin
150
    for i := 0 to Vertexes.Count - 1 do
151
    begin
152
      SetVector(dblVector, Vertexes.Items[i]);
153
      gluTessVertex(tess, dblVector, Vertexes.ItemAddress[i]);
154
    end;
155
  end;
156
  gluTessEndContour(tess);
157

158
  // End Tesselation of polygon, THIS is where the data is processed! (And all the events triggered!)
159
  gluTessEndPolygon(tess);
160

161
  // Destroy the Tessellation GLU object.
162
  gluDeleteTess(tess);
163

164
  // deallocate extra buffer used by GLU in complex polygons.
165
  FreeMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));
166
end;
167

168
end.
169

170

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.