•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the Pascal and Delphi section within the Software Development category of DaniWeb, a massive community of 422,790 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,385 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Pascal and Delphi advertiser: Programming Forums
Views: 1387 | Replies: 1
![]() |
| |
•
•
Join Date: Jan 2008
Posts: 1
Reputation:
Rep Power: 0
Solved Threads: 0
This is a 3DS max loader in Delphi6. The program always end with an access violation in memory, somwhere in the T3DObject.Create section, when it is called from an another class. (first occur in TChunk.Load3Data when AddObject is called) Why? How can it be solved?
===========================================================
===========================================================
unit Unit3DS_11;
interface
uses Windows, Classes;
type point = record
k:integer;
x,y,z,nx,ny,nz:Single;
end;
type face = record
a,b,c:integer;
end;
type T3DObject = class(TObject)
private
// Nothing here at moment
public
PointCount, FaceCount: Integer;
ObjectName:String;
p:array of point;
f:array of face;
constructor Create;
destructor Destroy; override;
procedure Draw;
end;
type TChunk = class(TObject)
private
function ReadObjectString:String;
public
Id: word;
iBytesReaded, ChunkLength : Integer;
iFileHandle, iFileLength, ObjCount:Integer;
Objects:array of T3DObject;
function ReadChunk: Integer;
function ReadBuffer(var Buffer; Count:Integer):Integer;
procedure AddObject(ObjNr: Integer);
procedure Load3Data;
constructor Create;
destructor Destroy; override;
end;
type T3DModel = class(TObject)
private
ObjCount:Integer;
RootChunk:TChunk;
Objects:array of T3DObject;
public
constructor Create;
destructor Destroy; override;
procedure LoadFromFile(const FileName:string);
procedure Clone3Data;
procedure Draw;
end;
implementation
uses SysUtils, OpenGL;
constructor T3DObject.Create;
begin
inherited;
ObjectName:='';
PointCount:=0; FaceCount:=0;
p:=nil;
f:=nil;
end;
destructor T3DObject.Destroy;
begin
Finalize(p);
Finalize(f);
inherited;
end;
procedure T3Dobject.Draw;
var i:integer;
begin
for i:=0 to FaceCount-1 do begin
glBegin(GL_POLYGON);
glVertex3f(p[f[i].a].x,p[f[i].a].y,p[f[i].a].z);
glVertex3f(p[f[i].b].x,p[f[i].b].y,p[f[i].b].z);
glVertex3f(p[f[i].c].x,p[f[i].c].y,p[f[i].c].z);
glEnd();
end; end;
constructor TChunk.Create;
begin
inherited;
iFileHandle:=0; iFileLength:=0; iBytesReaded:=0; ObjCount:=0; ChunkLength:=0;
Id:=0;
Objects:=nil;
end;
destructor TChunk.Destroy;
begin
Finalize(Objects);
inherited;
end;
function TChunk.ReadChunk: Integer;
begin
iBytesReaded:=FileRead(iFileHandle, Id, 2);
iBytesReaded:=iBytesReaded + FileRead(iFileHandle, ChunkLength, 4);
Result:=iBytesReaded;
end;
function TChunk.ReadBuffer(var Buffer; Count: Integer): Integer;
begin
Result:=FileRead(iFileHandle, Buffer, Count);
iBytesReaded:=iBytesReaded + Result;
end;
function TChunk.ReadObjectString:String;
var //S:String;
C:Char;
i:integer;
SStr:ShortString;
begin
C:=#255; i:=0;
while (C<>#0) {and (i<=20)} do begin
iBytesReaded:=iBytesReaded+FileRead(iFileHandle, C, 1);
SStr[i+1]:=C;
Inc(i);
end;
SetLength(Result, I-1);
Move(SStr[1], Result[1], I-1);
end;
procedure TChunk.AddObject(ObjNr:Integer);
begin
SetLength(Objects,ObjNr);
Objects[ObjNr].Create;
end;
procedure TChunk.Load3Data;
var i,x: Integer;
begin
while (iBytesReaded < iFileLength) do begin
ReadChunk;
case Id of
$4D4D: begin
// MAIN CHUNK
// ShowMessage('Found $4D4D at: ' + IntToStr(iBytesReaded) + ' length: ' + IntToStr(ChunkLength));
end;
$3D3D: begin
// 3D EDITOR CHUNK
// ShowMessage('Found $3D3D at: ' + IntToStr(iBytesReaded) + ' length: ' + IntToStr(ChunkLength));
end;
$4000: begin
// OBJECT BLOCK
inc(ObjCount);
AddObject(ObjCount);
Objects[ObjCount].ObjectName:=ReadObjectString; // PROPERTY USE ???!!!
// ShowMessage(ObjectName);
end;
$4100: begin
// 3D Data Chunk (kb)
end;
$4110: begin // VERTICES LIST
with Objects[ObjCount] do begin
ReadBuffer(PointCount, 2);
SetLength(p,PointCount);
for i:=0 to PointCount-1 do begin
ReadBuffer(p[i].x,4);
ReadBuffer(p[i].y,4);
ReadBuffer(p[i].z,4);
end; end; end;
$4120: begin // FACES DESCRIPTION
with Objects[ObjCount] do begin
ReadBuffer(FaceCount, 2);
SetLength(f,FaceCount);
for i:=0 to FaceCount-1 do begin
ReadBuffer(f[i].a, 2);
ReadBuffer(f[i].b, 2);
ReadBuffer(f[i].c, 2);
ReadBuffer(x, 2);
end; end; end;
else
iBytesReaded:=FileSeek(iFileHandle,ChunkLength-6,1); end;
end; // while end;
end;
constructor T3DModel.Create;
begin
inherited;
ObjCount:=0;
//RootChunk:=nil;
Objects:=nil;
end;
destructor T3DModel.Destroy;
begin
Finalize(Objects);
inherited;
end;
procedure T3DModel.LoadFromFile(const FileName:string);
var iFileHandle, iFileLength: Integer;
begin
iFileHandle:=0; //iFileLength:=0;
try
iFileHandle := FileOpen(FileName, fmOpenRead);
finally
iFileLength := FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
RootChunk:=TChunk.Create;
RootChunk.iFileHandle:=iFileHandle;
RootChunk.iFileLength:=iFileLength;
RootChunk.Load3Data;
Clone3Data;
RootChunk.Free;
RootChunk.Destroy;
//ShowMessage('RootChunk Destroyed Successfully');
FileClose(iFileHandle);
end;
end;
procedure T3DModel.Clone3Data;
var i,j:integer;
begin
ObjCount:=RootChunk.ObjCount;
SetLength(Objects,ObjCount);
for i:=1 to ObjCount do begin
Objects[i].Create;
with Objects[i] do begin
PointCount:=RootChunk.Objects[i].PointCount;
FaceCount:=RootChunk.Objects[i].FaceCount;
SetLength(p,Objects[i].PointCount);
SetLength(f,Objects[i].FaceCount);
ObjectName:=RootChunk.Objects[i].ObjectName;
for j:=0 to PointCount-1 do p[j]:= RootChunk.Objects[i].p[j];
for j:=0 to FaceCount-1 do f[j]:= RootChunk.Objects[i].f[j];
end;
end;
end;
procedure T3DModel.Draw;
var i:integer;
begin
for i:=1 to ObjCount do Objects[i].Draw;
end;
end.===========================================================
•
•
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,875
Reputation:
Rep Power: 11
Solved Threads: 193
To be honest, I didn't want to look too hard at this (and I haven't) just because you didn't put your code in the proper tags.
[code=Delphi]
program hello;
begin
writeln( 'Hello, world!' )
end.
[/code]
becomes all nice and pretty, easy to read, and easy to select, copy, and paste for testing:
BTW, you don't actually have to explicitly assign '' or 0 or nil to anything in the constructor. The
At just a quick glance, it looks like you are trying to keep track of the objects with a counter. So when you say AddObject the first time it goes something like this:
The other problem is in part 3 there. You cannot just say
You must say
(that, or you must first use the
In general, the way you should handle this kind of thing (playing with dynamic arrays) is always to refer directly to the dynamic array for information about itself. You can do it thus:
This code also has the property that it will generate a proper exception on error.
If ever you want to know how many objects there are, use the
Also, in the destructor, don't just
There is no actual need to call
Hope this helps.
[code=Delphi]
program hello;
begin
writeln( 'Hello, world!' )
end.
[/code]
becomes all nice and pretty, easy to read, and easy to select, copy, and paste for testing:
Delphi Syntax (Toggle Plain Text)
program hello; begin writeln( 'Hello, world!' ) end.
BTW, you don't actually have to explicitly assign '' or 0 or nil to anything in the constructor. The
inherited; does that for you.At just a quick glance, it looks like you are trying to keep track of the objects with a counter. So when you say AddObject the first time it goes something like this:
- AddObject( 1 )
- setLength( Objects, 1 )
- Objects[ 1 ].create
The other problem is in part 3 there. You cannot just say
foo.createYou must say
foo := TFoo.create(that, or you must first use the
new procedure...).In general, the way you should handle this kind of thing (playing with dynamic arrays) is always to refer directly to the dynamic array for information about itself. You can do it thus:
Delphi Syntax (Toggle Plain Text)
procedure TChunk.AddObject; begin setLength( Objects, length( Objects ) +1 ); Objects[ high( Objects ) ] := T3DObject.create end;
If ever you want to know how many objects there are, use the
length function.Also, in the destructor, don't just
finalize( Objects ), as that doesn't bother to call each object's destructor, which means you've got a memory leak. Instead, make sure to free each Object: Delphi Syntax (Toggle Plain Text)
for n := 0 to high( Objects ) do Objects[ n ].free;
finalize or setlength( Objects, 0 ) or Objects := nil or whatever --the destructor does that for you since Objects is of the proper storage class: destroying the TChunk object will also destroy the member objects.Hope this helps.
![]() |
•
•
•
•
•
•
•
•
DaniWeb Pascal and Delphi Marketplace
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
- Delphi Onjects (Pascal and Delphi)
Other Threads in the Pascal and Delphi Forum
- Previous Thread: i want to read a particular file and searching for a particular word in that file
- Next Thread: delphi object casting



Hybrid Mode