Что такое код stretchdibits


С++ MFC StretchDIBits PixelFormat8bppIndexed

Игра с MFC и кажется, что при рисовании PixelFormat8bppIndexed что-то не так.

С другими форматами все в порядке.

Я думаю, проблема в:

Как это исправить?

Gdiplus::GetHBITMAP позволяет напрямую получать HBITMAP . В большинстве случаев этого достаточно, чтобы разрешить использование функций GDI с помощью GDI+.

Если по какой-то причине вы должны использовать StretchDIBits , тогда сначала используйте GetDIBits для извлечения bits и BITMAPINFO

При распределении памяти для BITMAPINFO убедитесь, что вы добавили дополнительную память для палитры в случае работы с 8-битным растровым изображением:

Вы также можете использовать вспомогательный класс gdiplus_init чтобы убедиться, что запуск/выключение всегда вызываются.

SetDIBitsToDevice vs D3D/DD

сразу оговорюсь о том, что с DirectX знаком на уровне туторов и небольших самописных тестовых приложений. теперь собственно по теме: имеется большой битмап, формат BGRA, типичные размеры 5 000 x 5 000. в риалтайме происходит его обработка\прорисовка на основе получаемых в риалтайме данных. оптимизация алгоритмов под MMX\SSE позволила снизить время обработки до 2-4 ms на проход. узким местом стал именно вывод на экран через SetDIBitsToDevice (аналог StretchDIBits без маштабирования), занимает вывод около 7-8 ms. скорость работы вполне приемлима (

100 fps), но есть несколько но:

1. на мой взгляд, не спортивно когда вывод на экран занимает в два-четыри раза больше времени, чем сами расчёты. хотелось бы этот момент оптимизировать.
2. tearing-артифакт. с этим понятно.

выход один — D3D/DD. тут тоже, по моему мнению, не всё гладко:

1. обработку нельзая перенести на GPU, следовательно текстура будет в обычной памяти, т.е. будет каждый кадр переноситься в память GPU.
2. нельзя создать одну текстуру для всего битмапа, его размеры не позволяют, т.е. каждый кадр получаем дополнительный перенос из битмапа в текстуру меньшего размера.

будет ли в таком случае хоть какой-то прирост производительности? может быть что-то ещё присоветуете?

в д3д10 можно сделать текстуру размером 8192х8192 и думаю вполне можно выполнить любую обработку шейдером.

если по политическим или другим причинам д3д10 не подходит.
то еще можно попробовать

DrawDib
The DrawDib functions provide high performance image-drawing capabilities for device-independent bitmaps (DIBs). DrawDib functions support DIBs of 8-bit, 16-bit, 24-bit, and 32-bit image depths.

DrawDib functions write directly to video memory. They do not rely on functions of the graphics device interface (GDI).

по идее то что не используется GDI может ускорить вывод.

stab
А формат битмэпа соответствует формату экрана? Какой размер выводимого окна? А то что-то медленно, у меня SetDiBits дает 250 fps на 1024*768.

DrawDib API — чуда не произошло, производительность не выросла ни на сотую долю миллисекунды. что касается D3D10, это конечно хорошо, только мало у кого есть D3D10-карточки.

Mikle, в настройках экрана стоит 32 bit, т.е. видимо соответствует. размер 1280×1024.

.. если расчёты отключить то около 150 fps выдаёт. при 1024×768 тоже

stab
>с DirectX знаком на уровне туторов и небольших самописных тестовых приложений.
Рекомендуется сначала изучить тему глубже.
Прироста не будет, будут фантастические тормоза в любой реальной задаче.

ЗлобныйШкольнег, эти 250 fps при 1024×768 следует понимать как предел по пропускной способности AGP?

stab
Потому что у CPU есть еще куча дел, кроме растеризации.

хм.. это уже скорее не по теме. что-то я не очень понимаю откуда берётся это ограничение. загрузка процессора на приоритетах REALTIME_PRIORITY_CLASS + THREAD_PRIORITY_TIME_CRITICAL —

55%, так же как и при обычных приоритетах. выходит, при тупом выводе одного и того же битмапа без его модификаций, около 50 процентов времени процессор простаивает, что есть хорошо, а с другой стороны плохо.

причём, скорость безусловной обработки производимой CPU над битмапом 1024×768 без вывода на экран — 500 fps (2 мс на проход), по 1.5 Гб/c по DDR качает в обе стороны (чтение\запись), данные в кеш CPU полностью точно не влазят. загрузка CPU — 70%. в сумме, при условии, что хоть что-то закешировалось — 2-3 Гб/c.

