Gå til innhold

Glorg - Spillmotor og OpenGL wrapper for C#


Anbefalte innlegg

Dette skal bare være en slags "blogg" hvor jeg bare skriver ned hva jeg driver med, og hvilke problemer og løsninger jeg har når det gjelder wannabe spillmotoren min Glorg.

 

Denne motoren er skrevet 100% i C# og bruker OpenGL/OpenAL

 

Det jeg jobber med akkurat nå er CSG som er Constructive Solid Geometry. For de som har drevet med spill eller 3D programmer før, så er dette grunnteknikken for map-editing i UnrealED og WorldCraft, og i 3D Studio kjenner en det best igjen som Boolean i Compound Objects.

 

Det jeg til nå har gjort, er å implementere brush builders for kube, kule, sylinder og smultring (uten fett)

Disse er mer beskrivelser av objektene og er ikke med en gang klare til å rendres (uten å bruke OpenGLDevice.Debug.DrawCsgBrush)

DrawCsgBrush er som kanskje litt kommer frem av objekttilhørighet, en debug funksjon, og rendrer wireframe og normalene til alle polygonene. Forskjellen på CsgBrush og for eksempel en Mesh, er at den ikke nødvendigvis består av triangler, den består av konvekse polygoner, og polygonene deler alltid vertices.

 

Idéen nå, er at en kan lage flere CsgBrush, og bruke + (Add) -(Subtract) *(Intersect) og / (Deintersect) på modellene, så en kan skrive:

 

CsgBrush result = CsgSphere() + CsgCube() som vil utføre boolean add på de to og danne en CsgBrush som resultat. Deretter kan en bruke CsgHelper.CreateStandardMesh som akkurat nå bruke Triangle fan metoden for å danne triangler av polygonene og en kan eventuelt legge på teksturkoordinater etterpå.

 

En ting jeg har lurt på, er om det kanskje kan være lurt å ta med teksturkoordinater i selve CsgBrush? men problemer vil dukke opp dersom en limer sammen flere brushes fordi at teksturene vil bli dradd i sømmene pga at de mest sannsynlig vil ha forskjellig teksturkoordinater på et slikt punkt.

Svaret er nok å legge to vertexer for de to forskjellige modellene i sømmene, slik at teksturkoordinatene kan bli bevart.

Jeg har også nå brukt unsigned short som datatype for index bufferet til CsgBrush, som ved nærmere ettertanke var et temmelig idiotisk valg. Det er litt sent/tidlig for meg å fikse det nå, så jeg får ta dette ved et senere tidspunkt.

 

Jeg ble temmelig overrasket over hvor enkel triangle fan var

 

src.Polygons.ForEach(delegate( Face f ) { index_count += (f.Indices.Data.Length - 2) * 3; } );
ushort[] indices = new ushort[index_count];
for(int i = 0; i < src.Polygons.Count; i++)
{
Face face = src.Polygons[i];
for ( int j = 2; j < face.Indices.Data.Length; j++ )
{
	indices[index++] = face.Indices[j - 1];
	indices[index++] = face.Indices[0];
	indices[index++] = face.Indices[j];
}
}

 

For de som er interessert.

 

Grunnen til den første linjen, er for å telle opp hvor mange trekanter som trengs for å danne hele indexbufferet, siden polygonene er n-kantede.

 

Det jeg gjør, er å velg indexen til den første verticen som startpunkt for trianglefan funksjonen, og deretter bare gå igjennom alle vertexene og danne en "vifte".

Jeg har gjort den omvendt her, fordi jeg har røret med hva som er frontsiden og hva som er baksiden av et polygon i Csg koden :p og jeg lurer på om jeg ikke har gjort det samme i Plane.LineIntersect og Polygon.LineIntersect som kan bli problematisk siden disse funksjonene brukes veldig mye i CSG.

 

Jeg skal få hostet Glorg med kildekode etterhvert, men jeg vil helst ha det på min egen side, og ikke bruke sourceforge eller lignende. Grunnen er rett og slett at jeg vil ha litt reklame for meg selv hvis noen først skal laste det ned.

 

post-31659-1229929166_thumb.png

