implemented txd read/write and basic d3d8 native textures

This commit is contained in:
aap 2015-09-13 20:23:22 +02:00
parent 2671141370
commit b39d9d2b89
7 changed files with 575 additions and 93 deletions

View File

@ -100,6 +100,41 @@ unlockVertices(void *vertexBuffer)
#endif
}
void*
createTexture(int32 width, int32 height, int32 levels, uint32 format)
{
#ifdef RW_D3D9
IDirect3DTexture9 *tex;
device->CreateTexture(width, height, levels, 0,
(D3DFORMAT)format, D3DPOOL_MANAGED, &tex, NULL);
return tex;
#else
assert(0 && "only supported with RW_D3D9");
#endif
}
uint8*
lockTexture(void *texture, int32 level)
{
#ifdef RW_D3D9
IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture;
D3DLOCKED_RECT lr;
tex->LockRect(level, &lr, 0, 0);
return (uint8*)lr.pBits;
#else
assert(0 && "only supported with RW_D3D9");
#endif
}
void
unlockTexture(void *texture, int32 level)
{
#ifdef RW_D3D9
IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture;
tex->UnlockRect(level);
#endif
}
void
deleteObject(void *object)
{
@ -113,5 +148,188 @@ deleteObject(void *object)
#endif
}
// Native Raster
int32 nativeRasterOffset;
void
makeNativeRaster(Raster *raster)
{
static uint32 formatMap[] = {
0,
D3DFMT_A1R5G5B5,
D3DFMT_R5G6B5,
D3DFMT_A4R4G4B4,
D3DFMT_L8,
D3DFMT_A8R8G8B8,
D3DFMT_X8R8G8B8,
0, 0, 0,
D3DFMT_X1R5G5B5,
0, 0, 0, 0, 0
};
static bool32 alphaMap[] = {
0,
1,
0,
1,
0,
1,
0,
0, 0, 0,
0,
0, 0, 0, 0, 0
};
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
if(raster->flags & 0x80)
return;
uint32 format = formatMap[(raster->format >> 8) & 0xF];
ras->format = 0;
ras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF];
ras->texture = createTexture(raster->width, raster->width,
raster->format & Raster::MIPMAP ? 0 : 1,
format);
assert((raster->flags & (Raster::PAL4 | Raster::PAL8)) == 0);
}
uint8*
lockRaster(Raster *raster, int32 level)
{
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
return lockTexture(ras->texture, level);
}
void
unlockRaster(Raster *raster, int32 level)
{
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
unlockTexture(ras->texture, level);
}
int32
getNumLevels(Raster *raster)
{
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
#ifdef RW_D3D9
IDirect3DTexture9 *tex = (IDirect3DTexture9*)ras->texture;
return tex->GetLevelCount();
#else
assert(0 && "only supported with RW_D3D9");
#endif
}
// stolen from d3d8to9
uint32
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
{
#define D3DFMT_W11V11U10 65
switch(format){
default:
case D3DFMT_UNKNOWN:
return 0;
case D3DFMT_R3G3B2:
case D3DFMT_A8:
case D3DFMT_P8:
case D3DFMT_L8:
case D3DFMT_A4L4:
return width * height * depth;
case D3DFMT_R5G6B5:
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
case D3DFMT_A4R4G4B4:
case D3DFMT_A8R3G3B2:
case D3DFMT_X4R4G4B4:
case D3DFMT_A8P8:
case D3DFMT_A8L8:
case D3DFMT_V8U8:
case D3DFMT_L6V5U5:
case D3DFMT_D16_LOCKABLE:
case D3DFMT_D15S1:
case D3DFMT_D16:
case D3DFMT_UYVY:
case D3DFMT_YUY2:
return width * 2 * height * depth;
case D3DFMT_R8G8B8:
return width * 3 * height * depth;
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
case D3DFMT_A2B10G10R10:
case D3DFMT_A8B8G8R8:
case D3DFMT_X8B8G8R8:
case D3DFMT_G16R16:
case D3DFMT_X8L8V8U8:
case D3DFMT_Q8W8V8U8:
case D3DFMT_V16U16:
case D3DFMT_W11V11U10:
case D3DFMT_A2W10V10U10:
case D3DFMT_D32:
case D3DFMT_D24S8:
case D3DFMT_D24X8:
case D3DFMT_D24X4S4:
return width * 4 * height * depth;
case D3DFMT_DXT1:
assert(depth <= 1);
return ((width + 3) >> 2) * ((height + 3) >> 2) * 8;
case D3DFMT_DXT2:
case D3DFMT_DXT3:
case D3DFMT_DXT4:
case D3DFMT_DXT5:
assert(depth <= 1);
return ((width + 3) >> 2) * ((height + 3) >> 2) * 16;
}
}
int32
getLevelSize(Raster *raster, int32 level)
{
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
#ifdef RW_D3D9
IDirect3DTexture9 *tex = (IDirect3DTexture9*)ras->texture;
D3DSURFACE_DESC desc;
tex->GetLevelDesc(level, &desc);
return calculateTextureSize(desc.Width, desc.Height, 1, desc.Format);
#else
assert(0 && "only supported with RW_D3D9");
#endif
}
static void*
createNativeRaster(void *object, int32 offset, int32)
{
D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset);
raster->texture = NULL;
raster->palette = NULL;
raster->format = 0;
raster->hasAlpha = 0;
return object;
}
static void*
destroyNativeRaster(void *object, int32 offset, int32)
{
// TODO:
return object;
}
static void*
copyNativeRaster(void *dst, void *, int32 offset, int32)
{
D3dRaster *raster = PLUGINOFFSET(D3dRaster, dst, offset);
raster->texture = NULL;
raster->palette = NULL;
raster->format = 0;
raster->hasAlpha = 0;
return dst;
}
void
registerNativeRaster(void)
{
nativeRasterOffset = Raster::registerPlugin(sizeof(D3dRaster),
0x12340000 | PLATFORM_D3D9,
createNativeRaster,
destroyNativeRaster,
copyNativeRaster);
}
}
}

