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

Тут можно читать онлайн Стэн Трухильо - Графика для Windows средствами DirectDraw - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Графика для Windows средствами DirectDraw
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.88/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 100
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)

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

Интервал:

Закладка:

Сделать

} else if (abs(curx-oldcurx) >= cursor_width || abs(cury-oldcury) >= cursor_height) {

//----- простой случай: прямоугольники нового

// и старого курсора не перекрываются -----

win->UpdateCursorSimpleCase(curx, cury, oldcurx, oldcury);

} else {

//----- сложный случай: прямоугольники нового

// и старого курсора перекрываются -----

win->UpdateCursorComplexCase(curx, cury, oldcurx, oldcury);

}

nevermind:;

critsection.Unlock();

}

TRACE("leaving mouse thread\n");

return 0;

};

Функция MouseThread()имеет один параметр — значение, передаваемое функции AfxBeginThread()при создании потока (см. листинг 7.3). Мы передавали указатель this, поэтому сейчас сможем присвоить его значение указателю на класс CursorWin(переменная win). В функции MouseThread()указатель winбудет использоваться для доступа к членам класса CursorWin.

Функция MouseThread()в цикле выполняет блокировку по двум событиям. Класс CMultiLockпозволяет блокироваться как по событиям от мыши, так и по событию завершения потока. Фактическая блокировка выполняется функцией CMultiLock::Lock(). По умолчанию функция Lock()блокирует поток до установки всех (в данном случае - двух) заданных событий. Мы изменяем это поведение и передаем FALSEв качестве второго аргумента Lock(), показывая тем самым, что функция должна снимать блокировку при установке хотя бы одного из этих событий.

Когда любое из двух событий переходит в установленное состояние, функция 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 failed\n");

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 failed\n");

CheckResult(r);

}

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

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

if (r!=DD_OK) {

TRACE("Blt 3 failed\n");

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 failed\n");

CheckResult(r);

}

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

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

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

if (r!=DD_OK) {

TRACE("Blt 2 failed\n");

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 failed\n");

CheckResult(r);

}

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

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

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

if (r!=DD_OK) {

TRACE("Blt 4 failed\n");

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 failed\n");

CheckResult(r);

}

return TRUE;

}

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

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

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


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

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




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x