I've been thinking about waht you want to do and how about this.

Yuor TModel is really just a class which stores the data needed to render a model on the screen. So you, so you have a TModel which contains data such as vertex arrays, texture info etc. You could then derive you TGLModel or a TDXModel to handle rendering (athough I would say that you just need to implement that in a TRenderer and have on TRenderer for each API).

To load model formats make use of a TModelReader class, which takes a Stream or filename as a constructor parameter so you get

[pascal]
var Model: TModel;
var Reader: TModelReader;
begin

Model := TModel.Create;
Reader := T3DSModelReader.Create('Filename.3ds');
try
Model.LoadFromReader(Reader);
finally
Reader.Free;
end;

[/pascal]

You can then also have a TModelWriter as well to save the model data to a file


[pascal]
var Writer: TModelWriter;
begin

Writer := TOBJModelWriter.Create('Filename.obj');
try
Model.SaveToWriter(Writer);
finally
Writer.Free;
end;

[/pascal]

The TModelWriter and TModelReaders would have overloaded constructors to take filenames, or a Stream. You then have one public Load / Save method that you override in the descendent classes.

[pascal]
type

TModelReader = class
private
FData: TStream;
protected
property Data: TStream read FData;
public
// implement the create from file to call , createFromStream
constructor CreateFromFile(const AFilename: string);
// createfromStream simply sets the FData field to the incomming stream
constructor CreateFromStream(const AStream: TStream);

// override this method in descendent classes
function LoadModel: TModel; virtual; abstract;

end;

[/pascal]

So you end up with the TModel that has no loading or saving functionality, and the TModelReader and Writers that are specialists in loading or saving particular model formats.

You can also see how to can merge the Reader and Writers into one class that can handle both loading and savng

[pascal]
type

TModelReadWriter = class
private
FData: TStream;
protected
property Data: TStream read FData;
public
// implement the create from file to call , createFromStream
constructor CreateFromFile(const AFilename: string);
// createfromStream simply sets the FData field to the incomming stream
constructor CreateFromStream(const AStream: TStream);

// override this method in descendent classes
function LoadModel: TModel; virtual; abstract;
procedure SaveModel(const AModel: TModel); virtual; abstract;

end;

[/pascal]

In this case youd need to ensure that in the CreateFromFile when you created a TFileStream to pass it to CreateFromStream that you open the file for both read and write operations.

Just a few thoughts for you anyway. There are 101 ways to handle that problem you have.