View File

@ -380,5 +380,139 @@ makeMatFXPipeline(void)
return pipe;
}
// Native Texture and Raster
Texture*
readNativeTexture(Stream *stream)
{
static uint32 dxtMap[] = {
0x31545844, // DXT1
0x32545844, // DXT2
0x33545844, // DXT3
0x34545844, // DXT4
0x35545844, // DXT5
};
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
assert(stream->readU32() == PLATFORM_D3D8);
Texture *tex = new Texture;
// Texture
tex->filterAddressing = stream->readU32();
stream->read(tex->name, 32);
stream->read(tex->mask, 32);
// Raster
int32 format = stream->readI32();
bool32 hasAlpha = stream->readI32();
int32 width = stream->readU16();
int32 height = stream->readU16();
int32 depth = stream->readU8();
int32 numLevels = stream->readU8();
int32 type = stream->readU8();
int32 compression = stream->readU8();
Raster *raster;
D3dRaster *ras;
if(compression){
raster = new Raster(width, height, depth, format | type | 0x80, PLATFORM_D3D8);
ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
ras->format = dxtMap[compression-1];
ras->hasAlpha = hasAlpha;
ras->texture = createTexture(raster->width, raster->width,
raster->format & Raster::MIPMAP ? 0 : 1,
ras->format);
raster->flags &= ~0x80;
}else
raster = new Raster(width, height, depth, format | type, PLATFORM_D3D8);
tex->raster = raster;
// TODO: check if format supported and convert if necessary
if(raster->format & (Raster::PAL4 | Raster::PAL8))
assert(0 && "don't support palettes");
uint32 size;
uint8 *data;
for(uint32 i = 0; i < numLevels; i++){
size = stream->readU32();
if(i < raster->getNumLevels()){
data = raster->lock(i);
stream->read(data, size);
raster->unlock(i);
}else
stream->seek(size);
}
tex->streamReadPlugins(stream);
return tex;
}
void
writeNativeTexture(Texture *tex, Stream *stream)
{
int32 chunksize = getSizeNativeTexture(tex);
int32 plgsize = tex->streamGetPluginSize();
writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize);
stream->writeU32(PLATFORM_D3D8);
// Texture
stream->writeU32(tex->filterAddressing);
stream->write(tex->name, 32);
stream->write(tex->mask, 32);
// Raster
Raster *raster = tex->raster;
D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
int32 numLevels = raster->getNumLevels();
stream->writeI32(raster->format);
stream->writeI32(ras->hasAlpha);
stream->writeU16(raster->width);
stream->writeU16(raster->height);
stream->writeU8(raster->depth);
stream->writeU8(numLevels);
stream->writeU8(raster->type);
int32 compression = 0;
if(ras->format)
switch(ras->format){
case 0x31545844: // DXT1
compression = 1;
break;
case 0x32545844: // DXT2
compression = 2;
break;
case 0x33545844: // DXT3
compression = 3;
break;
case 0x34545844: // DXT4
compression = 4;
break;
case 0x35545844: // DXT5
compression = 5;
break;
}
stream->writeU8(compression);
uint32 size;
uint8 *data;
for(uint32 i = 0; i < numLevels; i++){
size = getLevelSize(raster, i);
stream->writeU32(size);
data = raster->lock(i);
stream->write(data, size);
raster->unlock(i);
}
tex->streamWritePlugins(stream);
}
uint32
getSizeNativeTexture(Texture *tex)
{
uint32 size = 12 + 72 + 16;
int32 levels = tex->raster->getNumLevels();
for(int32 i = 0; i < levels; i++)
size += 4 + getLevelSize(tex->raster, i);
size += 12 + tex->streamGetPluginSize();
return size;
}
}
}

