S> А на каких виндах такие директы стоят гарантированно?
Помоему на всех старше 95-х...
кстати прикол — 95-е называют игровой системой ... а директ икса на ней по умолчанию нет.
а NT4.0 который ругают что он не для игр, так там DirectX3 по умолчанию и IDirectDraw там есть.
S> Клево! Т.е. будет работать на win9x начиная с win98 и winnt начиная с nt4?
Ну да ...
S> Кстати, есть ли какие-нибудь преимущества у IDirectDraw7 перед просто IDirectDraw?
Ну одно время когда делал скроллинг экрана получалось что на DirectDraw были дергунчики
на DirectDraw7 получалось плавно. Но это все использовалось директ-иксовское...BltFast
и прочая фигня.
Из возможностей DirectDraw помоему лучше использовать только
FDDSPrimary.Lock.
Скопировать необх. данные ...
FDDSPrimary.Unlock.
или
FDDSBack.Lock.
Скопировать необх. данные ...
FDDSBack.Unlock.
Flip;
Частенько для того чтобы написать текст пользуюсь функциями GDI ( TextOut и др. )
При этом вызывается MySurface.GetDC(h); ...
А если я например сделаю так
MySurface = allocmem(SurfaceWidth*SurfaceHeight*(BPP/8));
т.е. просто выделю опр. кусок памяти, можно ли для него получить HDC.
Ведь в результате это по сути и происходит — текст отображается в память выделенной при создании поверхности.
PZ>А если я например сделаю так PZ> MySurface = allocmem(SurfaceWidth*SurfaceHeight*(BPP/8));
Если я правильно понимаю вопрос, тебе нужно создать в памяти совместимый контекст, рисовать там, а потом отображать на реальный?
Если так, то поступай следующим образом:
1)CreateCompatibleDC — создаем в памяти совместимый контекст
2)CreateCompatibleBitmap — создаем совместимый битмэп
3)рисуем уже туда
4)BitBlt — когда необходимо копируем из памяти на реальный контекст
GT>Если я правильно понимаю вопрос, тебе нужно создать в памяти совместимый контекст, рисовать там, а потом отображать на реальный?
Ну почти так.
Допустим у меня имеется область памяти 1, которую я трактую как изображение.которая создается
при помощи allocmem(size)...т.е. не битмэп ...а чисто массив WORD например ( для 16 битного режима ).
Также есть понятие области видео-памяти 2 где находится видимый экран.
Я копирую данные из области 1 в область 2 и получаю картинку на экране.
Иногда нужно в область 1 вывести текст. Пока приходится придумывать всякие методы типа:
— создать битмэп. вывести на него текст . просканить и занести соотв. точки в область 1. удалить битмэп.
— создать Surface. затем GetDC, вывести текст , залочить , просканить, разлочить, удалить.
Все это выглядит довольно громоздко и на мой взгляд неправильный подход.
GT>Если так, то поступай следующим образом: GT>1)CreateCompatibleDC — создаем в памяти совместимый контекст
Возможно это решение, а я потом смогу получить указатель на память . т.е. чтобы остальные функции нормально работали ?. Т.е. эта функция выделяет опр. кусок памяти или как ?.
GT>2)CreateCompatibleBitmap — создаем совместимый битмэп GT>3)рисуем уже туда GT>4)BitBlt — когда необходимо копируем из памяти на реальный контекст
Главное чтобы память была выделена в оперативке и была непрерывной...и на нее можно было применять функции типа TextOut...т.к. самому реализовать кажется достаточно сложной задачей ( учитывая параметры фонта и пр.)
Здравствуйте, PavZ, Вы писали:
PZ>Главное чтобы память была выделена в оперативке и была непрерывной...и на нее можно было применять функции типа TextOut...т.к. самому реализовать кажется достаточно сложной задачей ( учитывая параметры фонта и пр.)
С этим контекстом можно работать так-же как с реальным (выделяется область в памяти и для неё создаётся контекст, совместимый с контекстом реального устройства)
а работает всё гораздо быстрее, т.к. не происходит физического вывода на экран
GT>С этим контекстом можно работать так-же как с реальным (выделяется область в памяти и для неё создаётся контекст, совместимый с контекстом реального устройства) GT>а работает всё гораздо быстрее, т.к. не происходит физического вывода на экран
Ок. А как получить указатель на выделеную память ? в доках не нашел про эту фичу ничего.
GT>>С этим контекстом можно работать так-же как с реальным (выделяется область в памяти и для неё создаётся контекст, совместимый с контекстом реального устройства) GT>>а работает всё гораздо быстрее, т.к. не происходит физического вывода на экран
PZ>Ок. А как получить указатель на выделеную память ? в доках не нашел про эту фичу ничего.
Копать тебе нужно в сторону CreateDIBSection:
CreateDIBSection
The CreateDIBSection function creates a DIB that applications can write to directly. The function gives you a pointer to the location of the bitmap bit values. You can supply a handle to a file-mapping object that the function will use to create the bitmap, or you can let the system allocate the memory for the bitmap.
HBITMAP CreateDIBSection(
HDC hdc, // handle to DC
CONST BITMAPINFO *pbmi, // bitmap data
UINT iUsage, // data type indicator
VOID **ppvBits, // bit values
HANDLE hSection, // handle to file mapping object
DWORD dwOffset // offset to bitmap bit values
);
После создания ты имеешь указатель на непрерывный участок памяти и плюс к этому,HBITMAP ,
с которым ты можешь работать посредством GDI.
Создаешь, выбираешь ее на предварительно созданном MemDC (CreateCompatibleDC)
и рисуешь.
Пошарься в интернете насчет готового класса CDib.Я сам такой сделал — работает и с DIBами и с JPEGами и
очено прост в использовании.
И что-то подобное есть на www.codeguru.com
Здравствуйте, B_A_D, Вы писали:
B_A>Копать тебе нужно в сторону CreateDIBSection:
B_A>[code]
B_A>CreateDIBSection
А можно что-нибудь сделать, если указатель на изображение уже имеется (имеется другая структура, преставляющая битмап)? Как получить HBITMAP так, чтобы он сам память не выделял (ну и соответсвенно не прибивал )?
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, swamp, Вы писали:
БП>Как получить HBITMAP так, чтобы он сам память не выделял (ну и соответсвенно не прибивал )?
БП>HBITMAP никак, HDC можно. Для этого нужно создать c этой памяти IDirectDraw7 поверхность, а у нее спросить HDC. БП>Павел.
Соответственно не будет работать там где нет DirectX 7 (если я не ошибаюсь он по умолчанию ставится на Windows 2000?)...
Здравствуйте, swamp, Вы писали:
S> Соответственно не будет работать там где нет DirectX 7 (если я не ошибаюсь он по умолчанию ставится на Windows 2000?)...
Ну тогда используйте IDirectDrawSurface4 или вообще IDirectDrawSurface. Это возможность появилась еще в самом первом директе
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, swamp, Вы писали:
S>> Соответственно не будет работать там где нет DirectX 7 (если я не ошибаюсь он по умолчанию ставится на Windows 2000?)... БП>Ну тогда используйте IDirectDrawSurface4 или вообще IDirectDrawSurface. Это возможность появилась еще в самом первом директе
А на каких виндах такие директы стоят гарантированно?
S>> А на каких виндах такие директы стоят гарантированно?
PZ>Помоему на всех старше 95-х... PZ>кстати прикол — 95-е называют игровой системой ... а директ икса на ней по умолчанию нет. PZ>а NT4.0 который ругают что он не для игр, так там DirectX3 по умолчанию и IDirectDraw там есть.
Клево! Т.е. будет работать на win9x начиная с win98 и winnt начиная с nt4?
Кстати, есть ли какие-нибудь преимущества у IDirectDraw7 перед просто IDirectDraw?
S>> Клево! Т.е. будет работать на win9x начиная с win98 и winnt начиная с nt4? PZ>Ну да ...
Это меняет дело...
S>> Кстати, есть ли какие-нибудь преимущества у IDirectDraw7 перед просто IDirectDraw?
PZ>Ну одно время когда делал скроллинг экрана получалось что на DirectDraw были дергунчики PZ>на DirectDraw7 получалось плавно. Но это все использовалось директ-иксовское...BltFast PZ>и прочая фигня.
Ну тогда если нет DirectDraw7 то работать через просто DirectDraw, тогда тормоза — проблемы того, кто ленится поставить себе DirectX7
PZ>Из возможностей DirectDraw помоему лучше использовать только
Мне собственно надо на кусок памяти сделать HDC чтобы туда что-нибудь нарисовать (например линию) через GDI и чтобы эти изменения применились на битмапе естетсвенно. Создавать HBITMAPы и копировать память туда-сюда не в кайф...
Кстати, можно где-нибудь глянуть сампл, демонстрирующий как это проделать? А то я с директом никогда дела не имел...
S> Мне собственно надо на кусок памяти сделать HDC чтобы туда что-нибудь нарисовать (например линию) через GDI и чтобы эти изменения применились на битмапе естетсвенно. Создавать HBITMAPы и копировать память туда-сюда не в кайф...
S> Кстати, можно где-нибудь глянуть сампл, демонстрирующий как это проделать? А то я с директом никогда дела не имел...
Немного непонятно...причем здесь директ, если это просто кусок памяти...
если это DirectDrawSurface ( собственно при использовании DirectX )
то делается так:
А как получить уже на выделеную память HDC я пока сам не понял.
Выше обсуждалось что нужно изначально об этом заботиться и выделять память другим способом.
пока не пробовал...
S>> Мне собственно надо на кусок памяти сделать HDC чтобы туда что-нибудь нарисовать (например линию) через GDI и чтобы эти изменения применились на битмапе естетсвенно. Создавать HBITMAPы и копировать память туда-сюда не в кайф...
S>> Кстати, можно где-нибудь глянуть сампл, демонстрирующий как это проделать? А то я с директом никогда дела не имел...
PZ>Немного непонятно...причем здесь директ, если это просто кусок памяти...
PZ>если это DirectDrawSurface ( собственно при использовании DirectX ) PZ>то делается так:
PZ> HDC hdc; PZ> MySurface->GetDC(hdc); PZ> MoveTo(hdc,0,0); PZ> LineTo(hdc,100,0); PZ> MySurface->ReleaseDC(hdc);
PZ>А как получить уже на выделеную память HDC я пока сам не понял. PZ>Выше обсуждалось что нужно изначально об этом заботиться и выделять память другим способом. PZ>пока не пробовал...
А как сделать MySurface из сырого битмапа (т.е. указателя на данные, ширины/высоты, глубины цвета и т.п.)?
Здравствуйте, PavZ, Вы писали:
S>> А как сделать MySurface из сырого битмапа (т.е. указателя на данные, ширины/высоты, глубины цвета и т.п.)?
PZ>В SDK есть модуль ddutil.h ( соотв. ddutil.pas ) в нем есть функция DDLoadBitmap(LPSTR *Filename, ...);
PZ>Т.е. указываешь имя файла и она сама создает поверхность для твоего битмэпа с учетом палитры, PZ>битности и пр.
Вообще-то мой битмап уже в памяти, так что конкретно такая функция не катит Но тем не менее за наводку спасибо, завтра поставлю DirectX SDK (я так понимаю ты имеешь ввиду именно его?) и буду смотреть...
Здравствуйте, swamp, Вы писали:
S>Здравствуйте, PavZ, Вы писали:
S>>> А как сделать MySurface из сырого битмапа (т.е. указателя на данные, ширины/высоты, глубины цвета и т.п.)?
PZ>>В SDK есть модуль ddutil.h ( соотв. ddutil.pas ) в нем есть функция DDLoadBitmap(LPSTR *Filename, ...);
PZ>>Т.е. указываешь имя файла и она сама создает поверхность для твоего битмэпа с учетом палитры, PZ>>битности и пр.
S> Вообще-то мой битмап уже в памяти, так что конкретно такая функция не катит Но тем не менее за наводку спасибо, завтра поставлю DirectX SDK (я так понимаю ты имеешь ввиду именно его?) и буду смотреть...
Там , если посмотреть реализацию то легко и из памяти загрузить.
Помоему даже при помощи доп. флажков решается.
Здравствуйте, PavZ, Вы писали:
PZ>Из возможностей DirectDraw помоему лучше использовать только
PZ>FDDSPrimary.Lock. PZ> Скопировать необх. данные ... PZ>FDDSPrimary.Unlock.
PZ>или
PZ>FDDSBack.Lock. PZ> Скопировать необх. данные ... PZ>FDDSBack.Unlock. PZ>Flip;
PZ>ну и установку видеорежима.
PZ>создавать доп. поверхности = доп. гемор... PZ>лучшая поверхность — выделить просто кусок оперативки...
Интереса для попробуй свой подход сравнить с подходом OFFSCREEN_SURFACE + BltFaast на видеокарточке типа GeForce...
если пробовать писать руками в видеопамять на GeForce — гарантированы тормоза... а если создать OFFSCREEN_SURFACE + SYSTEM_MEMORY... то тормоза пропадают...
так что твой солюшн — не лучший...
да и при подходе, который привожу я (про работу с поверхностями в системной памяти) тоже тормоза есть... я такой подход только при реализации Alpha Blend'а пользовал...
... << RSDN@Home 1.1 alpha 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[16]: а если память уже выделена?
От:
Аноним
Дата:
09.07.03 20:21
Оценка:
H_D>Интереса для попробуй свой подход сравнить с подходом OFFSCREEN_SURFACE + BltFaast на видеокарточке типа GeForce... H_D>если пробовать писать руками в видеопамять на GeForce — гарантированы тормоза... а если создать OFFSCREEN_SURFACE + SYSTEM_MEMORY... то тормоза пропадают...
Cорри, на GeForce завтра попробую у товарища. Сейчас потестил на своей карте TNT2.
======================================================
1000 Копирований на Primary Surface (640х480 16 bit)
======================================================
ВLTFAST — 30 сек.
Копирование руками (ASM) — 5 сек.
-----------------------------------------------------
Впринципе я где-то полгода назад проводил тест, написал тестовую программу по копированию
из разных типов памяти (SYS->VID) (VID->VID) (VID->SYS) (SYS->SYS) разными способами,
несколько алгоритмов на ASM а также при помощи функций BltFast.
тест прошел примерно на 20 компах (там 2 из них были с Geforce). Вывод получился один.->
-----------------------
Обновление экрана
-----------------------
Primary.Lock
Копируем нужные участки (ASM)
Primary Unlock
-----------------------
-----------------------
Игровой Цикл
-----------------------
копирование только SYS->SYS на ASM.
-----------------------
H_D>Интереса для попробуй свой подход сравнить с подходом OFFSCREEN_SURFACE + BltFaast на видеокарточке типа GeForce... H_D>если пробовать писать руками в видеопамять на GeForce — гарантированы тормоза... а если создать OFFSCREEN_SURFACE + SYSTEM_MEMORY... то тормоза пропадают...
Cорри, на GeForce завтра попробую у товарища. Сейчас потестил на своей карте TNT2.
======================================================
1000 Копирований на Primary Surface (640х480 16 bit)
======================================================
ВLTFAST — 30 сек.
Копирование руками (ASM) — 5 сек.
-----------------------------------------------------
Впринципе я где-то полгода назад проводил тест, написал тестовую программу по копированию
из разных типов памяти (SYS->VID) (VID->VID) (VID->SYS) (SYS->SYS) разными способами,
несколько алгоритмов на ASM а также при помощи функций BltFast.
тест прошел примерно на 20 компах (там 2 из них были с Geforce). Вывод получился один.->
-----------------------
Обновление экрана
-----------------------
Primary.Lock
Копируем нужные участки (ASM)
Primary Unlock
-----------------------
-----------------------
Игровой Цикл
-----------------------
копирование только SYS->SYS на ASM.
-----------------------
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, swamp, Вы писали:
S>> А как сделать MySurface из сырого битмапа (т.е. указателя на данные, ширины/высоты, глубины цвета и т.п.)?
БП>
БП>Этот пример создает 32-x битный IDirectDrawSurface с указанными БП>nHeight, nWidth, nPitch и pBits;
Спасибо, Павел, это то что нужно. Однако попытавшись сделать аналогичное, столкнулся с проблемой:
DDSURFACEDESC dd={0};
dd.dwSize = sizeof(DDSURFACEDESC2);
dd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT;
dd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
dd.dwHeight = m_curData->height; // m_curData - это структура, где все хранится...
dd.dwWidth = m_curData->width;
dd.lPitch = m_curData->stride; // если я правильно понял - pitch = stride?
dd.lpSurface = m_curData->data;
dd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
dd.ddpfPixelFormat.dwFlags= DDPF_RGB;
// X8R8G8B8 firmat
dd.ddpfPixelFormat.dwRGBBitCount = 32;
dd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
dd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
dd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
//CAggDirectDraw dirdraw(_T("test"),NULL);
CComPtr<IDirectDraw> piDraw;
CComPtr<IDirectDrawSurface> piSurf;
HRESULT hr = DirectDrawCreate(NULL, &piDraw,NULL);
if (FAILED(hr))
return hr;
hr = piDraw->SetCooperativeLevel(NULL, DDSCL_NORMAL);
if (FAILED(hr))
return hr;
hr = piDraw->CreateSurface(&dd, &piSurf, NULL);
if (FAILED(hr))
return hr;// возвращает E_INVALIDARG... :(
HDC tempDC=NULL;
hr = piSurf->GetDC(&tempDC);
if (FAILED(hr))
return hr;
item->DrawOnHdc(tempDC); // тут происходит рисование, впрочем это не важно...
hr = piSurf->ReleaseDC(tempDC);
if (FAILED(hr))
return hr;
Проблема в том, что CreateSurface возвращает E_INVALIDARG. Может структуру DDSURFACEDESC надо заполнять иначе чем DDSURFACEDESC2? Вроде мемберы все одни и те же...
S>>[ccode] S>> DDSURFACEDESC dd={0}; S>> dd.dwSize = sizeof(DDSURFACEDESC2);
PZ>Структура имеет тип DDSURFACEDESC а передаешь размер от второй версии структуры. PZ>Либо PZ> dd.dwSize = sizeof(DDSURFACEDESC); PZ>Либо PZ> DDSURFACEDESC2 dd={0};
PZ>Раз юзаешь DirectDrawSurface то нужно первый вариант писать. dd.dwSize = sizeof(DDSURFACEDESC);
И в самом деле Хотя после исправления, проблема осталась. Читал доку, нашел вот что про структуру DDSCAPS (точнее про флаг DDSCAPS_SYSTEMMEMORY который я юзаю):
DDSCAPS_SYSTEMMEMORY — This surface memory was allocated from system memory. If this capability bit is set by the Windows 2000 or later driver, DirectDraw is disabled.
Не означает ли это, что на 2000 и выше это дело работать и не должно? Или что значит "DirectDraw is disabled"?
S> И в самом деле Хотя после исправления, проблема осталась. Читал доку, нашел вот что про структуру DDSCAPS (точнее про флаг DDSCAPS_SYSTEMMEMORY который я юзаю):
Попробуй отказаться от lpSurface и lPitch ( отключи флажки )...если не поможет, то и pixelformat
прибей. Мне кажеться ему не нравяться твои собственные lpSurface и lPitch, он сам любит распоряжаться что и куда засовывать.
Особено учитывая что это интерфейс первой версии. Попробуй для DirectDrawSurface7 сделать,
может там прокатит.
S> DDSCAPS_SYSTEMMEMORY — This surface memory was allocated from system memory. If this capability bit is set by the Windows 2000 or later driver, DirectDraw is disabled. S> Не означает ли это, что на 2000 и выше это дело работать и не должно? Или что значит "DirectDraw is disabled"?
Возможно это означает что аппаратные возможности использоваться не будут. Хотя это только мой вариант перевода.
S>> И в самом деле Хотя после исправления, проблема осталась. Читал доку, нашел вот что про структуру DDSCAPS (точнее про флаг DDSCAPS_SYSTEMMEMORY который я юзаю):
Еще вопрос на засыпку — чему равно stride ... по идее должно быть width*4
Здравствуйте, PavZ, Вы писали:
PZ>Здравствуйте, PavZ, Вы писали:
S>>> И в самом деле Хотя после исправления, проблема осталась. Читал доку, нашел вот что про структуру DDSCAPS (точнее про флаг DDSCAPS_SYSTEMMEMORY который я юзаю):
PZ>Еще вопрос на засыпку — чему равно stride ... по идее должно быть width*4
В случае 32 бит на пиксель — да, а так там все сложнее...
Здравствуйте, swamp, Вы писали:
S> А можно что-нибудь сделать, если указатель на изображение уже имеется (имеется другая структура, преставляющая битмап)? Как получить HBITMAP так, чтобы он сам память не выделял (ну и соответсвенно не прибивал )?
Вообще-то, если почитать MSDN, обнаруживаются интересные вещи:
CreateBitmap
The CreateBitmap function creates a bitmap with the specified width, height, and color format (color planes and bits per pixel).
HBITMAP CreateBitmap(
int nWidth, // bitmap width, in pixels
int nHeight, // bitmap height, in pixels
UINT cPlanes, // number of color planes used by device
UINT cBitsPerPel, // number of bits required to identify a color
CONST VOID *lpvBits // pointer to array containing color data
);
lpvBits — Pointer to an array of color data used to set the colors in a rectangle of pixels. Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros). If this parameter is NULL, the new bitmap is undefined.
то есть если при создании битмапины ты подсунешь ей указатель на твое изображение,
то после создания она будет содержать нужную тебе картинку. И никакого гесороя с
DirecxX.
S>> И в самом деле Хотя после исправления, проблема осталась. Читал доку, нашел вот что про структуру DDSCAPS (точнее про флаг DDSCAPS_SYSTEMMEMORY который я юзаю):
PZ>Попробуй отказаться от lpSurface и lPitch ( отключи флажки )...если не поможет, то и pixelformat PZ>прибей. Мне кажеться ему не нравяться твои собственные lpSurface и lPitch, он сам любит распоряжаться что и куда засовывать. PZ>Особено учитывая что это интерфейс первой версии. Попробуй для DirectDrawSurface7 сделать, PZ>может там прокатит.
Ок, надо попробовать, хотя в таком случае пропадет вся прелесть — совместимость со старыми версиями виндов...
S>> DDSCAPS_SYSTEMMEMORY — This surface memory was allocated from system memory. If this capability bit is set by the Windows 2000 or later driver, DirectDraw is disabled. S>> Не означает ли это, что на 2000 и выше это дело работать и не должно? Или что значит "DirectDraw is disabled"? PZ>Возможно это означает что аппаратные возможности использоваться не будут. Хотя это только мой вариант перевода.
B_A>Вообще-то, если почитать MSDN, обнаруживаются интересные вещи: B_A>CreateBitmap B_A>то есть если при создании битмапины ты подсунешь ей указатель на твое изображение,
Вы упустили один очень важный момент: нужно избежать копирования, А CreateBitmap
именно копирует их. Картинка 1600x1200x32 бита копиреутся очень долго.
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, B_A_D, Вы писали:
B_A>>Вообще-то, если почитать MSDN, обнаруживаются интересные вещи: B_A>>CreateBitmap B_A>>то есть если при создании битмапины ты подсунешь ей указатель на твое изображение,
БП>Вы упустили один очень важный момент: нужно избежать копирования, А CreateBitmap БП>именно копирует их. Картинка 1600x1200x32 бита копиреутся очень долго.
БП>Павел.
Да, согласен. Ну если человек не хочет заморачиваться с DirectX,
почему бу ему действительно вместо выделения памяти так, как он делает
сейчас:
и работай на здоровье по-всякому. Есть указатель, который выделяется только 1 раз
и есть HBITMAP, с которым можно работать функциями GDI.
Все проще, чем с DirectX.
Здравствуйте, B_A_D, Вы писали:
B_A>Да, согласен. Ну если человек не хочет заморачиваться с DirectX,
Если речь идет обо мне, то я не против заморочиться с директом, если это решение будет совместимо со старыми версиями виндов и не выставлять требования к инсталляции дополнительных софтин (например, как я понимаю, если завязаться на DirectX7, то на 98й винде по умолчанию работать не будет)...
B_A>почему бу ему действительно вместо выделения памяти так, как он делает B_A>сейчас:
B_A>
B_A>и работай на здоровье по-всякому. Есть указатель, который выделяется только 1 раз B_A>и есть HBITMAP, с которым можно работать функциями GDI. B_A>Все проще, чем с DirectX.
Я бы и рад, но проблема в том, что для хранения растра используется структура, альтернативная DIB. Поэтому так не покатит... Все-таки не понятно, почему не сделали возможность создания HBITMAP на основе всего готового без копирований...
B_A>>и работай на здоровье по-всякому. Есть указатель, который выделяется только 1 раз B_A>>и есть HBITMAP, с которым можно работать функциями GDI. B_A>>Все проще, чем с DirectX.
S> Я бы и рад, но проблема в том, что для хранения растра используется структура, альтернативная DIB. Поэтому так не покатит... Все-таки не понятно, почему не сделали возможность создания HBITMAP на основе всего готового без копирований...
Мне кажется B_A_D предложил хороший метод. А как ты память выделяешь, m_curData->data;
этот указатель как получается ?
Если это GetMem,allocmem и прочее то почему бы не выделить при помощи CreateDIBSection ...получится тот же указатель + HDC.По крайней мере я так понял, пока не юзал.
H_D>Интереса для попробуй свой подход сравнить с подходом OFFSCREEN_SURFACE + BltFaast на видеокарточке типа GeForce... H_D>если пробовать писать руками в видеопамять на GeForce — гарантированы тормоза... а если создать OFFSCREEN_SURFACE + SYSTEM_MEMORY... то тормоза пропадают... H_D>так что твой солюшн — не лучший...
Вот попробовал на Geforce4 c PIV-2Ггц.
==================================================================================
1000 Копирований из области системной памяти в primary размер обоих 640х480х16 бит
----------------------------------------------------------------------------------
BltFast 2,7 cек
копирование руками (ASM) 1,1 сек.
===================================================================================
Да еще один момент, не всегда можно создать так называемую WIDESURFACE т.е. с шириной большей чем Primary, даже с флагом DDSCAPS_SYSTEMMEMORY все зависит от видяхи.
С allocmem таких проблем нет.
Здравствуйте, PavZ, Вы писали:
H_D>>Интереса для попробуй свой подход сравнить с подходом OFFSCREEN_SURFACE + BltFaast на видеокарточке типа GeForce... H_D>>если пробовать писать руками в видеопамять на GeForce — гарантированы тормоза... а если создать OFFSCREEN_SURFACE + SYSTEM_MEMORY... то тормоза пропадают... H_D>>так что твой солюшн — не лучший...
PZ>Вот попробовал на Geforce4 c PIV-2Ггц. PZ>================================================================================== PZ>1000 Копирований из области системной памяти в primary размер обоих 640х480х16 бит PZ>---------------------------------------------------------------------------------- PZ>BltFast 2,7 cек
PZ>копирование руками (ASM) 1,1 сек. PZ>===================================================================================
забавно... у меня что на GeForce2, что на GeForce4 тормозит не по детски.... а на S3 — нормально...
... << RSDN@Home 1.1 alpha 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
PZ>>копирование руками (ASM) 1,1 сек. PZ>>=================================================================================== H_D>забавно... у меня что на GeForce2, что на GeForce4 тормозит не по детски.... а на S3 — нормально...
Ну да S3 в этом плане быстрее, хотя достаточно глючная карта.
Если хочешь могу прогу тест прислать. (оставь мыло ). Попробуешь какие у тебя результаты получатся,чтобы можно было сравнивать, алгоритмы все-таки тоже влияют..
PZ>>>копирование руками (ASM) 1,1 сек. PZ>>>=================================================================================== H_D>>забавно... у меня что на GeForce2, что на GeForce4 тормозит не по детски.... а на S3 — нормально...
PZ>Ну да S3 в этом плане быстрее, хотя достаточно глючная карта. PZ>Если хочешь могу прогу тест прислать. (оставь мыло ). Попробуешь какие у тебя результаты получатся,чтобы можно было сравнивать, алгоритмы все-таки тоже влияют..
да не было там алгоритма...
surface->Lock();
_asm {
push eax
push ecx
push edi
pushf
mov edi, addr
mov ecx, cnt
mov eax, 0xffffffff
cli
rep stosd
popf
pop edi
pop ecx
pop eax
};
surace->UnLock();
... << RSDN@Home 1.1 alpha 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуйте, PavZ, Вы писали:
PZ>Особено учитывая что это интерфейс первой версии. Попробуй для DirectDrawSurface7 сделать, PZ>может там прокатит.
Как оказалось, прокатил DirectDraw4. Теперь осталось убедиться, что это действительно пашет на всех старых виндах... Всем большое спасибо!
P.S. Я попытался найти какие-нибудь источники, которые подтверждают, что все это хозяйство работает как минимум в 98, однако наткнулся на любопытное обсуждение: http://www.subduck.com/history/topic/832.html
Суть в том, что чуваку доказывают, что не надо юзать старые версии директ иксов, потому что это не будет работать на новых (Thats why you use DX7 SDK, which is compatible back to 98. DX3 is not compatible with newer versions of DX. So if you use DX3, it will work on 95/98 but not 2000/Me/XP. If you use DX7 your fine with 98SE/2000/Me/XP). Это так? Хотя с другой стороны, на моей XP все замечательно работает.
PZ>>Ну да S3 в этом плане быстрее, хотя достаточно глючная карта. PZ>>Если хочешь могу прогу тест прислать. (оставь мыло ). Попробуешь какие у тебя результаты получатся,чтобы можно было сравнивать, алгоритмы все-таки тоже влияют.. H_D>да не было там алгоритма... H_D>
H_D>surface->Lock();
H_D>_asm {
H_D> push eax
H_D> push ecx
H_D> push edi
H_D> pushf
H_D> mov edi, addr
H_D> mov ecx, cnt
H_D> mov eax, 0xffffffff
H_D> cli
H_D> rep stosd
H_D> popf
H_D> pop edi
H_D> pop ecx
H_D> pop eax
H_D>};
H_D>surace->UnLock();
H_D>
Я твой вариант тоже потестил ( назвал ASM Fill) ... он выполняется быстрее чем копирование.
Вот резултаты теста на 3-х компах
(1000 копирований из SYS в VID ...640x480 16 bit
===========================================================
Комп | BltFast | ASM Copy | Asm Fill
===========================================================
Piii-550
Riva TNT2 30cек. 5сек. 3сек.
Есть предположение, почему у тебя тормозит, возможно из-за того что
при заполнении некоторые точки вылезают за экран ( когда Addr>ScreenWidth но <Pitch )
т.к. на GF2 и GF4 заметил что Pitch > 1280 (640*2). И экран при помощи Asm Fill закрашивался не весь. У меня были подобные проблемы ( тормоза ) когда я вылазил за экран ( карта TNT2) , которые наблюдались не на всех компах с этой картой. Возможно зависит от версии детонатора.
Здравствуйте, PavZ, Вы писали:
PZ>Есть предположение, почему у тебя тормозит, возможно из-за того что PZ>при заполнении некоторые точки вылезают за экран ( когда Addr>ScreenWidth но <Pitch ) PZ>т.к. на GF2 и GF4 заметил что Pitch > 1280 (640*2). И экран при помощи Asm Fill закрашивался не весь. У меня были подобные проблемы ( тормоза ) когда я вылазил за экран ( карта TNT2) , которые наблюдались не на всех компах с этой картой. Возможно зависит от версии детонатора.
На самом деле, если бы ты почитал форум "Исходники" — ты бы нашел мою функцию Alpha Blend... там еще и чтения из видеопамяти есть...
так что ключ — наверное в этом...
кстати, у меня DirectDraw вполне сносно работает... а самому писать графику — я это еще под досом прошел надоело
... << RSDN@Home 1.1 alpha 1 >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Здравствуйте, Hacker_Delphi, Вы писали:
H_D>Здравствуйте, PavZ, Вы писали:
PZ>>Есть предположение, почему у тебя тормозит, возможно из-за того что PZ>>при заполнении некоторые точки вылезают за экран ( когда Addr>ScreenWidth но <Pitch ) PZ>>т.к. на GF2 и GF4 заметил что Pitch > 1280 (640*2). И экран при помощи Asm Fill закрашивался не весь. У меня были подобные проблемы ( тормоза ) когда я вылазил за экран ( карта TNT2) , которые наблюдались не на всех компах с этой картой. Возможно зависит от версии детонатора.
H_D>На самом деле, если бы ты почитал форум "Исходники" — ты бы нашел мою функцию Alpha Blend... там еще и чтения из видеопамяти есть...
Ну про это речи не шло, я так понял что у тебя stosd заполняет медленнее чем BltFast.
H_D>так что ключ — наверное в этом...
Если из видяхи читать , то конечно
H_D>кстати, у меня DirectDraw вполне сносно работает... а самому писать графику — я это еще под досом прошел надоело
А чего ее писать . BltFast это разве графика ...она даже alpha blend делать не умеет. Копирование прямоугольника.
Вот так вот, вредно мощные компы делать, так все на GDI перейдут .
Я не против простоты написания, но к сожалению КПД компьютеров от этого падает. Грубо говоря то что должно работать
на P100 еле тащиться на P-IV . Получается что быстрые процы делают не для того чтобы мы больше могли сделать за то же время, а для того чтобы вместо movsd писать for x:=0 to Width do for y:=0 to Height do Mem1^:=Mem2^;