[[ header START ]]

Welcome to OS2.GURU site! (eComStation.RU)

Select your language: Russian English Deutch Spanish Italian Portuguese Czech Polish French

Frequently asked questions and answers:
telegram

Форум обсуждение

telegram

Send message

telegram

[ +7-981-8529467 (Санкт-Петербург)

telegram

t.me/os2_guru

eComStation.RU


ru · en · de · es · it · pt · cz · pl · fr
OS/2 - это совершенно другая операционная система для PC (ArcaOS, eComStation, IBM OS/2 Warp)
Программы, новости, статьи, поддержка пользователей, оборудование, вопросы и ответы.
 
[Что такое OS/2?  Новости  Установка  Обновление  
 
 
Применение  Будущее  Сообщество  Проекты  

[Как заработать в OS/2?

Как купить OS/2 дискету?

Идеи для фанатов OS/2

*

(Карта сайта)

 
 
[[ head-3-search ]]

Списки протестированного OS/2 оборудования

[[ head-3-search END ]]

 
Обновление

 
Программы

 
(Санкт-Петербург)

 
Преимущества (1)

 
Разработчику (1)

 
(Пайпы программ)

 
Компании: (1)

 
История (1):

 
(Бонусы)

 
Советы:

 
(Барьеры и решения)

 
Технологии: (1)

 
(Применение в науке, лаборатории, ..)

 

 
Готовые решения:

 
Новая eComStation:

 
Будущее: (1)

 
(Ссылки на другие сайты)

 
(Картинка дня)

 
Артефакты OS/2

 
Гаджеты

Обновите ArcaOS до уровня NeoWPS

  • Установите набор PNG иконок, нарисованных дизайнером, специализирующемся на оформлении OS/2
  • Установите eSchemes 2018, чтобы менять цвета и кнопки на рабочем столе

Применение DIVE для создания графических приложений


TITLE: Применение DIVE для создания графических приложений

DATE: 2002-02-04 12:19:52

AUTHOR: Artem Davidenko

DIVE (Direct Interface Video Extensions) был разработан для скоростного доступа к видео буферу. В своем API имеет функции для "прозрачной" организации клиппирования вывода, скаллинга и конверсии глубины цвета. DIVE оптимизирован для вывода потокового видео и использования в играх. Может задействовать, при наличии, 2D функции видео-ускорителя для повышения скорости вывода.

Динамически линкуемая библиотека DIVE экспортирует следующие функции:

  • Запрос параметров текущего видеорежима
  • Инициализация и деинициализация DIVE
  • Спецификации видимого региона
  • Определения видео буфера
  • Установки буфер-буфер или буфер-экран трансфера (посредством блиттера)
  • Симуляции восьмибитовой палитры
  • Функции применяемые для прямого доступа, включая функция вычисления стартового адреса окна
  • Функции переключения банков (для banked-режимов)

Входные форматы:

  • CLUT 8 (256 color) - "LUT8"
  • 8-bit grayscale - "GREY"
  • RGB 16 (5-6-5, 5-5-5) - "R565", "R555", "R664"
  • RGB 24 (R-G-B, B-G-R) - "RGB3", "BGR3"
  • RGB 32 (R-G-B, B-G-R) - "RGB4", "BGR4"
  • YUV 9 - DVI/Indeo three-plane color subsampled - "YUV9"
  • YUV 411 - "YUV411"
  • YUV 422 - "YUV422"
  • YUV CCIR601 - three-plane 2x2 color subsampled (MJPEG, MPEG) - "Y2X2"
  • YUV CCIR601 - three-plane 4x4 color subsampled? - "Y4X4"

Выходные форматы:

  • CLUT 8 (256 цветов)
  • RGB 16 (5-6-5, 5-5-5, 6-6-4)
  • RGB 24 (R-G-B, B-G-R)
  • RGB 32 (R-G-B-x,? B-G-R-x)
  • Blitter Operation

Существует два пути использования DIVE: применение DIVE-блиттера и прямой доступ к буферу. Следующая последовательность инициализирует DIVE и возвращает DIVE handle:

ULONG  ulErrorCode;
HDIVE  *phDiveInst;
BOOL   fNonScreenInstance;
PPVOID ppFrameBuffer;

ulErrorCode = DiveOpen(*phDiveInst, fNonScreenInstance, ppFrameBuffer);

Функция DiveClose должна быть вызвана по окончании работы приложения.

Если DIVE использует блиттинг в видео-буфер, то fNonScreenInstance должна быть установлена в FALSE, иначе, если DIVE используется только для конверсии глубины цвета или изменения размера буфера без вывода на экран fNonScreenInstance = TRUE. Чтобы DIVE мог использовать функции 2D ускорителя для операций вывода буфера, он должен быть определен при помощи DiveAllocImageBuffer. Следующий фрагмент показывает как это сделать:

ULONG   ulBufNum;
FOURCC  fccColorSpace;
ULONG   ulWidth, ulHeight, ulLineSizeBytes;
PBYTE   pbImageBuffer;

ulErrorCode = DiveAllocImageBuffer
              (
               hDive,             /* DIVE хэндл */
               &ulBufNum,         /* Номер буфера */
               fccColorSpace,     /* Формат */
               ulWidth, ulHeight, /* Максимальный размер изображения */
               ulLineSizeBytes,
               &pbImageBuffer
              );

После того как буфер определен, перед записью в него необходимо вызвать функцию DiveBeginImageBufferAccess так, как это показано в следующем примере:

PBYTE   pbImageBuffer;
ULONG   ulBufferScanLineBytes, ulBufferScanLines;

ulErrorCode = DiveBeginImageBufferAccess
              (
               hDiveInst,              /* DIVE хэндл */
               ulBufferNumber,         /* Номер буфера */
               &pbImageBuffer,         /* Указатель на буфер */
               &ulBufferScanLineBytes, /* Размер линии в байтах */
               &ulBufferScanLines      /* Всего линий */
               );

DIVE вычисляет количество байт на одну линию буфера и возвращает значение в ulBufferScanLineBytes. Далее приложение может проводить запись данных в pbImageBuffer. После того как данные были записаны, приложение должно вызвать DiveEndImageBufferAccess.

Приложение должно информировать DIVE о состоянии физической палитры во время его инициализации и при каждой смене палитры. Для инициализации приложения и при полученном сообщении WM_REALIZEPALETTE должна вызываться следующая последовательность:

BYTE       pbPal 1024;

/* Запрос текущей физической палитры у Presentation Manager */
GpiQueryRealColors(hps, 0, 0, 256, (PLONG)pbPal);

/* Установка ее как целевой палитры в DIVE */
DiveSetDestinationPalette(hDive, (PBYTE)pbPal);

Если приложение само использует палитру (например, для вывода палитрового изображения на экран), она должна быть сообщена DIVE посредством DiveSetSourcePalette. Если предполагается вывод серии изображений в одной палитре, то вызов функции необходим только перед выводом первого изображения.

DIVE обеспечивает высокоскоростное обновления экрана в обход Presentation Manager. Для нормальной работы совместно с PM десктопом, DIVE приложение должно сообщать DIVE об изменениях видимого региона окна приложения, что-бы обеспечить таким образом клиппирование.

Каждое DIVE приложение во время инициализации должно устанавливать нотификацию видимого региона следующим вызовом:

WinSetVisibleRegionNotify(hwnd, TRUE);

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

WinSetVisibleRegionNotify(hwnd, FALSE);

для выключения нотификации.

При изменении видимого региона окна, например, когда оно было перенесено или был изменен его размер или другое окно или иконка перекрыли его при перенесении или изменении размера, окно получает сообщение WM_VRNDISABLED. В ответ на это сообщение DIVE приложение должно вызвать

DiveSetupBlitter(hDiveInst, 0);

После того как перемещение окончено, окно получает сообщение WM_VRNENABLED. Следующим шагом должен следовать запрос нового видимого региона, посредством функции WinQueryVisibleRegion:

hps = WinGetPS(hwnd);
hrgn = GpiCreateRegion(hps, 0, NULL);
WinQueryVisibleRegion(hwnd, hrgn);

Функция DiveSetupBlitter должна вызываться всякий раз при изменениях видимого региона, глубины цвета, размеров исходного и целевого изображений. Это должно выглядеть примерно так:

RECTL   rctls;
RGNRECT rgnCtl;
SETUP_BLITTER   SetupBlitter;
POINTL  pointl;
SWP     swp;
HPS     hps;
HRGN    hrgn;

rgnCtl.ircStart = 0;
rgnCtl.crc = 50;
rgnCtl.ulDirection = RECTDIR_LFRT_TOPBOT;

/* Получение видимого региона */
GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, rctls);

/* Получение позиции текущего окна относительно родительского. */
WinQueryWindowPos( hwnd, &swp );

/* Маппинг позиции окна на десктоп */
pointl.x = swp.x;
pointl.y = swp.y;
WinMapWindowPoints(WinQueryWindow(hwnd, QW_PARENT), 
                   HWND_DESKTOP, &pointl, 1);

/* Сообщить информацию о новых установках в DIVE */
SIZEL   sizlSrcImg;  /* Размер исходного изображения */
FOURCC  fccSrcColors /* Формат */

SetupBlitter.ulStructLen = sizeof (SETUP_BLITTER);
SetupBlitter.fInvert = 0;
SetupBlitter.fccSrcColorFormat = fccSrcColors;
SetupBlitter.ulSrcLineSizeBytes = ulScanLineBytes;
SetupBlitter.ulSrcWidth = sizlSrcImg.cx;
SetupBlitter.ulSrcHeight = sizlSrcImg.cy;
SetupBlitter.ulSrcPosX = 0;
SetupBlitter.ulSrcPosY = 0;
SetupBlitter.fccDstColorFormat = FOURCC_SCRN;
SetupBlitter.ulDstLineSizeBytes = 0;
SetupBlitter.ulDstWidth = swp.cx;
SetupBlitter.ulDstHeight = swp.cy;
SetupBlitter.ulDstPosX = 0;
SetupBlitter.ulDstPosY = 0;
SetupBlitter.lScreenPosX = pointl.x;
SetupBlitter.lScreenPosY = pointl.y;
SetupBlitter.ulNumDstRects = rgnCtl.crcReturned;
SetupBlitter.pVisDstRects = rctls;
DiveSetupBlitter (hDive, &SetupBlitter);

Формат цвета исходного изображения описывается посредством fccSrcColors.

В приведенном выше примере, DIVE блиттер устанавливается для вывода в видеобуфер. Но это не единственный вариант использования блиттера. Он может применяться так-же для конверсии глубины цвета или изменения размера с выводом в другой буфер. Целевой формат цвета должен быть установлен в fccDstColorFormat. ulDstWidth и ulDstHeight должны указывать новый размер изображения, ulNumDstRects должен быть равен 1 и pVisDstRects должен указывать на область с xLeft = yBottom = 0, xRight = ulDstWidth и yTop = ulDstHeight.


Как упоминалось ранее, *ppFrameBuffer возвращаемая DiveOpen служит для прямой адресации к видео-буферу. Этот метод доступа предполагает, что приложение будет само организовывать клиппирование, конверсию цвета и переключение банков. Функции необходимые для прямого доступа:

  • DiveAcquireFrameBuffer
  • DiveDeacquireFrameBuffer
  • DiveSwitchBank
  • DiveCalcFrameBufferAddress

Функция DiveQueryCaps используется для получения информации о нахождении видео подсистемы в banked режиме. DiveCalcFrameBufferAddress получает линейный адрес буфера.

PRECTL prectlDest;          /* Координаты в десктопе */
PVOID  pDestinationAddress; /* Адрес буфера */
PULONG pulBankNumber;       /* Номер банка */
PULONG pulRemlinesInBank;   /* Линии, оставшиеся в банке */

ulErrorCode = DiveCalcFrameBufferAddress
              (
               hDiveInst, &prectlDest, &pDestinationAddress,
               &pulBankNumber, &pulRemlinesInBank
              );

Для выполнения корректного клиппирования prectlDest должен находиться внутри видимой области окна приложения. Если текущий видео режим требует переключения банков, то приложение не должно выводить больше чем pulRemlinesInBank линий для каждого банка. Данные выводимые в pDestinationAddress должны быть того же формата что и видео-буфер(см. DiveQueryCaps) (Для приведения их к этому виду можно использовать все тот же DIVE). Плюс к тому, если текущий режим является палитровым, то данные должны соответствовать физической палитре.

Все записи в буфер должны начинаться с DiveAcquireFrameBuffer и заканчиваться DiveDeacquireFrameBuffer. Кроме того приложение не должно получать доступа к видео-буферу между сообщениями WM_VRNDISABLED и WM_VRNENABLED. Следующий фрагмент представляет прямой вывод видео-буфер при разбиении на банки. Флаг fFBAccessOK снимается когда приложение получает сообщение WM_VRNDISABLED и устанавливается при сообщении WM_VRNENABLED.

BOOL  fKeepBlitting = TRUE;
BOOL  fFBAccessOK;
RECTL rectlOutput;
RECTL rectlDest;
ULONG ulMoreLines;
LONG  lBlitTop;
PVOID pDestinationAddress;
ULONG ulBankNumber;
ULONG ulRemlinesInAperature;
BOOL  fAcquired = FALSE;

while (fKeepBlitting)
{
   /* ... здесь вызов DiveSetupBlitter как и раньше ...    */
   /********************************************************/
   /* Вычисление количества линий для вывода. Вывод только */
   /* тех линий которые находятся в текущем банке          */
   /* Переключение банков пока все изображение не будет    */
   /* выведено.                                            */
   /********************************************************/

   ulMoreLines = rectlDest.yTop - rectlDest.yBottom;
   memcpy(&rectlDest, &rectlOutput, sizeof(RECTL));
   while (ulMoreLines && fFBAccessOK)
   {
      ulErrorCode = DiveCalcFrameBufferAddress
                    (
                     hDive, rectlDest, &pDestinationAddress,
                     &ulBankNumber, &ulRemlinesInAperture
                    );
      if (!fAcquired)
      if (!DiveAcquireFrameBuffer(hDive, ulBankNumber)) 
       fAcquired = TRUE;
       else break;
       
      DiveSwitchBank(hDive, ulBankNumber);
      {
         if (ulRemlinesInAperture < ulMoreLines)
         {
            rectlDest.yTop -= ulRemlinesInAperture;
            ulMoreLines -= ulRemlinesInAperture;
         }
         else ulMoreLines = 0;
      }
      if (fAcquired)
       DiveDeacquireFrameBuffer(hDive);
   } /* end: пока есть линии для вывода */
} /* end: цикл вывода */

Пара советов:

  • Прежде всего, если это возможно, сразу определится с глубиной цвета.
  • Пускать блиттер лучше (читай правильнее) в отдельной нити.
  • Почитать про DIVE можно в тулките - book/mmref2.inf
  • Примеры все в том-же тулките - samples/mm/dive/ и /samples/mm/fsdive/
  • Очень неплохая статья Дмитрия Завалишина помогает понять идеологию программирования под /2 (и в частности графики).
  • Так-же полезно поинтересоваться RDM2.

Здесь вы можете посмотреть на примеры использования DIVE

Простенькая демка и ее аналог для dos'a (необходим какой-нибудь dpmi сервер (os/2 в качестве сервера подойдет:))
моя версия "the Matrix" :)
ксоникс, еще в процессе разработки.

- Артем Давиденко aka sNOa aka 2:5036/12.777

P.S.

По сути эта статья является переводом divestuff.zip, добытого с CD06.

P.P.S.

greetings всем маньякам которые верят в то что у /2 есть будущее.

всем кто живет на #os2russian

e-Deniska и e-co за периодическое пинание на подвиги

Lelik - WarpVision просто класс

[zuko] - ты уже перестал пить коньяк по утрам (отвечай да/нет)

nickk - в частности за новый mkisofs

RElf - за множество полезной информации

Попробуй программу:

Одевать ли свитер? брать ли зонтик? Виджет Weather Widget показывает температуру воздуха и даёт прогноз погоды.

Комментарии:

Validator
2002-02-04 16:00:00

Насчет "радужная" - специфика сайта обязывает :-). А демы у мя на Warp4+XRRM15+14.082c+SDD b44 - без проблем. Кстати смотрятся кульно. Тока я не понял, пачяму в матрице иероглифы? |-)

