mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-02 17:33:41 +02:00
247 lines
4.2 KiB
ObjectPascal
247 lines
4.2 KiB
ObjectPascal
{
|
|
Bouncing ball demo. Color index mode only!
|
|
|
|
This program is in the public domain
|
|
Brian Paul
|
|
|
|
Converted to Pascal by Peter Vreman
|
|
}
|
|
program bounce;
|
|
|
|
{$mode objfpc}
|
|
|
|
uses
|
|
gl,glut;
|
|
|
|
const
|
|
RED=1;
|
|
WHITE=2;
|
|
CYAN=3;
|
|
|
|
var
|
|
IndexMode : Boolean;
|
|
Ball : GLuint;
|
|
|
|
const
|
|
Zrot : GLfloat = 0.0;
|
|
Zstep : GLfloat = 6.0;
|
|
Xpos : GLfloat = 0.0;
|
|
Ypos : GLfloat = 1.0;
|
|
Xvel : GLfloat = 0.2;
|
|
Yvel : GLfloat = 0.0;
|
|
Xmin : GLfloat = -4.0;
|
|
Xmax : GLfloat = 4.0;
|
|
Ymin : GLfloat = -3.8;
|
|
Ymax : GLfloat = 4.0;
|
|
G : GLfloat = -0.1;
|
|
|
|
|
|
function make_ball:GLuint;
|
|
var
|
|
list : GLuint;
|
|
a,b,
|
|
ar,br : GLFloat;
|
|
da,db,
|
|
dar : GLFloat;
|
|
radius : GLFloat;
|
|
color : boolean;
|
|
x,y,z : GLFloat;
|
|
begin
|
|
da:=18.0;
|
|
db:=18.0;
|
|
radius:=1.0;
|
|
|
|
list := glGenLists(1);
|
|
|
|
glNewList(list, GL_COMPILE);
|
|
|
|
color := false;
|
|
a:=-90.0;
|
|
while (a+da<=90.0) do
|
|
begin
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
b:=0.0;
|
|
while (b<=360.0) do
|
|
begin
|
|
if (color) then
|
|
begin
|
|
glIndexi(RED);
|
|
glColor3f(1, 0, 0);
|
|
end
|
|
else
|
|
begin
|
|
glIndexi(WHITE);
|
|
glColor3f(1, 1, 1);
|
|
end;
|
|
|
|
ar:=a * 3.14159/180.0;
|
|
br:=b * 3.14159/180.0;
|
|
x := COS(br) * COS(ar);
|
|
y := SIN(br) * COS(ar);
|
|
z := SIN(ar);
|
|
glVertex3f(x, y, z);
|
|
|
|
dar:=da * 3.14159/180.0;
|
|
x := radius * COS(br) * COS(ar + dar);
|
|
y := radius * SIN(br) * COS(ar + dar);
|
|
z := radius * SIN(ar + dar);
|
|
glVertex3f(x, y, z);
|
|
|
|
color := not color;
|
|
b:=b+db;
|
|
end;
|
|
|
|
glEnd();
|
|
a:=a+da;
|
|
end;
|
|
|
|
glEndList();
|
|
|
|
make_ball:=list;
|
|
end;
|
|
|
|
|
|
procedure reshape(width,height:longint); cdecl;
|
|
var
|
|
aspect : glFloat;
|
|
begin
|
|
aspect := glfloat(width) / glfloat(height);
|
|
glViewport(0, 0, width, height);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(-6.0 * aspect, 6.0 * aspect, -6.0, 6.0, -6.0, 6.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
end;
|
|
|
|
|
|
procedure key(k:byte;x,y:longint); cdecl;
|
|
begin
|
|
case k of
|
|
27 :
|
|
halt(0);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure draw; cdecl;
|
|
var
|
|
i : GLint;
|
|
begin
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glIndexi(CYAN);
|
|
glColor3f(0, 1, 1);
|
|
glBegin(GL_LINES);
|
|
for i:=-5 to 5 do
|
|
begin
|
|
glVertex2i(i, -5);
|
|
glVertex2i(i, 5);
|
|
end;
|
|
for i:=-5 to 5 do
|
|
begin
|
|
glVertex2i(-5, i);
|
|
glVertex2i(5, i);
|
|
end;
|
|
for i:=-5 to 5 do
|
|
begin
|
|
glVertex2i(i, -5);
|
|
glVertex2f(i * 1.15, -5.9);
|
|
end;
|
|
glVertex2f(-5.3, -5.35);
|
|
glVertex2f(5.3, -5.35);
|
|
glVertex2f(-5.75, -5.9);
|
|
glVertex2f(5.75, -5.9);
|
|
glEnd();
|
|
|
|
glPushMatrix();
|
|
glTranslatef(Xpos, Ypos, 0.0);
|
|
glScalef(2.0, 2.0, 2.0);
|
|
glRotatef(8.0, 0.0, 0.0, 1.0);
|
|
glRotatef(90.0, 1.0, 0.0, 0.0);
|
|
glRotatef(Zrot, 0.0, 0.0, 1.0);
|
|
|
|
glCallList(Ball);
|
|
|
|
glPopMatrix();
|
|
|
|
glFlush();
|
|
glutSwapBuffers();
|
|
end;
|
|
|
|
|
|
const
|
|
vel0 : glfloat = -100.0;
|
|
procedure idle; cdecl;
|
|
begin
|
|
Zrot:=Zrot+Zstep;
|
|
Xpos:=Xpos+Xvel;
|
|
if (Xpos >= Xmax) then
|
|
begin
|
|
Xpos := Xmax;
|
|
Xvel := -Xvel;
|
|
Zstep := -Zstep;
|
|
end;
|
|
if (Xpos <= Xmin) then
|
|
begin
|
|
Xpos := Xmin;
|
|
Xvel := -Xvel;
|
|
Zstep := -Zstep;
|
|
end;
|
|
Ypos:=Ypos+Yvel;
|
|
Yvel:=Yvel+G;
|
|
if (Ypos < Ymin) then
|
|
begin
|
|
Ypos := Ymin;
|
|
if (vel0 = -100.0) then
|
|
vel0 := abs(Yvel);
|
|
Yvel := vel0;
|
|
end;
|
|
glutPostRedisplay();
|
|
end;
|
|
|
|
|
|
procedure visible(vis:longint); cdecl;
|
|
begin
|
|
if (vis=GLUT_VISIBLE) then
|
|
glutIdleFunc(@idle)
|
|
else
|
|
glutIdleFunc(nil);
|
|
end;
|
|
|
|
|
|
begin
|
|
glutInit(@argc, argv);
|
|
glutInitWindowPosition(0, 0);
|
|
glutInitWindowSize(600, 450);
|
|
|
|
if paramcount>1 then
|
|
IndexMode:=(paramstr(1)='-ci');
|
|
|
|
if (IndexMode) then
|
|
glutInitDisplayMode(GLUT_INDEX or GLUT_DOUBLE)
|
|
else
|
|
glutInitDisplayMode(GLUT_RGB or GLUT_DOUBLE);
|
|
|
|
glutCreateWindow('Bounce');
|
|
Ball := make_ball();
|
|
glCullFace(GL_BACK);
|
|
glEnable(GL_CULL_FACE);
|
|
glDisable(GL_DITHER);
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glutDisplayFunc(@draw);
|
|
glutReshapeFunc(@reshape);
|
|
glutVisibilityFunc(@visible);
|
|
glutKeyboardFunc(@key);
|
|
|
|
if (IndexMode) then
|
|
begin
|
|
glutSetColor(RED, 1.0, 0.0, 0.0);
|
|
glutSetColor(WHITE, 1.0, 1.0, 1.0);
|
|
glutSetColor(CYAN, 0.0, 1.0, 1.0);
|
|
end;
|
|
|
|
glutMainLoop();
|
|
end.
|