; ; OpenGL Демонстрация Гаджетов ; ; (c) Fantaisie Software ; ; Объяснение оси: ; ; + ; y ; ; | ; | ; + | ; x ---------\ ; \ ; \ ; \ ; z+ ; ; Таким образом, поворот по оси y будет принимать ось y как центр. С OpenGL мы можем указать ; положительное и отрицательное значение. Положительные значения всегда в том же смысле, ; что и ось (как описано на schmatic, со знаками "+"). ; Global RollAxisX.f Global RollAxisY.f Global RollAxisZ.f Global RotateSpeedX.f = 1.0 Global RotateSpeedY.f Global RotateSpeedZ.f = 1.0 Global ZoomFactor.f = 1.0 ; Расстояние до камеры. Отрицательное значение = зум назад Procedure DrawCube(Gadget) SetGadgetAttribute(Gadget, #PB_OpenGL_SetContext, #True) glPushMatrix_() ; Сохранить исходные координаты матрицы glMatrixMode_(#GL_MODELVIEW) glTranslatef_(0, 0, ZoomFactor) ; Немного подвинем его вперед glRotatef_ (RollAxisX, 1.0, 0, 0) ; Вращаем вокруг оси X glRotatef_ (RollAxisY, 0, 1.0, 0) ; Вращаем вокруг оси Y glRotatef_ (RollAxisZ, 0, 0, 1.0) ; Вращаем вокруг оси Z RollAxisX + RotateSpeedX RollAxisY + RotateSpeedY RollAxisZ + RotateSpeedZ ; Очистим фрейм-буфер И буфер глубины. glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) ; Нарисуем грани куба. ; Нарисуем цветные грани. glDisable_(#GL_LIGHTING) glBegin_ (#GL_QUADS) ; Построим грань, состоящую из 4 вершин! ; GlBegin () определяет, как рассматриваются вершины. Здесь группа ; из 4-х вершин (GL_QUADS) образует прямоугольную поверхность. ; Теперь цвет: это r, v, b, но с плавающими значениями, которые могут ; изменяться от 0.0 до 1.0 (0 - это нуль, а 1.0 - полная интенсивность) glNormal3f_ (0,0,1.0) glColor3f_ (0,0,1.0) glVertex3f_ (0.5,0.5,0.5) glColor3f_ (0,1.0,1.0) glVertex3f_ (-0.5,0.5,0.5) glColor3f_ (1.0,1.0,1.0) glVertex3f_ (-0.5,-0.5,0.5) glColor3f_ (0,0,0) glVertex3f_ (0.5,-0.5,0.5) ; Другая грань такая же, как и предыдущая, ; кроме цвета с красивым сине-белым градиентом glNormal3f_ (0,0,-1.0) glColor3f_ (0,0,1.0) glVertex3f_ (-0.5,-0.5,-0.5) glColor3f_ (0,0,1.0) glVertex3f_ (-0.5,0.5,-0.5) glColor3f_ (1.0,1.0,1.0) glVertex3f_ (0.5,0.5,-0.5) glColor3f_ (1.0,1.0,1.0) glVertex3f_ (0.5,-0.5,-0.5) glEnd_() ; Рисуем затененные грани. glEnable_(#GL_LIGHTING) glEnable_(#GL_LIGHT0) glBegin_ (#GL_QUADS) glNormal3f_ ( 0, 1.0, 0) glVertex3f_ ( 0.5, 0.5, 0.5) glVertex3f_ ( 0.5, 0.5,-0.5) glVertex3f_ (-0.5, 0.5,-0.5) glVertex3f_ (-0.5, 0.5, 0.5) glNormal3f_ (0,-1.0,0) glVertex3f_ (-0.5,-0.5,-0.5) glVertex3f_ (0.5,-0.5,-0.5) glVertex3f_ (0.5,-0.5,0.5) glVertex3f_ (-0.5,-0.5,0.5) glNormal3f_ (1.0,0,0) glVertex3f_ (0.5,0.5,0.5) glVertex3f_ (0.5,-0.5,0.5) glVertex3f_ (0.5,-0.5,-0.5) glVertex3f_ (0.5,0.5,-0.5) glNormal3f_ (-1.0, 0, 0) glVertex3f_ (-0.5,-0.5,-0.5) glVertex3f_ (-0.5,-0.5, 0.5) glVertex3f_ (-0.5, 0.5, 0.5) glVertex3f_ (-0.5, 0.5,-0.5) glEnd_() glPopMatrix_() glFinish_() SetGadgetAttribute(Gadget, #PB_OpenGL_FlipBuffers, #True) EndProcedure Procedure SetupGL() glMatrixMode_(#GL_PROJECTION) gluPerspective_(30.0, 200/200, 1.0, 10.0) ; Позиция просмотра. glMatrixMode_(#GL_MODELVIEW) glTranslatef_(0, 0, -5.0) glEnable_(#GL_DEPTH_TEST) ; Включено, это замедляет рендеринг. Это чтобы быть уверенным, ; чем переданные объекты внутри Z-буфера. glEnable_(#GL_CULL_FACE) ; Это увеличит скорость рендеринга, так как вся задняя поверхность ; будет игнорироваться. Это работает только с CLOSED-объектами, такими как куб ; Одиночные плоскости поверхностей будут видимыми только с одной стороны. glShadeModel_(#GL_SMOOTH) EndProcedure Procedure HandleError (Result, Text$) If Result = 0 MessageRequester("Ошибка", Text$, 0) End EndIf EndProcedure OpenWindow(0, 0, 0, 530, 320, "OpenGL Gadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) OpenGLGadget(0, 10, 10, 200, 200) SetupGL() OpenGLGadget(1, 220, 10, 300, 300) SetupGL() AddWindowTimer(0, 1, 16) ; Около 60 кадров в секунду Repeat Event = WaitWindowEvent() Select Event Case #PB_Event_Timer If EventTimer() = 1 DrawCube(0) DrawCube(1) EndIf EndSelect Until Event = #PB_Event_CloseWindow