View File

@ -9,6 +9,8 @@
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwd3d.h"
#include "rwd3d8.h"
using namespace std;
@ -28,8 +30,10 @@ TexDictionary::TexDictionary(void)
void
TexDictionary::add(Texture *tex)
{
tex->next = this->first;
this->first = tex;
Texture **tp;
for(tp = &this->first; *tp; tp = &(*tp)->next)
;
*tp = tex;
}
Texture*
@ -41,6 +45,49 @@ TexDictionary::find(const char *name)
return NULL;
}
TexDictionary*
TexDictionary::streamRead(Stream *stream)
{
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
int32 numTex = stream->readI16();
stream->readI16(); // some platform id (1 = d3d8, 2 = d3d9, 5 = opengl,
// 6 = ps2, 8 = xbox)
TexDictionary *txd = new TexDictionary;
for(int32 i = 0; i < numTex; i++){
assert(findChunk(stream, ID_TEXTURENATIVE, NULL, NULL));
Texture *tex = Texture::streamReadNative(stream);
txd->add(tex);
}
txd->streamReadPlugins(stream);
return txd;
}
void
TexDictionary::streamWrite(Stream *stream)
{
writeChunkHeader(stream, ID_TEXDICTIONARY, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, 4);
int32 numTex = 0;
for(Texture *tex = this->first; tex; tex = tex->next)
numTex++;
stream->writeI16(numTex);
stream->writeI16(0);
for(Texture *tex = this->first; tex; tex = tex->next)
tex->streamWriteNative(stream);
this->streamWritePlugins(stream);
}
uint32
TexDictionary::streamGetSize(void)
{
uint32 size = 12 + 4;
Texture *tex;
for(Texture *tex = this->first; tex; tex = tex->next)
size += 12 + tex->streamGetSizeNative();
size += 12 + this->streamGetPluginSize();
return size;
}
//
// Texture
//
@ -91,7 +138,7 @@ Texture::read(const char *name, const char *mask)
raster = Raster::createFromImage(img);
delete img;
}else
raster = new Raster;
raster = new Raster(0, 0, 0, 0x80);
tex->raster = raster;
if(currentTexDictionary && img)
currentTexDictionary->add(tex);
@ -158,6 +205,33 @@ Texture::streamGetSize(void)
return size;
}
Texture*
Texture::streamReadNative(Stream *stream)
{
if(rw::platform == PLATFORM_D3D8)
return d3d8::readNativeTexture(stream);
assert(0 && "unsupported platform");
return NULL;
}
void
Texture::streamWriteNative(Stream *stream)
{
if(this->raster->platform == PLATFORM_D3D8)
d3d8::writeNativeTexture(this, stream);
else
assert(0 && "unsupported platform");
}
uint32
Texture::streamGetSizeNative(void)
{
if(this->raster->platform == PLATFORM_D3D8)
return d3d8::getSizeNativeTexture(this);
assert(0 && "unsupported platform");
return 0;
}
//
// Image
//
@ -443,12 +517,19 @@ writeTGA(Image *image, const char *filename)
// Raster
//
Raster::Raster(void)
Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{
this->type = 0;
this->width = this->height = this->depth = this->stride = 0;
this->format = 0;
this->platform = platform ? platform : rw::platform;
this->type = format & 0x7;
this->flags = format & 0xF8;
this->format = format & 0xFF00;
this->width = width;
this->height = height;
this->depth = depth;
this->texels = this->palette = NULL;
if(this->platform == PLATFORM_D3D8 ||
this->platform == PLATFORM_D3D9)
d3d::makeNativeRaster(this);
this->constructPlugins();
}
@ -459,30 +540,58 @@ Raster::~Raster(void)
delete[] this->palette;
}
uint8*
Raster::lock(int32 level)
{
if(this->platform == PLATFORM_D3D8 ||
this->platform == PLATFORM_D3D9)
return d3d::lockRaster(this, level);
assert(0 && "unsupported raster platform");
}
void
Raster::unlock(int32 level)
{
if(this->platform == PLATFORM_D3D8 ||
this->platform == PLATFORM_D3D9)
d3d::unlockRaster(this, level);
else
assert(0 && "unsupported raster platform");
}
int32
Raster::getNumLevels(void)
{
if(this->platform == PLATFORM_D3D8 ||
this->platform == PLATFORM_D3D9)
return d3d::getNumLevels(this);
assert(0 && "unsupported raster platform");
return 1;
}
// BAD BAD BAD BAD
Raster*
Raster::createFromImage(Image *image)
{
Raster *raster = new Raster;
raster->type = 4;
raster->width = image->width;
raster->stride = image->stride;
raster->height = image->height;
raster->depth = image->depth;
raster->texels = raster->palette = NULL;
if(raster->depth == 32)
raster->format = Raster::C8888;
else if(raster->depth == 24)
raster->format = Raster::C888;
else if(raster->depth == 16)
raster->format = Raster::C1555;
else if(raster->depth == 8)
raster->format = Raster::PAL8 | Raster::C8888;
else if(raster->depth == 4)
raster->format = Raster::PAL4 | Raster::C8888;
else{
delete raster;
assert(0 && "unsupported atm");
int32 format;
// TODO: make that into a function
if(image->depth == 32)
format = Raster::C8888;
else if(image->depth == 24)
format = Raster::C888;
else if(image->depth == 16)
format = Raster::C1555;
else if(image->depth == 8)
format = Raster::PAL8 | Raster::C8888;
else if(image->depth == 4)
format = Raster::PAL4 | Raster::C8888;
else
return NULL;
}
Raster *raster = new Raster(image->width, image->height,
image->depth, format | 4 | 0x80);
raster->stride = image->stride;
raster->texels = new uint8[raster->stride*raster->height];
memcpy(raster->texels, image->pixels, raster->stride*raster->height);
if(image->palette){

View File

@ -65,7 +65,28 @@ void unlockIndices(void *indexBuffer);
void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool);
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
void unlockVertices(void *vertexBuffer);
void *createTexture(int32 width, int32 height, int32 levels, uint32 format);
uint8 *lockTexture(void *texture, int32 level);
void unlockTexture(void *texture, int32 level);
void deleteObject(void *object);
// Native Raster
struct D3dRaster {
void *texture; // IDirect3DTexture9
void *palette;
uint32 format;
bool32 hasAlpha;
};
extern int32 nativeRasterOffset;
void makeNativeRaster(Raster *raster);
uint8 *lockRaster(Raster *raster, int32 level);
void unlockRaster(Raster *raster, int32 level);
int32 getNumLevels(Raster *raster);
int32 getLevelSize(Raster *raster, int32 level);
void registerNativeRaster(void);
}
}

