Gå til innhold

SlickDx - gøy med Direct3D 11.1


Anbefalte innlegg

Forord

Jeg har alltid vært glad i spill. Å spille dem har selvfølgelig vært gøy, men jeg har også hatt en fascinasjon for teknologien som ligger bak og som får tannhjulene til å gå rundt. Dette var noe av grunnen til at jeg for noen år siden begynte på en utdannelse som spillprogrammerer. I ettertid har jeg byttet retning til web- og enterpriseprogrammering, men jeg har fremdeles beholdt interessen for spillutvikling. Derfor har jeg sittet litt på fritiden og puslet med diverse måter å tegne pene ting på skjermen, og føler etter utallige iterasjoner at jeg endelig kan nok til å få implementert ideene mine.

 

SlickDx

Jeg har ikke klart å bli 100% enig med meg selv om hva SlickDx egentlig skal symbolisere, men foreløpig kaller jeg det en forkortelse for Slick DirectX. Målet med prosjektet er å lage en robust DirectX-basert kjerne med grafikk, input, lyd og andre systemer man trenger i en spillmotor. Med dette fundamentet håper jeg å få på plass en god base jeg kan bruke til rask prototyping av alle slags spill og (primært) 3D-applikasjoner. Det er også ment som et generelt læringsprosjekt for å bli stødigere i C++ og ikke minst Direct3D API'en.

 

Teknologi

SlickDx benytter seg av Direct3D 11.1 og DXGI 1.2 API'ene, og vil derfor kun fungere på Windows 7 SP1 og Windows 8. DirectInput 8 blir brukt til å ta imot input, og lyd har jeg ennå ikke bestemt meg for, men jeg ser for meg å bruke FMOD til det. All intern kode skrives i C++, og data som må leses inn lagres i XML. Assets lagres i og hentes ut av en eller flere ZIP-arkiv. zlib benyttes til å lese inn disse filene.

 

Hvorfor Direct3D?

Jeg liker Microsoft-teknologi, og all utviklingen jeg driver med foregår i et Windows-miljø. Integrasjonen med DXGI og den mer objektorienterte API'en i forhold til OpenGL sin C gjorde derfor Direct3D til det eneste aktuelle valget for dette. Direct3D 11 API'et er en ny iterasjon av Direct3D 10 API'et, som var en helt ny struktur i forhold til Direct3D 9 og tidligere. Da jeg ser på SlickDx som et læringsprosjekt, ønsker jeg å lære meg teknologi som blir aktuell i fremtiden også, og da er Direct3D 11.1 det ferskeste så langt. Et API orientert mer mot C++ er også som sagt å foretrekke fremfor C, da jeg også ønsker å bli stødigere med C++ generelt.

 

Hva er gjort?

Grunnoppsettet er på plass, med oppstart av applikasjonen, applikasjonsvinduet og initialisering av Direct3D 11.1 og støttesystemer. Diverse interfaces for forskjellige undersystemer har blitt lagt inn. Jeg vil forklare den sentrale arkitekturen nærmere senere, men slik det er nå ligger motoren sentralt, og et applikasjonslag ligger på toppen for ting som konfigurasjon, assets og lignende applikasjonsspesifikke ressurser. Et IScene-interface representerer en game state, og å bruke motoren er foreløpig så enkelt som å implentere dette interfacet og kalle det som startparameter i motorens main-metode. Et eksempel på oppstart av testspillet mitt som bruker motoren:

 

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
 sdx::Core core;
 core.LoadConfigFromFile( "config.xml" );
 return core.Main( new SandboxScene( &core ) );
}

 

Hva skal gjøres i nærmeste fremtid?

Foreløpig er det ingen form for logging, noe som hadde vært ekstremt nyttig for debugging. Dette skal implementeres først. Deretter skal engine loop'en utbedres. Et asset-system som kan laste inn teksturer, shaders og så videre fra ZIP-filene må også på plass før jeg kommer noe videre.

 

Når en litt mer innholdsrik kodebase er på plass, kommer jeg til å legge ut koden åpent på github og lenke den her. Jeg har også lyst til å beskrive arkitekturvalgene og hvordan de forskjellige klassene i motoren henger sammen.

 

Denne posten kommer nok til å bli redigert, men jeg gleder meg i hvertfall til å jobbe videre med SlickDx, og håper at denne loggen kan komme noen til nytte, enten som inspirasjon eller annet. Hvis det er ønske om en kommentartråd etter hvert, send meg en PM :)

Endret av Wedvich
Lenke til kommentar
Videoannonse
Annonse

Assetsystemet er på god vei, men ikke helt ferdig ennå. Et 3D-kamera og inputsystem er på plass, og også tekst ved bruk av DirectWrite. Dette sparer meg for alt det vanlige stresset med å opprette et spritesheet, parse koordinater for hvert enkelt tegn, opprette vertexes, mappe til spritesheetet osv. I tillegg slipper jeg å opprette et separat spritesheet for forskjellige tekststørrelser, uthevet skrift osv... det bare fungerer.

 

Selv om DirectWrite brukes gjennom Direct2D, er det veldig lett å integrere med Direct3D ettersom begge er bygget oppå DXGI. Man kan derfor bruke de felles ressursene gjennom DXGI.

 

Direct3D 11 device'en må opprettes med D3D11_CREATE_DEVICE_BGRA_SUPPORT inkludert i device flags, og swap chainen må bruke formatet DXGI_FORMAT_B8G8R8A8_UNORM. Så kan jeg opprette et Direct2D render target på følgende måte (feilhåndtering og releasing er strippet vekk her):

 

// Hent ut backbufferen fra swap chain opprettet tidligere
IDXGISurface2* pDxgiSurface;
m_pSwapChain->GetBuffer( 0, __uuidof( IDXGISurface2 ), reinterpret_cast< void** >( &pDxgiSurface ) );

// Opprett Direct2D factory
ID2DFactory1* pD2dFactory;
D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof( ID2D1Factory1 ), reinterpret_cast< void** >( &pD2dFactory ) );

// Sett nødvendig informasjon for å opprette Direct2D render target
float dpiX, dpiY;
pD2dFactory->GetDesktopDpi( &dpiX, &dpiY );
D2D1_RENDER_TARGET_PROPERTIES d2dProps;
d2dProps.dpiX =   dpiX;
d2dProps.dpiY =   dpiY;
d2dProps.minLevel =  D2D1_FEATURE_LEVEL_DEFAULT;
d2dProps.pixelFormat = D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED );
d2dProps.type =   D2D1_RENDER_TARGET_TYPE_DEFAULT;
d2dProps.usage =  D2D1_RENDER_TARGET_USAGE_NONE;

// Opprett render target - m_pD2dRenderTarget er en peker til ID2D1RenderTarget
pD2dFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &d2dProps, &m_pD2dRenderTarget );

 

Og slik kan jeg bruke m_pD2dRenderTarget til å gjøre alt som har med Direct2D å gjøre oppå samme backbuffer som Direct3D bruker. Vurderer å bygge hele GUI-laget i Direct2D nå, men den API'en er litt tungvint å jobbe med, så vi får se.

 

Her er et screenshot av hvordan tekst ser ut; den eneste forskjellen i størrelse er en skaleringsmatrise, så tar DirectWrite seg av å rendre fonten i riktig størrelse. Det hadde nok sett betydelig mer blurry ut ved bruk av sprites!

 

post-72253-0-21862600-1359211654_thumb.png

Endret av Wedvich
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...