Mikle
>А формат битмэпа соответствует формату экрана?
stab
>формат BGRA
>.
>в настройках экрана стоит 32 bit,
> т.е. видимо соответствует.

а вот не факт ))
по мойму экранный формат чаще RGBA бывает или ARGB
может там еще байтики местами при выводе меняютцо ?

AndryBlack, NVIDIA в документе озаглавленном как «Achieving Efficient Bandwidth Rates» пишет:

.. NVIDIA graphics cards are built to match the Microsoft GDI
pixel layout, so make sure the pixel format in system memory is BGRA.

.. storing 8-bit textures in a BGRA layout in system memory and use the
GL_BGRA as the external format for textures to avoid swizzling.

c++ — Как заменить StretchDIBits на BitBlt

Здравствуйте! Использую такую функцию:

Но она медленная по сравнению с BitBlt. Вопрос в том, как ее заменить?

    6 1
  • 19 янв 2020 2020-01-19 05:59:32
  • helldrg

1 ответ

это делается проще всего где-то так:

Для работы с памятью на прямую, вам нужна таки секция:

За тем вам нужно скопировать данные именно в выданый системой участок памяти и именно с bits работать. эту ссылку bits можно после копирования переписать в buffer->Memory https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd183494%28v=vs.85%29.aspx Освобождать (DeleteObject,DeleteDC) и рисовать (BitBlt) также само.

Рисовать win умеет только dc. Но эта dc должна быть связана с bitmap. Поэтому так.

Проверьте что б CreateBitmap возвращало не ноль. Ф-ция довольно «вредная». Она не все форматы поддерживает. Формат указывается в предпоследнем параметре. Ещё я сталкивался с тем, что строки картинки в некоторых случаях нужно выравнивать по границам двойного слова, иначе картинку «перекашивает» по диагонали набок.

Если надо загружать с памяти или с диска то можно так: Как загрузить картинку из памяти С++ (Win)?

Технология отображения растров

Для вывода DIB-растров используются функции StretchDIBits и SetDIBitsToDevice. Функция StretchDIBits имеет следующие пара­метры:

— дескриптор контекста устройства;

— х и у координаты, ширина и высота области-приемника изобра­жения (в логических единицах);

— х и у координаты, ширина и высота области-источника изображе­ния^ пикселах);

— адрес массива пикселов изображения;

— адрес заголовка информационного блока в bmp;

— флаг интерпретации цветовой таблицы;

— код растровой операции.

Область-источник указывает, какая часть растра выводится, проис­ходит ли зеркальное отображение по горизонтали и/или по вертикали. Область-приемник задает место на поверхности изображения графиче­ского устройства, область-приемник также можно зеркально отразить и масштабировать. Если размеры областей источника и приемника совпадают, то вывод растра происходит без масштабирования. Способ добавления новых или удаления ненужных пикселов хранится в кон­тексте устройства и может быть изменен функцией SetStretchBltMode. Так, возможно вычислять средний цвет по группе пикселов, комбинировать пикселы с помощью побитовых логических операций, отбрасывать лишние пикселы.

Илон Маск рекомендует:  Как сделать подчёркивание заголовка

Флаг интерпретации цветовой таблицы указывает, что именно со­держит эта таблица компоненты RGB или индексы цветов в логиче­ской палитре.

Код растровой операции показывает способ копирования из облас­ти-источника в область-приемник. Простейшим кодом является SRCCOPY, задающий копирование без дополнительных операций.

Функция SetDIBitsToDevice позволяет выводить растры с сохране­нием масштаба и ориентации либо полностью, либо по строкам.

Для работы с DDB-растрами, являющимися объектами GDI и хра­нящимися в памяти GDI, используются другие API-функции.

Создать DDB-растр можно с помощью функций CreateBitmap, CreateBitmapInDirect, CreateCompatibleBitmap. Все эти функции возвращают дескриптор растрового объекта. CreateBitmap имеет сле­дующие параметры;

— ширина и высота растра в пикселах;

— количество плоскостей cPlanes для хранения цвета пиксела;

— количество битов на 1 пиксел cBitsToPxl;

— адрес массива с пикселами.

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

