texture_xcoords:array [0..511] of glubyte
X координатытекстур
texture_ycoords:array [0..511] of glubyte
Y координатытекстур
object_name:array [0..15] of char
имятекущегообъекта
texture:array[0..$ff,0..$ff,0..2] of glubyte
последовательно перечислены составляющие красного, зеленого и голубого цветов для каждой из точек рисунка.
rx,ry : Glfloat
поворот объекта от начального состояния вокруг осей OX и OY.
tx : Glfloat
перенос от начального положения оп оси OZ.
current_poligon:byte
номер полигона, обрабатываемого в данный момент. Счет начинается с нуля.
ptr:word
Указатель. Т.к. создан массив для каждой из координат точек и каждой из координат текстуры, то по этому индексу одновременно можно обратиться ко всем характеристикам какой-либо точки.
dots_num:word
число точек из которых состоит грань.
current_dot:word
текущая обрабатываемая точка грани
locked_dot:byte
номер вершины текстуры на которую наведен курсор (форма №2).
Если курсор не указывает не на одну из точек, то переменная равна $FF
Кроме вышеперечисленных, существует еще ряд переменных, использующихся, в основном, при организации циклов FOR.
Текст основных подпрограмм
Процедура ‘Detal’ - собственна само изображение объекта на экране.
Для повышения быстродействия, написаны отдельные части кода для работы с треугольниками, четырехугольниками, и гранями, имеющими количество углом больше четырех. В зависимости от режима работы, текстура либо налагается, либо нет.
procedure TForm1.Detal;
var a:integer;
begin
a:=0;
if texturing=true then glEnable (GL_TEXTURE_2D);
while pols[a]<>0 do begin
if pols[a]=3 then begin inc (a);
glBegin (GL_TRIANGLES) ;
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
glEnd; end;
if pols[a]=4 then begin inc (a);
glBegin (GL_Quads) ;
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
glEnd; end;
if pols[a]>4 then begin inc (a);
glBegin (GL_Polygon) ;
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
if pols[a]=$ff then continue;
if texturing=true then glTexCoord2d (d*texture_ycoords[a],d*texture_xcoords[a]);
glVertex3f(fx[pols[a]], fy[pols[a]], fz[pols[a]]); inc (a);
glEnd;
end;end;
if texturing=true then glDisable (GL_TEXTURE_2D);
end;
Выполняется подготовка к выводу очередного кадра: очищается Z буфер, выполняются необходимые преобразования координат. Затем обрисовывается объект и изображение переносится из виртуального экрана на экран.
procedure TForm1.FormPaint(Sender: TObject);
begin
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glPushMatrix;
glTranslatef (0, 0.0, tx);
glRotatef (rx, 1.0, 0.0, 0.0);
glRotatef (ry, 0.0, 1.0, 0.0);
Detal;
glPopMatrix;
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;
Создание формы. Инициализация рабочих массивов, создание контекста воспроизведения и связь его с окном формы. Определение атрибутов формы, включениеZ буфера.
procedure TForm1.FormCreate(Sender: TObject);
var x:integer;
begin
for x:=0 to 22 do pols[x]:=pols_start[x];
for x:=0 to dots do fx[x]:=fx_start[x];
for x:=0 to dots do fy[x]:=fy_start[x];
for x:=0 to dots do fz[x]:=fz_start[x];
for x:=0 to poligons do pols_pointer[x]:=pols_pointer_start[x];
for x:=0 to 22 do texture_xcoords[x]:=texture_xcoords_start[x];
for x:=0 to 22 do texture_ycoords[x]:=texture_ycoords_start[x];
Bitmap := TBitmap.Create;
DC := GetDC (Handle);
SetDCPixelFormat(DC);
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
glClearColor (0.5, 0.5, 0.75, 1.0);
glColor3f (0.0, 0.0, 0.0
glLineWidth (1);
Form1.Color:=$c08080;
glEnable (GL_DEPTH_TEST);
statusbar1.Panels.Items[0].Text:='Имяобъекта: '+object_name;
statusbar1.Panels.Items[1].Text:='Точек: '+inttostr(dots);
statusbar1.Panels.Items[2].Text:=Полигонов: '+inttostr(poligons);
end;
Освобождение памяти занимаемой программой, выполняется при закрытии приложения.
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
ReleaseDC (Handle, DC);
DeleteDC (DC);
Bitmap.Free;
end;
Изменение размеров формы. Т.к. размер формы в ходе работы приложения изменить невозможно, то процедура выполняется лишь раз, при запуске программы. Выполняются действия, необходимые для корректной работы OpenGL.
procedure TForm1.FormResize(Sender: TObject);
begin
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1, 1, -1, 1, 2, 29);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
glTranslatef(0.0, 0.0, -6.0);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE) ;
end;
Процедура загрузки текстуры в предназначенный для нее массив. После загрузки задаются необходимые параметры текстурирования, инициализируется форма №2.
procedure TForm1.Texture1Click(Sender: TObject);
var x,y:integer;
begin
opendialog1.Filter:='Texture file (Bitmap 256*256)|*.bmp';
if opendialog1.Execute then begin
Form2.Image1.Picture.LoadFromFile(opendialog1.FileName);
Bitmap.LoadFromFile(opendialog1.FileName);
for y:=0 to $ff do begin
for x:=0 to $ff do begin
texture[x,y,0]:=GetRValue(Bitmap.Canvas.Pixels [x,y]);
texture[x,y,1]:=GetGValue(Bitmap.Canvas.Pixels[x,y]);;
texture[x,y,2]:=GetBValue(Bitmap.Canvas.Pixels[x,y]);
end;end;
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2d(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, @texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Form2_prepearing;
Form2.show;
Form2.paintpoligon;
end; end;
Заключение
Конечно же, данная работа не претендует на пример использования библиотеки OpenGL с полной отдачей. Даже затронутая тема облегания тела поверхностью раскрыта не полностью. Однако, это скорее говорит не о слабом использовании предоставляемых OpenGL возможностей, а об их почти неограниченном количестве. С внедрением этой библиотеки, программисты при работе с графикой освободились от написания огромного количества одинаковых процедур и от требования обязательных навыков программирования на языках низкого уровня. Кроме того, появилась возможность создать полноценное качественное приложение почти без знаний математических принципов трехмерной графики и формул цветовых смешений.
Список литературы
1. OpenGL. Графика в проектах Delphi. М. Краснов.
2. OpenGL. Игорь Тарасов.
3. Материалы с сайта ‘opengl.org.ru’.
4. Компьютерная графика. Полигональные модели Шикин А. В., Боресков Л. В.
5. 3D programming FAQ. АндрейАксёнов.