Рейтинговые книги
Читем онлайн Графика для Windows средствами DirectDraw - Стэн Трухильо

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 30 31 32 33 34 35 36 37 38 ... 66

Неоптимизированный цикл похож на тот, что применялся для 16-битных поверхностей, но на этот раз нам не нужно выполнять сокращение цветов. Для доступа к поверхности и графическим данным используются два указателя, surf и image. Оба являются указателями на 24-битный тип RGBTRIPLE, что упрощает перебор 24-битных пикселей.

Каждая цветовая составляющая извлекается из буфера графических данных и сдвигается в соответствии со значением переменных loREDbit, loGREENbit и loBLUEbit. Затем компоненты объединяются и заносятся в память поверхности. Наконец, инкрементирование указателей surf и image перемещает их к следующему пикселю. 

32-битные поверхности

Последняя функция, Copy_Bmp24_Surface32(), предназначена для 32-битных поверхностей и очень напоминает функцию Copy_Bmp24_Surface24(). Если бы в 32-битной поверхности все 32 бита использовались для хранения цветовых составляющих, нам пришлось бы выполнять расширение цветов, но так как используется только 24 бита, в этом нет необходимости. Функция Copy_Bmp24_Surface32() приведена в листинге 5.4.

Листинг 5.4. Функция Copy_Bmp24_Surface32()

BOOL DirectDrawWin::Copy_Bmp24_Surface32(LPDIRECTDRAWSURFACE surf, BYTE* bmpbuf, int w, int h) {

 if (surf==0 || bmpbuf==0)  return FALSE;

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 HRESULT r=surf->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0);

 if (r!=DD_OK) {

  TRACE("Copy_Bmp24_Surface32: Lock() failedn");

  return FALSE;

 }

 int bytesrequired=w*3;

 int bytesgiven=(bytesrequired+3) & ~3;

 BYTE* surfbits = (BYTE*)desc.lpSurface;

 BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);

 for(int i=0; i<h; i++) {

  DWORD* surf=(DWORD*)surfbits;

  RGBTRIPLE* image=(RGBTRIPLE*)imagebits;

  for (int p=0;p>w;p++) {

   DWORD r=image->rgbtRed << loREDbit;

   DWORD g=image->rgbtGreen << loGREENbit;

   DWORD b=image->rgbtBlue << loBLUEbit;

   DWORD* data=(DWORD*)surf;

   *data = r|g|b;

   surf++;

   image++;

  }

  surfbits += desc.lPitch;

  imagebits -= bytesgiven;

 }

 surf->Unlock(0);

 return TRUE;

}

Для работы с пикселями каждой строки используются два указателя, surf и image. Первый является указателем на 32-битный тип DWORD и используется для перебора 32-битных пикселей в памяти поверхности. Второй является указателем на 24-битный тип RGBTRIPLE и используется для доступа к пикселям графических данных. Функция вряд ли нуждается в пояснениях, поскольку она ничем не отличается от своего аналога для 24-битных поверхностей, кроме типа указателя surf и отсутствия оптимизированного варианта цикла.

Программа BmpView 

На основе полученных знаний мы напишем приложение DirectDraw для просмотра BMP-файлов. Программа BmpView отображает диалоговое окно, в котором пользователь выбирает BMP-файл. Затем она выводит список всех видеорежимов, пригодных для просмотра выбранного изображения. Если выбрать видеорежим и нажать кнопку Display, программа BmpView переходит в заданный режим и отображает содержимое BMP-файла. Если изображение не помещается на экране, его можно прокрутить с помощью клавиш стрелок, Home, End, Page Up и Page Down. Диалоговое окно для выбора файла изображено на рис. 5.7. 

Рис. 5.7. Диалоговое окно для выбора файла в программе BmpView

Обратите внимание на то, что в диалоговом окне отображаются размеры выбранного файла, а глубина пикселей определяет, какие видеорежимы могут использоваться для его отображения. На рисунке выбрано 8-битное изображение, поэтому в список включены только 8-битные режимы. Если выбрать 24-битное изображение, то список состоял бы только из беспалитровых режимов.

Наше знакомство с программой BmpView затрагивает следующие вопросы:

• загрузка изображений из BMP-файлов;

• прямой доступ к памяти поверхности;

• прокрутка больших поверхностей;

• работа с диалоговыми окнами Windows в DirectDraw.

