You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.6 KiB
Plaintext

unit UDraw;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, gl, UGLTypes;
const
// The number of sections per corner must be at least 1.
CCornerSectionCount = 4;
CCornerSectionAngle = Pi / (2 * CCornerSectionCount);
type
{ TDraw }
TDraw = class
public
class constructor Create;
class procedure AddRoundBox(ACenterX, ACenterY, AWidth, AHeight,
ACornerSize: Single); static;
private
FCornerSectionVertices: array[0..CCornerSectionCount + 1] of TVertex3f; static;
class procedure MakeVertexList; static;
end;
implementation
{ TDraw }
class constructor TDraw.Create;
begin
MakeVertexList;
end;
class procedure TDraw.AddRoundBox(ACenterX, ACenterY, AWidth, AHeight,
ACornerSize: Single);
var
i, flip: Integer;
begin
glPushMatrix;
// Draws a cross from two quads: the panel without the corners.
glTranslatef(ACenterX, ACenterY, 0);
glPushMatrix;
glTranslatef(-0.5 * AWidth, -0.5 * AHeight, 0);
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
glVertex2f(AWidth - ACornerSize, AHeight);
glVertex2f(ACornerSize, AHeight);
glVertex2f(ACornerSize, 0);
glVertex2f(AWidth - ACornerSize, 0);
glVertex2f(AWidth, AHeight - ACornerSize);
glVertex2f(0, AHeight - ACornerSize);
glVertex2f(0, ACornerSize);
glVertex2f(AWidth, ACornerSize);
glEnd;
glPopMatrix;
// Draws the four corners by mirroring one fan of triangles. Its vertex
// coordinates are precalculated in 'FCornerSectionVertices'.
for i := 0 to 3 do
begin
glPushMatrix;
glTranslatef(0.5 * AWidth - ACornerSize, 0.5 * AHeight - ACornerSize, 0);
glScalef(ACornerSize, ACornerSize, 1);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, @FCornerSectionVertices[0]);
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(FCornerSectionVertices));
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix;
flip := 2 * (i and 1);
glScalef(flip - 1, 1 - flip, 1);
end;
glPopMatrix;
end;
class procedure TDraw.MakeVertexList;
var
i, last: Integer;
begin
FCornerSectionVertices[0].X := 0;
FCornerSectionVertices[0].Y := 0;
FCornerSectionVertices[1].X := 1;
FCornerSectionVertices[1].Y := 0;
last := Length(FCornerSectionVertices) - 1;
for i := 2 to last - 1 do
begin
FCornerSectionVertices[i].X := Cos(CCornerSectionAngle * (i - 1));
FCornerSectionVertices[i].Y := Sin(CCornerSectionAngle * (i - 1));
end;
FCornerSectionVertices[last].X := 0;
FCornerSectionVertices[last].Y := 1;
end;
end.