Code:
unit mvRenderHelpers;
{**<
@author(Jani Alanen <http://www.projectminiverse.com>)
@created(2007-01-27)
@lastmod(2009-01-07)
Miscellaneous helper code for rendering .
History
Created:
27.01.2007 (JA)
Modified:
07.01.2009 (JA)
- Renamed to mvRenderHelpers.pas
}
interface
uses
{$IFDEF USE_SDL}
GL, GLU,
{$ELSE}
dglOpenGL,
{$ENDIF}
mvMath;
procedure DrawCube(Size: TFloat);
procedure DrawTorus(MinorRadius, MajorRadius: TFloat; NumMinor, NumMajor: TInt);
procedure DrawSphere(NumMajor, NumMinor: TInt; Radius: TFloat);
procedure DrawCylinder(NumMajor, NumMinor: TInt; Height, Radius: TFloat);
procedure DrawSkewedPyramid(Size: TFloat);
procedure DrawWireSkewedPyramid(Size: TFloat);
procedure DrawTetrahedron(Size: TFloat);
procedure DrawWireTetrahedron(Size: TFloat);
procedure DrawOctahedron(Size: TFloat);
procedure DrawWireOctahedron(Size: TFloat);
implementation
uses
mvGLUtils, mvGlobal;
procedure DrawCube(Size: TFloat);
const
// Texture coordinates from bottom left to top right
TexCoord: array [0..3] of TTexel = ((u: 0; v: 0),
(u: 1; v: 0),
(u: 1; v: 1),
(u: 0; v: 1));
// Vertices used in cube
Vertex: array [0..7] of TVertex = ((v:(-1.0, 1.0, 1.0)), // 0
(v:( 1.0, 1.0, 1.0)), // 1
(v:( 1.0,-1.0, 1.0)), // 2
(v:(-1.0,-1.0, 1.0)), // 3
(v:(-1.0, 1.0,-1.0)), // 4
(v:( 1.0, 1.0,-1.0)), // 5
(v:( 1.0,-1.0,-1.0)), // 6
(v:(-1.0,-1.0,-1.0))); // 7
// Faces of the cube
Cube: array [0..5, 0..3] of Integer = ((0, 1, 2, 3),
(1, 5, 6, 2),
(4, 5, 1, 0),
(0, 3, 7, 4),
(3, 2, 6, 7),
(5, 4, 7, 6));
// Normals for each face of the cube
// Angle of normal and face is allways 90 degrees and
// length is allways 1.0!
Normals: array [0..5] of TVertex = ((v:( 0.0, 0.0, 1.0)),
(v:( 1.0, 0.0, 0.0)),
(v:( 0.0, 1.0, 0.0)),
(v:(-1.0, 0.0, 0.0)),
(v:( 0.0,-1.0, 0.0)),
(v:( 0.0, 0.0,-1.0)));
var
i, j: Integer;
begin
{
// Start rendering quads
glBegin(GL_QUADS);
for i := 0 to 5 do
begin
// Set normal for this face
glNormal3fv(@Normals[i][0]);
for j := 0 to 3 do
begin
// Texture coordinates for this vertex in texels
glTexCoord2f(TexCoord[j, 0], TexCoord[j, 1]);
// Position for this vertex, object position NOT world position
glVertex3fv(@Vertex[Cube[i, j]][0]);
end;
glCheckForError();
end;
// End rendering quads
glEnd;
}
glBegin(GL_QUADS);
//glColor3f(1, 1, 1);
glNormal3f( 0.0, 0.0, 1.0);
glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
glTexCoord2f(1, 0); glVertex3f(-Size / 2, Size / 2, Size / 2);
glTexCoord2f(1, 1); glVertex3f(-Size / 2,-Size / 2, Size / 2);
glTexCoord2f(0, 1); glVertex3f( Size / 2,-Size / 2, Size / 2);
//glColor3f(1, 0, 0);
glNormal3f( 0.0, 0.0,-1.0);
glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
glTexCoord2f(1, 0);glVertex3f(-Size / 2, Size / 2,-Size / 2);
glTexCoord2f(1, 1); glVertex3f( Size / 2, Size / 2,-Size / 2);
glTexCoord2f(0, 1); glVertex3f( Size / 2,-Size / 2,-Size / 2);
//glColor3f(0, 1, 0);
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
glTexCoord2f(1, 0); glVertex3f( Size / 2, Size / 2,-Size / 2);
glTexCoord2f(1, 1); glVertex3f(-Size / 2, Size / 2,-Size / 2);
glTexCoord2f(0, 1); glVertex3f(-Size / 2, Size / 2, Size / 2);
//glColor3f(0, 0, 1);
glNormal3f( 0.0,-1.0, 0.0);
glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
glTexCoord2f(1, 0); glVertex3f( Size / 2,-Size / 2,-Size / 2);
glTexCoord2f(1, 1); glVertex3f( Size / 2,-Size / 2, Size / 2);
glTexCoord2f(0, 1); glVertex3f(-Size / 2,-Size / 2, Size / 2);
//glColor3f(0, 1, 1);
glNormal3f( 1.0, 0.0, 0.0);
glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
glTexCoord2f(1, 0); glVertex3f( Size / 2,-Size / 2, Size / 2);
glTexCoord2f(1, 1); glVertex3f( Size / 2,-Size / 2,-Size / 2);
glTexCoord2f(0, 1); glVertex3f( Size / 2, Size / 2,-Size / 2);
//glColor3f(1, 1, 0);
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
glTexCoord2f(1, 0); glVertex3f(-Size / 2,-Size / 2, Size / 2);
glTexCoord2f(1, 1); glVertex3f(-Size / 2, Size / 2, Size / 2);
glTexCoord2f(0, 1); glVertex3f(-Size / 2, Size / 2,-Size / 2);
glEnd();
{
glVertex3f(-Size + x, Size + y, Size + z);
glVertex3f( Size + x, Size + y, Size + z);
glVertex3f( Size + x,-Size + y, Size + z);
glVertex3f(-Size + x,-Size + y, Size + z);
glVertex3f( Size + x, Size + y, Size + z);
glVertex3f( Size + x, Size + y,-Size + z);
glVertex3f( Size + x,-Size + y,-Size + z);
glVertex3f( Size + x,-Size + y, Size + z);
glVertex3f(-Size + x, Size + y,-Size + z);
glVertex3f( Size + x, Size + y,-Size + z);
glVertex3f( Size + x, Size + y,-Size + z);
glVertex3f(-Size + x, Size + y,-Size + z);
glVertex3f(-Size + x, Size + y,-Size + z);
glVertex3f(-Size + x,-Size + y, Size + z);
glVertex3f(-Size + x,-Size + y,-Size + z);
glVertex3f(-Size + x, Size + y,-Size + z);
glVertex3f(-Size + x,-Size + y, Size + z);
glVertex3f( Size + x,-Size + y, Size + z);
glVertex3f( Size + x,-Size + y,-Size + z);
glVertex3f(-Size + x,-Size + y,-Size + z);
glVertex3f( Size + x, Size,-Size + z);
glVertex3f(-Size + x, Size,-Size + z);
glVertex3f(-Size + x,-Size,-Size + z);
glVertex3f( Size + x,-Size,-Size + z);
}
//glEnd;
end;
procedure DrawTorus(MinorRadius, MajorRadius: TFloat; NumMinor, NumMajor: TInt);
var
MajorStep, MinorStep: TFloat;
i, j: Integer;
a0, a1, b: TFloat;
x0, y0, x1, y1, c, r, z: TFloat;
begin
MajorStep := 2.7 * PI / NumMajor;
MinorStep := 2.7 * PI / NumMajor;
for i := 0 to numMajor do
begin
a0 := i * MajorStep;
a1 := a0 + MajorStep;
x0 := Cos(a0);
y0 := Sin(a0);
x1 := Cos(a1);
y1 := Sin(a1);
glBegin(GL_TRIANGLE_STRIP);
for j := 0 to numMinor do
begin
b := j * MinorStep;
c := Cos(b);
r := MinorRadius * c + MajorRadius;
z := MinorRadius * Sin(b);
glNormal3f(x0 * c, y0 * c, z / MinorRadius);
glTexCoord2f(i / NumMajor, j / NumMinor);
glVertex3f(x0 * r, y0 * r, z);
glNormal3f(x1 * c, y1 * c, z / MinorRadius);
glTexCoord2f((i + 1) / NumMajor, j / NumMinor);
glVertex3f(x1 * r, y1 * r, z);
end;
glEnd();
end;
end;
procedure DrawSphere(NumMajor, NumMinor: Integer; Radius: TFloat);
var
MajorStep, MinorStep: TFloat;
i, j: Integer;
a, b, c, r0, r1: TFloat;
x, y, z0, z1: TFloat;
begin
MajorStep := (PI / NumMajor);
MinorStep := (2.0 * PI / NumMinor);
for i := 0 to NumMajor do
begin
a := i * MajorStep;
b := a + MajorStep;
r0 := radius * Sin(a);
r1 := radius * Sin(b);
z0 := radius * Cos(a);
z1 := radius * Cos(b);
glBegin(GL_TRIANGLE_STRIP);
for j := 0 to NumMinor do
begin
c := j * MinorStep;
x := Cos(c);
y := Sin(c);
glNormal3f((x * r0) / radius, (y * r0) / Radius, z0 / Radius);
glTexCoord2f(j / NumMinor, i / NumMajor);
glVertex3f(x * r0, y * r0, z0);
glNormal3f((x * r1) / Radius, (y * r1) / Radius, z1 / Radius);
glTexCoord2f(j / NumMinor, (i + 1) / NumMajor);
glVertex3f(x * r1, y * r1, z1);
end;
glEnd();
end;
end;
procedure DrawCylinder(NumMajor, NumMinor: TInt; Height, Radius: TFloat);
var MajorStep, MinorStep: TFloat;
i, j: Integer;
a, x, y, z0, z1: TFloat;
begin
MajorStep := Height / NumMajor;
MinorStep := 2.0 * PI / NumMinor;
for i := 0 to NumMajor do
begin
z0 := 0.5 * Height - i * MajorStep;
z1 := z0 - MajorStep;
glBegin(GL_TRIANGLE_STRIP);
for j := 0 to NumMinor do
begin
a := j * MinorStep;
x := Radius * Cos(a);
y := Radius * Sin(a);
glNormal3f(x / radius, y / radius, 0.0);
glTexCoord2f(j / numMinor, i / numMajor);
glVertex3f(x, y, z0);
glNormal3f(x / radius, y / radius, 0.0);
glTexCoord2f(j / numMinor, (i + 1) / numMajor);
glVertex3f(x, y, z1);
end;
glEnd();
end;
end;
procedure DrawSkewedPyramid(Size: TFloat);
begin
glBegin(GL_TRIANGLES);
// Back
glVertex3f(0, Size, -(Size / 2)); // Top
glVertex3f(Size/2, 0, -(Size / 2)); // Bottom right
glVertex3f(-Size/2, 0, -(Size / 2)); // Bottom left
//glVertex3f(0, Size, -(Size / 2));
glEnd;
// Left
glBegin(GL_TRIANGLES);
glVertex3f(0, 0, (Size / 2)); // Nose
glVertex3f(0, Size, -(Size / 2));
glVertex3f(-Size/2, 0, -(Size / 2));
//glVertex3f(0, 0, (Size / 2));
glEnd;
// Right
glBegin(GL_TRIANGLES);
glVertex3f(0, Size, -(Size / 2));
glVertex3f(0, 0, (Size / 2));
glVertex3f(Size/2, 0, -(Size / 2));
//glVertex3f(0, Size, -(Size / 2));
glEnd();
// Bottom
glBegin(GL_TRIANGLES);
glVertex3f(0, 0, (Size / 2));
glVertex3f(-Size/2, 0, -(Size / 2));
glVertex3f(Size/2, 0, -(Size / 2));
//glVertex3f(0, 0, (Size / 2));
glEnd();
end;
procedure DrawWireSkewedPyramid(Size: TFloat);
begin
glBegin(GL_LINE_STRIP);
// Back
glVertex3f(0, Size, -(Size / 2)); // Top
glVertex3f(Size/2, 0, -(Size / 2)); // Bottom right
glVertex3f(-Size/2, 0, -(Size / 2)); // Bottom left
glVertex3f(0, Size, -(Size / 2));
glEnd;
// Left
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, (Size / 2)); // Nose
glVertex3f(0, Size, -(Size / 2));
glVertex3f(-Size/2, 0, -(Size / 2));
glVertex3f(0, 0, (Size / 2));
glEnd;
// Right
glBegin(GL_LINE_STRIP);
glVertex3f(0, Size, -(Size / 2));
glVertex3f(0, 0, (Size / 2));
glVertex3f(Size/2, 0, -(Size / 2));
glVertex3f(0, Size, -(Size / 2));
glEnd();
// Bottom
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, (Size / 2));
glVertex3f(-Size/2, 0, -(Size / 2));
glVertex3f(Size/2, 0, -(Size / 2));
glVertex3f(0, 0, (Size / 2));
glEnd();
end;
procedure DrawTetrahedron(Size: TFloat);
begin
{
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(0, 0, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
glEnd();
}
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(0, -0.5, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
glEnd();
end;
procedure DrawWireTetrahedron(Size: TFloat);
begin
{
glBegin(GL_LINE_STRIP);
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(0, 0, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(0, 0, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2), 0);
glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
glVertex3f(0, 0, -1.4 * (Size / 2));
glEnd();
}
glBegin(GL_LINE_STRIP);
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(0, -0.5, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(0, -0.5, -1.4 * (Size / 2));
glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
glVertex3f(0, -0.5, -1.4 * (Size / 2));
glEnd();
end;
procedure DrawOctahedron(Size: TFloat);
const
Vertices: array [0..5] of TVector3f = (
(v: (0.0, 0.0, 1.0/SQRT2)),
(v: ( 0.5, 0.5, 0.0)),
(v: (-0.5, 0.5, 0.0)),
(v: (-0.5,-0.5, 0.0)),
(v: (0.5,-0.5, 0.0)),
(v: (0.0, 0.0, -1.0/SQRT2))
);
begin
glScalef(Size, Size, Size);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[1]);
glVertex3fv(@Vertices[2]);
glVertex3fv(@Vertices[3]);
glVertex3fv(@Vertices[4]);
glVertex3fv(@Vertices[1]);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[1]);
glVertex3fv(@Vertices[4]);
glVertex3fv(@Vertices[3]);
glVertex3fv(@Vertices[2]);
glVertex3fv(@Vertices[1]);
glEnd();
end;
procedure DrawWireOctahedron(Size: TFloat);
const
Vertices: array [0..5] of TVector3f = (
(v: (0.0, 0.0, 1.0/SQRT2)),
(v: ( 0.5, 0.5, 0.0)),
(v: (-0.5, 0.5, 0.0)),
(v: (-0.5,-0.5, 0.0)),
(v: (0.5,-0.5, 0.0)),
(v: (0.0, 0.0, -1.0/SQRT2))
);
begin
glScalef(Size, Size, Size);
glBegin(GL_LINES);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[1]);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[2]);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[3]);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[4]);
glVertex3fv(@Vertices[0]);
glVertex3fv(@Vertices[1]);
glEnd();
glBegin(GL_LINES);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[1]);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[4]);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[3]);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[2]);
glVertex3fv(@Vertices[5]);
glVertex3fv(@Vertices[1]);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3fv(@Vertices[1]);
glVertex3fv(@Vertices[4]);
glVertex3fv(@Vertices[3]);
glVertex3fv(@Vertices[2]);
glVertex3fv(@Vertices[1]);
glEnd();
end;
end.
Bookmarks