Графика (Работа с видестраницами и видеопамятью)
ScreenSet
Функция позволяет устанавливать рабочую и видимую страницу. Вы можете отображать на экране что-то одно, а в это время что-то рисовать на второй странице, потом нарисованную скопировать на экран, а на первой опять что-то отрисовывать. Получится эффект двойной буферизации, которая стала так популярна в графике. Двойная буферизация в значительной степени уменьшает мерцание.
Синтаксис:
ScreenSet [ work_page ] [, visible_page ]
- work_page - рабочая страница
- visible_page - видимая страница
Страницы имеют отсчет от 0. Если использовать функцию без параметров, то
рисуется и отображается все на нулевой странице, что для анимации малоприемлемо.
Если использовать только какой-то один параметр, то втором параметре
предполагается 0 страница.
Примеры с двойной буферизацией я покажу в обзоре
следующей функции, а здесь просто пример из справки работы функции ScreenSet.
Этот пример очень хорошо показывает ее работу:
'' 320x200x8, with 3 pages Screen 13,,3 '' image for page #1 Screenset 1, 0 Cls Circle( 160, 100 ), 90, 1 ,,,, f Circle( 160, 100 ), 90, 15 Print "Press 2 to copy page #2 to visible page" Print "Press escape to exit" '' image for page #2 Screenset 2, 0 Cls Line( 50, 50 )-( 270, 150 ), 2, bf Line( 50, 50 )-( 270, 150 ), 15, b Print "Press 1 to copy page #1 to visible page" Print "Press escape to exit" '' page #0 is the visible page Screenset 0, 0 Cls Print "Press 1 to copy page #1 to visible page" Print "Press 2 to copy page #2 to visible page" Print "Press escape to exit" Dim k As String Do k = Inkey Select Case k Case Chr(27) Exit Do Case "1" Screenset 0, 1 Case "2" Screenset 0, 2 End Select Sleep 25 Loop
В примере используются три видеостраницы, далее последовательно
отрисовываются. Самая последняя страница устанавливается видимой по умолчанию.
Далее в цикле при нажатии на клавиши 1 или 2 , устанавливается видимой 1 или 2
страница. Конечно правильно в условном операторе вместо ScreenSet использовать
Pcopy , и в справке так и сделано, но чисто для понимания я решил изменить код.
В принципе для этой задачи большой производительности не нужно.
ScreenCopy = PCopy = Flip
Эти три функции абсолютно одинакового можно использовать как для GFX , так и для OpenGL. Просто привычнее, что в OpenGL используют Flip. Данные функции копируют содержимое одной видеостраницы в другую. Кстати эта операция выполняется значительно быстрее, чем переключение страниц в прошлом примере. ScreenSet нужен лишь для переключения страниц под нужную операцию, а всю рутину выполняет PCopy.
Синтаксис:
Flip [ frompage ] [, topage ]
- frompage - копируемая страница
- topage - страница куда копировать
Если функция вызывается без параметров, то она берет установленные правила функцией ScreenSet. Если указывается какой-то один параметр, то во втором параметре предполагается нулевая страница. Для того, чтобы реально понять разницу, между выводом графики с двойной буферизацией и простым выводом , который был использован в прошлой статье "Координаты графических областей" , я взял один небольшой пример из справки и записал его двумя способами.
Вот такой подход рисования я думаю никого не устроит:
Screen 13 Color ,15 Dim x As Integer x = -40 Do Cls Paint(20,20),2 Line (x, 80)-(x + 39, 119), 4, BF x = x + 1 If (x > 319) Then x = -40 Sleep(10) Loop While Inkey = ""
А вот этот же пример только с двойной буферизацией:
Screen 13,,2 Color ,15 Dim x As Integer x = -40 Screenset 1 Do Cls Paint(20,20),2 Line (x, 80)-(x + 39, 119), 4, BF x = x + 1 If (x > 319) Then x = -40 Sleep(10) Pcopy Loop While Inkey = ""
Надеюсь разницу заметили.
ScreenLock и ScreenUnLock
Есть еще один способ, который помогает справляться с мерцанием и выводом более качественного отображения анимации. Второй способ предлагает обязательное использование двух функций:
ScreenLock - для запирания экрана
ScreenUnLock - для отпирания экрана
Принцип:
- Запираем экран
- Рисуем
- Отпираем экран
Разработчики FreeBasic настоятельно советуют во время запирания экрана, не производить никаких лишних действий помимо рисования, то есть все подсчеты нужно вынести за рамки блока: ScreenLock - ScreenUnLock . И уж тем более не рекомендуется делать заведомые паузы.
У функции ScreenUnLock есть два параметра, но что-то я не смог получить никакого эффекта от их использования. Скорее всего разработчики их просто отключили... По сути где не встречал, обе функции используются без параметров.
Пример:
Screen 13 Color ,15 Dim x As Integer x = -40 Do Screenlock Cls Paint(20,20),2 Line (x, 80)-(x + 39, 119), 4, BF Screenunlock x = x + 1 If (x > 319) Then x = -40 Sleep(10) Loop While Inkey = ""
ScreenPtr
Данная функция позволяет получать доступ для чтения и записи видеобуфера страницы. Этодает возможность получить доступ к каждому пикселю видеобуфера.
Пример из справки (вырезал все лишнее) :
Dim As Integer w, h, pitch Screenres 256, 256, 32 Screeninfo w,h,,,pitch Dim buffer As Any Ptr = Screenptr() For y As Integer = 0 To h - 1 Dim As Uinteger Ptr pixel = buffer For x As Integer = 0 To w - 1 *pixel = Rgb(x, 6, y) pixel += 1 Next x buffer += pitch Next y Sleep
В примере получаем указатель на страницу видеобуфера. Внешний цикл
проходит по всем строкам страницы. Внутренний по всем пикселям каждой строки. В
каждый пиксель пишется определенное цветовое значение с помощью макроса RGB.
Этой статьей я завершаю главу про графику. Всего доброго!
содержание | назад | вперед