Функция CreateBitmapInDirect работает с теми же параметрами, что и CreateBitmap, однако они передаются через структуру типа BITMAP. Функция CreateCompatibleBitmap создает DDB-растр, со­вместимый с контекстом заданного устройства. Недостатком трех рас­смотренных функций является то, что они создают либо монохромный растр с инициализацией пикселов, либо цветной растр без инициали­зации.

Для работы в программе с инициализированными цветными рас­трами лучшим выходом является использование ресурсов. Ресурсами являются пиктограммы, рисунки, меню, диалоговые окна, курсоры и шрифты. Они описываются во внешнем текстовом файле, называемом файлом ресурсов и имеющим расширение гс. Различные ресурсы опи­сываются в нем в соответствии со своими форматами. Для того чтобы включить ресурсы в *.ехе файл, их необходимо откомпилировать спе­циальным компилятором ресурсов, который может быть встроен в ин­тегрированную среду разработки программ. Результатом работы ком­пилятора ресурсов является файл с расширением res, который вместе с объектным модулем обрабатывается редактором связей для получения ехе-файла. Преимуществами использования ресурсов являются про­стота их редактирования и независимость описания от текста исходно­го модуля, возможность редактирования ресурсов непосредственно в загрузочном файле (например, для перевода пунктов меню на другой язык), возможность извлечения ресурсов из загрузочного файла для последующего использования в других приложениях.

Каждому ресурсу при описании присваивается идентификатор ре­сурса, который затем используется API-функциями. Например, описа­ние пиктограммы ICON1.ICO имеет вид:

Идентификатор_ресурса ICON [параметры] «ICON1.ICO»

а описание растрового изображения BITMAP1.BMP:

Идентификатор_ресурса BITMAP [параметры] «BITMAP1.BMP» В MASM32 используется числовой идентификатор ресурса.

Несмотря на важность DDB-растров, в Windows отсутствует функ­ция их отображения на устройстве вывода. Их вывод осуществляется

путем копирования с одного устройства на другое как без изменения масштаба (функция BitBlt), так и с изменением (функция StretchBlt). Устройством-приемником служит окно, а в качестве устройства-источника в памяти нужно создать область, которая по своим возмож­ностям должна быть совместима с экраном и в которую нужно запи­сать изображение. Совместимая с окном область памяти также должна иметь свой контекст, называемый контекстом памяти или совмести­мым контекстом памяти. В контексте памяти хранятся дескрипторы инструментов рисования, которые можно заменять на свои, в контекст памяти можно выводить графику. Отличием контекста памяти от кон­текста окна является возможность загрузки в контекст памяти деск­риптора растрового изображения.

Рассмотрим реализацию вывода на экран DDB-растра, описанного как ресурс. Для вывода растрового изображения необходимо выпол­нить следующие действия:

1) загрузить растровое изображение в память и запомнить его деск­риптор. Для этого используется функция LoadBitmap, первым пара­метром которой является дескриптор экземпляра приложения, а вто­рым идентификатор ресурса, описывающего DIB-растр. Функция выделяет память под изображение, загружает его туда, преобразует в DDB-формат и возвращает дескриптор hBmp области памяти с рас­тром. Этот шаг выполняется вне обработки сообщения WMPAINT. Отметим, что если требуется работать с изображением, размер которо­го будет известен позже, то можно зарезервировать требуемый объем памяти функцией CreateCompatibleBitmap. Загрузку битового образа можно осуществлять с помощью функции Loadlmage, загружающей не только растры, но еще пиктограммы и курсоры. Loadlmage воз­вращает дескриптор DDB-растра.

2) получить совместимый с окном контекст устройства для области памяти, где будет храниться изображение, с использованием функции CreateCompatibleDC, единственным параметром которой является дескриптор контекста устройства, куда должно быть выведено изо­бражение. Этот дескриптор hDC либо возвращается функцией Begin-Paint в обработке WMPAINT, либо должен быть получен с помощью функции GetDC. Если использовалась функция GetDC, необходимо после работы вернуть контекст системе с помощью функции Re-leaseDC.

3) включить дескриптор области памяти с растровым изображени­ем hBmp в совместимый с окном контекст памяти, используя функцию SelectObject. Значение дескриптора растрового изображения по умол­чанию в совместимом контексте нужно сохранить, хотя он описывает

изображение размером всего в 1 пиксел. После этого в совместимую память можно выводить любые объекты, вызывать функции рисова­ния.