View File

@ -52,5 +52,11 @@ ObjPipeline *makeSkinPipeline(void);
ObjPipeline *makeMatFXPipeline(void);
// Native Texture and Raster
Texture *readNativeTexture(Stream *stream);
void writeNativeTexture(Texture *tex, Stream *stream);
uint32 getSizeNativeTexture(Texture *tex);
}
}

View File

@ -97,30 +97,36 @@ void writeTGA(Image *image, const char *filename);
struct Raster : PluginBase<Raster>
{
int32 platform;
int32 type; // hardly used
int32 flags;
int32 format;
int32 width, height, depth;
int32 stride;
int32 format;
uint8 *texels;
uint8 *palette;
Raster(void);
Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0);
~Raster(void);
static Raster *createFromImage(Image *image);
uint8 *lock(int32 level);
void unlock(int32 level);
int32 getNumLevels(void);
enum Format {
DEFAULT = 0,
C1555 = 0x100,
C565 = 0x200,
C4444 = 0x300,
LUM8 = 0x400,
C8888 = 0x500,
C888 = 0x600,
D16 = 0x700,
D24 = 0x800,
D32 = 0x900,
C555 = 0xa00,
DEFAULT = 0,
C1555 = 0x0100,
C565 = 0x0200,
C4444 = 0x0300,
LUM8 = 0x0400,
C8888 = 0x0500,
C888 = 0x0600,
D16 = 0x0700,
D24 = 0x0800,
D32 = 0x0900,
C555 = 0x0A00,
AUTOMIPMAP = 0x1000,
PAL8 = 0x2000,
PAL4 = 0x4000,
@ -147,6 +153,9 @@ struct Texture : PluginBase<Texture>
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
static Texture *read(const char *name, const char *mask);
static Texture *streamReadNative(Stream *stream);
void streamWriteNative(Stream *stream);
uint32 streamGetSizeNative(void);
enum FilterMode {
NEAREST = 1,
@ -408,13 +417,16 @@ private:
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
};
struct TexDictionary
struct TexDictionary : PluginBase<Texture>
{
Texture *first;
TexDictionary(void);
void add(Texture *tex);
Texture *find(const char *name);
static TexDictionary *streamRead(Stream *stream);
void streamWrite(Stream *stream);
uint32 streamGetSize(void);
};
struct Animation;

View File

@ -15,49 +15,10 @@ namespace rw {
namespace d3d {
int32 nativeRasterOffset;
struct D3d9Raster {
IDirect3DTexture9 *texture;
};
static void*
createNativeRaster(void *object, int32 offset, int32)
{
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, object, offset);
raster->texture = NULL;
return object;
}
static void*
destroyNativeRaster(void *object, int32 offset, int32)
{
// TODO:
return object;
}
static void*
copyNativeRaster(void *dst, void *, int32 offset, int32)
{
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, dst, offset);
raster->texture = NULL;
return dst;
}
void
registerNativeRaster(void)
{
nativeRasterOffset = Raster::registerPlugin(sizeof(D3d9Raster),
0x12340000 | PLATFORM_D3D9,
createNativeRaster,
destroyNativeRaster,
copyNativeRaster);
}
void
createTexture(Texture *tex)
{
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, tex->raster, nativeRasterOffset);
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
int32 w, h;
w = tex->raster->width;
h = tex->raster->height;
@ -79,6 +40,7 @@ createTexture(Texture *tex)
}
texture->UnlockRect(0);
raster->texture = texture;
raster->format = D3DFMT_A8R8G8B8;
}
void
@ -94,11 +56,11 @@ setTexture(Texture *tex)
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
};
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, tex->raster, nativeRasterOffset);
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
if(tex->raster){
if(raster->texture == NULL)
createTexture(tex);
Device->SetTexture(0, raster->texture);
Device->SetTexture(0, (IDirect3DTexture9*)raster->texture);
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
@ -216,23 +178,42 @@ void
initrw(void)
{
gta::attachPlugins();
rw::currentTexDictionary = new rw::TexDictionary;
rw::Image::setSearchPath("D:\\rockstargames\\ps2\\gta3\\MODELS\\gta3_archive\\txd_extracted\\;"
"D:\\rockstargames\\ps2\\gtavc\\MODELS\\gta3_archive\\txd_extracted\\;"
"D:\\rockstargames\\ps2\\gtasa\\models\\gta3_archive\\txd_extracted\\");
rw::d3d::registerNativeRaster();
rw::platform = rw::PLATFORM_D3D9;
// rw::currentTexDictionary = new rw::TexDictionary;
// rw::Image::setSearchPath("D:\\rockstargames\\ps2\\gta3\\MODELS\\gta3_archive\\txd_extracted\\;"
// "D:\\rockstargames\\ps2\\gtavc\\MODELS\\gta3_archive\\txd_extracted\\;"
// "D:\\rockstargames\\ps2\\gtasa\\models\\gta3_archive\\txd_extracted\\");
rw::platform = rw::PLATFORM_D3D8;
rw::d3d::device = Device;
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff";
if(0){
char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.txd";
rw::StreamFile in;
if(in.open(filename, "rb") == NULL){
MessageBox(0, "couldn't open file\n", 0, 0);
printf("couldn't open file\n");
}
rw::findChunk(&in, rw::ID_TEXDICTIONARY, NULL, NULL);
rw::TexDictionary *txd;
txd = rw::TexDictionary::streamRead(&in);
assert(txd);
in.close();
rw::currentTexDictionary = txd;
rw::StreamFile out;
out.open("out.txd", "wb");
txd->streamWrite(&out);
out.close();
}
char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff";
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\player.dff";
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\od_newscafe_dy.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\admiral.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\lae2_roads89.dff";
char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\casinoblock41_nt.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\casinoblock41_nt.dff";
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\cutscene_archive\\csremington92.dff";
// char *filename = "C:\\gtasa\\test\\hanger.dff";
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
@ -298,7 +279,8 @@ Setup()
camera->setNearFar(0.1f, 450.0f);
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
camera->setPosition(Vec3(0.0f, -70.0f, 0.0f));
// camera->setPosition(Vec3(0.0f, -70.0f, 0.0f));
camera->setPosition(Vec3(0.0f, -10.0f, 0.0f));
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
return true;