sNOa
2002-02-04 17:33:34

вообще там не иероглифы, а японский шрифт(специально для этого часами медитировал перед скриншутом с фильма). все писалось на ACP2+SDD b43.

Сергей
2002-02-04 17:44:35

2sNOa: А еще какие-нибудь проги есть? Игра какая-нибудь маленькая, но прикольная?

Sergey Posokhov
2002-02-04 18:49:19

Bugs, выпускаемая когда-то Стардоком.

Летит такая чушка и стреляет жуков!!!

Для детей от 5 до 8 подойдет :-)

zuko
2002-02-04 20:05:44

sNOa: да/нет

sNOa
2002-02-04 21:28:57

2zuko: кааайф.

2Сергей: проги-то есть а вот с графикой грабли.

из меня то художник еще тот :(

Max Droganow
2002-02-05 09:48:34

Чнго- ты про графику-то плачешься ??? Нарисую что надо - ты ИДЕИ дава-а-а-а-й.... (рисовать буду пока с плюсами не разберусь - тады уж ты мне рисовать будешь ;-))))) )

Max Droganow
2002-02-05 09:50:31

И вообще - пора симулятор алкоголиков писать... (PSSST-4 ZX Speccy)

RElf
2002-02-05 11:16:29

А помните мы тут с Леликом баг в DIVE зафиксили:

