123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- //
- // The graphics engine GLXEngine. The unit of GXScene for Delphi
- //
- unit GXS.PolygonTesselation;
- (* Code to generate triangle strips and fans for polygons *)
- interface
- {$I Stage.Defines.inc}
- uses
- Winapi.OpenGL,
- Winapi.OpenGLext,
- System.SysUtils,
- GXS.VectorFileObjects,
- GXS.VectorLists,
- Stage.VectorGeometry,
- Stage.VectorTypes;
- (* Tesselates the polygon outlined by the Vertexes.
- And addeds them to the first facegroup of the Mesh. *)
- procedure DoTesselate(Vertexes: TgxAffineVectorList;
- Mesh: TgxBaseMesh; normal: PAffineVector = nil; invertNormals: Boolean = False);
- implementation //-------------------------------------------------------------
- var
- TessMesh: TgxMeshObject;
- TessFace: TgxFGIndexTexCoordList;
- TessExtraVertices: Integer;
- TessVertices: PAffineVectorArray;
- procedure DoTessBegin(mode: GLEnum);
- {$IFDEF MSWIDOWS} stdcall;{$ELSE} cdecl;{$ENDIF}
- begin
- TessFace := TgxFGIndexTexCoordList.CreateOwned(TessMesh.FaceGroups);
- case mode of
- GL_TRIANGLES: TessFace.Mode := fgmmTriangles;
- GL_TRIANGLE_STRIP: TessFace.Mode := fgmmTriangleStrip;
- GL_TRIANGLE_FAN: TessFace.Mode := fgmmTriangleFan;
- end;
- end;
- procedure DoTessVertex3fv(v: PAffineVector);
- {$IFDEF MSWIDOWS} stdcall;{$ELSE} cdecl;{$ENDIF}
- begin
- TessFace.Add(TessMesh.Vertices.Add(v^), 0, 0);
- end;
- procedure DoTessEnd;
- {$IFDEF MSWIDOWS} stdcall;{$ELSE} cdecl;{$ENDIF}
- begin
- //
- end;
- procedure DoTessError(errno: GLEnum);
- {$IFDEF MSWIDOWS} stdcall;{$ELSE} cdecl;{$ENDIF}
- begin
- Assert(False, IntToStr(errno) + ': ' + string(gluErrorString(errno)));
- end;
- function AllocNewVertex: PAffineVector;
- begin
- Inc(TessExtraVertices);
- Result := @TessVertices[TessExtraVertices - 1];
- end;
- procedure DoTessCombine(coords: PDoubleVector; vertex_data: Pointer; weight: PGLFloat; var outData: Pointer);
- {$IFDEF MSWIDOWS} stdcall;{$ELSE} cdecl;{$ENDIF}
- begin
- outData := AllocNewVertex;
- SetVector(PAffineVector(outData)^, coords[0], coords[1], coords[2]);
- end;
- procedure DoTesselate(Vertexes: TgxAffineVectorList; Mesh: TgxBaseMesh; normal: PAffineVector = nil; invertNormals: Boolean = False);
- var
- Tess: GLUTesselator;
- i: Integer;
- dblVector: TAffineDblVector;
- begin
- // Select or Create FaceGroup
- if Mesh.MeshObjects.Count = 0 then
- begin
- TessMesh := TgxMeshObject.CreateOwned(Mesh.MeshObjects);
- Mesh.MeshObjects[0].Mode := momFaceGroups;
- end
- else
- TessMesh := Mesh.MeshObjects[0];
- // allocate extra buffer used by GLU in complex polygons.
- GetMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));
- // make a Tessellation GLU object.
- Tess := gluNewTess;
- // set up callback events
- gluTessCallback(Tess, GLU_TESS_BEGIN, @DoTessBegin);
- gluTessCallback(tess, GLU_TESS_VERTEX, @DoTessVertex3fv);
- gluTessCallback(tess, GLU_TESS_END, @DoTessEnd);
- gluTessCallback(tess, GLU_TESS_ERROR, @DoTessError);
- gluTessCallback(tess, GLU_TESS_COMBINE, @DoTessCombine);
- if Assigned(normal) then
- gluTessNormal(tess, normal^.X, normal^.Y, normal^.Z)
- else
- gluTessNormal(tess, 0, 1, 0);
- // start tesselation of polygon
- gluTessBeginPolygon(tess, nil);
- // build outline, a polygon can have multiple outlines.
- gluTessBeginContour(tess);
- TessExtraVertices := 0;
- if invertNormals then
- begin
- for i := Vertexes.Count - 1 downto 0 do
- begin
- SetVector(dblVector, Vertexes.Items[i]);
- gluTessVertex(tess, @dblVector, Vertexes.ItemAddress[i]);
- end;
- end
- else
- begin
- for i := 0 to Vertexes.Count - 1 do
- begin
- SetVector(dblVector, Vertexes.Items[i]);
- gluTessVertex(tess, @dblVector, Vertexes.ItemAddress[i]);
- end;
- end;
- gluTessEndContour(tess);
- // End Tesselation of polygon, THIS is where the data is processed! (And all the events triggered!)
- gluTessEndPolygon(tess);
- // Destroy the Tessellation GLU object.
- gluDeleteTess(tess);
- // deallocate extra buffer used by GLU in complex polygons.
- FreeMem(TessVertices, Vertexes.Count * SizeOf(TAffineVector));
- end;
- end.
|