;
; 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