Pisanie programów na zamówienie

Pisanie na zamówienie Pisanie programów na zamówienie, stron www itp. Kilka programów do sciągnięcia Artykuły na tematy programowania Strona główna

Wprowadzenie do DirectDraw


Pisanie programów pod DirectDraw należy zacząć od przygotowania wszystkich obiektów, zmiennych itp.(plik nagłówkowy od DirectDraw to ddraw.h, trzeba też dodać ddraw.lib).

Na początku deklarujemy obiekt główny DirectDraw wygląda to następująco:
LPDIRECTDRAW dd;

Aby zainicjować obiekt należy wywołać funkcję DirectDrawCreate.
DirectDrawCreate(NULL,dd,NULL);

Jej pierwszym argumentem jest identyfikator karty graficznej NULL oznacza aktualną kartę, drugi argument to zadeklarowany obiekt DirectDraw, pod który zostanie zapisany wskaźnik do interfejsu DirectDraw. Jeżeli wszystko będzie ok. to funkcja zwróci DD_OK.(do zmiennej typu HRESULT).

Przykład:
LPDIRECTDRAW dd;
HRESULT hr=DirectDrawCreate(NULL,dd,NULL);
if(hr!=DD_OK.)
{
//Błąd
}

Następnym krokiem jest ustalenie trybu współpracy. Wykonuje się to przy pomocy funkcji SetCooperativeLevel na rzecz obiektu głównego DirectDraw. Czyli:
dd->SetCooperativeLevel(hwnd,dwf);

Pierwszym argumentem jest uchwyt do okna aplikacji(typ HWND). Drugim jest flaga która może przyjmować różne wartości np.
DDSCL_ALLOWMODEX - tylko z DDSCL_EXCLUSIVE i DDSCL_FULLSCREEN.
DDSCL_ALLOWREBOOT - można używać CTRL+ALT+DEL.
DDSCL_EXCLUSIVE - tylko z DDSCL_FULLSCREEN.
DDSCL_FULLSCREEN - aplikacja pracuje w trybie pełnoekranowym.
DDSCL_NORMAL - typowa aplikacja Windows 95.
DDSCL_NOWINDOWCHANGES - aplikacji nie można minimalizować.

