OpenGL для начинающих
************************************************* Часть II ****************************************************В этой части будут только указаны исправления кода MyOpenGL.pas, которые надеюсь без труда сделаете сами, или просто общие сведения.09 Списки ========="Список - это некоторый набор команд OpenGL, который можно создать один раз, например, перед началом работы программы, а потом им пользоваться вызывая его. По логике он аналогичен процедуре (или функции, как хотите). Отличие его от процедуры в том, что при формировании списка библиотека сохраняет его в каком-то своем, оптимизированном формате и вызовы списка приводят к значительно меньшим вычислительным затратам чем вызов функции, делающей тоже самое. Особенно хорошо это заметно на картах, где операции со списками реализованы аппаратно."(Взято с http://firststeps.ru/mfc/opengl/r.php?41)Где-то до использования MyOpenGL.glDraw (напр. в MyOpenGL.glInit)
var
MyList: GLuint;
...
// указываем, что в списке два набора команд
MyList := glGenLists(2);
// Создаем первый набор команд
// Флаг GL_COMPILE указывает что его надо только создать
// Использование GL_COMPILE_AND_EXECUTE сразу же еще и выполнило бы этот набор
// В первом наборе будем рисовать треугольник
glNewList(MyList, GL_COMPILE);
glBegin(GL_POLYGON);
glVertex3F(0.0, 0.0, 0.0);
glVertex3F(100.0, 0.0, 0.0);
glVertex3F(50.0, sqrt(3)*50, 0.0);
glEnd;
// Указываем что завершили создание набора команд
glEndList();
// Создаем второй набор команд
// Во втором наборе к матрице GL_MODELVIEW будет добавляться параллельный
// перенос на 50 по оси OX и на 1 по оси OZ (это чтобы поверх остального)
// Поставить переменные значения в перенос нельзя, так как это будет уже
// другая матрица. Хотя может я и ошибаюсь.
glNewList(MyList + 1, GL_COMPILE);
glTranslatef(50, sqrt(3) * 12.5, 1);
// Указываем что завершили создание набора команд
glEndList();
begin
// очистка Экрана и буфера глубины
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
// Сбрасываем GL_MODELVIEW до единичной
glLoadIdentity();
// Устанавливаем зеленый цвет для фигур
glColor(0.0, 1.0, 0.0, 1);
// Создаем фигуру, используя набор команд MyList
glCallList(MyList);
// Добавляем значение к углу поворота
Angle := (Angle + 5) mod 360;
// Вызываем второй набор команд, который хранится по MyList + 1
// В результате к GL_MODELVIEW добавляется перенос
glCallList(MyList + 1);
// Добавим к GL_MODELVIEW-матрице еще и поворот на угол Angle
glRotate(Angle, 0.0, 0.0, 1.0);
// Устанавливаем красный цвет для фигур
glColor(1.0, 0.0, 0.0, 1);
// Создаем фигуру, используя набор команд MyList
// Поскольку GL_MODELVIEW-матрица у нее другая, то и распалагается
// она уже иначе, чем первая фигура
glCallList(MyList);
// Выводим на экран подготовленную сцену
SwapBuffers(DC);
end;
uses
windows,
messages,
MyOpenGL in 'MyOpenGL.pas';
var
MainWnd: hWND;
FPSCount: Integer; // Число FPS
keys : array [0..255] of Boolean; // Статусы кнопок
function IntToStr(Num: Integer) : String;
begin
Str(Num, result);
end;
// Обработка кнопок
procedure ProcessKeys;
begin
if (keys[VK_UP]) then
begin
// Что-то делаем
//...
// Сбрасываем нажатие этой кнопки
keys[VK_UP] := False;
end;
if Keys[Ord('H')] then
begin
// Что-то делаем
//...
// Сбрасываем нажатие этой кнопки
Keys[Ord('H')] := FALSE;
end;
end;
function WindowProc(Wnd: HWND; Msg: Integer; wParam: wParam; lParam:lParam):lResult;stdcall;
begin
case Msg of
WM_DESTROY:
begin
glKill(MainWnd);
postquitmessage(0);
Result := 0;
exit;
end;
WM_KEYDOWN:
begin
keys[wParam] := True;
Result := 0;
end;
WM_KEYUP:
begin
keys[wParam] := False;
Result := 0;
end;
WM_TIMER:
begin
FPSCount := Round(FPSCount * 1000/{FPS-интервал - у нас 1с}1000);
SetWindowText(MainWnd, PChar('FPS: ' + IntToStr(FPSCount)));
FPSCount := 0;
end;
WM_SIZE:
begin
glOnResize(loWord(lParam), hiWord(lParam));
Result := 0;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
var
Mesg: TMsg;
wc : TWndClassEx;
finished: Boolean = False; // Флаг завершения работы OpenGL
begin
wc.cbSize := sizeof(wc);
wc.style := CS_HREDRAW or CS_VREDRAW;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := hInstance;
wc.hIcon := LoadIcon(0, IDI_WINLOGO);
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground := COLOR_BTNFACE + 2;
wc.lpszMenuName := nil;
wc.lpszClassName := 'aWnd';
RegisterClassEx(wc);
// Создаем окно 400х400
MainWnd := CreateWindowEx (0, 'aWnd', 'MyOpenGL', WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400, 0, 0, hInstance, nil);
// Создаем контекст воспроизведения OpenGL и его параметры
glInit(MainWnd);
// Задаем матрицы OpenGL для размера окна 400х400
glOnResize(400, 400);
// Устанавливаем таймер на 1с для отображения FPS в заголовке окна
SetTimer(MainWnd, 1, 1000, nil);
while not finished do
begin
// Если очередь сообщений для окна пуста, то проводим
// расчет и отрисовку сцены, иначе обрабатываем
// очередь сообщений
if (PeekMessage(Mesg, 0, 0, 0, PM_REMOVE)) then
begin
// Если было получено WM_QUIT, то выход
if (Mesg.message = WM_QUIT) then
finished := True
else
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end
else
begin
// Увеличиваем счетчик отрисованных кадров
Inc(FPSCount);
// Рисуем-с кадр
glDraw();
// Если была до этого нажата ESC, то сразу выходим
if (keys[VK_ESCAPE]) then
finished := True
else
ProcessKeys;
end;
end;
end.
Очень сильно помогло для вывода текста. Спасибо.
Отправить комментарий