noeska
05-04-2008, 04:54 PM
Delphi2005
DglOpenGL
GLU
Tesselate
cpp -> delphi conversion
I am trying to tesselate a star using glu funtions. Only for one point the colors seem to be wrong. i.e. it turns out to be black.
I am trying to follow this tutorial: http://www.songho.ca/opengl/gl_tessellation.html
Thanks for your answers in advance.
unit OpenGLTemplateForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, DglOpenGL;
type
TDGLForm = class(TForm)
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TOpenGLRender = class(TThread)
private
DC:HDC;
RC:HGLRC;
angle: integer;
fHandle: cardinal;
fOptions: TRCOptions;
fPixelDepth: byte;
fDepthBuffer: byte;
public
destructor Destroy; override;
procedure Init;
procedure Draw;
procedure Stop;
procedure Execute; override;
property Handle: cardinal read fHandle write fHandle;
property Options: TRCOptions read fOptions write fOptions;
property PixelDepth: byte read fPixelDepth write fPixelDepth;
property DepthBuffer: byte read fDepthBuffer write fDepthBuffer;
end;
var
DGLForm: TDGLForm;
OpenGLRender: TOpenGLRender;
implementation
{$R *.DFM}
type
PGLarrayd3 = ^TGLArrayd3;
TGLArrayd4 = array[0..3] of GLDouble;
PGLArrayd4 = ^TGLArrayd4;
TGLArrayd6 = array[0..5] of GLDouble;
PGLArrayd6 = ^TGLArrayd6;
TGLArrayvertex4 = array[0..3] of TGLArrayd6;
PGLArrayvertex4 = ^TGLArrayvertex4;
function getNormal(p1,p2,p3:TGLArrayf3):TGLArrayf3;
var a,b:TGLArrayf3;
begin
a[0]:=p2[0]-p1[0]; a[1]:=p2[1]-p1[1]; a[2]:=p2[2]-p1[2];
b[0]:=p3[0]-p1[0]; b[1]:=p3[1]-p1[1]; b[2]:=p3[2]-p1[2];
result[0]:=a[1]*b[2]-a[2]*b[1];
result[1]:=a[2]*b[0]-a[0]*b[2];
result[2]:=a[0]*b[1]-a[1]*b[0];
end;
//TOpenGLRender
destructor TOpenGLRender.Destroy;
begin
inherited;
end;
procedure TOpenGLRender.Execute;
begin
Init;
while not terminated do
begin
Draw;
sleep(1);
end;
Stop;
end;
procedure TOpenGLRender.Init;
const
light0_position:TGLArrayf4=( -8.0, 8.0, -16.0, 0.0);
ambient: TGLArrayf4=( 0.3, 0.3, 0.3, 0.3);
begin
InitOpenGL;
DC := GetDC(fHandle);
// Create RenderContext (32 Bit PixelDepth, 24 Bit DepthBuffer, Doublebuffering)
RC := CreateRenderingContext(DC, fOptions, fPixelDepth, fDepthBuffer, 0, 0, 0, 0);
// Activate RenderContext
ActivateRenderingContext(DC, RC);
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
// position viewer
glMatrixMode(GL_MODELVIEW);
// Active DepthBuffer
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glShadeModel(GL_SMOOTH); // shading mathod: GL_SMOOTH or GL_FLAT
// track material ambient and diffuse from surface color, call it before glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
// Set lighting
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, @ambient);
glEnable(GL_LIGHT0);
// Set clear background color
glClearColor(0,0,0,0);
end;
procedure tessBeginCB(which: GLenum); stdcall;
begin
glBegin(which);
end;
procedure tessEndCB(); stdcall;
begin
glEnd();
end;
procedure tessErrorCB(errorCode: GLenum); stdcall;
var
errorStr: string;
begin
errorStr := gluErrorString(errorCode);
end;
procedure tessVertexCB(data: PGLArrayd6); stdcall;
begin
glColor3d(data[3], data[4], data[5]);
glVertex3d( data[0], data[1], data[2] );
end;
var
vertices: array[0..64] of TGLArrayd6;
vertexIndex: integer = 0;
procedure tessCombineCB(newVertex : PGLArrayd6; neighborVertex : Pointer;
neighborWeight : PGLArrayd4; var outData : Pointer); stdcall;
type
PGLArrayd3= ^TGLArrayd3;
var
vertice: PGLarrayd3;
test: pointer;
begin
vertices[vertexIndex][0] := newVertex[0];
vertices[vertexIndex][1] := newVertex[1];
vertices[vertexIndex][2] := newVertex[2];
vertices[vertexIndex][3] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][3] + // red
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][3] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][3] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][3];
vertices[vertexIndex][4] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][4] + // green
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][4] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][4] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][4];
vertices[vertexIndex][5] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][5] + // blue
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][5] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][5] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][5];
// return output data (vertex coords and others)
outData := @vertices[vertexindex];
vertexIndex := vertexIndex + 1; // increase index for next vertex
end;
procedure TOpenGLRender.Draw;
var
test: TGLArrayd3;
star: array[0..4] of TGLArrayd6;
tess: pointer;
begin
vertexindex:=0;
angle:=180;//angle+1;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -12.0);
glRotatef(angle, 0.0, 1.0, 0.0);
star[0][0] := 0.0;
star[0][1] := 3.0;
star[0][2] := 0.0;
star[0][3] := 1;
star[0][4] := 0;
star[0][5] := 0;
star[1][0] := -1.0;
star[1][1] := 0.0;
star[1][2] := 0.0;
star[1][3] := 0;
star[1][4] := 1;
star[1][5] := 0;
star[2][0] := 1.6;
star[2][1] := 1.9;
star[2][2] := 0.0;
star[2][3] := 1;
star[2][4] := 0;
star[2][5] := 1;
star[3][0] := -1.6;
star[3][1] := 1.9;
star[3][2] := 0.0;
star[3][3] := 1;
star[3][4] := 1;
star[3][5] := 0;
star[4][0] := 1.0;
star[4][1] := 0.0;
star[4][2] := 0.0;
star[4][3] := 0;
star[4][4] := 0;
star[4][5] := 1;
tess := gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, @tessBeginCB);
gluTessCallback(tess, GLU_TESS_END, @tessEndCB);
gluTessCallback(tess, GLU_TESS_ERROR, @tessErrorCB);
gluTessCallback(tess, GLU_TESS_VERTEX, @tessVertexCB);
gluTessCallback(tess, GLU_TESS_COMBINE, @tessCombineCB);
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(tess, 0); // with NULL data
gluTessBeginContour(tess);
test[0] := star[0][0];
test[1] := star[0][1];
test[2] := star[0][2];
gluTessVertex(tess, test, @star[0]);
test[0] := star[1][0];
test[1] := star[1][1];
test[2] := star[1][2];
gluTessVertex(tess, test, @star[1]);
test[0] := star[2][0];
test[1] := star[2][1];
test[2] := star[2][2];
gluTessVertex(tess, test, @star[2]);
test[0] := star[3][0];
test[1] := star[3][1];
test[2] := star[3][2];
gluTessVertex(tess, test, @star[3]);
test[0] := star[4][0];
test[1] := star[4][1];
test[2] := star[4][2];
gluTessVertex(tess, test, @star[4]);
gluTessEndContour(tess);
gluTessEndPolygon(tess);
gluDeleteTess(tess); // delete after tessellation
SwapBuffers(DC);
end;
procedure TOpenGLRender.Stop;
begin
DeactivateRenderingContext; // Deactivate RenderContext
wglDeleteContext(RC); //Delete RenderContext
ReleaseDC(Handle, DC);
end;
//TDGLForm
procedure TDGLForm.FormCreate(Sender: TObject);
begin
DecimalSeparator:='.'; //always use . as decimal seperator
OpenGLRender := TOpenGLRender.Create(true);
OpenGLRender.Handle := Handle;
OpenGLRender.Options := [opDoubleBuffered];
OpenGLRender.PixelDepth := 32;
OpenGLRender.DepthBuffer := 24;
OpenGLRender.Resume;
end;
procedure TDGLForm.FormDestroy(Sender: TObject);
begin
OpenGLRender.Suspend;
OpenGLRender.Free;
end;
procedure TDGLForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
case Key of
#27 : Close;
end;
end;
end.
DglOpenGL
GLU
Tesselate
cpp -> delphi conversion
I am trying to tesselate a star using glu funtions. Only for one point the colors seem to be wrong. i.e. it turns out to be black.
I am trying to follow this tutorial: http://www.songho.ca/opengl/gl_tessellation.html
Thanks for your answers in advance.
unit OpenGLTemplateForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, DglOpenGL;
type
TDGLForm = class(TForm)
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TOpenGLRender = class(TThread)
private
DC:HDC;
RC:HGLRC;
angle: integer;
fHandle: cardinal;
fOptions: TRCOptions;
fPixelDepth: byte;
fDepthBuffer: byte;
public
destructor Destroy; override;
procedure Init;
procedure Draw;
procedure Stop;
procedure Execute; override;
property Handle: cardinal read fHandle write fHandle;
property Options: TRCOptions read fOptions write fOptions;
property PixelDepth: byte read fPixelDepth write fPixelDepth;
property DepthBuffer: byte read fDepthBuffer write fDepthBuffer;
end;
var
DGLForm: TDGLForm;
OpenGLRender: TOpenGLRender;
implementation
{$R *.DFM}
type
PGLarrayd3 = ^TGLArrayd3;
TGLArrayd4 = array[0..3] of GLDouble;
PGLArrayd4 = ^TGLArrayd4;
TGLArrayd6 = array[0..5] of GLDouble;
PGLArrayd6 = ^TGLArrayd6;
TGLArrayvertex4 = array[0..3] of TGLArrayd6;
PGLArrayvertex4 = ^TGLArrayvertex4;
function getNormal(p1,p2,p3:TGLArrayf3):TGLArrayf3;
var a,b:TGLArrayf3;
begin
a[0]:=p2[0]-p1[0]; a[1]:=p2[1]-p1[1]; a[2]:=p2[2]-p1[2];
b[0]:=p3[0]-p1[0]; b[1]:=p3[1]-p1[1]; b[2]:=p3[2]-p1[2];
result[0]:=a[1]*b[2]-a[2]*b[1];
result[1]:=a[2]*b[0]-a[0]*b[2];
result[2]:=a[0]*b[1]-a[1]*b[0];
end;
//TOpenGLRender
destructor TOpenGLRender.Destroy;
begin
inherited;
end;
procedure TOpenGLRender.Execute;
begin
Init;
while not terminated do
begin
Draw;
sleep(1);
end;
Stop;
end;
procedure TOpenGLRender.Init;
const
light0_position:TGLArrayf4=( -8.0, 8.0, -16.0, 0.0);
ambient: TGLArrayf4=( 0.3, 0.3, 0.3, 0.3);
begin
InitOpenGL;
DC := GetDC(fHandle);
// Create RenderContext (32 Bit PixelDepth, 24 Bit DepthBuffer, Doublebuffering)
RC := CreateRenderingContext(DC, fOptions, fPixelDepth, fDepthBuffer, 0, 0, 0, 0);
// Activate RenderContext
ActivateRenderingContext(DC, RC);
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
// position viewer
glMatrixMode(GL_MODELVIEW);
// Active DepthBuffer
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glShadeModel(GL_SMOOTH); // shading mathod: GL_SMOOTH or GL_FLAT
// track material ambient and diffuse from surface color, call it before glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
// Set lighting
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, @ambient);
glEnable(GL_LIGHT0);
// Set clear background color
glClearColor(0,0,0,0);
end;
procedure tessBeginCB(which: GLenum); stdcall;
begin
glBegin(which);
end;
procedure tessEndCB(); stdcall;
begin
glEnd();
end;
procedure tessErrorCB(errorCode: GLenum); stdcall;
var
errorStr: string;
begin
errorStr := gluErrorString(errorCode);
end;
procedure tessVertexCB(data: PGLArrayd6); stdcall;
begin
glColor3d(data[3], data[4], data[5]);
glVertex3d( data[0], data[1], data[2] );
end;
var
vertices: array[0..64] of TGLArrayd6;
vertexIndex: integer = 0;
procedure tessCombineCB(newVertex : PGLArrayd6; neighborVertex : Pointer;
neighborWeight : PGLArrayd4; var outData : Pointer); stdcall;
type
PGLArrayd3= ^TGLArrayd3;
var
vertice: PGLarrayd3;
test: pointer;
begin
vertices[vertexIndex][0] := newVertex[0];
vertices[vertexIndex][1] := newVertex[1];
vertices[vertexIndex][2] := newVertex[2];
vertices[vertexIndex][3] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][3] + // red
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][3] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][3] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][3];
vertices[vertexIndex][4] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][4] + // green
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][4] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][4] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][4];
vertices[vertexIndex][5] := neighborWeight[0] * PGLArrayvertex4(neighborVertex)[0][5] + // blue
neighborWeight[1] * PGLArrayvertex4(neighborVertex)[1][5] +
neighborWeight[2] * PGLArrayvertex4(neighborVertex)[2][5] +
neighborWeight[3] * PGLArrayvertex4(neighborVertex)[3][5];
// return output data (vertex coords and others)
outData := @vertices[vertexindex];
vertexIndex := vertexIndex + 1; // increase index for next vertex
end;
procedure TOpenGLRender.Draw;
var
test: TGLArrayd3;
star: array[0..4] of TGLArrayd6;
tess: pointer;
begin
vertexindex:=0;
angle:=180;//angle+1;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -12.0);
glRotatef(angle, 0.0, 1.0, 0.0);
star[0][0] := 0.0;
star[0][1] := 3.0;
star[0][2] := 0.0;
star[0][3] := 1;
star[0][4] := 0;
star[0][5] := 0;
star[1][0] := -1.0;
star[1][1] := 0.0;
star[1][2] := 0.0;
star[1][3] := 0;
star[1][4] := 1;
star[1][5] := 0;
star[2][0] := 1.6;
star[2][1] := 1.9;
star[2][2] := 0.0;
star[2][3] := 1;
star[2][4] := 0;
star[2][5] := 1;
star[3][0] := -1.6;
star[3][1] := 1.9;
star[3][2] := 0.0;
star[3][3] := 1;
star[3][4] := 1;
star[3][5] := 0;
star[4][0] := 1.0;
star[4][1] := 0.0;
star[4][2] := 0.0;
star[4][3] := 0;
star[4][4] := 0;
star[4][5] := 1;
tess := gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, @tessBeginCB);
gluTessCallback(tess, GLU_TESS_END, @tessEndCB);
gluTessCallback(tess, GLU_TESS_ERROR, @tessErrorCB);
gluTessCallback(tess, GLU_TESS_VERTEX, @tessVertexCB);
gluTessCallback(tess, GLU_TESS_COMBINE, @tessCombineCB);
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(tess, 0); // with NULL data
gluTessBeginContour(tess);
test[0] := star[0][0];
test[1] := star[0][1];
test[2] := star[0][2];
gluTessVertex(tess, test, @star[0]);
test[0] := star[1][0];
test[1] := star[1][1];
test[2] := star[1][2];
gluTessVertex(tess, test, @star[1]);
test[0] := star[2][0];
test[1] := star[2][1];
test[2] := star[2][2];
gluTessVertex(tess, test, @star[2]);
test[0] := star[3][0];
test[1] := star[3][1];
test[2] := star[3][2];
gluTessVertex(tess, test, @star[3]);
test[0] := star[4][0];
test[1] := star[4][1];
test[2] := star[4][2];
gluTessVertex(tess, test, @star[4]);
gluTessEndContour(tess);
gluTessEndPolygon(tess);
gluDeleteTess(tess); // delete after tessellation
SwapBuffers(DC);
end;
procedure TOpenGLRender.Stop;
begin
DeactivateRenderingContext; // Deactivate RenderContext
wglDeleteContext(RC); //Delete RenderContext
ReleaseDC(Handle, DC);
end;
//TDGLForm
procedure TDGLForm.FormCreate(Sender: TObject);
begin
DecimalSeparator:='.'; //always use . as decimal seperator
OpenGLRender := TOpenGLRender.Create(true);
OpenGLRender.Handle := Handle;
OpenGLRender.Options := [opDoubleBuffered];
OpenGLRender.PixelDepth := 32;
OpenGLRender.DepthBuffer := 24;
OpenGLRender.Resume;
end;
procedure TDGLForm.FormDestroy(Sender: TObject);
begin
OpenGLRender.Suspend;
OpenGLRender.Free;
end;
procedure TDGLForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
case Key of
#27 : Close;
end;
end;
end.