Первые два вопроса мы уже обсудили, осталось лишь рассмотреть код. Хотя два последних вопроса и не имеют прямого отношения к теме, о них тоже стоит поговорить. 

Прокрутка больших поверхностей 

До выхода DirectX 5 библиотека DirectDraw не позволяла размещать в видеопамяти поверхности, ширина которых превышала ширину первичной поверхности. В DirectX 5 это ограничение снято, но лишь для видеоустройств, поддерживающих такую возможность.

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

• установка библиотеки DirectX 5;

• поддержка широких поверхностей видеоустройством;

• наличие достаточного объема видеопамяти.

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

Проблемы с диалоговыми окнами 

Работать с диалоговыми окнами Windows в полноэкранном приложении оказывается не так уж просто. Разумеется, полноэкранному приложению нужен интерфейс, но стоит ли для этого использовать знакомый интерфейс Windows — вопрос спорный. Решение этой проблемы можно выбрать из трех основных вариантов:

• организовать переключение страниц и управление палитрами, чтобы обеспечить правильное отображение диалоговых окон Windows;

• восстанавливать рабочий стол каждый раз, когда потребуется вывести диалоговое окно;

• создать нестандартное диалоговое окно и управляющие элементы DirectDraw.

В первом варианте вам придется самостоятельно управлять переключением страниц и палитрами с учетом Windows GDI. GDI не поддерживает DirectDraw, так что независимо от того, какая страница видеопамяти отображается в данный момент, диалоговые окна GDI всегда выводятся на «настоящей» первичной поверхности, или поверхности GDI. В беспалитровых режимах вывод GDI выглядит правильно и без вмешательства с вашей стороны, но в палитровых режимах отсутствие поддержки DirectDraw в GDI дает о себе знать — GDI продолжает выводить диалоговые окна в системной палитре Windows, не подозревая о том, что в данный момент может действовать другая палитра. Решение зависит от требований, предъявляемых приложением к палитре.

В программе BmpView мы будем управлять механизмом переключения страниц и восстанавливать системную палитру Windows для правильного отображения диалоговых окон. Вы увидите, как это делается, при изучении кода BmpView.

Второй вариант — восстанавливать видеорежим и рабочий стол Windows перед отображением диалогового окна. Он встречается в некоторых коммерческих продуктах; например в игре MechWarrior 2 фирмы Activision для заставок, воспроизведения видеороликов и вступительного инструктажа используется стандартный интерфейс Windows. Затем, с началом миссии, игра берет на себя все управление видеокартой и не пользуется никакими интерфейсными компонентами Windows. После завершения миссии поверхность рабочего стола снова восстанавливается. В этой игре данная методика работает неплохо.

Версия MechWarrior 2, о которой я говорю, проектировалась для чипов 3Dfx. Для видеоустройств, построенных на таких чипах, вывод диалоговых окон в DirectDraw невозможен, потому что 3Dfx являются вторичными видеоустройствами, и GDI ничего не знает об их существовании. Поэтому команда разработчиков Activision не могла выбрать первый вариант и отображать диалоговые окна в DirectDraw.

Третья стратегия (создание нестандартных интерфейсов на базе DirectDraw) оказывается самой трудоемкой. Разработка нестандартных управляющих элементов давно превратилась в отдельную отрасль программной индустрии, и мало кто из разработчиков позволяет себе тратить время на создание кнопок, ползунков и списков, когда с приложением и без того хватает хлопот. С другой стороны, этот вариант позволяет создать интерфейс, спроектированный специально для вашего приложения. Теоретически этот интерфейс может быть столь же привлекательным и впечатляющим, как и само приложение.

В программе BmpView используется первый вариант. Перед выводом диалогового окна на рис. 5.7 мы отображаем поверхность GDI и восстанавливаем системную палитру. 

Определение класса 

В программе BmpView, как и в других программах этой книги, класс окна приложения является производным от класса DirectDrawWin. К сожалению, по нашему соглашению об именах имя производного класса образуется из имени приложения и суффикса Win. Следовательно, класс окна приложения BmpView называется BmpViewWin, что выглядит несколько неуклюже. Объявление класса BmpViewWin приведено в листинге 5.5.

1 ... 30 31 32 33 34 35 36 37 38 ... 66
На этой странице вы можете бесплатно читать книгу Графика для Windows средствами DirectDraw - Стэн Трухильо бесплатно.
Похожие на Графика для Windows средствами DirectDraw - Стэн Трухильо книги

Оставить комментарий