Her vises først modellen som er blitt dannet av CreateStandardMesh, og det grønne er DrawCsgBrush.

Jeg har startet på selve CSG koden, men det er mye feil enda, så den ser ut til å lage helt tilfeldige resultater :p

 

Mvh Henning Moe

Lenke til kommentar
Videoannonse
Annonse

Sitter nå og sliter litt med Csg.

 

Jeg leser ikke noen tutorial eller noe, for jeg prøver å finne ut av dette selv.

 

Problemet jeg tenker på, er om det er best å gjøre polygon-edge sjekk, eller edge-polygon sjekk?

Nå bruker jeg polygon-edge, men ejg tror ikke det blir riktig, fordi jeg ikke tar hensyn til at en linje kan krysse flere polygoner.

 

Tror denne tegningen forklarer litt hva jeg er ute etter:

post-31659-1229967118_thumb.png

 

Men i samme åndedrag så må dette gjøres på begge formene, for å kunne få en ordentlig omriss av formen.

 

Dette er vanskelige greier :S

Lenke til kommentar

Vel, nå har jeg laget det slik at den sjekker om en side treffer andre polygoner, men det ser ut til at jeg har feil i Polygon.LineIntersection funksjonen min:

 

public Vertex LineIntersection( Vertex a, Vertex b, out FaceSide side )
{
Vertex dir = ( b - a ).Normalize(); // Calcualte line normal

float t = ( m_plane.D - dir.X * a.X - dir.Y * a.Y - dir.Z * a.Z ) / ( dir.X * ( b.X - a.X ) + dir.Y * ( b.Y - a.Y ) + dir.Z * ( b.Z - a.Z ) );

float dir_side = VertexHelper.DotProduct(dir, m_plane.Normal);

if ( dir_side < 0 )
	side = FaceSide.Front;
else if ( dir_side > 0 )
	side = FaceSide.Back;
else
	side = FaceSide.Adjacent;

if ( float.IsNaN(t) || t < 0 || t > 1 )
	return Vertex.Undefined;

float dot = VertexHelper.DotProduct( dir, m_plane.Normal );

Vertex pos = a + dir * t * ( b - a );

// Check if all the faces on the polygon faces outward from our intersection point
for ( int i = 0; i < m_verts.Length - 1; i++ )
	if ( VertexHelper.DotProduct( Triangle.CalculateNormal( m_verts[i], m_verts[i + 1], pos ), m_plane.Normal ) < 0 )
		return Vertex.Undefined;
if ( VertexHelper.DotProduct( Triangle.CalculateNormal( m_verts[m_verts.Length - 1], m_verts[0], pos ), m_plane.Normal ) < 0 )
	return Vertex.Undefined;



return pos;
}

 

Jeg vet ikke hva jeg har gjort feil :S

 

edit: Hmmmm jeg ser ihvertfall én grov feil... men den forklarer fortsatt ikke helt hva som er galt....

Endret av GeirGrusom
Lenke til kommentar

Etter at Giddion spurte om OggVorbis støtte, har jeg kikket nærmere på dette.

 

Jeg har funnet ut at OpenAL delen er bare kluss og rør, men jeg har nå lagt inn støtte for Vorbis ved å bruke libvorbisfile. Dette er en .dll fil som jeg bare kompilerte for vanlig native code og bruker P/Invoke mot.

 

Nå har jeg laget slik at en kan i teorien spille den av, men jeg fant ut at OpenAL delen av Glorg er temmelig dårlig, så jeg har tenkt til å skrive denne delen på nytt.

 

Jeg er ikke så veldig erfaren med lyd, men er det en idé å kanskje la Glorg sette opp en egen tråd for AudioDevicen som passer på at alle lydkilder får buffret data? Hvis OpenAL er som OpenGL på dette, så må jeg nesten finne en måte å invoke dette for hoved-tråden, eller tråden som OpenAL devicen ble laget for.

Jaja, får se mer på dette over jul.

Endret av GeirGrusom
Lenke til kommentar

Vel, har en del problemer med libvorbisfile.

 

Først og fremst får jeg det ikke til å fungere under 64-bit, som kan være et temmelig stort problem.

