📄 teeglcanvas.pas
字号:
begin
if Brush.Bitmap<>nil then
begin
glEnable(GL_TEXTURE_2D);
{$IFNDEF LINUX}
glBindTexture(GL_TEXTURE_2D, FindTexture(Brush.Bitmap));
{$ENDIF}
gluQuadricTexture(FQuadric,{$IFDEF LINUX}True{$ELSE}GL_TRUE{$ENDIF});
end;
end;
Procedure TGLCanvas.EndBrushBitmap;
begin
if Brush.Bitmap<>nil then
begin
gluQuadricTexture(FQuadric,{$IFDEF LINUX}False{$ELSE}GL_FALSE{$ENDIF});
glDisable(GL_TEXTURE_2D);
end;
end;
Procedure TGLCanvas.Cube(Left,Right,Top,Bottom,Z0,Z1:Integer; DarkSides:Boolean);
begin
glEnable(GL_CULL_FACE);
if Left>Right then SwapInteger(Left,Right);
if Top>Bottom then SwapInteger(Top,Bottom);
if z0>z1 then SwapInteger(z0,z1);
if Brush.Style<>bsClear then
begin
SetColor(Brush.Color);
SetBrushBitmap;
glBegin(GL_QUADS);
TeeNormal( 0, 0, -1);
glTexCoord2f(1,0);
TeeVertex3D( Left, Bottom, z0);
glTexCoord2f(1,1);
TeeVertex3D( Right, Bottom, z0);
glTexCoord2f(0,1);
TeeVertex3D( Right, Top, z0);
glTexCoord2f(0,0);
TeeVertex3D( Left, Top, z0);
TeeNormal(-1, 0, 0);
glTexCoord2f(0,0);
TeeVertex3D( Left, Top, z1);
glTexCoord2f(0,1);
TeeVertex3D( Left, Bottom, z1);
glTexCoord2f(1,1);
TeeVertex3D( Left, Bottom, z0);
glTexCoord2f(1,0);
TeeVertex3D( Left, Top, z0);
TeeNormal( 0, 0, 1);
glTexCoord2f(0,0);
TeeVertex3D( Right, Top, z1);
glTexCoord2f(0,1);
TeeVertex3D( Right, Bottom, z1);
glTexCoord2f(1,1);
TeeVertex3D( Left, Bottom, z1);
glTexCoord2f(1,0);
TeeVertex3D( Left, Top, z1);
TeeNormal( 1, 0, 0);
glTexCoord2f(0,0);
TeeVertex3D( Right, Bottom, z0);
glTexCoord2f(0,1);
TeeVertex3D( Right, Bottom, z1);
glTexCoord2f(1,1);
TeeVertex3D( Right, Top, z1);
glTexCoord2f(1,0);
TeeVertex3D( Right, Top, z0);
TeeNormal( 0, 1, 0);
glTexCoord2f(0,0);
TeeVertex3D( Left, Top, z1);
glTexCoord2f(0,1);
TeeVertex3D( Left, Top, z0);
glTexCoord2f(1,1);
TeeVertex3D( Right, Top, z0);
glTexCoord2f(1,0);
TeeVertex3D( Right, Top, z1);
TeeNormal( 0, -1, 0);
glTexCoord2f(0,0);
TeeVertex3D( Right, Bottom, z0);
glTexCoord2f(0,1);
TeeVertex3D( Left, Bottom, z0);
glTexCoord2f(1,1);
TeeVertex3D( Left, Bottom, z1);
glTexCoord2f(1,0);
TeeVertex3D( Right, Bottom, z1);
glEnd;
EndBrushBitmap;
end;
if Pen.Style<>psClear then
begin
SetPen;
glBegin(GL_LINE_LOOP);
TeeVertex3D( Left, Bottom, z0);
TeeVertex3D( Right, Bottom, z0);
TeeVertex3D( Right, Top, z0);
TeeVertex3D( Left, Top, z0);
glEnd;
glBegin(GL_LINE_LOOP);
TeeVertex3D( Left, Top, z1);
TeeVertex3D( Left, Bottom, z1);
TeeVertex3D( Right, Bottom, z1);
TeeVertex3D( Right, Top, z1);
glEnd;
glBegin(GL_LINE_LOOP);
TeeVertex3D( Right, Top, z0);
TeeVertex3D( Right, Top, z1);
TeeVertex3D( Right, Bottom, z1);
TeeVertex3D( Right, Bottom, z0);
glEnd;
glBegin(GL_LINE_LOOP);
TeeVertex3D( Left, Top, z0);
TeeVertex3D( Left, Bottom, z0);
TeeVertex3D( Left, Bottom, z1);
TeeVertex3D( Left, Top, z1);
glEnd;
glBegin(GL_LINE_LOOP);
TeeVertex3D( Right, Top, z1);
TeeVertex3D( Right, Top, z0);
TeeVertex3D( Left, Top, z0);
TeeVertex3D( Left, Top, z1);
glEnd;
end;
glDisable(GL_CULL_FACE);
Assert(CheckGLError,'Cube');
end;
Procedure TGLCanvas.SetMaterialColor;
Function GLColor(Const Value:Double):GLMat;
begin
result[0]:=Value;
result[1]:=Value;
result[2]:=Value;
result[3]:=1;
end;
var tmp:GLMat;
begin
tmp:=GLColor(TeeMaterialDiffuse);
glMaterialfv(TeeColorPlanes,GL_DIFFUSE,@tmp);
tmp:=GLColor(TeeMaterialSpecular);
glMaterialfv(TeeColorPlanes,GL_SPECULAR,@tmp);
tmp:=GLColor(TeeMaterialAmbient);
glMaterialfv(TeeColorPlanes,GL_AMBIENT,@tmp);
Assert(CheckGLError,'Material '+IntToStr(FSavedError));
end;
{$IFNDEF LINUX}
Function TGLCanvas.GetDCHandle:HDC;
begin
{$IFDEF CLX}
result:=GetDC(GetActiveWindow);
{$ELSE}
result:=FDC;
{$ENDIF}
end;
{$ENDIF}
Function TGLCanvas.InitWindow( DestCanvas:TCanvas;
A3DOptions:TView3DOptions;
ABackColor:TColor;
Is3D:Boolean;
Const UserRect:TRect):TRect;
begin
if (IDestCanvas<>DestCanvas) or (View3DOptions<>A3DOptions) then
begin
IDestCanvas:=DestCanvas;
View3DOptions:=A3DOptions;
{$IFNDEF LINUX}
InitOpenGL;
{$ENDIF}
DestroyGLContext;
FDC:=DestCanvas.Handle;
{$IFNDEF LINUX}
{$IFDEF CLX}
IDrawToBitmap:=False;
{$ELSE}
IDrawToBitmap:=GetObjectType(FDC) = OBJ_MEMDC;
{$ENDIF}
HRC:=CreateRenderingContext(GetDCHandle,[opDoubleBuffered],24,0);
ActivateRenderingContext(GetDCHandle,HRC);
Assert(CheckGLError,'ActivateContext');
{$ENDIF}
glEnable(GL_NORMALIZE);
Assert(CheckGLError,'EnableNormalize');
glEnable(GL_DEPTH_TEST);
Assert(CheckGLError,'EnableDepth');
glDepthFunc(GL_LESS);
Assert(CheckGLError,'DepthFunc');
glEnable(GL_LINE_STIPPLE);
Assert(CheckGLError,'EnableLineStipple');
glEnable(GL_COLOR_MATERIAL);
Assert(CheckGLError,'EnableColorMaterial');
glColorMaterial(TeeColorPlanes,GL_AMBIENT_AND_DIFFUSE);
Assert(CheckGLError,'ColorMaterial');
SetMaterialColor;
{$IFNDEF LINUX}
//glEnable(GL_POLYGON_OFFSET_LINE);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.5,1);
Assert(CheckGLError,'PolygonOffset');
{$ENDIF}
// Enable / Disable antialias smoothing:
if TeeSmooth then
begin
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
end
else
begin
glDisable(GL_POLYGON_SMOOTH);
glDisable(GL_POINT_SMOOTH);
glDisable(GL_LINE_SMOOTH);
end;
glDisable(GL_CULL_FACE);
glEnable(GL_DITHER);
Assert(CheckGLError,'Dither');
glHint(GL_PERSPECTIVE_CORRECTION_HINT, TeePerspectiveQuality);
glHint(GL_LINE_SMOOTH_HINT, TeeSmoothQuality);
glHint(GL_POINT_SMOOTH_HINT, TeeSmoothQuality);
glHint(GL_POLYGON_SMOOTH_HINT, TeeSmoothQuality);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,TeeFullLightModel);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,TeeLightLocal);
Assert(CheckGLError,'LightModel');
end;
FX:=0;
FY:=0;
FIs3D:=Is3D;
{$IFNDEF LINUX}
if GetObjectType(GetDCHandle) <> OBJ_MEMDC then
begin
FDC:=DestCanvas.Handle;
ActivateRenderingContext(GetDCHandle,HRC);
end;
{$ENDIF}
SetCanvas(DestCanvas);
FBackColor:=ABackColor;
result:=UserRect;
end;
Procedure TGLCanvas.InitAmbientLight(AmbientLight:Integer);
var tmp:GLMat;
tmpNum:Double;
begin
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
glDisable(GL_LIGHT2);
Assert(CheckGLError,'DisableLight');
if AmbientLight>0 then
begin
glEnable(GL_LIGHTING);
Assert(CheckGLError,'EnableLight');
tmpNum:=AmbientLight*0.01;
tmp[0]:=tmpNum;
tmp[1]:=tmpNum;
tmp[2]:=tmpNum;
tmp[3]:=1;
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @tmp);
// glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
Assert(CheckGLError,'LightModel');
end
else
begin
tmp[0]:=0;
tmp[1]:=0;
tmp[2]:=0;
tmp[3]:=1;
glEnable(GL_LIGHTING);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @tmp);
Assert(CheckGLError,'LightModel');
glDisable(GL_LIGHTING);
Assert(CheckGLError,'DisableLightModel');
end;
end;
Procedure TGLCanvas.SetShininess(Const Value:Double);
begin
glMateriali(TeeColorPlanes, GL_SHININESS, Round(128.0*Value));
Assert(CheckGLError,'Shininess');
end;
Procedure TGLCanvas.InitLight(Num:Integer; Const AColor:GLMat; Const X,Y,Z:Double);
Const tmpSpec=0.9;
tmpDif =0.9;
tmpAmb =0.2;
var tmp : GLMat;
begin
glEnable(GL_LIGHTING);
glEnable(Num);
Assert(CheckGLError,'EnableLight '+IntToStr(Num));
tmp[0]:=tmpAmb;
tmp[1]:=tmpAmb;
tmp[2]:=tmpAmb;
tmp[3]:=1;
tmp:=AColor;
glLightfv(Num,GL_AMBIENT, @tmp);
Assert(CheckGLError,'LightAmbient '+IntToStr(Num));
tmp[0]:=tmpDif;
tmp[1]:=tmpDif;
tmp[2]:=tmpDif;
tmp[3]:=1;
glLightfv(Num,GL_DIFFUSE, @tmp);
Assert(CheckGLError,'LightDiffuse '+IntToStr(Num));
tmp[0]:=tmpSpec;
tmp[1]:=tmpSpec;
tmp[2]:=tmpSpec;
tmp[3]:=1;
glLightfv(Num,GL_SPECULAR, @tmp);
Assert(CheckGLError,'LightSpecular '+IntToStr(Num));
tmp[0]:= X;
tmp[1]:= -Y;
tmp[2]:= -Z;
tmp[3]:=1;
glLightfv(Num,GL_POSITION, @tmp);
Assert(CheckGLError,'LightPosition '+IntToStr(Num));
glLighti(Num,GL_SPOT_CUTOFF,TeeDefaultLightSpot);
Assert(CheckGLError,'LightSpot '+IntToStr(Num));
// glLighti(Num,GL_SPOT_EXPONENT,2);
// glLightf(Num,GL_CONSTANT_ATTENUATION,1.2);
// glLightf(Num,GL_QUADRATIC_ATTENUATION,0.00001);
end;
Procedure TGLCanvas.ShowImage(DestCanvas,DefaultCanvas:TCanvas; Const UserRect:TRect);
begin
glFlush;
Assert(CheckGLError,'Flush');
{$IFNDEF LINUX}
SwapBuffers(GetDCHandle);
{$ENDIF}
SetCanvas(DefaultCanvas);
Assert(CheckGLError,'ShowImage');
end;
Function TGLCanvas.ReDrawBitmap:Boolean;
begin
result:=False;
end;
procedure TGLCanvas.Rectangle(X0,Y0,X1,Y1:Integer);
begin
if Brush.Style<>bsClear then FillRect(TeeRect(X0,Y0,X1,Y1));
if Pen.Style<>psClear then
begin
SetPen;
glBegin(GL_LINE_LOOP);
TeeVertex2D(X0,Y0);
TeeVertex2D(X1,Y0);
TeeVertex2D(X1,Y1);
TeeVertex2D(X0,Y1);
glEnd;
end;
Assert(CheckGLError,'Rectangle');
end;
procedure TGLCanvas.SetTextAlign(Align:Integer);
begin
FTextAlign:=Align;
end;
procedure TGLCanvas.MoveTo(X, Y: Integer);
begin
FX:=X;
FY:=Y;
end;
procedure TGLCanvas.Pyramid(Vertical:Boolean; Left,Top,Right,Bottom,z0,z1:Integer; DarkSides:Boolean);
var AWidth,
AHeight,
ADepth:Integer;
begin
glPushMatrix;
glEnable(GL_CULL_FACE);
if Vertical then
begin
if Left>Right then SwapInteger(Left,Right);
if Top>Bottom then glDisable(GL_CULL_FACE);
end
else
begin
if Top>Bottom then SwapInteger(Top,Bottom);
if Left>Right then glDisable(GL_CULL_FACE);
end;
if z0>z1 then SwapInteger(z0,z1);
glTranslatef(Left,-Bottom,-z0);
if Vertical then
begin
AWidth:=Right-Left;
AHeight:=Top-Bottom;
end
else
begin
AWidth:=Bottom-Top;
AHeight:=Right-Left;
glRotatef(90,0,0,1);
end;
ADepth:=z1-z0;
if Brush.Style<>bsClear then
begin
glBegin(GL_TRIANGLE_FAN);
SetColor(Brush.Color);
SetBrushBitmap;
//TeeNormal(0,0,-1);
TeeNormal(AWidth div 2,-AHeight,ADepth div 2);
TeeVertex3D(AWidth div 2,AHeight,ADepth div 2);
TeeNormal(0,0,-1);
TeeVertex2D(0,0);
TeeNormal(1,0,-1);
TeeVertex2D(AWidth,0);
TeeNormal(1,0,1);
TeeVertex3D(AWidth,0,ADepth);
TeeNormal(0,0,1);
TeeVertex3D(0,0,ADepth);
TeeNormal(0,0,-1);
TeeVertex2D(0,0);
glEnd;
RectangleY(0,0,AWidth,0,ADepth);
EndBrushBitmap;
end;
glDisable(GL_CULL_FACE);
if Pen.Style<>psClear then
begin
SetPen;
glBegin(GL_LINE_LOOP);
TeeVertex2D(0,0);
TeeVertex2D(AWidth,0);
TeeVertex3D(AWidth,0,ADepth);
TeeVertex3D(0,0,ADepth);
glEnd;
glBegin(GL_LINE_STRIP);
TeeVertex2D(0,0);
TeeVertex3D(AWidth div 2,AHeight,ADepth div 2);
TeeVertex3D(0,0,ADepth);
glEnd;
glBegin(GL_LINE_STRIP);
TeeVertex2D(AWidth,0);
TeeVertex3D(AWidth div 2,AHeight,ADepth div 2);
TeeVertex3D(AWidth,0,ADepth);
glEnd;
end;
glPopMatrix;
Assert(CheckGLError,'Pyramid');
end;
procedure TGLCanvas.InternalCylinder(Vertical:Boolean;
Left,Top,Right,Bottom,Z0,Z1:Integer; Dark3D:Boolean;
ConePercent:Integer);
Var tmpSize,
tmp,
tmp2,
Radius:Integer;
begin
glPushMatrix;
Radius:=Abs(Z1-Z0) div 2;
if Left>Right then SwapInteger(Left,Right);
if Top>Bottom then SwapInteger(Top,Bottom);
if z0>z1 then SwapInteger(z0,z1);
if Vertical then
begin
Radius:=MinInteger((Right-Left) div 2,Radius);
glTranslatef((Left+Right) div 2,-Top,-(z0+z1) div 2);
glRotatef(90,1,0,0);
tmpSize:=Bottom-Top;
end
else
begin
Radius:=MinInteger((Bottom-Top) div 2,Radius);
glTranslatef(Left,-(Top+Bottom) div 2,-(z0+z1) div 2);
glRotatef(90,0,1,0);
tmpSize:=Right-Left;
end;
if ConePercent=100 then tmp:=Radius
else tmp:=Round(0.01*ConePercent*Radius);
tmp2:=Math.Min(18,6*Radius);
if Brush.Style<>bsClear then
begin
glEnable(GL_CULL_FACE);
SetColor(Brush.Color);
SetBrushBitmap;
gluCylinder(FQuadric,tmp,Radius,tmpSize,tmp2,6);
EndBrushBitmap;
if ConePercent=100 then
begin
gluQuadricOrientation(FQuadric, GLU_INSIDE);
gluDisk(FQuadric,0,tmp,tmp2,6);
gluQuadricOrientation(FQuadric, GLU_OUTSIDE);
glPushMatrix;
glTranslated(0,0,tmpSize);
gluDisk(FQuadric,0,tmp,tmp2,6);
glPopMatrix;
end;
glDisable(GL_CULL_FACE);
end;
if Pen.Style<>psClear then
begin
SetPen;
gluQuadricDrawStyle(FQuadric, GLU_LINE);
gluCylinder(FQuadric,tmp+0.5,Radius+0.5,tmpSize+0.5,tmp2,6);
gluQuadricDrawStyle(FQuadric, GLU_FILL);
end;
glPopMatrix;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -