• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

OpenGL и Delphi на практике

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Сообщения
1,151
Симпатии
222
Баллы
155
VK
Для начала придется проделать подготовительную работу:

  • настроить формат пикселей с учетом отображаемой информации;
  • создать контекст OpenGL и подготовить сам движок OpenGL к работе.
Формат пикселей удобно вынести в отдельную процедуру, которую мы оформим следующим образом:
Код:
procedure SetDCPixelFormat (dc: HDC);
var           pfd: TPixelFormatDescriptor;
     nPixelFormat: Integer;
begin
  FillChar (pfd, SizeOf (pfd),0);
  with pfd do
    begin
      nSize:= sizeof (pfd);
      nVersion:= 1;
      dwFlags:= PFD_DRAW_TO_WINDOW or
      PFD_SUPPORT_OPENGL or
      PFD_DOUBLEBUFFER;
      iPixelType:= PFD_TYPE_RGBA;
      cColorBits:= 16;
      cDepthBits:= 64;
      iLayerType:= PFD_MAIN_PLANE;
    end;
  nPixelFormat:=ChoosePixelFormat (DC,@pfd);
  SetPixelFormat (DC, nPixelFormat,@pfd);
end;
Здесь при заполнении структуры TPixelFormatDescriptor мы задаем параметры будущего графического отображения, в том числе количество цветовых бит, а также тип пикселей (iPixelType). Мы также задаем флаги, которые, как видно из названия, указывают, что наша программа будет поддерживать OpenGL, а также что мы будем рисовать в окне и использовать двойную буферизацию (параметр, необходимый для воспроизведения движущихся объектов).

Далее посредством вызова ChoosePixelFormat система выбирает подходящий формат пикселя - и мы присваиваем его (через SetPixelFormat) нашему окну.

Теперь нужно инициализировать контекст самого OpenGL посредством функций, содержащихся в модуле Windows, и произвести дополнительную настройку движка:
Код:
procedure TForm1.FormCreate (Sender: TObject);
begin
  H:=Handle;
  DC:=GetDC (H);
  SetDCPixelFormat (DC);
  RC:=wglCreateContext (DC);
  wglMakeCurrent (DC, RC);
  glClearColor (0.6,0.6,0.6,1.0);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity;
  glFrustum (-1,1,-1,1,2,20);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity;
  glTranslatef (0.0,-1.0,-6.0);
  BeginPaint;
end;
Как видим, сначала мы задали для нашей графики необходимый формат пикселей. Теперь при помощи функции wglCreateContext создаем OpenGL-контекст, а впоследствии делаем его текущим контекстом. Далее, используя уже универсальные функции**, произведем настройку "мира", который будем создавать. Для этого через glClearColor очистим контекст и заполним ее 60-процентным черным цветом. Далее выберем матрицу проекций, которая определяет, как будут проецироваться трехмерные объекты на плоскость экрана (в оконные координаты) и через glLoadIdentity установим единичную матрицу и зададим границы плана в "мировых координатах" при помощи вызова glFrustum. После чего загрузим модельно видовую матрицу и произведем ее смещение (glTranslatef).
Прорисовка сцены
Код:
unit MainForm;


interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,OpenGL, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
   RC:HGLRC;
   DC:HDC;
   H:THandle;
   procedure BeginPaint;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

const mat1_dif:Array[0..2] of Single = (0.8,0.8,0.0);
const mat1_amb:Array[0..2] of Single = (0.2,0.2,0.2);
const mat1_spec:Array[0..2] of Single = (0.6,0.6,0.6);
const mat1_shininess = 0.5*128;

procedure DrawElement(A,b,R0,r1:Single);
procedure DrawFace(A,R:Single;Normal:Boolean);
implementation
procedure SetDCPixelFormat(dc:HDC);
var pfd:TPixelFormatDescriptor;
    nPixelFormat:Integer;
begin
FillChar(pfd,SizeOf(pfd),0);
with pfd do
begin
  nSize     := sizeof(pfd);
  nVersion  := 1;
  dwFlags   := PFD_DRAW_TO_WINDOW or
               PFD_SUPPORT_OPENGL or
               PFD_DOUBLEBUFFER;
  iPixelType:= PFD_TYPE_RGBA;
  cColorBits:= 16;
  cDepthBits:= 64;
  iLayerType:= PFD_MAIN_PLANE;
end;

nPixelFormat:=ChoosePixelFormat(DC,@pfd);
SetPixelFormat(DC,nPixelFormat,@pfd);
end;

procedure TForm1.BeginPaint;
begin
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
timer1.enabled:=true;
end;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
H:=Handle;
DC:=GetDC(H);
SetDCPixelFormat(DC);
RC:=wglCreateContext(DC);
wglMakeCurrent(DC,RC);
glClearColor(0.6,0.6,0.6,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1,1,-1,1,2,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glTranslatef(0.0,-1.0,-6.0);
BeginPaint;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0,0);
wglDeleteContext(RC);
ReleaseDC(H,DC);
DeleteDC(DC);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
glRotatef(4.0,0.0,1.0,0.0);
SwapBuffers(DC);
InvalidateRect(H,nil,False);
end;

procedure DrawElement(a,b,r0,r1:Single);
var x1b,y1b:Single;
    x1e,y1e:Single;
    x0b,y0b:Single;
    x0e,y0e:Single;
    t0,t1:Single;
    dt:single;
begin
t0:=-3;t1:=3;
dt:=0.06;
while t0
 
Вверх Снизу