Fix for DIVE.DLL to allow hicolor. Look for 0BC0C745F000 and replace the latest 00 with 01. Don't forget to unpack by lxLite before!

SERG
2002-02-05 11:57:07

Какой симулятор алкаголиков.

АРКАНОИД хочу чем не идея.

Даже полвовина графического материала есть например в игре xonex.

Eugene Gorbunoff
2002-02-05 13:13:02

Сделайте гаму про БиллаГейтса. Что-нибудь типа "Захват главного офиса Микрософт".

Eugene
2002-02-05 14:28:15

Из FAQ по фильму "Матрица":

Q: Что это за зеленого цвета в коде Матрицы?

A: Это числа и зеркально отраженные японские буквы алфавита катакана.

sNOa
2002-02-05 14:58:02

eros2: спасибо, учту.

RElf: таки да, жить стало лучше, жить стало веселей(отфикшенный дайв буду подкладывать в архивы).

ppl: а кто укажет на точный алгоритм этого эффекта.

Max Droganow
2002-02-07 12:11:18

Про Билли идеи сразу отметаются. Этот главный телепузик сам подохнет ... а симулятор алкоголиков - давно вынашиваемая идея - довольно проста в реализации, но играбелна до жути...

Олег Булаский
2002-02-11 07:19:45

