Книги

OpenGL / FPC - Глава 2

Прежде всего, окно OpenGL — такое же, как и любое другое окно. Оно имеет оконный класс, контекст устройства и тп. Если вы не знаете, что это такое — не волнуйтесь: в действительности для первых забав с OpenGL вам это и не понадобится. Если вам нужно разобраться с OpenGL поглубже, возьмите учебник про Windows и ознакомьтесь.

Для начала, определим и создадим окно.

function WindowRegister: Boolean;
var
  WindowClass: WndClass;
begin
  WindowClass.Style := cs_hRedraw or cs_vRedraw;
  WindowClass.lpfnWndProc := WndProc(@GLWndProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := 'GLWindow';
  WindowRegister := RegisterClass(WindowClass) <> 0;
end;

Это и есть наш класс окна. Единственное, чем он отличается, — мы не определяем фон. Мы хотим рисовать в окне объекты OpenGL, так что нам он не нужен, и мы устанавливаем hbrBackground в plain white. Заметим, что функция возвращает true или false, в зависимости от успеха в регистрации класса окна.

Теперь создаем окно. Опять-таки ничего нового.

function WindowCreate(pcApplicationName : pChar): HWnd;
var
  hWindow: HWnd;		// Handle to Window
  dmScreenSettings : DEVMODE;	// Used for Full Screen Mode
begin

  hWindow := CreateWindow('GLWindow',
			  pcApplicationName,
			  WS_CAPTION or WS_POPUPWINDOW or WS_VISIBLE 
			  or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,
			  cw_UseDefault,
			  cw_UseDefault,
			  width,
			  height,
			  0, 0,
			  system.MainInstance,
			  nil);
  if hWindow <> 0 then begin
    ShowWindow(hWindow, CmdShow);
    UpdateWindow(hWindow);
  end;
  WindowCreate := hWindow;
end;

Заметим, что мы создали окно с меняющимися размерами. В результате функция возвращает хэндл (Windows Handle) окна.

Теперь займемся инициализацией нашего окна. Сначала, мы запрашиваем контекст устройства, а затем определим формат пикселя для нашего окна.

Следует установить PFD_SUPPORT_OPENGL в pfd.dwFlags. Именно так наше окно станет поддерживать OpenGL. Существует парочка других стилей, связанных с OpenGL, таких как PFD_DRAW_TO_WINDOW и/или PFD_DOUBLEBUFFER. Просто взгляните на список в любой доке по OpenGL.

Далее rcWindow := wglCreateContext( dcWindow );. Здесь мы запрашиваем OpenGL Render Context для нашего окна. Последнее, что следует сделать — сказать Windows, что окно будет получателем наших вызовов функций OpenGL.

function WindowInit(hParent : HWnd): Boolean;
var
  FunctionError : integer;
  pfd : PIXELFORMATDESCRIPTOR;
  iFormat : integer;	// Pixel Format

begin

 FunctionError := 0;
  dcWindow := GetDC( hParent );	// Get Device Context

  FillChar(pfd, sizeof(pfd), 0);	// Define Pixel Format
  pfd.nSize         := sizeof(pfd);
  pfd.nVersion      := 1;
  pfd.dwFlags       := PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or PFD_DOUBLEBUFFER;
  pfd.iPixelType    := PFD_TYPE_RGBA;
  pfd.cColorBits    := bits;
  pfd.cDepthBits    := 16;
  pfd.iLayerType    := PFD_MAIN_PLANE;
  iFormat := ChoosePixelFormat( dcWindow, @pfd );
  if (iFormat = 0) then FunctionError := 1;
  SetPixelFormat( dcWindow, iFormat, @pfd );
  rcWindow := wglCreateContext( dcWindow );
  if (rcWindow = 0) then FunctionError := 2;
  wglMakeCurrent( dcWindow, rcWindow );
 if FunctionError = 0 then WindowInit := true else WindowInit := false;

end;

Начнем. Если запускать эти процедуры друг за дружкой, то вы получите окно OpenGL!

Следующим шагом настраиваем OpenGL само по себе. Начнем с простой строки.

procedure OpenGL_Init;
begin

  glClearColor( 0.0, 0.0, 0.0, 1.0 );

end;

С помощью glClearColor() можно определить цвет, которым будет очищаться окно. Значения задаются в RGB, то есть первый аргумент — интенсивность красного, второй — зеленого, а третий — синего цвета. Величины меняются от 0.0 (min) до 1.0 (max). Например, 1.0, 0.0, 0.0 будет ярко красным. Четвертый аргумент — значение параметра альфа, но об этом — позже.

А теперь — основной цикл (main loop). Добавим строку: SwapBuffers( window_hDC ); С помощью SwapBuffers, вы копируете содержимое буфера на экран, делая его, таким образом, видимым. Без этой строчки, ваш OpenGL код бесполезен.

Вот и готова первая программа-пример. Она инициализирует окно и ... и больше ничего не делает ;) Полный код программы здесь. Посмотрите, скомпилируйте, а мы встретимся в следующей главе.

Актуальные версии
FPC3.2.2release
Lazarus3.2release
MSE5.10.0release
fpGUI1.4.1release
links
Для вас в нашей организации плайтерра по невысоким ценам.