Przykład:
LPDIRECTDRAW dd;
if(DirectDrawCreate(NULL,dd,NULL)!=DD_OK.)
{
//błąd;
}
if(dd->SetCooperativeLevel(mojeokno, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK.)
{
//błąd
}

Aby zainicjować tryb graficzny należy wywołać funkcję SetDisplayMode na rzecz obiektu głównego.
dd->SetDisplayMode(640,480,16);

Pierwszym argumentem jest szerokość ekranu, drugim wysokość, a trzecim ilość kolorów w bitach.

Przykład kolejny:
LPDIRECTDRAW dd;
if(DirectDrawCreate(NULL,dd,NULL)!=DD_OK.)
{
//błąd;
}
if(dd->SetCooperativeLevel(mojeokno, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK.)
{
//błąd
}
if(dd->SetDisplayMode(640,480,16)!=DD_OK.)
{
//błąd
}

Teraz trzeba stworzyć (stronę) bufor w na którym będą wykonywane operację graficzne. Najpierw należy zadeklarować obiekt struktury LPDIRECTDRAWSURFAC reprezentującą ten bufor i wygląda to tak:
LPDIRECTDRAWSURFACE buf1;

Po deklaracji obiektu trzeba zadeklarować obiekt struktury DDSURFACEDESC czyli:
DDSURFACEDESC ds;

Następnie wypełniamy pola struktury ds. Ważniejsze pola to:
ds.dwSize - Rozmiar struktury
ds.dwFlags - Flaga wskazuje które pole jest ważne, może przyjmować np.
- DDSD_BACKBUFFERCOUNT
- DDSD_CAPS
- DDSD_HEIGHT|DDSD_WIDTH .
ds.dwHeight
- wysokość strony
ds.dwWidth - szerokość strony
ds.dwBackBufferCount - ilość niewidocznych stron
ds.ddsCaps - struktura DDSCAPS.

W strukturze DDSCAPS ważne jest pole dwCaps określające właściwości bufora. Ważniejsze wartości:
DDSCAPS_3DDEVICE - bufor może być użyty do renderingu 3D.
DDSCAPS_BACKBUFFER - bufor jest niewidoczny, tylna strona.
DDSCAPS_FLIP - bufor jest przełączany z innym na zmiane.
DDSCAPS_OFFSCREENPLAIN - bufor niewidoczny.
DDSCAPS_PRIMARYSURFACE - bufor reprezentuje ekran
DDSCAPS_SYSTEMMEMORY - bufor tworzony w pamięci
DDSCAPS_TEXTURE - bufor przeznaczony do przechowywania tekstury.
DDSCAPS_VIDEOMEMORY - bufor jest tworzony z użyciem pamięci karty graficznej
DDSCAPS_WRITEONLY -tylko do odczytu.

Przykład:
LPDIRECTDRAW dd;
if(DirectDrawCreate(NULL,dd,NULL)!=DD_OK.)
{
//błąd;
}
if(dd->SetCooperativeLevel(mojeokno, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK.)
{
//błąd
}

if(dd->SetDisplayMode(640,480,16)!=DD_OK.)
{
//błąd
}
LPDIRECTDRAWSURFACE buf1;
DDSURFACEDESC ds;
ZeroMemory(&ds, sizeof(ds));
ds.dwSize = sizeof(ds);
ds.dwFlags = DDSD_CAPS;
ds.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

Strona zostaje utworzona po wywołaniu funkcji CreateSurface na rzecz obiektu głównego.
dd->CreateSurface(&ds,&buf1,NULL);
Pierwszym argumentem jest obiekt struktury DDSURFACEDESC. Jako drugi podaje się obiekt struktury LPDIRECTDRAWSURFACE czyli obiekt bufora. Trzecim argumentem jest NULL.

Przykład:
LPDIRECTDRAW dd;
if(DirectDrawCreate(NULL,dd,NULL)!=DD_OK.)
{
//błąd;
}
if(dd->SetCooperativeLevel(mojeokno, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK.)
{
//błąd
}
if(dd->SetDisplayMode(640,480,16)!=DD_OK.)
{
//błąd
}
LPDIRECTDRAWSURFACE buf1,buf2;
DDSURFACEDESC ds;
ZeroMemory(&ds, sizeof(ds));
ds.dwSize = sizeof(ds);
ds.dwFlags = DDSD_CAPS;
ds.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if(dd->CreateSurface(&ds,&buf1,NULL)!=DD_OK)
{
//błąd
}
ZeroMemory(&ds, sizeof(ds));
ds.dwSize = sizeof(ds);
ds.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ds.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ds.dwWidth = 100;
ds.dwHeight = 100;
if(dd->CreateSurface(&ds,&buf2,NULL)!=DD_OK)
{
//błąd
}

Stworzone zostały tutaj 2 strony jedna reprezentująca ekran, a druga niewidoczna o rozmiarze 100x100.

W przypadku kiedy tworzy się 2 strony i jedna jest widoczna, a druga nie i maja one być przełączane, to przydatna może być funkcja AddAttachedSurface która tworzy kolejkę buforów.

Przykład:
buf1->AddAttachedSurface(buf2);
Funkcja jest wywoływana na rzecz bufora 1, a argumentem jest bufor 2.

Po przygotowaniu już wszystkiego można zacząć np. rysować. Aby uzyskać wskaźnik na wykreślacz należy wywołać funkcję GetDC na rzecz obiektu strony. Czyli:
HDC hdc;
buf1->GetDC(&hdc);

Do rysowania można używać funkcji:
Ellipse(HDC hdc, int xl, int yl, int xp, int yp); - rysuje elipse
hdc - wskaźnik do wyreślacza
xl - współrzędna x lewego górnego rogu
yl - współrzędna y lewego górnego rogu
xp - współrzędna x prawego górnego rogu
yp - współrzędna y prawego górnego rogu

Rectangle(HDC hdc, int xl, int yl, int xp, int yp); - rysuje prostokąt
hdc - wskaźnik do wyreślacza
xl - współrzędna x lewego górnego rogu
yl - współrzędna y lewego górnego rogu
xp - współrzędna x prawego górnego rogu
yp - współrzędna y prawego górnego rogu

SetPixel(HDC hdc, int xl, int yl, COLORREF col); -rysuje pixel
hdc - wskaźnik do wyreślacza
xl - współrzędna x
yl - współrzędna y
col - kolor pixela np. RGB(0,0,0)

LineTo(HDC hdc, int x, int y); - rysuje linie od punktu ustawienia wyreślacza
hdc - wskaźnik do wyreślacza
x - współrzędna x
y - współrzędna y

TextOut(HDC hdc, int x, int y,char *buf, int rozm); - tekst
hdc - wskaźnik do wyreślacza
x - współrzędna x
y - współrzędna y
buf - tablica w której znajduje się tekst
rozm - rozmiar tablicy z tekstem

Zmiana koloru pędzla odbywa się przy użyciu funkcji CreateSolidBrush - funkcja zwraca wskaźnik na pędzel.
Np.
CreateSolidBrush(COLORREF col);
col - kolor w RGB

Przykład:
HBRUSH br=CreateSolidBrush(RGB(10,10,10));

Aby utworzyć własne pióro należy wywołać funkcję CreatePen - zwracany jest wskaźnik do utworzonego.
Np.
CreatePen(int styl, int szer, COLORREF col);
styl - styl linii. Główne to:
- PS_SOLID normalna linia
- PS_DOT kropkowana linia
szer - szerokość lini
col - kolor w RGB

Przykład:
HPEN pen=CreatePen(PS_SOLID,2,RGB(255,255,255));
SelectObject(hdc,pen);

Ładowanie do wykreślacza np. koloru pędzla lub koloru pióra odbywa się przy użyciu funkcji SelectObject.
SelectObject(HDC hdc,HGDIOBJ hg);
hdc - wskaźnik na wyreślacz
hg - object ładowany np. pióro, pędzel, bitmapa itp.

Przykład:
buf1->GetDC(&hdc); HBRUSH bru=CreateSolidBrush(RGB(0,0,0));
SelectObject(hdc,bru);
Rectangle(hdc,0,0,10,10);

Tworzony jest tutaj wskaźnik do wykreślacza, ładowany do niego pędzel koloru czarnego i rysowany prostokąt.

Ważna jest funkcja ReleaseDC, zwalnia ona wykreślacz.
ReleaseDC(HDC hdc);

Przykład:
buf1->Release(hdc);
Po wykonaniu operacji graficznych należy wywołać tą funkcję.

Temat ten jest taki rozległy że można by napisać parę książek na jego temat. Myślę, że na początek to wystarczy. Powodzenia.

Autorem tekstu jest: Tomasz Urbaniak

Strona główna | Artykuły na temat programowania | Programy do ściągnięcia | Pisanie programów na zamówienie
Eurohaft - haft komputerowy