unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LCLType, ExtCtrls, Windows, MMSystem, // timeBeginPeriod を使うために追加 OpenGLContext, GL, glu; // OpenGLを使うために追加 type { TForm1 } TForm1 = class(TForm) OpenGLControl1: TOpenGLControl; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); procedure FormShow(Sender: TObject); procedure OpenGLControl1Paint(Sender: TObject); procedure OpenGLControl1Resize(Sender: TObject); procedure Timer1Timer(Sender: TObject); private fAngle: double; fLastTime: DWORD; procedure DrawCube; procedure ResizeGL; procedure SetFullscreen; public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } { フォームが生成された時の処理 } procedure TForm1.FormCreate(Sender: TObject); begin // タイマー精度を1msにする。(Windows Only) timeBeginPeriod(1); fLastTime := timeGetTime; fAngle := 0.0; // タイマーの時間間隔を設定 Timer1.Interval := 15; Timer1.Enabled := True; KeyPreview := True; end; { フォームが破棄された時の処理 } procedure TForm1.FormDestroy(Sender: TObject); begin // タイマー精度を元に戻す。(Windows Only) timeEndPeriod(1); OpenGLControl1.Cursor := crDefault; end; { フォームが表示された時の処理} procedure TForm1.FormShow(Sender: TObject); begin // フルスクリーン表示を指定 //SetFullscreen; //OpenGLControl1.Cursor := crNone; ResizeGL; end; { フルスクリーン表示を設定 } procedure TForm1.SetFullscreen; begin BorderStyle := bsNone; WindowState := wsFullScreen; //WindowState := wsMaximized; //BoundsRect := Screen.Monitors[0].BoundsRect; OpenGLControl1.Align := alClient; end; { キーが押された時の処理 } procedure TForm1.FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); begin // ESCキーで終了 //if Key = VK_ESCAPE then // Application.Terminate; Application.Terminate; end; { 一定時間毎に呼ばれる処理。Timer1のOnTimerに割り当て } procedure TForm1.Timer1Timer(Sender: TObject); begin // TOpenGLControlの再描画を要求 OpenGLControl1.Invalidate; end; { 箱を描画 } procedure TForm1.DrawCube; const D: double = 0.5; begin glBegin(GL_QUADS); glColor3f(1.0, 0.0, 0.0); glVertex3f(-D, -D, D); glVertex3f(D, -D, D); glVertex3f(D, D, D); glVertex3f(-D, D, D); glColor3f(0.0, 1.0, 0.0); glVertex3f(-D, -D, -D); glVertex3f(-D, D, -D); glVertex3f(D, D, -D); glVertex3f(D, -D, -D); glColor3f(0.0, 0.0, 1.0); glVertex3f(-D, D, -D); glVertex3f(-D, D, D); glVertex3f(D, D, D); glVertex3f(D, D, -D); glColor3f(1.0, 1.0, 0.0); glVertex3f(-D, -D, -D); glVertex3f(D, -D, -D); glVertex3f(D, -D, D); glVertex3f(-D, -D, D); glColor3f(1.0, 0.0, 1.0); glVertex3f(D, -D, -D); glVertex3f(D, D, -D); glVertex3f(D, D, D); glVertex3f(D, -D, D); glColor3f(0.0, 1.0, 1.0); glVertex3f(-D, -D, -D); glVertex3f(-D, -D, D); glVertex3f(-D, D, D); glVertex3f(-D, D, -D); glEnd(); end; { TOpenGLControlの描画処理 } procedure TForm1.OpenGLControl1Paint(Sender: TObject); var ct: DWORD; dt: double; begin // 前回からの時間差を取得 ct := timeGetTime; dt := (ct - fLastTime) / 1000.0; // 秒単位にする fLastTime := ct; // 角度を変更 fAngle := fAngle + (90.0 * dt); //if fAngle >= 360.0 then // fAngle := fAngle - 360.0; glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); // 背景を消去 glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // カメラを少し後ろに下げる glTranslatef(0.0, 0.0, -2.5); // 回転させる glRotatef(fAngle * 0.3, 1, 0, 0); glRotatef(fAngle, 0, 1, 0); // 立方体を描画 DrawCube; // ダブルバッファ切り替え OpenGLControl1.SwapBuffers; end; procedure TForm1.OpenGLControl1Resize(Sender: TObject); begin ResizeGL; end; { ウインドウリサイズ時に行うべき処理 } procedure TForm1.ResizeGL; var Aspect: double; begin if OpenGLControl1.Height <= 0 then Exit; // 透視変換をするように設定 glViewport(0, 0, OpenGLControl1.Width, OpenGLControl1.Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); Aspect := OpenGLControl1.Width / OpenGLControl1.Height; gluPerspective(45.0, Aspect, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); end; end.