Gå til innhold

Anbefalte innlegg

For tiden jobber jeg med et prosjekt i C++ der målet er en enkel 3D grafikkmotor for romskipsimulator.

 

Jeg kommer ikke til å kommentere spillet noe lenger en dette, men gå mer inn på detaljene rundt selve programmeringen.

 

Jeg har bestemt meg for å bruke en rekke API-er

 

Grafikk - Direct3D

Lyd/muskk - OpenAL

Fysikk - PhysX

Scripting - Squirrel

 

Hvorfor jeg valgte Direct3D

Jeg valgte D3D fordi det sparer meg for mye tid, pluss at Direct3D er tilgjengelig både på Xbox360 og Windows.

I tillegg er det forholdsvis enkelt å bytte til OpenGL dersom det er nødvendig.

 

Hvorfor jeg valgte OpenAL

I DirectX nå kan man bruke XAct audio, som er en software API for lyd, noe som får det til å skurre for meg...

Hvorfor bruke software, når man har hardware tilgjengelig? selv billigkorta til Creative støtter EAX3, og med

OpenAL kan jeg da utnytte EAX og annen funksjonalitet som hardware støtter.

 

Hvorfor jeg valgte PhysX

Ærlig talt har jeg ikke sett på så mange andre, men PhysX er enkel å få til å fungere, og etter det jeg har sett,

veldig rask og presis. (jeg har bare sett Havok tifligere, og jeg mener at PhysX er raskere og mer presis, uten å

ha noe annet sammenligningsgrunnlag en det jeg har sett med egne øyne på min egen PC)

 

Hvorfor jeg valgte Squirrel

Vel, først tenkte jeg på C#, men det kunne gitt meg problemer i etterkant, på grunn av at C# ikke er støttet av alle

plattformer.

Deretter tenkte jeg på Python, men fant ut at ved siden av å være forholdsvis treg, er Python sitt C API forholdsvis komplisert.

Jeg kom deretter til å se på Lua, og da begynte det å ligne noe. Lua har et enkel stack-basert vinkel på hvordan man

fytter data mellom VM og host-programmet, men jeg var ikke helt overbevist over syntaks i Lua, så valget falt til slutt på Squirrel,

som er kompakt og lite, samtidig som at det har samme stack-baserte måte å flytte data mellom VM og host-programmet.

 

OK!

 

Nå har jeg valgt alle relevante deler av programmet, og programmeringen har begynt.

...

men jeg har støtt på et problem med PhysX: bruk av convex shape.

Denne funksjonen bruker en stream for å flytte data fra host-programmet til PhysX objektet, greit nok.

Problemet kommer imidlertid når jeg inheriter fra base klassen NxStream for å lage en MemoryStream klasse; NxStream er abstract

og derfor må jeg arve alle funksjonene og skrive over dem, noe jeg har gjort, men Visual C++ sier at MemoryStream er en abstract class

og kan ikke instansieres...

WTF? jeg er bombesikker på at jeg har skrevet over alle pure virtual functions...

det kan ha noe med at det står virtual void somefunction() = const 0; fordi jeg vet ikke hva 'const' betyr i denne sammenhengen :S

 

Jeg såvidt har begynt på et ressursfilsystem, der alle enheter legges i et directorytree, som igjen inneholder en rekke properties. Datatypen til hver property bestemmes av en unsigned short, som igjen er et bitfelt, som forteller om det er et array, om det er et integer, om det er et flyttall, og deretter størrelsen (første bytet holdes av til dette)

Dette brukes til å lage et dynamisk type system, hvor brukeren kan legge til egne egenskaper til hvert objekt.

Disse ressursfilene vil da inneholde script, modeller, teksturer, animasjoner etc.

Lenke til kommentar
Videoannonse
Annonse

Nå har jeg fått fikset NxStream problemet, og både Direct3D og PhysX fungerer som forventet, men jeg må lese litt om PMaps, og vurdere om PMaps skal caches til disken når en modell lastes første gang, eller om de skal ligge med selve modellene.

Er egentlig veldig fornøyd med hvor enkelt PhysX er i bruk, alle Actors kan gi deg en GlobalPose, som er en matrise man bare multipliserer med nåværende matrisen, så flyttes og roteres objektet etter resultatet av simuleringen.

 

