Cool, it works perfectly now, i also implemented callback for adding new vertices, so self intresecting polygons work now! (tested! ) so make use of this code as much as you need, i'm posting this so that google bots find it and if anybody has problems with this it is here to help
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, opengl;
type
DVector = packed record
x, y, z: double;
end;
PDVector = ^DVector;
Tweight = array[0..3] of single;
Tvertexdata = array[0..3] of longword;
TForm1 = class(TForm)
BitBtn1: TBitBtn;
output: TMemo;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
poly: array of DVector;
const
GLU_TESS_VERTEX_DATA = 100107;
GLU_TESS_BEGIN_DATA = 100106;
GLU_TESS_EDGE_FLAG_DATA = 100110;
GLU_TESS_COMBINE_DATA = 100111;
procedure gluTessBeginPolygon( tess: GLUtesselator; gon_data: Pointer ); stdcall; external glu32;
implementation
{$R *.DFM}
procedure TForm1.BitBtn1Click(Sender: TObject);
var
tess: GLUtesselator;
i: integer;
procedure tessError(errno : GLEnum); stdcall;
begin
showmessage('error, ERROR! ' + inttostr(errno));
end;
procedure ElementBegin (mode: GLenum); stdcall;
begin
unit1.Form1.output.lines.add('BEGIN ' + inttostr(mode));
end;
procedure ElementEnd; stdcall;
begin
unit1.Form1.output.lines.add('END');
end;
Procedure PrimitiveCombine (coords: PDVector; vertex_data: pointer; weight: pointer; var outData: pointer; UserData: Pointer); stdcall;
begin
setlength(poly, length(poly)+1);
move(coords^, poly[length(poly)-1].x, sizeof(dvector));
outData:= @poly[length(poly)-1].x;
end;
Procedure EdgeFlagNull(flag: glboolean; lpContext: pointer); stdcall;
begin
end;
procedure ElementPrimitiveV2(vertexData : Pointer; polygonData : Pointer); stdcall;
var
pv: DVector;
begin
move(vertexData^, pv, sizeof(dvector));
unit1.Form1.
output.lines.add(
format('%f %f %f', [
pv.x,
pv.y,
pv.z])
);
end;
begin
tess:= gluNewTess;
gluTessCallback(tess, GLU_TESS_BEGIN, @ElementBegin);
gluTessCallback(tess, GLU_TESS_VERTEX_DATA, @ElementPrimitiveV2);
//gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, @EdgeFlagNull); // uncomment and you'll get only GL_TRIANGLES!
gluTessCallback(tess, GLU_TESS_COMBINE_DATA, @PrimitiveCombine);
gluTessCallback(tess, GLU_TESS_END, @ElementEnd);
gluTessCallback(tess, GLU_TESS_ERROR, @tessError);
gluTessBeginPolygon(tess, nil);
gluTessBeginContour(tess);
setlength(poly, 4);
poly[0].x:= 0;
poly[0].y:= 0;
poly[0].z:= 0;
poly[1].x:= 1;
poly[1].y:= 0; // set to 1 to test self intresecting polygons
poly[1].z:= 0;
poly[2].x:= 1;
poly[2].y:= 1; // set to 0 to test self intresecting polygons
poly[2].z:= 0;
poly[3].x:= 0;
poly[3].y:= 1;
poly[3].z:= 0;
for i:= 0 to high(poly) do begin
gluTessVertex(tess, @poly[i].x, @poly[i].x);
end;
gluTessEndContour(tess);
gluTessEndPolygon(tess);
gluDeleteTess(tess);
end;
end.
Bookmarks