4) Для того чтобы отобразить на экране созданное изображение,
необходимо скопировать его в окно с использованием функций BitBIt
или StretchBlt. Рассмотрим вызов и параметры функции BitBIt. Вызов
имеет вид:

— hDC и memDCдескрипторы окна приложения, куда копируется изображение, и совместимого контекста памяти;

— хО и уО координаты начальной точки верхнего левого угла изо­бражения-источника, с которой начинается копирование в изображе­ние-приемник. Если все изображение копируется полностью, то нужно указать нулевые значения хО и уО;

— х и у задают координаты верхнего левого угла копии в окне, счи­тая от начала его клиентской области;

— w и h задают ширину и высоту копируемой прямоугольной части изображения. Максимальное значение этих параметров ширина и высота в пикселах исходного изображения. Характеристики изображе­ния можно получить с помощью функции GetObject, которая для рас­трового изображения заполняет структуру BITMAP, поля которой bmWidth и bmHeight хранят ширину и высоту изображения.

— FLAG указывает вид операции над битами изображения и бита­ми области копирования, что используется для реализации мультипли­кации. В простейшем случае FLAG=SRCCOPY, что указывает на ко­пирование источника в приемник с затиранием области копирования. Если нужно реализовать мультипликацию, то в цикле перемещения объекта сначала выводится изображение с FLAG=SRCCOPY, затем после задержки с FLAG=MERGEPAINT, что дает стирание изображе­ния и получение белого фона, после чего изменяют координаты выво­да.

Функция StretchBlt позволяет масштабировать изображение и вы­полнять его зеркальные отражения.

5) вернуть в совместимый контекст памяти старое значение деск­риптора битового изображения.

6) Уничтожить контекст совместимой с окном области памяти.

Иллюстрирующий текст продедуры вывода DDB-растра на MASM32:

Paint_Proc proc hWin:DWORD, hDC:DWORD

LOCAL memDC :DWORD

return 0 Paint_Proc endp

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

Что такое код stretchdibits

The StretchDIBits function copies the color data for a rectangle of pixels in a DIB, JPEG, or PNG image to the specified destination rectangle. If the destination rectangle is larger than the source rectangle, this function stretches the rows and columns of color data to fit the destination rectangle. If the destination rectangle is smaller than the source rectangle, this function compresses the rows and columns by using the specified raster operation.

Syntax

Parameters

A handle to the destination device context.

Илон Маск рекомендует:  Что такое код getobject

The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.

The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.

The width, in logical units, of the destination rectangle.

The height, in logical units, of the destination rectangle.

The x-coordinate, in pixels, of the source rectangle in the image.

The y-coordinate, in pixels, of the source rectangle in the image.

The width, in pixels, of the source rectangle in the image.

The height, in pixels, of the source rectangle in the image.

A pointer to the image bits, which are stored as an array of bytes. For more information, see the Remarks section.

A pointer to a BITMAPINFO structure that contains information about the DIB.

Specifies whether the bmiColors member of the BITMAPINFO structure was provided and, if so, whether bmiColors contains explicit red, green, blue (RGB) values or indexes. The iUsage parameter must be one of the following values.

The array contains 16-bit indexes into the logical palette of the source device context.

The color table contains literal RGB values.

For more information, see the Remarks section.

A raster-operation code that specifies how the source pixels, the destination device context’s current brush, and the destination pixels are to be combined to form the new image. For a list of some common raster operation codes, see BitBlt.

Return value

If the function succeeds, the return value is the number of scan lines copied. Note that this value can be negative for mirrored content.

If the function fails, or no scan lines are copied, the return value is 0.

If the driver cannot support the JPEG or PNG file image passed to StretchDIBits, the function will fail and return GDI_ERROR. If failure does occur, the application must fall back on its own JPEG or PNG support to decompress the image into a bitmap, and then pass the bitmap to StretchDIBits.

Remarks

The origin of a bottom-up DIB is the lower-left corner; the origin of a top-down DIB is the upper-left corner.

StretchDIBits creates a mirror image of a bitmap if the signs of the nSrcWidth and nDestWidth parameters, or if the nSrcHeight and nDestHeight parameters differ. If nSrcWidth and nDestWidth have different signs, the function creates a mirror image of the bitmap along the x-axis. If nSrcHeight and nDestHeight have different signs, the function creates a mirror image of the bitmap along the y-axis.

StretchDIBits creates a top-down image if the sign of the biHeight member of the BITMAPINFOHEADER structure for the DIB is negative. For a code example, see Sizing a JPEG or PNG Image.