Jeg har begynt med et eget filssystem for ressursdata, og har fundert på noen forskjellige løsninger. Dette skal være et pakkesystem som skal kunne inneholde metadata om de forskjellige ressursene, samt kunne tilegne objekter brukerdefinerte data.

Jeg tenkte meg noe lignende et vanlig filsystem, for da kan data patches enkelt, og filer legges til eller trekkes fra, og at clusterbitmap da blir akkurat stort nok til at filen kan maks være 4 GB, som er filpekerne som brukes i filsystemet.

 

Nok om det

 

Når det kommer til verdensrommet, så tenkte jeg å dele hele universet inn i soner, for å kunne bedre utnytte flyttallet (siden oppløsningen er begrenset) der hver sone 100km x 100km stor. Det er viktig at alt er i skala for meg, men problemet kan da komme med stjerner og lignende massive objekter, for hvordan kan jeg tegne opp et objekt som kanskje er mange lysår unna? Det hadde også vært morsomt om romskipene ble tiltrukket av stjernenes tyngdekraft, men jeg får se på det når den tid kommer, langt igjen....

 

Jeg er litt villedet av hvordan jeg skal lage basisobjektet, nå består den av kun en NxActor for PhysX, som lages ved å bruke funksjonene BuildCollisionBox, BuildCollisionSphere, BuildCollisionCylinder og BuildCollisionMesh.

Den inneholder også ev funksjon for å lese og skrive til Mass, og en virtual funksjon som heter Render.

Men Squirrel kan kreve at ting gjøres annerledes, men jeg får se på det etterhvert som jeg får Squirrel til å gjøre som jeg vil.

 

Når det gjelder Squirrel, så har jeg såvidt begynt på dette, og egentlig ikke testet om jeg får det til å fungere enda, jeg har såvidt laget noen hjelpefunksjoner for å registrere funksjoner, men jeg må se hvordan jeg kan bruke klasser til å få Squirrel til å lage nye objekter, eller slette gamle.

Squirrel er også en av de API-ene jeg er veldig fornøyd med, den er lett og logisk å bruke. Jeg bruker ikke SquirrelPlus.

 

GUI-en har jeg også såvidt begynt med, den kommer selvsagt til å bruke Squirrel ganske gjennomgående for alle spillets funksjoner, og GUI-ens utseende og funksjon.

 

... og grunnen til at det heter DeepSpace 3 er fordi det første spillet jeg noensinne laget (I VB6 med DirectDraw het DeepSpace, og deretter fulgte DeepSpace 2 som var en VB.NET versjon av samme spillet)

Det har ingenting me DeepSpace 9 å gjøre ;) men det hadde vært kult om jeg kunne lagt til at man skal bekjempe enterprise i en mission eller noe... men det er langt i fremtiden :)

 

Jeg må også legge til at Direct3D er ikke så verst å jobbe med, når man kommer inn i rutinene. Til å begynne med ble jeg ganske forvirret av LockVertexBuffer og LockIndexBuffer, men denne måten å gjøre det på gjør det ganske trygt med tanke på memory leaks. Jeg er ikke helt sikker på hvorfor Direct3D ikke tegner noen tekstur på objektene mine, men det er sikkert en veldig god grunn.

Endret av GeirGrusom
Lenke til kommentar

Har såvidt begynt med en editor til deepspace, siden dette kreves for å kunne lage ressurser til programmet, og oppsett av miljø.

Det jeg starter med er en material editor, en sak for å definere planeter og andre "statiske" objekter.

Idéen er at planeter skal være i naturlig størrelse... problemet er at jeg ikke er helt sikker på hvordan et 16-bit/32-bit Z-buffer reagerer på et objekt som har en radius større 6 371 000 m (jorda)... for som kjent så blir Z-bufferet mindre presist dess større forskjellen på min og max er.

Trikset blir kanskje å endre rekkevidden på Z-bufferet for å rendre små objekter, eller objekter som er nærme spilleren.

 

Editoren brukes nå til å skape ressursfiler, og data for motoren. Jeg synes det er litt irriterende at man MÅ definere en Control som Direct3DDevicen skal rendre på, siden det hadde gjort det mye enklere for editoren siden mange vinduer må bruke samme devicen for å rendre sine scener.

