Читаем Учебник по Haskell полностью

этого мы воспользуемся GLFW, это библиотека также пришла в Haskell из С. Интерфейсы GLFW и OpenGL очень

похожи. Мы будем обновлять различные параметры библиотеки с помощью типа StateVar. Давайте создадим

окно и закрасим фон белым цветом:

module Main where

import Graphics.UI.GLFW

import Graphics.Rendering.OpenGL

import System.Exit

title = ”Hello OpenGL”

width

= 700

height

= 600

main = do

initialize

openWindow (Size width height) [] Window

windowTitle $= title

clearColor $= Color4 1 1 1 1

windowCloseCallback $= exitWith ExitSuccess

loop

loop = do

display

loop

display = do

clear [ColorBuffer]

swapBuffers

Мы инициализируем GLFW, задаём параметры окна. Устанавливаем цвет фона. Цвет имеет четыре пара-

метра это RGB-цвета и параметр прозрачности. Затем мы говорим, что программе делать при закрытии окна.

Мы устанавливаем функцию обратного вызова (callback) windowCloseCallback. В самом конце мы входим в

цикл, который только и делает, что стирает окно цветом фона и делает рабочий буфер видимым. Что такое

буфер? Буфер – это место в котором мы рисуем. У нас есть два буфера. Один мы показываем пользователю,

а в другом в это в время рисуем, когда приходит время обновлять картинку мы просто меняем их местами

командой swapBuffers.

Посмотрим, что у нас получилось:

$ ghc --make HelloOpenGL.hs

$ ./HelloOpenGL

Нарисуем упрощённое начальное положение нашей игры: прямоугольную рамку и в ней – красный шар:

290 | Глава 20: Императивное программирование

module Main where

import Graphics.UI.GLFW

import Graphics.Rendering.OpenGL

import System.Exit

title = ”Hello OpenGL”

width, height :: GLsizei

width

= 700

height

= 600

w2, h2 :: GLfloat

w2 = (fromIntegral $ width) / 2

h2 = (fromIntegral $ height)

/ 2

dw2, dh2 :: GLdouble

dw2 = fromRational $ toRational w2

dh2 = fromRational $ toRational h2

main = do

initialize

openWindow (Size width height) [] Window

windowTitle $= title

clearColor $= Color4 1 1 1 1

ortho (-dw2-50) (dw2+50) (-dh2-50) (dh2+50) (-1) 1

windowCloseCallback $= exitWith ExitSuccess

windowSizeCallback

$= (\size -> viewport $= (Position 0 0, size))

loop

loop = do

display

loop

display = do

clear [ColorBuffer]

color black

line (-w2) (-h2) (-w2) h2

line (-w2) h2

w2

h2

line w2

h2

w2

(-h2)

line w2

(-h2)

(-w2) (-h2)

color red

circle 0 0 10

swapBuffers

vertex2f :: GLfloat -> GLfloat -> IO ()

vertex2f a b = vertex (Vertex3 a b 0)

-- colors

white = Color4 (0::GLfloat)

black = Color4 (0::GLfloat) 0 0 1

red

= Color4 (1::GLfloat) 0 0 1

-- primitives

line :: GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()

Основные библиотеки | 291

line ax ay bx by = renderPrimitive Lines $ do

vertex2f ax ay

vertex2f bx by

circle :: GLfloat -> GLfloat -> GLfloat -> IO ()

circle cx cy rad =

renderPrimitive Polygon $ mapM_ (uncurry vertex2f) points

where n = 50

points = zip xs ys

xs = fmap (\x -> cx + rad * sin (2*pi*x/n)) [0 .. n]

ys = fmap (\x -> cy + rad * cos (2*pi*x/n)) [0 .. n]

Рис. 20.1: Начальное положение

Мы рисуем с помощью функции renderPrimitive. Она принимает метку элемента, который мы собира-

емся рисовать и набор вершин. Так метка Lines обозначает линии, а метка Polygon – закрашенные много-

угольники. В OpenGL нет специальной операции для рисования окружностей, поэтому нам придётся предста-

вить окружность в виде многоугольника (circle). Функция ortho устанавливает область видимости рисунка,

шесть аргументов функции обозначают пары диапазонов по каждой из трёх координат. При этом вершины

передаются не списком а в специальном do-блоке. За счёт этого мы можем изменить какие-нибудь парамет-

ры OpenGL во время рисования. Обратите внимание на то, как мы изменяем цвет примитива. Перед тем как

рисовать примитив мы устанавливаем значение цвета (color).

Анимация

Оживим нашу картинку. При клике мышкой шарик игрока последует в направлении курсора. Для того

чтобы картинка задвигалась нам необходимо обновлять рисунок с определённой частотой. Мы будем регу-

лировать частоту обновления с помощью функции sleep, с её помощью мы можем задержать выполнение

программы (время измеряется в секундах):

sleep :: Double -> IO ()

За перехват действий пользователя отвечает функции:

getMouseButton

:: MouseButton -> IO KeyButtonState

mousePos

:: StateVar Position

Функция getMouseButton сообщает текущее состояние кнопок мыши, мы будем перехватывать положение

мыши во время нажатия левой кнопки:

292 | Глава 20: Императивное программирование

onMouse ball = do

mb <- getMouseButton ButtonLeft

when (mb == Press) (get mousePos >>= updateVel ball)

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных