My-library.info
Все категории

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

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Стэн Трухильо - Графика для Windows средствами DirectDraw. Жанр: Программирование издательство неизвестно, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
Графика для Windows средствами DirectDraw
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
17 сентябрь 2019
Количество просмотров:
155
Читать онлайн
Стэн Трухильо - Графика для Windows средствами DirectDraw

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

Стэн Трухильо - Графика для Windows средствами DirectDraw - описание и краткое содержание, автор Стэн Трухильо, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info

Графика для Windows средствами DirectDraw читать онлайн бесплатно

Графика для Windows средствами DirectDraw - читать книгу онлайн бесплатно, автор Стэн Трухильо

Когда любое из двух событий переходит в установленное состояние, функция Lock() завершается, и мы проверяем код возврата. Если выясняется, что было установлено событие завершения потока (обозначенное константой quit_event_index), мы выходим из функции MouseThread(), тем самым завершая поток. В противном случае активизация потока вызвана событием мыши, поэтому мы переходим к обработке новых данных.

Однако сначала необходимо захватить критическую секцию с помощью объекта critsection. Для получения данных нам придется обращаться к очереди событий от кнопок мыши и к первичной поверхности, поэтому выполнение этого кода следует синхронизировать с основным потоком.

Мы в цикле получаем данные от объекта DirectInputDevice, представляющего мышь, с помощью функции GetDeviceData(). Если получены данные о перемещении мыши, происходит обновление переменных curx и cury. Если получены данные о нажатии кнопок, они заносятся в очередь событий.

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

Наконец, мы проверяем новое положение курсора. Если перемещение курсора не обнаружено, критическая секция освобождается, а объект CMultiLock снова используется для блокировки по обоим событиям. Если курсор переместился в другое положение, мы вызываем одну из двух функций обновления курсора в зависимости от того, перекрывается ли старая область курсора с новой. Если области перекрываются, вызывается функция UpdateCursorComplexCase(); в противном случае вызывается функция UpdateCursorSimpleCase().

Начнем с более простой функции UpdateCursorSimpleCase() (см. листинг 7.6).


Листинг 7.6. Функция UpdateCursorSimpleCase()

BOOL CursorWin::UpdateCursorSimpleCase(int curx, int cury, int oldcurx, int oldcury) {

 RECT src;

 HRESULT r;

 //------ Блиттинг 1: стирание старого курсора ----------

 r=primsurf->BltFast(oldcurx, oldcury, cursor_under, 0, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 1 failedn");

  CheckResult(r);

 }

 //------ Блиттинг 2: сохранение области под новым курсором ------

 src.left=curx;

 src.top=cury;

 src.right=curx+cursor_width;

 src.bottom=cury+cursor_height;

 r=cursor_under->BltFast(0, 0, primsurf, &src, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 2 failedn");

  CheckResult(r);

 }

 //------ Блиттинг 3: рисование нового курсора ----------

 r=primsurf->BltFast(curx, cury, cursor, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 3 failedn");

  CheckResult(r);

 }

 return TRUE;

}

С помощью трех последовательных вызовов функции BltFast() интерфейса DirectDrawSurface, функция UpdateCursorSimpleCase() стирает существующий курсор, сохраняет область под новым курсором и рисует новый курсор.

В UpdateCursorComplexCase() функция BltFast() вызывается пять раз. Два дополнительных блиттинга предназначены для копирования обновляемой части первичной поверхности на вспомогательную поверхность (cursor_union) и обратно. Функция UpdateCursorComplexCase() приведена в листинге 7.7.


Листинг 7.7. Функция UpdateCursorComplexCase()