Derfor har jeg laget et fake skjult vindu som jeg gir til devicen, som ikke brukes til å tegne på, vet ikke hvordan Direct3D reagerer på det enda, fordi jeg har ikke kommet så langt, men det er ikke aktuelt å lage en device for hvert vindu.

Lenke til kommentar
  • 2 uker senere...

Jeg har nå laget et markup language, som ser litt mer ut som et programmeringsspråk, grunnen til dette er rett og slett at jeg synes System.Xml er helt idiotisk laget.

Foreløpig har den to forskjellig typer elementer, element og string.

Den kan også har flere noder i grunnivået :D

Pluss at den idiotiske noden som forklarer tekst encodingen er fjernet :p

 

#system(name="Sol")
{
 #position(x="1", y="1", z="0");
 #planet(name="Merkur", mass="1", radius="1");
 #planet(name="Venus", mass="1", radius="1");
 #planet(name="Tellus", mass="999999", radius="9999999")
 {
#satellite(name="Moon", mass="8888888", radius="6000");
 }
 #planet(name="Mars", mass="1", radius="1")
 {
#satellite(name="Phobos", mass="1", radius="1");
 }
}
#unit(name="Asteroid")
{
 $script
 {
function FrameTick(var time)
{
   DoSomething();
}
 }
}

 

På tekstnoden ($) er det veldig viktig at all teksten inne i den er tabbet én innover, for ellers kan parseren ta feil av hvilke } som hører til teksten inne i den.

Lenke til kommentar

Har endret på noen av specene til dette markup språket.

For å kunne enklere lese det fra en stream som kanskje inneholder flere forskjellige elementer, så må hver fil inneholde en root som kan hete hva som helst, og eventuelle parameter til parseren føres i parameterne til noden.

f.eks.

 

#universe(author="Bjurt Bjørghild")
{
...
}

Lenke til kommentar
  • 2 uker senere...

Biblioteket for dette markupspråket er ferdig for både C#(brukes av editorer) og C++ (brukes av selve spillet)

Jeg vil etterhvert gi ut disse i Open Source, selvom det meste av programmene ikke vil være Open Source.

Jeg skal bare legge til mulighetene til en include node, som fører til at parseren fortesetter på en annen fil innen dokumentet, som gjør at man har et hoveddokument med flere under dokumenter. Dette gjør at f.eks. universe kan inneholde flere solsystemer, som kan endres uavhengig av hovedfilen.

Et viktig poeng er at dette ikke blir klippet og limet, men at parseren bare begynner å streame en annen fil istedet for hovedfilen.

 

#universe(author="me")
{
 +include(filename="sol.pml")
 +include(filename="proximacentauri.pml")
}

 

Så det jeg akter å fortsette med nå, er grafikken.

Jeg har tenkt på teksturer og slikt, og tenker jeg bruker et eget filformat for å lage forskjellige material-biblioteker.

Deretter vil hver modell referere til en fil, og et under-materiale.

Et materiale består av et udefinert antall parameter, grunnen til at antallet er udefinert, er fordi det må være mulig å legge til egenskaper til materialer som kanskje skal behandles av PhysX eller av shaders.

Lenke til kommentar
  • 1 måned senere...

Har såvidt begynt å kikke litt mer på dette.

Jeg fant ut at hvert objekt kan ha angular damping og linear damping, som gjøre det betydelig enklere for meg å lage romskipspill :D

Grunnen er at i utgangspunktet er det fryktelig vanskelig å styre et romskip i rommet, fordi objekter fortsetter i en retning helt til det blir stanset. Derfor jukser jeg til "atmosfære" ved å legge til angular damping og linear damping som gjør at objektet vil bremse ganske fort så lenge spilleren ikke har foten på gassen.

 

Jeg må nok starte fra scratch, for det prosjektet jeg har satt opp er blitt ganske rotete. Så jeg har tenkt til å lage tegninger over klasser og funksjoner, sånn at jeg ikke driter meg ut på et sent stadie.

 

Jeg tar vare på datatypene, og kanskje drar med meg noe fra mitt eget scriptspråk (for consolen i dvorient) får se ettersom tiden går, og jeg får litt bedre tid.

 

