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