А нельзя Matrix переделать как модуль к скринсейверу, а?

Очень хоцца...

sNOa
2002-02-12 22:14:04

2 Олег Булаский: а к какому ссэйверу?

RElf
2002-02-13 04:35:31

Как я понял, имеется ввиду

[url]

ErOS2 сделал несколько DIVE модулей к нему, включая мою адаптацию IFSIM2. Их можно найти на его странице [url]

Так что, можно к нему обращаться за консультацией.

ErOs2
2002-02-13 14:35:13

Можно обращатся. Только моя страница счас в дауне. Скринсейверные модули которые я делал работают с ScreenSaver (by Зигфрид Ханиш) и Blanker. Модули есть на хоббесе.

Deniska
2002-02-13 15:15:15

а отдельными exe их можно получить? а то ставить это чудо не хочется, а тот же IFSIM - очень красивая штука.

ErOs2
2002-02-13 17:19:42

to Deniska: пока нет.

Олег Булаский
2002-03-04 07:16:36

to ErOs2 & sNOa: блин, мужики, ну сделайте "матрицу" к скринсеверу...

sNOa
2002-03-04 18:45:52

хыхы, ленимся мы:) пока

LightElf
2002-03-16 10:31:02

Хотелось бы остановиться на двух моментах:

1. Наличие аппаратной акселерации можно определить (в какой-то степени) по порядку следования элементов в списке поодерживаемых входных форматов, который возвращает функция DiveQueryCaps. Если аппаратной поддержки нет, то первым (наиболее предпочтительным с точки зрения DIVE) будет FOURCC_R565. При наличии в системе аппаратного акселератора первыми в списке будут форматы, поддерживаемые акселератором. Это может быть полезно для тех, кто пишет разнообразные видеоплейеры.