And og nest fremst, så feiler ov_read av ukjente årsaker. Det er en .NET relatert feil, så jeg er usikker på hva jeg kan gjøre med det. Jeg bruker nå ov_fopen for å åpne .ogg fila, og det ser ut til å fungere fint (OggVorbis_file blir fyllt ut og full fryd etc)

Men når den kommer til ov_read, så er det plutselig ikke så morsomt lenger, da dukker det opp

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

som er typisk for at den skriver utenfor bufferet eller lignende... men det burde ikke skje nå.

 

int len = 0;
byte[] buffer = new byte[buffer_size];
int ret_len;
fixed(byte* ptr = buffer)
ret_len = LibVorbisFile.ov_read( ref m_file, ptr, buffer.Length, 0, 2, 1, out len );

(i utgangspunktet brukte jeg byte[] som datatype der det står ptr, men byttet til byte* istedet tilfelle det var noe marshalling problemer)

 

Jeg kan ikke se noe galt med importen min

 

[DllImport( "libvorbisfile", CallingConvention = CallingConvention.Cdecl )]
	internal static extern unsafe int ov_read( ref OggVorbis_File vf, byte* buffer, int length,
		int bigendianp, int word, int sgned, out int bitstream );

 

extern long CALLCONV ov_read(OggVorbis_File *vf,char *buffer,int length,
		int bigendianp,int word,int sgned,int *bitstream);

CALLCONV er ikke definert til noe nå (fordi jeg bruker bare vanlig cdecl fremfor stdcall)[/code]

 

Jeg kan ikke forstå hva jeg gjør galt :S

 

Det blir vel til at jeg etterhvert heller leter etter en C# implementasjon eller skriver en wrapper i C++/CLI.

Lenke til kommentar

Jeg har kikket mer på CSG, og har kommet frem til den konklusjonen at det er noe galt med plane-interpolation algoritmen min. Polygon-saken er også feil, fori jeg går rundt polygonet og behandler den som trekanter, noe som jeg antar er feil fremgangsmåte.

Jeg kan tenke meg at for å sjekke om et punkt er innenfor et polygon, så sjekker en hvilken vei hver linje peker...noe som hadde vært enkelt dersom dette var et 2D polygon.

Jeg kan kanskje bruke triangelmetoden som er der nå, ved at dersom den er innenfor noen av trianglene, så ansees den som innenfor polygonet. Foreløpig tenkte jeg så kort at den måtte være innenfor alle :blush:

 

Dette er helt klart noe jeg vet for lite om. Jeg får bare konsentrere meg om å få line-plane-intersection til å fungere først.

 

Jeg har også begynt på en klasse som skal konvertere en CSG-brush til en modell, der en har muligheten til å legge over teksturkoordinater (som UVW-map i 3dsmax) ved å bruke beskrivende klasser, som CsgTextureMapSphere. En kan også legge til modifiers som bend, twist e.l. ved å bruke Transform funksjonen i CsgBrush klassen (forøvrig tar denne funksjonen også Matrix for å translere, skalere eller rotere modellen)

Denne gir forøvrig tilbake et vertex-buffer og et index-buffer og ikke StandardMesh, noe som gjør CSG-en mer nyttig (siden en ikke er begrenset til 65536 punkter)

 

Det skal bli interessant å se om jeg er smart nok til å få til dette, men foreløpig ser det mørkt ut :)

 

Jeg har også vurdert om det burde være mulig å gjøre om en CSG-brush til et BSP-tre før modellen gjøres om til triangler. Fordelen er at det blir færre operasjoner, og et kjapt BSP-system er å foretrekke. Grunnen til at det blir kjappere, er at alle poygonene i CSG-brushen er n-kantede, men konvekse, så istedet for å måtte regne ut for alle trianglene som blir dannet, kan en regne ut BSP-treet for hyperplane til hvert n-kantede polygon (som regel firkanter regner jeg med)

Da må jeg også lage en BSP-tre klasse, men jeg tror jeg skal la dette vente til jeg eventuelt faktisk får til CSG.

 

 

