LECKÉK:              

Saját ablak

Directdraw1

Directdraw 2

Directdraw_3

Üdvözöllek!

Az első lecke a saját képernyő volt. Most megpróbálunk a windows-tól kikunyerálni egy teljes képernyős ablakot.

Ehhez létrhozunk egy új fájl-t, egy új osztállyal. A lényeg a játékokban,hogy a bábuk mindig

mozognak a képernyőn,és ehhez mindig újra kell rajzolni őket.Ebből következik,hogy miközben a vidikártya bőszen rajzolja a monitorra a képet,közben a mi progink meg a saját bábuját a vidikártyára, hát ebből lesz a kép villodzása,feldarabolódása....

Ennek lekerülésére kell egy directx felületet létrehozni, és mindjárt két képernyőnek kell helyet foglalni. az első amit látunk, és egy hátsó amire rajzolunk... ha minden rajzolással készen vagyunk,akkor egy váltás, és máris rajzolhatunk a másik képernyőre. ezzel ki van lőve a képernyő villogása, feldarabolódása.A projecthez adjál egy új fáljt, méghozzá a Header mappába. a neve legyenRajz.hpp . A hpp kiterjesztés előnye hogy nem kell külön .h és .cpp fájl.

( DEVC++ nál:                                              msvc6.0

                                                          

Az új fájl-ban hozzuk létre az osztályunkat....

//RAJZ OSZTÁLY
//
#ifndef _RAJZ_ //ujabb definíció és fordítási hiba elkerülésére
#define _RAJZ_

#include <ddraw.h>

//dekralációk:
class RAJZ //osztály neve
{
public: //public szó alatti függvények- változók kívülről láthatóak
RAJZ(); //konstruktor dekralálása
~RAJZ(); //destruktor
protected: //protected alattiakat csak az osztály láthatja és még az utód osztályok
LPDIRECTDRAW7 obj; //objektum mutató
LPDIRECTDRAWSURFACE7 front; //elsőképernyőre mutató pointer
LPDIRECTDRAWSURFACE7 back; //hátsóképernyőre mutató pointer
LPDIRECTDRAWCLIPPER cl; //klipper objektum

};

#endif

Nos akinek idegen egy osztály, annak idegen a konstruktor és destruktor fogalma is. A lényege: ha az osztályt statikusan hozzuk létre,akkor az exe betöltődésekor, ha dinamikusan,akkor a memória foglalásakor meghívódik a konstruktor..... felfogható az osztály inicializáló függvényének,azaz meghívhat más függvényeket,lefoglalhat újabb dinamikus változókat, mindent,amit csak akarunk, vagy éppen semmit sem. A destruktor akkor aktivizálódik,amikor megszűnik az osztályunk, de ott nekünk kell gondoskodni a dinamikus helyfoglalás felszabadításáról....

 A dekralációban tulajdonképpen helyet foglalunk a directdraw7 típusú mutatóknak,Amelyek sorra megkapják az értéküket a különböző függvény hívások után:Kell egy directdraw objektum,amin keresztül létrehozhatjuk az első és hátsó képernyő felületeket,valamint egy klipper objektumot, ez utóbbi arra kell, hogyha egy képet szeretnénk átrajzolni a háttérre, akkor ha csak egy pixellel is kilóg, akkor már nem rajzolja ki a Blt(...) függvény. A vágóobjektum nélkül.

Nos a directx felülethez kell az ablakunk hwnd típusú változója,de ez ugye egy másik fájl-ban a main.cpp -ben van. Ha már egyszer dekraláltuk, akkor itt is egyszerűen használhatjuk,csak

mondjuk meg a fordítónak,hogy ez egy külső változó (majd megkeresi a helyét) tehát valahova a

#define _RAJZ_  alá kell beírni:

extern HWND hwnd;

 

Csapjunk bele!

hozzunk létre egy init() függvényt a rajz osztályban:

dekralációkhoz: bool init();

Az  #endif  utasítás előtt építjük ki a megvalósítását a függvényeinknek:

//MEGVALÓSÍTÁSOK:

Elsőnek a konstruktor, destruktor,majd az init függvény:

//Megvalósítások:
RAJZ::RAJZ() //A konstruktor neve maga az osztálynév nem adhat vissza értéket,
{ //tehát tipusa sem lehet itt csak egy üres konstruktor van egyenlőre
}
//
RAJZ::~RAJZ() //destruktor egyenlőre ez is üres.
{
}
//
bool RAJZ::init()    // a RAJZ:: -tal jelöljük hogy az osztály függvénye és nem globális
{
HRESULT hr; //egy visszajelzés,hogy sikerült-e a függvényt végrehajtani
hr = DirectDrawCreateEx( NULL, (VOID**)&obj,IID_IDirectDraw7, NULL );//átadjuk a mutatót
//a directdraw objektum létrehozásához
if(hr!=DD_OK) return false;
hr = obj->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );//együttműködési szint
//teljes képernyő kell
if(hr!=DD_OK) return false;
hr=obj->SetDisplayMode( 800, 600, 32,75,0);//képernyő felbontás,színmélység,frekvencia.
if(hr!=DD_OK) return false;
DDSURFACEDESC2 ddsd;//struktúra helyfoglalaása
ZeroMemory( &ddsd, sizeof( ddsd ) );//adatok kitöltése
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |DDSCAPS_COMPLEX ;
ddsd.dwBackBufferCount = 1;//1 db háttérfelület kell
hr = obj->CreateSurface( &ddsd, &front,NULL );//létrehozzuk a felületet
if(hr!=DD_OK) return false;
DDSCAPS2 ddscaps;
ZeroMemory( &ddscaps, sizeof( ddscaps ) );
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = front->GetAttachedSurface( &ddscaps,&back );//lekérdezzük a hátsóképernyő címét
if(hr!=DD_OK) return false;
hr = obj->CreateClipper( 0, &cl, NULL );//klipper objektum létrehozása
cl->SetHWnd( 0, hwnd );
hr = back->SetClipper(cl);//és hozzárendelése a háttérhez.
UpdateWindow(hwnd); //ablakfrissítés

return true;//ha eddig elér a progi,akkor van dx felületünk.

}

Nos azért írtam hogy ha eddig elér a progi mert ezzel a függvénnyel szokott probléma lenni:SetDisplayMode( 800, 600, 32,75,0)Vagy a videokártya vagy a monitor nem bírja,akkor állítgatni kell.felbontás pl  640x 480 színmélység 16 , 8  frekvencia 50 60 75 100 Hertz vagy NULL ekkor a monitor alapfrekvenciája lesz a mérvadó.

Menjél a Main.cpp-be, és add hozzá a Rajz.hpp-t a fájl-hoz:

#include <Rajz.hpp>

fordítás....

Hibaüzenet elhárítása:

DEVC++                                                                                                msvc

Marad a ddraw.h és a ddraw.lib hozzáadása:

DEVC++:                                                                                MSVC:

Ha sikerültek a beállítások,akkor a main cpp-ben

hozzuk létre az új  statikus osztályt:

RAJZ rajz;

Használni pedig az egyes tagfüggvényeket a . operátorral lehet:

Irjad be a ShowWindow(hwnd,nFunsterStil); után hogy:

if(rajz.init())MessageBox(NULL,"directdraw nem oké","",0);;

fordít futtat.

Ha lett egy teljesképernyős szürke képed,akkor minden oké.

Azonban nem frissül,de ezt a következőben...

itt a kod:

Ha nem lenne meg a ddraw.h és ddraw.lib itt letölthetitek.

Vissza