Alpha IIMedlem sedan maj 20002 993 inlägg Ingen kommer säkert orka läsa igenom den här koden men men...
När jag till delar member variablerna i classen ett värde kraschar programmet med EAccessViolation. Det får man väl om man försöker använda ett objekt som man inte har skapat än? Men den här koden borde väl fungera, eller är jag blind??
unit ST3DMLoader;
interface
uses
OpenGL12,
Math3D,
SysUtils,
TGATexture,
MyFunctions;
type
TST3DM = class
private
m_DisplayList : GLuint;
m_NumMaterials : integer;
m_NumVertices : integer;
m_NumFaces : integer;
m_Materials : array of GLuint;
m_Vertices : array of TVertex;
m_Faces : array of TFace;
public
constructor CreateMesh(Filename: String);
procedure Draw();
end;
implementation
constructor TST3DM.CreateMesh(Filename: String);
var
F: Textfile;
currVert : integer;
currFace : integer;
I : integer;
J : integer;
S: String;
return: TStringArray;//array of string;
tmp: String;
begin
inherited Create();
//**************************************
//******* PARSE TEXT FILE **************
//**************************************
currVert := 0;
currFace := 0;
AssignFile(F, Filename);
Reset(F);
while not eof(F) do
begin
ReadLn(F, S);
if (Length(S)<1) or (S[1]='/') or (S[1]=#10) then continue;
Return := Explode(S, ' ');
if (S[1]='#') then
begin
if Return[0] = '#NUM_MATERIALS' then m_NumMaterials := StrToInt(Return[1]);
if Return[0] = '#NUM_VERTICES' then m_NumVertices := StrToInt(Return[1]);
if Return[0] = '#NUM_FACES' then m_NumFaces := StrToInt(Return[1]);
end else
if (Return[0]='material') then
begin
LoadTGA(Return[2], m_Materials[StrToInt(Return[1])], False);
end else
if (Return[0]='vert') then
begin
m_Vertices[currVert].X := StrToFloat(Return[1]);
m_Vertices[currVert].Y := StrToFloat(Return[2]);
m_Vertices[currVert].Z := StrToFloat(Return[3]);
m_Vertices[currVert].U := StrToFloat(Return[4]);
m_Vertices[currVert].V := StrToFloat(Return[5]);
m_Vertices[currVert].R := StrToFloat(Return[6]);
m_Vertices[currVert].G := StrToFloat(Return[7]);
m_Vertices[currVert].B := StrToFloat(Return[8]);
m_Vertices[currVert].A := StrToFloat(Return[9]);
Inc(CurrVert);
end else
if (Return[0]='face') then
begin
m_Faces[currFace].Material := StrToInt(Return[1]);
m_Faces[currFace].Vertices := StrToInt(Return[2]);
Inc(currFace);
end;
end;
CloseFile(F);
//**************************************
//******* MAKE DISPLAY LIST ************
//**************************************
m_DisplayList := glGenLists(1);
glNewList(m_DisplayList, GL_COMPILE);
currVert := 0;
for I := 0 to m_NumFaces do
begin
glBindTexture(GL_TEXTURE_2D, m_Materials[m_Faces[I].Material]);
glBegin(GL_QUADS);
for J := 0 to m_Faces[I].Vertices do
begin
glTexCoord2f(m_Vertices[currVert].U,m_Vertices[currVert].V);
glVertex3f(m_Vertices[currVert].X, m_Vertices[currVert].Y, m_Vertices[currVert].Z);
Inc(currVert);
end;
glEnd();
end;
glEndList();
end;
procedure TST3DM.Draw();
begin
glCallList(m_DisplayList);
end;
end.
Hej!
Jag tycker vid en hastig anblick att det ser ut som om du tappat ett "else begin" efter kontrollen av om raden du läser från filen innehåller något... Så här bör det nog vara:
constructor TST3DM.CreateMesh(Filename: String);
var
F: Textfile;
currVert : integer;
currFace : integer;
I : integer;
J : integer;
S: String;
return: TStringArray;//array of string;
tmp: String;
begin
inherited Create();
//**************************************
//******* PARSE TEXT FILE **************
//**************************************
currVert := 0;
currFace := 0;
AssignFile(F, Filename);
Reset(F);
while not eof(F) do
begin
ReadLn(F, S);
if (Length(S)<1) or (S[1]='/') or (S[1]=#10) then continue
[RED]else begin[/RED]
Return := Explode(S, ' ');
if (S[1]='#') then
begin
if Return[0] = '#NUM_MATERIALS' then m_NumMaterials := StrToInt(Return[1]);
if Return[0] = '#NUM_VERTICES' then m_NumVertices := StrToInt(Return[1]);
if Return[0] = '#NUM_FACES' then m_NumFaces := StrToInt(Return[1]);
end else
if (Return[0]='material') then
begin
LoadTGA(Return[2], m_Materials[StrToInt(Return[1])], False);
end else
if (Return[0]='vert') then
begin
m_Vertices[currVert].X := StrToFloat(Return[1]);
m_Vertices[currVert].Y := StrToFloat(Return[2]);
m_Vertices[currVert].Z := StrToFloat(Return[3]);
m_Vertices[currVert].U := StrToFloat(Return[4]);
m_Vertices[currVert].V := StrToFloat(Return[5]);
m_Vertices[currVert].R := StrToFloat(Return[6]);
m_Vertices[currVert].G := StrToFloat(Return[7]);
m_Vertices[currVert].B := StrToFloat(Return[8]);
m_Vertices[currVert].A := StrToFloat(Return[9]);
Inc(CurrVert);
end else
if (Return[0]='face') then
begin
m_Faces[currFace].Material := StrToInt(Return[1]);
m_Faces[currFace].Vertices := StrToInt(Return[2]);
Inc(currFace);
end;
[RED]end[/RED]
end;
CloseFile(F);
//**************************************
//******* MAKE DISPLAY LIST ************
//**************************************
m_DisplayList := glGenLists(1);
glNewList(m_DisplayList, GL_COMPILE);
currVert := 0;
for I := 0 to m_NumFaces do
begin
glBindTexture(GL_TEXTURE_2D, m_Materials[m_Faces[I].Material]);
glBegin(GL_QUADS);
for J := 0 to m_Faces[I].Vertices do
begin
glTexCoord2f(m_Vertices[currVert].U,m_Vertices[currVert].V);
glVertex3f(m_Vertices[currVert].X, m_Vertices[currVert].Y, m_Vertices[currVert].Z);
Inc(currVert);
end;
glEnd();
end;
glEndList();
end;
Alpha IIMedlem sedan maj 20002 993 inlägg Det ska nog inte vara något else eftersom continue gör att den struntar i koden efter och börjar om i nästa slinga elelr vad man säger :)
Oj, du har rätt!! :r
Inträffar AccVion när du anropar konstruktorn? Kan du inte debugga dig fram till exakt vilken rad som går snett? Det finns ett antal saker som kan gå fel...
Funktionen Explode har du ju skrivit själv, ser jag i en annan tråd, så den returnerar väl garanterat en array med tio element? Annars blir det garanterat fel om man försöker accessa element 9 i en array som bara innehåller tre element...
Vad gör LoadTGA? Vad gör glGenList och glNewList, etc...
Lite debugging rekommenderas alltså! :OO
jtMedlem sedan juni 2000350 inlägg Du använder dynamiska arrayer tex "m_Faces : array of TFace;" det verkar inte som du sätter någon längd på dessa. Om TFace är en klass så måste du även skapa instanser av den. Dessa fel kan nog resultera i det felmeddelande du får. Har inte studerat koden i detalj så jag kan säkert ha missat något.
typ
SetLength(m_Faces, 10);
for i := Low(m_Faces) to High(m_Faces) do
m_Faces := TFace.Create()
Alpha IIMedlem sedan maj 20002 993 inlägg Det är inte det som blir fel!
Det är på varje rad som en variabel tilldelas ett värde som det blie AccesViolation, ändrade också så att jag sätter längden äen om det inte blev ngn skillnad :(
Alpha IIMedlem sedan maj 20002 993 inlägg
agneta_rung skrev:
Oj, du har rätt!! :r
Inträffar AccVion när du anropar konstruktorn? Kan du inte debugga dig fram till exakt vilken rad som går snett? Det finns ett antal saker som kan gå fel...
Funktionen Explode har du ju skrivit själv, ser jag i en annan tråd, så den returnerar väl garanterat en array med tio element? Annars blir det garanterat fel om man försöker accessa element 9 i en array som bara innehåller tre element...
Vad gör LoadTGA? Vad gör glGenList och glNewList, etc...
Lite debugging rekommenderas alltså! :OO
JAg har försökt att debgga :l
LoadTGA, en funktion som laddar en TGA textur till en GLuint, glGenList.. um hur ska man förklara... ställer in så att man kan lagra 2 "displatlists" i en GLuint, glNewList ställer in värdet i en displaylist.... massa OpenGL tjafs alltså :)
jtMedlem sedan juni 2000350 inlägg
Alpha II skrev:
Det är inte det som blir fel!
hmm hur vet du det?
Testa följande kod
var
test: array of integer;
begin
test[0] := 1;
end;
Får du något felmmedelande?
Alpha IIMedlem sedan maj 20002 993 inlägg men även om jag tilldelar m_NumFaces ngt så blir det ju fel!
jtMedlem sedan juni 2000350 inlägg
Alpha II skrev:
men även om jag tilldelar m_NumFaces ngt så blir det ju fel!
Menar du att det blir fel på raden där du tilldelar m_NumFaces ett värde?
Det räker ju inte att tilldela m_NumFaces något du måste göra följande för de dynamiska arrayer du använder.
if Return\[0\] = '#NUM_MATERIALS' then
begin
m_NumMaterials := StrToInt(Return\[1\]);
SetLength(m_Materials, m_NumMaterials);
end;
Koden upprepas även för arrayerna m_Vertices och m_Faces.
Är någon av typerna GLuint, TVertex, TFace klasser måste även objekten skapas.
tex
for i := Low(m_Faces) to High(m_Faces) do
m_Faces := TFace.Create
Alpha IIMedlem sedan maj 20002 993 inlägg Jag har skrivit som du gjort.. har bara glömt att uppdatera koden, men det fungerar ändå inte. Och det är så att om jag tilldelar tillexpel m_NumFaces blir det AccessViloation men inte om jag använder en variabel deklarerad i construktorn.
Konstigt :q
Alpha IIMedlem sedan maj 20002 993 inlägg TVertex och TFace är records jag har gjort. GLuint är en unisgned integer som finns i OpenGL. Behövs alltså inte skapas..
Ska jag posta koden så ni får testa kompilera?
jtMedlem sedan juni 2000350 inlägg
Alpha II skrev:
Ska jag posta koden så ni får testa kompilera?
Visst, testar bara om jag slipper installera något.
Return := Explode(S, ' ');
Om du lägger till koden nedan(efter raden ovan)vad får du för meddelande?
if Return <> Nil then
ShowMessage(IntToStr(High(Return)))
else
ShowMEssage('Nil');
Alpha IIMedlem sedan maj 20002 993 inlägg Finns säkert 1000 bättre sätt att ladda 3D modeller, men jag har aldrig gjort det själv, bara använt färdig kod för att ladda 3ds filer.
jtMedlem sedan juni 2000350 inlägg Jag lyckades inte köra programmet men det beror nog på att jag inte har OpenGL korrekt installerat.
Men jag kollade lite snabbt i koden och hittade ett fel som antagligen gör att det inte funkar.
I Loader.dpr har du följande rad 70
obj3D.CreateMesh('Data\Meshes\QUAD.ST3DM');
Byt till denna rad
obj3D := TST3DM.CreateMesh('Data\Meshes\QUAD.ST3DM');
Nu kommer det nog att gå bättre.
Alpha IIMedlem sedan maj 20002 993 inlägg Ja det fungerar tack :)
Men tyvärr verkar det vara lite fel på min parser kod :(
Alpha IIMedlem sedan maj 20002 993 inlägg nu funger allt (vad jag har märkt!) :D
Men hur ska jag få tex 3DS Max att spara mina filer?
Så här ser dom ut:
#NUM_MATERIALS 0
#NUM_VERTICES 5
#NUM_FACES 1
//material_# location\filename.tga
material 0 Data\gfx\square.tga
//vert x y z u v r g b a
vert 1,0 -1,0 0,0 1,0 0,0 1,0 0,0 0,0 1,0
vert -1,0 -1,0 0,0 0,0 0,0 0,0 1,0 0,0 1,0
vert -1,0 1,0 0,0 0,0 1,0 0,0 0,0 1,0 1,0
vert 1,0 1,0 0,0 1,0 1,0 1,5 0,5 1,5 1,0
//face [MATERIAL#] [VERTICES]
face 0 4