Jeg fant også ut av trianglestrip, men jeg tror jeg holder meg til trianglefan metoden for å gjøre om polygoner til triangler. Grunnen er at jeg ikke kan se noen reell gevinst med trianglestrip. Forskjellen er at mens trianglefan bare tar et vilkårlig punkt, og lager trekanter fra den til alle andre punkter, så går trianglestrip fra 0->1->(-1), 1->2->(-1), 2->(-2)->(-1)

Hvor alle negative tall er regnet fra slutten av listen. Altså den lager et sikksakkmønster med triangler over polygonet.

 

Et par urelaterte endringer:

 

Jeg har endret temmelig mye på hvordan lysa fungerer nå. Tidligere brukte en funksjonen UpdateLight for å få lyset til å være gjeldende, denne funksjonen er nå fjernet, og alle egenskapene som blir endret, vil bli endret med en gang. Tidligere mellomlagret jeg alle endringer og gjorde dem gjeldende ved å kalle UpdateLight.

 

Jeg må også få fjernet Lock begrensningen på Buffer klassen, dette er helt unødvendig, men jeg må bare finne en god metode for å passe på at arrayet blir låst opp igjen til riktig tid, og eventuelt en mekanisme for å hindre to tråder fra å endre samme arrayet. Det er ikke ulovlig at to stykker leser eller skriver til arrayet nå, men jeg må kanskje gjøre programmereren obs på hva han driver med.

Det eneste lock funksjonen egentlig gjør i dag, er å hindre at GC flytter arrayet.

 

Vel, jeg får lite tid til å jobbe med dette før etter nyttår.

Lenke til kommentar

Det var en som etterspurte multisampling i Glorg, så jeg har begynt med dette. Det startet med at jeg måtte implementere framebuffers, som jeg trodde skulle gå relativt greit... men tro er noe jeg må slutte med :p

 

Vel, nå skal alt være på plass, men et sted har jeg gjort noe galt.

 

Fremgangsmåten i Glorg for å få inn framebuffer, er at du lager først en ny FrameBuffer, og legger til ett eller flere RenderBuffer. Når dette er gjort, så skal det bare være å kalle [OpenGLDevice].MakeCurrent([FrameBuffer])

 

Nå sier den imidlertidig IncompleteAttachment (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT) som er litt fnodig. Jeg har fulgt denne tutorialen så slavisk som jeg klarer, men jeg kom over en ting jeg synes var litt pussig:

Hvorfor bruker en GL_DEPTH_COMPONENT på Z-bufferet? hva skal jeg da bruke på farge og stencil? det er ikke noe som heter GL_COLOR_COMPONENT eller GL_STENCIL_COMPONENT. Men etter å ha RTFM-et ser det ut til at jeg skal bruke GL_RGB, GL_RGBA eller GL_STENCIL_INDEX.

 

Tar jeg ikke helt feil, så kan en bruke multisampling på FrameBufferet ved å bruke glRenderbufferStorageMultisampleEXT fremfor glRenderbufferStorageEXT. Dette er dog en egen extension utenfor selve frame-buffer extensionen... men det går sikkert fint :)

Det er bedre å kunne bruke en extension som ikke er WGL-avhengig. En av fordelene med Glorg nå, er at det aldri er nødvendig å restarte motoren for å gjøre endringer.

 

Edit: Fikk det til nå, glCheckFramebufferStatusEXT returnerer nå Complete :)

Edit2: Vel, den sier complete... men skjermkortdriveren fryser hver gang jeg prøver programmet... hømm... vel, det får blir for en annen dag.

Endret av GeirGrusom
Lenke til kommentar

Ok, nå returnerer FrameBuffer Complete, men ikke hvis jeg binder en tekstur tid den, da kommer den med unsupported, som litt RTFM-ing forteller meg at internalformat av enten bitmapen eller RenderBufferet ikke er støttet av implementasjon, eller det er en kræsj imellom dem.

 

Jaja...

 

Finner sikkert ut av det til neste år.

Endret av GeirGrusom
Lenke til kommentar

Geometry shaders skal være implementert nå, men jeg har ikke hardware til å teste det selv (NV80 har NV78X). Så hvis noen vil prøve, kan dere laste ned glorg her og teste.

 

