[DirectDraw] - Kluczowanie koloru

0

Witam, piszę ten temat, bo już dosłownie nie mam pojęcia, jak uporać się z tym problemem.

Mam funkcje wyświetlającą bitmapy:

DWORD B32(BYTE r,BYTE g,BYTE b) 
{
      return 0xFF000000 | (r<<16) | (g<<8)|b;
};

int Display(int x,int y,int w,int h,TCHAR Src[])
{
    Bg = LoadImage(NULL, Src, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    
    DDCOLORKEY ddck;
    ddck.dwColorSpaceLowValue = ddck.dwColorSpaceHighValue = B32(255,0,255);
       
    Buffor->SetColorKey(DDCKEY_SRCBLT,&ddck);
    
    tempHDC = CreateCompatibleDC(0);
    SelectObject(tempHDC,Bg);
    Buffor->GetDC(&mHDC);
   
    BitBlt(mHDC,x,y,w,h,tempHDC,0,0,SRCCOPY);

    Buffor->ReleaseDC(mHDC);
    DeleteDC(tempHDC);
    DeleteObject(Bg);
} ;

Wywołuję ją na przykład tak:

Display(0,750,1024,100,"data/belka.bmp");

Wykonuję to w Timerze w WinApi, pod koniec Timera tylko Flipuję:

Surface->Flip(NULL, DDFLIP_WAIT);  

I kluczowanie nie działa :(. Bardzo proszę o pomoc. Kodzę w Dev-C++ z użyciem DirectDraw, wszystko podlinkowane, wszystko się ładnie wyświetla - tylko tła obrazków pozostają.

0

Dla uproszczenia przyjmij jako CK kolor 0x0.
Format piksela moze byc rozny i program moze reagowac inaczej niz chcesz ;)
Nie pamietam juz za wiele, ale robilem to kiedys tak:
Screen->GetSurface()->BltFast(PosX, PosY, Bitmap->GetSurface(), &rect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

0

To co robisz, nie ma raczej większego sensu - ustawiasz colorkey na powierzchni DirectDraw,a kopiuszesz korzystająć z BitBlt GDI na docelowy uchwyt kontekstu pobranego z powierzchni - a to tak nie działa. GDI to GDI, DDraw to DDraw.
Ale zakładając, że do czegoś jest Ci to potrzebne(zapewne do łatwiejszego wczytania bitmapy), to musisz wiedzieć, że BitBlit nie oferuje obslugi colorkey. Do tego musisz wykorzystać funkcję TransparentBlt, znajduje się ona w msimg32.dll. A przy okazji warto wiedzieć, że funkcja ta wg MS nie powinna być wykorzystywana w Windowsach 9x.

Pozdrawiam.

0

Dzięki za pomoc, jeszcze jedna sprawa. Zdobyłem i zaincludowałem plik msimg32.lib, ale wciąż dostaję błąd:

72 D:\dRaiser-C++\RPGEngine\backup\main.cpp `TransparentBlt' undeclared (first use this function)

Jeśli komuś wygodniej, to poproszę o odpowiedź na [email protected] .

0

Mój aktualny kod wygląda inaczej, i teoretycznie jest poprawny i wyświetlać wszystko powinien - tylko nie kluczuje się poprawnie;/.

int Display(int x,int y,int w,int h,LPCSTR Src)
{
    HBITMAP hbmBitmapa, hbmOld;
    BITMAP bmp;
    HDC mHDC,tempHDC;
   
    int o=l;
    l++;
    hbmBitmapa = (HBITMAP)LoadImage(NULL, Src, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    GetObject(hbmBitmapa, sizeof(bmp),&bmp);
   
    tempHDC = CreateCompatibleDC(NULL);
    hbmOld = (HBITMAP)SelectObject(tempHDC,hbmBitmapa);
   
    DDSURFACEDESC ddsd;
    ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
    ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
    ddsd.dwWidth = bmp.bmWidth;
    ddsd.dwHeight = bmp.bmHeight;
    DD->CreateSurface(&ddsd,&Op[o],NULL);
       
    Op[o]->GetDC(&mHDC);
   
    BitBlt(mHDC,x,y,w,h,tempHDC,0,0,SRCCOPY);

    Op[o]->ReleaseDC(mHDC);
   
    DDCOLORKEY ddck;
    ddck.dwColorSpaceLowValue = ddck.dwColorSpaceHighValue = 0;

    Op[o]->SetColorKey(DDCKEY_SRCBLT,&ddck); 
    SetRect(&Obj[o],x,y,w,h);
   
    DeleteDC(tempHDC);
    DeleteObject(Bg);
    DeleteObject(hbmBitmapa);
} ;

//Potem w Timerze:

DDBLTFX fx;
fx.dwSize=sizeof(fx);
fx.dwFillColor= 0; //zamiast 0 kolor, którym czyścisz
Buffor->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&fx);

Display(0,0,1024,768,"katakumby.bmp");
Display(10,10,160,160,"Ufok.bmp");

for (int i=1; i<3; i++)
Buffor->Blt(&Obj[i],Op[i],NULL,DDBLT_KEYSRC | DDBLT_WAIT, NULL);
Surface->Flip(NULL, DDFLIP_WAIT); 

Bardzo prosze o pomoc w rozwiazaniu problemu...

0

domyślam się, że nie używasz kompilatora VC++ ani microsoftowych headerów.

TransparentBlt ma swoją definicję w pliku Wingdi.h , ponieważ msimg32.dll jest jedynie pośrednikiem w wywołaniu funkcji _TransparentBlt z gdi32.dll.

Najprawdopodobniej Twoj plik nagłówkowy WinGDI.h nie posiada deklaracji dla tej funkcji.
Wygląda ona w ten spsob:

WINGDIAPI BOOL WINAPI TransparentBlt(__in HDC hdcDest,__in int xoriginDest, __in int yoriginDest, __in int wDest, __in int hDest, __in HDC hdcSrc, __in int xoriginSrc, __in int yoriginSrc, __in int wSrc, __in int hSrc, __in UINT crTransparent);

UINT crTransparet - to COLORREF

0
dRaiser napisał(a)

Mój aktualny kod wygląda inaczej, i teoretycznie jest poprawny i wyświetlać wszystko powinien - tylko nie kluczuje się poprawnie;/.

Bardzo prosze o pomoc w rozwiazaniu problemu...

w wypadku SetColorKey metodę wywołać powinieneś na powierzchni docelowej, a nie źródłowej.

0

Dzięki, już poradziłem sobie, i to nawet z Blt():)!

1 użytkowników online, w tym zalogowanych: 0, gości: 1