mirror of
https://github.com/aap/librw.git
synced 2024-11-25 13:15:43 +00:00
implemented txd read/write and basic d3d8 native textures
This commit is contained in:
parent
2671141370
commit
b39d9d2b89
218
src/d3d.cpp
218
src/d3d.cpp
@ -100,6 +100,41 @@ unlockVertices(void *vertexBuffer)
|
|||||||
#endif
|
#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
|
void
|
||||||
deleteObject(void *object)
|
deleteObject(void *object)
|
||||||
{
|
{
|
||||||
@ -113,5 +148,188 @@ deleteObject(void *object)
|
|||||||
#endif
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
134
src/d3d8.cpp
134
src/d3d8.cpp
@ -380,5 +380,139 @@ makeMatFXPipeline(void)
|
|||||||
return pipe;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
163
src/image.cpp
163
src/image.cpp
@ -9,6 +9,8 @@
|
|||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
#include "rwobjects.h"
|
#include "rwobjects.h"
|
||||||
|
#include "rwd3d.h"
|
||||||
|
#include "rwd3d8.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -28,8 +30,10 @@ TexDictionary::TexDictionary(void)
|
|||||||
void
|
void
|
||||||
TexDictionary::add(Texture *tex)
|
TexDictionary::add(Texture *tex)
|
||||||
{
|
{
|
||||||
tex->next = this->first;
|
Texture **tp;
|
||||||
this->first = tex;
|
for(tp = &this->first; *tp; tp = &(*tp)->next)
|
||||||
|
;
|
||||||
|
*tp = tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture*
|
Texture*
|
||||||
@ -41,6 +45,49 @@ TexDictionary::find(const char *name)
|
|||||||
return NULL;
|
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
|
// Texture
|
||||||
//
|
//
|
||||||
@ -91,7 +138,7 @@ Texture::read(const char *name, const char *mask)
|
|||||||
raster = Raster::createFromImage(img);
|
raster = Raster::createFromImage(img);
|
||||||
delete img;
|
delete img;
|
||||||
}else
|
}else
|
||||||
raster = new Raster;
|
raster = new Raster(0, 0, 0, 0x80);
|
||||||
tex->raster = raster;
|
tex->raster = raster;
|
||||||
if(currentTexDictionary && img)
|
if(currentTexDictionary && img)
|
||||||
currentTexDictionary->add(tex);
|
currentTexDictionary->add(tex);
|
||||||
@ -158,6 +205,33 @@ Texture::streamGetSize(void)
|
|||||||
return size;
|
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
|
// Image
|
||||||
//
|
//
|
||||||
@ -443,12 +517,19 @@ writeTGA(Image *image, const char *filename)
|
|||||||
// Raster
|
// Raster
|
||||||
//
|
//
|
||||||
|
|
||||||
Raster::Raster(void)
|
Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform)
|
||||||
{
|
{
|
||||||
this->type = 0;
|
this->platform = platform ? platform : rw::platform;
|
||||||
this->width = this->height = this->depth = this->stride = 0;
|
this->type = format & 0x7;
|
||||||
this->format = 0;
|
this->flags = format & 0xF8;
|
||||||
|
this->format = format & 0xFF00;
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
this->depth = depth;
|
||||||
this->texels = this->palette = NULL;
|
this->texels = this->palette = NULL;
|
||||||
|
if(this->platform == PLATFORM_D3D8 ||
|
||||||
|
this->platform == PLATFORM_D3D9)
|
||||||
|
d3d::makeNativeRaster(this);
|
||||||
this->constructPlugins();
|
this->constructPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,30 +540,58 @@ Raster::~Raster(void)
|
|||||||
delete[] this->palette;
|
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*
|
||||||
Raster::createFromImage(Image *image)
|
Raster::createFromImage(Image *image)
|
||||||
{
|
{
|
||||||
Raster *raster = new Raster;
|
assert(0 && "unsupported atm");
|
||||||
raster->type = 4;
|
int32 format;
|
||||||
raster->width = image->width;
|
// TODO: make that into a function
|
||||||
raster->stride = image->stride;
|
if(image->depth == 32)
|
||||||
raster->height = image->height;
|
format = Raster::C8888;
|
||||||
raster->depth = image->depth;
|
else if(image->depth == 24)
|
||||||
raster->texels = raster->palette = NULL;
|
format = Raster::C888;
|
||||||
if(raster->depth == 32)
|
else if(image->depth == 16)
|
||||||
raster->format = Raster::C8888;
|
format = Raster::C1555;
|
||||||
else if(raster->depth == 24)
|
else if(image->depth == 8)
|
||||||
raster->format = Raster::C888;
|
format = Raster::PAL8 | Raster::C8888;
|
||||||
else if(raster->depth == 16)
|
else if(image->depth == 4)
|
||||||
raster->format = Raster::C1555;
|
format = Raster::PAL4 | Raster::C8888;
|
||||||
else if(raster->depth == 8)
|
else
|
||||||
raster->format = Raster::PAL8 | Raster::C8888;
|
|
||||||
else if(raster->depth == 4)
|
|
||||||
raster->format = Raster::PAL4 | Raster::C8888;
|
|
||||||
else{
|
|
||||||
delete raster;
|
|
||||||
return NULL;
|
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];
|
raster->texels = new uint8[raster->stride*raster->height];
|
||||||
memcpy(raster->texels, image->pixels, raster->stride*raster->height);
|
memcpy(raster->texels, image->pixels, raster->stride*raster->height);
|
||||||
if(image->palette){
|
if(image->palette){
|
||||||
|
21
src/rwd3d.h
21
src/rwd3d.h
@ -65,7 +65,28 @@ void unlockIndices(void *indexBuffer);
|
|||||||
void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool);
|
void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool);
|
||||||
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
|
uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags);
|
||||||
void unlockVertices(void *vertexBuffer);
|
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);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,5 +52,11 @@ ObjPipeline *makeSkinPipeline(void);
|
|||||||
|
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
|
// Native Texture and Raster
|
||||||
|
|
||||||
|
Texture *readNativeTexture(Stream *stream);
|
||||||
|
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||||
|
uint32 getSizeNativeTexture(Texture *tex);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,30 +97,36 @@ void writeTGA(Image *image, const char *filename);
|
|||||||
|
|
||||||
struct Raster : PluginBase<Raster>
|
struct Raster : PluginBase<Raster>
|
||||||
{
|
{
|
||||||
|
int32 platform;
|
||||||
|
|
||||||
int32 type; // hardly used
|
int32 type; // hardly used
|
||||||
|
int32 flags;
|
||||||
|
int32 format;
|
||||||
int32 width, height, depth;
|
int32 width, height, depth;
|
||||||
int32 stride;
|
int32 stride;
|
||||||
int32 format;
|
|
||||||
uint8 *texels;
|
uint8 *texels;
|
||||||
uint8 *palette;
|
uint8 *palette;
|
||||||
|
|
||||||
Raster(void);
|
Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0);
|
||||||
~Raster(void);
|
~Raster(void);
|
||||||
|
|
||||||
static Raster *createFromImage(Image *image);
|
static Raster *createFromImage(Image *image);
|
||||||
|
uint8 *lock(int32 level);
|
||||||
|
void unlock(int32 level);
|
||||||
|
int32 getNumLevels(void);
|
||||||
|
|
||||||
enum Format {
|
enum Format {
|
||||||
DEFAULT = 0,
|
DEFAULT = 0,
|
||||||
C1555 = 0x100,
|
C1555 = 0x0100,
|
||||||
C565 = 0x200,
|
C565 = 0x0200,
|
||||||
C4444 = 0x300,
|
C4444 = 0x0300,
|
||||||
LUM8 = 0x400,
|
LUM8 = 0x0400,
|
||||||
C8888 = 0x500,
|
C8888 = 0x0500,
|
||||||
C888 = 0x600,
|
C888 = 0x0600,
|
||||||
D16 = 0x700,
|
D16 = 0x0700,
|
||||||
D24 = 0x800,
|
D24 = 0x0800,
|
||||||
D32 = 0x900,
|
D32 = 0x0900,
|
||||||
C555 = 0xa00,
|
C555 = 0x0A00,
|
||||||
AUTOMIPMAP = 0x1000,
|
AUTOMIPMAP = 0x1000,
|
||||||
PAL8 = 0x2000,
|
PAL8 = 0x2000,
|
||||||
PAL4 = 0x4000,
|
PAL4 = 0x4000,
|
||||||
@ -147,6 +153,9 @@ struct Texture : PluginBase<Texture>
|
|||||||
bool streamWrite(Stream *stream);
|
bool streamWrite(Stream *stream);
|
||||||
uint32 streamGetSize(void);
|
uint32 streamGetSize(void);
|
||||||
static Texture *read(const char *name, const char *mask);
|
static Texture *read(const char *name, const char *mask);
|
||||||
|
static Texture *streamReadNative(Stream *stream);
|
||||||
|
void streamWriteNative(Stream *stream);
|
||||||
|
uint32 streamGetSizeNative(void);
|
||||||
|
|
||||||
enum FilterMode {
|
enum FilterMode {
|
||||||
NEAREST = 1,
|
NEAREST = 1,
|
||||||
@ -408,13 +417,16 @@ private:
|
|||||||
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TexDictionary
|
struct TexDictionary : PluginBase<Texture>
|
||||||
{
|
{
|
||||||
Texture *first;
|
Texture *first;
|
||||||
|
|
||||||
TexDictionary(void);
|
TexDictionary(void);
|
||||||
void add(Texture *tex);
|
void add(Texture *tex);
|
||||||
Texture *find(const char *name);
|
Texture *find(const char *name);
|
||||||
|
static TexDictionary *streamRead(Stream *stream);
|
||||||
|
void streamWrite(Stream *stream);
|
||||||
|
uint32 streamGetSize(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Animation;
|
struct Animation;
|
||||||
|
@ -15,49 +15,10 @@ namespace rw {
|
|||||||
|
|
||||||
namespace d3d {
|
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
|
void
|
||||||
createTexture(Texture *tex)
|
createTexture(Texture *tex)
|
||||||
{
|
{
|
||||||
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, tex->raster, nativeRasterOffset);
|
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
|
||||||
int32 w, h;
|
int32 w, h;
|
||||||
w = tex->raster->width;
|
w = tex->raster->width;
|
||||||
h = tex->raster->height;
|
h = tex->raster->height;
|
||||||
@ -79,6 +40,7 @@ createTexture(Texture *tex)
|
|||||||
}
|
}
|
||||||
texture->UnlockRect(0);
|
texture->UnlockRect(0);
|
||||||
raster->texture = texture;
|
raster->texture = texture;
|
||||||
|
raster->format = D3DFMT_A8R8G8B8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -94,11 +56,11 @@ setTexture(Texture *tex)
|
|||||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||||
};
|
};
|
||||||
|
|
||||||
D3d9Raster *raster = PLUGINOFFSET(D3d9Raster, tex->raster, nativeRasterOffset);
|
D3dRaster *raster = PLUGINOFFSET(D3dRaster, tex->raster, nativeRasterOffset);
|
||||||
if(tex->raster){
|
if(tex->raster){
|
||||||
if(raster->texture == NULL)
|
if(raster->texture == NULL)
|
||||||
createTexture(tex);
|
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_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||||
Device->SetSamplerState(0, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
Device->SetSamplerState(0, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||||
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
Device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||||
@ -216,23 +178,42 @@ void
|
|||||||
initrw(void)
|
initrw(void)
|
||||||
{
|
{
|
||||||
gta::attachPlugins();
|
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::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;
|
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\\player.dff";
|
||||||
// char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\od_newscafe_dy.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\\admiral.dff";
|
||||||
// char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\lae2_roads89.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 = "D:\\rockstargames\\pc\\gtasa\\models\\cutscene_archive\\csremington92.dff";
|
||||||
// char *filename = "C:\\gtasa\\test\\hanger.dff";
|
// char *filename = "C:\\gtasa\\test\\hanger.dff";
|
||||||
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
|
// char *filename = "C:\\Users\\aap\\Desktop\\tmp\\out.dff";
|
||||||
@ -298,7 +279,8 @@ Setup()
|
|||||||
camera->setNearFar(0.1f, 450.0f);
|
camera->setNearFar(0.1f, 450.0f);
|
||||||
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
|
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
|
||||||
// camera->setPosition(Vec3(0.0f, 5.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));
|
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user