2. При наличии аппаратной акселерации, буфер выделяемый по DiveAllocImageBuffer реально располагается в видеопамяти со всеми вытекающими последствиями (видеопамять не кэшируется на чтение и вообще, чтение оттуда очень медленное), так что в этот буфер надо только писать и как можно более быстро.

Прокомментируйте эту статью (напоминаем, автор работал над текстом несколько недель, уважайте мнение других).


Ваше имя:

Ваш E-Mail:

CODE:
......

  

Ваш комментарий:


В eComStation 2.0 реализовано удобное (автоматическое) переключение между WiFi и Ethernet-соединением. Что нового в eCS 2.0?

Статьи

Операционная система
Программное обеспечение
Оборудование
Для разработчика
Разное
Колонка редактора


Готовая eComStation на SSD диске

 





Последний активный опрос: Какая высота барьера RPM?

[Google]

IBM OS/2 Warp

 
Обучение новичков

Списки протестированного OS/2 оборудования

 
Статьи


   
  Почему eComStation?
Возможности
Особенности
Применение
Ролики и скриншоты
   eComStation для
для бизнесменов
для студентов и инженеров
для продавцов компьютеров
сообщество пользователей
   Разработчик
Распространить программу
Описание API, библиотеки
Начать новый проект
Конкурсы
   Программы
Он-лайн каталог
Выбрать через eCo Market
   Служба поддержки
Отправить вопрос
Купить eComStation
Вопросы и ответы
Обучение новичков
 
 
© 2001 - 2021 eCo Software, All rights reserved
Сибирский Медведь технологическая компания
eComStation Serenity Systems International • OS/2 Warp IBM Corporation • ArcaOS Arca Noae