Glorg.zip

 

Fremgangsmåten er enkel, lag en Shader.Program og fest inn shaders. Når alt det er ferdig, kaller du Program.Compile()

Program.GeometryInputType, Program.GeometryOutputType og Program.MaximumNumberOfVertices setter Geometry shader parameter.

 

Glorg.Shader.Program prog = new Glorg.Shader.Program
(
new Glorg.Shader.ProgramArgs( VertexShaderCode, Glorg.Shader.ShaderType.VertexShader ),
new Glorg.Shader.ProgramArgs( GeometryShaderCode, Glorg.Shader.ShaderType.GeometryShader ),
new Glorg.Shader.ProgramArgs( FragmentShaderCode, Glorg.Shader.ShaderType.FragmentShader )
);
prog.Compile();

device.MakeCurrent(prog);

 

Etter det er det bare å rendre som vanlig.

 

Her er en geometry shader tutorial

http://cirl.missouri.edu/gpu/glsl_lessons/...ader/index.html

 

En kan forsøke på en sphere, enkleste måten å lage det på nå er igjennom CsgBrush saken.

StandardMesh mesh = Glorg.Csg.CsgHelper.CreateStandardMesh(new Glorg.Csg.CsgSphere( 1f, 64, 32 ));

 

Denne rendrer du gjennom OpenGLDevicen ved å kalle dette:

device.AssignVertexBuffer(mesh.VertexBuffer);
device.DrawPrimitives(mesh.Parts[0].Indices);

Lenke til kommentar

Jeg har nå lagt til motion blur i Glorg, som var en temmelig simpel prosess i OpenGL, ikke nødvendig å bruke shadere eller noe.

 

Metoden er beskrevet her og bruker accumulation buffer.

 

I Glorg nå skriver en rett og slett [OpenGLDevice].MotionBlur([styrke]) for å legge på motion blur, dette gjøres helst rett før [OpenGLDevice].Present();

 

Ved siden av å ha lagt til funksjoner for stencil buffer og accumulation buffer, har jeg også lagt til en mekanisme for å gjøre en matrise gjeldende innenfor et område, uten å måtte manuelt kalle PushModelMatrix og PopModelMatrix selv.

 

Dette fungerer ved at en struktur som kalles Transform brukes i en using blokk.

For eksempel:

 

[dev er OpenGLDevice]

using(new Transform(new RotationYMatrix(45.0f), dev))
{
 // tegn et objekt
}

 

Dette vil føre til at objektet innenfor using vil bli rotert 45° rundt Y aksen.

For å gjøre en omvendt multiplikasjon, brukes TransformReverse strukturen istedet.

 

Fordelen med dette er at det blir enklere å skrive koden, og det ser ganske tøft ut :)

 

Det er i enkelhet laget ved at Transform og TransformReverse er strukturer som implementerer IDisposable, som using kaller når blokken er ferdig. I constructoren så pushes matrisen til stack, og multipliseres med parameteret, i Dispose så kalles PopModelMatrix.

Endret av GeirGrusom
Lenke til kommentar

Ok, jeg kjenner jeg nå må fokusere mer på å få dette til å bli en spillmotor, så jeg tenkte sette opp en prioriteringsliste:

 

- Revamp av nodetree systemet, og bruke matriser på hver node, og unngå direkte OpenGL kall i disse klassene.

- Implementere OpenAL på en tålelig måte med Ogg Vorbis

- Ny standardmesh klasse med flere muligheter og uint index-buffer

- PhysX eller lignende API støtte (Newton kanskje?)

- Rigid body dynamics første prioritet

- Bygge CSG-brush med flere valg og modifiers

- CSG i fungerende stand

- Bedre støtte for funksjoner, flere filformater, bedre støtte for cube texture, 3D texture osv.

 

Endelige mål vil være å kunne bygge et fullstendig spill uten å bruke noe annet en klassene som er innebygget i Glorg, både 2D spill og 3D spill.

Mulighet for å bruke et IDE for dette med støtte for C# scripting, testing og debugging.

 