This function allows a JPEG or PNG image to be passed as the source image. How each parameter is used remains the same, except:

  • If the biCompression member of BITMAPINFOHEADER is BI_JPEG or BI_PNG, lpBits points to a buffer containing a JPEG or PNG image, respectively. The biSizeImage member of the BITMAPINFOHEADER structure specifies the size of the buffer. The iUsage parameter must be set to DIB_RGB_COLORS. The dwRop parameter must be set to SRCCOPY.
  • To ensure proper metafile spooling while printing, applications must call the CHECKJPEGFORMAT or CHECKPNGFORMAT escape to verify that the printer recognizes the JPEG or PNG image, respectively, before calling StretchDIBits.

ICM: Color management is performed if color management has been enabled with a call to SetICMMode with the iEnableICM parameter set to ICM_ON. If the bitmap specified by lpBitsInfo has a BITMAPV4HEADER that specifies the gamma and endpoints members, or a BITMAPV5HEADER that specifies either the gamma and endpoints members or the profileData and profileSize members, then the call treats the bitmap’s pixels as being expressed in the color space described by those members, rather than in the device context’s source color space.

Examples

Requirements

Minimum supported client

Windows 2000 Professional [desktop apps only]

Функция StretchDIBits

Описание:

function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHeigth, SrcX, SrcY, SrcWidth, ScrHeight: Word; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: Word; Rop:DWord): Integer;

Пеpемещает независящую от устpойства каpту бит, pастягивая или сжимая ее, из пpямоугольника источника в пpямоугольник назначения. Источник и назначение комбиниpуются указанным в Rop обpазом.

Параметры:

DC: Контекст пpинимающего устpойства.
DestX, DestY: Начало пpямоугольника назначения (в логических единицах).
DestWidth: Шиpина пpямоугольника назначения (в логических единицах).
DestHeight: Высота пpямоугольника назначения (в логических единицах).
SrcX, SrcY: Начало пpямоугольника источника (в логических единицах).
ScrWidth: Шиpина пpямоугольника источника (в логических единицах).
ScrHeight: Высота пpямоугольника источника (в логических единицах).
Bits: Массив байт, содеpжащий каpту бит, независящую от устpойства.
Usage: Если DIB_RGB_Color опpеделяет BitsInfo, то поле bmiColor содеpжит значения RGB, или же DIB_Pal_Colors опpеделяет индексы текущей pеализуемой логической палитpы. См. pаздел «Идентификатоpы таблицы цветов, DIB» в главе 1.
Rop: Одна из теpнаpных pастpовых опеpаций. См. pаздел «Теpнаpные pастpовые опеpации» в главе 1.

StretchDIBits

Описание: function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHeigth, SrcX, SrcY,

SrcWidth, ScrHeight: Word; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage:

Word; Rop:DWord): Integer;

Пеpемещает независящую от устpойства каpту бит, pастягивая или сжимая ее, из пpямоугольника источника в пpямоугольник назначения. Источник и назначение комбиниpуются указанным в Rop обpазом.

Паpаметpы:

DC: Контекст пpинимающего устpойства.

DestX, DestY: Начало пpямоугольника назначения (в логических единицах).

DestWidth: Шиpина пpямоугольника назначения (в логических единицах).

DestHeight: Высота пpямоугольника назначения (в логических единицах).

SrcX, SrcY: Начало пpямоугольника источника (в логических единицах).

ScrWidth: Шиpина пpямоугольника источника (в логических единицах).

ScrHeight: Высота пpямоугольника источника (в логических единицах).

Bits: Массив байт, содеpжащий каpту бит, независящую от устpойства.

Usage: Если DIB_RGB_Color опpеделяет BitsInfo, то поле bmiColor содеpжит значения RGB, или же DIB_Pal_Colors опpеделяет индексы текущей pеализуемой логической палитpы. См. pаздел

«Идентификатоpы таблицы цветов, DIB» в главе 1.

Rop: Одна из теpнаpных pастpовых опеpаций. См. pаздел «Теpнаpные pастpовые опеpации» в главе 1.

Возвpащаемое значение:

Число скопиpованных стpок pазвеpтки. функция находится в файле gdi32.dll

Немного о создании демок, часть 1

