From 701e35759004695103a51aeb35b568f8512e9035 Mon Sep 17 00:00:00 2001 From: dpethes Date: Tue, 28 Jul 2020 14:45:10 +0200 Subject: [PATCH] model viewer: plug memleaks --- model_viewer/hob_mesh.pas | 63 ++++++++++++++++++++++------------- model_viewer/model_viewer.lpi | 3 ++ model_viewer/model_viewer.pas | 8 ++--- rs_units/hob_parser.pas | 19 +++++++++++ 4 files changed, 66 insertions(+), 27 deletions(-) diff --git a/model_viewer/hob_mesh.pas b/model_viewer/hob_mesh.pas index fb0b96b..bf8d7e0 100644 --- a/model_viewer/hob_mesh.pas +++ b/model_viewer/hob_mesh.pas @@ -66,9 +66,9 @@ type _materials: TMaterialArray; _objects: TRenderObjectList; _current_robject: TRenderObject; + _model_loaded: boolean; - _hmt: THmtFile; - _hmt_loaded: boolean; + procedure DeallocObjects; procedure HmtRead(stream: TMemoryStream); procedure HobRead(stream: TMemoryStream); procedure HobTransform(const hobject: THobObject); @@ -77,7 +77,7 @@ type constructor Create; destructor Destroy; override; procedure Load(hob, hmt: TMemoryStream); - procedure InitGL; + procedure InitGL(hmt: THmtFile); procedure DrawGL(var opts: TRenderOpts); procedure ExportObj(const obj_name: string; const png_textures: boolean); end; @@ -111,7 +111,6 @@ var current_block_vertices: TVertexList; triangle: TTriangle; fg_idx: integer; - tris: TTriangleList; function InitVertex(face: THobFace; offset: integer): TTriangle; var @@ -160,15 +159,12 @@ begin robjpart.vertices.PushBack(v); current_block_vertices.PushBack(v); end; - tris := TTriangleList.Create; for i := 0 to fg.face_count - 1 do begin triangle := InitVertex(fg.faces[i], 0); - tris.PushBack(triangle); robjpart.triangles.PushBack(triangle); if fg.faces[i].ftype <> 3 then begin triangle := InitVertex(fg.faces[i], 2); - tris.PushBack(triangle); robjpart.triangles.PushBack(triangle); end; end; @@ -188,27 +184,31 @@ var hob: THobFile; begin hob := ParseHobFile(stream); - _objects.Clear; if hob.obj_count = 0 then exit; for i := 0 to hob.obj_count-1 do HobTransform(hob.objects[i]); + DeallocHob(hob); + //WriteLn('vertices: ', _vertices.Size); //WriteLn('faces (triangulated): ', _triangles.Count); end; procedure TModel.HmtRead(stream: TMemoryStream); +var + hmt: THmtFile; + procedure SetTexByName (var mat: TMaterial; const name: string); var i: integer; tex: THmtTexture; begin mat.has_texture := false; - for i := 0 to _hmt.texture_count - 1 do - if _hmt.textures[i].name_string = name then begin - tex := _hmt.textures[i]; + for i := 0 to hmt.texture_count - 1 do + if hmt.textures[i].name_string = name then begin + tex := hmt.textures[i]; mat.bpp := 24; if tex.image.type_ = 3 then @@ -229,16 +229,32 @@ var i: integer; name: string; begin - _hmt := ParseHmtFile(stream); - SetLength(_materials, _hmt.material_count); - for i := 0 to _hmt.material_count - 1 do begin - name := _hmt.materials[i].name_string; //preserve for obj/mtl export + hmt := ParseHmtFile(stream); + SetLength(_materials, hmt.material_count); + for i := 0 to hmt.material_count - 1 do begin + name := hmt.materials[i].name_string; //preserve for obj/mtl export _materials[i].name := name; writeln('material: ', name); SetTexByName(_materials[i], name); end; + InitGL(hmt); + DeallocHmt(hmt); end; +procedure TModel.DeallocObjects; +var + i, k: integer; +begin + if _objects.Size = 0 then + exit; + for i := 0 to _objects.Size - 1 do begin + for k := 0 to _objects[i].parts.Size - 1 do begin + _objects[i].parts[k].vertices.Free; + _objects[i].parts[k].triangles.Free; + end; + _objects[i].parts.Free; + end; +end; constructor TModel.Create; begin @@ -248,20 +264,23 @@ end; destructor TModel.Destroy; begin inherited Destroy; + DeallocObjects; _materials := nil; _objects.Free; end; procedure TModel.Load(hob, hmt: TMemoryStream); begin - if _hmt_loaded then - DeallocHmt(_hmt); + if _model_loaded then begin + DeallocObjects; + _objects.Clear; + end; WriteLn('Loading mesh file'); HobRead(hob); WriteLn('Loading material file'); HmtRead(hmt); - _hmt_loaded := true; + _model_loaded := true; end; procedure pnm_save(const fname: string; const p: pbyte; const w, h: integer); @@ -290,7 +309,7 @@ Begin CloseFile (f); end; -procedure TModel.InitGL; +procedure TModel.InitGL(hmt: THmtFile); procedure GenTexture(var mat: TMaterial); begin @@ -321,9 +340,7 @@ procedure TModel.InitGL; var i: integer; begin - if not _hmt_loaded then - exit; - for i := 0 to _hmt.material_count - 1 do begin + for i := 0 to hmt.material_count - 1 do begin if _materials[i].has_texture then GenTexture(_materials[i]); end; @@ -337,7 +354,7 @@ procedure TModel.DrawGL(var opts: TRenderOpts); mat: TMaterial; k: Integer; begin - if _hmt_loaded then begin + if _model_loaded then begin mat := _materials[tri.material_index]; if mat.has_texture then begin glEnable(GL_TEXTURE_2D); diff --git a/model_viewer/model_viewer.lpi b/model_viewer/model_viewer.lpi index bcc536c..988285e 100644 --- a/model_viewer/model_viewer.lpi +++ b/model_viewer/model_viewer.lpi @@ -152,6 +152,9 @@ + + + diff --git a/model_viewer/model_viewer.pas b/model_viewer/model_viewer.pas index 9cb4b49..ddd1dd9 100644 --- a/model_viewer/model_viewer.pas +++ b/model_viewer/model_viewer.pas @@ -262,7 +262,6 @@ begin g_model := TModel.Create; g_model.Load(hob, hmt); - g_model.InitGL; hob.Free; hmt.Free; @@ -598,13 +597,14 @@ begin //WindowScreenshot( surface^.w, surface^.h ); end; - WindowFree; - SDL_Quit; - +{$ifdef DEBUG} if g_model <> nil then g_model.Free; + WindowFree; + SDL_Quit; g_filelist.Free; g_rs_files.Free; rsdata.Free; +{$endif} end. diff --git a/rs_units/hob_parser.pas b/rs_units/hob_parser.pas index ec9c9bd..6835164 100644 --- a/rs_units/hob_parser.pas +++ b/rs_units/hob_parser.pas @@ -65,6 +65,7 @@ type end; function ParseHobFile(f: TMemoryStream): THobFile; +procedure DeallocHob(var h: THobFile); //************************************************************************************************** implementation @@ -348,5 +349,23 @@ begin result := hob; end; +procedure DeallocHob(var h: THobFile); +var + o: THobObject; + fg: THobFaceGroup; + i, k: Integer; +begin + for k := 0 to Length(h.objects) - 1 do begin + o := h.objects[k]; + for i := 0 to Length(o.object_parts) - 1 do begin + fg := o.object_parts[i]; + fg.vertices := nil; + fg.faces := nil; + end; + o.object_parts := nil; + end; + h.objects := nil; +end; + end.