Звезды

gif.

Задача: создать сцену вращения звезд на OpenGL.

Среда разработки: Delphi7

Исходный код содержит комментарии по основным пунктам

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  OpenGL, math, ExtCtrls;
 
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    DC : HDC;
    hrc: HGLRC;
    quadObj : GLUquadricObj;
    Bitmap: TBitmap;
    Bits: Array [0..127, 0..127, 0..3] of GLubyte;   // массив битов текстуры
    stars:array[1..100,1..7] of glfloat; //массив звезд
    c,p:integer;
    a,g:glfloat;
    procedure BmpTexture;
  end;
 
var
  Form1: TForm1;
  mode : (POINT, LINE, FILL, SILHOUETTE) = FILL;
  gluobj : (SPHERE, CONE, CYLINDER, DISK) = SPHERE;
  orientation : (OUTSIDE, INSIDE) = OUTSIDE;
  normals : (NONE, FLAT, SMOOTH) = SMOOTH;
 
implementation
 
{$R *.DFM}
 
procedure TForm1.BmpTexture; //процедура загрузки картинки текстуры
var
  i, j: Integer;
begin
   bitmap := TBitmap.Create;
   bitmap.LoadFromFile('star.bmp'); //открываем файл
    For i := 0 to 127 do
      For j := 0 to 127 do begin
        bits [i, j, 0] := GetRValue(bitmap.Canvas.Pixels[i,j]);
        bits [i, j, 1] := GetGValue(bitmap.Canvas.Pixels[i,j]);
        bits [i, j, 2] := GetBValue(bitmap.Canvas.Pixels[i,j]);
        bits[i, j, 3]:=bits [i, j, 0]; // прозрачность рисунка
 end;
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); //параметры отображения текстуры
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,128,128,0,GL_RGBA,GL_UNSIGNED_BYTE,@bits); // бла бла бла
glEnable(GL_TEXTURE_2D);
glenable(gl_blend); // врубаем прозрачность
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
end;
 
{Перерисовка окна}
procedure TForm1.FormPaint(Sender: TObject);
var
  i:integer;
begin
 glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);      // очистка буфера цвета
for i := 1 to 100 do //рисуем звезды
begin
 if stars[i,7] <> 0 then
 begin
 glPushMatrix;
 glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  glRotatef (stars[i,1], 0.0, 0.0, 1.0); //поворот звезды относительно центра рисунка
     glTranslatef(0.0, stars[i,3], 0.0);   // перенос объекта - ось Y
     glRotatef (stars[i,2], 0.0, 0.0, 0.5);  //поворот звезды относительно ее
      glColor3f(stars[i,4],stars[i,5],stars[i,6]);  //цвет звезды
   glBegin (GL_quads);
        glTexCoord2d (1, 0.0); //накладываем текстуру на квадрат
        glVertex3f (-1.0, -1.0, 0.0);
	      glTexCoord2d (1, 1.0);
        glVertex3f (1.0, -1.0, 0.0);
	      glTexCoord2d (0.0, 1.0);
        glVertex3f (1, 1, 0.0);
        glTexCoord2d (0.0, 0.0);
        glVertex3f (-1.0, 1, 0.0);
    glEnd;
    gldisable(GL_TEXTURE_2D);
 gldisable(GL_BLEND);
 glPopMatrix;
 end;
end;
 SwapBuffers(DC);
end;
 
{Формат пикселя}
procedure SetDCPixelFormat (hdc : HDC);
var
 pfd : TPixelFormatDescriptor;
 nPixelFormat : Integer;
begin
 FillChar (pfd, SizeOf (pfd), 0);
 pfd.dwFlags  := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
 nPixelFormat := ChoosePixelFormat (hdc, @pfd);
 SetPixelFormat (hdc, nPixelFormat, @pfd);
end;
 
{Создание формы}
procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
begin
 DC := GetDC (Handle);
 SetDCPixelFormat(DC);
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);
 glLineWidth (1.5);
 glEnable (GL_LIGHTING);   //врубаем свет
 glEnable (GL_LIGHT0);
 glEnable (GL_COLOR_MATERIAL);
 quadObj := gluNewQuadric;
 BmpTexture;
  glShadeModel(GL_SMOOTH);
  glClearColor(0.0, 0.0, 0.0, 0.5);
  glClearDepth(1.0);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE);
  a := 0;
  g := 0;
end;
 
{Конец работы приложения}
procedure TForm1.FormDestroy(Sender: TObject);
begin
 gluDeleteQuadric (quadObj);
 wglMakeCurrent(0, 0);
 wglDeleteContext(hrc);
 ReleaseDC (Handle, DC);
 DeleteDC (DC);
end;
 
procedure TForm1.FormResize(Sender: TObject);
begin
 glViewport(0, 0, ClientWidth, ClientHeight);
 glMatrixMode (GL_PROJECTION);
 glLoadIdentity;
 glFrustum (-1, 1, -1, 1, 2, 10);
 glMatrixMode (GL_MODELVIEW);
 glLoadIdentity;
 glTranslatef(0.0, 0.0, -5.0);   // перенос объекта - ось Z
 InvalidateRect(Handle, nil, False);
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
var
  i:integer;
begin
  p := p + 1;
  if p > 10 then
  begin
    p := 0;
    c := c + 1;
    if c > 100 then
      c := 1;
    if c mod 30 = 0 then
      g := g + 36;
    a := a + g;
    stars[c,1] := a;
    stars[c,3] := 2.5;
    stars[c,4] := random(256)/255;
    stars[c,5] := random(256)/255;
    stars[c,6] := random(256)/255;
    stars[c,7] := 1;
  end;
  for i := 1 to 100 do
  begin
    if stars[i,7] <> 0 then // меняем положение звёзд
    begin
      stars[i,1] := stars[i,1] + 1;
      stars[i,2] := stars[i,2] - 5;
      stars[i,3] := stars[i,3] - 0.005;
      if stars[i,3] < 0 then // если она достигла центра перестаем рисовать
        stars[i,7] := 0;
    end;
  end;
  InvalidateRect(Handle, nil, False);
end;
 
end.

Ключевые слова: 
openGL, звезды, вращение, сияние
ВложениеРазмер
stars.zip214.48 кб