BOOL CursorWin::UpdateCursorComplexCase(int curx, int cury, int oldcurx, int oldcury) {

 RECT src;

 HRESULT r;

 int unionx=min(curx, oldcurx);

 int uniony=min(cury, oldcury);

 int unionw=max(curx, oldcurx)-unionx+cursor_width;

 int unionh=max(cury, oldcury)-uniony+cursor_height;

 //----- Блиттинг 1: копирование объединяющего прямоугольника

 // во вспомогательный буфер --------

 src.left=unionx;

 src.top=uniony;

 src.right=unionx+unionw;

 src.bottom=uniony+unionh;

 r=cursor_union->BltFast(0, 0, primsurf, &src, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 1 failedn");

  CheckResult(r);

 }

 //------ Блиттинг 2: стирание старого курсора

 // во вспомогательном буфере ---------

 r=cursor_union->BltFast(oldcurx-unionx, oldcury-uniony, cursor_under, 0, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 2 failedn");

  CheckResult(r);

 }

 //------ Блиттинг 3: сохранение области под новым курсором -----

 src.left=curx-unionx;

 src.top=cury-uniony;

 src.right=src.left+cursor_width;

 src.bottom=src.top+cursor_height;

 r=cursor_under->BltFast(0, 0, cursor_union, &src, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 3 failedn");

  CheckResult(r);

 }

 //------ Блиттинг 4: рисование нового курсора

 // во вспомогательном буфере ---------

 r=cursor_union->BltFast(curx-unionx, cury-uniony, cursor, 0, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 4 failedn");

  CheckResult(r);

 }

 //------- Блиттинг 5: копирование вспомогательного буфера

 // на первичную поверхность --------

 src.left=0;

 src.top=0;

 src.right=unionw;

 src.bottom=unionh;

 r=primsurf->BltFast(unionx, uniony, cursor_union, &src, DDBLTFAST_WAIT);

 if (r!=DD_OK) {

  TRACE("Blt 5 failedn");

  CheckResult(r);

 }

 return TRUE;

}

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

Завершение приложения 

Осталось лишь поговорить о том, как завершается работа приложения. Эта тема неоднократно рассматривалась, и ее можно было бы пропустить, но для программы Cursor она важна из-за наличия дополнительного потока. Мы должны не только послать потоку ввода сигнал о завершении, но и проследить за тем, чтобы поток завершился до уничтожения объекта устройства мыши и поверхностей DirectDraw. В противном случае он может попытаться обратиться к мыши или обновить первичную поверхность после того, как соответствующие объекты перестанут существовать. Функция OnDestroy() выглядит так:

void CursorWin::OnDestroy() {

 critsection.Lock();

 DirectDrawWin::OnDestroy();

 if (mouse) {

  TRACE("mouse->Unacquire()n");

  mouse->Unacquire();

  TRACE("sending mouse quit message...n");

  mouse_event[quit_event_index]->SetEvent();

  Sleep(100);

  // дать потоку мыши возможность ответить

  TRACE("Releasing mouse pointer...n");

  mouse->Release(), mouse=0;

  delete mouse_event[mouse_event_index];

  delete mouse_event[quit_event_index];

 }

 if (keyboard) keyboard->Release(), keyboard=0;

 if (dinput) dinput->Release(), dinput=0;

 critsection.Unlock();

}

Когда MFC вызывает функцию OnDestroy(), основной поток заведомо не обновляет экран, потому что он занят выполнением этой функции. Тем не менее мы не знаем, не обновляется ли экран потоком ввода. Чтобы поток ввода закончил последнее обновление, мы блокируем критическую секцию.

Далее мы уступаем мышь. Устройство перестает генерировать новые события, которые заставили бы поток ввода попытаться снова обновить экран. Затем функция CEvent::SetEvent() посылает потоку ввода сигнал о завершении.

Нам осталось лишь освободить объекты DirectInput. Но перед тем, как это делать, мы вызываем функцию Sleep(), чтобы ненадолго приостановить основной поток. Поток ввода получает возможность обработать событие и завершиться. Наконец, мы освобождаем критическую секцию, и функция завершается — на этом работа приложения заканчивается.

Заключение 

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

Глава 8. Воспроизведение видеороликов

Видеоролики встречаются в компьютерных играх уже несколько лет, но обычно лишь в простейших заставках или переходах между уровнями. Впрочем, иногда они образуют все содержание самой игры. Например, в игре Phantasmagoria фирмы Sierra On-Line видеотехнология применяется для наложения роликов с живыми актерами на интерьеры, сгенерированные компьютером. В результате возникает на удивление правдоподобный синтез реального и компьютерного окружения. В этом случае видео обеспечивает уровень реализма, которого было бы невозможно добиться с синтезированными актерами.

В этой главе мы узнаем, как считать AVI-файл и вывести его на поверхности DirectDraw. Хотя материал не ориентирован ни на какие конкретные цели, кроме простого воспроизведения видеороликов, он станет хорошей отправной точкой для самостоятельной работы с видео в DirectDraw. Изложенный материал воплощен в программе AviPlay, предназначенной для воспроизведения AVI-файлов.


Стэн Трухильо читать все книги автора по порядку

Стэн Трухильо - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


Графика для Windows средствами DirectDraw отзывы

Отзывы читателей о книге Графика для Windows средствами DirectDraw, автор: Стэн Трухильо. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.