Здравствуйте!
Эта статья, прежде всего для новичков, тех, кто только решил заняться демосценой, если статья будет положительно принята сообществом, то я сделаю цикл из нескольких статей о создании демок. Каждая статья будет короткой, но в конце каждой статьи будет вполне рабочий пример.
Сразу предупрежу, эта статья не о том как делать Demo с помощью OpenGL, DirectX, и миллионов шейдеров, об этом есть много хороших статей, я буду писать о рисовании в памяти.

На чем писать?

Для начала надо разобраться, как и на чём мы будем писать демку.
Писать мы будем на C, с помощью Visual Studio 2008.

Несколько организационных моментов

Давайте сначала опишем в модуле Images.h структуру TImage, она будет хранить информацию об изображении:

А непосредственно битовая карта изображения будет храниться в массиве, на который будет указывать pBitMap.

Поскольку мы не будем использовать OpenGL и DirectX, надо определиться, как мы будем выводить пиксели на экран.
Вариант с SetPixel() нам не подходит из-за своей медлительности.
На помощь приходит функция WinApi StretchDIBits(), она выводит на Handle массив пикселей, попутно производя масштабирование, если это необходимо.
Вот как выглядит функция, которая выводит массив, где каждый пиксель состоит из 4-х байт, на экран:

Классический цикл выглядит так:

Но мы работаем в Windows, следовательно постоянно должны обрабатывать сообщения окна иначе у пользователя создастся впечатление, что программа зависла, поскольку мы в любом случае будем вызывать Pause() то почему бы не производить обработку сообщений окна в нем?
Нет конечно вполне можно использовать State Machine, но в кому нужна гигантская и неповоротливая State Machine в демке (я не говорю об играх).
Выглядеть pause.c будет так:

Это не очень красиво, но работает вполне надежно.
Любители многопоточности могут просто сделать отдельный поток.

Осталось создать окно:

Теперь можно запускать!

Но пока кроме пустого окна мы ничего не увидим, все верно ведь мы в цикле только очищаем буфер и копируем его на экран:

Рисуем точку

Давайте для начала нарисуем красную точку с координатами x=1, y=1.
Экран для нас будет выглядеть вот так:

Где каждый пиксель изображения можно представить в виде 4-х unsigned char либо одним unsigned long:

То, что серое — это альфа, мы ее пока трогать не будем.

Теперь надо вычислить по формуле (x + y*disp.width) Demo.c

Читают сейчас

Похожие публикации

  • 28 февраля 2020 в 13:16

Инструкция: что делать, если вы не успеваете к дедлайну

Кейс: бесконечная разработка конечной флешки или как не стоит делать стартап. Часть 1: от идеи к продукту

Как делают бумажные деньги

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

Качество анимации в такой демке будет неважным из-за отсутствия синхронизации с вертикальной разверткой монитора. Вам бы, автор, почитать, как делались демки на старых компьютерах, вроде ZX Spectrum, C64, Amiga или Atari. Везде использовалась синхронизация с вертикальной разверткой, обеспечивая плавность анимации. А у вас будут дергания и/или Tearing artifacts — «разрезание надвое» изображения, когда кусок предыдущего кадра виден на экране одновременно с куском следующего кадра, разделенные друг от друга горизонтальной полосой, каждый раз в разном месте.

Проблема синхронизации с вертикальной разверткой до недавних пор очень сложно решалась в Windows из-за того, что разработчики ОС тоже не понимали важность этой задачи. В результате компьютеры от Apple, где разработчики позаботились о синхронизации, сразу покорили пользователей плавностью и красотой анимации.

В Direct3D9Ex есть функция WaitForVBlank — рекомендую пользоваться. Без нее будут большие потери процессорного времени по циклам опроса положения луча и т.д.

Если вы не в курсе — даже в современных мониторах изображение передается с видеокарты на монитор с постоянной скоростью по последовательному интерфейсу. Для такой передачи изображение подвергается развертке — кадровой и строчной, потому что в каждый момент времени по интерфейсу передаются данные не более, чем небольшого числа пикселов. С точки зрения искажений при анимации ничего не меняется по сравнению со случаем старых ЭЛТ-мониторов с их сканирующим лучом.

И если не заботиться о синхронизации — то кадры, передаваемые видеокартой, будут содержать желаемое изображение с вышеописанными искажениями (Tearing). Даже если Tearing не будет проявляться вследствие того, что ОС его подавляет, принудительно используя BackBuffer, все равно анимация не будет плавной. Потому что некоторые желаемые кадры окажутся пропущены, а другие — отображены дважды.