Jeg vil fjerne hele Glorg base classen, denne lager bare trøbbel, og har ingen funksjon akkurat nå allikevel.

Idéen er å kunne bruke db4objects eller lignende til å lage et filsystem for et fullstendig spill med koden osv. Men jeg synes db4objects er laget på en litt dum måte akkurat nå, hvorfor brukes ikke Attributes der for å for eksempel fortelle hvilke felt som skal ligge i databasen eller ikke?

 

Jaja, jeg får se hvordan dette går fremover.

Lenke til kommentar
  • 3 uker senere...

Har nå lagt til litt flere ting i Glorg:

- Frame basert animasjoner fungerer nå (bruk ComplexMesh klassen) som bruker linear interpolering for å morfe mellom stadier.

- Startet på nytt med Node tree og bruker nå TransformReverse for at dette skal bli riktig.

- Begynt å implementere Vertex Buffer Objects, men dette er enda ikke helt i boks

- Lagt til Glorg.Generic.IndexBuffer. Dette er lagt til på grunn av Buffer Objects.

- Lagt til Nodes.Light som skal bli en erstatning for den nåværende klassen, NodeTree.Light. Denne bruker matrisen utelukkende for å posisjonere seg.

 

Alt i alt så skal Glorg være en del enklere i bruk nå.

 

Jeg har planer om å lage en kamera klasse, da denne vil bli temmelig mye enklere å lage nå en den var tidligere.

Det er heller ikke lenger noen behov for å kalle UpdateModelMatrix/UpdateProjectionMatrix lenger, da motoren selv merker om dette er nødvendig.

 

Det er dog verdt å merke seg at det kan være nødvendig å kalle disse funksjonene eksplisitt dersom du går rundt Glorg og bruker rene OpenGL kall.

En kan også skru av denne funksjonen ved å skru av KeepMatricesUpdated i OpenGLDevice.

 

Da er punkt nummer 1 på vei, og punkt nummer 3 ferdig.

Lenke til kommentar

Da har jeg kommet lenger på vei innen spillmotoren, og lagt til noen kjekke features.

 

Kamera klasse er implementert, sammen med CameraTransformState for å kunne enkelt gjøre kameraet gjeldende.

 

Jeg har skrevet noen Node klasser, Entity, Trigger og TimerTrigger.

Grunntanken her er at Trigger har en egenskap som heter TriggerTarget, som er en tekststring. Dersom triggeren fyrer av, så vil den lete etter alle nodene med dette navnet ved å bruke de nye Find og FindAll funksjonene i Node, og kalle Trigger funksjonen på dem. Oppførselen kan være tre ting: Trigger once, trigger toggle og trigger event.

Trigger once er ikke satt til noe enda, trigger toggle skru av og på Enabled på nodene som blir berørt. Trigger event fyrer av Trigger funksjonen på objektene som blir berørt, og denne funksjonen er planlagt at skal være den en vil overskrive i et spill.

 

Jeg har også lagt til en Wavefront Obj loader for enklere å laste modeller, .3ds loaderen er fryktelig vanskelig å bruke, så jeg tror jeg skal slette den og skrive hele skiten på nytt.

 

Kamera klassen er temmelig enkel i bruk egentlig, for å få den til å gjelde, bruker en CameraTransformState på denne måten:

 

using(new CameraTransformState(my_camera, device))
{
 // Render her
}

 

Eksempelvis:

 

rotate_matrix.RotateDegreesY(45f);
using(new CameraTransformState(my_camera, device))
{
 using(new TransformReverseState(rotate_matrix, device))
 {
my_complex_mesh.Render(device);
 }
}

 

Ideelt bruker en nå noder for å rendre, da slipper en å tenke på disse tingene. Alle noder har en virtual funksjon som heter Render, denne er virtual.

Eventuelt har også alle noder nå også en Mesh egenskap som består av ComplexMesh som nå har mulighet for frame-animasjoner.

 

Node my_scene = new Node();
Node new_node = new Node();
new_node.Mesh = my_model;
new_node.DrawMode = DrawMode.Mesh;

...