Må bare legge til at jeg er ganske imponert over PhysX og hvor utrolig enkelt det er å bruke.

 

Vurderer å kanskje gå over til OpenGL, grunnet at Direct3D 10 fungerer HELT annerledes en Direct3D 9, så hvis jeg vil legge inn Dx 10 funksjoner etterhvert, er det enklere med OpenGL enn å bytte fra Direct3D 9 til 10.

Dessuten har jeg mye mer erfaring med OpenGL, flyttbarheten vil øke betraktelig også.

 

Når det kommer til Squirrel, så er det et OK språk, liker syntaksen. Men det jeg ikke helt fatter, er hvorfor man må drive med denne stack manipuleringen? det er da mye enklere å kunne bestemme dette i selve scriptspråket (det er planen i mitt)

 

Nå er ikke dette språket ment for dette formålet, men jeg skal vise hva jeg mener

 

I Squirrel så må du lese fra stacken til VM og dytte data til stacken før man kaller en funksjon, planen i mitt språk er at man definerer spesielle eksporterte funksjoner slik:

 

values = <> // Define a dictionary
def SomeExportFunction({marshal:cstr}name = "", {marshal:float}value = 0.0) = 0
 values<name> = value
end

Litt eksempel kode fra språkdefinisjonen min.

Her sier den til VM at første parameter må konverteres fra en C-string(char*) til en dvString og andre må konverteres fra 32-bit flyttall til en dvFloat (double)

Det er mye enklere å programmere slik da, for da kan man bare typedef en funksjonspeker i programmet og så fikser VM resten.

 

Jeg holder meg til Squirrel, fordi det er betydelig enklere å få til en Lua, og ihvertfall Python.

Endret av GeirGrusom
Lenke til kommentar

Har skrevet litt videre, har nå fått frem et plug-in basert system, der Dll-er kan erstatte eller utbedre funskjoner i spillmotoren.

OpenGL er såvidt påbegynt, og samme med OpenAL, PhysX har jeg ikke begynt med enda, og heller ikke Squirrel.

 

Vel, motoren fungerer ved at Engine.dll laster nødvendig moduler (man trenger én renderer, foreløpig OpenGLDevice.dll, Én fysikkmotor (ikke påbegynt) en lydmotor (OpenALDevice.dll) og en scriptmotor (ikke påbegynt) i tillegg så vil den laste ting som er spesifikt for spillet som f.eks. spesifiserer main loopen, GUI etc. hvordan jeg gjør dette finner jeg mer ut av senere.

Man kan også skrive Dll-er for å laste teksturer og 3D modeller fra forskjellige formater, foreløpig har jeg ikke skrevet noen :p

 

Men grunnlaget er der ihvertfall.

Lenke til kommentar
  • 2 uker senere...
  • 1 år senere...

Litt sånn offtopic:

 

Jeg har fått sykt mye interesse for spill utvikling, og jeg tenkte meg å begynne å lage et enkelt spill til og begynne med. Et enkelt "Simulator" spill som lar meg kontrollere en person og stige opp på en ridedyr. Men etter jeg er komplett "Noob" så kan det ta meg rundt 6 måneder før jeg får til det.

 

Men spørsmålet mitt er hva trenger man som grunnleggende for å skape et 3D spill som lar deg kontrollere en person men jevne bevegelser, osv?

 

Jeg ser at du har Grafikk, Lyd/musikk, Fysikk og Script. Jeg antar at det trengs for å skape noe som helst men jeg vil vite litt mer om det :)

 

Jeg lekte med gamemaker som 12åring så jeg synes begynner å bli litt for enkelt, og dermed trenger en utfordring,og jeg trenger å skape et helt eget spill for å se hva jeg foretrekker mest innen spillutvikling.

Lenke til kommentar

Dette prosjektet var skrevet helt i C++. Det er derimot ingen krav for spill. Bruk det språket du kan.

Når det gjelder biblioteker, finnes det masse alternativer til de jeg bruker til alle mulige språk.

Det du må gjøre, er å kartlegge kravene til spillet ditt, finne de bibliotekene du trenger, og planlegge hvordan du skal begynne.

Spillutvikling er mer planlegging enn programmering, uten god planlegging vil du støte på problemer.

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...