>Если обновление экрана, например, отрисовка какого-либо графического эффекта, происходит за один фрейм — такой эффект называют фреймовым (one-frame). Например, фреймовый скролл — прокрутка экрана со сдвигом изображения каждые 1/50 секунды (для отсутствия искажений картинки при этом требуется учёт временны́х параметров развёртки). Так как ZX Spectrum не имеет аппаратных средств для быстрой обработки графики при относительно невысокой производительность процессора, фреймовые эффекты считаются показателем высокого уровня программирования и качества кода.

За время обратного хода луча много не прорисуешь. В играх и демках высшего класса все делалось еще хитрее. Рисование графики организовывалось таким образом, чтобы оно не прыгало по разным местам экрана, а шло сверху вниз. В результате можно рисовать графику «под лучом» так, чтобы текущее положение луча всегда было выше, чем рисуемый в данный момент участок экрана. Таким образом все время кадра можно безопасно использовать для рисования.

Или, при обновлении изображения один раз в 2 кадра, можно еще было рисовать «над лучом», вдогонку ему.

Недавно для Спектрума вышла игра «Sea Dragon», автор — Андрей Жиглов. Тип — горизонтальный скроллер. Я участвовал в разработке в качестве тестера. В игре была применена технология рисования «под лучом», обеспечивая плавную анимацию с обновлением изображения каждый кадр почти по всему экрану.

проблема с StretchDIBits?

привет всем.
хочу вывести на экран анимацию:

HDC hdc = ::GetDC(this->m_hWnd);
BITMAPINFOHEADER bmiHeader;
PVOID pBits; // pointer to the video buffer
CBitmap bmSection;

memset(&bmiHeader, 0, sizeof(bmiHeader));
bmiHeader.biW > bmiHeader.biHeight = 100;
bmiHeader.biPlanes = 1;
bmiHeader.biBitCount = 24;
bmiHeader.biCompression = BI_RGB;

HBITMAP hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bmiHeader, DIB_RGB_COLORS, &pBits, NULL, 0);
HGDIOBJ hOldBitmap = SelectObejct(FirstDC, hBitmap);

SelectObject(FirstDC, hOldBitmap);
::ReleaseDC(this->m_hWnd,hdc);

пробывал BitBlt и StretchBlt — зарисовывал в таймере весь экран — на компах

ты что ли используеш GDI ? попробуй директ драв или опен гл (в данном случае проще Direct Draw

Очень просто. Та прога перерисовывает не весь битмар а только изменившиеся куски. Пример я кажется видел в семплах к WTL.

А вообще ГДИ жутко тормозной, лучше и не парься.

Прога не может перерисовывать часть экрана — экран всегда разный.

задача:
нужно перерисовывать всегда (каждую мс) весь экран

Самое простое решение DirectDraw
быстро и удобно :)

кстати .. а заливка Битмапом не бастрее будет?
да, и неподскажите где про DirectDraw почитать акромя MSDN?

я тут пример нашел . ставил к себе, подключил библиотеку и. ничего, выдает ошибки

LPDIRECTDRAW7 pDD;
DirectDrawCreateEx(NULL, (VOID**)&pDD, IID_IDirectDraw7, NULL);
m_pDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );

эээ. а как это у тебя pDD в m_pDD превратилось? ;)

Что такое код stretchdibits

Объявляем указатель на описание нашего класса. Ссылку на класс в классе вида. Теперь конструктор и присвоение этой перменной значения NULL. По нажатию на пункт меню И функция рисования.

Из-за того, что когда я писал шаг меня отвлекли я проспал распределение памяти в CDib.cpp, вот необходимые изменения.

Проверим . Только не забудьте указать имя своего BMP файла.

С нашим классом просто. Создаем его и выводим на экран в функции OnDraw с помощью StretchDIBits.

Ну наконец получилось. Если Вы заметили я очень быстро пробежался по многим вопросам, которым нужно уделить больше внимания. Я попробую немного попозже. Несмотря на то, что сегодня суббота меня честно говоря достали. Всё-таки работать тоже надо иногда. То одному чего-то надо, то другому чего-то надо. Вообщем караул. Так что за ошибки извеняйте. Я в свою очередь обещаю описать все мутные вопросы, которые встречались здесь в подробностях.

Илон Маск рекомендует:  MySQL статьи, запросы, разработка приложений с mysql
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Value Meaning
DIB_PAL_COLORS
DIB_RGB_COLORS