OpenGL: Indlæse data fra filer

Tags:    delphi

<< < 12 > >>
Jeg har læst artikle om OpenGL spil programmering i Delphi, og det ser da meget fedt ud, problemet er bare: Hvad så hvis man vil have flere baner? Hvordan får jeg alt dette pakket ned i tekst-filer, og laver et program der kan indlæse disse data, og bygge 3D-verdenen op?



16 svar postet i denne tråd vises herunder
2 indlæg har modtaget i alt 2 karma
Sorter efter stemmer Sorter efter dato
Det første du skal gøre når du vil hente koordinater fra en fil er at udvikle en fil struktur. OpenGL skal havde koordinater (Vertex) for at rendere geometry. Men mange af koordinaterne er de samme. Det betyder at dine filer vil komme til at fylde utrolig meget. I stedet kan du lave en VertexArray og en FaceArray. VertexArrayen består af koordinater. Eksempelvis en kasse består af 8 vertexer. Du skriver derfor de koordinaterne på de 8 vertexer i den array! I din FaceArray skriver du så hvordan de 8 vertexer skal forbindes for at det kommer til at ligne en kasse. Når du skal rendere kassen, laver du derfor en For-To-do lykke på din FaceArray's længde og tegner din kasse. Denne teknik giver dig uanede muligheder!

type
TVector = record
X, Y, Z : Single;
end;

TFace = record
V1, V2, V3 : Integer;
end;

VertexArray : array of TVector;
FaceArray : earray of TFace;

Indlæs dine vertex koordinater og faces fra din fil til din arrays...

procedure Render;
var
I : Integer;
begin
glBegin(gl_Triangles);
for I := Low(FaceArray) to High(FaceArray) do
with FaceArray[I] do
begin
glVertex3fv(@VertexArray[V1]);
glVertex3fv(@VertexArray[V2]);
glVertex3fv(@VertexArray[V3]);
end;
glEnd;
end;



Kan du ikke komme med et konkret eksempel? Ellers forstår jeg det simpelthen ikke....

Hej,

Nu sad jeg og blev lidt interesseret i hvordan det kunne gøres...

Jeg har lavet en klasse som kan holde vektorer og faces samt gemme oh hente sig selv fra en fil (Jeg har taget udganspunkt fra det som Søren skrev):

HUSK at gemme koden i en pas fil med navnet 3dObject.pas
Fold kodeboks ind/udKode 


Når du skal bruge klassen 3dObject så kan du gøre det på følgende måder:
Fold kodeboks ind/udKode 


Grunden til at det ser lidt tricky ud når man skal render (her mener jeg ved glVertex3fv funktionskaldene) er det fordi min version af OpenGl.pas har defineret dens parameter som PGLfloat i stedet for en pointer til et array af single (hvilket det jo egentligt er da PGLfloat bare peger på et array med 1 element). Hvis det var defineret som jeg havde beskrevet så var vi ikke nødtil at typecaste PVector til en Pointer......Nå jeg skulle bare lige af med lidt luft ;-)

Du kan jo evt. udbygge 3dObject.pas med en ny klasse som kan indeholde/gemme/hente flere objekter...

Nå men jeg håber det hjælper dig lidt på vej..

PS. har du spørgsmål til koden så sig til.

/Michael.



En ting af gangen. Det der er vigtigst i starten, er, at kunne håndtere OpenGL og alle dens funktioner. Koordinater kan i realiteten bare gemmes i en text-fil ligesom AutoCad's DXF format og 3D Studio Max's ASC format. Mange udviklere brugere den metode. Men det er selvfølig op til dig, hvordan din fil struktur skal se ud.



I Delphi's hjælpe-fil kan du læse hvordan du gemmer og læser text-filer. Ellers kan du bare bruge en TStringList den har SaveToFile og LoadToFile funktioner indbygget!



Har også styr på det grundlæggende i OpenGL (ellers kunne jeg nok ikke skrive den artikel der ligger under C/C++).

Mit problem er bare, at som det ser ud nu, fra mit nuværende stadie, der jo er et begynderstadie, så kan jeg lære nok så mange nye smarte fancy funktioner, og stadig ærge mig over, at hver gang jeg skal indsætte et nyt objekt i min lille 3D verden, så skal jeg skrive det i kildekoden. Det gider jeg ikke.

Jeg ved hvordan jeg indlæser strings'ene osv.

Så nu splitter jeg spørgsmålet op, og vi antager, at jeg har 5 string-variabler.
De hedder S1, S2, S3, S4, S5, og ser sådan ud:

S1 := '1.0,1.0,1.0'; //x,y,z (1. punkt i koordinatsystemet sættes)
S2 := '2.0,2.0,2.0'; //x,y,z (2. punkt i koordinatsystemet sættes)
S3 := '3.0,3.0,3.0'; //x,y,z (3. punkt i koordinatsystemet sættes)
S4 := '4.0,4.0,4.0'; //x,y,z (4. punkt i koordinatsystemet sættes)


Okay, vi antager det er en firkant jeg har lavet, og jeg ved at ovenstående ikke danner nogen firkant, men gider altså ikke lige til at tænke over hvordan en firkant skal tegnes, så vi antager bare, at ovenstående danner en firkant.

Nu tilføjer jeg så en 5. og den ser sådan ud:

S5 := 'blue';

Så det kommer til at se sådan ud:

S1 := '1.0,1.0,1.0'; //x,y,z (1. punkt i koordinatsystemet sættes)
S2 := '2.0,2.0,2.0'; //x,y,z (2. punkt i koordinatsystemet sættes)
S3 := '3.0,3.0,3.0'; //x,y,z (3. punkt i koordinatsystemet sættes)
S4 := '4.0,4.0,4.0'; //x,y,z (4. punkt i koordinatsystemet sættes)
S5 := 'blue'; //Sæt farven til "blå".

Det jeg så vil have er, at jeg i forvejen et sted der i min "main code" altså der hvor jeg sådan arbejder rigtigt (der hvor man tegner objekterne) har defineret at der skal være en firkant.
I denne kodeblok skal S1 - S4 indsættes som koordinater for at danne denne firkant.
S5 skal udfylde firkanten med en given farve. Altså "HVIS S5 = 'blue' SÅ Udfyld Firkanten med Farven "Blå".



Du har defineret V1, V2 og V3 som Integer... hvorfor det? Man arbejder da i floating points i OpenGL!



Hvis du kigger godt efter er de Integer ikke direkte til at definere koordinater med, men til at finde de rette koordinater i VertexArrayen!




Kan du ikke komme med et konkret eksempel? Ellers forstår jeg det simpelthen ikke....



Jeg glemte lige at fortælle hvordan filformatet ser ud:
Fold kodeboks ind/udKode 


/Michael.


[Redigeret d. 02/12-03 22:28:50 af Michael Skovslund]



Under koden:

F.Delimiter := ASeperator;

skriver den:

Undecleared Identifier 'Delimeter'.

Samt Undecleard Identifier 'DelimitedText'.





<< < 12 > >>
t