1{ 2 *************************************************************************** 3 * * 4 * This source is free software; you can redistribute it and/or modify * 5 * it under the terms of the GNU General Public License as published by * 6 * the Free Software Foundation; either version 2 of the License, or * 7 * (at your option) any later version. * 8 * * 9 * This code is distributed in the hope that it will be useful, but * 10 * WITHOUT ANY WARRANTY; without even the implied warranty of * 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 12 * General Public License for more details. * 13 * * 14 * A copy of the GNU General Public License is available on the World * 15 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also * 16 * obtain it by writing to the Free Software Foundation, * 17 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * 18 * * 19 *************************************************************************** 20 21written 2001 by Satan 22 23} 24unit ExampleForm; 25 26{$mode objfpc}{$H+} 27 28interface 29 30uses 31 Classes, SysUtils, LazFileUtils, LazUTF8, LCLProc, Forms, LResources, Buttons, 32 StdCtrls, Dialogs, Graphics, IntfGraphics, GL, FPimage, OpenGLContext; 33 34const 35 GL_CLAMP_TO_EDGE = $812F; 36 37type 38 TglTexture = class 39 public 40 Width,Height: longint; 41 Data : pointer; 42 destructor Destroy; override; 43 end; 44 45type 46 47 { TExampleForm } 48 49 TExampleForm = class(TForm) 50 OpenGLControl1: TOpenGLControl; 51 ExitButton1: TButton; 52 LightingButton1: TButton; 53 BlendButton1: TButton; 54 MoveCubeButton1: TButton; 55 MoveBackgroundButton1: TButton; 56 RotateZButton1: TButton; 57 RotateZButton2: TButton; 58 HintLabel1: TLabel; 59 procedure IdleFunc(Sender: TObject; var Done: Boolean); 60 procedure FormResize(Sender: TObject); 61 procedure ExitButton1Click(Sender: TObject); 62 procedure LightingButton1Click(Sender: TObject); 63 procedure BlendButton1Click(Sender: TObject); 64 procedure MoveCubeButton1Click(Sender: TObject); 65 procedure MoveBackgroundButton1Click(Sender: TObject); 66 procedure RotateZButton1Click(Sender: TObject); 67 procedure RotateZButton2Click(Sender: TObject); 68 procedure OpenGLControl1Paint(Sender: TObject); 69 procedure OpenGLControl1Resize(Sender: TObject); 70 public 71 constructor Create(TheOwner: TComponent); override; 72 destructor Destroy; override; 73 procedure LoadTextures; 74 private 75 AreaInitialized: boolean; 76 FrameCount: integer; 77 LastFrameTicks: integer; 78 end; 79 80 TParticle = class 81 x, y, z: GLfloat; 82 vx, vy, vz: GLfloat; 83 life: single; 84 end; 85 86 TParticleEngine = class 87 xspawn: GLfloat; 88 Particle: array [1..2001] of TParticle; 89 procedure MoveParticles; 90 procedure DrawParticles; 91 procedure Start; 92 public 93 constructor Create; 94 destructor Destroy; override; 95 private 96 procedure RespawnParticle(i: integer); 97 end; 98 99var AnExampleForm: TExampleForm; 100 front, left1: GLuint; 101 rx, ry, rz, rrx, rry, rrz: single; 102 LightAmbient : array [0..3] of GLfloat; 103 checked, blended, lighted, ParticleBlended, MoveCube, MoveBackground: boolean; 104 textures : array [0..2] of GLuint; // Storage For 3 Textures 105 MyglTextures : array [0..2] of TglTexture; 106 lightamb, lightdif, lightpos, light2pos, light2dif, 107 light3pos, light3dif, light4pos, light4dif, fogcolor: array [0..3] of GLfloat; 108 ParticleEngine: TParticleEngine; 109 ParticleList, CubeList, BackList: GLuint; 110 111var direction: boolean; 112 timer: single; 113 LastMsecs: integer; 114 115function LoadFileToMemStream(const Filename: string): TMemoryStream; 116function LoadglTexImage2DFromPNG(PNGFilename:string; 117 Image: TglTexture): boolean; 118 119implementation 120 121 122function LoadFileToMemStream(const Filename: string): TMemoryStream; 123var FileStream: TFileStream; 124begin 125 Result:=TMemoryStream.Create; 126 try 127 FileStream:=TFileStream.Create(UTF8ToSys(Filename), fmOpenRead); 128 try 129 Result.CopyFrom(FileStream,FileStream.Size); 130 Result.Position:=0; 131 finally 132 FileStream.Free; 133 end; 134 except 135 Result.Free; 136 Result:=nil; 137 end; 138end; 139 140function LoadglTexImage2DFromPNG(PNGFilename: string; Image: TglTexture 141 ): boolean; 142var 143 png: TPortableNetworkGraphic; 144 IntfImg: TLazIntfImage; 145 y: Integer; 146 x: Integer; 147 c: TFPColor; 148 p: PByte; 149begin 150 Result:=false; 151 png:=TPortableNetworkGraphic.Create; 152 IntfImg:=nil; 153 try 154 png.LoadFromFile(PNGFilename); 155 IntfImg:=png.CreateIntfImage; 156 Image.Width:=IntfImg.Width; 157 Image.Height:=IntfImg.Height; 158 GetMem(Image.Data,Image.Width*Image.Height * 3); 159 p:=PByte(Image.Data); 160 for y:=0 to IntfImg.Height-1 do begin 161 for x:=0 to IntfImg.Width-1 do begin 162 c:=IntfImg.Colors[x,y]; 163 p^:=c.red shr 8; 164 inc(p); 165 p^:=c.green shr 8; 166 inc(p); 167 p^:=c.blue shr 8; 168 inc(p); 169 end; 170 end; 171 finally 172 png.Free; 173 IntfImg.Free; 174 end; 175 Result:=true; 176end; 177 178{ TExampleForm } 179 180constructor TExampleForm.Create(TheOwner: TComponent); 181begin 182 inherited CreateNew(TheOwner); 183 if LazarusResources.Find(ClassName)=nil then begin 184 SetBounds((Screen.Width-800) div 2,(Screen.Height-600) div 2,800,600); 185 Caption:='LCL example for the TOpenGLControl'; 186 187 Application.OnIdle:=@IdleFunc; 188 OnResize:=@FormResize; 189 blended:=false; 190 lighted:=false; 191 ParticleEngine:=TParticleEngine.Create; 192 193 ExitButton1:=TButton.Create(Self); 194 with ExitButton1 do begin 195 Name:='ExitButton1'; 196 Parent:=Self; 197 SetBounds(320,10,80,25); 198 Caption:='Exit'; 199 OnClick:=@ExitButton1Click; 200 end; 201 202 LightingButton1:=TButton.Create(Self); 203 with LightingButton1 do begin 204 Name:='LightingButton1'; 205 Parent:=Self; 206 SetBounds(220,0,80,25); 207 Caption:='Lighting'; 208 OnClick:=@LightingButton1Click; 209 end; 210 211 BlendButton1:=TButton.Create(Self); 212 with BlendButton1 do begin 213 Name:='BlendButton1'; 214 Parent:=Self; 215 SetBounds(220,0,80,25); 216 Caption:='Blending'; 217 OnClick:=@BlendButton1Click; 218 end; 219 220 MoveCubeButton1:=TButton.Create(Self); 221 with MoveCubeButton1 do begin 222 Name:='MoveCubeButton1'; 223 Parent:=Self; 224 SetBounds(320,10,80,25); 225 Caption:='Move Cube'; 226 Checked:=false; 227 OnClick:=@MoveCubeButton1Click; 228 end; 229 230 MoveBackgroundButton1:=TButton.Create(Self); 231 with MoveBackgroundButton1 do begin 232 Name:='MoveBackgroundButton1'; 233 Parent:=Self; 234 SetBounds(320,10,80,25); 235 Caption:='Move Back'; 236 Checked:=false; 237 OnClick:=@MoveBackgroundButton1Click; 238 end; 239 240 RotateZButton1:=TButton.Create(Self); 241 with RotateZButton1 do begin 242 Name:='RotateZButton1'; 243 Parent:=Self; 244 SetBounds(320,10,80,25); 245 Caption:='P. Respawn'; 246 Checked:=false; 247 OnClick:=@RotateZButton1Click; 248 end; 249 250 RotateZButton2:=TButton.Create(Self); 251 with RotateZButton2 do begin 252 Name:='RotateZButton2'; 253 Parent:=Self; 254 SetBounds(320,10,80,25); 255 Caption:='P. Blending'; 256 Checked:=false; 257 OnClick:=@RotateZButton2Click; 258 end; 259 260 HintLabel1:=TLabel.Create(Self); 261 with HintLabel1 do begin 262 Name:='HintLabel1'; 263 Parent:=Self; 264 SetBounds(0,0,280,50); 265 Caption:='Demo'; 266 end; 267 268 // resize the components first, because the opengl context needs some time to setup 269 FormResize(Self); 270 271 OpenGLControl1:=TOpenGLControl.Create(Self); 272 with OpenGLControl1 do begin 273 Name:='OpenGLControl1'; 274 Parent:=Self; 275 SetBounds(10,90,380,200); 276 OnPaint:=@OpenGLControl1Paint; 277 OnResize:=@OpenGLControl1Resize; 278 end; 279 280 end; 281 282 LoadTextures; 283 284 // now resize 285 FormResize(Self); 286end; 287 288destructor TExampleForm.Destroy; 289var i: integer; 290begin 291 for i:=0 to 2 do begin 292 Textures[i]:=0; 293 FreeAndNil(MyglTextures[i]); 294 end; 295 FreeAndNil(ParticleEngine); 296 297 inherited Destroy; 298end; 299 300procedure TExampleForm.LoadTextures; 301 302 procedure LoadglTexture(Filename:string; Image:TglTexture); 303 begin 304 Filename:=ExpandFileNameUTF8(Filename); 305 if not LoadglTexImage2DFromPNG(Filename,Image) then begin 306 MessageDlg('File not found', 307 'Image file not found: '+Filename, 308 mtError,[mbOk],0); 309 raise Exception.Create('Image file not found: '+Filename); 310 end; 311 end; 312 313var 314 i: Integer; 315begin 316 for i:=0 to 2 do begin 317 Textures[i]:=0; 318 MyglTextures[i]:=TglTexture.Create; 319 end; 320 {loading the texture and setting its parameters} 321 322 LoadglTexture('data/particle.png',MyglTextures[0]); 323 LoadglTexture('data/texture2.png',MyglTextures[1]); 324 LoadglTexture('data/texture3.png',MyglTextures[2]); 325end; 326 327// -------------------------------------------------------------------------- 328// Particle Engine 329// -------------------------------------------------------------------------- 330 331constructor TParticleEngine.Create; 332var i: integer; 333begin 334 for i:=1 to 2001 do Particle[i]:=TParticle.Create; 335 xspawn:=0; 336end; 337 338destructor TParticleEngine.Destroy; 339var i: integer; 340begin 341 for i:=1 to 2001 do FreeAndNil(Particle[i]); 342 inherited Destroy; 343end; 344 345procedure TParticleEngine.DrawParticles; 346var i: integer; 347begin 348 for i:=1 to 2001 do begin 349 glPushMatrix; 350 glTranslatef(Particle[i].x, Particle[i].y, Particle[i].z); 351 glCallList(ParticleList); 352 glPopMatrix; 353 end; 354end; 355 356procedure TParticleEngine.RespawnParticle(i: integer); 357begin 358 if (xspawn>2) and (direction=true) then direction:=false; 359 if (xspawn<-2) and (direction=false) then direction:=true; 360 if direction then 361 xspawn:=xspawn+0.0002*(timer/10) 362 else 363 xspawn:=xspawn-0.0002*(timer/10); 364 Particle[i].x:=xspawn; 365 Particle[i].y:=-0.5; 366 Particle[i].z:=0; 367 Particle[i].vx:=-0.005+GLFloat(random(2000))/200000; 368 Particle[i].vy:=0.035+GLFloat(random(750))/100000; 369 Particle[i].vz:=-0.005+GLFloat(random(2000))/200000; 370 Particle[i].life:=GLFloat(random(1250))/1000+1; 371end; 372 373procedure TParticleEngine.MoveParticles; 374var i: integer; 375begin 376 for i:=1 to 2001 do begin 377 if Particle[i].life>0 then begin 378 Particle[i].life:=Particle[i].life-0.01*(timer/10); 379 Particle[i].x:=Particle[i].x+Particle[i].vx*(timer/10); 380 381 Particle[i].vy:=Particle[i].vy-0.00035*(timer/10); // gravity 382 Particle[i].y:=Particle[i].y+Particle[i].vy*(timer/10); 383 384 Particle[i].z:=Particle[i].z+Particle[i].vz*(timer/10); 385 end else begin 386 RespawnParticle(i); 387 end; 388 end; 389end; 390 391procedure TParticleEngine.Start; 392var i: integer; 393begin 394 for i:=1 to 2001 do begin 395 RespawnParticle(i); 396 end; 397end; 398 399// --------------------------------------------------------------------------- 400// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 401// --------------------------------------------------------------------------- 402 403procedure TExampleForm.IdleFunc(Sender: TObject; var Done: Boolean); 404begin 405 OpenGLControl1.Invalidate; 406 //OpenGLControl1Paint(Self); 407 Done:=false; // tell lcl to handle messages and return immediatly 408end; 409 410// -------------------------------------------------------------------------- 411// Buttons 412// -------------------------------------------------------------------------- 413 414procedure TExampleForm.LightingButton1Click(Sender: TObject); 415begin 416 if lighted then glDisable(GL_LIGHTING) else glEnable(GL_LIGHTING); 417 lighted:=not lighted; 418 OpenGLControl1.Invalidate;// not need 419end; 420 421procedure TExampleForm.BlendButton1Click(Sender: TObject); 422begin 423 blended:=not blended; 424 OpenGLControl1.Invalidate; 425end; 426 427procedure TExampleForm.MoveCubeButton1Click(Sender: TObject); 428begin 429 MoveCube:=not MoveCube; 430 OpenGLControl1.Invalidate; 431end; 432 433procedure TExampleForm.MoveBackgroundButton1Click(Sender: TObject); 434begin 435 MoveBackground:=not MoveBackground; 436 OpenGLControl1.Invalidate; 437end; 438 439procedure TExampleForm.RotateZButton1Click(Sender: TObject); 440begin 441 ParticleEngine.Start; 442 OpenGLControl1.Invalidate; 443end; 444 445procedure TExampleForm.RotateZButton2Click(Sender: TObject); 446begin 447 ParticleBlended:=not ParticleBlended; 448 OpenGLControl1.Invalidate; 449end; 450 451// --------------------------------------------------------------------------- 452// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 453// --------------------------------------------------------------------------- 454 455procedure TExampleForm.FormResize(Sender: TObject); 456begin 457 if OpenGLControl1<>nil then 458 OpenGLControl1.SetBounds(10, 30, Width-120, Height-40); 459 ExitButton1.SetBounds(Width-90, 5, 80, 25); 460 LightingButton1.SetBounds(Width-90, 180, 80, 25); 461 BlendButton1.SetBounds(Width-90, 210, 80, 25); 462 MoveCubeButton1.SetBounds(Width-90, 50, 80, 25); 463 MoveBackgroundButton1.SetBounds(Width-90, 80, 80, 25); 464 RotateZButton1.SetBounds(Width-90, 115, 80, 25); 465 RotateZButton2.SetBounds(Width-90, 145, 80, 25); 466 HintLabel1.SetBounds(10, 0, 80, 25); 467end; 468 469procedure TExampleForm.ExitButton1Click(Sender: TObject); 470begin 471 Close; 472end; 473 474procedure TExampleForm.OpenGLControl1Paint(Sender: TObject); 475 476 procedure myInit; 477 begin 478 {init lighting variables} 479 {ambient color} 480 lightamb[0]:=0.5; 481 lightamb[1]:=0.5; 482 lightamb[2]:=0.5; 483 lightamb[3]:=1.0; 484 {diffuse color} 485 lightdif[0]:=0.8; 486 lightdif[1]:=0.0; 487 lightdif[2]:=0.0; 488 lightdif[3]:=1.0; 489 {diffuse position} 490 lightpos[0]:=0.0; 491 lightpos[1]:=0.0; 492 lightpos[2]:=3.0; 493 lightpos[3]:=1.0; 494 {diffuse 2 color} 495 light2dif[0]:=0.0; 496 light2dif[1]:=0.8; 497 light2dif[2]:=0.0; 498 light2dif[3]:=1.0; 499 {diffuse 2 position} 500 light2pos[0]:=3.0; 501 light2pos[1]:=0.0; 502 light2pos[2]:=3.0; 503 light2pos[3]:=1.0; 504 {diffuse 3 color} 505 light3dif[0]:=0.0; 506 light3dif[1]:=0.0; 507 light3dif[2]:=0.8; 508 light3dif[3]:=1.0; 509 {diffuse 3 position} 510 light3pos[0]:=-3.0; 511 light3pos[1]:=0.0; 512 light3pos[2]:=0.0; 513 light3pos[3]:=1.0; 514 {fog color} 515 516 fogcolor[0]:=0.5; 517 fogcolor[1]:=0.5; 518 fogcolor[2]:=0.5; 519 fogcolor[3]:=1.0; 520 521 end; 522 523const GLInitialized: boolean = false; 524 525procedure InitGL; 526var 527 i: Integer; 528begin 529 if GLInitialized then exit; 530 GLInitialized:=true; 531 {setting lighting conditions} 532 glLightfv(GL_LIGHT0,GL_AMBIENT,lightamb); 533 glLightfv(GL_LIGHT1,GL_AMBIENT,lightamb); 534 glLightfv(GL_LIGHT2,GL_DIFFUSE,lightdif); 535 glLightfv(GL_LIGHT2,GL_POSITION,lightpos); 536 glLightfv(GL_LIGHT3,GL_DIFFUSE,light2dif); 537 glLightfv(GL_LIGHT3,GL_POSITION,light2pos); 538 glLightfv(GL_LIGHT4,GL_POSITION,light3pos); 539 glLightfv(GL_LIGHT4,GL_DIFFUSE,light3dif); 540 glEnable(GL_LIGHT0); 541 glEnable(GL_LIGHT1); 542 glEnable(GL_LIGHT2); 543 glEnable(GL_LIGHT3); 544 glEnable(GL_LIGHT4); 545 546 glGenTextures(3, @textures[0]); 547 for i:=0 to 2 do begin 548 glBindTexture(GL_TEXTURE_2D, Textures[i]); 549 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); 550 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); 551 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 552 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 553 glTexImage2D(GL_TEXTURE_2D,0,3,MyglTextures[i].Width,MyglTextures[i].Height,0 554 ,GL_RGB,GL_UNSIGNED_BYTE,MyglTextures[i].Data); 555 end; 556 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 557 {instead of GL_MODULATE you can try GL_DECAL or GL_BLEND} 558 glEnable(GL_TEXTURE_2D); // enables 2d textures 559 glClearColor(0.0,0.0,0.0,1.0); // sets background color 560 glClearDepth(1.0); 561 glDepthFunc(GL_LEQUAL); // the type of depth test to do 562 glEnable(GL_DEPTH_TEST); // enables depth testing 563 glShadeModel(GL_SMOOTH); // enables smooth color shading 564 {blending} 565 glColor4f(1.0,1.0,1.0,0.5); // Full Brightness, 50% Alpha ( NEW ) 566 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 567 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 568 {} 569 glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); 570 glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST); 571 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); 572 573 // creating display lists 574 575 ParticleList:=glGenLists(1); 576 glNewList(ParticleList, GL_COMPILE); 577 glBindTexture(GL_TEXTURE_2D, textures[0]); 578 glBegin(GL_TRIANGLE_STRIP); 579 glNormal3f( 0.0, 0.0, 1.0); 580 glTexCoord2f( 1.0, 1.0); glVertex3f(+0.025, +0.025, 0); 581 glTexCoord2f( 0.0, 1.0); glVertex3f(-0.025, +0.025, 0); 582 glTexCoord2f( 1.0, 0.0); glVertex3f(+0.025, -0.025, 0); 583 glTexCoord2f( 0.0, 0.0); glVertex3f(-0.025, -0.025, 0); 584 glEnd; 585 glEndList; 586 587 BackList:=ParticleList+1; 588 glNewList(BackList, GL_COMPILE); 589 glBindTexture(GL_TEXTURE_2D, textures[2]); 590 glBegin(GL_QUADS); 591 {Front Face} 592 glNormal3f( 0.0, 0.0, 1.0); 593 glTexCoord2f( 1.0, 1.0); glVertex3f( 2.5, 2.5, 2.5); 594 glTexCoord2f( 0.0, 1.0); glVertex3f(-2.5, 2.5, 2.5); 595 glTexCoord2f( 0.0, 0.0); glVertex3f(-2.5,-2.5, 2.5); 596 glTexCoord2f( 1.0, 0.0); glVertex3f( 2.5,-2.5, 2.5); 597 {Back Face} 598 glNormal3f( 0.0, 0.0,-1.0); 599 glTexCoord2f( 0.0, 1.0); glVertex3f( 2.5, 2.5,-2.5); 600 glTexCoord2f( 0.0, 0.0); glVertex3f( 2.5,-2.5,-2.5); 601 glTexCoord2f( 1.0, 0.0); glVertex3f(-2.5,-2.5,-2.5); 602 glTexCoord2f( 1.0, 1.0); glVertex3f(-2.5, 2.5,-2.5); 603 {Left Face} 604 glNormal3f(-1.0, 0.0, 0.0); 605 glTexCoord2f( 1.0, 1.0); glVertex3f(-2.5, 2.5, 2.5); 606 glTexCoord2f( 0.0, 1.0); glVertex3f(-2.5, 2.5,-2.5); 607 glTexCoord2f( 0.0, 0.0); glVertex3f(-2.5,-2.5,-2.5); 608 glTexCoord2f( 1.0, 0.0); glVertex3f(-2.5,-2.5, 2.5); 609 {Right Face} 610 glNormal3f( 1.0, 0.0, 0.0); 611 glTexCoord2f( 1.0, 1.0); glVertex3f( 2.5, 2.5,-2.5); 612 glTexCoord2f( 0.0, 1.0); glVertex3f( 2.5, 2.5, 2.5); 613 glTexCoord2f( 0.0, 0.0); glVertex3f( 2.5,-2.5, 2.5); 614 glTexCoord2f( 1.0, 0.0); glVertex3f( 2.5,-2.5,-2.5); 615 {Top Face} 616 glNormal3f( 0.0, 1.0, 0.0); 617 glTexCoord2f( 1.0, 1.0); glVertex3f( 2.5, 2.5,-2.5); 618 glTexCoord2f( 0.0, 1.0); glVertex3f(-2.5, 2.5,-2.5); 619 glTexCoord2f( 0.0, 0.0); glVertex3f(-2.5, 2.5, 2.5); 620 glTexCoord2f( 1.0, 0.0); glVertex3f( 2.5, 2.5, 2.5); 621 {Bottom Face} 622 glNormal3f( 0.0,-1.0, 0.0); 623 glTexCoord2f( 1.0, 1.0); glVertex3f(-2.5,-2.5,-2.5); 624 glTexCoord2f( 0.0, 1.0); glVertex3f( 2.5,-2.5,-2.5); 625 glTexCoord2f( 0.0, 0.0); glVertex3f( 2.5,-2.5, 2.5); 626 glTexCoord2f( 1.0, 0.0); glVertex3f(-2.5,-2.5, 2.5); 627 628 glEnd; 629 glEndList; 630 631 CubeList:=BackList+1; 632 glNewList(CubeList, GL_COMPILE); 633 glBindTexture(GL_TEXTURE_2D, textures[1]); 634 glBegin(GL_QUADS); 635 {Front Face} 636 glNormal3f( 0.0, 0.0, 1.0); 637 glTexCoord2f( 1.0, 1.0); glVertex3f( 0.5, 0.5, 0.5); 638 glTexCoord2f( 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); 639 glTexCoord2f( 0.0, 0.0); glVertex3f(-0.5,-0.5, 0.5); 640 glTexCoord2f( 1.0, 0.0); glVertex3f( 0.5,-0.5, 0.5); 641 {Back Face} 642 glNormal3f( 0.0, 0.0,-1.0); 643 glTexCoord2f( 0.0, 1.0); glVertex3f( 0.5, 0.5,-0.5); 644 glTexCoord2f( 0.0, 0.0); glVertex3f( 0.5,-0.5,-0.5); 645 glTexCoord2f( 1.0, 0.0); glVertex3f(-0.5,-0.5,-0.5); 646 glTexCoord2f( 1.0, 1.0); glVertex3f(-0.5, 0.5,-0.5); 647 glEnd; 648 glBindTexture(GL_TEXTURE_2D, textures[1]); 649 glBegin(GL_QUADS); 650 {Left Face} 651 glNormal3f(-1.0, 0.0, 0.0); 652 glTexCoord2f( 1.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); 653 glTexCoord2f( 0.0, 1.0); glVertex3f(-0.5, 0.5,-0.5); 654 glTexCoord2f( 0.0, 0.0); glVertex3f(-0.5,-0.5,-0.5); 655 glTexCoord2f( 1.0, 0.0); glVertex3f(-0.5,-0.5, 0.5); 656 {Right Face} 657 glNormal3f( 1.0, 0.0, 0.0); 658 glTexCoord2f( 1.0, 1.0); glVertex3f( 0.5, 0.5,-0.5); 659 glTexCoord2f( 0.0, 1.0); glVertex3f( 0.5, 0.5, 0.5); 660 glTexCoord2f( 0.0, 0.0); glVertex3f( 0.5,-0.5, 0.5); 661 glTexCoord2f( 1.0, 0.0); glVertex3f( 0.5,-0.5,-0.5); 662 glEnd; 663 glBindTexture(GL_TEXTURE_2D, textures[2]); 664 glBegin(GL_QUADS); 665 {Top Face} 666 glNormal3f( 0.0, 1.0, 0.0); 667 glTexCoord2f( 1.0, 1.0); glVertex3f( 0.5, 0.5,-0.5); 668 glTexCoord2f( 0.0, 1.0); glVertex3f(-0.5, 0.5,-0.5); 669 glTexCoord2f( 0.0, 0.0); glVertex3f(-0.5, 0.5, 0.5); 670 glTexCoord2f( 1.0, 0.0); glVertex3f( 0.5, 0.5, 0.5); 671 {Bottom Face} 672 glNormal3f( 0.0,-1.0, 0.0); 673 glTexCoord2f( 1.0, 1.0); glVertex3f(-0.5,-0.5,-0.5); 674 glTexCoord2f( 0.0, 1.0); glVertex3f( 0.5,-0.5,-0.5); 675 glTexCoord2f( 0.0, 0.0); glVertex3f( 0.5,-0.5, 0.5); 676 glTexCoord2f( 1.0, 0.0); glVertex3f(-0.5,-0.5, 0.5); 677 glEnd; 678 glEndList; 679 680end; 681 682var 683 CurTime: TDateTime; 684 MSecs: integer; 685begin 686 inc(FrameCount); 687 inc(LastFrameTicks,OpenGLControl1.FrameDiffTimeInMSecs); 688 if (LastFrameTicks>=1000) then begin 689 DebugLn(['TExampleForm.OpenGLControl1Paint Frames per second: ',FrameCount]); 690 dec(LastFrameTicks,1000); 691 FrameCount:=0; 692 end; 693 694 if OpenGLControl1.MakeCurrent then 695 begin 696 if not AreaInitialized then begin 697 myInit; 698 InitGL; 699 glMatrixMode (GL_PROJECTION); { prepare for and then } 700 glLoadIdentity (); { define the projection } 701 glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); { transformation } 702 glMatrixMode (GL_MODELVIEW); { back to modelview matrix } 703 glViewport (0, 0, OpenGLControl1.Width, OpenGLControl1.Height); 704 { define the viewport } 705 AreaInitialized:=true; 706 end; 707 708 CurTime:=Now; 709 MSecs:=round(CurTime*86400*1000) mod 1000; 710 if MSecs<0 then MSecs:=1000+MSecs; 711 timer:=msecs-LastMsecs; 712 if timer<0 then timer:=1000+timer; 713 LastMsecs:=MSecs; 714 715 ParticleEngine.MoveParticles; 716 717 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); 718 glLoadIdentity; { clear the matrix } 719 glTranslatef (0.0, 0.0,-3.0); // -2.5); { viewing transformation } 720 {rotate} 721 722 glPushMatrix; 723 724 if MoveBackground then begin 725 rrx:=rrx-0.6*(timer/10); 726 rry:=rry-0.5*(timer/10); 727 rrz:=rrz-0.3*(timer/10); 728 end; 729 730 glRotatef(rrx,1.0,0.0,0.0); 731 glRotatef(rry,0.0,1.0,0.0); 732 glRotatef(rrz,0.0,0.0,1.0); 733 734 // draw background 735 if blended then begin 736 glEnable(GL_BLEND); 737 glDisable(GL_DEPTH_TEST); 738 end; 739 glCallList(BackList); 740 741 glPopMatrix; 742 743 glPushMatrix; 744 745 if MoveCube then begin 746 rx:=rx+0.5*(timer/10); 747 ry:=ry+0.25*(timer/10); 748 rz:=rz+0.8*(timer/10); 749 end; 750 751 glRotatef(rx,1.0,0.0,0.0); 752 glRotatef(ry,0.0,1.0,0.0); 753 glRotatef(rz,0.0,0.0,1.0); 754 755 // draw cube 756 glCallList(CubeList); 757 if blended then begin 758 glDisable(GL_BLEND); 759 glEnable(GL_DEPTH_TEST); 760 end; 761 762 glPopMatrix; 763 764 if ParticleBlended then glEnable(GL_BLEND); 765 ParticleEngine.DrawParticles; 766 if ParticleBlended then glDisable(GL_BLEND); 767 //glFlush; 768 //glFinish; 769 // Swap backbuffer to front 770 OpenGLControl1.SwapBuffers; 771 end; 772end; 773 774procedure TExampleForm.OpenGLControl1Resize(Sender: TObject); 775begin 776 if (AreaInitialized) 777 and OpenGLControl1.MakeCurrent then 778 glViewport (0, 0, OpenGLControl1.Width, OpenGLControl1.Height); 779end; 780 781 782{ TglTexture } 783 784destructor TglTexture.Destroy; 785begin 786 if Data<>nil then FreeMem(Data); 787 inherited Destroy; 788end; 789 790end. 791