DelphiでのOpenGL開発入門
14131 ワード
unit Unit1;
interface
uses
OpenGL,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
angle:single;
procedure Draw; //Draws an OpenGL scene on request
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function getNormal(p1,p2,p3:TGLArrayf3):TGLArrayf3;
var a,b:TGLArrayf3;
begin
//make two vectors
a[0]:=p2[0]-p1[0]; a[1]:=p2[1]-p1[1]; a[2]:=p2[2]-p1[2];
b[0]:=p3[0]-p1[0]; b[1]:=p3[1]-p1[1]; b[2]:=p3[2]-p1[2];
//calculate cross-product
result[0]:=a[1]*b[2]-a[2]*b[1];
result[1]:=a[2]*b[0]-a[0]*b[2];
result[2]:=a[0]*b[1]-a[1]*b[0];
end;
procedure setupPixelFormat(DC:HDC);
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR); // size
nVersion:1; // version
dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
PFD_DOUBLEBUFFER; // support double-buffering
iPixelType:PFD_TYPE_RGBA; // color type
cColorBits:24; // preferred color depth
cRedBits:0; cRedShift:0; // color bits (ignored)
cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:0; cAlphaShift:0; // no alpha buffer
cAccumBits: 0;
cAccumRedBits: 0; // no accumulation buffer,
cAccumGreenBits: 0; // accum bits (ignored)
cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:16; // depth buffer
cStencilBits:0; // no stencil buffer
cAuxBuffers:0; // no auxiliary buffers
iLayerType:PFD_MAIN_PLANE; // main layer
bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0; // no layer, visible, damage masks
);
var pixelFormat:integer;
begin
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then
exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
exit;
end;
procedure GLInit;
const
light0_position:TGLArrayf4=( -8.0, 8.0, -16.0, 0.0);
ambient: TGLArrayf4=( 0.3, 0.3, 0.3, 0.3);
begin
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.3, 25.0);
// position viewer */
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
// set lights
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_POSITION, @light0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, @ambient);
glEnable(GL_LIGHT0);
end;
procedure TForm1.Draw;
const D=1.5;
H1=D/1.732;
H2=D*1.732-H1; // D/H = tg(30) = 1/sqrt(3)
HY=3.0;
const //vertexes
a1:TGLArrayf3=(-D, 0, -H1);
a2:TGLArrayf3=(D, 0, -H1);
a3:TGLArrayf3=(0, 0, H2);
a4:TGLArrayf3=(0, HY, 0);
var n1, n2, n3, n4: TGLArrayf3; //normals
begin
n1 := getNormal(a1,a3,a2);
n2 := getNormal(a1,a2,a4);
n3 := getNormal(a2,a3,a4);
n4 := getNormal(a3,a1,a4);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glEnable(GL_NORMALIZE);
glShadeModel(GL_FLAT);
glCullFace(GL_BACK);
glLoadIdentity;
glTranslatef(0.0, 0.0, -12.0);
glBegin(GL_TRIANGLES);
glNormal3fv(@n1);
glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a3);
glNormal3fv(@n2);
glVertex3fv(@a1); glVertex3fv(@a2); glVertex3fv(@a4);
glNormal3fv(@n3);
glVertex3fv(@a2); glVertex3fv(@a3); glVertex3fv(@a4);
glNormal3fv(@n4);
glVertex3fv(@a3); glVertex3fv(@a1); glVertex3fv(@a4);
glEnd;
SwapBuffers(wglGetCurrentDC);
end;
procedure TForm1.FormCreate(Sender: TObject);
var DC:HDC;
RC:HGLRC;
i:integer;
begin
DC:=GetDC(Handle); //Actually, you can use any windowed control here
SetupPixelFormat(DC);
RC:=wglCreateContext(DC); //makes OpenGL window out of DC
wglMakeCurrent(DC, RC); //makes OpenGL window active
GLInit; //initialize OpenGL
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
Draw;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
angle:=angle+1.0;
Draw;
end;
end.