Задача: создать сцену вращения звезд на 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, звезды, вращение, сияние
|
|||||||