void Render()
{
 using(new CameraTransfromState(camera, device))
 {
my_scene.Process(device, OpenGLDevice.GetTimeElapsed());
 }
}

Det er også mulig å bruke Glorg.Game.Game klassen, denne inneholder noen spillfunksjoner, men foreløpig er det bare en wrapper klasse for noder og kamera.

Lenke til kommentar

Jeg har nå gjort FrameAnimation klassen helt generisk. Tidligere var den av typen VertexNormalTex, men nå bruker jeg lambda expressions og generics for at en skal kunne velge datatypen selv.

 

Så for å lage FrameAnimation nå og kalle Process funksjonen gjør en eksempelvis slik:

 

FrameAnimation<VertexNormalTex> animation;
// Les inn data til klassen
// ...
// Animer
animation.Process( time, ( VertexNormalTex vert ) => vert.Position, ( ref VertexNormalTex vert, Vertex data ) => { vert.Position = data; } );

Grunnen til dette er at en ikke kan lese vertex data direkte i generics (dette er ikke templates) så jeg måtte bruke delegates for å få det til.

Lenke til kommentar
  • 2 uker senere...

Da er PhysX delvis på plass.

 

Jeg har også byttet ut store deler av NodeTree, så det skal nå fungere, og PhysX er en del av dette.

En kan nå lage en instans av Game, og StartGame vil starte en ny tråd som rendrer kontinuerlig. Grunnnoden er PhysicsBaseNode root noden til et physics objekt må alltid være en PhysicsBaseNode.

En danner en shape etter at objektet er lagt til listen, dette er svært viktig, fordi physics objektet leter etter grunnnoden når en kaller Create metoden.

Støttede shapes er nå Box, Plane og Sphere, flere kommer selvsagt etterhvert.

 

Jeg har dog store problemer med PhysX støtten, fordi jeg bruker PhysX-sharp. Denne bruker P/Invoke mot en native dll som heter PhysX.dll. Problemet her, er at denne er 32-bit, og jeg får ikke kompilert den for 64-bit. Dette virker til å være fordi jeg har en nyere SDK. Feilmeldingen er "Cannot instansiate abstract class" som tyder på at noen funksjoner ikke blir lagt til i en av funksjonene i wrapperen.

 

Så foreløpig må en bruke 32-bit for at Glorg skal støtte PhysX, dette går dessverre merkbart utover ytelsen.

edit: Laget en fiks for det, nå sover ikke render tråden overhode, noe som økte ytelsen endel.

 

Jeg er blitt temmelig fornøyd med Game og Nodes nå, det skal ikke mange linjene til med kode for at programmet skal fungere.

 

edit: legger med Demo nummer 1. Krever .NET 3.5 og PhysX System Software installert.

GlorgPhysX.zip

Endret av GeirGrusom
Lenke til kommentar
  • 1 måned senere...

Jeg holder nå på å skrive to ting: en Ogg Vorbis dekoder og en mulighet for å bruke DirectShow i Glorg.

Akkurat nå funker DirectShow ypperlig både i 32-bit og 64-bit, men den bruker DirectSound som standard output. Hvordan kan jeg få DirectShow til å bruke OpenAL istedet? Det er dog ikke kritisk, men det ville vært en stor fordel, siden en da kan bruke DirectShow filter på helt vanlige lyder. Men det ser ut til at jeg enten må implementere IBaseFilter i en klasse, eller bruke SampleGrabber filteret og sende data til Null.

 

Jeg har noen problemer med Ogg Vorbis også, jeg er temmelig sikker på at jeg har fått Ogg til å funke riktig, og jeg kan fint lese ut informasjon om Vorbis streamen, men jeg kjenner jeg går på temmelig tynn is når jeg prøver å skrive koden som leser initialiseringsdata for vorbis streamen (codebooks og whatnot) siden jeg ikke aner hva disse egentlig er til, og jeg synes ikke Vorbis dokumentasjonen forklarer det godt nok (sikkert fordi den forventer at jeg har peiling på dette fra før)

 

Så foreløpig bruker jeg DirectShow, da dette i det minste fungerer, og kan spille Ogg Vorbis med riktig dekoder installert.

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å
×
×
  • Opprett ny...