diff options
| author | claude-bot <[email protected]> | 2026-07-13 12:40:03 +0000 |
|---|---|---|
| committer | claude-bot <[email protected]> | 2026-07-13 12:40:03 +0000 |
| commit | 847962910f0bff071f3bf07c9abb87764fb6cac3 (patch) | |
| tree | ddcd429e134c7fd5f72ddc97ced175de8d66fcd0 /src/d3d | |
| download | librw-master.tar.gz librw-master.zip | |
Snapshot for re3/reVC vendoring, per @lzcnt.
Source: https://github.com/aap/librw (master).
Diffstat (limited to 'src/d3d')
50 files changed, 13366 insertions, 0 deletions
diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp new file mode 100644 index 0000000..f1f5f49 --- /dev/null +++ b/src/d3d/d3d.cpp @@ -0,0 +1,1087 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" +#include "rwd3dimpl.h" + +#define PLUGIN_ID ID_DRIVER + +namespace rw { +namespace d3d { + +bool32 isP8supported = 1; // set to 0 when actual d3d device is used + +// stolen from d3d8to9 +static 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; + } +} + +int vertFormatMap[] = { + -1, VERT_FLOAT2, VERT_FLOAT3, VERT_FLOAT4, VERT_ARGB, VERT_RGBA /* blend indices */ +}; + +void* +createIndexBuffer(uint32 length, bool dynamic) +{ +#ifdef RW_D3D9 + IDirect3DIndexBuffer9 *ibuf; + if(dynamic) + d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuf, 0); + else + d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0); + if(ibuf) + d3d9Globals.numIndexBuffers++; + return ibuf; +#else + return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER); +#endif +} + +void +destroyIndexBuffer(void *indexBuffer) +{ +#ifdef RW_D3D9 + if(indexBuffer){ + if(((IUnknown*)indexBuffer)->Release() != 0) + printf("indexBuffer wasn't destroyed\n"); + d3d9Globals.numIndexBuffers--; + } +#else + rwFree(indexBuffer); +#endif +} + +uint16* +lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags) +{ + if(indexBuffer == nil) + return nil; +#ifdef RW_D3D9 + uint16 *indices; + IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer; + ibuf->Lock(offset, size, (void**)&indices, flags); + return indices; +#else + (void)offset; + (void)size; + (void)flags; + return (uint16*)indexBuffer; +#endif +} + +void +unlockIndices(void *indexBuffer) +{ + if(indexBuffer == nil) + return; +#ifdef RW_D3D9 + IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer; + ibuf->Unlock(); +#endif +} + +void* +createVertexBuffer(uint32 length, uint32 fvf, bool dynamic) +{ +#ifdef RW_D3D9 + IDirect3DVertexBuffer9 *vbuf; + if(dynamic) + d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, fvf, D3DPOOL_DEFAULT, &vbuf, 0); + else + d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, D3DPOOL_MANAGED, &vbuf, 0); + if(vbuf) + d3d9Globals.numVertexBuffers++; + return vbuf; +#else + (void)fvf; + return rwNewT(uint8, length, MEMDUR_EVENT | ID_DRIVER); +#endif +} + +void +destroyVertexBuffer(void *vertexBuffer) +{ +#ifdef RW_D3D9 + if(vertexBuffer){ + if(((IUnknown*)vertexBuffer)->Release() != 0) + printf("vertexBuffer wasn't destroyed\n"); + d3d9Globals.numVertexBuffers--; + } +#else + rwFree(vertexBuffer); +#endif +} + +uint8* +lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags) +{ + if(vertexBuffer == nil) + return nil; +#ifdef RW_D3D9 + uint8 *verts; + IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer; + vertbuf->Lock(offset, size, (void**)&verts, flags); + return verts; +#else + (void)offset; + (void)size; + (void)flags; + return (uint8*)vertexBuffer; +#endif +} + +void +unlockVertices(void *vertexBuffer) +{ + if(vertexBuffer == nil) + return; +#ifdef RW_D3D9 + IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer; + vertbuf->Unlock(); +#endif +} + +void* +createTexture(int32 width, int32 height, int32 numlevels, uint32 usage, uint32 format) +{ +#ifdef RW_D3D9 + IDirect3DTexture9 *tex; + d3ddevice->CreateTexture(width, height, numlevels, usage, + (D3DFORMAT)format, D3DPOOL_MANAGED, &tex, nil); + if(tex) + d3d9Globals.numTextures++; + return tex; +#else + int32 w = width; + int32 h = height; + int32 size = 0; + for(int32 i = 0; i < numlevels; i++){ + size += calculateTextureSize(w, h, 1, format); + w /= 2; + if(w == 0) w = 1; + h /= 2; + if(h == 0) h = 1; + } + uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size, + MEMDUR_EVENT | ID_DRIVER); + RasterLevels *levels = (RasterLevels*)data; + data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1); + levels->numlevels = numlevels; + levels->format = format; + w = width; + h = height; + for(int32 i = 0; i < numlevels; i++){ + levels->levels[i].width = w; + levels->levels[i].height = h; + levels->levels[i].data = data; + levels->levels[i].size = calculateTextureSize(w, h, 1, format); + data += levels->levels[i].size; + w /= 2; + if(w == 0) w = 1; + h /= 2; + if(h == 0) h = 1; + } + return levels; +#endif +} + +void +destroyTexture(void *texture) +{ +#ifdef RW_D3D9 + if(texture){ + if(((IUnknown*)texture)->Release() != 0) + printf("texture wasn't destroyed\n"); + d3d9Globals.numTextures--; + } +#else + rwFree(texture); +#endif +} + +// Native Raster + +int32 nativeRasterOffset; + +struct RasterFormatInfo +{ + uint32 d3dformat; + int32 depth; + bool32 hasAlpha; + uint32 rwFormat; +}; + +// indexed directly by RW format +static RasterFormatInfo formatInfoRW[16] = { + { 0, 0, 0, 0}, + { D3DFMT_A1R5G5B5, 16, 1, Raster::C1555 }, + { D3DFMT_R5G6B5, 16, 0, Raster::C565 }, + { D3DFMT_A4R4G4B4, 16, 1, Raster::C4444 }, + { D3DFMT_L8, 8, 0, Raster::LUM8 }, + { D3DFMT_A8R8G8B8, 32, 1, Raster::C8888 }, + { D3DFMT_X8R8G8B8, 32, 0, Raster::C888 }, + { D3DFMT_D16, 16, 0, Raster::D16 }, + { D3DFMT_D24X8, 32, 0, Raster::D24 }, + { D3DFMT_D32, 32, 0, Raster::D32 }, + { D3DFMT_X1R5G5B5, 16, 0, Raster::C555 }, +}; + +static RasterFormatInfo formatInfoFull[] = { + { D3DFMT_R8G8B8, 0, 24, 0 }, + { D3DFMT_A8R8G8B8, 1, 32, Raster::C8888 }, + { D3DFMT_X8R8G8B8, 0, 32, Raster::C888 }, + { D3DFMT_R5G6B5, 0, 16, Raster::C565 }, + { D3DFMT_X1R5G5B5, 0, 16, Raster::C555 }, + { D3DFMT_A1R5G5B5, 1, 16, Raster::C1555 }, + { D3DFMT_A4R4G4B4, 1, 16, Raster::C4444 }, + { D3DFMT_R3G3B2, 0, 8, 0 }, + { D3DFMT_A8, 1, 8, 0 }, + { D3DFMT_A8R3G3B2, 1, 16, 0 }, + { D3DFMT_X4R4G4B4, 0, 16, 0 }, + { D3DFMT_A2B10G10R10, 1, 32, 0 }, + { D3DFMT_A8B8G8R8, 1, 32, 0 }, + { D3DFMT_X8B8G8R8, 0, 32, 0 }, + { D3DFMT_G16R16, 0, 32, 0 }, + { D3DFMT_A2R10G10B10, 1, 32, 0 }, + { D3DFMT_A16B16G16R16, 1, 64, 0 }, + { D3DFMT_A8P8, 1, 16, 0 }, +// { D3DFMT_P8, 0, 8, ... }, +// { D3DFMT_L8, 0, 8, ... }, + { D3DFMT_A8L8, 1, 16, 0 }, + { D3DFMT_A4L4, 1, 8, 0 }, + { D3DFMT_V8U8, 0, 16, 0 }, + { D3DFMT_L6V5U5, 0, 16, 0 }, + { D3DFMT_X8L8V8U8, 0, 32, 0 }, + { D3DFMT_Q8W8V8U8, 0, 32, 0 }, + { D3DFMT_V16U16, 0, 32, 0 }, + { D3DFMT_A2W10V10U10, 1, 32, 0 }, + { D3DFMT_D16_LOCKABLE, 0, 16, Raster::D16 }, + { D3DFMT_D32, 0, 32, Raster::D32 }, + { D3DFMT_D15S1, 0, 16, Raster::D16 }, + { D3DFMT_D24S8, 0, 32, Raster::D32 }, + { D3DFMT_D24X8, 0, 32, Raster::D32 }, + { D3DFMT_D24X4S4, 0, 32, Raster::D32 }, + { D3DFMT_D16, 0, 16, Raster::D16 }, + { D3DFMT_D32F_LOCKABLE, 0, 32, Raster::D32 }, + { D3DFMT_D24FS8, 0, 32, Raster::D32 }, + { D3DFMT_L16, 0, 16, 0 }, + { D3DFMT_Q16W16V16U16, 0, 64, 0 }, + { D3DFMT_R16F, 0, 16, 0 }, + { D3DFMT_G16R16F, 0, 32, 0 }, + { D3DFMT_A16B16G16R16F, 1, 64, 0 }, + { D3DFMT_R32F, 0, 32, 0 }, + { D3DFMT_G32R32F, 0, 64, 0 }, + { D3DFMT_A32B32G32R32F, 1, 128, 0 }, + { D3DFMT_CxV8U8, 0, 16, 0 }, +}; + +RasterFormatInfo* +findFormatInfoD3D(uint32 d3dformat) +{ + static RasterFormatInfo fake = { 0, 0, 0, 0 }; + int i; + for(i = 0; i < (int)nelem(formatInfoFull); i++) + if(formatInfoFull[i].d3dformat == d3dformat) + return &formatInfoFull[i]; + return &fake; +} + + +static void +rasterSetFormat(Raster *raster) +{ + if(raster->format == 0){ + // have to find a format first + // this could perhaps be a bit more intelligent + + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + raster->format = Raster::C8888; + break; + +#ifdef RW_D3D9 + case Raster::ZBUFFER: + // TODO: allow other formats + raster->format = findFormatInfoD3D(d3d9Globals.present.AutoDepthStencilFormat)->rwFormat; + // can this even happen? just do something... + if(raster->format == 0) + raster->format = Raster::D32; + break; + + case Raster::CAMERATEXTURE: +// let's not use this because we apparently don't want alpha +// raster->format = findFormatInfoD3D(d3d9Globals.present.BackBufferFormat)->rwFormat; + raster->format = findFormatInfoD3D(d3d9Globals.startMode.mode.Format)->rwFormat; + // can this even happen? just do something... + if(raster->format == 0) + raster->format = Raster::C888; + break; + case Raster::CAMERA: + raster->format = findFormatInfoD3D(d3d9Globals.present.BackBufferFormat)->rwFormat; + // can this even happen? just do something... + if(raster->format == 0) + raster->format = Raster::C8888; + break; +#endif + } + } + + + D3dRaster *natras = GETD3DRASTEREXT(raster); + if(raster->format & (Raster::PAL4 | Raster::PAL8)){ + // TODO: do we even allow PAL4? + natras->format = D3DFMT_P8; + raster->depth = 8; + }else{ + natras->format = formatInfoRW[(raster->format >> 8) & 0xF].d3dformat; + raster->depth = formatInfoRW[(raster->format >> 8) & 0xF].depth; + } + natras->bpp = raster->depth/8; + natras->hasAlpha = formatInfoRW[(raster->format >> 8) & 0xF].hasAlpha; + raster->stride = raster->width*natras->bpp; + + natras->autogenMipmap = (raster->format & (Raster::MIPMAP|Raster::AUTOMIPMAP)) == (Raster::MIPMAP|Raster::AUTOMIPMAP); +} + +static Raster* +rasterCreateTexture(Raster *raster) +{ + int32 levels; + D3dRaster *natras = GETD3DRASTEREXT(raster); + + if(natras->format == D3DFMT_P8) + natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER); + if(natras->autogenMipmap) + levels = 0; + else if(raster->format & Raster::MIPMAP) + levels = Raster::calculateNumLevels(raster->width, raster->height); + else + levels = 1; + + assert(natras->texture == nil); + natras->texture = createTexture(raster->width, raster->height, + levels, + natras->autogenMipmap ? D3DUSAGE_AUTOGENMIPMAP : 0, + natras->format); + if(natras->texture == nil){ + RWERROR((ERR_NOTEXTURE)); + return nil; + } + return raster; +} + +#ifdef RW_D3D9 + +static Raster* +rasterCreateCameraTexture(Raster *raster) +{ + if(raster->format & (Raster::PAL4 | Raster::PAL8)){ + RWERROR((ERR_NOTEXTURE)); + return nil; + } + + int32 levels; + D3dRaster *natras = GETD3DRASTEREXT(raster); + if(natras->autogenMipmap) + levels = 0; + else if(raster->format & Raster::MIPMAP) + levels = Raster::calculateNumLevels(raster->width, raster->height); + else + levels = 1; + + IDirect3DTexture9 *tex; + d3ddevice->CreateTexture(raster->width, raster->height, + levels, + (natras->autogenMipmap ? D3DUSAGE_AUTOGENMIPMAP : 0) | D3DUSAGE_RENDERTARGET, + (D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil); + assert(natras->texture == nil); + natras->texture = tex; + if(natras->texture == nil){ + RWERROR((ERR_NOTEXTURE)); + return nil; + } + d3d9Globals.numTextures++; + addVidmemRaster(raster); + return raster; +} + +static Raster* +rasterCreateCamera(Raster *raster) +{ + D3dRaster *natras = GETD3DRASTEREXT(raster); + + natras->autogenMipmap = 0; + + natras->format = d3d9Globals.present.BackBufferFormat; + raster->depth = findFormatDepth(natras->format); + + natras->texture = nil; // global default render target + return raster; +} + +static Raster* +rasterCreateZbuffer(Raster *raster) +{ + D3dRaster *natras = GETD3DRASTEREXT(raster); + + natras->autogenMipmap = 0; + + // TODO: allow other formats + natras->format = d3d9Globals.present.AutoDepthStencilFormat; + raster->depth = findFormatDepth(natras->format); + + RECT rect; + GetClientRect(d3d9Globals.window, &rect); + // This check is done by RW but it's rather strange... + if(rect.right == raster->width && rect.bottom == raster->height) + natras->texture = d3d9Globals.defaultDepthSurf; + else{ + IDirect3DSurface9 *surf = nil; + d3ddevice->CreateDepthStencilSurface(raster->width, raster->height, (D3DFORMAT)natras->format, + d3d9Globals.present.MultiSampleType, d3d9Globals.present.MultiSampleQuality, + FALSE, &surf, nil); + assert(natras->texture == nil); + natras->texture = surf; + if(natras->texture == nil){ + RWERROR((ERR_NOTEXTURE)); + return nil; + } + } + addVidmemRaster(raster); + + return raster; +} +#endif + +Raster* +rasterCreate(Raster *raster) +{ + rasterSetFormat(raster); + + Raster *ret = raster; + + if(raster->width == 0 || raster->height == 0){ + raster->flags |= Raster::DONTALLOCATE; + raster->stride = 0; + goto ret; + } + if(raster->flags & Raster::DONTALLOCATE) + goto ret; + + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + ret = rasterCreateTexture(raster); + break; + +#ifdef RW_D3D9 + case Raster::CAMERATEXTURE: + ret = rasterCreateCameraTexture(raster); + break; + case Raster::ZBUFFER: + ret = rasterCreateZbuffer(raster); + break; + case Raster::CAMERA: + ret = rasterCreateCamera(raster); + break; +#endif + + default: + RWERROR((ERR_INVRASTER)); + return nil; + } + +ret: + raster->originalWidth = raster->width; + raster->originalHeight = raster->height; + raster->originalStride = raster->stride; + raster->originalPixels = raster->pixels; + return ret; +} + +uint8* +rasterLock(Raster *raster, int32 level, int32 lockMode) +{ + D3dRaster *natras = GETD3DRASTEREXT(raster); + + // check if already locked + if(raster->privateFlags & (Raster::PRIVATELOCK_READ|Raster::PRIVATELOCK_WRITE)) + return nil; + +#ifdef RW_D3D9 + DWORD flags = D3DLOCK_NOSYSLOCK; + if(lockMode & Raster::LOCKREAD) + flags |= D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE; + IDirect3DTexture9 *tex = (IDirect3DTexture9*)natras->texture; + IDirect3DSurface9 *surf, *rt; + D3DLOCKED_RECT lr; + + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: { + tex->GetSurfaceLevel(level, &surf); + natras->lockedSurf = surf; + HRESULT res = surf->LockRect(&lr, 0, flags); + assert(res == D3D_OK); + break; + } + + case Raster::CAMERATEXTURE: + case Raster::CAMERA: { + if(lockMode & Raster::PRIVATELOCK_WRITE) + assert(0 && "can't lock framebuffer for writing"); + if(raster->type == Raster::CAMERA) + rt = d3d9Globals.defaultRenderTarget; + else + tex->GetSurfaceLevel(level, &rt); + D3DSURFACE_DESC desc; + rt->GetDesc(&desc); + HRESULT res = d3ddevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, nil); + if(res != D3D_OK) + return nil; + d3ddevice->GetRenderTargetData(rt, surf); + natras->lockedSurf = surf; + res = surf->LockRect(&lr, 0, flags); + assert(res == D3D_OK); + break; + } + + default: + assert(0 && "can't lock this raster type (yet)"); + } + + raster->pixels = (uint8*)lr.pBits; + raster->width >>= level; + raster->height >>= level; + raster->stride = lr.Pitch; + if(raster->width == 0) raster->width = 1; + if(raster->height == 0) raster->height = 1; +#else + RasterLevels *levels = (RasterLevels*)natras->texture; + raster->pixels = levels->levels[level].data; + raster->width = levels->levels[level].width; + raster->height = levels->levels[level].height; + raster->stride = raster->width*natras->bpp; +#endif + if(lockMode & Raster::LOCKREAD) raster->privateFlags |= Raster::PRIVATELOCK_READ; + if(lockMode & Raster::LOCKWRITE) raster->privateFlags |= Raster::PRIVATELOCK_WRITE; + + return raster->pixels; +} + +void +rasterUnlock(Raster *raster, int32 level) +{ +#if RW_D3D9 + D3dRaster *natras = GETD3DRASTEREXT(raster); + IDirect3DSurface9 *surf = (IDirect3DSurface9*)natras->lockedSurf; + surf->UnlockRect(); + surf->Release(); + natras->lockedSurf = nil; +#endif + raster->width = raster->originalWidth; + raster->height = raster->originalHeight; + raster->stride = raster->originalStride; + raster->pixels = raster->originalPixels; + + raster->privateFlags &= ~(Raster::PRIVATELOCK_READ|Raster::PRIVATELOCK_WRITE); +} + +int32 +rasterNumLevels(Raster *raster) +{ + D3dRaster *natras = GETD3DRASTEREXT(raster); +#ifdef RW_D3D9 + IDirect3DTexture9 *tex = (IDirect3DTexture9*)natras->texture; + return tex->GetLevelCount(); +#else + RasterLevels *levels = (RasterLevels*)natras->texture; + return levels->numlevels; +#endif +} + +// Almost the same as ps2 and gl3 function +bool32 +imageFindRasterFormat(Image *img, int32 type, + int32 *pWidth, int32 *pHeight, int32 *pDepth, int32 *pFormat) +{ + int32 width, height, depth, format; + + assert((type&0xF) == Raster::TEXTURE); + +// for(width = 1; width < img->width; width <<= 1); +// for(height = 1; height < img->height; height <<= 1); + // Perhaps non-power-of-2 textures are acceptable? + width = img->width; + height = img->height; + + depth = img->depth; + + if(depth <= 8 && !isP8supported) + depth = 32; + + switch(depth){ + case 32: + if(img->hasAlpha()) + format = Raster::C8888; + else{ + format = Raster::C888; + depth = 24; + } + break; + case 24: + format = Raster::C888; + break; + case 16: + format = Raster::C1555; + break; + case 8: + format = Raster::PAL8 | Raster::C8888; + break; + case 4: + format = Raster::PAL4 | Raster::C8888; + break; + default: + RWERROR((ERR_INVRASTER)); + return 0; + } + + format |= type; + + *pWidth = width; + *pHeight = height; + *pDepth = depth; + *pFormat = format; + + return 1; +} + +bool32 +rasterFromImage(Raster *raster, Image *image) +{ + if((raster->type&0xF) != Raster::TEXTURE) + return 0; + + void (*conv)(uint8 *out, uint8 *in) = nil; + + // Unpalettize image if necessary but don't change original + Image *truecolimg = nil; + if(image->depth <= 8 && !isP8supported){ + truecolimg = Image::create(image->width, image->height, image->depth); + truecolimg->pixels = image->pixels; + truecolimg->stride = image->stride; + truecolimg->palette = image->palette; + truecolimg->unpalettize(); + image = truecolimg; + } + + D3dRaster *natras = GETD3DRASTEREXT(raster); + int32 format = raster->format&(Raster::PAL8 | Raster::PAL4 | 0xF00); + switch(image->depth){ + case 32: + if(format == Raster::C8888) + conv = conv_BGRA8888_from_RGBA8888; + else if(format == Raster::C888) + conv = conv_BGR888_from_RGB888; + else + goto err; + break; + case 24: + if(format == Raster::C8888) + conv = conv_BGRA8888_from_RGB888; + else if(format == Raster::C888) + conv = conv_BGR888_from_RGB888; + else + goto err; + break; + case 16: + if(format == Raster::C1555) + conv = conv_ARGB1555_from_ARGB1555; + else + goto err; + break; + case 8: + if(format == (Raster::PAL8 | Raster::C8888)) + conv = conv_8_from_8; + else + goto err; + break; + case 4: + if(format == (Raster::PAL4 | Raster::C8888) || + format == (Raster::PAL8 | Raster::C8888)) + conv = conv_8_from_8; + else + goto err; + break; + default: + err: +fprintf(stderr, "%d %x\n", image->depth, format); fflush(stdout); + RWERROR((ERR_INVRASTER)); + return 0; + } + + uint8 *in, *out; + int pallength = 0; + if(raster->format & Raster::PAL4) + pallength = 16; + else if(raster->format & Raster::PAL8) + pallength = 256; + if(pallength){ + in = image->palette; + out = (uint8*)natras->palette; + for(int32 i = 0; i < pallength; i++){ + conv_RGBA8888_from_RGBA8888(out, in); + in += 4; + out += 4; + } + } + + bool unlock = false; + if(raster->pixels == nil){ + raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + unlock = true; + } + + uint8 *pixels = raster->pixels; + assert(pixels); + uint8 *imgpixels = image->pixels; + + int x, y; + assert(image->width == raster->width); + assert(image->height == raster->height); + for(y = 0; y < image->height; y++){ + uint8 *imgrow = imgpixels; + uint8 *rasrow = pixels; + for(x = 0; x < image->width; x++){ + conv(rasrow, imgrow); + imgrow += image->bpp; + rasrow += natras->bpp; + } + imgpixels += image->stride; + pixels += raster->stride; + } + if(unlock) + raster->unlock(0); + + if(truecolimg) + truecolimg->destroy(); + + return 1; +} + +Image* +rasterToImage(Raster *raster) +{ + int32 depth; + Image *image; + + bool unlock = false; + if(raster->pixels == nil){ + raster->lock(0, Raster::LOCKREAD); + unlock = true; + } + + D3dRaster *natras = GETD3DRASTEREXT(raster); + if(natras->customFormat){ + int w = raster->width; + int h = raster->height; + // pixels are in the upper right corner + if(w < 4) w = 4; + if(h < 4) h = 4; + image = Image::create(w, h, 32); + image->allocate(); + uint8 *pix = raster->pixels; + switch(natras->format){ + case D3DFMT_DXT1: + image->setPixelsDXT(1, pix); + if((raster->format & 0xF00) == Raster::C565) + image->removeMask(); + break; + case D3DFMT_DXT3: + image->setPixelsDXT(3, pix); + break; + case D3DFMT_DXT5: + image->setPixelsDXT(5, pix); + break; + default: + image->destroy(); + if(unlock) + raster->unlock(0); + return nil; + } + // fix it up again + image->width = raster->width; + image->height = raster->height; + + if(unlock) + raster->unlock(0); + return image; + } + + void (*conv)(uint8 *out, uint8 *in) = nil; + switch(raster->format & 0xF00){ + case Raster::C1555: + depth = 16; + conv = conv_ARGB1555_from_ARGB1555; + break; + case Raster::C8888: + depth = 32; + conv = conv_RGBA8888_from_BGRA8888; + break; + case Raster::C888: + depth = 24; + conv = conv_RGB888_from_BGR888; + break; + case Raster::C555: + depth = 16; + conv = conv_ARGB1555_from_RGB555; + break; + + default: + case Raster::C565: + case Raster::C4444: + case Raster::LUM8: + RWERROR((ERR_INVRASTER)); + return nil; + } + int32 pallength = 0; + if((raster->format & Raster::PAL4) == Raster::PAL4){ + depth = 4; + pallength = 16; + }else if((raster->format & Raster::PAL8) == Raster::PAL8){ + depth = 8; + pallength = 256; + } + + uint8 *in, *out; + image = Image::create(raster->width, raster->height, depth); + image->allocate(); + + if(pallength){ + out = image->palette; + in = (uint8*)natras->palette; + for(int32 i = 0; i < pallength; i++){ + conv_RGBA8888_from_RGBA8888(out, in); + in += 4; + out += 4; + } + } + + uint8 *imgpixels = image->pixels; + uint8 *pixels = raster->pixels; + + int x, y; + assert(image->width == raster->width); + assert(image->height == raster->height); + for(y = 0; y < image->height; y++){ + uint8 *imgrow = imgpixels; + uint8 *rasrow = pixels; + for(x = 0; x < image->width; x++){ + conv(imgrow, rasrow); + imgrow += image->bpp; + rasrow += natras->bpp; + } + imgpixels += image->stride; + pixels += raster->stride; + } + image->compressPalette(); + + if(unlock) + raster->unlock(0); + + return image; +} + +int32 +getLevelSize(Raster *raster, int32 level) +{ + D3dRaster *ras = GETD3DRASTEREXT(raster); +#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 + RasterLevels *levels = (RasterLevels*)ras->texture; + return levels->levels[level].size; +#endif +} + +void +allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha) +{ + static uint32 dxtMap[] = { + 0x31545844, // DXT1 + 0x32545844, // DXT2 + 0x33545844, // DXT3 + 0x34545844, // DXT4 + 0x35545844, // DXT5 + }; + D3dRaster *ras = GETD3DRASTEREXT(raster); + ras->format = dxtMap[dxt-1]; + ras->hasAlpha = hasAlpha; + ras->customFormat = 1; + if(ras->autogenMipmap) + numLevels = 0; + else if(raster->format & Raster::MIPMAP) + {} + else + numLevels = 1; + ras->texture = createTexture(raster->width, raster->height, + numLevels, + ras->autogenMipmap ? D3DUSAGE_AUTOGENMIPMAP : 0, + ras->format); + raster->flags &= ~Raster::DONTALLOCATE; +} + +void +setPalette(Raster *raster, void *palette, int32 size) +{ + D3dRaster *ras = GETD3DRASTEREXT(raster); + memcpy(ras->palette, palette, 4*size); +} + +void +setTexels(Raster *raster, void *texels, int32 level) +{ + uint8 *dst = raster->lock(level, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + memcpy(dst, texels, getLevelSize(raster, level)); + raster->unlock(level); +} + +static void* +createNativeRaster(void *object, int32 offset, int32) +{ + D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset); + raster->texture = nil; + raster->palette = nil; + raster->lockedSurf = nil; + raster->format = 0; + raster->hasAlpha = 0; + raster->customFormat = 0; + return object; +} + +static void* +destroyNativeRaster(void *object, int32 offset, int32) +{ + Raster *raster = (Raster*)object; + D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, offset); +#ifdef RW_D3D9 + removeVidmemRaster(raster); + evictD3D9Raster(raster); +#endif + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + case Raster::CAMERATEXTURE: + destroyTexture(natras->texture); + break; + + case Raster::ZBUFFER: +#ifdef RW_D3D9 + if(raster->flags & Raster::DONTALLOCATE) + break; + if(natras->texture != d3d9Globals.defaultDepthSurf) + ((IDirect3DSurface9*)natras->texture)->Release(); + natras->texture = nil; +#endif + break; + case Raster::CAMERA: + break; + } + rwFree(natras->palette); + return object; +} + +static void* +copyNativeRaster(void *dst, void *, int32 offset, int32) +{ + D3dRaster *raster = PLUGINOFFSET(D3dRaster, dst, offset); + raster->texture = nil; + raster->palette = nil; + raster->lockedSurf = nil; + raster->format = 0; + raster->hasAlpha = 0; + raster->customFormat = 0; + return dst; +} + +void +registerNativeRaster(void) +{ + nativeRasterOffset = Raster::registerPlugin(sizeof(D3dRaster), + ID_RASTERD3D9, + createNativeRaster, + destroyNativeRaster, + copyNativeRaster); +} + +} +} diff --git a/src/d3d/d3d8.cpp b/src/d3d/d3d8.cpp new file mode 100644 index 0000000..671948f --- /dev/null +++ b/src/d3d/d3d8.cpp @@ -0,0 +1,678 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" +#include "rwd3d8.h" + +#include "rwd3dimpl.h" + +#define PLUGIN_ID 2 + +namespace rw { +namespace d3d8 { +using namespace d3d; + +static void* +driverOpen(void *o, int32, int32) +{ + engine->driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline(); + + engine->driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset; + engine->driver[PLATFORM_D3D8]->rasterCreate = rasterCreate; + engine->driver[PLATFORM_D3D8]->rasterLock = rasterLock; + engine->driver[PLATFORM_D3D8]->rasterUnlock = rasterUnlock; + engine->driver[PLATFORM_D3D8]->rasterNumLevels = rasterNumLevels; + engine->driver[PLATFORM_D3D8]->imageFindRasterFormat = imageFindRasterFormat; + engine->driver[PLATFORM_D3D8]->rasterFromImage = rasterFromImage; + engine->driver[PLATFORM_D3D8]->rasterToImage = rasterToImage; + return o; +} + +static void* +driverClose(void *o, int32, int32) +{ + return o; +} + +void +registerPlatformPlugins(void) +{ + Driver::registerPlugin(PLATFORM_D3D8, 0, PLATFORM_D3D8, + driverOpen, driverClose); + // shared between D3D8 and 9 + if(nativeRasterOffset == 0) + registerNativeRaster(); +} + +uint32 +makeFVFDeclaration(uint32 flags, int32 numTex) +{ + uint32 fvf = 0x2; + if(flags & Geometry::NORMALS) + fvf |= 0x10; + if(flags & Geometry::PRELIT) + fvf |= 0x40; + fvf |= numTex << 8; + return fvf; +} + +int32 +getStride(uint32 flags, int32 numTex) +{ + int32 stride = 12; + if(flags & Geometry::NORMALS) + stride += 12;; + if(flags & Geometry::PRELIT) + stride += 4; + stride += numTex*8; + return stride; +} + +void* +destroyNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D8) + return object; + InstanceDataHeader *header = + (InstanceDataHeader*)geometry->instData; + geometry->instData = nil; + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + destroyIndexBuffer(inst->indexBuffer); + destroyVertexBuffer(inst->vertexBuffer); + inst++; + } + rwFree(header->inst); + rwFree(header); + return object; +} + +Stream* +readNativeData(Stream *stream, int32, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + uint32 platform; + if(!findChunk(stream, ID_STRUCT, nil, nil)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_D3D8){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + geometry->instData = header; + header->platform = PLATFORM_D3D8; + + int32 size = stream->readI32(); + uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY); + stream->read8(data, size); + uint8 *p = data; + header->serialNumber = *(uint16*)p; p += 2; + header->numMeshes = *(uint16*)p; p += 2; + header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + inst->minVert = *(uint32*)p; p += 4; + inst->stride = *(uint32*)p; p += 4; + inst->numVertices = *(uint32*)p; p += 4; + inst->numIndices = *(uint32*)p; p += 4; + uint32 matid = *(uint32*)p; p += 4; + inst->material = geometry->matList.materials[matid]; + inst->vertexShader = *(uint32*)p; p += 4; + inst->primType = *(uint32*)p; p += 4; + inst->indexBuffer = nil; p += 4; + inst->vertexBuffer = nil; p += 4; + inst->baseIndex = 0; p += 4; + inst->vertexAlpha = *p++; + inst->managed = 0; p++; + inst->remapped = 0; p++; // TODO: really unused? and what's that anyway? + inst++; + } + rwFree(data); + + inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + assert(inst->indexBuffer == nil); + inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false); + uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); + stream->read8(indices, 2*inst->numIndices); + unlockIndices(inst->indexBuffer); + + inst->managed = 1; + assert(inst->vertexBuffer == nil); + inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, false); + uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + stream->read8(verts, inst->stride*inst->numVertices); + unlockVertices(inst->vertexBuffer); + + inst++; + } + return stream; +} + +Stream* +writeNativeData(Stream *stream, int32 len, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + writeChunkHeader(stream, ID_STRUCT, len-12); + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D8) + return stream; + stream->writeU32(PLATFORM_D3D8); + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + + int32 size = 4 + geometry->meshHeader->numMeshes*0x2C; + uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY); + stream->writeI32(size); + uint8 *p = data; + *(uint16*)p = header->serialNumber; p += 2; + *(uint16*)p = header->numMeshes; p += 2; + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + *(uint32*)p = inst->minVert; p += 4; + *(uint32*)p = inst->stride; p += 4; + *(uint32*)p = inst->numVertices; p += 4; + *(uint32*)p = inst->numIndices; p += 4; + int32 matid = geometry->matList.findIndex(inst->material); + *(int32*)p = matid; p += 4; + *(uint32*)p = inst->vertexShader; p += 4; + *(uint32*)p = inst->primType; p += 4; + *(uint32*)p = 0; p += 4; // index buffer + *(uint32*)p = 0; p += 4; // vertex buffer + *(uint32*)p = inst->baseIndex; p += 4; + *p++ = inst->vertexAlpha; + *p++ = inst->managed; + *p++ = inst->remapped; + inst++; + } + stream->write8(data, size); + rwFree(data); + + inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); + stream->write8(indices, 2*inst->numIndices); + unlockIndices(inst->indexBuffer); + + uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + stream->write8(verts, inst->stride*inst->numVertices); + unlockVertices(inst->vertexBuffer); + inst++; + } + return stream; +} + +int32 +getSizeNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D8) + return 0; + + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + InstanceData *inst = header->inst; + int32 size = 12 + 4 + 4 + 4 + header->numMeshes*0x2C; + for(int32 i = 0; i < header->numMeshes; i++){ + size += inst->numIndices*2 + inst->numVertices*inst->stride; + inst++; + } + return size; +} + +void +registerNativeDataPlugin(void) +{ + Geometry::registerPlugin(0, ID_NATIVEDATA, + nil, destroyNativeData, nil); + Geometry::registerPluginStream(ID_NATIVEDATA, + readNativeData, + writeNativeData, + getSizeNativeData); +} + + +static void +instance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + // TODO: allow for REINSTANCE + if(geo->instData) + return; + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + MeshHeader *meshh = geo->meshHeader; + geo->instData = header; + header->platform = PLATFORM_D3D8; + + header->serialNumber = meshh->serialNum; + header->numMeshes = meshh->numMeshes; + header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + + InstanceData *inst = header->inst; + Mesh *mesh = meshh->getMeshes(); + for(uint32 i = 0; i < header->numMeshes; i++){ + findMinVertAndNumVertices(mesh->indices, mesh->numIndices, + &inst->minVert, &inst->numVertices); + inst->numIndices = mesh->numIndices; + inst->material = mesh->material; + inst->vertexShader = 0; + inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; + inst->vertexBuffer = nil; + inst->baseIndex = 0; // (maybe) not used by us + inst->vertexAlpha = 0; + inst->managed = 0; + inst->remapped = 0; + + inst->indexBuffer = createIndexBuffer(inst->numIndices*2, false); + uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); + if(inst->minVert == 0) + memcpy(indices, mesh->indices, inst->numIndices*2); + else + for(int32 j = 0; j < inst->numIndices; j++) + indices[j] = mesh->indices[j] - inst->minVert; + unlockIndices(inst->indexBuffer); + + pipe->instanceCB(geo, inst); + mesh++; + inst++; + } +} + +static void +uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + if((geo->flags & Geometry::NATIVE) == 0) + return; + assert(geo->instData != nil); + assert(geo->instData->platform == PLATFORM_D3D8); + geo->numTriangles = geo->meshHeader->guessNumTriangles(); + geo->allocateData(); + geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0); + + InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; + InstanceData *inst = header->inst; + Mesh *mesh = geo->meshHeader->getMeshes(); + for(uint32 i = 0; i < header->numMeshes; i++){ + uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); + if(inst->minVert == 0) + memcpy(mesh->indices, indices, inst->numIndices*2); + else + for(int32 j = 0; j < inst->numIndices; j++) + mesh->indices[j] = indices[j] + inst->minVert; + unlockIndices(inst->indexBuffer); + + pipe->uninstanceCB(geo, inst); + mesh++; + inst++; + } + geo->generateTriangles(); + geo->flags &= ~Geometry::NATIVE; + destroyNativeData(geo, 0, 0); +} + +static void +render(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + // TODO: allow for REINSTANCE + if(geo->instData == nil) + pipe->instance(atomic); + assert(geo->instData != nil); + assert(geo->instData->platform == PLATFORM_D3D8); + if(pipe->renderCB) + pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData); +} + +void +ObjPipeline::init(void) +{ + this->rw::ObjPipeline::init(PLATFORM_D3D8); + this->impl.instance = d3d8::instance; + this->impl.uninstance = d3d8::uninstance; + this->impl.render = d3d8::render; + this->instanceCB = nil; + this->uninstanceCB = nil; + this->renderCB = nil; +} + +ObjPipeline* +ObjPipeline::create(void) +{ + ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL); + pipe->init(); + return pipe; +} + +void +defaultInstanceCB(Geometry *geo, InstanceData *inst) +{ + inst->vertexShader = makeFVFDeclaration(geo->flags, geo->numTexCoordSets); + inst->stride = getStride(geo->flags, geo->numTexCoordSets); + + assert(inst->vertexBuffer == nil); + inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride, + inst->vertexShader, false); + inst->managed = 1; + + uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + instV3d(VERT_FLOAT3, dst, + &geo->morphTargets[0].vertices[inst->minVert], + inst->numVertices, inst->stride); + dst += 12; + + if(geo->flags & Geometry::NORMALS){ + instV3d(VERT_FLOAT3, dst, + &geo->morphTargets[0].normals[inst->minVert], + inst->numVertices, inst->stride); + dst += 12; + } + + inst->vertexAlpha = 0; + if(geo->flags & Geometry::PRELIT){ + inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[inst->minVert], + inst->numVertices, inst->stride); + dst += 4; + } + + for(int32 i = 0; i < geo->numTexCoordSets; i++){ + instTexCoords(VERT_FLOAT2, dst, &geo->texCoords[i][inst->minVert], + inst->numVertices, inst->stride); + dst += 8; + } + unlockVertices(inst->vertexBuffer); +} + +void +defaultUninstanceCB(Geometry *geo, InstanceData *inst) +{ + uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + uninstV3d(VERT_FLOAT3, + &geo->morphTargets[0].vertices[inst->minVert], + src, inst->numVertices, inst->stride); + src += 12; + + if(geo->flags & Geometry::NORMALS){ + uninstV3d(VERT_FLOAT3, + &geo->morphTargets[0].normals[inst->minVert], + src, inst->numVertices, inst->stride); + src += 12; + } + + inst->vertexAlpha = 0; + if(geo->flags & Geometry::PRELIT){ + uninstColor(VERT_ARGB, &geo->colors[inst->minVert], src, + inst->numVertices, inst->stride); + src += 4; + } + + for(int32 i = 0; i < geo->numTexCoordSets; i++){ + uninstTexCoords(VERT_FLOAT2, &geo->texCoords[i][inst->minVert], src, + inst->numVertices, inst->stride); + src += 8; + } + unlockVertices(inst->vertexBuffer); +} + +ObjPipeline* +makeDefaultPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB; + return pipe; +} + +// Native Texture and Raster + +// only handles 4 and 8 bit textures right now +Raster* +readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format, int32 numLevels) +{ + uint8 palette[256*4]; + int32 pallen = 0; + uint8 *data = nil; + + Image *img = Image::create(width, height, 32); + img->allocate(); + + if(format & Raster::PAL4){ + pallen = 16; + stream->read8(palette, 4*32); + }else if(format & Raster::PAL8){ + pallen = 256; + stream->read8(palette, 4*256); + } + if(!Raster::formatHasAlpha(format)) + for(int32 i = 0; i < pallen; i++) + palette[i*4+3] = 0xFF; + + Raster *ras = nil; + + for(int i = 0; i < numLevels; i++){ + uint32 size = stream->readU32(); + + // don't read levels that don't exist + if(ras && i >= ras->getNumLevels()){ + stream->seek(size); + continue; + } + + // one allocation is enough, first level is largest + if(data == nil) + data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE); + stream->read8(data, size); + + if(ras){ + ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + img->width = ras->width; + img->height = ras->height; + img->stride = img->width*img->bpp; + } + + if(format & (Raster::PAL4 | Raster::PAL8)){ + uint8 *idx = data; + uint8 *pixels = img->pixels; + for(int y = 0; y < img->height; y++){ + uint8 *line = pixels; + for(int x = 0; x < img->width; x++){ + line[0] = palette[*idx*4+0]; + line[1] = palette[*idx*4+1]; + line[2] = palette[*idx*4+2]; + if(img->bpp > 3) + line[3] = palette[*idx*4+3]; + line += img->bpp; + idx++; + } + pixels += img->stride; + } + } + + if(ras == nil){ + // Important to have filled the image with data + int32 newformat; + Raster::imageFindRasterFormat(img, format&7, &width, &height, &depth, &newformat); + newformat |= format & (Raster::MIPMAP | Raster::AUTOMIPMAP); + ras = Raster::create(width, height, depth, newformat); + ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + } + + ras->setFromImage(img); + ras->unlock(i); + } + + rwFree(data); + img->destroy(); + return ras; +} + +Texture* +readNativeTexture(Stream *stream) +{ + uint32 platform; + if(!findChunk(stream, ID_STRUCT, nil, nil)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_D3D8){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + Texture *tex = Texture::create(nil); + if(tex == nil) + return nil; + + // Texture + tex->filterAddressing = stream->readU32(); + stream->read8(tex->name, 32); + stream->read8(tex->mask, 32); + + // Raster + uint32 format = stream->readU32(); + 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(); + + int32 pallength = 0; + if(format & Raster::PAL4 || format & Raster::PAL8){ + pallength = format & Raster::PAL4 ? 32 : 256; + if(!d3d::isP8supported){ + tex->raster = readAsImage(stream, width, height, depth, format|type, numLevels); + return tex; + } + } + + Raster *raster; + D3dRaster *ras; + if(compression){ + raster = Raster::create(width, height, depth, format | type | Raster::DONTALLOCATE, PLATFORM_D3D8); + ras = GETD3DRASTEREXT(raster); + allocateDXT(raster, compression, numLevels, hasAlpha); + ras->customFormat = 1; + }else{ + raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D8); + ras = GETD3DRASTEREXT(raster); + } + tex->raster = raster; + + // TODO: check if format supported and convert if necessary + + if(pallength != 0) + stream->read8(ras->palette, 4*pallength); + + uint32 size; + uint8 *data; + for(int32 i = 0; i < numLevels; i++){ + size = stream->readU32(); + if(i < raster->getNumLevels()){ + data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + stream->read8(data, size); + raster->unlock(i); + }else + stream->seek(size); + } + return tex; +} + +void +writeNativeTexture(Texture *tex, Stream *stream) +{ + int32 chunksize = getSizeNativeTexture(tex); + writeChunkHeader(stream, ID_STRUCT, chunksize-12); + stream->writeU32(PLATFORM_D3D8); + + // Texture + stream->writeU32(tex->filterAddressing); + stream->write8(tex->name, 32); + stream->write8(tex->mask, 32); + + // Raster + Raster *raster = tex->raster; + D3dRaster *ras = GETD3DRASTEREXT(raster); + 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); + + if(raster->format & Raster::PAL4) + stream->write8(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->write8(ras->palette, 4*256); + + uint32 size; + uint8 *data; + for(int32 i = 0; i < numLevels; i++){ + size = getLevelSize(raster, i); + stream->writeU32(size); + data = raster->lock(i, Raster::LOCKREAD); + stream->write8(data, size); + raster->unlock(i); + } +} + +uint32 +getSizeNativeTexture(Texture *tex) +{ + uint32 size = 12 + 72 + 16; + int32 levels = tex->raster->getNumLevels(); + if(tex->raster->format & Raster::PAL4) + size += 4*32; + else if(tex->raster->format & Raster::PAL8) + size += 4*256; + for(int32 i = 0; i < levels; i++) + size += 4 + getLevelSize(tex->raster, i); + return size; +} + +} +} diff --git a/src/d3d/d3d8matfx.cpp b/src/d3d/d3d8matfx.cpp new file mode 100644 index 0000000..580203e --- /dev/null +++ b/src/d3d/d3d8matfx.cpp @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d8.h" + +namespace rw { +namespace d3d8 { +using namespace d3d; + +static void* +matfxOpen(void *o, int32, int32) +{ + matFXGlobals.pipelines[PLATFORM_D3D8] = makeMatFXPipeline(); + return o; +} + +static void* +matfxClose(void *o, int32, int32) +{ + ((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_D3D8])->destroy(); + matFXGlobals.pipelines[PLATFORM_D3D8] = nil; + return o; +} + +void +initMatFX(void) +{ + Driver::registerPlugin(PLATFORM_D3D8, 0, ID_MATFX, + matfxOpen, matfxClose); +} + +ObjPipeline* +makeMatFXPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB; + pipe->pluginID = ID_MATFX; + pipe->pluginData = 0; + return pipe; +} + +} +} diff --git a/src/d3d/d3d8render.cpp b/src/d3d/d3d8render.cpp new file mode 100644 index 0000000..c5375cb --- /dev/null +++ b/src/d3d/d3d8render.cpp @@ -0,0 +1,65 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" +#include "rwd3d8.h" + +namespace rw { +namespace d3d8 { +using namespace d3d; + +#ifndef RW_D3D9 +void defaultRenderCB(Atomic*, InstanceDataHeader*) {} +#else + +// This is a bit abandoned, use d3d9 instead + +void +defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) +{ + RawMatrix world; + + d3d::lightingCB_Fix(atomic); + + uint32 flags = atomic->geometry->flags; + d3d::setRenderState(D3DRS_LIGHTING, !!(flags & rw::Geometry::LIGHT)); + + Frame *f = atomic->getFrame(); + convMatrix(&world, f->getLTM()); + d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + d3d::setTexture(0, inst->material->texture); + d3d::setMaterial(flags, inst->material->color, inst->material->surfaceProps); + + + d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); + d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); + if(flags & Geometry::PRELIT) + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + else + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + + d3ddevice->SetFVF(inst->vertexShader); + setStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride); + setIndices((IDirect3DIndexBuffer9*)inst->indexBuffer); + uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3; + d3d::flushCache(); + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex, + 0, inst->numVertices, 0, numPrim); + inst++; + } +} + +#endif +} +} diff --git a/src/d3d/d3d8skin.cpp b/src/d3d/d3d8skin.cpp new file mode 100644 index 0000000..d9b0921 --- /dev/null +++ b/src/d3d/d3d8skin.cpp @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d8.h" + +namespace rw { +namespace d3d8 { +using namespace d3d; + +static void* +skinOpen(void *o, int32, int32) +{ + skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline(); + return o; +} + +static void* +skinClose(void *o, int32, int32) +{ + ((ObjPipeline*)skinGlobals.pipelines[PLATFORM_D3D8])->destroy(); + skinGlobals.pipelines[PLATFORM_D3D8] = nil; + return o; +} + +void +initSkin(void) +{ + Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN, + skinOpen, skinClose); +} + +ObjPipeline* +makeSkinPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB; + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; + return pipe; +} + +} +} diff --git a/src/d3d/d3d9.cpp b/src/d3d/d3d9.cpp new file mode 100644 index 0000000..851397b --- /dev/null +++ b/src/d3d/d3d9.cpp @@ -0,0 +1,853 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" +#include "rwd3d9.h" + +#include "rwd3dimpl.h" + +#define PLUGIN_ID 2 + +namespace rw { +namespace d3d9 { +using namespace d3d; + +// TODO: move to header, but not as #define +#ifndef RW_D3D9 +static VertexElement _d3ddec_end = {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}; +#define D3DDECL_END() _d3ddec_end +#endif + +#define NUMDECLELT 12 + +static void* +driverOpen(void *o, int32, int32) +{ +#ifdef RW_D3D9 + createDefaultShaders(); +#endif + engine->driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline(); + + engine->driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset; + engine->driver[PLATFORM_D3D9]->rasterCreate = rasterCreate; + engine->driver[PLATFORM_D3D9]->rasterLock = rasterLock; + engine->driver[PLATFORM_D3D9]->rasterUnlock = rasterUnlock; + engine->driver[PLATFORM_D3D9]->rasterNumLevels = rasterNumLevels; + engine->driver[PLATFORM_D3D9]->imageFindRasterFormat = imageFindRasterFormat; + engine->driver[PLATFORM_D3D9]->rasterFromImage = rasterFromImage; + engine->driver[PLATFORM_D3D9]->rasterToImage = rasterToImage; + return o; +} + +static void* +driverClose(void *o, int32, int32) +{ +#ifdef RW_D3D9 + destroyDefaultShaders(); +#endif + return o; +} + +void +registerPlatformPlugins(void) +{ + Driver::registerPlugin(PLATFORM_D3D9, 0, PLATFORM_D3D9, + driverOpen, driverClose); + // shared between D3D8 and 9 + if(nativeRasterOffset == 0) + registerNativeRaster(); +} + +void* +createVertexDeclaration(VertexElement *elements) +{ +#ifdef RW_D3D9 + IDirect3DVertexDeclaration9 *decl = 0; + d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl); + if(decl) + d3d9Globals.numVertexDeclarations++; + return decl; +#else + int n = 0; + VertexElement *e = (VertexElement*)elements; + while(e[n++].stream != 0xFF) + ; + e = rwNewT(VertexElement, n, MEMDUR_EVENT | ID_DRIVER); + memcpy(e, elements, n*sizeof(VertexElement)); + return e; +#endif +} + +void +destroyVertexDeclaration(void *declaration) +{ +#ifdef RW_D3D9 + if(declaration){ + if(((IUnknown*)declaration)->Release() != 0) + printf("declaration wasn't destroyed\n"); + d3d9Globals.numVertexDeclarations--; + } +#else + rwFree(declaration); +#endif +} + +uint32 +getDeclaration(void *declaration, VertexElement *elements) +{ +#ifdef RW_D3D9 + IDirect3DVertexDeclaration9 *decl = (IDirect3DVertexDeclaration9*)declaration; + UINT numElt; + decl->GetDeclaration((D3DVERTEXELEMENT9*)elements, &numElt); + return numElt; +#else + int n = 0; + VertexElement *e = (VertexElement*)declaration; + while(e[n++].stream != 0xFF) + ; + if(elements) + memcpy(elements, declaration, n*sizeof(VertexElement)); + return n; +#endif +} + +void +freeInstanceData(Geometry *geometry) +{ + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D9) + return; + InstanceDataHeader *header = + (InstanceDataHeader*)geometry->instData; + geometry->instData = nil; + destroyVertexDeclaration(header->vertexDeclaration); + destroyIndexBuffer(header->indexBuffer); + destroyVertexBuffer(header->vertexStream[0].vertexBuffer); + destroyVertexBuffer(header->vertexStream[1].vertexBuffer); + rwFree(header->inst); + rwFree(header); + return; +} + + +void* +destroyNativeData(void *object, int32, int32) +{ + freeInstanceData((Geometry*)object); + return object; +} + +Stream* +readNativeData(Stream *stream, int32, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + uint32 platform; + if(!findChunk(stream, ID_STRUCT, nil, nil)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_D3D9){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + geometry->instData = header; + header->platform = PLATFORM_D3D9; + + int32 size = stream->readI32(); + uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY); + stream->read8(data, size); + uint8 *p = data; + header->serialNumber = *(uint32*)p; p += 4; + header->numMeshes = *(uint32*)p; p += 4; + header->indexBuffer = nil; p += 4; + header->primType = *(uint32*)p; p += 4; + p += 16*2; // skip vertex streams, they're repeated with the vertex buffers + header->useOffsets = *(bool32*)p; p += 4; + header->vertexDeclaration = nil; p += 4; + header->totalNumIndex = *(uint32*)p; p += 4; + header->totalNumVertex = *(uint32*)p; p += 4; + header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + inst->numIndex = *(uint32*)p; p += 4; + inst->minVert = *(uint32*)p; p += 4; + uint32 matid = *(uint32*)p; p += 4; + inst->material = geometry->matList.materials[matid]; + inst->vertexAlpha = *(bool32*)p; p += 4; + inst->vertexShader = nil; p += 4; + inst->baseIndex = 0; p += 4; + inst->numVertices = *(uint32*)p; p += 4; + inst->startIndex = *(uint32*)p; p += 4; + inst->numPrimitives = *(uint32*)p; p += 4; + inst++; + } + + VertexElement elements[NUMDECLELT]; + uint32 numDeclarations = stream->readU32(); + stream->read8(elements, numDeclarations*8); + header->vertexDeclaration = createVertexDeclaration(elements); + + assert(header->indexBuffer == nil); + header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false); + uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); + stream->read8(indices, 2*header->totalNumIndex); + unlockIndices(header->indexBuffer); + + VertexStream *s; + p = data; + for(int i = 0; i < 2; i++){ + stream->read8(p, 16); + s = &header->vertexStream[i]; + s->vertexBuffer = (void*)(uintptr)*(uint32*)p; p += 4; + s->offset = 0; p += 4; + s->stride = *(uint32*)p; p += 4; + s->geometryFlags = *(uint16*)p; p += 2; + s->managed = *p++; + s->dynamicLock = *p++; + + if(s->vertexBuffer == nil) + continue; + // TODO: use dynamic VB when doing morphing + assert(s->vertexBuffer == nil); + s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, false); + uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + stream->read8(verts, s->stride*header->totalNumVertex); + unlockVertices(s->vertexBuffer); + } + + // TODO: somehow depends on number of streams used (baseIndex = minVert when more than one) + inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + inst->baseIndex = inst->minVert + header->vertexStream[0].offset / header->vertexStream[0].stride; + inst++; + } + + rwFree(data); + return stream; +} + +Stream* +writeNativeData(Stream *stream, int32 len, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + writeChunkHeader(stream, ID_STRUCT, len-12); + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D9) + return stream; + stream->writeU32(PLATFORM_D3D9); + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + int32 size = 64 + geometry->meshHeader->numMeshes*36; + uint8 *data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_GEOMETRY); + stream->writeI32(size); + + uint8 *p = data; + *(uint32*)p = header->serialNumber; p += 4; + *(uint32*)p = header->numMeshes; p += 4; + p += 4; // skip index buffer + *(uint32*)p = header->primType; p += 4; + p += 16*2; // skip vertex streams, they're repeated with the vertex buffers + *(bool32*)p = header->useOffsets; p += 4; + p += 4; // skip vertex declaration + *(uint32*)p = header->totalNumIndex; p += 4; + *(uint32*)p = header->totalNumVertex; p += 4; + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + *(uint32*)p = inst->numIndex; p += 4; + *(uint32*)p = inst->minVert; p += 4; + int32 matid = geometry->matList.findIndex(inst->material); + *(int32*)p = matid; p += 4; + *(bool32*)p = inst->vertexAlpha; p += 4; + *(uint32*)p = 0; p += 4; // vertex shader + *(uint32*)p = inst->baseIndex; p += 4; // not used but meh... + *(uint32*)p = inst->numVertices; p += 4; + *(uint32*)p = inst->startIndex; p += 4; + *(uint32*)p = inst->numPrimitives; p += 4; + inst++; + } + stream->write8(data, size); + + VertexElement elements[NUMDECLELT]; + uint32 numElt = getDeclaration(header->vertexDeclaration, elements); + stream->writeU32(numElt); + stream->write8(elements, 8*numElt); + + uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); + stream->write8(indices, 2*header->totalNumIndex); + unlockIndices(header->indexBuffer); + + VertexStream *s; + for(int i = 0; i < 2; i++){ + s = &header->vertexStream[i]; + p = data; + *(uint32*)p = s->vertexBuffer ? 0xbadeaffe : 0; p += 4; + *(uint32*)p = s->offset; p += 4; + *(uint32*)p = s->stride; p += 4; + *(uint16*)p = s->geometryFlags; p += 2; + *p++ = s->managed; + *p++ = s->dynamicLock; + stream->write8(data, 16); + + if(s->vertexBuffer == nil) + continue; + uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + stream->write8(verts, s->stride*header->totalNumVertex); + unlockVertices(s->vertexBuffer); + } + + rwFree(data); + return stream; +} + +int32 +getSizeNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_D3D9) + return 0; + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + int32 size = 12 + 4 + 4 + 64 + header->numMeshes*36; + uint32 numElt = getDeclaration(header->vertexDeclaration, nil); + size += 4 + numElt*8; + size += 2*header->totalNumIndex; + size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex; + size += 0x10 + header->vertexStream[1].stride*header->totalNumVertex; + return size; +} + +void +registerNativeDataPlugin(void) +{ + Geometry::registerPlugin(0, ID_NATIVEDATA, + nil, destroyNativeData, nil); + Geometry::registerPluginStream(ID_NATIVEDATA, + readNativeData, + writeNativeData, + getSizeNativeData); +} + +static InstanceDataHeader* +instanceMesh(rw::ObjPipeline *rwpipe, Geometry *geo) +{ + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + MeshHeader *meshh = geo->meshHeader; + header->platform = PLATFORM_D3D9; + + header->serialNumber = meshh->serialNum; + header->numMeshes = meshh->numMeshes; + header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; + header->useOffsets = 0; + header->vertexDeclaration = nil; + header->totalNumVertex = geo->numVertices; + header->totalNumIndex = meshh->totalIndices; + header->inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + + header->indexBuffer = createIndexBuffer(header->totalNumIndex*2, false); + + uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); + InstanceData *inst = header->inst; + Mesh *mesh = meshh->getMeshes(); + uint32 startindex = 0; + for(uint32 i = 0; i < header->numMeshes; i++){ + findMinVertAndNumVertices(mesh->indices, mesh->numIndices, + &inst->minVert, (int32*)&inst->numVertices); + inst->numIndex = mesh->numIndices; + inst->material = mesh->material; + inst->vertexAlpha = 0; + inst->vertexShader = nil; + inst->baseIndex = inst->minVert; + inst->startIndex = startindex; + inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3; + if(inst->minVert == 0) + memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*2); + else + for(uint32 j = 0; j < inst->numIndex; j++) + indices[inst->startIndex+j] = mesh->indices[j] - inst->minVert; + startindex += inst->numIndex; + mesh++; + inst++; + } + unlockIndices(header->indexBuffer); + + memset(&header->vertexStream, 0, 2*sizeof(VertexStream)); + + return header; +} + +static void +instance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + // don't try to (re)instance native data + if(geo->flags & Geometry::NATIVE) + return; + + InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; + if(geo->instData){ + // Already have instanced data, so check if we have to reinstance + assert(header->platform == PLATFORM_D3D9); + if(header->serialNumber != geo->meshHeader->serialNum){ + // Mesh changed, so reinstance everything + freeInstanceData(geo); + } + } + + // no instance or complete reinstance + if(geo->instData == nil){ + geo->instData = instanceMesh(rwpipe, geo); + pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 0); + }else if(geo->lockedSinceInst) + pipe->instanceCB(geo, (InstanceDataHeader*)geo->instData, 1); + + geo->lockedSinceInst = 0; +} + +static void +uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + if((geo->flags & Geometry::NATIVE) == 0) + return; + assert(geo->instData != nil); + assert(geo->instData->platform == PLATFORM_D3D9); + geo->numTriangles = geo->meshHeader->guessNumTriangles(); + geo->allocateData(); + geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0); + + InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; + uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); + InstanceData *inst = header->inst; + Mesh *mesh = geo->meshHeader->getMeshes(); + for(uint32 i = 0; i < header->numMeshes; i++){ + if(inst->minVert == 0) + memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2); + else + for(uint32 j = 0; j < inst->numIndex; j++) + mesh->indices[j] = indices[inst->startIndex+j] + inst->minVert; + mesh++; + inst++; + } + unlockIndices(header->indexBuffer); + + pipe->uninstanceCB(geo, header); + geo->generateTriangles(); + geo->flags &= ~Geometry::NATIVE; + destroyNativeData(geo, 0, 0); +} + +static void +render(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + pipe->instance(atomic); + assert(geo->instData != nil); + assert(geo->instData->platform == PLATFORM_D3D9); + if(pipe->renderCB) + pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData); +} + +void +ObjPipeline::init(void) +{ + this->rw::ObjPipeline::init(PLATFORM_D3D9); + this->impl.instance = d3d9::instance; + this->impl.uninstance = d3d9::uninstance; + this->impl.render = d3d9::render; + this->instanceCB = nil; + this->uninstanceCB = nil; + this->renderCB = nil; +} + +ObjPipeline* +ObjPipeline::create(void) +{ + ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL); + pipe->init(); + return pipe; +} + +void +defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) +{ + int i = 0; + VertexElement dcl[NUMDECLELT]; + VertexStream *s = &header->vertexStream[0]; + + bool isPrelit = (geo->flags & Geometry::PRELIT) != 0; + bool hasNormals = (geo->flags & Geometry::NORMALS) != 0; + + // TODO: support both vertex buffers + + if(!reinstance){ + // Create declarations and buffers only the first time + + assert(s->vertexBuffer == nil); + s->offset = 0; + s->managed = 1; + s->geometryFlags = 0; + s->dynamicLock = 0; + + dcl[i].stream = 0; + dcl[i].offset = 0; + dcl[i].type = D3DDECLTYPE_FLOAT3; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_POSITION; + dcl[i].usageIndex = 0; + i++; + uint16 stride = 12; + s->geometryFlags |= 0x2; + + if(isPrelit){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + s->geometryFlags |= 0x8; + stride += 4; + } + + for(int32 n = 0; n < geo->numTexCoordSets; n++){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = (uint8)n; + i++; + s->geometryFlags |= 0x10 << n; + stride += 8; + } + + if(hasNormals){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_FLOAT3; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_NORMAL; + dcl[i].usageIndex = 0; + i++; + s->geometryFlags |= 0x4; + stride += 12; + } + + // We expect some attributes to always be there, use the constant buffer as fallback + if(!isPrelit){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, color); + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + } + if(geo->numTexCoordSets == 0){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, texCoors[0]); + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = 0; + i++; + } + + dcl[i] = D3DDECL_END(); + s->stride = stride; + + assert(header->vertexDeclaration == nil); + header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); + + assert(s->vertexBuffer == nil); + s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false); + }else + getDeclaration(header->vertexDeclaration, dcl); + + uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + + // Instance vertices + if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) + ; + instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->morphTargets[0].vertices, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + // Instance prelight colors + if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) + ; + InstanceData *inst = header->inst; + uint32 n = header->numMeshes; + while(n--){ + uint32 stride = header->vertexStream[dcl[i].stream].stride; + inst->vertexAlpha = instColor(vertFormatMap[dcl[i].type], + verts + dcl[i].offset + stride*inst->minVert, + geo->colors + inst->minVert, + inst->numVertices, + stride); + inst++; + } + } + + // Instance tex coords + for(int32 n = 0; n < geo->numTexCoordSets; n++){ + if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++) + ; + instTexCoords(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->texCoords[n], + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + } + + // Instance normals + if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) + ; + instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->morphTargets[0].normals, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + unlockVertices(s->vertexBuffer); +} + +void +defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + VertexElement dcl[NUMDECLELT]; + + uint8 *verts[2]; + verts[0] = lockVertices(header->vertexStream[0].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + verts[1] = lockVertices(header->vertexStream[1].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + getDeclaration(header->vertexDeclaration, dcl); + + int i; + for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) + ; + uninstV3d(vertFormatMap[dcl[i].type], + geo->morphTargets[0].vertices, + verts[dcl[i].stream] + dcl[i].offset, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + + if(geo->flags & Geometry::PRELIT){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) + ; + uninstColor(vertFormatMap[dcl[i].type], + geo->colors, + verts[dcl[i].stream] + dcl[i].offset, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + for(int32 n = 0; n < geo->numTexCoordSets; n++){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++) + ; + uninstTexCoords(vertFormatMap[dcl[i].type], + geo->texCoords[n], + verts[dcl[i].stream] + dcl[i].offset, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + if(geo->flags & Geometry::NORMALS){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) + ; + uninstV3d(vertFormatMap[dcl[i].type], + geo->morphTargets[0].normals, + verts[dcl[i].stream] + dcl[i].offset, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + unlockVertices(verts[0]); + unlockVertices(verts[1]); +} + +ObjPipeline* +makeDefaultPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB_Shader; + return pipe; +} + +// Native Texture and Raster + +Texture* +readNativeTexture(Stream *stream) +{ + uint32 platform; + if(!findChunk(stream, ID_STRUCT, nil, nil)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_D3D9){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + Texture *tex = Texture::create(nil); + if(tex == nil) + return nil; + + // Texture + tex->filterAddressing = stream->readU32(); + stream->read8(tex->name, 32); + stream->read8(tex->mask, 32); + + // Raster + int32 format = stream->readI32(); + int32 d3dformat = stream->readI32(); + int32 width = stream->readU16(); + int32 height = stream->readU16(); + int32 depth = stream->readU8(); + int32 numLevels = stream->readU8(); + int32 type = stream->readU8(); +/* +#define HAS_ALPHA (1<<0) +#define IS_CUBE (1<<1) +#define USE_AUTOMIPMAPGEN (1<<2) +#define IS_COMPRESSED (1<<3) +*/ + int32 flags = stream->readU8(); + + Raster *raster; + D3dRaster *ext; + + if(flags & 8){ + // is compressed + assert((flags & 2) == 0 && "Can't have cube maps yet"); + raster = Raster::create(width, height, depth, format | type | Raster::DONTALLOCATE, PLATFORM_D3D9); + assert(raster); + ext = GETD3DRASTEREXT(raster); + ext->format = d3dformat; + ext->hasAlpha = flags & 1; + ext->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? numLevels : 1, + 0, + ext->format); + assert(ext->texture); + raster->flags &= ~Raster::DONTALLOCATE; + ext->customFormat = 1; + }else if(flags & 2){ + assert(0 && "Can't have cube maps yet"); + }else{ + raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D9); + assert(raster); + ext = GETD3DRASTEREXT(raster); + } + tex->raster = raster; + + // TODO: check if format supported and convert if necessary + + if(raster->format & Raster::PAL4) + stream->read8(ext->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->read8(ext->palette, 4*256); + + uint32 size; + uint8 *data; + for(int32 i = 0; i < numLevels; i++){ + size = stream->readU32(); + if(i < raster->getNumLevels()){ + data = raster->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + stream->read8(data, size); + raster->unlock(i); + }else + stream->seek(size); + } + return tex; +} + +void +writeNativeTexture(Texture *tex, Stream *stream) +{ + int32 chunksize = getSizeNativeTexture(tex); + writeChunkHeader(stream, ID_STRUCT, chunksize-12); + stream->writeU32(PLATFORM_D3D9); + + // Texture + stream->writeU32(tex->filterAddressing); + stream->write8(tex->name, 32); + stream->write8(tex->mask, 32); + + // Raster + Raster *raster = tex->raster; + D3dRaster *ext = GETD3DRASTEREXT(raster); + int32 numLevels = raster->getNumLevels(); + stream->writeI32(raster->format); + stream->writeU32(ext->format); + stream->writeU16(raster->width); + stream->writeU16(raster->height); + stream->writeU8(raster->depth); + stream->writeU8(numLevels); + stream->writeU8(raster->type); + uint8 flags = 0; + if(ext->hasAlpha) + flags |= 1; + // no cube supported yet + if(ext->autogenMipmap) + flags |= 4; + if(ext->customFormat) + flags |= 8; + stream->writeU8(flags); + + if(raster->format & Raster::PAL4) + stream->write8(ext->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->write8(ext->palette, 4*256); + + uint32 size; + uint8 *data; + for(int32 i = 0; i < numLevels; i++){ + size = getLevelSize(raster, i); + stream->writeU32(size); + data = raster->lock(i, Raster::LOCKREAD); + stream->write8(data, size); + raster->unlock(i); + } +} + +uint32 +getSizeNativeTexture(Texture *tex) +{ + uint32 size = 12 + 72 + 16; + int32 levels = tex->raster->getNumLevels(); + if(tex->raster->format & Raster::PAL4) + size += 4*32; + else if(tex->raster->format & Raster::PAL8) + size += 4*256; + for(int32 i = 0; i < levels; i++) + size += 4 + getLevelSize(tex->raster, i); + return size; +} + +} +} diff --git a/src/d3d/d3d9matfx.cpp b/src/d3d/d3d9matfx.cpp new file mode 100644 index 0000000..d544e65 --- /dev/null +++ b/src/d3d/d3d9matfx.cpp @@ -0,0 +1,313 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwrender.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d9.h" + +namespace rw { +namespace d3d9 { +using namespace d3d; + +#ifndef RW_D3D9 +void matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) {} +#else + +static void *matfx_env_amb_VS; +static void *matfx_env_amb_dir_VS; +static void *matfx_env_all_VS; +static void *matfx_env_PS; +static void *matfx_env_tex_PS; + +enum +{ + VSLOC_texMat = VSLOC_afterLights, + VSLOC_colorClamp = VSLOC_texMat + 4, + VSLOC_envColor, + + PSLOC_shininess = 1, +}; + +void +matfxRender_Default(InstanceDataHeader *header, InstanceData *inst, int32 lightBits) +{ + Material *m = inst->material; + + // Pick a shader + if((lightBits & VSLIGHT_MASK) == 0) + setVertexShader(default_amb_VS); + else if((lightBits & VSLIGHT_MASK) == VSLIGHT_DIRECT) + setVertexShader(default_amb_dir_VS); + else + setVertexShader(default_all_VS); + + SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255); + + if(inst->material->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(default_tex_PS); + }else + setPixelShader(default_PS); + + drawInst(header, inst); +} + +static Frame *lastEnvFrame; + +static RawMatrix normal2texcoord = { + { 0.5f, 0.0f, 0.0f }, 0.0f, + { 0.0f, -0.5f, 0.0f }, 0.0f, + { 0.0f, 0.0f, 1.0f }, 0.0f, + { 0.5f, 0.5f, 0.0f }, 1.0f +}; + +void +uploadEnvMatrix(Frame *frame) +{ + Matrix invMat; + if(frame == nil) + frame = engine->currentCamera->getFrame(); + + // cache the matrix across multiple meshes +// can't do it, frame matrix may change +// if(frame == lastEnvFrame) +// return; +// lastEnvFrame = frame; + + RawMatrix envMtx, invMtx; + Matrix::invert(&invMat, frame->getLTM()); + convMatrix(&invMtx, &invMat); + invMtx.pos.set(0.0f, 0.0f, 0.0f); + float uscale = fabs(normal2texcoord.right.x); + normal2texcoord.right.x = MatFX::envMapFlipU ? -uscale : uscale; + RawMatrix::mult(&envMtx, &invMtx, &normal2texcoord); + d3ddevice->SetVertexShaderConstantF(VSLOC_texMat, (float*)&envMtx, 4); +} + +void +matfxRender_EnvMap(InstanceDataHeader *header, InstanceData *inst, int32 lightBits, MatFX::Env *env) +{ + Material *m = inst->material; + + if(env->tex == nil || env->coefficient == 0.0f){ + matfxRender_Default(header, inst, lightBits); + return; + } + + d3d::setTexture(1, env->tex); + uploadEnvMatrix(env->frame); + + SetRenderState(SRCBLEND, BLENDONE); + + static float zero[4]; + static float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + struct { + float shininess; + float disableFBA; + float unused[2]; + } fxparams; + fxparams.shininess = env->coefficient; + fxparams.disableFBA = env->fbAlpha ? 0.0f : 1.0f; + d3ddevice->SetPixelShaderConstantF(PSLOC_shininess, (float*)&fxparams, 1); + // This clamps the vertex color below. With it we can achieve both PC and PS2 style matfx + if(MatFX::envMapApplyLight) + d3ddevice->SetVertexShaderConstantF(VSLOC_colorClamp, zero, 1); + else + d3ddevice->SetVertexShaderConstantF(VSLOC_colorClamp, one, 1); + RGBAf envcol[4]; + if(MatFX::envMapUseMatColor) + convColor(envcol, &m->color); + else + convColor(envcol, &MatFX::envMapColor); + d3ddevice->SetVertexShaderConstantF(VSLOC_envColor, (float*)&envcol, 1); + + // Pick a shader + if((lightBits & VSLIGHT_MASK) == 0) + setVertexShader(matfx_env_amb_VS); + else if((lightBits & VSLIGHT_MASK) == VSLIGHT_DIRECT) + setVertexShader(matfx_env_amb_dir_VS); + else + setVertexShader(matfx_env_all_VS); + + bool32 texAlpha = GETD3DRASTEREXT(env->tex->raster)->hasAlpha; + + if(inst->material->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(matfx_env_tex_PS); + }else + setPixelShader(matfx_env_PS); + + SetRenderState(VERTEXALPHA, texAlpha || inst->vertexAlpha || m->color.alpha != 255); + + drawInst(header, inst); + + SetRenderState(SRCBLEND, BLENDSRCALPHA); +} + +void +matfxRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) +{ + int vsBits; + uint32 flags = atomic->geometry->flags; + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + 0, header->vertexStream[0].stride); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + + lastEnvFrame = nil; + + vsBits = lightingCB_Shader(atomic); + uploadMatrices(atomic->getFrame()->getLTM()); + + bool normals = !!(atomic->geometry->flags & Geometry::NORMALS); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + Material *m = inst->material; + + setMaterial(flags, m->color, m->surfaceProps); + + MatFX *matfx = MatFX::get(m); + if(matfx == nil) + matfxRender_Default(header, inst, vsBits); + else switch(matfx->type){ + case MatFX::ENVMAP: + if(normals) + matfxRender_EnvMap(header, inst, vsBits, &matfx->fx[0].env); + else + matfxRender_Default(header, inst, vsBits); + break; + case MatFX::NOTHING: + case MatFX::BUMPMAP: + case MatFX::BUMPENVMAP: + case MatFX::DUAL: + case MatFX::UVTRANSFORM: + case MatFX::DUALUVTRANSFORM: + // not supported yet + matfxRender_Default(header, inst, vsBits); + break; + } + + inst++; + } + d3d::setTexture(1, nil); +} + +#define VS_NAME g_vs20_main +#define PS_NAME g_ps20_main + +void +createMatFXShaders(void) +{ + { + static +#include "shaders/matfx_env_amb_VS.h" + matfx_env_amb_VS = createVertexShader((void*)VS_NAME); + assert(matfx_env_amb_VS); + } + { + static +#include "shaders/matfx_env_amb_dir_VS.h" + matfx_env_amb_dir_VS = createVertexShader((void*)VS_NAME); + assert(matfx_env_amb_dir_VS); + } + { + static +#include "shaders/matfx_env_all_VS.h" + matfx_env_all_VS = createVertexShader((void*)VS_NAME); + assert(matfx_env_all_VS); + } + + + { + static +#include "shaders/matfx_env_PS.h" + matfx_env_PS = createPixelShader((void*)PS_NAME); + assert(matfx_env_PS); + } + { + static +#include "shaders/matfx_env_tex_PS.h" + matfx_env_tex_PS = createPixelShader((void*)PS_NAME); + assert(matfx_env_tex_PS); + } + +} + +void +destroyMatFXShaders(void) +{ + destroyVertexShader(matfx_env_amb_VS); + matfx_env_amb_VS = nil; + + destroyVertexShader(matfx_env_amb_dir_VS); + matfx_env_amb_dir_VS = nil; + + destroyVertexShader(matfx_env_all_VS); + matfx_env_all_VS = nil; + + + destroyPixelShader(matfx_env_PS); + matfx_env_PS = nil; + + destroyPixelShader(matfx_env_tex_PS); + matfx_env_tex_PS = nil; +} + +#endif + +static void* +matfxOpen(void *o, int32, int32) +{ +#ifdef RW_D3D9 + createMatFXShaders(); +#endif + + matFXGlobals.pipelines[PLATFORM_D3D9] = makeMatFXPipeline(); + return o; +} + +static void* +matfxClose(void *o, int32, int32) +{ +#ifdef RW_D3D9 + destroyMatFXShaders(); +#endif + + ((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_D3D9])->destroy(); + matFXGlobals.pipelines[PLATFORM_D3D9] = nil; + return o; +} + +void +initMatFX(void) +{ + Driver::registerPlugin(PLATFORM_D3D9, 0, ID_MATFX, + matfxOpen, matfxClose); +} + +ObjPipeline* +makeMatFXPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = matfxRenderCB_Shader; + pipe->pluginID = ID_MATFX; + pipe->pluginData = 0; + return pipe; +} + +} +} diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp new file mode 100644 index 0000000..89d937f --- /dev/null +++ b/src/d3d/d3d9render.cpp @@ -0,0 +1,185 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "../rwrender.h" +#include "rwd3d.h" +#include "rwd3d9.h" + +namespace rw { +namespace d3d9 { +using namespace d3d; + +#ifndef RW_D3D9 +void defaultRenderCB(Atomic*, InstanceDataHeader*) {} +void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) {} +#else + +void +drawInst_simple(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) +{ + d3d::flushCache(); + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, + 0, inst->numVertices, + inst->startIndex, inst->numPrimitives); +} + +// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer +void +drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst) +{ + uint32 hasAlpha; + int alphafunc, alpharef, gsalpharef; + int zwrite; + d3d::getRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); + if(hasAlpha){ + zwrite = rw::GetRenderState(rw::ZWRITEENABLE); + alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC); + if(zwrite){ + alpharef = rw::GetRenderState(rw::ALPHATESTREF); + gsalpharef = rw::GetRenderState(rw::GSALPHATESTREF); + + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL); + SetRenderState(rw::ALPHATESTREF, gsalpharef); + drawInst_simple(header, inst); + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS); + SetRenderState(rw::ZWRITEENABLE, 0); + drawInst_simple(header, inst); + SetRenderState(rw::ZWRITEENABLE, 1); + SetRenderState(rw::ALPHATESTFUNC, alphafunc); + SetRenderState(rw::ALPHATESTREF, alpharef); + }else{ + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS); + drawInst_simple(header, inst); + SetRenderState(rw::ALPHATESTFUNC, alphafunc); + } + }else + drawInst_simple(header, inst); +} + +void +drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) +{ + if(rw::GetRenderState(rw::GSALPHATEST)) + drawInst_GSemu(header, inst); + else + drawInst_simple(header, inst); +} + +/* +void +defaultRenderCB_Fix(Atomic *atomic, InstanceDataHeader *header) +{ + RawMatrix world; + Geometry *geo = atomic->geometry; + + int lighting = !!(geo->flags & rw::Geometry::LIGHT); + if(lighting) + d3d::lightingCB_Fix(atomic); + + d3d::setRenderState(D3DRS_LIGHTING, lighting); + + Frame *f = atomic->getFrame(); + convMatrix(&world, f->getLTM()); + d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world); + + setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); + setIndices(header->indexBuffer); + setVertexDeclaration(header->vertexDeclaration); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + SetRenderState(VERTEXALPHA, inst->vertexAlpha || inst->material->color.alpha != 255); + const static rw::RGBA white = { 255, 255, 255, 255 }; + d3d::setMaterial(white, inst->material->surfaceProps); + + d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); + if(geo->flags & Geometry::PRELIT) + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + else + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, inst->vertexAlpha ? D3DMCS_COLOR1 : D3DMCS_MATERIAL); + + if(inst->material->texture){ + // Texture + d3d::setTexture(0, inst->material->texture); + d3d::setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + d3d::setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT); + d3d::setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + d3d::setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d::setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + d3d::setTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + }else{ + d3d::setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3d::setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT); + d3d::setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + d3d::setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + } + + // Material colour + const rw::RGBA *col = &inst->material->color; + d3d::setTextureStageState(1, D3DTSS_CONSTANT, D3DCOLOR_ARGB(col->alpha,col->red,col->green,col->blue)); + d3d::setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + d3d::setTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); + d3d::setTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CONSTANT); + d3d::setTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d::setTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); + d3d::setTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CONSTANT); + + drawInst(header, inst); + inst++; + } + d3d::setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + d3d::setTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); +} +*/ + +void +defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header) +{ + int vsBits; + uint32 flags = atomic->geometry->flags; + setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); + setIndices(header->indexBuffer); + setVertexDeclaration(header->vertexDeclaration); + + vsBits = lightingCB_Shader(atomic); + uploadMatrices(atomic->getFrame()->getLTM()); + + // Pick a shader + if((vsBits & VSLIGHT_MASK) == 0) + setVertexShader(default_amb_VS); + else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT) + setVertexShader(default_amb_dir_VS); + else + setVertexShader(default_all_VS); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + Material *m = inst->material; + + SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255); + + setMaterial(flags, m->color, m->surfaceProps); + + if(m->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(default_tex_PS); + }else + setPixelShader(default_PS); + + drawInst(header, inst); + inst++; + } +} + +#endif +} +} diff --git a/src/d3d/d3d9skin.cpp b/src/d3d/d3d9skin.cpp new file mode 100644 index 0000000..86c79ab --- /dev/null +++ b/src/d3d/d3d9skin.cpp @@ -0,0 +1,418 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwrender.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d9.h" + +namespace rw { +namespace d3d9 { +using namespace d3d; + +#ifndef RW_D3D9 +void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) {} +void skinRenderCB(Atomic *atomic, InstanceDataHeader *header) {} +#else + + +static void *skin_amb_VS; +static void *skin_amb_dir_VS; +static void *skin_all_VS; + +#define NUMDECLELT 14 + +void +skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance) +{ + int i = 0; + VertexElement dcl[NUMDECLELT]; + VertexStream *s = &header->vertexStream[0]; + + bool isPrelit = (geo->flags & Geometry::PRELIT) != 0; + bool hasNormals = (geo->flags & Geometry::NORMALS) != 0; + + // TODO: support both vertex buffers + + if(!reinstance){ + // Create declarations and buffers only the first time + + assert(s->vertexBuffer == nil); + s->offset = 0; + s->managed = 1; + s->geometryFlags = 0; + s->dynamicLock = 0; + + dcl[i].stream = 0; + dcl[i].offset = 0; + dcl[i].type = D3DDECLTYPE_FLOAT3; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_POSITION; + dcl[i].usageIndex = 0; + i++; + uint16 stride = 12; + s->geometryFlags |= 0x2; + + if(isPrelit){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + s->geometryFlags |= 0x8; + stride += 4; + } + + for(int32 n = 0; n < geo->numTexCoordSets; n++){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = (uint8)n; + i++; + s->geometryFlags |= 0x10 << n; + stride += 8; + } + + if(hasNormals){ + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_FLOAT3; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_NORMAL; + dcl[i].usageIndex = 0; + i++; + s->geometryFlags |= 0x4; + stride += 12; + } + + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_FLOAT4; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_BLENDWEIGHT; + dcl[i].usageIndex = 0; + i++; + stride += 16; + + dcl[i].stream = 0; + dcl[i].offset = stride; + dcl[i].type = D3DDECLTYPE_UBYTE4; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_BLENDINDICES; + dcl[i].usageIndex = 0; + i++; + stride += 4; + + // We expect some attributes to always be there, use the constant buffer as fallback + if(!isPrelit){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, color); + dcl[i].type = D3DDECLTYPE_D3DCOLOR; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_COLOR; + dcl[i].usageIndex = 0; + i++; + } + if(geo->numTexCoordSets == 0){ + dcl[i].stream = 2; + dcl[i].offset = offsetof(VertexConstantData, texCoors[0]); + dcl[i].type = D3DDECLTYPE_FLOAT2; + dcl[i].method = D3DDECLMETHOD_DEFAULT; + dcl[i].usage = D3DDECLUSAGE_TEXCOORD; + dcl[i].usageIndex = 0; + i++; + } + + dcl[i] = D3DDECL_END(); + s->stride = stride; + + assert(header->vertexDeclaration == nil); + header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); + + assert(s->vertexBuffer == nil); + s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, false); + }else + getDeclaration(header->vertexDeclaration, dcl); + + Skin *skin = Skin::get(geo); + uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); + + // Instance vertices + if(!reinstance || geo->lockedSinceInst&Geometry::LOCKVERTICES){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) + ; + instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->morphTargets[0].vertices, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + // Instance prelight colors + if(isPrelit && (!reinstance || geo->lockedSinceInst&Geometry::LOCKPRELIGHT)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) + ; + InstanceData *inst = header->inst; + uint32 n = header->numMeshes; + while(n--){ + uint32 stride = header->vertexStream[dcl[i].stream].stride; + inst->vertexAlpha = instColor(vertFormatMap[dcl[i].type], + verts + dcl[i].offset + stride*inst->minVert, + geo->colors + inst->minVert, + inst->numVertices, + stride); + inst++; + } + } + + // Instance tex coords + for(int32 n = 0; n < geo->numTexCoordSets; n++){ + if(!reinstance || geo->lockedSinceInst&(Geometry::LOCKTEXCOORDS<<n)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++) + ; + instTexCoords(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->texCoords[n], + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + } + + // Instance normals + if(hasNormals && (!reinstance || geo->lockedSinceInst&Geometry::LOCKNORMALS)){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) + ; + instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + geo->morphTargets[0].normals, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + // Instance skin weights + if(!reinstance){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_BLENDWEIGHT || dcl[i].usageIndex != 0; i++) + ; + instV4d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + (V4d*)skin->weights, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + // Instance skin indices + if(!reinstance){ + for(i = 0; dcl[i].usage != D3DDECLUSAGE_BLENDINDICES || dcl[i].usageIndex != 0; i++) + ; + // not really colors of course but what the heck + instColor(vertFormatMap[dcl[i].type], verts + dcl[i].offset, + (RGBA*)skin->indices, + header->totalNumVertex, + header->vertexStream[dcl[i].stream].stride); + } + + unlockVertices(s->vertexBuffer); +} + +enum +{ + VSLOC_boneMatrices = VSLOC_afterLights +}; + +static float skinMatrices[64*16]; + +void +uploadSkinMatrices(Atomic *a) +{ + int i; + Skin *skin = Skin::get(a->geometry); + float *m = skinMatrices; + HAnimHierarchy *hier = Skin::getHierarchy(a); + + if(hier){ + Matrix *invMats = (Matrix*)skin->inverseMatrices; + Matrix tmp, tmp2; + + assert(skin->numBones == hier->numNodes); + if(hier->flags & HAnimHierarchy::LOCALSPACEMATRICES){ + for(i = 0; i < hier->numNodes; i++){ + invMats[i].flags = 0; + Matrix::mult(&tmp, &invMats[i], &hier->matrices[i]); + RawMatrix::transpose((RawMatrix*)m, (RawMatrix*)&tmp); + m += 12; + } + }else{ + Matrix invAtmMat; + Matrix::invert(&invAtmMat, a->getFrame()->getLTM()); + for(i = 0; i < hier->numNodes; i++){ + invMats[i].flags = 0; + Matrix::mult(&tmp, &hier->matrices[i], &invAtmMat); + Matrix::mult(&tmp2, &invMats[i], &tmp); + RawMatrix::transpose((RawMatrix*)m, (RawMatrix*)&tmp2); + m += 12; + } + } + }else{ + for(i = 0; i < skin->numBones; i++){ + m[0] = 1.0f; + m[1] = 0.0f; + m[2] = 0.0f; + m[3] = 0.0f; + + m[4] = 0.0f; + m[5] = 1.0f; + m[6] = 0.0f; + m[7] = 0.0f; + + m[8] = 0.0f; + m[9] = 0.0f; + m[10] = 1.0f; + m[11] = 0.0f; + + m += 12; + } + } + d3ddevice->SetVertexShaderConstantF(VSLOC_boneMatrices, skinMatrices, skin->numBones*3); +} + +void +skinRenderCB(Atomic *atomic, InstanceDataHeader *header) +{ + int vsBits; + uint32 flags = atomic->geometry->flags; + setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, + 0, header->vertexStream[0].stride); + setIndices((IDirect3DIndexBuffer9*)header->indexBuffer); + setVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); + + vsBits = lightingCB_Shader(atomic); + uploadMatrices(atomic->getFrame()->getLTM()); + + uploadSkinMatrices(atomic); + + // Pick a shader + if((vsBits & VSLIGHT_MASK) == 0) + setVertexShader(skin_amb_VS); + else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT) + setVertexShader(skin_amb_dir_VS); + else + setVertexShader(skin_all_VS); + + InstanceData *inst = header->inst; + for(uint32 i = 0; i < header->numMeshes; i++){ + Material *m = inst->material; + + SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255); + + setMaterial(flags, m->color, m->surfaceProps); + + if(inst->material->texture){ + d3d::setTexture(0, m->texture); + setPixelShader(default_tex_PS); + }else + setPixelShader(default_PS); + + drawInst(header, inst); + inst++; + } +} + +#define VS_NAME g_vs20_main +#define PS_NAME g_ps20_main + +void +createSkinShaders(void) +{ + { + static +#include "shaders/skin_amb_VS.h" + skin_amb_VS = createVertexShader((void*)VS_NAME); + assert(skin_amb_VS); + } + { + static +#include "shaders/skin_amb_dir_VS.h" + skin_amb_dir_VS = createVertexShader((void*)VS_NAME); + assert(skin_amb_dir_VS); + } + // Skinning takes a lot of instructions....lighting may be not possible + // TODO: should do something about this + { + static +#include "shaders/skin_all_VS.h" + skin_all_VS = createVertexShader((void*)VS_NAME); +// assert(skin_all_VS); + } +} + +void +destroySkinShaders(void) +{ + destroyVertexShader(skin_amb_VS); + skin_amb_VS = nil; + + destroyVertexShader(skin_amb_dir_VS); + skin_amb_dir_VS = nil; + + if(skin_all_VS){ + destroyVertexShader(skin_all_VS); + skin_all_VS = nil; + } +} + +#endif + +static void* +skinOpen(void *o, int32, int32) +{ +#ifdef RW_D3D9 + createSkinShaders(); +#endif + + skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline(); + return o; +} + +static void* +skinClose(void *o, int32, int32) +{ +#ifdef RW_D3D9 + destroySkinShaders(); +#endif + + ((ObjPipeline*)skinGlobals.pipelines[PLATFORM_D3D9])->destroy(); + skinGlobals.pipelines[PLATFORM_D3D9] = nil; + return o; +} + +void +initSkin(void) +{ + Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN, + skinOpen, skinClose); +} + +ObjPipeline* +makeSkinPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = skinInstanceCB; + pipe->uninstanceCB = nil; + pipe->renderCB = skinRenderCB; + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; + return pipe; +} + +} +} diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp new file mode 100644 index 0000000..62c46b8 --- /dev/null +++ b/src/d3d/d3ddevice.cpp @@ -0,0 +1,2022 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwplg.h" +#include "../rwerror.h" +#include "../rwrender.h" +#include "../rwengine.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "rwd3d.h" +#include "rwd3dimpl.h" + +#define PLUGIN_ID 0 + +namespace rw { +namespace d3d { + +#ifdef RW_D3D9 + +D3d9Globals d3d9Globals; + +// Keep track of rasters exclusively in video memory +// as they need special treatment sometimes +struct VidmemRaster +{ + Raster *raster; + VidmemRaster *next; +}; +static VidmemRaster *vidmemRasters; +void addVidmemRaster(Raster *raster); +void removeVidmemRaster(Raster *raster); + +// Same thing for dynamic vertex buffers +struct DynamicVB +{ + uint32 length; + uint32 fvf; + IDirect3DVertexBuffer9 **buf; + DynamicVB *next; +}; +static DynamicVB *dynamicVBs; +void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); +void removeDynamicVB(IDirect3DVertexBuffer9 **buf); + +// Same thing for dynamic index buffers +struct DynamicIB +{ + uint32 length; + IDirect3DIndexBuffer9 **buf; + DynamicIB *next; +}; +static DynamicIB *dynamicIBs; +void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); +void removeDynamicIB(IDirect3DIndexBuffer9 **buf); + + +struct RwRasterStateCache { + Raster *raster; + Texture::Addressing addressingU; + Texture::Addressing addressingV; + Texture::FilterMode filter; + int32 maxAniso; +}; + +#define MAXNUMSTAGES 8 + +// cached RW render states +struct RwStateCache { + bool32 vertexAlpha; + bool32 textureAlpha; + uint32 srcblend, destblend; + uint32 zwrite; + uint32 ztest; + uint32 fogenable; + RGBA fogcolor; + uint32 cullmode; + uint32 stencilenable; + uint32 stencilpass; + uint32 stencilfail; + uint32 stencilzfail; + uint32 stencilfunc; + uint32 stencilref; + uint32 stencilmask; + uint32 stencilwritemask; + uint32 alphafunc; + uint32 alpharef; + + // emulation of PS2 GS + bool32 gsalpha; + uint32 gsalpharef; + + RwRasterStateCache texstage[MAXNUMSTAGES]; +}; +static RwStateCache rwStateCache; + +void *constantVertexStream; +static IDirect3DTexture9 *whiteTex; + +D3dShaderState d3dShaderState; + +#define MAXNUMSTATES (D3DRS_BLENDOPALPHA+1) +#define MAXNUMTEXSTATES (D3DTSS_CONSTANT+1) +#define MAXNUMSAMPLERSTATES (D3DSAMP_DMAPOFFSET+1) +#define MAXNUMSTREAMS (3) +#define MAXNUMRENDERTARGETS (4) + +static int32 numDirtyStates; +static uint32 dirtyStates[MAXNUMSTATES]; +static struct { + uint32 value; + bool32 dirty; +} stateCache[MAXNUMSTATES]; +static uint32 d3dStates[MAXNUMSTATES]; + +// Things that aren't just integers +struct D3dDeviceCache { + IDirect3DVertexShader9 *vertexShader; + IDirect3DPixelShader9 *pixelShader; + IDirect3DVertexDeclaration9 *vertexDeclaration; + IDirect3DIndexBuffer9 *indices; + struct { + IDirect3DVertexBuffer9 *buffer; + uint32 offset; + uint32 stride; + } vertexStreams[MAXNUMSTREAMS]; + IDirect3DSurface9 *renderTargets[MAXNUMRENDERTARGETS]; + IDirect3DSurface9 *depthSurface; +}; +static D3dDeviceCache deviceCache; + +static int32 numDirtyTextureStageStates; +static struct { + uint32 stage; + uint32 type; +} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES]; +static struct { + uint32 value; + bool32 dirty; +} textureStageStateCache[MAXNUMTEXSTATES][MAXNUMSTAGES]; +static uint32 d3dTextureStageStates[MAXNUMTEXSTATES][MAXNUMSTAGES]; + +static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES]; + + +static bool validStates[MAXNUMSTATES]; +static bool validTexStates[MAXNUMTEXSTATES]; + +static D3DMATERIAL9 d3dmaterial; + + +static uint32 blendMap[] = { + D3DBLEND_ZERO, // actually invalid + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_SRCCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_SRCALPHA, + D3DBLEND_INVSRCALPHA, + D3DBLEND_DESTALPHA, + D3DBLEND_INVDESTALPHA, + D3DBLEND_DESTCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_SRCALPHASAT +}; + +static uint32 stencilOpMap[] = { + D3DSTENCILOP_KEEP, // actually invalid + D3DSTENCILOP_KEEP, + D3DSTENCILOP_ZERO, + D3DSTENCILOP_REPLACE, + D3DSTENCILOP_INCRSAT, + D3DSTENCILOP_DECRSAT, + D3DSTENCILOP_INVERT, + D3DSTENCILOP_INCR, + D3DSTENCILOP_DECR +}; + +static uint32 stencilFuncMap[] = { + D3DCMP_NEVER, // actually invalid + D3DCMP_NEVER, + D3DCMP_LESS, + D3DCMP_EQUAL, + D3DCMP_LESSEQUAL, + D3DCMP_GREATER, + D3DCMP_NOTEQUAL, + D3DCMP_GREATEREQUAL, + D3DCMP_ALWAYS +}; + +static uint32 alphafuncMap[] = { + D3DCMP_ALWAYS, + D3DCMP_GREATEREQUAL, + D3DCMP_LESS +}; + +static uint32 cullmodeMap[] = { + D3DCULL_NONE, // actually invalid + D3DCULL_NONE, + D3DCULL_CW, + D3DCULL_CCW +}; + +static uint32 filterConvMap[] = { + 0, D3DTEXF_POINT, D3DTEXF_LINEAR, + D3DTEXF_POINT, D3DTEXF_LINEAR, + D3DTEXF_POINT, D3DTEXF_LINEAR +}; +static uint32 filterConvMap_MIP[] = { + 0, D3DTEXF_NONE, D3DTEXF_NONE, + D3DTEXF_POINT, D3DTEXF_POINT, + D3DTEXF_LINEAR, D3DTEXF_LINEAR +}; +static uint32 addressConvMap[] = { + 0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR, + D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER +}; + +// D3D render state + +void +setRenderState(uint32 state, uint32 value) +{ + if(stateCache[state].value != value){ + stateCache[state].value = value; + if(!stateCache[state].dirty){ + stateCache[state].dirty = 1; + dirtyStates[numDirtyStates++] = state; + } + } +} + +void +getRenderState(uint32 state, uint32 *value) +{ + *value = stateCache[state].value; +} + +void +setRenderTarget(int n, void *surf) +{ + if(surf != deviceCache.renderTargets[n]){ + deviceCache.renderTargets[n] = (IDirect3DSurface9*)surf; + d3ddevice->SetRenderTarget(n, deviceCache.renderTargets[n]); + } +} + +void +setDepthSurface(void *surf) +{ + if(surf != deviceCache.depthSurface){ + deviceCache.depthSurface = (IDirect3DSurface9*)surf; + d3ddevice->SetDepthStencilSurface(deviceCache.depthSurface); + } +} + +void +setTextureStageState(uint32 stage, uint32 type, uint32 value) +{ + if(textureStageStateCache[type][stage].value != value){ + textureStageStateCache[type][stage].value = value; + if(!textureStageStateCache[type][stage].dirty){ + textureStageStateCache[type][stage].dirty = 1; + dirtyTextureStageStates[numDirtyTextureStageStates].stage = stage; + dirtyTextureStageStates[numDirtyTextureStageStates].type = type; + numDirtyTextureStageStates++; + } + } +} + +void +getTextureStageState(uint32 stage, uint32 type, uint32 *value) +{ + *value = textureStageStateCache[type][stage].value; +} + +void +flushCache(void) +{ + uint32 s, t; + uint32 v; + for(int32 i = 0; i < numDirtyStates; i++){ + s = dirtyStates[i]; + v = stateCache[s].value; + stateCache[s].dirty = 0; + if(d3dStates[s] != v){ + d3ddevice->SetRenderState((D3DRENDERSTATETYPE)s, v); + d3dStates[s] = v; + } + } + numDirtyStates = 0; + for(int32 i = 0; i < numDirtyTextureStageStates; i++){ + s = dirtyTextureStageStates[i].stage; + t = dirtyTextureStageStates[i].type; + v = textureStageStateCache[t][s].value; + textureStageStateCache[t][s].dirty = 0; + if(d3dTextureStageStates[t][s] != v){ + d3ddevice->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v); + d3dTextureStageStates[t][s] = v; + } + } + numDirtyTextureStageStates = 0; + + if(d3dShaderState.fogDirty){ + d3ddevice->SetVertexShaderConstantF(VSLOC_fogData, (float*)&d3dShaderState.fogData, 1); + d3ddevice->SetPixelShaderConstantF(PSLOC_fogColor, (float*)&d3dShaderState.fogColor, 1); + d3dShaderState.fogDirty = false; + } +} + +void +setSamplerState(uint32 stage, uint32 type, uint32 value) +{ + if(d3dSamplerStates[type][stage] != value){ + d3ddevice->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value); + d3dSamplerStates[type][stage] = value; + } +} + +void +getSamplerState(uint32 stage, uint32 type, uint32 *value) +{ + *value = d3dSamplerStates[type][stage]; +} + +// Bring D3D device in accordance with saved render states (after a reset) +static void +restoreD3d9Device(void) +{ + int32 i; + uint32 s, t; + + for(i = 0; i < MAXNUMSTAGES; i++){ + Raster *raster = rwStateCache.texstage[i].raster; + if(raster){ + D3dRaster *d3draster = GETD3DRASTEREXT(raster); + d3ddevice->SetTexture(i, (IDirect3DTexture9*)d3draster->texture); + }else + d3ddevice->SetTexture(i, nil); + setSamplerState(i, D3DSAMP_ADDRESSU, addressConvMap[rwStateCache.texstage[i].addressingU]); + setSamplerState(i, D3DSAMP_ADDRESSV, addressConvMap[rwStateCache.texstage[i].addressingV]); + setSamplerState(i, D3DSAMP_MAGFILTER, filterConvMap[rwStateCache.texstage[i].filter]); + if(rwStateCache.texstage[i].maxAniso == 1) + setSamplerState(i, D3DSAMP_MINFILTER, filterConvMap[rwStateCache.texstage[i].filter]); + else + setSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); + setSamplerState(i, D3DSAMP_MIPFILTER, filterConvMap_MIP[rwStateCache.texstage[i].filter]); + } + for(s = 0; s < MAXNUMSTATES; s++) + if(validStates[s]) + d3ddevice->SetRenderState((D3DRENDERSTATETYPE)s, d3dStates[s]); + for(t = 0; t < MAXNUMTEXSTATES; t++) + if(validTexStates[t]) + for(s = 0; s < MAXNUMSTAGES; s++) + d3ddevice->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, d3dTextureStageStates[t][s]); + for(t = 1; t < MAXNUMSAMPLERSTATES; t++) + for(s = 0; s < MAXNUMSTAGES; s++) + d3ddevice->SetSamplerState(s, (D3DSAMPLERSTATETYPE)t, d3dSamplerStates[t][s]); + d3ddevice->SetMaterial(&d3dmaterial); + + d3ddevice->SetVertexShader(deviceCache.vertexShader); + d3ddevice->SetPixelShader(deviceCache.pixelShader); + d3ddevice->SetVertexDeclaration(deviceCache.vertexDeclaration); + d3ddevice->SetIndices(deviceCache.indices); + for(i = 0; i < MAXNUMSTREAMS; i++) + d3ddevice->SetStreamSource(i, deviceCache.vertexStreams[i].buffer, deviceCache.vertexStreams[i].offset, deviceCache.vertexStreams[i].stride); + + // shader constants are zero now + d3dShaderState.fogDirty = true; + d3dShaderState.matColor.red = 0; + d3dShaderState.matColor.green = 0; + d3dShaderState.matColor.blue = 0; + d3dShaderState.matColor.alpha = 0; + d3dShaderState.surfProps.ambient = 0.0f; + d3dShaderState.surfProps.specular = 0.0f; + d3dShaderState.surfProps.diffuse = 0.0f; + d3dShaderState.extraSurfProp = 0.0f; + d3dShaderState.numDir = 0; + d3dShaderState.numPoint = 0; + d3dShaderState.numSpot = 0; + d3dShaderState.ambient.red = 0.0f; + d3dShaderState.ambient.green = 0.0f; + d3dShaderState.ambient.blue = 0.0f; + d3dShaderState.ambient.alpha = 0.0f; +} + +void +evictD3D9Raster(Raster *raster) +{ + int i; + // Make sure we're not still referencing this raster + D3dRaster *natras = GETD3DRASTEREXT(raster); + switch(raster->type){ + case Raster::CAMERATEXTURE: + for(i = 0; i < MAXNUMRENDERTARGETS; i++) + if(deviceCache.renderTargets[i] == natras->texture) + setRenderTarget(i, i == 0 ? d3d9Globals.defaultRenderTarget : nil); + // fall through + case Raster::NORMAL: + case Raster::TEXTURE: + for(i = 0; i < MAXNUMSTAGES; i++) + if(rwStateCache.texstage[i].raster == raster) + rwStateCache.texstage[i].raster = nil; + break; + case Raster::ZBUFFER: + if(natras->texture == deviceCache.depthSurface) + setDepthSurface(d3d9Globals.defaultDepthSurf); + break; + } +} + +// RW render state + +static void +setDepthTest(bool32 enable) +{ + if(rwStateCache.ztest != enable){ + rwStateCache.ztest = enable; + if(rwStateCache.zwrite && !enable){ + // If we still want to write, enable but set mode to always + setRenderState(D3DRS_ZENABLE, TRUE); + setRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + }else{ + setRenderState(D3DRS_ZENABLE, rwStateCache.ztest); + setRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + } + } +} + +static void +setDepthWrite(bool32 enable) +{ + if(rwStateCache.zwrite != enable){ + rwStateCache.zwrite = enable; + if(enable && !rwStateCache.ztest){ + // Have to switch on ztest so writing can work + setRenderState(D3DRS_ZENABLE, TRUE); + setRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + } + setRenderState(D3DRS_ZWRITEENABLE, rwStateCache.zwrite); + } +} + +static void +setVertexAlpha(bool32 enable) +{ + if(rwStateCache.vertexAlpha != enable){ + if(!rwStateCache.textureAlpha){ + setRenderState(D3DRS_ALPHABLENDENABLE, enable); + setRenderState(D3DRS_ALPHATESTENABLE, enable); + } + rwStateCache.vertexAlpha = enable; + } +} + +void +setRasterStage(uint32 stage, Raster *raster) +{ + bool32 alpha; + D3dRaster *d3draster = nil; + if(raster != rwStateCache.texstage[stage].raster){ + rwStateCache.texstage[stage].raster = raster; + if(raster){ + assert(raster->platform == PLATFORM_D3D8 || + raster->platform == PLATFORM_D3D9); + d3draster = GETD3DRASTEREXT(raster); + d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture); + alpha = d3draster->hasAlpha; + }else{ + d3ddevice->SetTexture(stage, whiteTex); + alpha = 0; + } + if(stage == 0){ + if(rwStateCache.textureAlpha != alpha){ + rwStateCache.textureAlpha = alpha; + if(!rwStateCache.vertexAlpha){ + setRenderState(D3DRS_ALPHABLENDENABLE, alpha); + setRenderState(D3DRS_ALPHATESTENABLE, alpha); + } + } + } + } +} + +static void +setFilterMode(uint32 stage, int32 filter, int32 maxAniso = 1) +{ + if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){ + rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter; + setSamplerState(stage, D3DSAMP_MAGFILTER, filterConvMap[filter]); + if(maxAniso == 1) + setSamplerState(stage, D3DSAMP_MINFILTER, filterConvMap[filter]); + else + setSamplerState(stage, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); + setSamplerState(stage, D3DSAMP_MIPFILTER, filterConvMap_MIP[filter]); + } + if(rwStateCache.texstage[stage].maxAniso != maxAniso){ + rwStateCache.texstage[stage].maxAniso = maxAniso; + if(maxAniso == 1) + setSamplerState(stage, D3DSAMP_MINFILTER, filterConvMap[filter]); + else + setSamplerState(stage, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); + setSamplerState(stage, D3DSAMP_MAXANISOTROPY, maxAniso); + } +} + +static void +setAddressU(uint32 stage, int32 addressing) +{ + if(rwStateCache.texstage[stage].addressingU != (Texture::Addressing)addressing){ + rwStateCache.texstage[stage].addressingU = (Texture::Addressing)addressing; + setSamplerState(stage, D3DSAMP_ADDRESSU, addressConvMap[addressing]); + } +} + +static void +setAddressV(uint32 stage, int32 addressing) +{ + if(rwStateCache.texstage[stage].addressingV != (Texture::Addressing)addressing){ + rwStateCache.texstage[stage].addressingV = (Texture::Addressing)addressing; + setSamplerState(stage, D3DSAMP_ADDRESSV, addressConvMap[addressing]); + } +} + +void +setTexture(uint32 stage, Texture *tex) +{ + if(tex == nil){ + setRasterStage(stage, nil); + return; + } + if(tex->raster){ + setFilterMode(stage, tex->getFilter(), tex->getMaxAnisotropy()); + setAddressU(stage, tex->getAddressU()); + setAddressV(stage, tex->getAddressV()); + } + setRasterStage(stage, tex->raster); +} + +void +setD3dMaterial(D3DMATERIAL9 *mat9) +{ + if(d3dmaterial.Diffuse.r != mat9->Diffuse.r || + d3dmaterial.Diffuse.g != mat9->Diffuse.g || + d3dmaterial.Diffuse.b != mat9->Diffuse.b || + d3dmaterial.Diffuse.a != mat9->Diffuse.a || + d3dmaterial.Ambient.r != mat9->Ambient.r || + d3dmaterial.Ambient.g != mat9->Ambient.g || + d3dmaterial.Ambient.b != mat9->Ambient.b || + d3dmaterial.Ambient.a != mat9->Ambient.a || + d3dmaterial.Specular.r != mat9->Specular.r || + d3dmaterial.Specular.g != mat9->Specular.g || + d3dmaterial.Specular.b != mat9->Specular.b || + d3dmaterial.Specular.a != mat9->Specular.a || + d3dmaterial.Emissive.r != mat9->Emissive.r || + d3dmaterial.Emissive.g != mat9->Emissive.g || + d3dmaterial.Emissive.b != mat9->Emissive.b || + d3dmaterial.Emissive.a != mat9->Emissive.a || + d3dmaterial.Power != mat9->Power){ + d3ddevice->SetMaterial(mat9); + d3dmaterial = *mat9; + } +} + +void +setMaterial_fix(const RGBA &color, const SurfaceProperties &surfProps) +{ + D3DMATERIAL9 mat9; + D3DCOLORVALUE black = { 0, 0, 0, 0 }; + float ambmult = surfProps.ambient/255.0f; + float diffmult = surfProps.diffuse/255.0f; + mat9.Ambient.r = color.red*ambmult; + mat9.Ambient.g = color.green*ambmult; + mat9.Ambient.b = color.blue*ambmult; + mat9.Ambient.a = color.alpha; + mat9.Diffuse.r = color.red*diffmult; + mat9.Diffuse.g = color.green*diffmult; + mat9.Diffuse.b = color.blue*diffmult; + mat9.Diffuse.a = color.alpha; + mat9.Power = 0.0f; + mat9.Emissive = black; + mat9.Specular = black; + setD3dMaterial(&mat9); +} + + +void +setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp) +{ + if(!equal(d3dShaderState.matColor, color)){ + rw::RGBAf col; + convColor(&col, &color); + d3ddevice->SetVertexShaderConstantF(VSLOC_matColor, (float*)&col, 1); + d3dShaderState.matColor = color; + } + + if(d3dShaderState.surfProps.ambient != surfaceprops.ambient || + d3dShaderState.surfProps.specular != surfaceprops.specular || + d3dShaderState.surfProps.diffuse != surfaceprops.diffuse || + d3dShaderState.extraSurfProp != extraSurfProp){ + float surfProps[4]; + surfProps[0] = surfaceprops.ambient; + surfProps[1] = surfaceprops.specular; + surfProps[2] = surfaceprops.diffuse; + surfProps[3] = extraSurfProp; + d3ddevice->SetVertexShaderConstantF(VSLOC_surfProps, surfProps, 1); + d3dShaderState.surfProps = surfaceprops; + d3dShaderState.extraSurfProp = extraSurfProp; + } +} + +static void +setRwRenderState(int32 state, void *pvalue) +{ + uint32 value = (uint32)(uintptr)pvalue; + uint32 bval = value ? TRUE : FALSE; + switch(state){ + case TEXTURERASTER: + setRasterStage(0, (Raster*)pvalue); + break; + case TEXTUREADDRESS: + setAddressU(0, value); + setAddressV(0, value); + break; + case TEXTUREADDRESSU: + setAddressU(0, value); + break; + case TEXTUREADDRESSV: + setAddressV(0, value); + break; + case TEXTUREFILTER: + setFilterMode(0, value); + break; + case VERTEXALPHA: + setVertexAlpha(bval); + break; + case SRCBLEND: + if(rwStateCache.srcblend != value){ + rwStateCache.srcblend = value; + setRenderState(D3DRS_SRCBLEND, blendMap[value]); + } + break; + case DESTBLEND: + if(rwStateCache.destblend != value){ + rwStateCache.destblend = value; + setRenderState(D3DRS_DESTBLEND, blendMap[value]); + } + break; + case ZTESTENABLE: + setDepthTest(bval); + break; + case ZWRITEENABLE: + setDepthWrite(bval); + break; + case FOGENABLE: + if(rwStateCache.fogenable != bval){ + rwStateCache.fogenable = bval; +// setRenderState(D3DRS_FOGENABLE, rwStateCache.fogenable); + d3dShaderState.fogData.disable = bval ? 0.0f : 1.0f; + d3dShaderState.fogDirty = true; + }; + break; + case FOGCOLOR:{ + RGBA c; + c.red = value; + c.green = value>>8; + c.blue = value>>16; + c.alpha = value>>24; + if(!equal(rwStateCache.fogcolor, c)){ + rwStateCache.fogcolor = c; + setRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(c.red, c.green, c.blue, c.alpha)); + convColor(&d3dShaderState.fogColor, &c); + d3dShaderState.fogDirty = true; + }} break; + case CULLMODE: + if(rwStateCache.cullmode != value){ + rwStateCache.cullmode = value; + setRenderState(D3DRS_CULLMODE, cullmodeMap[value]); + } + break; + + case STENCILENABLE: + if(rwStateCache.stencilenable != bval){ + rwStateCache.stencilenable = bval; + setRenderState(D3DRS_STENCILENABLE, bval); + } + break; + case STENCILFAIL: + if(rwStateCache.stencilfail != value){ + rwStateCache.stencilfail = value; + setRenderState(D3DRS_STENCILFAIL, stencilOpMap[value]); + } + break; + case STENCILZFAIL: + if(rwStateCache.stencilzfail != value){ + rwStateCache.stencilzfail = value; + setRenderState(D3DRS_STENCILZFAIL, stencilOpMap[value]); + } + break; + case STENCILPASS: + if(rwStateCache.stencilpass != value){ + rwStateCache.stencilpass = value; + setRenderState(D3DRS_STENCILPASS, stencilOpMap[value]); + } + break; + case STENCILFUNCTION: + if(rwStateCache.stencilfunc != value){ + rwStateCache.stencilfunc = value; + setRenderState(D3DRS_STENCILFUNC, stencilFuncMap[value]); + } + break; + case STENCILFUNCTIONREF: + if(rwStateCache.stencilref != value){ + rwStateCache.stencilref = value; + setRenderState(D3DRS_STENCILREF, value); + } + break; + case STENCILFUNCTIONMASK: + if(rwStateCache.stencilmask != value){ + rwStateCache.stencilmask = value; + setRenderState(D3DRS_STENCILMASK, value); + } + break; + case STENCILFUNCTIONWRITEMASK: + if(rwStateCache.stencilwritemask != value){ + rwStateCache.stencilwritemask = value; + setRenderState(D3DRS_STENCILWRITEMASK, value); + } + break; + + case ALPHATESTFUNC: + if(rwStateCache.alphafunc != value){ + rwStateCache.alphafunc = value; + setRenderState(D3DRS_ALPHAFUNC, alphafuncMap[rwStateCache.alphafunc]); + } + break; + case ALPHATESTREF: + if(rwStateCache.alpharef != value){ + rwStateCache.alpharef = value; + setRenderState(D3DRS_ALPHAREF, rwStateCache.alpharef); + } + break; + case GSALPHATEST: + rwStateCache.gsalpha = value; + break; + case GSALPHATESTREF: + rwStateCache.gsalpharef = value; + break; + } +} + +static void* +getRwRenderState(int32 state) +{ + uint32 val; + switch(state){ + case TEXTURERASTER: + return rwStateCache.texstage[0].raster; + case TEXTUREADDRESS: + if(rwStateCache.texstage[0].addressingU == rwStateCache.texstage[0].addressingV) + val = rwStateCache.texstage[0].addressingU; + else + val = 0; // invalid + break; + case TEXTUREADDRESSU: + val = rwStateCache.texstage[0].addressingU; + break; + case TEXTUREADDRESSV: + val = rwStateCache.texstage[0].addressingV; + break; + case TEXTUREFILTER: + val = rwStateCache.texstage[0].filter; + break; + + case VERTEXALPHA: + val = rwStateCache.vertexAlpha; + break; + case SRCBLEND: + val = rwStateCache.srcblend; + break; + case DESTBLEND: + val = rwStateCache.destblend; + break; + case ZTESTENABLE: + val = rwStateCache.ztest; + break; + case ZWRITEENABLE: + val = rwStateCache.zwrite; + break; + case FOGENABLE: + val = rwStateCache.fogenable; + break; + case FOGCOLOR: + val = RWRGBAINT(rwStateCache.fogcolor.red, rwStateCache.fogcolor.green, + rwStateCache.fogcolor.blue, rwStateCache.fogcolor.alpha); + break; + case CULLMODE: + val = rwStateCache.cullmode; + break; + + case STENCILENABLE: + val = rwStateCache.stencilenable; + break; + case STENCILFAIL: + val = rwStateCache.stencilfail; + break; + case STENCILZFAIL: + val = rwStateCache.stencilzfail; + break; + case STENCILPASS: + val = rwStateCache.stencilpass; + break; + case STENCILFUNCTION: + val = rwStateCache.stencilfunc; + break; + case STENCILFUNCTIONREF: + val = rwStateCache.stencilref; + break; + case STENCILFUNCTIONMASK: + val = rwStateCache.stencilmask; + break; + case STENCILFUNCTIONWRITEMASK: + val = rwStateCache.stencilwritemask; + break; + + case ALPHATESTFUNC: + val = rwStateCache.alphafunc; + break; + case ALPHATESTREF: + val = rwStateCache.alpharef; + break; + case GSALPHATEST: + val = rwStateCache.gsalpha; + break; + case GSALPHATESTREF: + val = rwStateCache.gsalpharef; + break; + default: + val = 0; + } + return (void*)(uintptr)val; +} + +// Shaders + +void +setVertexShader(void *vs) +{ + if(deviceCache.vertexShader != vs){ + deviceCache.vertexShader = (IDirect3DVertexShader9*)vs; + d3ddevice->SetVertexShader(deviceCache.vertexShader); + } +} + +void +setPixelShader(void *ps) +{ + if(deviceCache.pixelShader != ps){ + deviceCache.pixelShader = (IDirect3DPixelShader9*)ps; + d3ddevice->SetPixelShader(deviceCache.pixelShader); + } +} + +void +setIndices(void *indexBuffer) +{ + if(deviceCache.indices != indexBuffer){ + deviceCache.indices = (IDirect3DIndexBuffer9*)indexBuffer; + d3ddevice->SetIndices(deviceCache.indices); + } +} + +void +setStreamSource(int n, void *buffer, uint32 offset, uint32 stride) +{ + if(deviceCache.vertexStreams[n].buffer != buffer || + deviceCache.vertexStreams[n].offset != offset || + deviceCache.vertexStreams[n].stride != stride){ + deviceCache.vertexStreams[n].buffer = (IDirect3DVertexBuffer9*)buffer; + deviceCache.vertexStreams[n].offset = offset; + deviceCache.vertexStreams[n].stride = stride; + d3ddevice->SetStreamSource(n, deviceCache.vertexStreams[n].buffer, offset, stride); + } +} + +void +setVertexDeclaration(void *declaration) +{ + if(deviceCache.vertexDeclaration != declaration){ + deviceCache.vertexDeclaration = (IDirect3DVertexDeclaration9*)declaration; + d3ddevice->SetVertexDeclaration(deviceCache.vertexDeclaration); + } +} + +void* +createVertexShader(void *csosrc) +{ + void *shdr; + if(d3ddevice->CreateVertexShader((DWORD*)csosrc, (IDirect3DVertexShader9**)&shdr) == D3D_OK){ + d3d9Globals.numVertexShaders++; + return shdr; + } + return nil; +} + +void* +createPixelShader(void *csosrc) +{ + void *shdr; + if(d3ddevice->CreatePixelShader((DWORD*)csosrc, (IDirect3DPixelShader9**)&shdr) == D3D_OK){ + d3d9Globals.numPixelShaders++; + return shdr; + } + return nil; +} + +void +destroyVertexShader(void *shader) +{ + if(shader){ + ((IDirect3DVertexShader9*)shader)->Release(); + d3d9Globals.numVertexShaders--; + } +} + +void +destroyPixelShader(void *shader) +{ + if(shader){ + ((IDirect3DPixelShader9*)shader)->Release(); + d3d9Globals.numPixelShaders--; + } +} + + +// Camera + +static void +setRenderSurfaces(Camera *cam) +{ + Raster *fbuf = cam->frameBuffer; + assert(fbuf); + { + if(fbuf->parent) + fbuf = fbuf->parent; + + D3dRaster *natras = GETD3DRASTEREXT(fbuf); + assert(fbuf->type == Raster::CAMERA || fbuf->type == Raster::CAMERATEXTURE); + if(natras->texture == nil) + setRenderTarget(0, d3d9Globals.defaultRenderTarget); + else{ + assert(fbuf->type == Raster::CAMERATEXTURE); + IDirect3DSurface9 *surf; + ((IDirect3DTexture9*)natras->texture)->GetSurfaceLevel(0, &surf); + setRenderTarget(0, surf); + surf->Release(); + } + } + + Raster *zbuf = cam->zBuffer; + if(zbuf){ + if(zbuf->parent) + zbuf = zbuf->parent; + + D3dRaster *natras = GETD3DRASTEREXT(zbuf); + assert(zbuf->type == Raster::ZBUFFER); + setDepthSurface(natras->texture); + }else + setDepthSurface(nil); + +} + +static void +setViewport(Raster *fb) +{ + D3DVIEWPORT9 vp; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + vp.X = fb->offsetX; + vp.Y = fb->offsetY; + vp.Width = fb->width; + vp.Height = fb->height; + d3ddevice->SetViewport(&vp); +} +// Manage video memory + +void +addVidmemRaster(Raster *raster) +{ + VidmemRaster *vmr = rwNewT(VidmemRaster, 1, ID_DRIVER | MEMDUR_EVENT); + vmr->raster = raster; + vmr->next = vidmemRasters; + vidmemRasters = vmr; +} + +void +removeVidmemRaster(Raster *raster) +{ + VidmemRaster **p, *vmr; + for(p = &vidmemRasters; *p; p = &(*p)->next) + if((*p)->raster == raster) + goto found; + return; +found: + vmr = *p; + *p = vmr->next; + rwFree(vmr); +} + +static void +releaseVidmemRasters(void) +{ + VidmemRaster *vmr; + Raster *raster; + D3dRaster *natras; + for(vmr = vidmemRasters; vmr; vmr = vmr->next){ + raster = vmr->raster; + natras = GETD3DRASTEREXT(raster); + switch(raster->type){ + case Raster::CAMERATEXTURE: + destroyTexture(natras->texture); + natras->texture = nil; + break; + + case Raster::ZBUFFER: + // we'll leave the default surface dangling so we can tell the difference + if(natras->texture != d3d9Globals.defaultDepthSurf){ + ((IDirect3DSurface9*)natras->texture)->Release(); + natras->texture = nil; + } + break; + } + } +} + +static void +recreateVidmemRasters(void) +{ + VidmemRaster *vmr; + Raster *raster; + D3dRaster *natras; + for(vmr = vidmemRasters; vmr; vmr = vmr->next){ + raster = vmr->raster; + natras = GETD3DRASTEREXT(raster); + switch(raster->type){ + case Raster::CAMERATEXTURE: { + int32 levels = Raster::calculateNumLevels(raster->width, raster->height); + IDirect3DTexture9 *tex = nil; + d3ddevice->CreateTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? levels : 1, + D3DUSAGE_RENDERTARGET, + (D3DFORMAT)natras->format, D3DPOOL_DEFAULT, &tex, nil); + natras->texture = tex; + if(natras->texture) + d3d9Globals.numTextures++; + break; + } + + case Raster::ZBUFFER: + if(natras->texture){ + RECT rect; + GetClientRect(d3d9Globals.window, &rect); + raster->width = rect.right; + raster->height = rect.bottom; + natras->texture = d3d9Globals.defaultDepthSurf; + natras->format = d3d9Globals.present.AutoDepthStencilFormat; + raster->depth = findFormatDepth(natras->format); + }else{ + IDirect3DSurface9 *surf = nil; + d3ddevice->CreateDepthStencilSurface(raster->width, raster->height, (D3DFORMAT)natras->format, + d3d9Globals.present.MultiSampleType, d3d9Globals.present.MultiSampleQuality, + FALSE, &surf, nil); + natras->texture = surf; + } + break; + } + } +} + +void +addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf) +{ + DynamicVB *dvb = rwNewT(DynamicVB, 1, ID_DRIVER | MEMDUR_EVENT); + dvb->length = length; + dvb->fvf = fvf; + dvb->buf = buf; + dvb->next = dynamicVBs; + dynamicVBs = dvb; +} + +void +removeDynamicVB(IDirect3DVertexBuffer9 **buf) +{ + DynamicVB **p, *dvb; + for(p = &dynamicVBs; *p; p = &(*p)->next) + if((*p)->buf == buf) + goto found; + return; +found: + dvb = *p; + *p = dvb->next; + rwFree(dvb); +} + +static void +releaseDynamicVBs(void) +{ + DynamicVB *dvb; + int i; + for(dvb = dynamicVBs; dvb; dvb = dvb->next){ + for(i = 0; i < MAXNUMSTREAMS; i++) + if(deviceCache.vertexStreams[i].buffer == *dvb->buf) + deviceCache.vertexStreams[i].buffer = nil; + destroyVertexBuffer(*dvb->buf); + *dvb->buf = nil; + } +} + +static void +recreateDynamicVBs(void) +{ + DynamicVB *dvb; + for(dvb = dynamicVBs; dvb; dvb = dvb->next){ + assert(*dvb->buf == nil); + *dvb->buf = (IDirect3DVertexBuffer9*)createVertexBuffer(dvb->length, dvb->fvf, true); + } +} + + +void +addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf) +{ + DynamicIB *ivb = rwNewT(DynamicIB, 1, ID_DRIVER | MEMDUR_EVENT); + ivb->length = length; + ivb->buf = buf; + ivb->next = dynamicIBs; + dynamicIBs = ivb; +} + +void +removeDynamicIB(IDirect3DIndexBuffer9 **buf) +{ + DynamicIB **p, *ivb; + for(p = &dynamicIBs; *p; p = &(*p)->next) + if((*p)->buf == buf) + goto found; + return; +found: + ivb = *p; + *p = ivb->next; + rwFree(ivb); +} + +static void +releaseDynamicIBs(void) +{ + DynamicIB *ivb; + for(ivb = dynamicIBs; ivb; ivb = ivb->next){ + if(deviceCache.indices == *ivb->buf) + deviceCache.indices = nil; + destroyIndexBuffer(*ivb->buf); + *ivb->buf = nil; + } +} + +static void +recreateDynamicIBs(void) +{ + DynamicIB *ivb; + for(ivb = dynamicIBs; ivb; ivb = ivb->next){ + assert(*ivb->buf == nil); + *ivb->buf = (IDirect3DIndexBuffer9*)createIndexBuffer(ivb->length, true); + } +} + +static void +releaseVideoMemory(void) +{ + int32 i; + for(i = 0; i < MAXNUMSTAGES; i++) + d3ddevice->SetTexture(i, nil); + d3ddevice->SetVertexDeclaration(nil); + d3ddevice->SetVertexShader(nil); + d3ddevice->SetPixelShader(nil); + d3ddevice->SetIndices(nil); + for(i = 0; i < MAXNUMSTREAMS; i++) + d3ddevice->SetStreamSource(0, nil, 0, 0); + + setRenderTarget(0, d3d9Globals.defaultRenderTarget); + for(i = 1; i < MAXNUMRENDERTARGETS; i++) + setRenderTarget(i, nil); + setDepthSurface(d3d9Globals.defaultDepthSurf); + + releaseVidmemRasters(); + releaseDynamicVBs(); + releaseDynamicIBs(); +} + +static void +restoreVideoMemory(void) +{ + // Have to get these back before recreating rasters + d3ddevice->GetRenderTarget(0, &d3d9Globals.defaultRenderTarget); + d3d9Globals.defaultRenderTarget->Release(); // refcount increased by Get + deviceCache.renderTargets[0] = d3d9Globals.defaultRenderTarget; + d3ddevice->GetDepthStencilSurface(&d3d9Globals.defaultDepthSurf); + d3d9Globals.defaultDepthSurf->Release(); // refcount increased by Get + deviceCache.depthSurface = d3d9Globals.defaultDepthSurf; + + recreateDynamicIBs(); + recreateDynamicVBs(); + // important that we get all raster back before restoring state + recreateVidmemRasters(); + + restoreD3d9Device(); +} + +static void +beginUpdate(Camera *cam) +{ + float view[16], proj[16]; + + // View Matrix + Matrix inv; + Matrix::invert(&inv, cam->getFrame()->getLTM()); + // Since we're looking into positive Z, + // flip X to ge a left handed view space. + view[0] = -inv.right.x; + view[1] = inv.right.y; + view[2] = inv.right.z; + view[3] = 0.0f; + view[4] = -inv.up.x; + view[5] = inv.up.y; + view[6] = inv.up.z; + view[7] = 0.0f; + view[8] = -inv.at.x; + view[9] = inv.at.y; + view[10] = inv.at.z; + view[11] = 0.0f; + view[12] = -inv.pos.x; + view[13] = inv.pos.y; + view[14] = inv.pos.z; + view[15] = 1.0f; + memcpy(&cam->devView, view, sizeof(RawMatrix)); +// d3ddevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view); + + // Projection Matrix + float32 invwx = 1.0f/cam->viewWindow.x; + float32 invwy = 1.0f/cam->viewWindow.y; + float32 invz = 1.0f/(cam->farPlane-cam->nearPlane); + + proj[0] = invwx; + proj[1] = 0.0f; + proj[2] = 0.0f; + proj[3] = 0.0f; + + proj[4] = 0.0f; + proj[5] = invwy; + proj[6] = 0.0f; + proj[7] = 0.0f; + + proj[8] = cam->viewOffset.x*invwx; + proj[9] = cam->viewOffset.y*invwy; + proj[12] = -proj[8]; + proj[13] = -proj[9]; + if(cam->projection == Camera::PERSPECTIVE){ + proj[10] = cam->farPlane*invz; + proj[11] = 1.0f; + + proj[15] = 0.0f; + }else{ + proj[10] = invz; + proj[11] = 0.0f; + + proj[15] = 1.0f; + } + proj[14] = -cam->nearPlane*proj[10]; + memcpy(&cam->devProj, proj, sizeof(RawMatrix)); +// d3ddevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj); + + // TODO: figure out where this is really done +// setRenderState(D3DRS_FOGSTART, *(uint32*)&cam->fogPlane); +// setRenderState(D3DRS_FOGEND, *(uint32*)&cam->farPlane); + d3dShaderState.fogData.start = cam->fogPlane; + d3dShaderState.fogData.end = cam->farPlane; + d3dShaderState.fogData.range = 1.0f/(cam->fogPlane - cam->farPlane); + // TODO: not quite sure this is the right place to do this... + d3dShaderState.fogData.disable = rwStateCache.fogenable ? 0.0f : 1.0f; + d3dShaderState.fogDisable.start = 0.0f; + d3dShaderState.fogDisable.end = 0.0f; + d3dShaderState.fogDisable.range = 0.0f; + d3dShaderState.fogDisable.disable = 1.0f; + d3dShaderState.fogDirty = true; + + RECT r; + GetClientRect(d3d9Globals.window, &r); + BOOL icon = IsIconic(d3d9Globals.window); + if(!icon && + (r.right != d3d9Globals.present.BackBufferWidth || r.bottom != d3d9Globals.present.BackBufferHeight)){ + + d3d9Globals.present.BackBufferWidth = r.right; + d3d9Globals.present.BackBufferHeight = r.bottom; + + releaseVideoMemory(); + d3d::d3ddevice->Reset(&d3d9Globals.present); + restoreVideoMemory(); + } + + setRenderSurfaces(cam); + + setViewport(cam->frameBuffer); + + d3ddevice->BeginScene(); +} + +static void +endUpdate(Camera *cam) +{ + d3ddevice->EndScene(); +} + +static void +clearCamera(Camera *cam, RGBA *col, uint32 mode) +{ + int flags = 0; + if(mode & Camera::CLEARIMAGE) + mode |= D3DCLEAR_TARGET; + if(mode & Camera::CLEARZ) + mode |= D3DCLEAR_ZBUFFER; + if(mode & Camera::CLEARSTENCIL) + mode |= D3DCLEAR_STENCIL; + D3DCOLOR c = D3DCOLOR_RGBA(col->red, col->green, col->blue, col->alpha); + + setRenderSurfaces(cam); + + setViewport(cam->frameBuffer); // need to set this for the clear to work correctly + d3ddevice->Clear(0, nil, mode, c, 1.0f, 0); +} + +static void +showRaster(Raster *raster, uint32 flag) +{ + UINT interval = flag & Raster::FLIPWAITVSYNCH ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + if(d3d9Globals.present.PresentationInterval != interval){ + d3d9Globals.present.PresentationInterval = interval; + releaseVideoMemory(); + d3d::d3ddevice->Reset(&d3d9Globals.present); + restoreVideoMemory(); + } + + // not used but we want cameras to have rasters + assert(raster); + HRESULT res = d3ddevice->Present(nil, nil, 0, nil); + + if(res == D3DERR_DEVICELOST){ + res = d3ddevice->TestCooperativeLevel(); + // lost while being minimized, not reset once we're back + if(res == D3DERR_DEVICENOTRESET){ + releaseVideoMemory(); + d3d::d3ddevice->Reset(&d3d9Globals.present); + restoreVideoMemory(); + } + } +} + +static bool32 +rasterRenderFast(Raster *raster, int32 x, int32 y) +{ + IDirect3DTexture9 *dsttex; + IDirect3DSurface9 *srcsurf, *dstsurf; + D3DSURFACE_DESC srcdesc, dstdesc; + RECT rect = { x, y, x, y }; + + Raster *src = raster; + Raster *dst = Raster::getCurrentContext(); + D3dRaster *natdst = GETD3DRASTEREXT(dst); + D3dRaster *natsrc = GETD3DRASTEREXT(src); + + switch(dst->type){ + case Raster::CAMERATEXTURE: + switch(src->type){ + case Raster::CAMERA: + dsttex = (IDirect3DTexture9*)natdst->texture; + dsttex->GetSurfaceLevel(0, &dstsurf); + assert(dstsurf); + dstsurf->GetDesc(&dstdesc); + + d3ddevice->GetRenderTarget(0, &srcsurf); + assert(srcsurf); + srcsurf->GetDesc(&srcdesc); + + rect.right += srcdesc.Width; + rect.bottom += srcdesc.Height; + + d3ddevice->StretchRect(srcsurf, &rect, dstsurf, &rect, D3DTEXF_NONE); + dstsurf->Release(); + srcsurf->Release(); + return 1; + } + break; + } + + return 0; +} + + +// +// Device +// + +int +findFormatDepth(uint32 format) +{ + // not all formats actually + switch(format){ + case D3DFMT_R8G8B8: return 24; + case D3DFMT_A8R8G8B8: return 32; + case D3DFMT_X8R8G8B8: return 32; + case D3DFMT_R5G6B5: return 16; + case D3DFMT_X1R5G5B5: return 16; + case D3DFMT_A1R5G5B5: return 16; + case D3DFMT_A4R4G4B4: return 16; + case D3DFMT_R3G3B2: return 8; + case D3DFMT_A8: return 8; + case D3DFMT_A8R3G3B2: return 16; + case D3DFMT_X4R4G4B4: return 16; + case D3DFMT_A2B10G10R10: return 32; + case D3DFMT_A8B8G8R8: return 32; + case D3DFMT_X8B8G8R8: return 32; + case D3DFMT_G16R16: return 32; + case D3DFMT_A2R10G10B10: return 32; + case D3DFMT_A16B16G16R16: return 64; + + case D3DFMT_L8: return 8; + case D3DFMT_D16: return 16; + case D3DFMT_D24S8: return 32; + case D3DFMT_D24X8: return 32; + case D3DFMT_D24X4S4: return 32; + case D3DFMT_D32: return 32; + + default: return 0; + } +} + +// the commented ones don't "work" +static D3DFORMAT fbFormats[] = { +// D3DFMT_A1R5G5B5, +/// D3DFMT_A2R10G10B10, // works but let's not use it... +// D3DFMT_A8R8G8B8, + D3DFMT_X8R8G8B8, +// D3DFMT_X1R5G5B5, + D3DFMT_R5G6B5 +}; + +static void +addVideoMode(D3DDISPLAYMODE *mode) +{ + int i; + + for(i = 1; i < d3d9Globals.numModes; i++){ + if(d3d9Globals.modes[i].mode.Width == mode->Width && + d3d9Globals.modes[i].mode.Height == mode->Height && + d3d9Globals.modes[i].mode.Format == mode->Format){ + // had this format already, remember highest refresh rate + if(mode->RefreshRate > d3d9Globals.modes[i].mode.RefreshRate) + d3d9Globals.modes[i].mode.RefreshRate = mode->RefreshRate; + return; + } + } + + // none found, add + d3d9Globals.modes[d3d9Globals.numModes].mode = *mode; + d3d9Globals.modes[d3d9Globals.numModes].flags = VIDEOMODEEXCLUSIVE; + d3d9Globals.numModes++; +} + +static void +makeVideoModeList(void) +{ + int i, j; + D3DDISPLAYMODE mode; + + d3d9Globals.numModes = 1; + for(i = 0; i < nelem(fbFormats); i++) + d3d9Globals.numModes += d3d9Globals.d3d9->GetAdapterModeCount(d3d9Globals.adapter, fbFormats[i]); + + rwFree(d3d9Globals.modes); + d3d9Globals.modes = rwNewT(DisplayMode, d3d9Globals.numModes, ID_DRIVER | MEMDUR_EVENT); + + // first mode is current mode as windowed + d3d9Globals.d3d9->GetAdapterDisplayMode(d3d9Globals.adapter, &d3d9Globals.modes[0].mode); + d3d9Globals.modes[0].flags = 0; + d3d9Globals.numModes = 1; + + for(i = 0; i < nelem(fbFormats); i++){ + int n = d3d9Globals.d3d9->GetAdapterModeCount(d3d9Globals.adapter, fbFormats[i]); + for(j = 0; j < n; j++){ + d3d9Globals.d3d9->EnumAdapterModes(d3d9Globals.adapter, fbFormats[i], j, &mode); + addVideoMode(&mode); + } + } +} + +static int +openD3D(EngineOpenParams *params) +{ + HWND win = params->window; + + d3d9Globals.window = win; + d3d9Globals.numAdapters = 0; + d3d9Globals.modes = nil; + d3d9Globals.numModes = 0; + d3d9Globals.currentMode = 0; + + d3d9Globals.d3d9 = Direct3DCreate9(D3D_SDK_VERSION); + if(d3d9Globals.d3d9 == nil){ + RWERROR((ERR_GENERAL, "Direct3DCreate9() failed")); + return 0; + } + + d3d9Globals.numAdapters = d3d9Globals.d3d9->GetAdapterCount(); + d3d9Globals.adapter = 0; + + for(d3d9Globals.adapter = 0; d3d9Globals.adapter < d3d9Globals.numAdapters; d3d9Globals.adapter++) + if(d3d9Globals.d3d9->GetDeviceCaps(d3d9Globals.adapter, D3DDEVTYPE_HAL, &d3d9Globals.caps) == D3D_OK) + goto found; + // no adapter + d3d9Globals.d3d9->Release(); + d3d9Globals.d3d9 = nil; + RWERROR((ERR_GENERAL, "Direct3DCreate9() failed")); + return 0; + +found: + makeVideoModeList(); + return 1; +} + +static int +closeD3D(void) +{ + ULONG ref = d3d9Globals.d3d9->Release(); + if(ref != 0) + printf("IDirect3D9_Release did not destroy\n"); + d3d9Globals.d3d9 = nil; + rwFree(d3d9Globals.modes); + d3d9Globals.modes = nil; + d3d9Globals.numModes = 0; + d3d9Globals.currentMode = 0; + return 1; +} + +static int +startD3D(void) +{ + HRESULT hr; + int vp; + if(d3d9Globals.caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) + vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; + else + vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; + + uint32 width, height, depth; + D3DFORMAT format, zformat; + d3d9Globals.startMode = d3d9Globals.modes[d3d9Globals.currentMode]; + format = d3d9Globals.startMode.mode.Format; + + bool windowed = !(d3d9Globals.startMode.flags & VIDEOMODEEXCLUSIVE); + + // Use window size in windowed mode, otherwise get size from video mode + if(windowed){ + RECT rect; + GetClientRect(d3d9Globals.window, &rect); + width = rect.right - rect.left; + height = rect.bottom - rect.top; + }else{ + // this will be much better for restoring after iconification + SetWindowLong(d3d9Globals.window, GWL_STYLE, WS_POPUP); + width = d3d9Globals.startMode.mode.Width; + height = d3d9Globals.startMode.mode.Height; + } + + // See if we can get an alpha channel + if(format == D3DFMT_X8R8G8B8){ + if(d3d9Globals.d3d9->CheckDeviceType(d3d9Globals.adapter, D3DDEVTYPE_HAL, format, D3DFMT_A8R8G8B8, windowed) == D3D_OK) + format = D3DFMT_A8R8G8B8; + } + + depth = findFormatDepth(format); + + // TOOD: use something more sophisticated maybe? + if(depth == 32) + zformat = D3DFMT_D24S8; + else + zformat = D3DFMT_D16; + + d3d9Globals.present.BackBufferWidth = width; + d3d9Globals.present.BackBufferHeight = height; + d3d9Globals.present.BackBufferFormat = format; + d3d9Globals.present.BackBufferCount = 1; + d3d9Globals.present.MultiSampleType = d3d9Globals.msLevel == 1 ? + D3DMULTISAMPLE_NONE : (D3DMULTISAMPLE_TYPE)d3d9Globals.msLevel; + d3d9Globals.present.MultiSampleQuality = 0; + d3d9Globals.present.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3d9Globals.present.hDeviceWindow = d3d9Globals.window; + d3d9Globals.present.Windowed = windowed; + d3d9Globals.present.EnableAutoDepthStencil = true; + d3d9Globals.present.AutoDepthStencilFormat = zformat; + d3d9Globals.present.Flags = 0; + d3d9Globals.present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; +// d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + d3d9Globals.present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + rw::d3d::isP8supported = 0; + + assert(d3d::d3ddevice == nil); + + BOOL icon = IsIconic(d3d9Globals.window); + IDirect3DDevice9 *dev; + hr = d3d9Globals.d3d9->CreateDevice(d3d9Globals.adapter, D3DDEVTYPE_HAL, + d3d9Globals.window, vp, &d3d9Globals.present, &dev); + if(FAILED(hr)){ + RWERROR((ERR_GENERAL, "CreateDevice() failed")); + return 0; + } + d3d::d3ddevice = dev; + return 1; +} + +static int +initD3D(void) +{ + int32 s, t; + + memset(&deviceCache, 0, sizeof(deviceCache)); + d3ddevice->GetRenderTarget(0, &d3d9Globals.defaultRenderTarget); + d3d9Globals.defaultRenderTarget->Release(); // refcount increased by Get + deviceCache.renderTargets[0] = d3d9Globals.defaultRenderTarget; + d3ddevice->GetDepthStencilSurface(&d3d9Globals.defaultDepthSurf); + d3d9Globals.defaultDepthSurf->Release(); // refcount increased by Get + deviceCache.depthSurface = d3d9Globals.defaultDepthSurf; + + d3d9Globals.numTextures = 0; + d3d9Globals.numVertexShaders = 0; + d3d9Globals.numPixelShaders = 0; + d3d9Globals.numVertexBuffers = 0; + d3d9Globals.numIndexBuffers = 0; + d3d9Globals.numVertexDeclarations = 0; + + VertexConstantData constants; + constants.normal.x = 0.0f; + constants.normal.y = 0.0f; + constants.normal.z = 0.0f; + constants.color.red = 0; + constants.color.green = 0; + constants.color.blue = 0; + constants.color.alpha = 255; + for(s = 0; s < 8; s++){ + constants.texCoors[s].u = 0.0f; + constants.texCoors[s].v = 0.0f; + } + assert(constantVertexStream == nil); + constantVertexStream = createVertexBuffer(sizeof(constants)*10000, 0, false); + assert(constantVertexStream); + uint8 *lockedvertices = lockVertices(constantVertexStream, 0, sizeof(constants), D3DLOCK_NOSYSLOCK); + assert(lockedvertices); + memcpy(lockedvertices, &constants, sizeof(constants)); + unlockVertices(constantVertexStream); + setStreamSource(2, constantVertexStream, 0, 0); + + d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + rwStateCache.alphafunc = ALPHAGREATEREQUAL; + d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10); + rwStateCache.alpharef = 10; + + rwStateCache.gsalpha = 0; + rwStateCache.gsalpharef = 128; + + d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + rwStateCache.fogenable = 0; + d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); + + d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + rwStateCache.cullmode = CULLNONE; + + d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + rwStateCache.srcblend = BLENDSRCALPHA; + d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + rwStateCache.destblend = BLENDINVSRCALPHA; + d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0); + rwStateCache.vertexAlpha = 0; + rwStateCache.textureAlpha = 0; + + rwStateCache.stencilenable = 0; + d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + rwStateCache.stencilfail = STENCILKEEP; + d3ddevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + rwStateCache.stencilzfail = STENCILKEEP; + d3ddevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + rwStateCache.stencilpass = STENCILKEEP; + d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); + rwStateCache.stencilfunc = STENCILALWAYS; + d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + rwStateCache.stencilref = 0; + d3ddevice->SetRenderState(D3DRS_STENCILREF, 0); + rwStateCache.stencilmask = 0xFFFFFFFF; + d3ddevice->SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF); + rwStateCache.stencilwritemask = 0xFFFFFFFF; + d3ddevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF); + + setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); +// setTextureStageState(0, D3DTSS_CONSTANT, 0xFFFFFFFF); +// setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT); +// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT); + + // These states exist, not all do + validStates[D3DRS_ZENABLE] = 1; + validStates[D3DRS_FILLMODE] = 1; + validStates[D3DRS_SHADEMODE] = 1; + validStates[D3DRS_ZWRITEENABLE] = 1; + validStates[D3DRS_ALPHATESTENABLE] = 1; + validStates[D3DRS_LASTPIXEL] = 1; + validStates[D3DRS_SRCBLEND] = 1; + validStates[D3DRS_DESTBLEND] = 1; + validStates[D3DRS_CULLMODE] = 1; + validStates[D3DRS_ZFUNC] = 1; + validStates[D3DRS_ALPHAREF] = 1; + validStates[D3DRS_ALPHAFUNC] = 1; + validStates[D3DRS_DITHERENABLE] = 1; + validStates[D3DRS_ALPHABLENDENABLE] = 1; + validStates[D3DRS_FOGENABLE] = 1; + validStates[D3DRS_SPECULARENABLE] = 1; + validStates[D3DRS_FOGCOLOR] = 1; + validStates[D3DRS_FOGTABLEMODE] = 1; + validStates[D3DRS_FOGSTART] = 1; + validStates[D3DRS_FOGEND] = 1; + validStates[D3DRS_FOGDENSITY] = 1; + validStates[D3DRS_RANGEFOGENABLE] = 1; + validStates[D3DRS_STENCILENABLE] = 1; + validStates[D3DRS_STENCILFAIL] = 1; + validStates[D3DRS_STENCILZFAIL] = 1; + validStates[D3DRS_STENCILPASS] = 1; + validStates[D3DRS_STENCILFUNC] = 1; + validStates[D3DRS_STENCILREF] = 1; + validStates[D3DRS_STENCILMASK] = 1; + validStates[D3DRS_STENCILWRITEMASK] = 1; + validStates[D3DRS_TEXTUREFACTOR] = 1; + validStates[D3DRS_WRAP0] = 1; + validStates[D3DRS_WRAP1] = 1; + validStates[D3DRS_WRAP2] = 1; + validStates[D3DRS_WRAP3] = 1; + validStates[D3DRS_WRAP4] = 1; + validStates[D3DRS_WRAP5] = 1; + validStates[D3DRS_WRAP6] = 1; + validStates[D3DRS_WRAP7] = 1; + validStates[D3DRS_CLIPPING] = 1; + validStates[D3DRS_LIGHTING] = 1; + validStates[D3DRS_AMBIENT] = 1; + validStates[D3DRS_FOGVERTEXMODE] = 1; + validStates[D3DRS_COLORVERTEX] = 1; + validStates[D3DRS_LOCALVIEWER] = 1; + validStates[D3DRS_NORMALIZENORMALS] = 1; + validStates[D3DRS_DIFFUSEMATERIALSOURCE] = 1; + validStates[D3DRS_SPECULARMATERIALSOURCE] = 1; + validStates[D3DRS_AMBIENTMATERIALSOURCE] = 1; + validStates[D3DRS_EMISSIVEMATERIALSOURCE] = 1; + validStates[D3DRS_VERTEXBLEND] = 1; + validStates[D3DRS_CLIPPLANEENABLE] = 1; + validStates[D3DRS_POINTSIZE] = 1; + validStates[D3DRS_POINTSIZE_MIN] = 1; + validStates[D3DRS_POINTSPRITEENABLE] = 1; + validStates[D3DRS_POINTSCALEENABLE] = 1; + validStates[D3DRS_POINTSCALE_A] = 1; + validStates[D3DRS_POINTSCALE_B] = 1; + validStates[D3DRS_POINTSCALE_C] = 1; + validStates[D3DRS_MULTISAMPLEANTIALIAS] = 1; + validStates[D3DRS_MULTISAMPLEMASK] = 1; + validStates[D3DRS_PATCHEDGESTYLE] = 1; + validStates[D3DRS_DEBUGMONITORTOKEN] = 1; + validStates[D3DRS_POINTSIZE_MAX] = 1; + validStates[D3DRS_INDEXEDVERTEXBLENDENABLE] = 1; + validStates[D3DRS_COLORWRITEENABLE] = 1; + validStates[D3DRS_TWEENFACTOR] = 1; + validStates[D3DRS_BLENDOP] = 1; + validStates[D3DRS_POSITIONDEGREE] = 1; + validStates[D3DRS_NORMALDEGREE] = 1; + validStates[D3DRS_SCISSORTESTENABLE] = 1; + validStates[D3DRS_SLOPESCALEDEPTHBIAS] = 1; + validStates[D3DRS_ANTIALIASEDLINEENABLE] = 1; + validStates[D3DRS_MINTESSELLATIONLEVEL] = 1; + validStates[D3DRS_MAXTESSELLATIONLEVEL] = 1; + validStates[D3DRS_ADAPTIVETESS_X] = 1; + validStates[D3DRS_ADAPTIVETESS_Y] = 1; + validStates[D3DRS_ADAPTIVETESS_Z] = 1; + validStates[D3DRS_ADAPTIVETESS_W] = 1; + validStates[D3DRS_ENABLEADAPTIVETESSELLATION] = 1; + validStates[D3DRS_TWOSIDEDSTENCILMODE] = 1; + validStates[D3DRS_CCW_STENCILFAIL] = 1; + validStates[D3DRS_CCW_STENCILZFAIL] = 1; + validStates[D3DRS_CCW_STENCILPASS] = 1; + validStates[D3DRS_CCW_STENCILFUNC] = 1; + validStates[D3DRS_COLORWRITEENABLE1] = 1; + validStates[D3DRS_COLORWRITEENABLE2] = 1; + validStates[D3DRS_COLORWRITEENABLE3] = 1; + validStates[D3DRS_BLENDFACTOR] = 1; + validStates[D3DRS_SRGBWRITEENABLE] = 1; + validStates[D3DRS_DEPTHBIAS] = 1; + validStates[D3DRS_WRAP8] = 1; + validStates[D3DRS_WRAP9] = 1; + validStates[D3DRS_WRAP10] = 1; + validStates[D3DRS_WRAP11] = 1; + validStates[D3DRS_WRAP12] = 1; + validStates[D3DRS_WRAP13] = 1; + validStates[D3DRS_WRAP14] = 1; + validStates[D3DRS_WRAP15] = 1; + validStates[D3DRS_SEPARATEALPHABLENDENABLE] = 1; + validStates[D3DRS_SRCBLENDALPHA] = 1; + validStates[D3DRS_DESTBLENDALPHA] = 1; + validStates[D3DRS_BLENDOPALPHA] = 1; + + validTexStates[D3DTSS_COLOROP] = 1; + validTexStates[D3DTSS_COLORARG1] = 1; + validTexStates[D3DTSS_COLORARG2] = 1; + validTexStates[D3DTSS_ALPHAOP] = 1; + validTexStates[D3DTSS_ALPHAARG1] = 1; + validTexStates[D3DTSS_ALPHAARG2] = 1; + validTexStates[D3DTSS_BUMPENVMAT00] = 1; + validTexStates[D3DTSS_BUMPENVMAT01] = 1; + validTexStates[D3DTSS_BUMPENVMAT10] = 1; + validTexStates[D3DTSS_BUMPENVMAT11] = 1; + validTexStates[D3DTSS_TEXCOORDINDEX] = 1; + validTexStates[D3DTSS_BUMPENVLSCALE] = 1; + validTexStates[D3DTSS_BUMPENVLOFFSET] = 1; + validTexStates[D3DTSS_TEXTURETRANSFORMFLAGS] = 1; + validTexStates[D3DTSS_COLORARG0] = 1; + validTexStates[D3DTSS_ALPHAARG0] = 1; + validTexStates[D3DTSS_RESULTARG] = 1; + validTexStates[D3DTSS_CONSTANT] = 1; + + // Save the current states + for(s = 0; s < MAXNUMSTATES; s++) + if(validStates[s]){ + d3ddevice->GetRenderState((D3DRENDERSTATETYPE)s, (DWORD*)&d3dStates[s]); + stateCache[s].value = d3dStates[s]; + } + for(t = 0; t < MAXNUMTEXSTATES; t++) + if(validTexStates[t]) + for(s = 0; s < MAXNUMSTAGES; s++){ + d3ddevice->GetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, (DWORD*)&d3dTextureStageStates[t][s]); + textureStageStateCache[t][s].value = d3dTextureStageStates[t][s]; + } + for(t = 1; t < MAXNUMSAMPLERSTATES; t++) + for(s = 0; s < MAXNUMSTAGES; s++){ + d3ddevice->GetSamplerState(s, (D3DSAMPLERSTATETYPE)t, (DWORD*)&d3dSamplerStates[t][s]); + d3dSamplerStates[t][s] = d3dSamplerStates[t][s]; + } + // init rw cache + for(t = 0; t < MAXNUMSTAGES; t++){ + setFilterMode(t, Texture::NEAREST); + setAddressU(t, Texture::WRAP); + setAddressV(t, Texture::WRAP); + } + + IDirect3DSurface9 *surf; + D3DLOCKED_RECT lr; + uint8 whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF}; + whiteTex = (IDirect3DTexture9*)createTexture(1, 1, 1, 0, D3DFMT_X8R8G8B8); + whiteTex->GetSurfaceLevel(0, &surf); + HRESULT res = surf->LockRect(&lr, 0, D3DLOCK_NOSYSLOCK); + assert(res == D3D_OK); + memcpy(lr.pBits, whitepixel, 4); + surf->UnlockRect(); + surf->Release(); + + openIm2D(); + openIm3D(); + + return 1; +} + +static int +termD3D(void) +{ + destroyVertexBuffer(constantVertexStream); + constantVertexStream = nil; + + destroyTexture(whiteTex); + whiteTex = nil; + + closeIm3D(); + closeIm2D(); + + releaseVideoMemory(); + + ULONG ref = d3d::d3ddevice->Release(); + if(ref != 0) + printf("IDirect3D9Device_Release did not destroy\n"); + d3d::d3ddevice = nil; + return 1; +} + +static int +finalizeD3D(void) +{ + return 1; +} + +static int +deviceSystem(DeviceReq req, void *arg, int32 n) +{ + D3DADAPTER_IDENTIFIER9 adapter; + VideoMode *rwmode; + + switch(req){ + case DEVICEOPEN: + return openD3D((EngineOpenParams*)arg); + case DEVICECLOSE: + return closeD3D(); + + case DEVICEINIT: + return startD3D() && initD3D(); + case DEVICETERM: + return termD3D(); + + case DEVICEFINALIZE: + return finalizeD3D(); + + + case DEVICEGETNUMSUBSYSTEMS: + return d3d9Globals.numAdapters; + + case DEVICEGETCURRENTSUBSYSTEM: + return d3d9Globals.adapter; + + case DEVICESETSUBSYSTEM: + if(n >= d3d9Globals.numAdapters) + return 0; + d3d9Globals.adapter = n; + if(d3d9Globals.d3d9->GetDeviceCaps(d3d9Globals.adapter, D3DDEVTYPE_HAL, &d3d9Globals.caps) != D3D_OK) + return 0; + makeVideoModeList(); + return 1; + + case DEVICEGETSUBSSYSTEMINFO: + if(n >= d3d9Globals.numAdapters) + return 0; + if(d3d9Globals.d3d9->GetAdapterIdentifier(d3d9Globals.adapter, 0, &adapter) != D3D_OK) + return 0; + strncpy(((SubSystemInfo*)arg)->name, adapter.Description, sizeof(SubSystemInfo::name)); + return 1; + + + case DEVICEGETNUMVIDEOMODES: + return d3d9Globals.numModes; + + case DEVICEGETCURRENTVIDEOMODE: + return d3d9Globals.currentMode; + + case DEVICESETVIDEOMODE: + if(n >= d3d9Globals.numModes) + return 0; + d3d9Globals.currentMode = n; + return 1; + + case DEVICEGETVIDEOMODEINFO: + rwmode = (VideoMode*)arg; + rwmode->width = d3d9Globals.modes[n].mode.Width; + rwmode->height = d3d9Globals.modes[n].mode.Height; + rwmode->depth = findFormatDepth(d3d9Globals.modes[n].mode.Format); + rwmode->flags = d3d9Globals.modes[n].flags; + return 1; + case DEVICEGETMAXMULTISAMPLINGLEVELS: + { + assert(d3d9Globals.d3d9 != nil); + uint32 level; + DWORD quality; + for (level = D3DMULTISAMPLE_16_SAMPLES; level > D3DMULTISAMPLE_NONMASKABLE; level--) { + if (SUCCEEDED(d3d9Globals.d3d9->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3d9Globals.startMode.mode.Format, + !(d3d9Globals.startMode.flags & VIDEOMODEEXCLUSIVE), (D3DMULTISAMPLE_TYPE)level, + &quality))) + return level; + } + } + return 1; + case DEVICEGETMULTISAMPLINGLEVELS: + if(d3d9Globals.msLevel == 0) + return 1; + return d3d9Globals.msLevel; + case DEVICESETMULTISAMPLINGLEVELS: + d3d9Globals.msLevel = (uint32)n; + return 1; + } + return 1; +} + +Device renderdevice = { + 0.0f, 1.0f, + d3d::beginUpdate, + d3d::endUpdate, + d3d::clearCamera, + d3d::showRaster, + d3d::rasterRenderFast, + d3d::setRwRenderState, + d3d::getRwRenderState, + d3d::im2DRenderLine, + d3d::im2DRenderTriangle, + d3d::im2DRenderPrimitive, + d3d::im2DRenderIndexedPrimitive, + d3d::im3DTransform, + d3d::im3DRenderPrimitive, + d3d::im3DRenderIndexedPrimitive, + d3d::im3DEnd, + d3d::deviceSystem, +}; + +#endif +} +} diff --git a/src/d3d/d3dimmed.cpp b/src/d3d/d3dimmed.cpp new file mode 100644 index 0000000..e0df9d9 --- /dev/null +++ b/src/d3d/d3dimmed.cpp @@ -0,0 +1,404 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwplg.h" +#include "../rwrender.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" +#include "rwd3d9.h" +#include "rwd3dimpl.h" + +namespace rw { +namespace d3d { + +#ifdef RW_D3D9 + +// might want to tweak this +#define NUMINDICES 10000 +#define NUMVERTICES 10000 + +static int primTypeMap[] = { + D3DPT_POINTLIST, // invalid + D3DPT_LINELIST, + D3DPT_LINESTRIP, + D3DPT_TRIANGLELIST, + D3DPT_TRIANGLESTRIP, + D3DPT_TRIANGLEFAN, + D3DPT_POINTLIST, // actually not supported! +}; + +static IDirect3DVertexDeclaration9 *im2ddecl; +static IDirect3DVertexBuffer9 *im2dvertbuf; +static IDirect3DIndexBuffer9 *im2dindbuf; + +void *im2dOverridePS; + +void +openIm2D(void) +{ + D3DVERTEXELEMENT9 elements[4] = { +// can't get proper fog with this :( +// { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 }, + { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, offsetof(Im2DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, + { 0, offsetof(Im2DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() + }; + assert(im2ddecl == nil); + im2ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements); + assert(im2ddecl); + + assert(im2dvertbuf == nil); + im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, true); + assert(im2dvertbuf); + addDynamicVB(NUMVERTICES*sizeof(Im2DVertex), 0, &im2dvertbuf); + + assert(im2dindbuf == nil); + im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true); + assert(im2dindbuf); + addDynamicIB(NUMINDICES*sizeof(uint16), &im2dindbuf); +} + +void +closeIm2D(void) +{ + d3d9::destroyVertexDeclaration(im2ddecl); + im2ddecl = nil; + + removeDynamicVB(&im2dvertbuf); + destroyVertexBuffer(im2dvertbuf); + im2dvertbuf = nil; + + removeDynamicIB(&im2dindbuf); + destroyIndexBuffer(im2dindbuf); + im2dindbuf = nil; +} + +static Im2DVertex tmpprimbuf[3]; + +void +im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2) +{ + Im2DVertex *verts = (Im2DVertex*)vertices; + tmpprimbuf[0] = verts[vert1]; + tmpprimbuf[1] = verts[vert2]; + im2DRenderPrimitive(PRIMTYPELINELIST, tmpprimbuf, 2); +} + +void +im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3) +{ + Im2DVertex *verts = (Im2DVertex*)vertices; + tmpprimbuf[0] = verts[vert1]; + tmpprimbuf[1] = verts[vert2]; + tmpprimbuf[2] = verts[vert3]; + im2DRenderPrimitive(PRIMTYPETRILIST, tmpprimbuf, 3); +} + +void +im2DSetXform(void) +{ + float xform[4]; + Camera *cam; + cam = (Camera*)engine->currentCamera; + xform[0] = 2.0f/cam->frameBuffer->width; + xform[1] = -2.0f/cam->frameBuffer->height; + xform[2] = -1.0f; + xform[3] = 1.0f; + // TODO: should cache this... + d3ddevice->SetVertexShaderConstantF(VSLOC_afterLights, xform, 1); +} + +void +im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices) +{ + if(numVertices > NUMVERTICES){ + // TODO: error + return; + } + uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD); + memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); + unlockVertices(im2dvertbuf); + + setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); + setVertexDeclaration(im2ddecl); + + im2DSetXform(); + + setVertexShader(im2d_VS); + if(im2dOverridePS) + setPixelShader(im2dOverridePS); + else if(engine->device.getRenderState(TEXTURERASTER)) + setPixelShader(im2d_tex_PS); + else + setPixelShader(im2d_PS); + + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = numVertices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = numVertices-1; + break; + case PRIMTYPETRILIST: + primCount = numVertices/3; + break; + case PRIMTYPETRISTRIP: + primCount = numVertices-2; + break; + case PRIMTYPETRIFAN: + primCount = numVertices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = numVertices; + break; + } + d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount); +} + +void +im2DRenderIndexedPrimitive(PrimitiveType primType, + void *vertices, int32 numVertices, void *indices, int32 numIndices) +{ + if(numVertices > NUMVERTICES || + numIndices > NUMINDICES){ + // TODO: error + return; + } + uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD); + memcpy(lockedindices, indices, numIndices*sizeof(uint16)); + unlockIndices(im2dindbuf); + + uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_DISCARD); + memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex)); + unlockVertices(im2dvertbuf); + + setStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex)); + setIndices(im2dindbuf); + setVertexDeclaration(im2ddecl); + + im2DSetXform(); + + setVertexShader(im2d_VS); + if(im2dOverridePS) + setPixelShader(im2dOverridePS); + else if(engine->device.getRenderState(TEXTURERASTER)) + setPixelShader(im2d_tex_PS); + else + setPixelShader(im2d_PS); + + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = numIndices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = numIndices-1; + break; + case PRIMTYPETRILIST: + primCount = numIndices/3; + break; + case PRIMTYPETRISTRIP: + primCount = numIndices-2; + break; + case PRIMTYPETRIFAN: + primCount = numIndices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = numIndices; + break; + } + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, + 0, numVertices, + 0, primCount); +} + + +// Im3D + + +static IDirect3DVertexDeclaration9 *im3ddecl; +static IDirect3DVertexBuffer9 *im3dvertbuf; +static IDirect3DIndexBuffer9 *im3dindbuf; +static int32 num3DVertices; + +void +openIm3D(void) +{ + D3DVERTEXELEMENT9 elements[5] = { + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, offsetof(Im3DVertex, normal), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, + { 0, offsetof(Im3DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, + { 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() + }; + + assert(im3ddecl == nil); + im3ddecl = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements); + assert(im3ddecl); + + assert(im3dvertbuf == nil); + im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, true); + assert(im3dvertbuf); + addDynamicVB(NUMVERTICES*sizeof(Im3DVertex), 0, &im3dvertbuf); + + assert(im3dindbuf == nil); + im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16), true); + assert(im3dindbuf); + addDynamicIB(NUMINDICES*sizeof(uint16), &im3dindbuf); +} + +void +closeIm3D(void) +{ + d3d9::destroyVertexDeclaration(im3ddecl); + im3ddecl = nil; + + removeDynamicVB(&im3dvertbuf); + destroyVertexBuffer(im3dvertbuf); + im3dvertbuf = nil; + + removeDynamicIB(&im3dindbuf); + destroyIndexBuffer(im3dindbuf); + im3dindbuf = nil; +} + +// settable by user - TOOD: make this less shit +RGBA im3dMaterialColor = { 255, 255, 255, 255 }; +SurfaceProperties im3dSurfaceProps = { 1.0f, 1.0f, 1.0f }; + +void +im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags) +{ + if(world == nil) + uploadMatrices(); + else + uploadMatrices(world); + + if((flags & im3d::VERTEXUV) == 0) + SetRenderStatePtr(TEXTURERASTER, nil); + + void *shader = default_amb_VS; + if(flags & im3d::LIGHTING){ + setMaterial(im3dMaterialColor, im3dSurfaceProps); + int32 vsBits = lightingCB_Shader(); + // Pick a shader + if((vsBits & VSLIGHT_MASK) == 0) + shader = default_amb_VS; + else if((vsBits & VSLIGHT_MASK) == VSLIGHT_DIRECT) + shader = default_amb_dir_VS; + else + shader = default_all_VS; + }else{ + static RGBA white = { 255, 255, 255, 255 }; + static SurfaceProperties surfprops = { 0.0f, 0.0f, 0.0f }; + setMaterial(white, surfprops); + } + + uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_DISCARD); + memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex)); + unlockVertices(im3dvertbuf); + + setStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex)); + setVertexDeclaration(im3ddecl); + + setVertexShader(shader); + + num3DVertices = numVertices; +} + +void +im3DRenderPrimitive(PrimitiveType primType) +{ + if(engine->device.getRenderState(TEXTURERASTER)) + setPixelShader(default_tex_PS); + else + setPixelShader(default_PS); + + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = num3DVertices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = num3DVertices-1; + break; + case PRIMTYPETRILIST: + primCount = num3DVertices/3; + break; + case PRIMTYPETRISTRIP: + primCount = num3DVertices-2; + break; + case PRIMTYPETRIFAN: + primCount = num3DVertices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = num3DVertices; + break; + } + d3ddevice->DrawPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, primCount); +} + +void +im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices) +{ + uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), D3DLOCK_DISCARD); + memcpy(lockedindices, indices, numIndices*sizeof(uint16)); + unlockIndices(im3dindbuf); + + setIndices(im3dindbuf); + + if(engine->device.getRenderState(TEXTURERASTER)) + setPixelShader(default_tex_PS); + else + setPixelShader(default_PS); + + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = numIndices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = numIndices-1; + break; + case PRIMTYPETRILIST: + primCount = numIndices/3; + break; + case PRIMTYPETRISTRIP: + primCount = numIndices-2; + break; + case PRIMTYPETRIFAN: + primCount = numIndices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = numIndices; + break; + } + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, + 0, num3DVertices, + 0, primCount); +} + +void +im3DEnd(void) +{ +} + +#endif +} +} diff --git a/src/d3d/d3drender.cpp b/src/d3d/d3drender.cpp new file mode 100644 index 0000000..d135d87 --- /dev/null +++ b/src/d3d/d3drender.cpp @@ -0,0 +1,424 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#define WITH_D3D +#include "../rwbase.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwd3d.h" + +namespace rw { +namespace d3d { + +#ifdef RW_D3D9 +IDirect3DDevice9 *d3ddevice = nil; + +#define MAX_LIGHTS 8 + + +#define VS_NAME g_vs20_main +#define PS_NAME g_ps20_main +void *default_amb_VS; +void *default_amb_dir_VS; +void *default_all_VS; +void *default_PS; +void *default_tex_PS; +void *im2d_VS; +void *im2d_PS; +void *im2d_tex_PS; + + +void +createDefaultShaders(void) +{ + { + static +#include "shaders/default_amb_VS.h" + default_amb_VS = createVertexShader((void*)VS_NAME); + assert(default_amb_VS); + } + { + static +#include "shaders/default_amb_dir_VS.h" + default_amb_dir_VS = createVertexShader((void*)VS_NAME); + assert(default_amb_dir_VS); + } + { + static +#include "shaders/default_all_VS.h" + default_all_VS = createVertexShader((void*)VS_NAME); + assert(default_all_VS); + } + + { + static +#include "shaders/default_PS.h" + default_PS = createPixelShader((void*)PS_NAME); + assert(default_PS); + } + { + static +#include "shaders/default_tex_PS.h" + default_tex_PS = createPixelShader((void*)PS_NAME); + assert(default_tex_PS); + } + + { + static +#include "shaders/im2d_VS.h" + im2d_VS = createVertexShader((void*)VS_NAME); + assert(im2d_VS); + } + { + static +#include "shaders/im2d_PS.h" + im2d_PS = createPixelShader((void*)PS_NAME); + assert(im2d_PS); + } + { + static +#include "shaders/im2d_tex_PS.h" + im2d_tex_PS = createPixelShader((void*)PS_NAME); + assert(im2d_tex_PS); + } +} + +void +destroyDefaultShaders(void) +{ + destroyVertexShader(default_amb_VS); + default_amb_VS = nil; + destroyVertexShader(default_amb_dir_VS); + default_amb_dir_VS = nil; + destroyVertexShader(default_all_VS); + default_all_VS = nil; + + destroyPixelShader(default_PS); + default_PS = nil; + destroyPixelShader(default_tex_PS); + default_tex_PS = nil; + + destroyVertexShader(im2d_VS); + im2d_VS = nil; + destroyPixelShader(im2d_PS); + im2d_PS = nil; + destroyPixelShader(im2d_tex_PS); + im2d_tex_PS = nil; +} + + +void +lightingCB_Fix(Atomic *atomic) +{ + WorldLights lightData; + Light *directionals[8]; + Light *locals[8]; + lightData.directionals = directionals; + lightData.numDirectionals = 8; + lightData.locals = locals; + lightData.numLocals = 8; + + ((World*)engine->currentWorld)->enumerateLights(atomic, &lightData); + + int i, n; + RGBA amb; + D3DLIGHT9 light; + light.Type = D3DLIGHT_DIRECTIONAL; + //light.Diffuse = { 0.8f, 0.8f, 0.8f, 1.0f }; + light.Specular = { 0.0f, 0.0f, 0.0f, 0.0f }; + light.Ambient = { 0.0f, 0.0f, 0.0f, 0.0f }; + light.Position = { 0.0f, 0.0f, 0.0f }; + //light.Direction = { 0.0f, 0.0f, -1.0f }; + light.Range = 0.0f; + light.Falloff = 0.0f; + light.Attenuation0 = 0.0f; + light.Attenuation1 = 0.0f; + light.Attenuation2 = 0.0f; + light.Theta = 0.0f; + light.Phi = 0.0f; + + convColor(&amb, &lightData.ambient); + d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha)); + + n = 0; + for(i = 0; i < lightData.numDirectionals; i++){ + if(n >= MAX_LIGHTS) + return; + Light *l = lightData.directionals[i]; + light.Type = D3DLIGHT_DIRECTIONAL; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + } + + for(i = 0; i < lightData.numLocals; i++){ + if(n >= MAX_LIGHTS) + return; + Light *l = lightData.locals[i]; + switch(l->getType()){ + case Light::POINT: + light.Type = D3DLIGHT_POINT; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction.x = 0.0f; + light.Direction.y = 0.0f; + light.Direction.z = 0.0f; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + break; + + case Light::SPOT: + light.Type = D3DLIGHT_SPOT; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); + light.Theta = l->getAngle()*2.0f; + light.Phi = light.Theta; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + break; + + case Light::SOFTSPOT: + light.Type = D3DLIGHT_SPOT; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); + light.Theta = 0.0f; + light.Phi = l->getAngle()*2.0f; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + break; + } + } + + for(; n < MAX_LIGHTS; n++) + d3ddevice->LightEnable(n, FALSE); +} + + +struct LightVS +{ + V3d color; float param0; + V3d position; float param1; + V3d direction; float param2; +}; + +void +setAmbient(const RGBAf &color) +{ + if(!equal(d3dShaderState.ambient, color)){ + d3dShaderState.ambient = color; + d3ddevice->SetVertexShaderConstantF(VSLOC_ambLight, (float*)&color, 1); + } +} + +void +setNumLights(int numDir, int numPoint, int numSpot) +{ + static int32 numLights[4*3]; + if(d3dShaderState.numDir != numDir || + d3dShaderState.numPoint != numPoint || + d3dShaderState.numSpot != numSpot){ + numLights[0] = d3dShaderState.numDir = numDir; + numLights[4] = d3dShaderState.numPoint = numPoint; + numLights[8] = d3dShaderState.numSpot = numSpot; + d3ddevice->SetVertexShaderConstantI(VSLOC_numLights, numLights, 3); + } +} + +int32 +uploadLights(WorldLights *lightData) +{ + int i; + int bits = 0; + float32 firstLight[4]; + firstLight[0] = 0; // directional + firstLight[1] = 0; // point + firstLight[2] = 0; // spot + firstLight[3] = 0; + + if(lightData->numAmbients) + bits |= VSLIGHT_AMBIENT; + + LightVS directionals[8]; + LightVS points[8]; + LightVS spots[8]; + for(i = 0; i < lightData->numDirectionals; i++){ + Light *l = lightData->directionals[i]; + directionals[i].color.x = l->color.red; + directionals[i].color.y = l->color.green; + directionals[i].color.z = l->color.blue; + directionals[i].direction = l->getFrame()->getLTM()->at; + bits |= VSLIGHT_DIRECT; + } + + int np = 0; + int ns = 0; + for(i = 0; i < lightData->numLocals; i++){ + Light *l = lightData->locals[i]; + + switch(l->getType()){ + case Light::POINT: + points[np].color.x = l->color.red; + points[np].color.y = l->color.green; + points[np].color.z = l->color.blue; + points[np].param0 = l->radius; + points[np].position = l->getFrame()->getLTM()->pos; + np++; + bits |= VSLIGHT_POINT; + break; + case Light::SPOT: + case Light::SOFTSPOT: + spots[ns].color.x = l->color.red; + spots[ns].color.y = l->color.green; + spots[ns].color.z = l->color.blue; + spots[ns].param0 = l->radius; + spots[ns].position = l->getFrame()->getLTM()->pos; + spots[ns].direction = l->getFrame()->getLTM()->at; + spots[ns].param1 = l->minusCosAngle; + // lower bound of falloff + if(l->getType() == Light::SOFTSPOT) + spots[ns].param2 = 0.0f; + else + spots[ns].param2 = 1.0f; + bits |= VSLIGHT_SPOT; + ns++; + break; + } + } + + firstLight[0] = 0; + int numDir = lightData->numDirectionals; + firstLight[1] = numDir + firstLight[0]; + int numPoint = np; + firstLight[2] = numPoint + firstLight[1]; + int numSpot = ns; + + setNumLights(numDir, numPoint, numSpot); + if(d3dShaderState.lightOffset[0] != firstLight[0] || + d3dShaderState.lightOffset[1] != firstLight[1] || + d3dShaderState.lightOffset[2] != firstLight[2]){ + d3dShaderState.lightOffset[0] = firstLight[0]; + d3dShaderState.lightOffset[1] = firstLight[1]; + d3dShaderState.lightOffset[2] = firstLight[2]; + d3ddevice->SetVertexShaderConstantF(VSLOC_lightOffset, firstLight, 1); + } + + int32 off = VSLOC_lights; + if(numDir) + d3ddevice->SetVertexShaderConstantF(off, (float*)&directionals, numDir*3); + off += numDir*3; + + if(numPoint) + d3ddevice->SetVertexShaderConstantF(off, (float*)&points, numPoint*3); + off += numPoint*3; + + if(numSpot) + d3ddevice->SetVertexShaderConstantF(off, (float*)&spots, numSpot*3); + + return bits; +} + +int32 +lightingCB_Shader(Atomic *atomic) +{ + WorldLights lightData; + Light *directionals[8]; + Light *locals[8]; + lightData.directionals = directionals; + lightData.numDirectionals = 8; + lightData.locals = locals; + lightData.numLocals = 8; + + if(atomic->geometry->flags & rw::Geometry::LIGHT){ + ((World*)engine->currentWorld)->enumerateLights(atomic, &lightData); + setAmbient(lightData.ambient); + return uploadLights(&lightData); + }else{ + static const RGBAf black = { 0.0f, 0.0f, 0.0f, 0.0f }; + setAmbient(black); + setNumLights(0, 0, 0); + return 0; + } +} + +int32 +lightingCB_Shader(void) +{ + WorldLights lightData; + Light *directionals[8]; + Light *locals[8]; + lightData.directionals = directionals; + lightData.numDirectionals = 8; + lightData.locals = locals; + lightData.numLocals = 8; + + ((World*)engine->currentWorld)->enumerateLights(&lightData); + setAmbient(lightData.ambient); + return uploadLights(&lightData); +} + +static RawMatrix identityXform = { + { 1.0f, 0.0f, 0.0f }, 0.0f, + { 0.0f, 1.0f, 0.0f }, 0.0f, + { 0.0f, 0.0f, 1.0f }, 0.0f, + { 0.0f, 0.0f, 0.0f }, 1.0f +}; + +void +uploadMatrices(void) +{ + RawMatrix combined; + Camera *cam = engine->currentCamera; + d3ddevice->SetVertexShaderConstantF(VSLOC_world, (float*)&identityXform, 4); + d3ddevice->SetVertexShaderConstantF(VSLOC_normal, (float*)&identityXform, 4); + + RawMatrix::mult(&combined, &cam->devView, &cam->devProj); + d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&combined, 4); +} + +void +uploadMatrices(Matrix *worldMat) +{ + RawMatrix combined, world, worldview; + Camera *cam = engine->currentCamera; + convMatrix(&world, worldMat); + d3ddevice->SetVertexShaderConstantF(VSLOC_world, (float*)&world, 4); + // TODO: inverse transpose + d3ddevice->SetVertexShaderConstantF(VSLOC_normal, (float*)&world, 4); + + RawMatrix::mult(&worldview, &world, &cam->devView); + RawMatrix::mult(&combined, &worldview, &cam->devProj); + d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&combined, 4); +} + + + +#endif + +} +} diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h new file mode 100644 index 0000000..cabfeff --- /dev/null +++ b/src/d3d/rwd3d.h @@ -0,0 +1,421 @@ +#ifdef RW_D3D9 +#ifdef WITH_D3D +#include <d3d9.h> +#endif +#endif + +namespace rw { + +#ifdef RW_D3D9 + +#ifdef _WINDOWS_ +struct EngineOpenParams +{ + HWND window; +}; +#else +struct EngineOpenParams +{ + uint32 please_include_windows_h; +}; +#endif +#else +#ifdef _D3D9_H_ +#error "please don't include d3d9.h for non-d3d9 platforms" +#endif +#endif + +namespace d3d { + +extern bool32 isP8supported; + +extern Device renderdevice; + +#ifdef RW_D3D9 +#ifdef _D3D9_H_ +extern IDirect3DDevice9 *d3ddevice; +void setD3dMaterial(D3DMATERIAL9 *mat9); +#endif + +#define COLOR_ARGB(a, r, g, b) ((rw::uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) + +struct Im3DVertex +{ + V3d position; + V3d normal; // librw extension + uint32 color; + float32 u, v; + + void setX(float32 x) { this->position.x = x; } + void setY(float32 y) { this->position.y = y; } + void setZ(float32 z) { this->position.z = z; } + void setNormalX(float32 x) { this->normal.x = x; } + void setNormalY(float32 y) { this->normal.y = y; } + void setNormalZ(float32 z) { this->normal.z = z; } + void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); } + void setU(float32 u) { this->u = u; } + void setV(float32 v) { this->v = v; } + + float getX(void) { return this->position.x; } + float getY(void) { return this->position.y; } + float getZ(void) { return this->position.z; } + float getNormalX(void) { return this->normal.x; } + float getNormalY(void) { return this->normal.y; } + float getNormalZ(void) { return this->normal.z; } + RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF, + this->color & 0xFF, this->color>>24 & 0xFF); } + float getU(void) { return this->u; } + float getV(void) { return this->v; } +}; +extern RGBA im3dMaterialColor; +extern SurfaceProperties im3dSurfaceProps; + +struct Im2DVertex +{ + float32 x, y, z; + //float32 q; // recipz no longer used because we have a vertex stage now + float32 w; + uint32 color; + float32 u, v; + + void setScreenX(float32 x) { this->x = x; } + void setScreenY(float32 y) { this->y = y; } + void setScreenZ(float32 z) { this->z = z; } + void setCameraZ(float32 z) { this->w = z; } +// void setRecipCameraZ(float32 recipz) { this->q = recipz; } + void setRecipCameraZ(float32 recipz) { this->w = 1.0f/recipz; } + void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = COLOR_ARGB(a, r, g, b); } + void setU(float32 u, float recipZ) { this->u = u; } + void setV(float32 v, float recipZ) { this->v = v; } + + float getScreenX(void) { return this->x; } + float getScreenY(void) { return this->y; } + float getScreenZ(void) { return this->z; } +// float getCameraZ(void) { return 1.0f/this->q; } +// float getRecipCameraZ(void) { return this->q; } + float getCameraZ(void) { return this->w; } + float getRecipCameraZ(void) { return 1.0f/this->w; } + RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF, + this->color & 0xFF, this->color>>24 & 0xFF); } + float getU(void) { return this->u; } + float getV(void) { return this->v; } +}; + +#else +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \ + ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 )) +#endif +enum { + D3DFMT_UNKNOWN = 0, + + D3DFMT_R8G8B8 = 20, + D3DFMT_A8R8G8B8 = 21, + D3DFMT_X8R8G8B8 = 22, + D3DFMT_R5G6B5 = 23, + D3DFMT_X1R5G5B5 = 24, + D3DFMT_A1R5G5B5 = 25, + D3DFMT_A4R4G4B4 = 26, + D3DFMT_R3G3B2 = 27, + D3DFMT_A8 = 28, + D3DFMT_A8R3G3B2 = 29, + D3DFMT_X4R4G4B4 = 30, + D3DFMT_A2B10G10R10 = 31, + D3DFMT_A8B8G8R8 = 32, + D3DFMT_X8B8G8R8 = 33, + D3DFMT_G16R16 = 34, + D3DFMT_A2R10G10B10 = 35, + D3DFMT_A16B16G16R16 = 36, + + D3DFMT_A8P8 = 40, + D3DFMT_P8 = 41, + + D3DFMT_L8 = 50, + D3DFMT_A8L8 = 51, + D3DFMT_A4L4 = 52, + + D3DFMT_V8U8 = 60, + D3DFMT_L6V5U5 = 61, + D3DFMT_X8L8V8U8 = 62, + D3DFMT_Q8W8V8U8 = 63, + D3DFMT_V16U16 = 64, + D3DFMT_A2W10V10U10 = 67, + + D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), + D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), + D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), + D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), + D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), + D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), + D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), + D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), + D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), + + D3DFMT_D16_LOCKABLE = 70, + D3DFMT_D32 = 71, + D3DFMT_D15S1 = 73, + D3DFMT_D24S8 = 75, + D3DFMT_D24X8 = 77, + D3DFMT_D24X4S4 = 79, + D3DFMT_D16 = 80, + + D3DFMT_D32F_LOCKABLE = 82, + D3DFMT_D24FS8 = 83, + + // d3d9ex only + /* Z-Stencil formats valid for CPU access */ + D3DFMT_D32_LOCKABLE = 84, + D3DFMT_S8_LOCKABLE = 85, + + D3DFMT_L16 = 81, + + D3DFMT_VERTEXDATA =100, + D3DFMT_INDEX16 =101, + D3DFMT_INDEX32 =102, + + D3DFMT_Q16W16V16U16 =110, + + D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M','E','T','1'), + + // Floating point surface formats + + // s10e5 formats (16-bits per channel) + D3DFMT_R16F = 111, + D3DFMT_G16R16F = 112, + D3DFMT_A16B16G16R16F = 113, + + // IEEE s23e8 formats (32-bits per channel) + D3DFMT_R32F = 114, + D3DFMT_G32R32F = 115, + D3DFMT_A32B32G32R32F = 116, + + D3DFMT_CxV8U8 = 117, + + // d3d9ex only + // Monochrome 1 bit per pixel format + D3DFMT_A1 = 118, + // 2.8 biased fixed point + D3DFMT_A2B10G10R10_XR_BIAS = 119, + // Binary format indicating that the data has no inherent type + D3DFMT_BINARYBUFFER = 199 +}; + +enum { + D3DLOCK_NOSYSLOCK = 0, // ignored + D3DPOOL_MANAGED = 0, // ignored + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + + + D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.) + D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.) + D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.) + D3DDECLTYPE_FLOAT4 = 3, // 4D float + D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range + // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) + D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte + D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.) + D3DDECLTYPE_SHORT4 = 7, // 4D signed short + + D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 + D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) + D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) + D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) + D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) + D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) + D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) + D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) + D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values + D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. + + + D3DDECLMETHOD_DEFAULT = 0, + + + D3DDECLUSAGE_POSITION = 0, + D3DDECLUSAGE_BLENDWEIGHT, // 1 + D3DDECLUSAGE_BLENDINDICES, // 2 + D3DDECLUSAGE_NORMAL, // 3 + D3DDECLUSAGE_PSIZE, // 4 + D3DDECLUSAGE_TEXCOORD, // 5 + D3DDECLUSAGE_TANGENT, // 6 + D3DDECLUSAGE_BINORMAL, // 7 + D3DDECLUSAGE_TESSFACTOR, // 8 + D3DDECLUSAGE_POSITIONT, // 9 + D3DDECLUSAGE_COLOR, // 10 + D3DDECLUSAGE_FOG, // 11 + D3DDECLUSAGE_DEPTH, // 12 + D3DDECLUSAGE_SAMPLE // 13 + , + + D3DUSAGE_AUTOGENMIPMAP = 0x400 +}; +#endif + +extern int vertFormatMap[]; + +void *createIndexBuffer(uint32 length, bool dynamic); +void destroyIndexBuffer(void *indexBuffer); +uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags); +void unlockIndices(void *indexBuffer); + +void *createVertexBuffer(uint32 length, uint32 fvf, bool dynamic); +void destroyVertexBuffer(void *vertexBuffer); +uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags); +void unlockVertices(void *vertexBuffer); + +void *createTexture(int32 width, int32 height, int32 levels, uint32 usage, uint32 format); +void destroyTexture(void *texture); +uint8 *lockTexture(void *texture, int32 level); +void unlockTexture(void *texture, int32 level); + +// Native Texture and Raster + +struct D3dRaster +{ + void *texture; + void *palette; + void *lockedSurf; + uint32 format; + uint32 bpp; // bytes per pixel + bool hasAlpha; + bool customFormat; + bool autogenMipmap; +}; + +int32 getLevelSize(Raster *raster, int32 level); +void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha); +void setPalette(Raster *raster, void *palette, int32 size); +void setTexels(Raster *raster, void *texels, int32 level); + +extern int32 nativeRasterOffset; +void registerNativeRaster(void); +#define GETD3DRASTEREXT(raster) PLUGINOFFSET(rw::d3d::D3dRaster, raster, rw::d3d::nativeRasterOffset) + +// Rendering + +void setRenderState(uint32 state, uint32 value); +void getRenderState(uint32 state, uint32 *value); +void setTextureStageState(uint32 stage, uint32 type, uint32 value); +void getTextureStageState(uint32 stage, uint32 type, uint32 *value); +void setSamplerState(uint32 stage, uint32 type, uint32 value); +void getSamplerState(uint32 stage, uint32 type, uint32 *value); +void flushCache(void); + +void setTexture(uint32 stage, Texture *tex); +void setMaterial(const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f); +inline void setMaterial(uint32 flags, const RGBA &color, const SurfaceProperties &surfaceprops, float extraSurfProp = 0.0f) +{ + static RGBA white = { 255, 255, 255, 255 }; + if(flags & Geometry::MODULATE) + setMaterial(color, surfaceprops, extraSurfProp); + else + setMaterial(white, surfaceprops, extraSurfProp); +} + +void setVertexShader(void *vs); +void setPixelShader(void *ps); +void setIndices(void *indexBuffer); +void setStreamSource(int n, void *buffer, uint32 offset, uint32 stride); +void setVertexDeclaration(void *declaration); + +void *createVertexShader(void *csosrc); +void *createPixelShader(void *csosrc); +void destroyVertexShader(void *shader); +void destroyPixelShader(void *shader); + + +/* + * Vertex shaders and common pipeline stuff + */ + +// This data will be available in vertex stream 2 +struct VertexConstantData +{ + V3d normal; + RGBA color; + TexCoords texCoors[8]; +}; +extern void *constantVertexStream; + +// TODO: figure out why this even still exists... +struct D3dShaderState +{ + // for VS + struct { + float32 start; + float32 end; + float32 range; // 1/(start-end) + float32 disable; // lower clamp + } fogData, fogDisable; + RGBA matColor; + SurfaceProperties surfProps; + float extraSurfProp; + float lightOffset[3]; + int32 numDir, numPoint, numSpot; + RGBAf ambient; + // for PS + RGBAf fogColor; + + bool fogDirty; +}; +extern D3dShaderState d3dShaderState; + +// Standard Vertex shader locations +enum +{ + VSLOC_combined = 0, + VSLOC_world = 4, + VSLOC_normal = 8, + VSLOC_matColor = 12, + VSLOC_surfProps = 13, + VSLOC_fogData = 14, + VSLOC_ambLight = 15, + VSLOC_lightOffset = 16, + VSLOC_lights = 17, + VSLOC_afterLights = VSLOC_lights + 8*3, + + VSLOC_numLights = 0, + + PSLOC_fogColor = 0 +}; + +// Vertex shader bits +enum +{ + // These should be low so they could be used as indices + VSLIGHT_DIRECT = 1, + VSLIGHT_POINT = 2, + VSLIGHT_SPOT = 4, + VSLIGHT_MASK = 7, // all the above + // less critical + VSLIGHT_AMBIENT = 8, +}; + +void lightingCB_Fix(Atomic *atomic); +int32 lightingCB_Shader(Atomic *atomic); +int32 lightingCB_Shader(void); +// for VS +void uploadMatrices(void); // no world transform +void uploadMatrices(Matrix *worldMat); +void setAmbient(const RGBAf &color); +void setNumLights(int numDir, int numPoint, int numSpot); +int32 uploadLights(WorldLights *lightData); // called by lightingCB_Shader + +extern void *im2dOverridePS; + +extern void *default_amb_VS; +extern void *default_amb_dir_VS; +extern void *default_all_VS; +extern void *default_PS; +extern void *default_tex_PS; +extern void *im2d_VS; +extern void *im2d_PS; +extern void *im2d_tex_PS; +void createDefaultShaders(void); +void destroyDefaultShaders(void); + + +} +} diff --git a/src/d3d/rwd3d8.h b/src/d3d/rwd3d8.h new file mode 100644 index 0000000..422379d --- /dev/null +++ b/src/d3d/rwd3d8.h @@ -0,0 +1,74 @@ +namespace rw { +namespace d3d8 { + +void registerPlatformPlugins(void); + +struct InstanceData +{ + uint32 minVert; + int32 stride; + int32 numVertices; + int32 numIndices; + Material *material; + uint32 vertexShader; + uint32 primType; + void *indexBuffer; + void *vertexBuffer; + uint32 baseIndex; + uint8 vertexAlpha; + uint8 managed; + uint8 remapped; +}; + +struct InstanceDataHeader : rw::InstanceDataHeader +{ + uint16 serialNumber; + uint16 numMeshes; + + InstanceData *inst; +}; + +uint32 makeFVFDeclaration(uint32 flags, int32 numTex); +int32 getStride(uint32 flags, int32 numTex); + +void *destroyNativeData(void *object, int32, int32); +Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); +Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); +int32 getSizeNativeData(void *object, int32, int32); +void registerNativeDataPlugin(void); + +class ObjPipeline : public rw::ObjPipeline +{ +public: + void init(void); + static ObjPipeline *create(void); + + void (*instanceCB)(Geometry *geo, InstanceData *header); + void (*uninstanceCB)(Geometry *geo, InstanceData *header); + void (*renderCB)(Atomic *atomic, InstanceDataHeader *header); +}; + +void defaultInstanceCB(Geometry *geo, InstanceData *header); +void defaultUninstanceCB(Geometry *geo, InstanceData *header); +void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header); + +ObjPipeline *makeDefaultPipeline(void); + +// Skin plugin + +void initSkin(void); +ObjPipeline *makeSkinPipeline(void); + +// MatFX plugin + +void initMatFX(void); +ObjPipeline *makeMatFXPipeline(void); + +// Native Texture and Raster + +Texture *readNativeTexture(Stream *stream); +void writeNativeTexture(Texture *tex, Stream *stream); +uint32 getSizeNativeTexture(Texture *tex); + +} +} diff --git a/src/d3d/rwd3d9.h b/src/d3d/rwd3d9.h new file mode 100644 index 0000000..03eccd5 --- /dev/null +++ b/src/d3d/rwd3d9.h @@ -0,0 +1,112 @@ +namespace rw { +namespace d3d9 { + +void registerPlatformPlugins(void); + +struct VertexElement +{ + uint16 stream; + uint16 offset; + uint8 type; + uint8 method; + uint8 usage; + uint8 usageIndex; +}; + +struct VertexStream +{ + void *vertexBuffer; + uint32 offset; + uint32 stride; + uint16 geometryFlags; + uint8 managed; + uint8 dynamicLock; +}; + +struct InstanceData +{ + uint32 numIndex; + uint32 minVert; + Material *material; + bool32 vertexAlpha; + void *vertexShader; + uint32 baseIndex; + uint32 numVertices; + uint32 startIndex; + uint32 numPrimitives; +}; + +struct InstanceDataHeader : rw::InstanceDataHeader +{ + uint32 serialNumber; + uint32 numMeshes; + void *indexBuffer; + uint32 primType; + VertexStream vertexStream[2]; + bool32 useOffsets; + void *vertexDeclaration; + uint32 totalNumIndex; + uint32 totalNumVertex; + + InstanceData *inst; +}; + +void *createVertexDeclaration(VertexElement *elements); +void destroyVertexDeclaration(void *delaration); +uint32 getDeclaration(void *declaration, VertexElement *elements); + +void drawInst_simple(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst); +// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer +void drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst); +// This one switches between the above two depending on render state; +void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst); + + + + +void *destroyNativeData(void *object, int32, int32); +Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); +Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); +int32 getSizeNativeData(void *object, int32, int32); +void registerNativeDataPlugin(void); + +class ObjPipeline : public rw::ObjPipeline +{ +public: + void init(void); + static ObjPipeline *create(void); + + void (*instanceCB)(Geometry *geo, InstanceDataHeader *header, bool32 reinstance); + void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header); + void (*renderCB)(Atomic *atomic, InstanceDataHeader *header); +}; + +void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance); +void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header); +void defaultRenderCB_Fix(Atomic *atomic, InstanceDataHeader *header); +void defaultRenderCB_Shader(Atomic *atomic, InstanceDataHeader *header); + +ObjPipeline *makeDefaultPipeline(void); + + +// Skin plugin + +void initSkin(void); +void uploadSkinMatrices(Atomic *atomic); +void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance); +void skinRenderCB(Atomic *atomic, InstanceDataHeader *header); +ObjPipeline *makeSkinPipeline(void); + +// MatFX plugin + +void initMatFX(void); +ObjPipeline *makeMatFXPipeline(void); + +// Native Texture and Raster + +Texture *readNativeTexture(Stream *stream); +void writeNativeTexture(Texture *tex, Stream *stream); +uint32 getSizeNativeTexture(Texture *tex); + +} +} diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h new file mode 100644 index 0000000..82f8a13 --- /dev/null +++ b/src/d3d/rwd3dimpl.h @@ -0,0 +1,81 @@ +namespace rw { +namespace d3d { + +#ifdef RW_D3D9 +void openIm2D(void); +void closeIm2D(void); +void im2DRenderLine(void *vertices, int32 numVertices, int32 vert1, int32 vert2); +void im2DRenderTriangle(void *vertices, int32 numVertices, int32 vert1, int32 vert2, int32 vert3); +void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32 numVertices); +void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices); + +void openIm3D(void); +void closeIm3D(void); +void im3DTransform(void *vertices, int32 numVertices, Matrix *world, uint32 flags); +void im3DRenderPrimitive(PrimitiveType primType); +void im3DRenderIndexedPrimitive(PrimitiveType primType, void *indices, int32 numIndices); +void im3DEnd(void); + + +struct DisplayMode +{ + D3DDISPLAYMODE mode; + uint32 flags; +}; + +struct D3d9Globals +{ + HWND window; + + IDirect3D9 *d3d9; + int numAdapters; + int adapter; + D3DCAPS9 caps; + DisplayMode *modes; + int numModes; + int currentMode; + DisplayMode startMode; + + uint32 msLevel; + + D3DPRESENT_PARAMETERS present; + + IDirect3DSurface9 *defaultRenderTarget; + IDirect3DSurface9 *defaultDepthSurf; + + int numTextures; + int numVertexShaders; + int numPixelShaders; + int numVertexBuffers; + int numIndexBuffers; + int numVertexDeclarations; +}; + +extern D3d9Globals d3d9Globals; + +void addVidmemRaster(Raster *raster); +void removeVidmemRaster(Raster *raster); + +void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer +void removeDynamicVB(IDirect3DVertexBuffer9 **buf); + +void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer +void removeDynamicIB(IDirect3DIndexBuffer9 **buf); + + +int findFormatDepth(uint32 format); +void evictD3D9Raster(Raster *raster); + +#endif + +Raster *rasterCreate(Raster *raster); +uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode); +void rasterUnlock(Raster *raster, int32 level); +int32 rasterNumLevels(Raster *raster); +bool32 imageFindRasterFormat(Image *img, int32 type, + int32 *width, int32 *height, int32 *depth, int32 *format); +bool32 rasterFromImage(Raster *raster, Image *image); +Image *rasterToImage(Raster *raster); + +} +} diff --git a/src/d3d/rwxbox.h b/src/d3d/rwxbox.h new file mode 100644 index 0000000..1abebe1 --- /dev/null +++ b/src/d3d/rwxbox.h @@ -0,0 +1,195 @@ +namespace rw { +namespace xbox { + +void registerPlatformPlugins(void); + +extern int v3dFormatMap[6]; +extern int v2dFormatMap[6]; + +struct InstanceData +{ + uint32 minVert; + int32 numVertices; + int32 numIndices; + void *indexBuffer; + Material *material; + uint32 vertexShader; +}; + +struct InstanceDataHeader : rw::InstanceDataHeader +{ + int32 size; + uint16 serialNumber; + uint16 numMeshes; + uint32 primType; + int32 numVertices; + int32 stride; + void *vertexBuffer; + bool32 vertexAlpha; + InstanceData *begin; + InstanceData *end; + + uint8 *data; +}; + +void *destroyNativeData(void *object, int32, int32); +Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); +Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); +int32 getSizeNativeData(void *object, int32, int32); +void registerNativeDataPlugin(void); + +class ObjPipeline : public rw::ObjPipeline +{ +public: + void init(void); + static ObjPipeline *create(void); + + void (*instanceCB)(Geometry *geo, InstanceDataHeader *header); + void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header); +}; + +ObjPipeline *makeDefaultPipeline(void); + +void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header); +void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header); + +// Skin plugin + +Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset); +Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset); +int32 getSizeNativeSkin(void *object, int32 offset); + +void initSkin(void); +ObjPipeline *makeSkinPipeline(void); + +// MatFX plugin + +void initMatFX(void); +ObjPipeline *makeMatFXPipeline(void); + +// Vertex Format plugin + +extern uint32 vertexFormatSizes[6]; + +uint32 *getVertexFmt(Geometry *g); +uint32 makeVertexFmt(int32 flags, uint32 numTexSets); +uint32 getVertexFmtStride(uint32 fmt); + +void registerVertexFormatPlugin(void); + +// Native Texture and Raster + +struct XboxRaster +{ + void *texture; + void *palette; + uint32 format; + uint32 bpp; // bytes per pixel + bool hasAlpha; + bool customFormat; + bool32 unknownFlag; +}; + +int32 getLevelSize(Raster *raster, int32 level); + +extern int32 nativeRasterOffset; +void registerNativeRaster(void); +#define GETXBOXRASTEREXT(raster) PLUGINOFFSET(rw::xbox::XboxRaster, raster, rw::xbox::nativeRasterOffset) + +Texture *readNativeTexture(Stream *stream); +void writeNativeTexture(Texture *tex, Stream *stream); +uint32 getSizeNativeTexture(Texture *tex); + +enum { + D3DFMT_UNKNOWN = 0xFFFFFFFF, + + /* Swizzled formats */ + + D3DFMT_A8R8G8B8 = 0x00000006, + D3DFMT_X8R8G8B8 = 0x00000007, + D3DFMT_R5G6B5 = 0x00000005, + D3DFMT_R6G5B5 = 0x00000027, + D3DFMT_X1R5G5B5 = 0x00000003, + D3DFMT_A1R5G5B5 = 0x00000002, + D3DFMT_A4R4G4B4 = 0x00000004, + D3DFMT_A8 = 0x00000019, + D3DFMT_A8B8G8R8 = 0x0000003A, + D3DFMT_B8G8R8A8 = 0x0000003B, + D3DFMT_R4G4B4A4 = 0x00000039, + D3DFMT_R5G5B5A1 = 0x00000038, + D3DFMT_R8G8B8A8 = 0x0000003C, + D3DFMT_R8B8 = 0x00000029, + D3DFMT_G8B8 = 0x00000028, + + D3DFMT_P8 = 0x0000000B, + + D3DFMT_L8 = 0x00000000, + D3DFMT_A8L8 = 0x0000001A, + D3DFMT_AL8 = 0x00000001, + D3DFMT_L16 = 0x00000032, + + D3DFMT_V8U8 = 0x00000028, + D3DFMT_L6V5U5 = 0x00000027, + D3DFMT_X8L8V8U8 = 0x00000007, + D3DFMT_Q8W8V8U8 = 0x0000003A, + D3DFMT_V16U16 = 0x00000033, + + D3DFMT_D16_LOCKABLE = 0x0000002C, + D3DFMT_D16 = 0x0000002C, + D3DFMT_D24S8 = 0x0000002A, + D3DFMT_F16 = 0x0000002D, + D3DFMT_F24S8 = 0x0000002B, + + /* YUV formats */ + + D3DFMT_YUY2 = 0x00000024, + D3DFMT_UYVY = 0x00000025, + + /* Compressed formats */ + + D3DFMT_DXT1 = 0x0000000C, + D3DFMT_DXT2 = 0x0000000E, + D3DFMT_DXT3 = 0x0000000E, + D3DFMT_DXT4 = 0x0000000F, + D3DFMT_DXT5 = 0x0000000F, + + /* Linear formats */ + + D3DFMT_LIN_A1R5G5B5 = 0x00000010, + D3DFMT_LIN_A4R4G4B4 = 0x0000001D, + D3DFMT_LIN_A8 = 0x0000001F, + D3DFMT_LIN_A8B8G8R8 = 0x0000003F, + D3DFMT_LIN_A8R8G8B8 = 0x00000012, + D3DFMT_LIN_B8G8R8A8 = 0x00000040, + D3DFMT_LIN_G8B8 = 0x00000017, + D3DFMT_LIN_R4G4B4A4 = 0x0000003E, + D3DFMT_LIN_R5G5B5A1 = 0x0000003D, + D3DFMT_LIN_R5G6B5 = 0x00000011, + D3DFMT_LIN_R6G5B5 = 0x00000037, + D3DFMT_LIN_R8B8 = 0x00000016, + D3DFMT_LIN_R8G8B8A8 = 0x00000041, + D3DFMT_LIN_X1R5G5B5 = 0x0000001C, + D3DFMT_LIN_X8R8G8B8 = 0x0000001E, + + D3DFMT_LIN_A8L8 = 0x00000020, + D3DFMT_LIN_AL8 = 0x0000001B, + D3DFMT_LIN_L16 = 0x00000035, + D3DFMT_LIN_L8 = 0x00000013, + + D3DFMT_LIN_V16U16 = 0x00000036, + D3DFMT_LIN_V8U8 = 0x00000017, + D3DFMT_LIN_L6V5U5 = 0x00000037, + D3DFMT_LIN_X8L8V8U8 = 0x0000001E, + D3DFMT_LIN_Q8W8V8U8 = 0x00000012, + + D3DFMT_LIN_D24S8 = 0x0000002E, + D3DFMT_LIN_F24S8 = 0x0000002F, + D3DFMT_LIN_D16 = 0x00000030, + D3DFMT_LIN_F16 = 0x00000031, + + D3DFMT_VERTEXDATA = 100, + D3DFMT_INDEX16 = 101 +}; + +} +} diff --git a/src/d3d/rwxboximpl.h b/src/d3d/rwxboximpl.h new file mode 100644 index 0000000..524ec28 --- /dev/null +++ b/src/d3d/rwxboximpl.h @@ -0,0 +1,11 @@ +namespace rw { +namespace xbox { + +Raster *rasterCreate(Raster *raster); +uint8 *rasterLock(Raster *raster, int32 level, int32 lockMode); +void rasterUnlock(Raster*, int32); +int32 rasterNumLevels(Raster *raster); +Image *rasterToImage(Raster *raster); + +} +} diff --git a/src/d3d/shaders/default_PS.h b/src/d3d/shaders/default_PS.h new file mode 100644 index 0000000..9f2cb31 --- /dev/null +++ b/src/d3d/shaders/default_PS.h @@ -0,0 +1,72 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /Fh default_PS.h default_PS.hlsl +// +// +// Parameters: +// +// float4 fogColor; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// + + ps_2_0 + dcl t0.xyz + dcl v0 + add r0.xyz, v0, -c0 + mad r0.xyz, t0.z, r0, c0 + mov r0.w, v0.w + mov oC0, r0 + +// approximately 4 instruction slots used +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 34, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 83, 0, + 0, 0, 0, 2, 255, 255, + 1, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 76, 0, 0, 0, 48, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 2, 0, 60, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 67, 111, 108, + 111, 114, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 112, 115, + 95, 50, 95, 48, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 2, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 228, 144, + 0, 0, 228, 161, 4, 0, + 0, 4, 0, 0, 7, 128, + 0, 0, 170, 176, 0, 0, + 228, 128, 0, 0, 228, 160, + 1, 0, 0, 2, 0, 0, + 8, 128, 0, 0, 255, 144, + 1, 0, 0, 2, 0, 8, + 15, 128, 0, 0, 228, 128, + 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/default_PS.hlsl b/src/d3d/shaders/default_PS.hlsl new file mode 100644 index 0000000..eaf279d --- /dev/null +++ b/src/d3d/shaders/default_PS.hlsl @@ -0,0 +1,19 @@ +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; + float4 Color : COLOR0; +}; + +sampler2D tex0 : register(s0); + +float4 fogColor : register(c0); + +float4 main(VS_out input) : COLOR +{ + float4 color = input.Color; +#ifdef TEX + color *= tex2D(tex0, input.TexCoord0.xy); +#endif + color.rgb = lerp(fogColor.rgb, color.rgb, input.TexCoord0.z); + return color; +} diff --git a/src/d3d/shaders/default_VS.hlsl b/src/d3d/shaders/default_VS.hlsl new file mode 100644 index 0000000..d2f5452 --- /dev/null +++ b/src/d3d/shaders/default_VS.hlsl @@ -0,0 +1,51 @@ +#include "standardConstants.h" + +struct VS_in +{ + float4 Position : POSITION; + float3 Normal : NORMAL; + float2 TexCoord : TEXCOORD0; + float4 Prelight : COLOR0; +}; + +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; // also fog + float4 Color : COLOR0; +}; + + +VS_out main(in VS_in input) +{ + VS_out output; + + output.Position = mul(combinedMat, input.Position); + float3 Vertex = mul(worldMat, input.Position).xyz; + float3 Normal = mul(normalMat, input.Normal); + + output.TexCoord0.xy = input.TexCoord; + + output.Color = input.Prelight; + output.Color.rgb += ambientLight.rgb * surfAmbient; + + int i; +#ifdef DIRECTIONALS + for(i = 0; i < numDirLights; i++) + output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse; +#endif +#ifdef POINTLIGHTS + for(i = 0; i < numPointLights; i++) + output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse; +#endif +#ifdef SPOTLIGHTS + for(i = 0; i < numSpotLights; i++) + output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse; +#endif + // PS2 clamps before material color + output.Color = clamp(output.Color, 0.0, 1.0); + output.Color *= matCol; + + output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0); + + return output; +} diff --git a/src/d3d/shaders/default_all_VS.h b/src/d3d/shaders/default_all_VS.h new file mode 100644 index 0000000..e6afa5d --- /dev/null +++ b/src/d3d/shaders/default_all_VS.h @@ -0,0 +1,491 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh +// default_all_VS.h default_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x4 combinedMat; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// int numPointLights; +// int numSpotLights; +// float4 surfProps; +// float4x4 worldMat; +// +// +// Registers: +// +// Name Reg Size +// -------------- ----- ---- +// numDirLights i0 1 +// numPointLights i1 1 +// numSpotLights i2 1 +// combinedMat c0 4 +// worldMat c4 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// + + vs_2_0 + def c11, 0, 3, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + mov oPos, r0 + mul r0.xyz, v0.y, c5 + mad r0.xyz, c4, v0.x, r0 + mad r0.xyz, c6, v0.z, r0 + mad r0.xyz, c7, v0.w, r0 + mul r1.xyz, v1.y, c9 + mad r1.xyz, c8, v1.x, r1 + mad r1.xyz, c10, v1.z, r1 + mov r2.x, c13.x + mad r2.xyz, c15, r2.x, v3 + mov r3.xyz, r2 + mov r1.w, c11.x + rep i0 + add r2.w, r1.w, c16.x + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + dp3 r2.w, r1, -c19[a0.x] + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, c17[a0.x] + mad r3.xyz, r4, c13.z, r3 + add r1.w, r1.w, c11.z + endrep + mov r2.xyz, r3 + mov r1.w, c11.x + rep i1 + add r2.w, r1.w, c16.y + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + add r4.xyz, r0, -c18[a0.x] + dp3 r2.w, r4, r4 + rsq r2.w, r2.w + mul r4.xyz, r2.w, r4 + dp3 r3.w, r1, -r4 + max r3.w, r3.w, c11.x + mul r4.xyz, r3.w, c17[a0.x] + rcp r2.w, r2.w + rcp r3.w, c17[a0.x].w + mad r2.w, r2.w, -r3.w, c11.z + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, r4 + mad r2.xyz, r4, c13.z, r2 + add r1.w, r1.w, c11.z + endrep + mov r3.xyz, r2 + mov r1.w, c11.x + rep i2 + add r2.w, r1.w, c16.z + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + add r4.xyz, r0, -c18[a0.x] + dp3 r2.w, r4, r4 + rsq r2.w, r2.w + mul r4.xyz, r2.w, r4 + dp3 r4.w, r1, -r4 + dp3 r4.x, r4, c19[a0.x] + max r4.y, r4.w, c11.x + mov r4.z, c11.z + add r4.xz, r4, c18[a0.x].w + rcp r4.z, r4.z + mul r4.x, r4.z, r4.x + slt r4.z, r4.x, c11.x + mad r4.y, r4.z, -r4.y, r4.y + max r4.x, r4.x, c19[a0.x].w + mul r4.x, r4.x, r4.y + mul r4.xyz, r4.x, c17[a0.x] + rcp r2.w, r2.w + rcp r4.w, c17[a0.x].w + mad r2.w, r2.w, -r4.w, c11.z + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, r4 + mad r3.xyz, r4, c13.z, r3 + add r1.w, r1.w, c11.z + endrep + mov r3.w, v3.w + max r1, r3, c11.x + min r1, r1, c11.z + mul oD0, r1, c12 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c11.z + mov oT0.xy, v2 + +// approximately 95 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 158, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 67, 2, + 0, 0, 0, 2, 254, 255, + 12, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 60, 2, 0, 0, 12, 1, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 2, 0, + 0, 0, 4, 0, 2, 0, + 56, 1, 0, 0, 0, 0, + 0, 0, 72, 1, 0, 0, + 2, 0, 16, 0, 1, 0, + 66, 0, 84, 1, 0, 0, + 0, 0, 0, 0, 100, 1, + 0, 0, 2, 0, 14, 0, + 1, 0, 58, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 108, 1, 0, 0, 2, 0, + 17, 0, 24, 0, 70, 0, + 184, 1, 0, 0, 0, 0, + 0, 0, 200, 1, 0, 0, + 2, 0, 12, 0, 1, 0, + 50, 0, 28, 1, 0, 0, + 0, 0, 0, 0, 207, 1, + 0, 0, 2, 0, 8, 0, + 3, 0, 34, 0, 220, 1, + 0, 0, 0, 0, 0, 0, + 236, 1, 0, 0, 1, 0, + 0, 0, 1, 0, 2, 0, + 252, 1, 0, 0, 0, 0, + 0, 0, 12, 2, 0, 0, + 1, 0, 1, 0, 1, 0, + 6, 0, 252, 1, 0, 0, + 0, 0, 0, 0, 27, 2, + 0, 0, 1, 0, 2, 0, + 1, 0, 10, 0, 252, 1, + 0, 0, 0, 0, 0, 0, + 41, 2, 0, 0, 2, 0, + 13, 0, 1, 0, 54, 0, + 28, 1, 0, 0, 0, 0, + 0, 0, 51, 2, 0, 0, + 2, 0, 4, 0, 4, 0, + 18, 0, 56, 1, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 99, 111, 109, 98, 105, 110, + 101, 100, 77, 97, 116, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 105, + 114, 115, 116, 76, 105, 103, + 104, 116, 0, 171, 1, 0, + 2, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 68, + 97, 116, 97, 0, 108, 105, + 103, 104, 116, 115, 0, 99, + 111, 108, 111, 114, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 112, 111, 115, 105, 116, 105, + 111, 110, 0, 100, 105, 114, + 101, 99, 116, 105, 111, 110, + 0, 171, 115, 1, 0, 0, + 124, 1, 0, 0, 140, 1, + 0, 0, 124, 1, 0, 0, + 149, 1, 0, 0, 124, 1, + 0, 0, 5, 0, 0, 0, + 1, 0, 12, 0, 8, 0, + 3, 0, 160, 1, 0, 0, + 109, 97, 116, 67, 111, 108, + 0, 110, 111, 114, 109, 97, + 108, 77, 97, 116, 0, 171, + 171, 171, 3, 0, 3, 0, + 3, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 110, 117, 109, 68, 105, 114, + 76, 105, 103, 104, 116, 115, + 0, 171, 171, 171, 0, 0, + 2, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 110, 117, 109, 80, + 111, 105, 110, 116, 76, 105, + 103, 104, 116, 115, 0, 110, + 117, 109, 83, 112, 111, 116, + 76, 105, 103, 104, 116, 115, + 0, 115, 117, 114, 102, 80, + 114, 111, 112, 115, 0, 119, + 111, 114, 108, 100, 77, 97, + 116, 0, 118, 115, 95, 50, + 95, 48, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 50, 57, + 46, 57, 53, 50, 46, 51, + 49, 49, 49, 0, 81, 0, + 0, 5, 11, 0, 15, 160, + 0, 0, 0, 0, 0, 0, + 64, 64, 0, 0, 128, 63, + 0, 0, 0, 0, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 15, 144, 31, 0, + 0, 2, 3, 0, 0, 128, + 1, 0, 15, 144, 31, 0, + 0, 2, 5, 0, 0, 128, + 2, 0, 15, 144, 31, 0, + 0, 2, 10, 0, 0, 128, + 3, 0, 15, 144, 5, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 85, 144, 1, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 15, 128, 0, 0, + 228, 160, 0, 0, 0, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 2, 0, 228, 160, 0, 0, + 170, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 3, 0, 228, 160, + 0, 0, 255, 144, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 15, 192, 0, 0, + 228, 128, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, + 85, 144, 5, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 4, 0, 228, 160, + 0, 0, 0, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 7, 128, 6, 0, + 228, 160, 0, 0, 170, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 7, 128, + 7, 0, 228, 160, 0, 0, + 255, 144, 0, 0, 228, 128, + 5, 0, 0, 3, 1, 0, + 7, 128, 1, 0, 85, 144, + 9, 0, 228, 160, 4, 0, + 0, 4, 1, 0, 7, 128, + 8, 0, 228, 160, 1, 0, + 0, 144, 1, 0, 228, 128, + 4, 0, 0, 4, 1, 0, + 7, 128, 10, 0, 228, 160, + 1, 0, 170, 144, 1, 0, + 228, 128, 1, 0, 0, 2, + 2, 0, 1, 128, 13, 0, + 0, 160, 4, 0, 0, 4, + 2, 0, 7, 128, 15, 0, + 228, 160, 2, 0, 0, 128, + 3, 0, 228, 144, 1, 0, + 0, 2, 3, 0, 7, 128, + 2, 0, 228, 128, 1, 0, + 0, 2, 1, 0, 8, 128, + 11, 0, 0, 160, 38, 0, + 0, 1, 0, 0, 228, 240, + 2, 0, 0, 3, 2, 0, + 8, 128, 1, 0, 255, 128, + 16, 0, 0, 160, 5, 0, + 0, 3, 2, 0, 8, 128, + 2, 0, 255, 128, 11, 0, + 85, 160, 46, 0, 0, 2, + 0, 0, 1, 176, 2, 0, + 255, 128, 8, 0, 0, 4, + 2, 0, 8, 128, 1, 0, + 228, 128, 19, 32, 228, 161, + 0, 0, 0, 176, 11, 0, + 0, 3, 2, 0, 8, 128, + 2, 0, 255, 128, 11, 0, + 0, 160, 5, 0, 0, 4, + 4, 0, 7, 128, 2, 0, + 255, 128, 17, 32, 228, 160, + 0, 0, 0, 176, 4, 0, + 0, 4, 3, 0, 7, 128, + 4, 0, 228, 128, 13, 0, + 170, 160, 3, 0, 228, 128, + 2, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 11, 0, 170, 160, 39, 0, + 0, 0, 1, 0, 0, 2, + 2, 0, 7, 128, 3, 0, + 228, 128, 1, 0, 0, 2, + 1, 0, 8, 128, 11, 0, + 0, 160, 38, 0, 0, 1, + 1, 0, 228, 240, 2, 0, + 0, 3, 2, 0, 8, 128, + 1, 0, 255, 128, 16, 0, + 85, 160, 5, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 85, 160, + 46, 0, 0, 2, 0, 0, + 1, 176, 2, 0, 255, 128, + 2, 0, 0, 4, 4, 0, + 7, 128, 0, 0, 228, 128, + 18, 32, 228, 161, 0, 0, + 0, 176, 8, 0, 0, 3, + 2, 0, 8, 128, 4, 0, + 228, 128, 4, 0, 228, 128, + 7, 0, 0, 2, 2, 0, + 8, 128, 2, 0, 255, 128, + 5, 0, 0, 3, 4, 0, + 7, 128, 2, 0, 255, 128, + 4, 0, 228, 128, 8, 0, + 0, 3, 3, 0, 8, 128, + 1, 0, 228, 128, 4, 0, + 228, 129, 11, 0, 0, 3, + 3, 0, 8, 128, 3, 0, + 255, 128, 11, 0, 0, 160, + 5, 0, 0, 4, 4, 0, + 7, 128, 3, 0, 255, 128, + 17, 32, 228, 160, 0, 0, + 0, 176, 6, 0, 0, 2, + 2, 0, 8, 128, 2, 0, + 255, 128, 6, 0, 0, 3, + 3, 0, 8, 128, 17, 32, + 255, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 2, 0, + 8, 128, 2, 0, 255, 128, + 3, 0, 255, 129, 11, 0, + 170, 160, 11, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 0, 160, + 5, 0, 0, 3, 4, 0, + 7, 128, 2, 0, 255, 128, + 4, 0, 228, 128, 4, 0, + 0, 4, 2, 0, 7, 128, + 4, 0, 228, 128, 13, 0, + 170, 160, 2, 0, 228, 128, + 2, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 11, 0, 170, 160, 39, 0, + 0, 0, 1, 0, 0, 2, + 3, 0, 7, 128, 2, 0, + 228, 128, 1, 0, 0, 2, + 1, 0, 8, 128, 11, 0, + 0, 160, 38, 0, 0, 1, + 2, 0, 228, 240, 2, 0, + 0, 3, 2, 0, 8, 128, + 1, 0, 255, 128, 16, 0, + 170, 160, 5, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 85, 160, + 46, 0, 0, 2, 0, 0, + 1, 176, 2, 0, 255, 128, + 2, 0, 0, 4, 4, 0, + 7, 128, 0, 0, 228, 128, + 18, 32, 228, 161, 0, 0, + 0, 176, 8, 0, 0, 3, + 2, 0, 8, 128, 4, 0, + 228, 128, 4, 0, 228, 128, + 7, 0, 0, 2, 2, 0, + 8, 128, 2, 0, 255, 128, + 5, 0, 0, 3, 4, 0, + 7, 128, 2, 0, 255, 128, + 4, 0, 228, 128, 8, 0, + 0, 3, 4, 0, 8, 128, + 1, 0, 228, 128, 4, 0, + 228, 129, 8, 0, 0, 4, + 4, 0, 1, 128, 4, 0, + 228, 128, 19, 32, 228, 160, + 0, 0, 0, 176, 11, 0, + 0, 3, 4, 0, 2, 128, + 4, 0, 255, 128, 11, 0, + 0, 160, 1, 0, 0, 2, + 4, 0, 4, 128, 11, 0, + 170, 160, 2, 0, 0, 4, + 4, 0, 5, 128, 4, 0, + 228, 128, 18, 32, 255, 160, + 0, 0, 0, 176, 6, 0, + 0, 2, 4, 0, 4, 128, + 4, 0, 170, 128, 5, 0, + 0, 3, 4, 0, 1, 128, + 4, 0, 170, 128, 4, 0, + 0, 128, 12, 0, 0, 3, + 4, 0, 4, 128, 4, 0, + 0, 128, 11, 0, 0, 160, + 4, 0, 0, 4, 4, 0, + 2, 128, 4, 0, 170, 128, + 4, 0, 85, 129, 4, 0, + 85, 128, 11, 0, 0, 4, + 4, 0, 1, 128, 4, 0, + 0, 128, 19, 32, 255, 160, + 0, 0, 0, 176, 5, 0, + 0, 3, 4, 0, 1, 128, + 4, 0, 0, 128, 4, 0, + 85, 128, 5, 0, 0, 4, + 4, 0, 7, 128, 4, 0, + 0, 128, 17, 32, 228, 160, + 0, 0, 0, 176, 6, 0, + 0, 2, 2, 0, 8, 128, + 2, 0, 255, 128, 6, 0, + 0, 3, 4, 0, 8, 128, + 17, 32, 255, 160, 0, 0, + 0, 176, 4, 0, 0, 4, + 2, 0, 8, 128, 2, 0, + 255, 128, 4, 0, 255, 129, + 11, 0, 170, 160, 11, 0, + 0, 3, 2, 0, 8, 128, + 2, 0, 255, 128, 11, 0, + 0, 160, 5, 0, 0, 3, + 4, 0, 7, 128, 2, 0, + 255, 128, 4, 0, 228, 128, + 4, 0, 0, 4, 3, 0, + 7, 128, 4, 0, 228, 128, + 13, 0, 170, 160, 3, 0, + 228, 128, 2, 0, 0, 3, + 1, 0, 8, 128, 1, 0, + 255, 128, 11, 0, 170, 160, + 39, 0, 0, 0, 1, 0, + 0, 2, 3, 0, 8, 128, + 3, 0, 255, 144, 11, 0, + 0, 3, 1, 0, 15, 128, + 3, 0, 228, 128, 11, 0, + 0, 160, 10, 0, 0, 3, + 1, 0, 15, 128, 1, 0, + 228, 128, 11, 0, 170, 160, + 5, 0, 0, 3, 0, 0, + 15, 208, 1, 0, 228, 128, + 12, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 5, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 11, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/default_amb_VS.h b/src/d3d/shaders/default_amb_VS.h new file mode 100644 index 0000000..6c22e23 --- /dev/null +++ b/src/d3d/shaders/default_amb_VS.h @@ -0,0 +1,156 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /Fh default_amb_VS.h default_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x4 combinedMat; +// float4 fogData; +// float4 matCol; +// float4 surfProps; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// combinedMat c0 4 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// + + vs_2_0 + def c4, 0, 1, 0, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_color v2 + mov r0.xyz, c15 + mad r0.xyz, r0, c13.x, v2 + mov r0.w, v2.w + max r0, r0, c4.x + min r0, r0, c4.y + mul oD0, r0, c12 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + add r1.x, r0.w, -c14.y + mov oPos, r0 + mul r0.x, r1.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.y + mov oT0.xy, v1 + +// approximately 16 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 69, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 220, 0, + 0, 0, 0, 2, 254, 255, + 5, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 213, 0, 0, 0, 128, 0, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 144, 0, + 0, 0, 0, 0, 0, 0, + 160, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 2, 0, + 172, 0, 0, 0, 0, 0, + 0, 0, 188, 0, 0, 0, + 2, 0, 14, 0, 1, 0, + 58, 0, 144, 0, 0, 0, + 0, 0, 0, 0, 196, 0, + 0, 0, 2, 0, 12, 0, + 1, 0, 50, 0, 144, 0, + 0, 0, 0, 0, 0, 0, + 203, 0, 0, 0, 2, 0, + 13, 0, 1, 0, 54, 0, + 144, 0, 0, 0, 0, 0, + 0, 0, 97, 109, 98, 105, + 101, 110, 116, 76, 105, 103, + 104, 116, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 99, 111, + 109, 98, 105, 110, 101, 100, + 77, 97, 116, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 68, + 97, 116, 97, 0, 109, 97, + 116, 67, 111, 108, 0, 115, + 117, 114, 102, 80, 114, 111, + 112, 115, 0, 118, 115, 95, + 50, 95, 48, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 81, 0, 0, 5, + 4, 0, 15, 160, 0, 0, + 0, 0, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, + 0, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 5, 0, 0, 128, 1, 0, + 15, 144, 31, 0, 0, 2, + 10, 0, 0, 128, 2, 0, + 15, 144, 1, 0, 0, 2, + 0, 0, 7, 128, 15, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 7, 128, 0, 0, + 228, 128, 13, 0, 0, 160, + 2, 0, 228, 144, 1, 0, + 0, 2, 0, 0, 8, 128, + 2, 0, 255, 144, 11, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 4, 0, + 0, 160, 10, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 4, 0, 85, 160, + 5, 0, 0, 3, 0, 0, + 15, 208, 0, 0, 228, 128, + 12, 0, 228, 160, 5, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 85, 144, 1, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 15, 128, 0, 0, + 228, 160, 0, 0, 0, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 2, 0, 228, 160, 0, 0, + 170, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 3, 0, 228, 160, + 0, 0, 255, 144, 0, 0, + 228, 128, 2, 0, 0, 3, + 1, 0, 1, 128, 0, 0, + 255, 128, 14, 0, 85, 161, + 1, 0, 0, 2, 0, 0, + 15, 192, 0, 0, 228, 128, + 5, 0, 0, 3, 0, 0, + 1, 128, 1, 0, 0, 128, + 14, 0, 170, 160, 11, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 0, 128, 14, 0, + 255, 160, 10, 0, 0, 3, + 0, 0, 4, 224, 0, 0, + 0, 128, 4, 0, 85, 160, + 1, 0, 0, 2, 0, 0, + 3, 224, 1, 0, 228, 144, + 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/default_amb_dir_VS.h b/src/d3d/shaders/default_amb_dir_VS.h new file mode 100644 index 0000000..768042f --- /dev/null +++ b/src/d3d/shaders/default_amb_dir_VS.h @@ -0,0 +1,272 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /Fh default_amb_dir_VS.h +// default_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x4 combinedMat; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// float4 surfProps; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// numDirLights i0 1 +// combinedMat c0 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// + + vs_2_0 + def c4, 0, 3, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + mov oPos, r0 + mul r0.xyz, v1.y, c9 + mad r0.xyz, c8, v1.x, r0 + mad r0.xyz, c10, v1.z, r0 + mov r1.x, c13.x + mad r1.xyz, c15, r1.x, v3 + mov r2.xyz, r1 + mov r1.w, c4.x + rep i0 + add r3.x, r1.w, c16.x + mul r3.x, r3.x, c4.y + mova a0.x, r3.x + dp3 r3.x, r0, -c19[a0.x] + max r3.x, r3.x, c4.x + mul r3.xyz, r3.x, c17[a0.x] + mad r2.xyz, r3, c13.z, r2 + add r1.w, r1.w, c4.z + endrep + mov r2.w, v3.w + max r1, r2, c4.x + min r1, r1, c4.z + mul oD0, r1, c12 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.z + mov oT0.xy, v2 + +// approximately 34 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 134, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 225, 1, + 0, 0, 0, 2, 254, 255, + 9, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 218, 1, 0, 0, 208, 0, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 224, 0, + 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 2, 0, + 252, 0, 0, 0, 0, 0, + 0, 0, 12, 1, 0, 0, + 2, 0, 16, 0, 1, 0, + 66, 0, 24, 1, 0, 0, + 0, 0, 0, 0, 40, 1, + 0, 0, 2, 0, 14, 0, + 1, 0, 58, 0, 224, 0, + 0, 0, 0, 0, 0, 0, + 48, 1, 0, 0, 2, 0, + 17, 0, 24, 0, 70, 0, + 124, 1, 0, 0, 0, 0, + 0, 0, 140, 1, 0, 0, + 2, 0, 12, 0, 1, 0, + 50, 0, 224, 0, 0, 0, + 0, 0, 0, 0, 147, 1, + 0, 0, 2, 0, 8, 0, + 3, 0, 34, 0, 160, 1, + 0, 0, 0, 0, 0, 0, + 176, 1, 0, 0, 1, 0, + 0, 0, 1, 0, 2, 0, + 192, 1, 0, 0, 0, 0, + 0, 0, 208, 1, 0, 0, + 2, 0, 13, 0, 1, 0, + 54, 0, 224, 0, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 99, 111, 109, 98, 105, 110, + 101, 100, 77, 97, 116, 0, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 105, + 114, 115, 116, 76, 105, 103, + 104, 116, 0, 171, 1, 0, + 2, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 68, + 97, 116, 97, 0, 108, 105, + 103, 104, 116, 115, 0, 99, + 111, 108, 111, 114, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 112, 111, 115, 105, 116, 105, + 111, 110, 0, 100, 105, 114, + 101, 99, 116, 105, 111, 110, + 0, 171, 55, 1, 0, 0, + 64, 1, 0, 0, 80, 1, + 0, 0, 64, 1, 0, 0, + 89, 1, 0, 0, 64, 1, + 0, 0, 5, 0, 0, 0, + 1, 0, 12, 0, 8, 0, + 3, 0, 100, 1, 0, 0, + 109, 97, 116, 67, 111, 108, + 0, 110, 111, 114, 109, 97, + 108, 77, 97, 116, 0, 171, + 171, 171, 3, 0, 3, 0, + 3, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 110, 117, 109, 68, 105, 114, + 76, 105, 103, 104, 116, 115, + 0, 171, 171, 171, 0, 0, + 2, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 115, 117, 114, 102, + 80, 114, 111, 112, 115, 0, + 118, 115, 95, 50, 95, 48, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 171, 171, 81, 0, + 0, 5, 4, 0, 15, 160, + 0, 0, 0, 0, 0, 0, + 64, 64, 0, 0, 128, 63, + 0, 0, 0, 0, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 15, 144, 31, 0, + 0, 2, 3, 0, 0, 128, + 1, 0, 15, 144, 31, 0, + 0, 2, 5, 0, 0, 128, + 2, 0, 15, 144, 31, 0, + 0, 2, 10, 0, 0, 128, + 3, 0, 15, 144, 5, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 85, 144, 1, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 15, 128, 0, 0, + 228, 160, 0, 0, 0, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 2, 0, 228, 160, 0, 0, + 170, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 3, 0, 228, 160, + 0, 0, 255, 144, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 15, 192, 0, 0, + 228, 128, 5, 0, 0, 3, + 0, 0, 7, 128, 1, 0, + 85, 144, 9, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 8, 0, 228, 160, + 1, 0, 0, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 7, 128, 10, 0, + 228, 160, 1, 0, 170, 144, + 0, 0, 228, 128, 1, 0, + 0, 2, 1, 0, 1, 128, + 13, 0, 0, 160, 4, 0, + 0, 4, 1, 0, 7, 128, + 15, 0, 228, 160, 1, 0, + 0, 128, 3, 0, 228, 144, + 1, 0, 0, 2, 2, 0, + 7, 128, 1, 0, 228, 128, + 1, 0, 0, 2, 1, 0, + 8, 128, 4, 0, 0, 160, + 38, 0, 0, 1, 0, 0, + 228, 240, 2, 0, 0, 3, + 3, 0, 1, 128, 1, 0, + 255, 128, 16, 0, 0, 160, + 5, 0, 0, 3, 3, 0, + 1, 128, 3, 0, 0, 128, + 4, 0, 85, 160, 46, 0, + 0, 2, 0, 0, 1, 176, + 3, 0, 0, 128, 8, 0, + 0, 4, 3, 0, 1, 128, + 0, 0, 228, 128, 19, 32, + 228, 161, 0, 0, 0, 176, + 11, 0, 0, 3, 3, 0, + 1, 128, 3, 0, 0, 128, + 4, 0, 0, 160, 5, 0, + 0, 4, 3, 0, 7, 128, + 3, 0, 0, 128, 17, 32, + 228, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 2, 0, + 7, 128, 3, 0, 228, 128, + 13, 0, 170, 160, 2, 0, + 228, 128, 2, 0, 0, 3, + 1, 0, 8, 128, 1, 0, + 255, 128, 4, 0, 170, 160, + 39, 0, 0, 0, 1, 0, + 0, 2, 2, 0, 8, 128, + 3, 0, 255, 144, 11, 0, + 0, 3, 1, 0, 15, 128, + 2, 0, 228, 128, 4, 0, + 0, 160, 10, 0, 0, 3, + 1, 0, 15, 128, 1, 0, + 228, 128, 4, 0, 170, 160, + 5, 0, 0, 3, 0, 0, + 15, 208, 1, 0, 228, 128, + 12, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 5, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 4, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/default_tex_PS.h b/src/d3d/shaders/default_tex_PS.h new file mode 100644 index 0000000..a25f918 --- /dev/null +++ b/src/d3d/shaders/default_tex_PS.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /DTEX /Fh default_tex_PS.h default_PS.hlsl +// +// +// Parameters: +// +// float4 fogColor; +// sampler2D tex0; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// tex0 s0 1 +// + + ps_2_0 + dcl t0.xyz + dcl v0 + dcl_2d s0 + texld r0, t0, s0 + mad r0.xyz, v0, r0, -c0 + mul r1.w, r0.w, v0.w + mad r1.xyz, t0.z, r0, c0 + mov oC0, r1 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 45, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 127, 0, + 0, 0, 0, 2, 255, 255, + 2, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 120, 0, 0, 0, 68, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 2, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 2, 0, + 104, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 67, + 111, 108, 111, 114, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 116, 101, 120, 48, 0, 171, + 171, 171, 4, 0, 12, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 112, 115, 95, 50, 95, 48, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 7, 176, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 0, 0, 0, 144, 0, 8, + 15, 160, 66, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 176, 0, 8, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 0, 0, 228, 144, + 0, 0, 228, 128, 0, 0, + 228, 161, 5, 0, 0, 3, + 1, 0, 8, 128, 0, 0, + 255, 128, 0, 0, 255, 144, + 4, 0, 0, 4, 1, 0, + 7, 128, 0, 0, 170, 176, + 0, 0, 228, 128, 0, 0, + 228, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 1, 0, + 228, 128, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/im2d_PS.h b/src/d3d/shaders/im2d_PS.h new file mode 100644 index 0000000..71f8b28 --- /dev/null +++ b/src/d3d/shaders/im2d_PS.h @@ -0,0 +1,72 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /Fh im2d_PS.h im2d_PS.hlsl +// +// +// Parameters: +// +// float4 fogColor; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// + + ps_2_0 + dcl t0.xyz + dcl v0 + add r0.xyz, v0, -c0 + mad r0.xyz, t0.z, r0, c0 + mov r0.w, v0.w + mov oC0, r0 + +// approximately 4 instruction slots used +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 34, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 83, 0, + 0, 0, 0, 2, 255, 255, + 1, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 76, 0, 0, 0, 48, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 2, 0, 60, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 67, 111, 108, + 111, 114, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 112, 115, + 95, 50, 95, 48, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 2, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 228, 144, + 0, 0, 228, 161, 4, 0, + 0, 4, 0, 0, 7, 128, + 0, 0, 170, 176, 0, 0, + 228, 128, 0, 0, 228, 160, + 1, 0, 0, 2, 0, 0, + 8, 128, 0, 0, 255, 144, + 1, 0, 0, 2, 0, 8, + 15, 128, 0, 0, 228, 128, + 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/im2d_PS.hlsl b/src/d3d/shaders/im2d_PS.hlsl new file mode 100644 index 0000000..eaf279d --- /dev/null +++ b/src/d3d/shaders/im2d_PS.hlsl @@ -0,0 +1,19 @@ +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; + float4 Color : COLOR0; +}; + +sampler2D tex0 : register(s0); + +float4 fogColor : register(c0); + +float4 main(VS_out input) : COLOR +{ + float4 color = input.Color; +#ifdef TEX + color *= tex2D(tex0, input.TexCoord0.xy); +#endif + color.rgb = lerp(fogColor.rgb, color.rgb, input.TexCoord0.z); + return color; +} diff --git a/src/d3d/shaders/im2d_VS.h b/src/d3d/shaders/im2d_VS.h new file mode 100644 index 0000000..bc36b1f --- /dev/null +++ b/src/d3d/shaders/im2d_VS.h @@ -0,0 +1,107 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /Fh im2d_VS.h im2d_VS.hlsl +// +// +// Parameters: +// +// float4 fogData; +// float4 xform; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogData c14 1 +// xform c41 1 +// + + vs_2_0 + def c0, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_color v2 + add r0.x, v0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c0.x + mad r0.xy, v0, c41, c41.zwzw + mov r0.z, v0.z + mul oPos.xyz, r0, v0.w + mov oPos.w, v0.w + mov oT0.xy, v1 + mov oD0, v2 + +// approximately 10 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 40, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 105, 0, + 0, 0, 0, 2, 254, 255, + 2, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 98, 0, 0, 0, 68, 0, + 0, 0, 2, 0, 14, 0, + 1, 0, 58, 0, 76, 0, + 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 2, 0, + 41, 0, 1, 0, 166, 0, + 76, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 68, + 97, 116, 97, 0, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 120, 102, 111, 114, + 109, 0, 118, 115, 95, 50, + 95, 48, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, + 32, 40, 82, 41, 32, 72, + 76, 83, 76, 32, 83, 104, + 97, 100, 101, 114, 32, 67, + 111, 109, 112, 105, 108, 101, + 114, 32, 57, 46, 50, 57, + 46, 57, 53, 50, 46, 51, + 49, 49, 49, 0, 171, 171, + 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 0, 128, 1, 0, 15, 144, + 31, 0, 0, 2, 10, 0, + 0, 128, 2, 0, 15, 144, + 2, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 255, 144, + 14, 0, 85, 161, 5, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 0, 128, 14, 0, + 170, 160, 11, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 255, 160, + 10, 0, 0, 3, 0, 0, + 4, 224, 0, 0, 0, 128, + 0, 0, 0, 160, 4, 0, + 0, 4, 0, 0, 3, 128, + 0, 0, 228, 144, 41, 0, + 228, 160, 41, 0, 238, 160, + 1, 0, 0, 2, 0, 0, + 4, 128, 0, 0, 170, 144, + 5, 0, 0, 3, 0, 0, + 7, 192, 0, 0, 228, 128, + 0, 0, 255, 144, 1, 0, + 0, 2, 0, 0, 8, 192, + 0, 0, 255, 144, 1, 0, + 0, 2, 0, 0, 3, 224, + 1, 0, 228, 144, 1, 0, + 0, 2, 0, 0, 15, 208, + 2, 0, 228, 144, 255, 255, + 0, 0 +}; diff --git a/src/d3d/shaders/im2d_VS.hlsl b/src/d3d/shaders/im2d_VS.hlsl new file mode 100644 index 0000000..20cf3ce --- /dev/null +++ b/src/d3d/shaders/im2d_VS.hlsl @@ -0,0 +1,30 @@ +#include "standardConstants.h" + +struct VS_in +{ + float4 Position : POSITION; + float2 TexCoord : TEXCOORD0; + float4 Color : COLOR0; +}; + +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; + float4 Color : COLOR0; +}; + +float4 xform : register(c41); + +VS_out main(in VS_in input) +{ + VS_out output; + + output.Position = input.Position; + output.Position.xy = output.Position.xy * xform.xy + xform.zw; + output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0); + output.Position.xyz *= output.Position.w; + output.Color = input.Color; + output.TexCoord0.xy = input.TexCoord; + + return output; +} diff --git a/src/d3d/shaders/im2d_tex_PS.h b/src/d3d/shaders/im2d_tex_PS.h new file mode 100644 index 0000000..a91888b --- /dev/null +++ b/src/d3d/shaders/im2d_tex_PS.h @@ -0,0 +1,89 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /DTEX /Fh im2d_tex_PS.h im2d_PS.hlsl +// +// +// Parameters: +// +// float4 fogColor; +// sampler2D tex0; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// tex0 s0 1 +// + + ps_2_0 + dcl t0.xyz + dcl v0 + dcl_2d s0 + texld r0, t0, s0 + mad r0.xyz, v0, r0, -c0 + mul r1.w, r0.w, v0.w + mad r1.xyz, t0.z, r0, c0 + mov oC0, r1 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 45, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 127, 0, + 0, 0, 0, 2, 255, 255, + 2, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 120, 0, 0, 0, 68, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 2, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 2, 0, + 104, 0, 0, 0, 0, 0, + 0, 0, 102, 111, 103, 67, + 111, 108, 111, 114, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 116, 101, 120, 48, 0, 171, + 171, 171, 4, 0, 12, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 112, 115, 95, 50, 95, 48, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 7, 176, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 0, 0, 0, 144, 0, 8, + 15, 160, 66, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 176, 0, 8, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 0, 0, 228, 144, + 0, 0, 228, 128, 0, 0, + 228, 161, 5, 0, 0, 3, + 1, 0, 8, 128, 0, 0, + 255, 128, 0, 0, 255, 144, + 4, 0, 0, 4, 1, 0, + 7, 128, 0, 0, 170, 176, + 0, 0, 228, 128, 0, 0, + 228, 160, 1, 0, 0, 2, + 0, 8, 15, 128, 1, 0, + 228, 128, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/lighting.h b/src/d3d/shaders/lighting.h new file mode 100644 index 0000000..4b08196 --- /dev/null +++ b/src/d3d/shaders/lighting.h @@ -0,0 +1,44 @@ +struct Light +{ + float4 color; // and radius + float4 position; // and -cos(angle) + float4 direction; // and falloff clamp +}; + +float3 DoDirLight(Light L, float3 N) +{ + float l = max(0.0, dot(N, -L.direction.xyz)); + return l*L.color.xyz; +} + +float3 DoDirLightSpec(Light L, float3 N, float3 V, float power) +{ + return pow(saturate(dot(N, normalize(V + -L.direction.xyz))), power)*L.color.xyz; +} + +float3 DoPointLight(Light L, float3 V, float3 N) +{ + // As on PS2 + float3 dir = V - L.position.xyz; + float dist = length(dir); + float atten = max(0.0, (1.0 - dist/L.color.w)); + float l = max(0.0, dot(N, -normalize(dir))); + return l*L.color.xyz*atten; +} + +float3 DoSpotLight(Light L, float3 V, float3 N) +{ + // As on PS2 + float3 dir = V - L.position.xyz; + float dist = length(dir); + float atten = max(0.0, (1.0 - dist/L.color.w)); + dir /= dist; + float l = max(0.0, dot(N, -dir)); + float pcos = dot(dir, L.direction.xyz); // cos to point + float ccos = -L.position.w; // cos of cone + float falloff = (pcos-ccos)/(1.0-ccos); + if(falloff < 0) // outside of cone + l = 0; + l *= max(falloff, L.direction.w); // falloff clamp + return l*L.color.xyz*atten; +} diff --git a/src/d3d/shaders/make_default.cmd b/src/d3d/shaders/make_default.cmd new file mode 100644 index 0000000..bc44429 --- /dev/null +++ b/src/d3d/shaders/make_default.cmd @@ -0,0 +1,11 @@ +@echo off +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh default_amb_VS.h default_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh default_amb_dir_VS.h default_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh default_all_VS.h default_VS.hlsl + +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh default_PS.h default_PS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh default_tex_PS.h default_PS.hlsl + +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh im2d_VS.h im2d_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh im2d_PS.h im2d_PS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh im2d_tex_PS.h im2d_PS.hlsl diff --git a/src/d3d/shaders/make_matfx.cmd b/src/d3d/shaders/make_matfx.cmd new file mode 100644 index 0000000..d0bc4fa --- /dev/null +++ b/src/d3d/shaders/make_matfx.cmd @@ -0,0 +1,7 @@ +@echo off +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh matfx_env_amb_VS.h matfx_env_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh matfx_env_amb_dir_VS.h matfx_env_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh matfx_env_all_VS.h matfx_env_VS.hlsl + +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /Fh matfx_env_PS.h matfx_env_PS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T ps_2_0 /DTEX /Fh matfx_env_tex_PS.h matfx_env_PS.hlsl diff --git a/src/d3d/shaders/make_skin.cmd b/src/d3d/shaders/make_skin.cmd new file mode 100644 index 0000000..b7822ca --- /dev/null +++ b/src/d3d/shaders/make_skin.cmd @@ -0,0 +1,4 @@ +@echo off +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /Fh skin_amb_VS.h skin_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /Fh skin_amb_dir_VS.h skin_VS.hlsl +"%DXSDK_DIR%\utilities\bin\x86\fxc.exe" /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh skin_all_VS.h skin_VS.hlsl diff --git a/src/d3d/shaders/matfx_env_PS.h b/src/d3d/shaders/matfx_env_PS.h new file mode 100644 index 0000000..e39a1f5 --- /dev/null +++ b/src/d3d/shaders/matfx_env_PS.h @@ -0,0 +1,124 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /Fh matfx_env_PS.h matfx_env_PS.hlsl +// +// +// Parameters: +// +// sampler2D envTex; +// float4 fogColor; +// float4 fxparams; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// fxparams c1 1 +// envTex s1 1 +// + + ps_2_0 + dcl t0.xyz + dcl t1.xy + dcl v0 + dcl v1.xyz + dcl_2d s1 + texld r0, t1, s1 + mul r1.xyz, v1, c1.x + mul r0.xyz, r0, r1 + mul r0.xyz, r0, t0.z + max r0.w, v0.w, c1.y + mul r0.xyz, r0.w, r0 + add r1.xyz, v0, -c0 + mad r1.xyz, t0.z, r1, c0 + mad r0.xyz, r1, v0.w, r0 + mov r0.w, v0.w + mov oC0, r0 + +// approximately 11 instruction slots used (1 texture, 10 arithmetic) +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 53, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 156, 0, + 0, 0, 0, 2, 255, 255, + 3, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 149, 0, 0, 0, 88, 0, + 0, 0, 3, 0, 1, 0, + 1, 0, 6, 0, 96, 0, + 0, 0, 0, 0, 0, 0, + 112, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 2, 0, + 124, 0, 0, 0, 0, 0, + 0, 0, 140, 0, 0, 0, + 2, 0, 1, 0, 1, 0, + 6, 0, 124, 0, 0, 0, + 0, 0, 0, 0, 101, 110, + 118, 84, 101, 120, 0, 171, + 4, 0, 12, 0, 1, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 111, + 103, 67, 111, 108, 111, 114, + 0, 171, 171, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 120, 112, 97, + 114, 97, 109, 115, 0, 112, + 115, 95, 50, 95, 48, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 50, 57, 46, 57, 53, + 50, 46, 51, 49, 49, 49, + 0, 171, 171, 171, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 7, 176, 31, 0, + 0, 2, 0, 0, 0, 128, + 1, 0, 3, 176, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 15, 144, 31, 0, + 0, 2, 0, 0, 0, 128, + 1, 0, 7, 144, 31, 0, + 0, 2, 0, 0, 0, 144, + 1, 8, 15, 160, 66, 0, + 0, 3, 0, 0, 15, 128, + 1, 0, 228, 176, 1, 8, + 228, 160, 5, 0, 0, 3, + 1, 0, 7, 128, 1, 0, + 228, 144, 1, 0, 0, 160, + 5, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 228, 128, + 1, 0, 228, 128, 5, 0, + 0, 3, 0, 0, 7, 128, + 0, 0, 228, 128, 0, 0, + 170, 176, 11, 0, 0, 3, + 0, 0, 8, 128, 0, 0, + 255, 144, 1, 0, 85, 160, + 5, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 255, 128, + 0, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 7, 128, + 0, 0, 228, 144, 0, 0, + 228, 161, 4, 0, 0, 4, + 1, 0, 7, 128, 0, 0, + 170, 176, 1, 0, 228, 128, + 0, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 7, 128, + 1, 0, 228, 128, 0, 0, + 255, 144, 0, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 8, 128, 0, 0, 255, 144, + 1, 0, 0, 2, 0, 8, + 15, 128, 0, 0, 228, 128, + 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/matfx_env_PS.hlsl b/src/d3d/shaders/matfx_env_PS.hlsl new file mode 100644 index 0000000..eb5187d --- /dev/null +++ b/src/d3d/shaders/matfx_env_PS.hlsl @@ -0,0 +1,42 @@ +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; + float2 TexCoord1 : TEXCOORD1; + float4 Color : COLOR0; + float4 EnvColor : COLOR1; +}; + +sampler2D diffTex : register(s0); +sampler2D envTex : register(s1); + +float4 fogColor : register(c0); + +float4 fxparams : register(c1); + +#define shininess (fxparams.x) +#define disableFBA (fxparams.y) + +float4 main(VS_out input) : COLOR +{ + float4 pass1 = input.Color; +#ifdef TEX + pass1 *= tex2D(diffTex, input.TexCoord0.xy); +#endif + + float4 pass2 = input.EnvColor*shininess*tex2D(envTex, input.TexCoord1.xy); + + pass1.rgb = lerp(fogColor.rgb, pass1.rgb, input.TexCoord0.z); + pass2.rgb = lerp(float3(0.0, 0.0, 0.0), pass2.rgb, input.TexCoord0.z); + + // We simulate drawing this in two passes. + // First pass with standard blending, second with addition + // We premultiply alpha so render state should be one. + // For FB alpha rendering assume that diffuse alpha (pass1.a) was + // written to framebuffer, so just multiply pass2 by it as well then. + float fba = max(pass1.a, disableFBA); + float4 color; + color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba; + color.a = pass1.a; + + return color; +} diff --git a/src/d3d/shaders/matfx_env_VS.hlsl b/src/d3d/shaders/matfx_env_VS.hlsl new file mode 100644 index 0000000..31b674c --- /dev/null +++ b/src/d3d/shaders/matfx_env_VS.hlsl @@ -0,0 +1,59 @@ +#include "standardConstants.h" + +float4x4 texMat : register(c41); +float4 colorClamp : register(c45); +float4 envColor : register(c46); + +struct VS_in +{ + float4 Position : POSITION; + float3 Normal : NORMAL; + float2 TexCoord : TEXCOORD0; + float4 Prelight : COLOR0; +}; + +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; // also fog + float2 TexCoord1 : TEXCOORD1; + float4 Color : COLOR0; + float4 EnvColor : COLOR1; +}; + + +VS_out main(in VS_in input) +{ + VS_out output; + + output.Position = mul(combinedMat, input.Position); + float3 V = mul(worldMat, input.Position).xyz; + float3 N = mul(normalMat, input.Normal); + + output.TexCoord0.xy = input.TexCoord; + output.TexCoord1 = mul(texMat, float4(N, 1.0)).xy; + + output.Color = input.Prelight; + output.Color.rgb += ambientLight.rgb * surfAmbient; + + int i; +#ifdef DIRECTIONALS + for(i = 0; i < numDirLights; i++) + output.Color.xyz += DoDirLight(lights[i+firstDirLight], N)*surfDiffuse; +#endif +#ifdef POINTLIGHTS + for(i = 0; i < numPointLights; i++) + output.Color.xyz += DoPointLight(lights[i+firstPointLight], V, N)*surfDiffuse; +#endif +#ifdef SPOTLIGHTS + for(i = 0; i < numSpotLights; i++) + output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], V, N)*surfDiffuse; +#endif + // PS2 clamps before material color + output.Color = clamp(output.Color, 0.0, 1.0); + output.EnvColor = max(output.Color, colorClamp) * envColor; + output.Color *= matCol; + + output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0); + + return output; +} diff --git a/src/d3d/shaders/matfx_env_all_VS.h b/src/d3d/shaders/matfx_env_all_VS.h new file mode 100644 index 0000000..65e1c15 --- /dev/null +++ b/src/d3d/shaders/matfx_env_all_VS.h @@ -0,0 +1,535 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh +// matfx_env_all_VS.h matfx_env_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4 colorClamp; +// float4x4 combinedMat; +// float4 envColor; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// int numPointLights; +// int numSpotLights; +// float4 surfProps; +// float4x4 texMat; +// float4x4 worldMat; +// +// +// Registers: +// +// Name Reg Size +// -------------- ----- ---- +// numDirLights i0 1 +// numPointLights i1 1 +// numSpotLights i2 1 +// combinedMat c0 4 +// worldMat c4 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// texMat c41 4 +// colorClamp c45 1 +// envColor c46 1 +// + + vs_2_0 + def c11, 0, 3, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + mov oPos, r0 + mul r0.xyz, v0.y, c5 + mad r0.xyz, c4, v0.x, r0 + mad r0.xyz, c6, v0.z, r0 + mad r0.xyz, c7, v0.w, r0 + mul r1.xyz, v1.y, c9 + mad r1.xyz, c8, v1.x, r1 + mad r1.xyz, c10, v1.z, r1 + mov r2.x, c13.x + mad r2.xyz, c15, r2.x, v3 + mov r3.xyz, r2 + mov r1.w, c11.x + rep i0 + add r2.w, r1.w, c16.x + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + dp3 r2.w, r1, -c19[a0.x] + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, c17[a0.x] + mad r3.xyz, r4, c13.z, r3 + add r1.w, r1.w, c11.z + endrep + mov r2.xyz, r3 + mov r1.w, c11.x + rep i1 + add r2.w, r1.w, c16.y + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + add r4.xyz, r0, -c18[a0.x] + dp3 r2.w, r4, r4 + rsq r2.w, r2.w + mul r4.xyz, r2.w, r4 + dp3 r3.w, r1, -r4 + max r3.w, r3.w, c11.x + mul r4.xyz, r3.w, c17[a0.x] + rcp r2.w, r2.w + rcp r3.w, c17[a0.x].w + mad r2.w, r2.w, -r3.w, c11.z + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, r4 + mad r2.xyz, r4, c13.z, r2 + add r1.w, r1.w, c11.z + endrep + mov r3.xyz, r2 + mov r1.w, c11.x + rep i2 + add r2.w, r1.w, c16.z + mul r2.w, r2.w, c11.y + mova a0.x, r2.w + add r4.xyz, r0, -c18[a0.x] + dp3 r2.w, r4, r4 + rsq r2.w, r2.w + mul r4.xyz, r2.w, r4 + dp3 r4.w, r1, -r4 + dp3 r4.x, r4, c19[a0.x] + max r4.y, r4.w, c11.x + mov r4.z, c11.z + add r4.xz, r4, c18[a0.x].w + rcp r4.z, r4.z + mul r4.x, r4.z, r4.x + slt r4.z, r4.x, c11.x + mad r4.y, r4.z, -r4.y, r4.y + max r4.x, r4.x, c19[a0.x].w + mul r4.x, r4.x, r4.y + mul r4.xyz, r4.x, c17[a0.x] + rcp r2.w, r2.w + rcp r4.w, c17[a0.x].w + mad r2.w, r2.w, -r4.w, c11.z + max r2.w, r2.w, c11.x + mul r4.xyz, r2.w, r4 + mad r3.xyz, r4, c13.z, r3 + add r1.w, r1.w, c11.z + endrep + mov r3.w, v3.w + max r2, r3, c11.x + min r2, r2, c11.z + mul oD0, r2, c12 + mul r0.xy, r1.y, c42 + mad r0.xy, c41, r1.x, r0 + mad r0.xy, c43, r1.z, r0 + add oT1.xy, r0, c44 + max r1, r2, c45 + mul oD1, r1, c46 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c11.z + mov oT0.xy, v2 + +// approximately 101 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 180, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 154, 2, + 0, 0, 0, 2, 254, 255, + 15, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 147, 2, 0, 0, 72, 1, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 88, 1, + 0, 0, 0, 0, 0, 0, + 104, 1, 0, 0, 2, 0, + 45, 0, 1, 0, 182, 0, + 88, 1, 0, 0, 0, 0, + 0, 0, 115, 1, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 128, 1, 0, 0, + 0, 0, 0, 0, 144, 1, + 0, 0, 2, 0, 46, 0, + 1, 0, 186, 0, 88, 1, + 0, 0, 0, 0, 0, 0, + 153, 1, 0, 0, 2, 0, + 16, 0, 1, 0, 66, 0, + 164, 1, 0, 0, 0, 0, + 0, 0, 180, 1, 0, 0, + 2, 0, 14, 0, 1, 0, + 58, 0, 88, 1, 0, 0, + 0, 0, 0, 0, 188, 1, + 0, 0, 2, 0, 17, 0, + 24, 0, 70, 0, 8, 2, + 0, 0, 0, 0, 0, 0, + 24, 2, 0, 0, 2, 0, + 12, 0, 1, 0, 50, 0, + 88, 1, 0, 0, 0, 0, + 0, 0, 31, 2, 0, 0, + 2, 0, 8, 0, 3, 0, + 34, 0, 44, 2, 0, 0, + 0, 0, 0, 0, 60, 2, + 0, 0, 1, 0, 0, 0, + 1, 0, 2, 0, 76, 2, + 0, 0, 0, 0, 0, 0, + 92, 2, 0, 0, 1, 0, + 1, 0, 1, 0, 6, 0, + 76, 2, 0, 0, 0, 0, + 0, 0, 107, 2, 0, 0, + 1, 0, 2, 0, 1, 0, + 10, 0, 76, 2, 0, 0, + 0, 0, 0, 0, 121, 2, + 0, 0, 2, 0, 13, 0, + 1, 0, 54, 0, 88, 1, + 0, 0, 0, 0, 0, 0, + 131, 2, 0, 0, 2, 0, + 41, 0, 4, 0, 166, 0, + 128, 1, 0, 0, 0, 0, + 0, 0, 138, 2, 0, 0, + 2, 0, 4, 0, 4, 0, + 18, 0, 128, 1, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 99, 111, 108, 111, 114, 67, + 108, 97, 109, 112, 0, 99, + 111, 109, 98, 105, 110, 101, + 100, 77, 97, 116, 0, 171, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 101, 110, + 118, 67, 111, 108, 111, 114, + 0, 102, 105, 114, 115, 116, + 76, 105, 103, 104, 116, 0, + 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 111, + 103, 68, 97, 116, 97, 0, + 108, 105, 103, 104, 116, 115, + 0, 99, 111, 108, 111, 114, + 0, 171, 171, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 112, 111, 115, 105, + 116, 105, 111, 110, 0, 100, + 105, 114, 101, 99, 116, 105, + 111, 110, 0, 171, 195, 1, + 0, 0, 204, 1, 0, 0, + 220, 1, 0, 0, 204, 1, + 0, 0, 229, 1, 0, 0, + 204, 1, 0, 0, 5, 0, + 0, 0, 1, 0, 12, 0, + 8, 0, 3, 0, 240, 1, + 0, 0, 109, 97, 116, 67, + 111, 108, 0, 110, 111, 114, + 109, 97, 108, 77, 97, 116, + 0, 171, 171, 171, 3, 0, + 3, 0, 3, 0, 3, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 110, 117, 109, 68, + 105, 114, 76, 105, 103, 104, + 116, 115, 0, 171, 171, 171, + 0, 0, 2, 0, 1, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 110, 117, + 109, 80, 111, 105, 110, 116, + 76, 105, 103, 104, 116, 115, + 0, 110, 117, 109, 83, 112, + 111, 116, 76, 105, 103, 104, + 116, 115, 0, 115, 117, 114, + 102, 80, 114, 111, 112, 115, + 0, 116, 101, 120, 77, 97, + 116, 0, 119, 111, 114, 108, + 100, 77, 97, 116, 0, 118, + 115, 95, 50, 95, 48, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 57, + 46, 50, 57, 46, 57, 53, + 50, 46, 51, 49, 49, 49, + 0, 171, 81, 0, 0, 5, + 11, 0, 15, 160, 0, 0, + 0, 0, 0, 0, 64, 64, + 0, 0, 128, 63, 0, 0, + 0, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 3, 0, 0, 128, 1, 0, + 15, 144, 31, 0, 0, 2, + 5, 0, 0, 128, 2, 0, + 15, 144, 31, 0, 0, 2, + 10, 0, 0, 128, 3, 0, + 15, 144, 5, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 85, 144, 1, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 15, 128, 0, 0, 228, 160, + 0, 0, 0, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 15, 128, 2, 0, + 228, 160, 0, 0, 170, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 3, 0, 228, 160, 0, 0, + 255, 144, 0, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 15, 192, 0, 0, 228, 128, + 5, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 85, 144, + 5, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 7, 128, + 4, 0, 228, 160, 0, 0, + 0, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 7, 128, 6, 0, 228, 160, + 0, 0, 170, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 7, 128, 7, 0, + 228, 160, 0, 0, 255, 144, + 0, 0, 228, 128, 5, 0, + 0, 3, 1, 0, 7, 128, + 1, 0, 85, 144, 9, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 7, 128, 8, 0, + 228, 160, 1, 0, 0, 144, + 1, 0, 228, 128, 4, 0, + 0, 4, 1, 0, 7, 128, + 10, 0, 228, 160, 1, 0, + 170, 144, 1, 0, 228, 128, + 1, 0, 0, 2, 2, 0, + 1, 128, 13, 0, 0, 160, + 4, 0, 0, 4, 2, 0, + 7, 128, 15, 0, 228, 160, + 2, 0, 0, 128, 3, 0, + 228, 144, 1, 0, 0, 2, + 3, 0, 7, 128, 2, 0, + 228, 128, 1, 0, 0, 2, + 1, 0, 8, 128, 11, 0, + 0, 160, 38, 0, 0, 1, + 0, 0, 228, 240, 2, 0, + 0, 3, 2, 0, 8, 128, + 1, 0, 255, 128, 16, 0, + 0, 160, 5, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 85, 160, + 46, 0, 0, 2, 0, 0, + 1, 176, 2, 0, 255, 128, + 8, 0, 0, 4, 2, 0, + 8, 128, 1, 0, 228, 128, + 19, 32, 228, 161, 0, 0, + 0, 176, 11, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 0, 160, + 5, 0, 0, 4, 4, 0, + 7, 128, 2, 0, 255, 128, + 17, 32, 228, 160, 0, 0, + 0, 176, 4, 0, 0, 4, + 3, 0, 7, 128, 4, 0, + 228, 128, 13, 0, 170, 160, + 3, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 11, 0, + 170, 160, 39, 0, 0, 0, + 1, 0, 0, 2, 2, 0, + 7, 128, 3, 0, 228, 128, + 1, 0, 0, 2, 1, 0, + 8, 128, 11, 0, 0, 160, + 38, 0, 0, 1, 1, 0, + 228, 240, 2, 0, 0, 3, + 2, 0, 8, 128, 1, 0, + 255, 128, 16, 0, 85, 160, + 5, 0, 0, 3, 2, 0, + 8, 128, 2, 0, 255, 128, + 11, 0, 85, 160, 46, 0, + 0, 2, 0, 0, 1, 176, + 2, 0, 255, 128, 2, 0, + 0, 4, 4, 0, 7, 128, + 0, 0, 228, 128, 18, 32, + 228, 161, 0, 0, 0, 176, + 8, 0, 0, 3, 2, 0, + 8, 128, 4, 0, 228, 128, + 4, 0, 228, 128, 7, 0, + 0, 2, 2, 0, 8, 128, + 2, 0, 255, 128, 5, 0, + 0, 3, 4, 0, 7, 128, + 2, 0, 255, 128, 4, 0, + 228, 128, 8, 0, 0, 3, + 3, 0, 8, 128, 1, 0, + 228, 128, 4, 0, 228, 129, + 11, 0, 0, 3, 3, 0, + 8, 128, 3, 0, 255, 128, + 11, 0, 0, 160, 5, 0, + 0, 4, 4, 0, 7, 128, + 3, 0, 255, 128, 17, 32, + 228, 160, 0, 0, 0, 176, + 6, 0, 0, 2, 2, 0, + 8, 128, 2, 0, 255, 128, + 6, 0, 0, 3, 3, 0, + 8, 128, 17, 32, 255, 160, + 0, 0, 0, 176, 4, 0, + 0, 4, 2, 0, 8, 128, + 2, 0, 255, 128, 3, 0, + 255, 129, 11, 0, 170, 160, + 11, 0, 0, 3, 2, 0, + 8, 128, 2, 0, 255, 128, + 11, 0, 0, 160, 5, 0, + 0, 3, 4, 0, 7, 128, + 2, 0, 255, 128, 4, 0, + 228, 128, 4, 0, 0, 4, + 2, 0, 7, 128, 4, 0, + 228, 128, 13, 0, 170, 160, + 2, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 11, 0, + 170, 160, 39, 0, 0, 0, + 1, 0, 0, 2, 3, 0, + 7, 128, 2, 0, 228, 128, + 1, 0, 0, 2, 1, 0, + 8, 128, 11, 0, 0, 160, + 38, 0, 0, 1, 2, 0, + 228, 240, 2, 0, 0, 3, + 2, 0, 8, 128, 1, 0, + 255, 128, 16, 0, 170, 160, + 5, 0, 0, 3, 2, 0, + 8, 128, 2, 0, 255, 128, + 11, 0, 85, 160, 46, 0, + 0, 2, 0, 0, 1, 176, + 2, 0, 255, 128, 2, 0, + 0, 4, 4, 0, 7, 128, + 0, 0, 228, 128, 18, 32, + 228, 161, 0, 0, 0, 176, + 8, 0, 0, 3, 2, 0, + 8, 128, 4, 0, 228, 128, + 4, 0, 228, 128, 7, 0, + 0, 2, 2, 0, 8, 128, + 2, 0, 255, 128, 5, 0, + 0, 3, 4, 0, 7, 128, + 2, 0, 255, 128, 4, 0, + 228, 128, 8, 0, 0, 3, + 4, 0, 8, 128, 1, 0, + 228, 128, 4, 0, 228, 129, + 8, 0, 0, 4, 4, 0, + 1, 128, 4, 0, 228, 128, + 19, 32, 228, 160, 0, 0, + 0, 176, 11, 0, 0, 3, + 4, 0, 2, 128, 4, 0, + 255, 128, 11, 0, 0, 160, + 1, 0, 0, 2, 4, 0, + 4, 128, 11, 0, 170, 160, + 2, 0, 0, 4, 4, 0, + 5, 128, 4, 0, 228, 128, + 18, 32, 255, 160, 0, 0, + 0, 176, 6, 0, 0, 2, + 4, 0, 4, 128, 4, 0, + 170, 128, 5, 0, 0, 3, + 4, 0, 1, 128, 4, 0, + 170, 128, 4, 0, 0, 128, + 12, 0, 0, 3, 4, 0, + 4, 128, 4, 0, 0, 128, + 11, 0, 0, 160, 4, 0, + 0, 4, 4, 0, 2, 128, + 4, 0, 170, 128, 4, 0, + 85, 129, 4, 0, 85, 128, + 11, 0, 0, 4, 4, 0, + 1, 128, 4, 0, 0, 128, + 19, 32, 255, 160, 0, 0, + 0, 176, 5, 0, 0, 3, + 4, 0, 1, 128, 4, 0, + 0, 128, 4, 0, 85, 128, + 5, 0, 0, 4, 4, 0, + 7, 128, 4, 0, 0, 128, + 17, 32, 228, 160, 0, 0, + 0, 176, 6, 0, 0, 2, + 2, 0, 8, 128, 2, 0, + 255, 128, 6, 0, 0, 3, + 4, 0, 8, 128, 17, 32, + 255, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 2, 0, + 8, 128, 2, 0, 255, 128, + 4, 0, 255, 129, 11, 0, + 170, 160, 11, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 11, 0, 0, 160, + 5, 0, 0, 3, 4, 0, + 7, 128, 2, 0, 255, 128, + 4, 0, 228, 128, 4, 0, + 0, 4, 3, 0, 7, 128, + 4, 0, 228, 128, 13, 0, + 170, 160, 3, 0, 228, 128, + 2, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 11, 0, 170, 160, 39, 0, + 0, 0, 1, 0, 0, 2, + 3, 0, 8, 128, 3, 0, + 255, 144, 11, 0, 0, 3, + 2, 0, 15, 128, 3, 0, + 228, 128, 11, 0, 0, 160, + 10, 0, 0, 3, 2, 0, + 15, 128, 2, 0, 228, 128, + 11, 0, 170, 160, 5, 0, + 0, 3, 0, 0, 15, 208, + 2, 0, 228, 128, 12, 0, + 228, 160, 5, 0, 0, 3, + 0, 0, 3, 128, 1, 0, + 85, 128, 42, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 41, 0, 228, 160, + 1, 0, 0, 128, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 3, 128, 43, 0, + 228, 160, 1, 0, 170, 128, + 0, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 3, 224, + 0, 0, 228, 128, 44, 0, + 228, 160, 11, 0, 0, 3, + 1, 0, 15, 128, 2, 0, + 228, 128, 45, 0, 228, 160, + 5, 0, 0, 3, 1, 0, + 15, 208, 1, 0, 228, 128, + 46, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 5, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 11, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/matfx_env_amb_VS.h b/src/d3d/shaders/matfx_env_amb_VS.h new file mode 100644 index 0000000..0367d5e --- /dev/null +++ b/src/d3d/shaders/matfx_env_amb_VS.h @@ -0,0 +1,225 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /Fh matfx_env_amb_VS.h matfx_env_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4 colorClamp; +// float4x4 combinedMat; +// float4 envColor; +// float4 fogData; +// float4 matCol; +// float3x3 normalMat; +// float4 surfProps; +// float4x4 texMat; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// combinedMat c0 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// texMat c41 4 +// colorClamp c45 1 +// envColor c46 1 +// + + vs_2_0 + def c4, 0, 1, 0, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + mul r0.xyz, v1.y, c9 + mad r0.xyz, c8, v1.x, r0 + mad r0.xyz, c10, v1.z, r0 + mul r0.yw, r0.y, c42.xxzy + mad r0.xy, c41, r0.x, r0.ywzw + mad r0.xy, c43, r0.z, r0 + add oT1.xy, r0, c44 + mov r0.xyz, c15 + mad r0.xyz, r0, c13.x, v3 + mov r0.w, v3.w + max r0, r0, c4.x + min r0, r0, c4.y + max r1, r0, c45 + mul oD0, r0, c12 + mul oD1, r1, c46 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + add r1.x, r0.w, -c14.y + mov oPos, r0 + mul r0.x, r1.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.y + mov oT0.xy, v2 + +// approximately 25 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 103, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 100, 1, + 0, 0, 0, 2, 254, 255, + 9, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 93, 1, 0, 0, 208, 0, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 224, 0, + 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 2, 0, + 45, 0, 1, 0, 182, 0, + 224, 0, 0, 0, 0, 0, + 0, 0, 251, 0, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 8, 1, 0, 0, + 0, 0, 0, 0, 24, 1, + 0, 0, 2, 0, 46, 0, + 1, 0, 186, 0, 224, 0, + 0, 0, 0, 0, 0, 0, + 33, 1, 0, 0, 2, 0, + 14, 0, 1, 0, 58, 0, + 224, 0, 0, 0, 0, 0, + 0, 0, 41, 1, 0, 0, + 2, 0, 12, 0, 1, 0, + 50, 0, 224, 0, 0, 0, + 0, 0, 0, 0, 48, 1, + 0, 0, 2, 0, 8, 0, + 3, 0, 34, 0, 60, 1, + 0, 0, 0, 0, 0, 0, + 76, 1, 0, 0, 2, 0, + 13, 0, 1, 0, 54, 0, + 224, 0, 0, 0, 0, 0, + 0, 0, 86, 1, 0, 0, + 2, 0, 41, 0, 4, 0, + 166, 0, 8, 1, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 99, 111, 108, 111, 114, 67, + 108, 97, 109, 112, 0, 99, + 111, 109, 98, 105, 110, 101, + 100, 77, 97, 116, 0, 171, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 101, 110, + 118, 67, 111, 108, 111, 114, + 0, 102, 111, 103, 68, 97, + 116, 97, 0, 109, 97, 116, + 67, 111, 108, 0, 110, 111, + 114, 109, 97, 108, 77, 97, + 116, 0, 171, 171, 3, 0, + 3, 0, 3, 0, 3, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 115, 117, 114, 102, + 80, 114, 111, 112, 115, 0, + 116, 101, 120, 77, 97, 116, + 0, 118, 115, 95, 50, 95, + 48, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 81, 0, 0, 5, 4, 0, + 15, 160, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 3, 0, + 0, 128, 1, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 0, 128, 2, 0, 15, 144, + 31, 0, 0, 2, 10, 0, + 0, 128, 3, 0, 15, 144, + 5, 0, 0, 3, 0, 0, + 7, 128, 1, 0, 85, 144, + 9, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 7, 128, + 8, 0, 228, 160, 1, 0, + 0, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 7, 128, 10, 0, 228, 160, + 1, 0, 170, 144, 0, 0, + 228, 128, 5, 0, 0, 3, + 0, 0, 10, 128, 0, 0, + 85, 128, 42, 0, 96, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 41, 0, 228, 160, + 0, 0, 0, 128, 0, 0, + 237, 128, 4, 0, 0, 4, + 0, 0, 3, 128, 43, 0, + 228, 160, 0, 0, 170, 128, + 0, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 3, 224, + 0, 0, 228, 128, 44, 0, + 228, 160, 1, 0, 0, 2, + 0, 0, 7, 128, 15, 0, + 228, 160, 4, 0, 0, 4, + 0, 0, 7, 128, 0, 0, + 228, 128, 13, 0, 0, 160, + 3, 0, 228, 144, 1, 0, + 0, 2, 0, 0, 8, 128, + 3, 0, 255, 144, 11, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 4, 0, + 0, 160, 10, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 4, 0, 85, 160, + 11, 0, 0, 3, 1, 0, + 15, 128, 0, 0, 228, 128, + 45, 0, 228, 160, 5, 0, + 0, 3, 0, 0, 15, 208, + 0, 0, 228, 128, 12, 0, + 228, 160, 5, 0, 0, 3, + 1, 0, 15, 208, 1, 0, + 228, 128, 46, 0, 228, 160, + 5, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 85, 144, + 1, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 15, 128, + 0, 0, 228, 160, 0, 0, + 0, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 15, 128, 2, 0, 228, 160, + 0, 0, 170, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 15, 128, 3, 0, + 228, 160, 0, 0, 255, 144, + 0, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 1, 0, 0, 2, + 0, 0, 15, 192, 0, 0, + 228, 128, 5, 0, 0, 3, + 0, 0, 1, 128, 1, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 4, 0, + 85, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/matfx_env_amb_dir_VS.h b/src/d3d/shaders/matfx_env_amb_dir_VS.h new file mode 100644 index 0000000..b93e572 --- /dev/null +++ b/src/d3d/shaders/matfx_env_amb_dir_VS.h @@ -0,0 +1,316 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /Fh matfx_env_amb_dir_VS.h +// matfx_env_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4 colorClamp; +// float4x4 combinedMat; +// float4 envColor; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// float4 surfProps; +// float4x4 texMat; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// numDirLights i0 1 +// combinedMat c0 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// texMat c41 4 +// colorClamp c45 1 +// envColor c46 1 +// + + vs_2_0 + def c4, 0, 3, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + mul r0, v0.y, c1 + mad r0, c0, v0.x, r0 + mad r0, c2, v0.z, r0 + mad r0, c3, v0.w, r0 + mov oPos, r0 + mul r0.xyz, v1.y, c9 + mad r0.xyz, c8, v1.x, r0 + mad r0.xyz, c10, v1.z, r0 + mov r1.x, c13.x + mad r1.xyz, c15, r1.x, v3 + mov r2.xyz, r1 + mov r1.w, c4.x + rep i0 + add r3.x, r1.w, c16.x + mul r3.x, r3.x, c4.y + mova a0.x, r3.x + dp3 r3.x, r0, -c19[a0.x] + max r3.x, r3.x, c4.x + mul r3.xyz, r3.x, c17[a0.x] + mad r2.xyz, r3, c13.z, r2 + add r1.w, r1.w, c4.z + endrep + mov r2.w, v3.w + max r1, r2, c4.x + min r1, r1, c4.z + mul oD0, r1, c12 + mul r2.xy, r0.y, c42 + mad r0.xy, c41, r0.x, r2 + mad r0.xy, c43, r0.z, r0 + add oT1.xy, r0, c44 + max r1, r1, c45 + mul oD1, r1, c46 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.z + mov oT0.xy, v2 + +// approximately 40 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 156, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 56, 2, + 0, 0, 0, 2, 254, 255, + 12, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 49, 2, 0, 0, 12, 1, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 44, 1, 0, 0, 2, 0, + 45, 0, 1, 0, 182, 0, + 28, 1, 0, 0, 0, 0, + 0, 0, 55, 1, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 68, 1, 0, 0, + 0, 0, 0, 0, 84, 1, + 0, 0, 2, 0, 46, 0, + 1, 0, 186, 0, 28, 1, + 0, 0, 0, 0, 0, 0, + 93, 1, 0, 0, 2, 0, + 16, 0, 1, 0, 66, 0, + 104, 1, 0, 0, 0, 0, + 0, 0, 120, 1, 0, 0, + 2, 0, 14, 0, 1, 0, + 58, 0, 28, 1, 0, 0, + 0, 0, 0, 0, 128, 1, + 0, 0, 2, 0, 17, 0, + 24, 0, 70, 0, 204, 1, + 0, 0, 0, 0, 0, 0, + 220, 1, 0, 0, 2, 0, + 12, 0, 1, 0, 50, 0, + 28, 1, 0, 0, 0, 0, + 0, 0, 227, 1, 0, 0, + 2, 0, 8, 0, 3, 0, + 34, 0, 240, 1, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 1, 0, 0, 0, + 1, 0, 2, 0, 16, 2, + 0, 0, 0, 0, 0, 0, + 32, 2, 0, 0, 2, 0, + 13, 0, 1, 0, 54, 0, + 28, 1, 0, 0, 0, 0, + 0, 0, 42, 2, 0, 0, + 2, 0, 41, 0, 4, 0, + 166, 0, 68, 1, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 99, 111, 108, 111, 114, 67, + 108, 97, 109, 112, 0, 99, + 111, 109, 98, 105, 110, 101, + 100, 77, 97, 116, 0, 171, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 101, 110, + 118, 67, 111, 108, 111, 114, + 0, 102, 105, 114, 115, 116, + 76, 105, 103, 104, 116, 0, + 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 111, + 103, 68, 97, 116, 97, 0, + 108, 105, 103, 104, 116, 115, + 0, 99, 111, 108, 111, 114, + 0, 171, 171, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 112, 111, 115, 105, + 116, 105, 111, 110, 0, 100, + 105, 114, 101, 99, 116, 105, + 111, 110, 0, 171, 135, 1, + 0, 0, 144, 1, 0, 0, + 160, 1, 0, 0, 144, 1, + 0, 0, 169, 1, 0, 0, + 144, 1, 0, 0, 5, 0, + 0, 0, 1, 0, 12, 0, + 8, 0, 3, 0, 180, 1, + 0, 0, 109, 97, 116, 67, + 111, 108, 0, 110, 111, 114, + 109, 97, 108, 77, 97, 116, + 0, 171, 171, 171, 3, 0, + 3, 0, 3, 0, 3, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 110, 117, 109, 68, + 105, 114, 76, 105, 103, 104, + 116, 115, 0, 171, 171, 171, + 0, 0, 2, 0, 1, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 115, 117, + 114, 102, 80, 114, 111, 112, + 115, 0, 116, 101, 120, 77, + 97, 116, 0, 118, 115, 95, + 50, 95, 48, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 57, 46, 50, + 57, 46, 57, 53, 50, 46, + 51, 49, 49, 49, 0, 171, + 171, 171, 81, 0, 0, 5, + 4, 0, 15, 160, 0, 0, + 0, 0, 0, 0, 64, 64, + 0, 0, 128, 63, 0, 0, + 0, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 3, 0, 0, 128, 1, 0, + 15, 144, 31, 0, 0, 2, + 5, 0, 0, 128, 2, 0, + 15, 144, 31, 0, 0, 2, + 10, 0, 0, 128, 3, 0, + 15, 144, 5, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 85, 144, 1, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 15, 128, 0, 0, 228, 160, + 0, 0, 0, 144, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 15, 128, 2, 0, + 228, 160, 0, 0, 170, 144, + 0, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 3, 0, 228, 160, 0, 0, + 255, 144, 0, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 15, 192, 0, 0, 228, 128, + 5, 0, 0, 3, 0, 0, + 7, 128, 1, 0, 85, 144, + 9, 0, 228, 160, 4, 0, + 0, 4, 0, 0, 7, 128, + 8, 0, 228, 160, 1, 0, + 0, 144, 0, 0, 228, 128, + 4, 0, 0, 4, 0, 0, + 7, 128, 10, 0, 228, 160, + 1, 0, 170, 144, 0, 0, + 228, 128, 1, 0, 0, 2, + 1, 0, 1, 128, 13, 0, + 0, 160, 4, 0, 0, 4, + 1, 0, 7, 128, 15, 0, + 228, 160, 1, 0, 0, 128, + 3, 0, 228, 144, 1, 0, + 0, 2, 2, 0, 7, 128, + 1, 0, 228, 128, 1, 0, + 0, 2, 1, 0, 8, 128, + 4, 0, 0, 160, 38, 0, + 0, 1, 0, 0, 228, 240, + 2, 0, 0, 3, 3, 0, + 1, 128, 1, 0, 255, 128, + 16, 0, 0, 160, 5, 0, + 0, 3, 3, 0, 1, 128, + 3, 0, 0, 128, 4, 0, + 85, 160, 46, 0, 0, 2, + 0, 0, 1, 176, 3, 0, + 0, 128, 8, 0, 0, 4, + 3, 0, 1, 128, 0, 0, + 228, 128, 19, 32, 228, 161, + 0, 0, 0, 176, 11, 0, + 0, 3, 3, 0, 1, 128, + 3, 0, 0, 128, 4, 0, + 0, 160, 5, 0, 0, 4, + 3, 0, 7, 128, 3, 0, + 0, 128, 17, 32, 228, 160, + 0, 0, 0, 176, 4, 0, + 0, 4, 2, 0, 7, 128, + 3, 0, 228, 128, 13, 0, + 170, 160, 2, 0, 228, 128, + 2, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 4, 0, 170, 160, 39, 0, + 0, 0, 1, 0, 0, 2, + 2, 0, 8, 128, 3, 0, + 255, 144, 11, 0, 0, 3, + 1, 0, 15, 128, 2, 0, + 228, 128, 4, 0, 0, 160, + 10, 0, 0, 3, 1, 0, + 15, 128, 1, 0, 228, 128, + 4, 0, 170, 160, 5, 0, + 0, 3, 0, 0, 15, 208, + 1, 0, 228, 128, 12, 0, + 228, 160, 5, 0, 0, 3, + 2, 0, 3, 128, 0, 0, + 85, 128, 42, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 41, 0, 228, 160, + 0, 0, 0, 128, 2, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 3, 128, 43, 0, + 228, 160, 0, 0, 170, 128, + 0, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 3, 224, + 0, 0, 228, 128, 44, 0, + 228, 160, 11, 0, 0, 3, + 1, 0, 15, 128, 1, 0, + 228, 128, 45, 0, 228, 160, + 5, 0, 0, 3, 1, 0, + 15, 208, 1, 0, 228, 128, + 46, 0, 228, 160, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 5, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 4, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/matfx_env_tex_PS.h b/src/d3d/shaders/matfx_env_tex_PS.h new file mode 100644 index 0000000..e2e7429 --- /dev/null +++ b/src/d3d/shaders/matfx_env_tex_PS.h @@ -0,0 +1,141 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T ps_2_0 /DTEX /Fh matfx_env_tex_PS.h matfx_env_PS.hlsl +// +// +// Parameters: +// +// sampler2D diffTex; +// sampler2D envTex; +// float4 fogColor; +// float4 fxparams; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// fogColor c0 1 +// fxparams c1 1 +// diffTex s0 1 +// envTex s1 1 +// + + ps_2_0 + dcl t0.xyz + dcl t1.xy + dcl v0 + dcl v1.xyz + dcl_2d s0 + dcl_2d s1 + texld r0, t1, s1 + texld r1, t0, s0 + mul r2.xyz, v1, c1.x + mul r0.xyz, r0, r2 + mul r0.xyz, r0, t0.z + mul r2.w, r1.w, v0.w + mad r1.xyz, v0, r1, -c0 + mad r1.xyz, t0.z, r1, c0 + max r0.w, r2.w, c1.y + mul r0.xyz, r0.w, r0 + mad r2.xyz, r1, r2.w, r0 + mov oC0, r2 + +// approximately 12 instruction slots used (2 texture, 10 arithmetic) +#endif + +const BYTE g_ps20_main[] = +{ + 0, 2, 255, 255, 254, 255, + 64, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 200, 0, + 0, 0, 0, 2, 255, 255, + 4, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 193, 0, 0, 0, 108, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 2, 0, 116, 0, + 0, 0, 0, 0, 0, 0, + 132, 0, 0, 0, 3, 0, + 1, 0, 1, 0, 6, 0, + 140, 0, 0, 0, 0, 0, + 0, 0, 156, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 2, 0, 168, 0, 0, 0, + 0, 0, 0, 0, 184, 0, + 0, 0, 2, 0, 1, 0, + 1, 0, 6, 0, 168, 0, + 0, 0, 0, 0, 0, 0, + 100, 105, 102, 102, 84, 101, + 120, 0, 4, 0, 12, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 101, 110, 118, 84, 101, 120, + 0, 171, 4, 0, 12, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 67, 111, 108, + 111, 114, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 102, 120, + 112, 97, 114, 97, 109, 115, + 0, 112, 115, 95, 50, 95, + 48, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 1, 0, 3, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 0, 0, + 0, 128, 1, 0, 7, 144, + 31, 0, 0, 2, 0, 0, + 0, 144, 0, 8, 15, 160, + 31, 0, 0, 2, 0, 0, + 0, 144, 1, 8, 15, 160, + 66, 0, 0, 3, 0, 0, + 15, 128, 1, 0, 228, 176, + 1, 8, 228, 160, 66, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 228, 176, 0, 8, + 228, 160, 5, 0, 0, 3, + 2, 0, 7, 128, 1, 0, + 228, 144, 1, 0, 0, 160, + 5, 0, 0, 3, 0, 0, + 7, 128, 0, 0, 228, 128, + 2, 0, 228, 128, 5, 0, + 0, 3, 0, 0, 7, 128, + 0, 0, 228, 128, 0, 0, + 170, 176, 5, 0, 0, 3, + 2, 0, 8, 128, 1, 0, + 255, 128, 0, 0, 255, 144, + 4, 0, 0, 4, 1, 0, + 7, 128, 0, 0, 228, 144, + 1, 0, 228, 128, 0, 0, + 228, 161, 4, 0, 0, 4, + 1, 0, 7, 128, 0, 0, + 170, 176, 1, 0, 228, 128, + 0, 0, 228, 160, 11, 0, + 0, 3, 0, 0, 8, 128, + 2, 0, 255, 128, 1, 0, + 85, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, + 255, 128, 0, 0, 228, 128, + 4, 0, 0, 4, 2, 0, + 7, 128, 1, 0, 228, 128, + 2, 0, 255, 128, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 8, 15, 128, 2, 0, + 228, 128, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/skin_VS.hlsl b/src/d3d/shaders/skin_VS.hlsl new file mode 100644 index 0000000..bede50f --- /dev/null +++ b/src/d3d/shaders/skin_VS.hlsl @@ -0,0 +1,63 @@ +#include "standardConstants.h" + +float4x3 boneMatrices[64] : register(c41); + +struct VS_in +{ + float4 Position : POSITION; + float3 Normal : NORMAL; + float2 TexCoord : TEXCOORD0; + float4 Prelight : COLOR0; + float4 Weights : BLENDWEIGHT; + int4 Indices : BLENDINDICES; +}; + +struct VS_out { + float4 Position : POSITION; + float3 TexCoord0 : TEXCOORD0; // also fog + float4 Color : COLOR0; +}; + + +VS_out main(in VS_in input) +{ + VS_out output; + + int j; + float3 SkinVertex = float3(0.0, 0.0, 0.0); + float3 SkinNormal = float3(0.0, 0.0, 0.0); + for(j = 0; j < 4; j++){ + SkinVertex += mul(input.Position, boneMatrices[input.Indices[j]]).xyz * input.Weights[j]; + SkinNormal += mul(input.Normal, (float3x3)boneMatrices[input.Indices[j]]).xyz * input.Weights[j]; + } + + output.Position = mul(combinedMat, float4(SkinVertex, 1.0)); + float3 Vertex = mul(worldMat, float4(SkinVertex, 1.0)).xyz; + float3 Normal = mul(normalMat, SkinNormal); + + output.TexCoord0.xy = input.TexCoord; + + output.Color = input.Prelight; + output.Color.rgb += ambientLight.rgb * surfAmbient; + + int i; +#ifdef DIRECTIONALS + for(i = 0; i < numDirLights; i++) + output.Color.xyz += DoDirLight(lights[i+firstDirLight], Normal)*surfDiffuse; +#endif +#ifdef POINTLIGHTS + for(i = 0; i < numPointLights; i++) + output.Color.xyz += DoPointLight(lights[i+firstPointLight], Vertex.xyz, Normal)*surfDiffuse; +#endif +#ifdef SPOTLIGHTS + for(i = 0; i < numSpotLights; i++) + output.Color.xyz += DoSpotLight(lights[i+firstSpotLight], Vertex.xyz, Normal)*surfDiffuse; +#endif + // PS2 clamps before material color + output.Color = clamp(output.Color, 0.0, 1.0); + output.Color *= matCol; + + output.TexCoord0.z = clamp((output.Position.w - fogEnd)*fogRange, fogDisable, 1.0); + + return output; +} diff --git a/src/d3d/shaders/skin_all_VS.h b/src/d3d/shaders/skin_all_VS.h new file mode 100644 index 0000000..67f89f3 --- /dev/null +++ b/src/d3d/shaders/skin_all_VS.h @@ -0,0 +1,664 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /DPOINTLIGHTS /DSPOTLIGHTS /Fh +// skin_all_VS.h skin_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x3 boneMatrices[64]; +// float4x4 combinedMat; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// int numPointLights; +// int numSpotLights; +// float4 surfProps; +// float4x4 worldMat; +// +// +// Registers: +// +// Name Reg Size +// -------------- ----- ---- +// numDirLights i0 1 +// numPointLights i1 1 +// numSpotLights i2 1 +// combinedMat c0 4 +// worldMat c4 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// boneMatrices c41 192 +// + + vs_2_0 + def c11, 3, 0, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + dcl_blendweight v4 + dcl_blendindices v5 + mul r0, v5, c11.x + mova a0.x, r0.x + dp3 r1.z, v1, c43[a0.x] + dp4 r2.x, v0, c41[a0.x] + dp4 r2.y, v0, c42[a0.x] + dp4 r2.z, v0, c43[a0.x] + dp3 r1.x, v1, c41[a0.x] + dp3 r1.y, v1, c42[a0.x] + mova a0.x, r0.y + dp3 r3.z, v1, c43[a0.x] + dp4 r4.x, v0, c41[a0.x] + dp4 r4.y, v0, c42[a0.x] + dp4 r4.z, v0, c43[a0.x] + mul r4.xyz, r4, v4.y + mad r2.xyz, r2, v4.x, r4 + dp3 r3.x, v1, c41[a0.x] + dp3 r3.y, v1, c42[a0.x] + mul r3.xyz, r3, v4.y + mad r1.xyz, r1, v4.x, r3 + mova a0.x, r0.z + dp3 r0.z, v1, c43[a0.x] + dp4 r3.x, v0, c41[a0.x] + dp4 r3.y, v0, c42[a0.x] + dp4 r3.z, v0, c43[a0.x] + mad r2.xyz, r3, v4.z, r2 + dp3 r0.x, v1, c41[a0.x] + dp3 r0.y, v1, c42[a0.x] + mad r0.xyz, r0, v4.z, r1 + mova a0.x, r0.w + dp3 r1.z, v1, c43[a0.x] + dp4 r3.x, v0, c41[a0.x] + dp4 r3.y, v0, c42[a0.x] + dp4 r3.z, v0, c43[a0.x] + mad r2.xyz, r3, v4.w, r2 + dp3 r1.x, v1, c41[a0.x] + dp3 r1.y, v1, c42[a0.x] + mad r0.xyz, r1, v4.w, r0 + mul r1.xyz, r2.y, c5 + mad r1.xyz, c4, r2.x, r1 + mad r1.xyz, c6, r2.z, r1 + add r1.xyz, r1, c7 + mul r3.xyz, r0.y, c9 + mad r0.xyw, c8.xyzz, r0.x, r3.xyzz + mad r0.xyz, c10, r0.z, r0.xyww + mov r3.x, c13.x + mad r3.xyz, c15, r3.x, v3 + mov r4.xyz, r3 + mov r0.w, c11.y + rep i0 + add r1.w, r0.w, c16.x + mul r1.w, r1.w, c11.x + mova a0.x, r1.w + dp3 r1.w, r0, -c19[a0.x] + max r1.w, r1.w, c11.y + mul r5.xyz, r1.w, c17[a0.x] + mad r4.xyz, r5, c13.z, r4 + add r0.w, r0.w, c11.z + endrep + mov r3.xyz, r4 + mov r0.w, c11.y + rep i1 + add r1.w, r0.w, c16.y + mul r1.w, r1.w, c11.x + mova a0.x, r1.w + add r5.xyz, r1, -c18[a0.x] + dp3 r1.w, r5, r5 + rsq r1.w, r1.w + mul r5.xyz, r1.w, r5 + dp3 r2.w, r0, -r5 + max r2.w, r2.w, c11.y + mul r5.xyz, r2.w, c17[a0.x] + rcp r1.w, r1.w + rcp r2.w, c17[a0.x].w + mad r1.w, r1.w, -r2.w, c11.z + max r1.w, r1.w, c11.y + mul r5.xyz, r1.w, r5 + mad r3.xyz, r5, c13.z, r3 + add r0.w, r0.w, c11.z + endrep + mov r4.xyz, r3 + mov r0.w, c11.y + rep i2 + add r1.w, r0.w, c16.z + mul r1.w, r1.w, c11.x + mova a0.x, r1.w + add r5.xyz, r1, -c18[a0.x] + dp3 r1.w, r5, r5 + rsq r1.w, r1.w + mul r5.xyz, r1.w, r5 + dp3 r2.w, r0, -r5 + dp3 r3.w, r5, c19[a0.x] + max r2.w, r2.w, c11.y + add r3.w, r3.w, c18[a0.x].w + mov r5.z, c11.z + add r5.x, r5.z, c18[a0.x].w + rcp r5.x, r5.x + mul r3.w, r3.w, r5.x + slt r5.x, r3.w, c11.y + mad r2.w, r5.x, -r2.w, r2.w + max r3.w, r3.w, c19[a0.x].w + mul r2.w, r2.w, r3.w + mul r5.xyz, r2.w, c17[a0.x] + rcp r1.w, r1.w + rcp r2.w, c17[a0.x].w + mad r1.w, r1.w, -r2.w, c11.z + max r1.w, r1.w, c11.y + mul r5.xyz, r1.w, r5 + mad r4.xyz, r5, c13.z, r4 + add r0.w, r0.w, c11.z + endrep + mov r4.w, v3.w + max r0, r4, c11.y + min r0, r0, c11.z + mul oD0, r0, c12 + mul r0, r2.y, c1 + mad r0, c0, r2.x, r0 + mad r0, c2, r2.z, r0 + add r0, r0, c3 + mov oPos, r0 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c11.z + mov oT0.xy, v2 + +// approximately 133 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 171, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 119, 2, + 0, 0, 0, 2, 254, 255, + 13, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 112, 2, 0, 0, 32, 1, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 48, 1, + 0, 0, 0, 0, 0, 0, + 64, 1, 0, 0, 2, 0, + 41, 0, 192, 0, 166, 0, + 80, 1, 0, 0, 0, 0, + 0, 0, 96, 1, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 108, 1, 0, 0, + 0, 0, 0, 0, 124, 1, + 0, 0, 2, 0, 16, 0, + 1, 0, 66, 0, 136, 1, + 0, 0, 0, 0, 0, 0, + 152, 1, 0, 0, 2, 0, + 14, 0, 1, 0, 58, 0, + 48, 1, 0, 0, 0, 0, + 0, 0, 160, 1, 0, 0, + 2, 0, 17, 0, 24, 0, + 70, 0, 236, 1, 0, 0, + 0, 0, 0, 0, 252, 1, + 0, 0, 2, 0, 12, 0, + 1, 0, 50, 0, 48, 1, + 0, 0, 0, 0, 0, 0, + 3, 2, 0, 0, 2, 0, + 8, 0, 3, 0, 34, 0, + 16, 2, 0, 0, 0, 0, + 0, 0, 32, 2, 0, 0, + 1, 0, 0, 0, 1, 0, + 2, 0, 48, 2, 0, 0, + 0, 0, 0, 0, 64, 2, + 0, 0, 1, 0, 1, 0, + 1, 0, 6, 0, 48, 2, + 0, 0, 0, 0, 0, 0, + 79, 2, 0, 0, 1, 0, + 2, 0, 1, 0, 10, 0, + 48, 2, 0, 0, 0, 0, + 0, 0, 93, 2, 0, 0, + 2, 0, 13, 0, 1, 0, + 54, 0, 48, 1, 0, 0, + 0, 0, 0, 0, 103, 2, + 0, 0, 2, 0, 4, 0, + 4, 0, 18, 0, 108, 1, + 0, 0, 0, 0, 0, 0, + 97, 109, 98, 105, 101, 110, + 116, 76, 105, 103, 104, 116, + 0, 171, 171, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 98, 111, 110, 101, + 77, 97, 116, 114, 105, 99, + 101, 115, 0, 171, 171, 171, + 3, 0, 3, 0, 4, 0, + 3, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 99, 111, + 109, 98, 105, 110, 101, 100, + 77, 97, 116, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 105, 114, 115, + 116, 76, 105, 103, 104, 116, + 0, 171, 1, 0, 2, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 68, 97, 116, + 97, 0, 108, 105, 103, 104, + 116, 115, 0, 99, 111, 108, + 111, 114, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 112, 111, + 115, 105, 116, 105, 111, 110, + 0, 100, 105, 114, 101, 99, + 116, 105, 111, 110, 0, 171, + 167, 1, 0, 0, 176, 1, + 0, 0, 192, 1, 0, 0, + 176, 1, 0, 0, 201, 1, + 0, 0, 176, 1, 0, 0, + 5, 0, 0, 0, 1, 0, + 12, 0, 8, 0, 3, 0, + 212, 1, 0, 0, 109, 97, + 116, 67, 111, 108, 0, 110, + 111, 114, 109, 97, 108, 77, + 97, 116, 0, 171, 171, 171, + 3, 0, 3, 0, 3, 0, + 3, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 110, 117, + 109, 68, 105, 114, 76, 105, + 103, 104, 116, 115, 0, 171, + 171, 171, 0, 0, 2, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 110, 117, 109, 80, 111, 105, + 110, 116, 76, 105, 103, 104, + 116, 115, 0, 110, 117, 109, + 83, 112, 111, 116, 76, 105, + 103, 104, 116, 115, 0, 115, + 117, 114, 102, 80, 114, 111, + 112, 115, 0, 119, 111, 114, + 108, 100, 77, 97, 116, 0, + 118, 115, 95, 50, 95, 48, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 50, 57, 46, 57, + 53, 50, 46, 51, 49, 49, + 49, 0, 81, 0, 0, 5, + 11, 0, 15, 160, 0, 0, + 64, 64, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, + 0, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 3, 0, 0, 128, 1, 0, + 15, 144, 31, 0, 0, 2, + 5, 0, 0, 128, 2, 0, + 15, 144, 31, 0, 0, 2, + 10, 0, 0, 128, 3, 0, + 15, 144, 31, 0, 0, 2, + 1, 0, 0, 128, 4, 0, + 15, 144, 31, 0, 0, 2, + 2, 0, 0, 128, 5, 0, + 15, 144, 5, 0, 0, 3, + 0, 0, 15, 128, 5, 0, + 228, 144, 11, 0, 0, 160, + 46, 0, 0, 2, 0, 0, + 1, 176, 0, 0, 0, 128, + 8, 0, 0, 4, 1, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 2, 0, 1, 128, 0, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 2, 0, 2, 128, + 0, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 9, 0, 0, 4, 2, 0, + 4, 128, 0, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 8, 0, 0, 4, + 1, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 8, 0, + 0, 4, 1, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 46, 0, 0, 2, 0, 0, + 1, 176, 0, 0, 85, 128, + 8, 0, 0, 4, 3, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 4, 0, 1, 128, 0, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 4, 0, 2, 128, + 0, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 9, 0, 0, 4, 4, 0, + 4, 128, 0, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 5, 0, 0, 3, + 4, 0, 7, 128, 4, 0, + 228, 128, 4, 0, 85, 144, + 4, 0, 0, 4, 2, 0, + 7, 128, 2, 0, 228, 128, + 4, 0, 0, 144, 4, 0, + 228, 128, 8, 0, 0, 4, + 3, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 8, 0, + 0, 4, 3, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 5, 0, 0, 3, 3, 0, + 7, 128, 3, 0, 228, 128, + 4, 0, 85, 144, 4, 0, + 0, 4, 1, 0, 7, 128, + 1, 0, 228, 128, 4, 0, + 0, 144, 3, 0, 228, 128, + 46, 0, 0, 2, 0, 0, + 1, 176, 0, 0, 170, 128, + 8, 0, 0, 4, 0, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 3, 0, 1, 128, 0, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 3, 0, 2, 128, + 0, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 9, 0, 0, 4, 3, 0, + 4, 128, 0, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 0, 176, 4, 0, 0, 4, + 2, 0, 7, 128, 3, 0, + 228, 128, 4, 0, 170, 144, + 2, 0, 228, 128, 8, 0, + 0, 4, 0, 0, 1, 128, + 1, 0, 228, 144, 41, 32, + 228, 160, 0, 0, 0, 176, + 8, 0, 0, 4, 0, 0, + 2, 128, 1, 0, 228, 144, + 42, 32, 228, 160, 0, 0, + 0, 176, 4, 0, 0, 4, + 0, 0, 7, 128, 0, 0, + 228, 128, 4, 0, 170, 144, + 1, 0, 228, 128, 46, 0, + 0, 2, 0, 0, 1, 176, + 0, 0, 255, 128, 8, 0, + 0, 4, 1, 0, 4, 128, + 1, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 0, 176, + 9, 0, 0, 4, 3, 0, + 1, 128, 0, 0, 228, 144, + 41, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 3, 0, 2, 128, 0, 0, + 228, 144, 42, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 3, 0, 4, 128, + 0, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 2, 0, + 7, 128, 3, 0, 228, 128, + 4, 0, 255, 144, 2, 0, + 228, 128, 8, 0, 0, 4, + 1, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 0, 176, 8, 0, + 0, 4, 1, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 0, 0, + 7, 128, 1, 0, 228, 128, + 4, 0, 255, 144, 0, 0, + 228, 128, 5, 0, 0, 3, + 1, 0, 7, 128, 2, 0, + 85, 128, 5, 0, 228, 160, + 4, 0, 0, 4, 1, 0, + 7, 128, 4, 0, 228, 160, + 2, 0, 0, 128, 1, 0, + 228, 128, 4, 0, 0, 4, + 1, 0, 7, 128, 6, 0, + 228, 160, 2, 0, 170, 128, + 1, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 7, 128, + 1, 0, 228, 128, 7, 0, + 228, 160, 5, 0, 0, 3, + 3, 0, 7, 128, 0, 0, + 85, 128, 9, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 11, 128, 8, 0, 164, 160, + 0, 0, 0, 128, 3, 0, + 164, 128, 4, 0, 0, 4, + 0, 0, 7, 128, 10, 0, + 228, 160, 0, 0, 170, 128, + 0, 0, 244, 128, 1, 0, + 0, 2, 3, 0, 1, 128, + 13, 0, 0, 160, 4, 0, + 0, 4, 3, 0, 7, 128, + 15, 0, 228, 160, 3, 0, + 0, 128, 3, 0, 228, 144, + 1, 0, 0, 2, 4, 0, + 7, 128, 3, 0, 228, 128, + 1, 0, 0, 2, 0, 0, + 8, 128, 11, 0, 85, 160, + 38, 0, 0, 1, 0, 0, + 228, 240, 2, 0, 0, 3, + 1, 0, 8, 128, 0, 0, + 255, 128, 16, 0, 0, 160, + 5, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 11, 0, 0, 160, 46, 0, + 0, 2, 0, 0, 1, 176, + 1, 0, 255, 128, 8, 0, + 0, 4, 1, 0, 8, 128, + 0, 0, 228, 128, 19, 32, + 228, 161, 0, 0, 0, 176, + 11, 0, 0, 3, 1, 0, + 8, 128, 1, 0, 255, 128, + 11, 0, 85, 160, 5, 0, + 0, 4, 5, 0, 7, 128, + 1, 0, 255, 128, 17, 32, + 228, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 4, 0, + 7, 128, 5, 0, 228, 128, + 13, 0, 170, 160, 4, 0, + 228, 128, 2, 0, 0, 3, + 0, 0, 8, 128, 0, 0, + 255, 128, 11, 0, 170, 160, + 39, 0, 0, 0, 1, 0, + 0, 2, 3, 0, 7, 128, + 4, 0, 228, 128, 1, 0, + 0, 2, 0, 0, 8, 128, + 11, 0, 85, 160, 38, 0, + 0, 1, 1, 0, 228, 240, + 2, 0, 0, 3, 1, 0, + 8, 128, 0, 0, 255, 128, + 16, 0, 85, 160, 5, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 11, 0, + 0, 160, 46, 0, 0, 2, + 0, 0, 1, 176, 1, 0, + 255, 128, 2, 0, 0, 4, + 5, 0, 7, 128, 1, 0, + 228, 128, 18, 32, 228, 161, + 0, 0, 0, 176, 8, 0, + 0, 3, 1, 0, 8, 128, + 5, 0, 228, 128, 5, 0, + 228, 128, 7, 0, 0, 2, + 1, 0, 8, 128, 1, 0, + 255, 128, 5, 0, 0, 3, + 5, 0, 7, 128, 1, 0, + 255, 128, 5, 0, 228, 128, + 8, 0, 0, 3, 2, 0, + 8, 128, 0, 0, 228, 128, + 5, 0, 228, 129, 11, 0, + 0, 3, 2, 0, 8, 128, + 2, 0, 255, 128, 11, 0, + 85, 160, 5, 0, 0, 4, + 5, 0, 7, 128, 2, 0, + 255, 128, 17, 32, 228, 160, + 0, 0, 0, 176, 6, 0, + 0, 2, 1, 0, 8, 128, + 1, 0, 255, 128, 6, 0, + 0, 3, 2, 0, 8, 128, + 17, 32, 255, 160, 0, 0, + 0, 176, 4, 0, 0, 4, + 1, 0, 8, 128, 1, 0, + 255, 128, 2, 0, 255, 129, + 11, 0, 170, 160, 11, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 11, 0, + 85, 160, 5, 0, 0, 3, + 5, 0, 7, 128, 1, 0, + 255, 128, 5, 0, 228, 128, + 4, 0, 0, 4, 3, 0, + 7, 128, 5, 0, 228, 128, + 13, 0, 170, 160, 3, 0, + 228, 128, 2, 0, 0, 3, + 0, 0, 8, 128, 0, 0, + 255, 128, 11, 0, 170, 160, + 39, 0, 0, 0, 1, 0, + 0, 2, 4, 0, 7, 128, + 3, 0, 228, 128, 1, 0, + 0, 2, 0, 0, 8, 128, + 11, 0, 85, 160, 38, 0, + 0, 1, 2, 0, 228, 240, + 2, 0, 0, 3, 1, 0, + 8, 128, 0, 0, 255, 128, + 16, 0, 170, 160, 5, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 11, 0, + 0, 160, 46, 0, 0, 2, + 0, 0, 1, 176, 1, 0, + 255, 128, 2, 0, 0, 4, + 5, 0, 7, 128, 1, 0, + 228, 128, 18, 32, 228, 161, + 0, 0, 0, 176, 8, 0, + 0, 3, 1, 0, 8, 128, + 5, 0, 228, 128, 5, 0, + 228, 128, 7, 0, 0, 2, + 1, 0, 8, 128, 1, 0, + 255, 128, 5, 0, 0, 3, + 5, 0, 7, 128, 1, 0, + 255, 128, 5, 0, 228, 128, + 8, 0, 0, 3, 2, 0, + 8, 128, 0, 0, 228, 128, + 5, 0, 228, 129, 8, 0, + 0, 4, 3, 0, 8, 128, + 5, 0, 228, 128, 19, 32, + 228, 160, 0, 0, 0, 176, + 11, 0, 0, 3, 2, 0, + 8, 128, 2, 0, 255, 128, + 11, 0, 85, 160, 2, 0, + 0, 4, 3, 0, 8, 128, + 3, 0, 255, 128, 18, 32, + 255, 160, 0, 0, 0, 176, + 1, 0, 0, 2, 5, 0, + 4, 128, 11, 0, 170, 160, + 2, 0, 0, 4, 5, 0, + 1, 128, 5, 0, 170, 128, + 18, 32, 255, 160, 0, 0, + 0, 176, 6, 0, 0, 2, + 5, 0, 1, 128, 5, 0, + 0, 128, 5, 0, 0, 3, + 3, 0, 8, 128, 3, 0, + 255, 128, 5, 0, 0, 128, + 12, 0, 0, 3, 5, 0, + 1, 128, 3, 0, 255, 128, + 11, 0, 85, 160, 4, 0, + 0, 4, 2, 0, 8, 128, + 5, 0, 0, 128, 2, 0, + 255, 129, 2, 0, 255, 128, + 11, 0, 0, 4, 3, 0, + 8, 128, 3, 0, 255, 128, + 19, 32, 255, 160, 0, 0, + 0, 176, 5, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 3, 0, 255, 128, + 5, 0, 0, 4, 5, 0, + 7, 128, 2, 0, 255, 128, + 17, 32, 228, 160, 0, 0, + 0, 176, 6, 0, 0, 2, + 1, 0, 8, 128, 1, 0, + 255, 128, 6, 0, 0, 3, + 2, 0, 8, 128, 17, 32, + 255, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 1, 0, + 8, 128, 1, 0, 255, 128, + 2, 0, 255, 129, 11, 0, + 170, 160, 11, 0, 0, 3, + 1, 0, 8, 128, 1, 0, + 255, 128, 11, 0, 85, 160, + 5, 0, 0, 3, 5, 0, + 7, 128, 1, 0, 255, 128, + 5, 0, 228, 128, 4, 0, + 0, 4, 4, 0, 7, 128, + 5, 0, 228, 128, 13, 0, + 170, 160, 4, 0, 228, 128, + 2, 0, 0, 3, 0, 0, + 8, 128, 0, 0, 255, 128, + 11, 0, 170, 160, 39, 0, + 0, 0, 1, 0, 0, 2, + 4, 0, 8, 128, 3, 0, + 255, 144, 11, 0, 0, 3, + 0, 0, 15, 128, 4, 0, + 228, 128, 11, 0, 85, 160, + 10, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 11, 0, 170, 160, 5, 0, + 0, 3, 0, 0, 15, 208, + 0, 0, 228, 128, 12, 0, + 228, 160, 5, 0, 0, 3, + 0, 0, 15, 128, 2, 0, + 85, 128, 1, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 15, 128, 0, 0, 228, 160, + 2, 0, 0, 128, 0, 0, + 228, 128, 4, 0, 0, 4, + 0, 0, 15, 128, 2, 0, + 228, 160, 2, 0, 170, 128, + 0, 0, 228, 128, 2, 0, + 0, 3, 0, 0, 15, 128, + 0, 0, 228, 128, 3, 0, + 228, 160, 1, 0, 0, 2, + 0, 0, 15, 192, 0, 0, + 228, 128, 2, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 255, 128, 14, 0, 85, 161, + 5, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 170, 160, 11, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 0, 128, 14, 0, + 255, 160, 10, 0, 0, 3, + 0, 0, 4, 224, 0, 0, + 0, 128, 11, 0, 170, 160, + 1, 0, 0, 2, 0, 0, + 3, 224, 2, 0, 228, 144, + 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/skin_amb_VS.h b/src/d3d/shaders/skin_amb_VS.h new file mode 100644 index 0000000..e0a5548 --- /dev/null +++ b/src/d3d/shaders/skin_amb_VS.h @@ -0,0 +1,253 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /Fh skin_amb_VS.h skin_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x3 boneMatrices[64]; +// float4x4 combinedMat; +// float4 fogData; +// float4 matCol; +// float4 surfProps; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// combinedMat c0 4 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// boneMatrices c41 192 +// + + vs_2_0 + def c4, 3, 0, 1, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_color v2 + dcl_blendweight v3 + dcl_blendindices v4 + mov r0.xyz, c15 + mad r0.xyz, r0, c13.x, v2 + mov r0.w, v2.w + max r0, r0, c4.y + min r0, r0, c4.z + mul oD0, r0, c12 + mul r0, v4, c4.x + mova a0.x, r0.y + dp4 r1.x, v0, c41[a0.x] + dp4 r1.y, v0, c42[a0.x] + dp4 r1.z, v0, c43[a0.x] + mul r1.xyz, r1, v3.y + mova a0.x, r0.x + dp4 r2.x, v0, c41[a0.x] + dp4 r2.y, v0, c42[a0.x] + dp4 r2.z, v0, c43[a0.x] + mad r1.xyz, r2, v3.x, r1 + mova a0.xy, r0.zwzw + dp4 r0.x, v0, c41[a0.x] + dp4 r0.y, v0, c42[a0.x] + dp4 r0.z, v0, c43[a0.x] + mad r0.xyz, r0, v3.z, r1 + dp4 r1.x, v0, c41[a0.y] + dp4 r1.y, v0, c42[a0.y] + dp4 r1.z, v0, c43[a0.y] + mad r0.xyz, r1, v3.w, r0 + mul r1, r0.y, c1 + mad r1, c0, r0.x, r1 + mad r0, c2, r0.z, r1 + add r0, r0, c3 + add r1.x, r0.w, -c14.y + mov oPos, r0 + mul r0.x, r1.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.z + mov oT0.xy, v1 + +// approximately 36 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 82, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 16, 1, + 0, 0, 0, 2, 254, 255, + 6, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 9, 1, 0, 0, 148, 0, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 164, 0, + 0, 0, 0, 0, 0, 0, + 180, 0, 0, 0, 2, 0, + 41, 0, 192, 0, 166, 0, + 196, 0, 0, 0, 0, 0, + 0, 0, 212, 0, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 224, 0, 0, 0, + 0, 0, 0, 0, 240, 0, + 0, 0, 2, 0, 14, 0, + 1, 0, 58, 0, 164, 0, + 0, 0, 0, 0, 0, 0, + 248, 0, 0, 0, 2, 0, + 12, 0, 1, 0, 50, 0, + 164, 0, 0, 0, 0, 0, + 0, 0, 255, 0, 0, 0, + 2, 0, 13, 0, 1, 0, + 54, 0, 164, 0, 0, 0, + 0, 0, 0, 0, 97, 109, + 98, 105, 101, 110, 116, 76, + 105, 103, 104, 116, 0, 171, + 171, 171, 1, 0, 3, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 98, 111, 110, 101, 77, 97, + 116, 114, 105, 99, 101, 115, + 0, 171, 171, 171, 3, 0, + 3, 0, 4, 0, 3, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 99, 111, 109, 98, + 105, 110, 101, 100, 77, 97, + 116, 0, 3, 0, 3, 0, + 4, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 68, 97, 116, + 97, 0, 109, 97, 116, 67, + 111, 108, 0, 115, 117, 114, + 102, 80, 114, 111, 112, 115, + 0, 118, 115, 95, 50, 95, + 48, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 50, 57, 46, + 57, 53, 50, 46, 51, 49, + 49, 49, 0, 171, 171, 171, + 81, 0, 0, 5, 4, 0, + 15, 160, 0, 0, 64, 64, + 0, 0, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 0, 128, 1, 0, 15, 144, + 31, 0, 0, 2, 10, 0, + 0, 128, 2, 0, 15, 144, + 31, 0, 0, 2, 1, 0, + 0, 128, 3, 0, 15, 144, + 31, 0, 0, 2, 2, 0, + 0, 128, 4, 0, 15, 144, + 1, 0, 0, 2, 0, 0, + 7, 128, 15, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 0, 0, 228, 128, + 13, 0, 0, 160, 2, 0, + 228, 144, 1, 0, 0, 2, + 0, 0, 8, 128, 2, 0, + 255, 144, 11, 0, 0, 3, + 0, 0, 15, 128, 0, 0, + 228, 128, 4, 0, 85, 160, + 10, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 4, 0, 170, 160, 5, 0, + 0, 3, 0, 0, 15, 208, + 0, 0, 228, 128, 12, 0, + 228, 160, 5, 0, 0, 3, + 0, 0, 15, 128, 4, 0, + 228, 144, 4, 0, 0, 160, + 46, 0, 0, 2, 0, 0, + 1, 176, 0, 0, 85, 128, + 9, 0, 0, 4, 1, 0, + 1, 128, 0, 0, 228, 144, + 41, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 1, 0, 2, 128, 0, 0, + 228, 144, 42, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 1, 0, 4, 128, + 0, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 0, 176, + 5, 0, 0, 3, 1, 0, + 7, 128, 1, 0, 228, 128, + 3, 0, 85, 144, 46, 0, + 0, 2, 0, 0, 1, 176, + 0, 0, 0, 128, 9, 0, + 0, 4, 2, 0, 1, 128, + 0, 0, 228, 144, 41, 32, + 228, 160, 0, 0, 0, 176, + 9, 0, 0, 4, 2, 0, + 2, 128, 0, 0, 228, 144, + 42, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 2, 0, 4, 128, 0, 0, + 228, 144, 43, 32, 228, 160, + 0, 0, 0, 176, 4, 0, + 0, 4, 1, 0, 7, 128, + 2, 0, 228, 128, 3, 0, + 0, 144, 1, 0, 228, 128, + 46, 0, 0, 2, 0, 0, + 3, 176, 0, 0, 238, 128, + 9, 0, 0, 4, 0, 0, + 1, 128, 0, 0, 228, 144, + 41, 32, 228, 160, 0, 0, + 0, 176, 9, 0, 0, 4, + 0, 0, 2, 128, 0, 0, + 228, 144, 42, 32, 228, 160, + 0, 0, 0, 176, 9, 0, + 0, 4, 0, 0, 4, 128, + 0, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 0, 176, + 4, 0, 0, 4, 0, 0, + 7, 128, 0, 0, 228, 128, + 3, 0, 170, 144, 1, 0, + 228, 128, 9, 0, 0, 4, + 1, 0, 1, 128, 0, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 85, 176, 9, 0, + 0, 4, 1, 0, 2, 128, + 0, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 85, 176, + 9, 0, 0, 4, 1, 0, + 4, 128, 0, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 85, 176, 4, 0, 0, 4, + 0, 0, 7, 128, 1, 0, + 228, 128, 3, 0, 255, 144, + 0, 0, 228, 128, 5, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 85, 128, 1, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 15, 128, 0, 0, + 228, 160, 0, 0, 0, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 2, 0, 228, 160, 0, 0, + 170, 128, 1, 0, 228, 128, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 3, 0, 228, 160, 2, 0, + 0, 3, 1, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 1, 0, 0, 2, + 0, 0, 15, 192, 0, 0, + 228, 128, 5, 0, 0, 3, + 0, 0, 1, 128, 1, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 4, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 1, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/skin_amb_dir_VS.h b/src/d3d/shaders/skin_amb_dir_VS.h new file mode 100644 index 0000000..7949749 --- /dev/null +++ b/src/d3d/shaders/skin_amb_dir_VS.h @@ -0,0 +1,503 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /nologo /T vs_2_0 /DDIRECTIONALS /Fh skin_amb_dir_VS.h skin_VS.hlsl +// +// +// Parameters: +// +// float4 ambientLight; +// float4x3 boneMatrices[64]; +// float4x4 combinedMat; +// int4 firstLight; +// float4 fogData; +// +// struct +// { +// float4 color; +// float4 position; +// float4 direction; +// +// } lights[8]; +// +// float4 matCol; +// float3x3 normalMat; +// int numDirLights; +// float4 surfProps; +// +// +// Registers: +// +// Name Reg Size +// ------------ ----- ---- +// numDirLights i0 1 +// combinedMat c0 4 +// normalMat c8 3 +// matCol c12 1 +// surfProps c13 1 +// fogData c14 1 +// ambientLight c15 1 +// firstLight c16 1 +// lights c17 24 +// boneMatrices c41 192 +// + + vs_2_0 + def c4, 3, 0, 1, 0 + dcl_position v0 + dcl_normal v1 + dcl_texcoord v2 + dcl_color v3 + dcl_blendweight v4 + dcl_blendindices v5 + mul r0, v5, c4.x + mova a0.w, r0.x + dp3 r1.z, v1, c43[a0.w] + mova a0.w, r0.x + dp3 r1.x, v1, c41[a0.w] + mova a0.w, r0.x + dp3 r1.y, v1, c42[a0.w] + mova a0.w, r0.y + dp3 r2.z, v1, c43[a0.w] + mova a0.w, r0.y + dp3 r2.x, v1, c41[a0.w] + mova a0.w, r0.y + dp3 r2.y, v1, c42[a0.w] + mul r2.xyz, r2, v4.y + mad r1.xyz, r1, v4.x, r2 + mova a0.w, r0.z + dp3 r2.z, v1, c43[a0.w] + mova a0.w, r0.z + dp3 r2.x, v1, c41[a0.w] + mova a0.w, r0.z + dp3 r2.y, v1, c42[a0.w] + mad r1.xyz, r2, v4.z, r1 + mova a0.w, r0.w + dp3 r2.z, v1, c43[a0.w] + mova a0.w, r0.w + dp3 r2.x, v1, c41[a0.w] + mova a0.w, r0.w + dp3 r2.y, v1, c42[a0.w] + mad r1.xyz, r2, v4.w, r1 + mul r2.xyz, r1.y, c9 + mad r1.xyw, c8.xyzz, r1.x, r2.xyzz + mad r1.xyz, c10, r1.z, r1.xyww + mov r2.x, c13.x + mad r2.xyz, c15, r2.x, v3 + mov r3.xyz, r2 + mov r1.w, c4.y + rep i0 + add r2.w, r1.w, c16.x + mul r2.w, r2.w, c4.x + mova a0.w, r2.w + dp3 r4.x, r1, -c19[a0.w] + max r4.x, r4.x, c4.y + mova a0.w, r2.w + mul r4.xyz, r4.x, c17[a0.w] + mad r3.xyz, r4, c13.z, r3 + add r1.w, r1.w, c4.z + endrep + mov r3.w, v3.w + max r1, r3, c4.y + min r1, r1, c4.z + mul oD0, r1, c12 + mova a0.w, r0.y + dp4 r1.x, v0, c41[a0.w] + mova a0.w, r0.y + dp4 r1.y, v0, c42[a0.w] + mova a0.w, r0.y + dp4 r1.z, v0, c43[a0.w] + mul r1.xyz, r1, v4.y + mova a0.w, r0.x + dp4 r2.x, v0, c41[a0.w] + mova a0.w, r0.x + dp4 r2.y, v0, c42[a0.w] + mova a0.w, r0.x + dp4 r2.z, v0, c43[a0.w] + mad r1.xyz, r2, v4.x, r1 + mova a0.w, r0.z + dp4 r2.x, v0, c41[a0.w] + mova a0.w, r0.z + dp4 r2.y, v0, c42[a0.w] + mova a0.w, r0.z + dp4 r2.z, v0, c43[a0.w] + mad r0.xyz, r2, v4.z, r1 + mova a0.w, r0.w + dp4 r1.x, v0, c41[a0.w] + mova a0.w, r0.w + dp4 r1.y, v0, c42[a0.w] + mova a0.w, r0.w + dp4 r1.z, v0, c43[a0.w] + mad r0.xyz, r1, v4.w, r0 + mul r1, r0.y, c1 + mad r1, c0, r0.x, r1 + mad r0, c2, r0.z, r1 + add r0, r0, c3 + mov oPos, r0 + add r0.x, r0.w, -c14.y + mul r0.x, r0.x, c14.z + max r0.x, r0.x, c14.w + min oT0.z, r0.x, c4.z + mov oT0.xy, v2 + +// approximately 92 instruction slots used +#endif + +const BYTE g_vs20_main[] = +{ + 0, 2, 254, 255, 254, 255, + 147, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 21, 2, + 0, 0, 0, 2, 254, 255, + 10, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 14, 2, 0, 0, 228, 0, + 0, 0, 2, 0, 15, 0, + 1, 0, 62, 0, 244, 0, + 0, 0, 0, 0, 0, 0, + 4, 1, 0, 0, 2, 0, + 41, 0, 192, 0, 166, 0, + 20, 1, 0, 0, 0, 0, + 0, 0, 36, 1, 0, 0, + 2, 0, 0, 0, 4, 0, + 2, 0, 48, 1, 0, 0, + 0, 0, 0, 0, 64, 1, + 0, 0, 2, 0, 16, 0, + 1, 0, 66, 0, 76, 1, + 0, 0, 0, 0, 0, 0, + 92, 1, 0, 0, 2, 0, + 14, 0, 1, 0, 58, 0, + 244, 0, 0, 0, 0, 0, + 0, 0, 100, 1, 0, 0, + 2, 0, 17, 0, 24, 0, + 70, 0, 176, 1, 0, 0, + 0, 0, 0, 0, 192, 1, + 0, 0, 2, 0, 12, 0, + 1, 0, 50, 0, 244, 0, + 0, 0, 0, 0, 0, 0, + 199, 1, 0, 0, 2, 0, + 8, 0, 3, 0, 34, 0, + 212, 1, 0, 0, 0, 0, + 0, 0, 228, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 2, 0, 244, 1, 0, 0, + 0, 0, 0, 0, 4, 2, + 0, 0, 2, 0, 13, 0, + 1, 0, 54, 0, 244, 0, + 0, 0, 0, 0, 0, 0, + 97, 109, 98, 105, 101, 110, + 116, 76, 105, 103, 104, 116, + 0, 171, 171, 171, 1, 0, + 3, 0, 1, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 98, 111, 110, 101, + 77, 97, 116, 114, 105, 99, + 101, 115, 0, 171, 171, 171, + 3, 0, 3, 0, 4, 0, + 3, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 99, 111, + 109, 98, 105, 110, 101, 100, + 77, 97, 116, 0, 3, 0, + 3, 0, 4, 0, 4, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 102, 105, 114, 115, + 116, 76, 105, 103, 104, 116, + 0, 171, 1, 0, 2, 0, + 1, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 102, 111, 103, 68, 97, 116, + 97, 0, 108, 105, 103, 104, + 116, 115, 0, 99, 111, 108, + 111, 114, 0, 171, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 112, 111, + 115, 105, 116, 105, 111, 110, + 0, 100, 105, 114, 101, 99, + 116, 105, 111, 110, 0, 171, + 107, 1, 0, 0, 116, 1, + 0, 0, 132, 1, 0, 0, + 116, 1, 0, 0, 141, 1, + 0, 0, 116, 1, 0, 0, + 5, 0, 0, 0, 1, 0, + 12, 0, 8, 0, 3, 0, + 152, 1, 0, 0, 109, 97, + 116, 67, 111, 108, 0, 110, + 111, 114, 109, 97, 108, 77, + 97, 116, 0, 171, 171, 171, + 3, 0, 3, 0, 3, 0, + 3, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 110, 117, + 109, 68, 105, 114, 76, 105, + 103, 104, 116, 115, 0, 171, + 171, 171, 0, 0, 2, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 115, 117, 114, 102, 80, 114, + 111, 112, 115, 0, 118, 115, + 95, 50, 95, 48, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 171, 171, 81, 0, 0, 5, + 4, 0, 15, 160, 0, 0, + 64, 64, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, + 0, 0, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 3, 0, 0, 128, 1, 0, + 15, 144, 31, 0, 0, 2, + 5, 0, 0, 128, 2, 0, + 15, 144, 31, 0, 0, 2, + 10, 0, 0, 128, 3, 0, + 15, 144, 31, 0, 0, 2, + 1, 0, 0, 128, 4, 0, + 15, 144, 31, 0, 0, 2, + 2, 0, 0, 128, 5, 0, + 15, 144, 5, 0, 0, 3, + 0, 0, 15, 128, 5, 0, + 228, 144, 4, 0, 0, 160, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 0, 128, + 8, 0, 0, 4, 1, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 0, 128, 8, 0, 0, 4, + 1, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 0, 128, 8, 0, + 0, 4, 1, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 255, 176, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 85, 128, + 8, 0, 0, 4, 2, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 85, 128, 8, 0, 0, 4, + 2, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 85, 128, 8, 0, + 0, 4, 2, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 255, 176, + 5, 0, 0, 3, 2, 0, + 7, 128, 2, 0, 228, 128, + 4, 0, 85, 144, 4, 0, + 0, 4, 1, 0, 7, 128, + 1, 0, 228, 128, 4, 0, + 0, 144, 2, 0, 228, 128, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 170, 128, + 8, 0, 0, 4, 2, 0, + 4, 128, 1, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 170, 128, 8, 0, 0, 4, + 2, 0, 1, 128, 1, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 170, 128, 8, 0, + 0, 4, 2, 0, 2, 128, + 1, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 255, 176, + 4, 0, 0, 4, 1, 0, + 7, 128, 2, 0, 228, 128, + 4, 0, 170, 144, 1, 0, + 228, 128, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 255, 128, 8, 0, 0, 4, + 2, 0, 4, 128, 1, 0, + 228, 144, 43, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 255, 128, 8, 0, + 0, 4, 2, 0, 1, 128, + 1, 0, 228, 144, 41, 32, + 228, 160, 0, 0, 255, 176, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 255, 128, + 8, 0, 0, 4, 2, 0, + 2, 128, 1, 0, 228, 144, + 42, 32, 228, 160, 0, 0, + 255, 176, 4, 0, 0, 4, + 1, 0, 7, 128, 2, 0, + 228, 128, 4, 0, 255, 144, + 1, 0, 228, 128, 5, 0, + 0, 3, 2, 0, 7, 128, + 1, 0, 85, 128, 9, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 11, 128, 8, 0, + 164, 160, 1, 0, 0, 128, + 2, 0, 164, 128, 4, 0, + 0, 4, 1, 0, 7, 128, + 10, 0, 228, 160, 1, 0, + 170, 128, 1, 0, 244, 128, + 1, 0, 0, 2, 2, 0, + 1, 128, 13, 0, 0, 160, + 4, 0, 0, 4, 2, 0, + 7, 128, 15, 0, 228, 160, + 2, 0, 0, 128, 3, 0, + 228, 144, 1, 0, 0, 2, + 3, 0, 7, 128, 2, 0, + 228, 128, 1, 0, 0, 2, + 1, 0, 8, 128, 4, 0, + 85, 160, 38, 0, 0, 1, + 0, 0, 228, 240, 2, 0, + 0, 3, 2, 0, 8, 128, + 1, 0, 255, 128, 16, 0, + 0, 160, 5, 0, 0, 3, + 2, 0, 8, 128, 2, 0, + 255, 128, 4, 0, 0, 160, + 46, 0, 0, 2, 0, 0, + 8, 176, 2, 0, 255, 128, + 8, 0, 0, 4, 4, 0, + 1, 128, 1, 0, 228, 128, + 19, 32, 228, 161, 0, 0, + 255, 176, 11, 0, 0, 3, + 4, 0, 1, 128, 4, 0, + 0, 128, 4, 0, 85, 160, + 46, 0, 0, 2, 0, 0, + 8, 176, 2, 0, 255, 128, + 5, 0, 0, 4, 4, 0, + 7, 128, 4, 0, 0, 128, + 17, 32, 228, 160, 0, 0, + 255, 176, 4, 0, 0, 4, + 3, 0, 7, 128, 4, 0, + 228, 128, 13, 0, 170, 160, + 3, 0, 228, 128, 2, 0, + 0, 3, 1, 0, 8, 128, + 1, 0, 255, 128, 4, 0, + 170, 160, 39, 0, 0, 0, + 1, 0, 0, 2, 3, 0, + 8, 128, 3, 0, 255, 144, + 11, 0, 0, 3, 1, 0, + 15, 128, 3, 0, 228, 128, + 4, 0, 85, 160, 10, 0, + 0, 3, 1, 0, 15, 128, + 1, 0, 228, 128, 4, 0, + 170, 160, 5, 0, 0, 3, + 0, 0, 15, 208, 1, 0, + 228, 128, 12, 0, 228, 160, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 85, 128, + 9, 0, 0, 4, 1, 0, + 1, 128, 0, 0, 228, 144, + 41, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 85, 128, 9, 0, 0, 4, + 1, 0, 2, 128, 0, 0, + 228, 144, 42, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 85, 128, 9, 0, + 0, 4, 1, 0, 4, 128, + 0, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 255, 176, + 5, 0, 0, 3, 1, 0, + 7, 128, 1, 0, 228, 128, + 4, 0, 85, 144, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 0, 128, 9, 0, + 0, 4, 2, 0, 1, 128, + 0, 0, 228, 144, 41, 32, + 228, 160, 0, 0, 255, 176, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 0, 128, + 9, 0, 0, 4, 2, 0, + 2, 128, 0, 0, 228, 144, + 42, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 0, 128, 9, 0, 0, 4, + 2, 0, 4, 128, 0, 0, + 228, 144, 43, 32, 228, 160, + 0, 0, 255, 176, 4, 0, + 0, 4, 1, 0, 7, 128, + 2, 0, 228, 128, 4, 0, + 0, 144, 1, 0, 228, 128, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 170, 128, + 9, 0, 0, 4, 2, 0, + 1, 128, 0, 0, 228, 144, + 41, 32, 228, 160, 0, 0, + 255, 176, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 170, 128, 9, 0, 0, 4, + 2, 0, 2, 128, 0, 0, + 228, 144, 42, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 170, 128, 9, 0, + 0, 4, 2, 0, 4, 128, + 0, 0, 228, 144, 43, 32, + 228, 160, 0, 0, 255, 176, + 4, 0, 0, 4, 0, 0, + 7, 128, 2, 0, 228, 128, + 4, 0, 170, 144, 1, 0, + 228, 128, 46, 0, 0, 2, + 0, 0, 8, 176, 0, 0, + 255, 128, 9, 0, 0, 4, + 1, 0, 1, 128, 0, 0, + 228, 144, 41, 32, 228, 160, + 0, 0, 255, 176, 46, 0, + 0, 2, 0, 0, 8, 176, + 0, 0, 255, 128, 9, 0, + 0, 4, 1, 0, 2, 128, + 0, 0, 228, 144, 42, 32, + 228, 160, 0, 0, 255, 176, + 46, 0, 0, 2, 0, 0, + 8, 176, 0, 0, 255, 128, + 9, 0, 0, 4, 1, 0, + 4, 128, 0, 0, 228, 144, + 43, 32, 228, 160, 0, 0, + 255, 176, 4, 0, 0, 4, + 0, 0, 7, 128, 1, 0, + 228, 128, 4, 0, 255, 144, + 0, 0, 228, 128, 5, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 85, 128, 1, 0, + 228, 160, 4, 0, 0, 4, + 1, 0, 15, 128, 0, 0, + 228, 160, 0, 0, 0, 128, + 1, 0, 228, 128, 4, 0, + 0, 4, 0, 0, 15, 128, + 2, 0, 228, 160, 0, 0, + 170, 128, 1, 0, 228, 128, + 2, 0, 0, 3, 0, 0, + 15, 128, 0, 0, 228, 128, + 3, 0, 228, 160, 1, 0, + 0, 2, 0, 0, 15, 192, + 0, 0, 228, 128, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 255, 128, 14, 0, + 85, 161, 5, 0, 0, 3, + 0, 0, 1, 128, 0, 0, + 0, 128, 14, 0, 170, 160, + 11, 0, 0, 3, 0, 0, + 1, 128, 0, 0, 0, 128, + 14, 0, 255, 160, 10, 0, + 0, 3, 0, 0, 4, 224, + 0, 0, 0, 128, 4, 0, + 170, 160, 1, 0, 0, 2, + 0, 0, 3, 224, 2, 0, + 228, 144, 255, 255, 0, 0 +}; diff --git a/src/d3d/shaders/standardConstants.h b/src/d3d/shaders/standardConstants.h new file mode 100644 index 0000000..088df7d --- /dev/null +++ b/src/d3d/shaders/standardConstants.h @@ -0,0 +1,28 @@ +float4x4 combinedMat : register(c0); +float4x4 worldMat : register(c4); +float3x3 normalMat : register(c8); +float4 matCol : register(c12); +float4 surfProps : register(c13); +float4 fogData : register(c14); +float4 ambientLight : register(c15); + +#define surfAmbient (surfProps.x) +#define surfSpecular (surfProps.y) +#define surfDiffuse (surfProps.z) + +#define fogStart (fogData.x) +#define fogEnd (fogData.y) +#define fogRange (fogData.z) +#define fogDisable (fogData.w) + +#include "lighting.h" + +int numDirLights : register(i0); +int numPointLights : register(i1); +int numSpotLights : register(i2); +int4 firstLight : register(c16); +Light lights[8] : register(c17); + +#define firstDirLight (firstLight.x) +#define firstPointLight (firstLight.y) +#define firstSpotLight (firstLight.z) diff --git a/src/d3d/xbox.cpp b/src/d3d/xbox.cpp new file mode 100644 index 0000000..62fab0c --- /dev/null +++ b/src/d3d/xbox.cpp @@ -0,0 +1,1005 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#include "rwxbox.h" + +#include "rwxboximpl.h" + +#define PLUGIN_ID 2 + +namespace rw { +namespace xbox { + +static void* +driverOpen(void *o, int32, int32) +{ + engine->driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline(); + + engine->driver[PLATFORM_XBOX]->rasterNativeOffset = nativeRasterOffset; + engine->driver[PLATFORM_XBOX]->rasterCreate = rasterCreate; + engine->driver[PLATFORM_XBOX]->rasterLock = rasterLock; + engine->driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock; + engine->driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels; + engine->driver[PLATFORM_XBOX]->rasterToImage = rasterToImage; + + return o; +} + +static void* +driverClose(void *o, int32, int32) +{ + return o; +} + +void +registerPlatformPlugins(void) +{ + Driver::registerPlugin(PLATFORM_XBOX, 0, PLATFORM_XBOX, + driverOpen, driverClose); + registerNativeRaster(); +} + +void* +destroyNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_XBOX) + return object; + InstanceDataHeader *header = + (InstanceDataHeader*)geometry->instData; + geometry->instData = nil; + rwFree(header->vertexBuffer); + rwFree(header->begin); + rwFree(header->data); + rwFree(header); + return object; +} + +Stream* +readNativeData(Stream *stream, int32, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + uint32 vers; + uint32 platform; + if(!findChunk(stream, ID_STRUCT, nil, &vers)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_XBOX){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + if(vers < 0x35000){ + RWERROR((ERR_VERSION, vers)); + return nil; + } + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + geometry->instData = header; + header->platform = PLATFORM_XBOX; + + int32 size = stream->readI32(); + // The 0x18 byte are the resentryheader. + // We don't have it but it's used for alignment. + header->data = rwNewT(uint8, size + 0x18, MEMDUR_EVENT | ID_GEOMETRY); + uint8 *p = header->data+0x18+4; + stream->read8(p, size-4); + + header->size = size; + header->serialNumber = *(uint16*)p; p += 2; + header->numMeshes = *(uint16*)p; p += 2; + header->primType = *(uint32*)p; p += 4; + header->numVertices = *(uint32*)p; p += 4; + header->stride = *(uint32*)p; p += 4; + // RxXboxVertexFormat in 3.3 here + p += 4; // skip vertexBuffer pointer + header->vertexAlpha = *(bool32*)p; p += 4; + p += 8; // skip begin, end pointers + + InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + header->begin = inst; + for(int i = 0; i < header->numMeshes; i++){ + inst->minVert = *(uint32*)p; p += 4; + inst->numVertices = *(int32*)p; p += 4; + inst->numIndices = *(int32*)p; p += 4; + inst->indexBuffer = header->data + *(uint32*)p; p += 4; + p += 8; // skip material and vertexShader + inst->vertexShader = 0; + // pixelShader in 3.3 here + inst++; + } + header->end = inst; + + header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY); + stream->read8(header->vertexBuffer, header->stride*header->numVertices); + return stream; +} + +Stream* +writeNativeData(Stream *stream, int32 len, void *object, int32, int32) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + writeChunkHeader(stream, ID_STRUCT, len-12); + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_XBOX) + return stream; + stream->writeU32(PLATFORM_XBOX); + assert(rw::version >= 0x35000 && "can't write native Xbox data < 0x35000"); + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + + // we just fill header->data and write that + uint8 *p = header->data+0x18; + *(int32*)p = header->size; p += 4; + *(uint16*)p = header->serialNumber; p += 2; + *(uint16*)p = header->numMeshes; p += 2; + *(uint32*)p = header->primType; p += 4; + *(uint32*)p = header->numVertices; p += 4; + *(uint32*)p = header->stride; p += 4; + // RxXboxVertexFormat in 3.3 here + p += 4; // skip vertexBuffer pointer + *(bool32*)p = header->vertexAlpha; p += 4; + p += 8; // skip begin, end pointers + + InstanceData *inst = header->begin; + for(int i = 0; i < header->numMeshes; i++){ + *(uint32*)p = inst->minVert; p += 4; + *(int32*)p = inst->numVertices; p += 4; + *(int32*)p = inst->numIndices; p += 4; + *(uint32*)p = (uint8*)inst->indexBuffer - header->data; p += 4; + p += 8; // skip material and vertexShader + // pixelShader in 3.3 here + inst++; + } + + stream->write8(header->data+0x18, header->size); + stream->write8(header->vertexBuffer, header->stride*header->numVertices); + return stream; +} + +int32 +getSizeNativeData(void *object, int32, int32) +{ + Geometry *geometry = (Geometry*)object; + if(geometry->instData == nil || + geometry->instData->platform != PLATFORM_XBOX) + return 0; + InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; + return 12 + 4 + header->size + header->stride*header->numVertices; +} + +void +registerNativeDataPlugin(void) +{ + Geometry::registerPlugin(0, ID_NATIVEDATA, + nil, destroyNativeData, nil); + Geometry::registerPluginStream(ID_NATIVEDATA, + readNativeData, + writeNativeData, + getSizeNativeData); +} + +enum { + D3DPT_TRIANGLELIST = 5, + D3DPT_TRIANGLESTRIP = 6 +}; + +static void +instance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + // TODO: allow for REINSTANCE (or not, xbox can't render) + if(geo->instData) + return; + InstanceDataHeader *header = rwNewT(InstanceDataHeader, 1, MEMDUR_EVENT | ID_GEOMETRY); + MeshHeader *meshh = geo->meshHeader; + geo->instData = header; + header->platform = PLATFORM_XBOX; + + header->size = 0x24 + meshh->numMeshes*0x18 + 0x10; + Mesh *mesh = meshh->getMeshes(); + for(uint32 i = 0; i < meshh->numMeshes; i++) + header->size += (mesh++->numIndices*2 + 0xF) & ~0xF; + // The 0x18 byte are the resentryheader. + // We don't have it but it's used for alignment. + header->data = rwNewT(uint8, header->size + 0x18, MEMDUR_EVENT | ID_GEOMETRY); + header->serialNumber = meshh->serialNum; + header->numMeshes = meshh->numMeshes; + header->primType = meshh->flags == MeshHeader::TRISTRIP ? + D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; + header->numVertices = geo->numVertices; + header->vertexAlpha = 0; + // set by the instanceCB + header->stride = 0; + header->vertexBuffer = nil; + + InstanceData *inst = rwNewT(InstanceData, header->numMeshes, MEMDUR_EVENT | ID_GEOMETRY); + header->begin = inst; + mesh = meshh->getMeshes(); + uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF); + for(uint32 i = 0; i < header->numMeshes; i++){ + findMinVertAndNumVertices(mesh->indices, mesh->numIndices, + &inst->minVert, &inst->numVertices); + inst->numIndices = mesh->numIndices; + inst->indexBuffer = indexbuf; + memcpy(inst->indexBuffer, mesh->indices, inst->numIndices*sizeof(uint16)); + indexbuf += (inst->numIndices*2 + 0xF) & ~0xF; + inst->material = mesh->material; + inst->vertexShader = 0; // TODO? + mesh++; + inst++; + } + header->end = inst; + + pipe->instanceCB(geo, header); +} + +static void +uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) +{ + ObjPipeline *pipe = (ObjPipeline*)rwpipe; + Geometry *geo = atomic->geometry; + if((geo->flags & Geometry::NATIVE) == 0) + return; + assert(geo->instData != nil); + assert(geo->instData->platform == PLATFORM_XBOX); + + InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; + InstanceData *inst = header->begin; + Mesh *mesh = geo->meshHeader->getMeshes(); + // For some reason numIndices in mesh and instance data are not always equal + // And primitive isn't always correct either. Maybe some internal conversion... + geo->meshHeader->totalIndices = 0; + for(uint32 i = 0; i < header->numMeshes; i++){ + mesh[i].numIndices = inst[i].numIndices; + geo->meshHeader->totalIndices += mesh[i].numIndices; + } + geo->meshHeader->flags = header->primType == D3DPT_TRIANGLESTRIP ? + MeshHeader::TRISTRIP : 0; + + geo->numTriangles = geo->meshHeader->guessNumTriangles(); + geo->allocateData(); + geo->allocateMeshes(geo->meshHeader->numMeshes, geo->meshHeader->totalIndices, 0); + + mesh = geo->meshHeader->getMeshes(); + for(uint32 i = 0; i < header->numMeshes; i++){ + uint16 *indices = (uint16*)inst->indexBuffer; + memcpy(mesh->indices, indices, inst->numIndices*2); + mesh++; + inst++; + } + + pipe->uninstanceCB(geo, header); + geo->generateTriangles(); + geo->flags &= ~Geometry::NATIVE; + destroyNativeData(geo, 0, 0); +} + +void +ObjPipeline::init(void) +{ + this->rw::ObjPipeline::init(PLATFORM_XBOX); + this->impl.instance = xbox::instance; + this->impl.uninstance = xbox::uninstance; + this->instanceCB = nil; + this->uninstanceCB = nil; +} + +ObjPipeline* +ObjPipeline::create(void) +{ + ObjPipeline *pipe = rwNewT(ObjPipeline, 1, MEMDUR_GLOBAL); + pipe->init(); + return pipe; +} + +int v3dFormatMap[] = { + -1, VERT_BYTE3, VERT_SHORT3, VERT_NORMSHORT3, VERT_COMPNORM, VERT_FLOAT3 +}; + +int v2dFormatMap[] = { + -1, VERT_BYTE2, VERT_SHORT2, VERT_NORMSHORT2, VERT_COMPNORM, VERT_FLOAT2 +}; + +void +defaultInstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + uint32 *vertexFmt = getVertexFmt(geo); + if(*vertexFmt == 0) + *vertexFmt = makeVertexFmt(geo->flags, geo->numTexCoordSets); + header->stride = getVertexFmtStride(*vertexFmt); + header->vertexBuffer = rwNewT(uint8, header->stride*header->numVertices, MEMDUR_EVENT | ID_GEOMETRY); + uint8 *dst = (uint8*)header->vertexBuffer; + + uint32 fmt = *vertexFmt; + uint32 sel = fmt & 0xF; + instV3d(v3dFormatMap[sel], dst, geo->morphTargets[0].vertices, + header->numVertices, header->stride); + dst += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + + sel = (fmt >> 4) & 0xF; + if(sel){ + instV3d(v3dFormatMap[sel], dst, geo->morphTargets[0].normals, + header->numVertices, header->stride); + dst += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + } + + if(fmt & 0x1000000){ + header->vertexAlpha = instColor(VERT_ARGB, dst, geo->colors, + header->numVertices, header->stride); + dst += 4; + } + + for(int i = 0; i < 4; i++){ + sel = (fmt >> (i*4 + 8)) & 0xF; + if(sel == 0) + break; + instTexCoords(v2dFormatMap[sel], dst, geo->texCoords[i], + header->numVertices, header->stride); + dst += sel == 4 ? 4 : 2*vertexFormatSizes[sel]; + } + + if(fmt & 0xE000000) + assert(0 && "can't instance tangents or whatever it is"); +} + +void +defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + uint32 *vertexFmt = getVertexFmt(geo); + uint32 fmt = *vertexFmt; + assert(fmt != 0); + uint8 *src = (uint8*)header->vertexBuffer; + + uint32 sel = fmt & 0xF; + uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].vertices, src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + + sel = (fmt >> 4) & 0xF; + if(sel){ + uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].normals, src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; + } + + if(fmt & 0x1000000){ + uninstColor(VERT_ARGB, geo->colors, src, + header->numVertices, header->stride); + src += 4; + } + + for(int i = 0; i < 4; i++){ + sel = (fmt >> (i*4 + 8)) & 0xF; + if(sel == 0) + break; + uninstTexCoords(v2dFormatMap[sel], geo->texCoords[i], src, + header->numVertices, header->stride); + src += sel == 4 ? 4 : 2*vertexFormatSizes[sel]; + } +} + +ObjPipeline* +makeDefaultPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + return pipe; +} + +// Native Texture and Raster + +int32 nativeRasterOffset; + +static uint32 +calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format) +{ +#define D3DFMT_W11V11U10 65 + switch(format){ + default: + case D3DFMT_UNKNOWN: + return 0; + case D3DFMT_A8: + case D3DFMT_P8: + case D3DFMT_L8: + case D3DFMT_AL8: + case D3DFMT_LIN_A8: + case D3DFMT_LIN_AL8: + case D3DFMT_LIN_L8: + return width * height * depth; + case D3DFMT_R5G6B5: + case D3DFMT_R6G5B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + case D3DFMT_A4R4G4B4: + case D3DFMT_R4G4B4A4: + case D3DFMT_R5G5B5A1: + case D3DFMT_R8B8: + case D3DFMT_G8B8: + case D3DFMT_A8L8: + case D3DFMT_L16: + //case D3DFMT_V8U8: + //case D3DFMT_L6V5U5: + case D3DFMT_D16_LOCKABLE: + //case D3DFMT_D16: + case D3DFMT_F16: + case D3DFMT_YUY2: + case D3DFMT_UYVY: + case D3DFMT_LIN_A1R5G5B5: + case D3DFMT_LIN_A4R4G4B4: + case D3DFMT_LIN_G8B8: + case D3DFMT_LIN_R4G4B4A4: + case D3DFMT_LIN_R5G5B5A1: + case D3DFMT_LIN_R5G6B5: + case D3DFMT_LIN_R6G5B5: + case D3DFMT_LIN_R8B8: + case D3DFMT_LIN_X1R5G5B5: + case D3DFMT_LIN_A8L8: + case D3DFMT_LIN_L16: + //case D3DFMT_LIN_V8U8: + //case D3DFMT_LIN_L6V5U5: + case D3DFMT_LIN_D16: + case D3DFMT_LIN_F16: + return width * 2 * height * depth; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A8B8G8R8: + case D3DFMT_B8G8R8A8: + case D3DFMT_R8G8B8A8: + //case D3DFMT_X8L8V8U8: + //case D3DFMT_Q8W8V8U8: + case D3DFMT_V16U16: + case D3DFMT_D24S8: + case D3DFMT_F24S8: + case D3DFMT_LIN_A8B8G8R8: + case D3DFMT_LIN_A8R8G8B8: + case D3DFMT_LIN_B8G8R8A8: + case D3DFMT_LIN_R8G8B8A8: + case D3DFMT_LIN_X8R8G8B8: + case D3DFMT_LIN_V16U16: + //case D3DFMT_LIN_X8L8V8U8: + //case D3DFMT_LIN_Q8W8V8U8: + case D3DFMT_LIN_D24S8: + case D3DFMT_LIN_F24S8: + 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; + } +} + +static void* +createTexture(int32 width, int32 height, int32 numlevels, uint32 format) +{ + int32 w = width; + int32 h = height; + int32 size = 0; + for(int32 i = 0; i < numlevels; i++){ + size += calculateTextureSize(w, h, 1, format); + w /= 2; + if(w == 0) w = 1; + h /= 2; + if(h == 0) h = 1; + } + size = (size+3)&~3; + uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size, + MEMDUR_EVENT | ID_DRIVER); + RasterLevels *levels = (RasterLevels*)data; + data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1); + levels->numlevels = numlevels; + levels->format = format; + w = width; + h = height; + for(int32 i = 0; i < numlevels; i++){ + levels->levels[i].width = w; + levels->levels[i].height = h; + levels->levels[i].data = data; + levels->levels[i].size = calculateTextureSize(w, h, 1, format); + data += levels->levels[i].size; + w /= 2; + if(w == 0) w = 1; + h /= 2; + if(h == 0) h = 1; + } + return levels; +} + +struct RasterFormatInfo +{ + uint32 d3dformat; + int32 depth; + bool32 hasAlpha; + uint32 rwFormat; +}; + +// indexed directly by RW format +static RasterFormatInfo formatInfoRW[16] = { + { 0, 0, 0, 0}, + { D3DFMT_A1R5G5B5, 16, 1, Raster::C1555 }, + { D3DFMT_R5G6B5, 16, 0, Raster::C565 }, + { D3DFMT_A4R4G4B4, 16, 1, Raster::C4444 }, + { D3DFMT_L8, 8, 0, Raster::LUM8 }, + { D3DFMT_A8R8G8B8, 32, 1, Raster::C8888 }, + { D3DFMT_X8R8G8B8, 32, 0, Raster::C888 }, + { D3DFMT_UNKNOWN, 16, 0, Raster::D16 }, + { D3DFMT_UNKNOWN, 32, 0, Raster::D24 }, + { D3DFMT_UNKNOWN, 32, 0, Raster::D32 }, + { D3DFMT_X1R5G5B5, 16, 0, Raster::C555 } +}; + +static void +rasterSetFormat(Raster *raster) +{ + assert(raster->format != 0); // no default yet + + XboxRaster *natras = GETXBOXRASTEREXT(raster); + if(raster->format & (Raster::PAL4 | Raster::PAL8)){ + natras->format = D3DFMT_P8; + raster->depth = 8; + }else{ + natras->format = formatInfoRW[(raster->format >> 8) & 0xF].d3dformat; + raster->depth = formatInfoRW[(raster->format >> 8) & 0xF].depth; + } + natras->bpp = raster->depth/8; + natras->hasAlpha = formatInfoRW[(raster->format >> 8) & 0xF].hasAlpha; + raster->stride = raster->width&natras->bpp; +} + +static Raster* +rasterCreateTexture(Raster *raster) +{ + XboxRaster *natras = GETXBOXRASTEREXT(raster); + int32 levels; + + if(natras->format == D3DFMT_P8) + natras->palette = (uint8*)rwNew(4*256, MEMDUR_EVENT | ID_DRIVER); + levels = Raster::calculateNumLevels(raster->width, raster->height); + assert(natras->texture == nil); + natras->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? levels : 1, + natras->format); + if(natras->texture == nil){ + RWERROR((ERR_NOTEXTURE)); + return nil; + } + return raster; +} + +Raster* +rasterCreate(Raster *raster) +{ + rasterSetFormat(raster); + + Raster *ret = raster; + + // Dummy to use as subraster + if(raster->width == 0 || raster->height == 0){ + raster->flags |= Raster::DONTALLOCATE; + raster->stride = 0; + goto ret; + } + if(raster->flags & Raster::DONTALLOCATE) + goto ret; + + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + ret = rasterCreateTexture(raster); + break; + default: + RWERROR((ERR_INVRASTER)); + return nil; + } + +ret: + raster->originalWidth = raster->width; + raster->originalHeight = raster->height; + raster->originalStride = raster->stride; + raster->originalPixels = raster->pixels; + return ret; +} + +uint8* +rasterLock(Raster *raster, int32 level, int32 lockMode) +{ + XboxRaster *natras = GETXBOXRASTEREXT(raster); + + // check if already locked + if(raster->privateFlags & (Raster::PRIVATELOCK_READ|Raster::PRIVATELOCK_WRITE)) + return nil; + + RasterLevels *levels = (RasterLevels*)natras->texture; + raster->pixels = levels->levels[level].data; + raster->width = levels->levels[level].width; + raster->height = levels->levels[level].height; + raster->stride = raster->width*natras->bpp; + + if(lockMode & Raster::LOCKREAD) raster->privateFlags |= Raster::PRIVATELOCK_READ; + if(lockMode & Raster::LOCKWRITE) raster->privateFlags |= Raster::PRIVATELOCK_WRITE; + + return raster->pixels; +} + +void +rasterUnlock(Raster *raster, int32 level) +{ + raster->width = raster->originalWidth; + raster->height = raster->originalHeight; + raster->stride = raster->originalStride; + raster->pixels = raster->originalPixels; + + raster->privateFlags &= ~(Raster::PRIVATELOCK_READ|Raster::PRIVATELOCK_WRITE); +} + +int32 +rasterNumLevels(Raster *raster) +{ + XboxRaster *natras = GETXBOXRASTEREXT(raster); + RasterLevels *levels = (RasterLevels*)natras->texture; + return levels->numlevels; +} + +static void +unswizzle(uint8 *dst, uint8 *src, int32 w, int32 h, int32 bpp) +{ + uint32 maskU = 0; + uint32 maskV = 0; + int32 i = 1; + int32 j = 1; + int32 c; + do{ + c = 0; + if(i < w){ + maskU |= j; + j <<= 1; + c = j; + } + if(i < h){ + maskV |= j; + j <<= 1; + c = j; + } + i <<= 1; + }while(c); + int32 x, y, u, v; + v = 0; + for(y = 0; y < h; y++){ + u = 0; + for(x = 0; x < w; x++){ + memcpy(&dst[(y*w + x)*bpp], &src[(u|v)*bpp], bpp); + u = (u - maskU) & maskU; + } + v = (v - maskV) & maskV; + } +} + +Image* +rasterToImage(Raster *raster) +{ + int32 depth; + Image *image; + + bool unlock = false; + if(raster->pixels == nil){ + raster->lock(0, Raster::LOCKREAD); + unlock = true; + } + + XboxRaster *natras = GETXBOXRASTEREXT(raster); + if(natras->customFormat){ + int w = raster->width; + int h = raster->height; + // pixels are in the upper right corner + if(w < 4) w = 4; + if(h < 4) h = 4; + image = Image::create(w, h, 32); + image->allocate(); + uint8 *pix = raster->pixels; + switch(natras->format){ + case D3DFMT_DXT1: + image->setPixelsDXT(1, pix); + // TODO: is this correct? + if(!natras->hasAlpha) + image->removeMask(); + break; + case D3DFMT_DXT3: + image->setPixelsDXT(3, pix); + break; + case D3DFMT_DXT5: + image->setPixelsDXT(5, pix); + break; + default: + assert(0 && "unknown format"); + image->destroy(); + if(unlock) + raster->unlock(0); + return nil; + } + // fix it up again + image->width = raster->width; + image->height = raster->height; + + if(unlock) + raster->unlock(0); + return image; + } + + switch(raster->format & 0xF00){ + case Raster::C1555: + depth = 16; + break; + case Raster::C8888: + depth = 32; + break; + case Raster::C888: + depth = 24; + break; + case Raster::C555: + depth = 16; + break; + + default: + case Raster::C565: + case Raster::C4444: + case Raster::LUM8: + assert(0 && "unsupported raster format"); + } + int32 pallength = 0; + if((raster->format & Raster::PAL4) == Raster::PAL4){ + depth = 4; + pallength = 16; + }else if((raster->format & Raster::PAL8) == Raster::PAL8){ + depth = 8; + pallength = 256; + } + + image = Image::create(raster->width, raster->height, depth); + image->allocate(); + + if(pallength){ + uint8 *out = image->palette; + uint8 *in = (uint8*)natras->palette; + // bytes are BGRA unlike regular d3d! + for(int32 i = 0; i < pallength; i++){ + conv_BGRA8888_from_RGBA8888(out, in); + in += 4; + out += 4; + } + } + + uint8 *imgpixels = image->pixels; + uint8 *pixels = raster->pixels; + + // NB: + assert(image->bpp == (int)natras->bpp); + assert(image->stride == raster->stride); + unswizzle(imgpixels, pixels, image->width, image->height, image->bpp); + // Fix RGB order + uint8 tmp; + if(depth > 8) + for(int32 y = 0; y < image->height; y++){ + uint8 *imgrow = imgpixels; + // uint8 *rasrow = pixels; + for(int32 x = 0; x < image->width; x++){ + switch(raster->format & 0xF00){ + case Raster::C8888: + case Raster::C888: + tmp = imgrow[0]; + imgrow[0] = imgrow[2]; + imgrow[2] = tmp; + imgrow += image->bpp; + break; + } + } + imgpixels += image->stride; + // pixels += raster->stride; + } + image->compressPalette(); + + if(unlock) + raster->unlock(0); + + return image; +} + +int32 +getLevelSize(Raster *raster, int32 level) +{ + XboxRaster *ras = GETXBOXRASTEREXT(raster); + RasterLevels *levels = (RasterLevels*)ras->texture; + return levels->levels[level].size; +} + +static void* +createNativeRaster(void *object, int32 offset, int32) +{ + XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset); + raster->texture = nil; + raster->palette = nil; + raster->format = 0; + raster->hasAlpha = 0; + raster->customFormat = 0; + raster->unknownFlag = 0; + return object; +} + +static void* +destroyNativeRaster(void *object, int32, int32) +{ + // TODO: + return object; +} + +static void* +copyNativeRaster(void *dst, void *, int32 offset, int32) +{ + XboxRaster *raster = PLUGINOFFSET(XboxRaster, dst, offset); + raster->texture = nil; + raster->palette = nil; + raster->format = 0; + raster->hasAlpha = 0; + raster->unknownFlag = 0; + return dst; +} + +void +registerNativeRaster(void) +{ + nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster), + ID_RASTERXBOX, + createNativeRaster, + destroyNativeRaster, + copyNativeRaster); +} + +Texture* +readNativeTexture(Stream *stream) +{ + uint32 vers, platform; + if(!findChunk(stream, ID_STRUCT, nil, &vers)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_XBOX){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + if(vers < 0x34001){ + RWERROR((ERR_VERSION, vers)); + return nil; + } + Texture *tex = Texture::create(nil); + if(tex == nil) + return nil; + + + // Texture + tex->filterAddressing = stream->readU32(); + stream->read8(tex->name, 32); + stream->read8(tex->mask, 32); + +//if(strcmp(tex->name, "bluallu") == 0) +//__debugbreak(); + + // Raster + int32 format = stream->readI32(); + bool32 hasAlpha = stream->readI16(); + bool32 unknownFlag = stream->readI16(); + int32 width = stream->readU16(); + int32 height = stream->readU16(); + int32 depth = stream->readU8(); + int32 numLevels = stream->readU8(); + int32 type = stream->readU8(); + int32 compression = stream->readU8(); + int32 totalSize = stream->readI32(); + + // isn't this the cube map flag? + assert(unknownFlag == 0); + Raster *raster; + if(compression){ + raster = Raster::create(width, height, depth, format | type | Raster::DONTALLOCATE, PLATFORM_XBOX); + XboxRaster *ras = GETXBOXRASTEREXT(raster); + ras->format = compression; + ras->hasAlpha = hasAlpha; + ras->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? numLevels : 1, + ras->format); + ras->customFormat = 1; + raster->flags &= ~Raster::DONTALLOCATE; + }else + raster = Raster::create(width, height, depth, format | type, PLATFORM_XBOX); + XboxRaster *ras = GETXBOXRASTEREXT(raster); + tex->raster = raster; + + if(raster->format & Raster::PAL4) + stream->read8(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->read8(ras->palette, 4*256); + + // exploit the fact that mipmaps are allocated consecutively + uint8 *data = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); + stream->read8(data, totalSize); + raster->unlock(0); + + return tex; +} + +void +writeNativeTexture(Texture *tex, Stream *stream) +{ + int32 chunksize = getSizeNativeTexture(tex); + writeChunkHeader(stream, ID_STRUCT, chunksize-12); + stream->writeU32(PLATFORM_XBOX); + + // Texture + stream->writeU32(tex->filterAddressing); + stream->write8(tex->name, 32); + stream->write8(tex->mask, 32); + + // Raster + Raster *raster = tex->raster; + XboxRaster *ras = GETXBOXRASTEREXT(raster); + int32 numLevels = raster->getNumLevels(); + stream->writeI32(raster->format); + stream->writeI16(ras->hasAlpha); + stream->writeI16(ras->unknownFlag); + stream->writeU16(raster->width); + stream->writeU16(raster->height); + stream->writeU8(raster->depth); + stream->writeU8(numLevels); + stream->writeU8(raster->type); + stream->writeU8(ras->format); + + int32 totalSize = 0; + for(int32 i = 0; i < numLevels; i++) + totalSize += getLevelSize(tex->raster, i); + totalSize = (totalSize+3)&~3; + stream->writeI32(totalSize); + + if(raster->format & Raster::PAL4) + stream->write8(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->write8(ras->palette, 4*256); + + // exploit the fact that mipmaps are allocated consecutively + uint8 *data = raster->lock(0, Raster::LOCKREAD); + stream->write8(data, totalSize); + raster->unlock(0); +} + +uint32 +getSizeNativeTexture(Texture *tex) +{ + uint32 size = 12 + 72 + 16 + 4; + int32 levels = tex->raster->getNumLevels(); + for(int32 i = 0; i < levels; i++) + size += getLevelSize(tex->raster, i); + size = (size+3)&~3; + if(tex->raster->format & Raster::PAL4) + size += 4*32; + else if(tex->raster->format & Raster::PAL8) + size += 4*256; + return size; +} + +} +} diff --git a/src/d3d/xboxmatfx.cpp b/src/d3d/xboxmatfx.cpp new file mode 100644 index 0000000..a6b8718 --- /dev/null +++ b/src/d3d/xboxmatfx.cpp @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwxbox.h" + +namespace rw { +namespace xbox { + +static void* +matfxOpen(void *o, int32, int32) +{ + matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline(); + return o; +} + +static void* +matfxClose(void *o, int32, int32) +{ + ((ObjPipeline*)matFXGlobals.pipelines[PLATFORM_XBOX])->destroy(); + matFXGlobals.pipelines[PLATFORM_XBOX] = nil; + return o; +} + +void +initMatFX(void) +{ + Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX, + matfxOpen, matfxClose); +} + +ObjPipeline* +makeMatFXPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->pluginID = ID_MATFX; + pipe->pluginData = 0; + return pipe; +} + +} +} diff --git a/src/d3d/xboxskin.cpp b/src/d3d/xboxskin.cpp new file mode 100644 index 0000000..0ce5cba --- /dev/null +++ b/src/d3d/xboxskin.cpp @@ -0,0 +1,252 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwxbox.h" + +#define PLUGIN_ID ID_SKIN + +namespace rw { +namespace xbox { + +struct NativeSkin +{ + int32 table1[256]; // maps indices to bones + int32 table2[256]; // maps bones to indices + int32 numUsedBones; + void *vertexBuffer; + int32 stride; +}; + +Stream* +readNativeSkin(Stream *stream, int32, void *object, int32 offset) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + uint32 vers, platform; + if(!findChunk(stream, ID_STRUCT, nil, &vers)){ + RWERROR((ERR_CHUNK, "STRUCT")); + return nil; + } + platform = stream->readU32(); + if(platform != PLATFORM_XBOX){ + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + if(vers < 0x35000){ + RWERROR((ERR_VERSION, vers)); + return nil; + } + + Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN); + *PLUGINOFFSET(Skin*, geometry, offset) = skin; + + int32 numBones = stream->readI32(); + skin->init(numBones, 0, 0); + NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN); + skin->platformData = natskin; + stream->read32(natskin->table1, 256*sizeof(int32)); + stream->read32(natskin->table2, 256*sizeof(int32)); + natskin->numUsedBones = stream->readI32(); + skin->numWeights = stream->readI32(); + stream->seek(4); // skip pointer to vertexBuffer + natskin->stride = stream->readI32(); + int32 size = geometry->numVertices*natskin->stride; + natskin->vertexBuffer = rwNewT(uint8, size, MEMDUR_EVENT | ID_SKIN); + stream->read8(natskin->vertexBuffer, size); + stream->read32(skin->inverseMatrices, skin->numBones*64); + + readSkinSplitData(stream, skin); + return stream; +} + +Stream* +writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) +{ + ASSERTLITTLE; + Geometry *geometry = (Geometry*)object; + Skin *skin = *PLUGINOFFSET(Skin*, object, offset); + assert(skin->platformData); + assert(rw::version >= 0x35000 && "can't handle native xbox skin < 0x35000"); + NativeSkin *natskin = (NativeSkin*)skin->platformData; + + writeChunkHeader(stream, ID_STRUCT, len-12); + stream->writeU32(PLATFORM_XBOX); + stream->writeI32(skin->numBones); + stream->write32(natskin->table1, 256*sizeof(int32)); + stream->write32(natskin->table2, 256*sizeof(int32)); + stream->writeI32(natskin->numUsedBones); + stream->writeI32(skin->numWeights); + stream->writeU32(0xBADEAFFE); // pointer to vertexBuffer + stream->writeI32(natskin->stride); + stream->write8(natskin->vertexBuffer, + geometry->numVertices*natskin->stride); + stream->write32(skin->inverseMatrices, skin->numBones*64); + + writeSkinSplitData(stream, skin); + return stream; +} + +int32 +getSizeNativeSkin(void *object, int32 offset) +{ + Geometry *geometry = (Geometry*)object; + Skin *skin = *PLUGINOFFSET(Skin*, object, offset); + if(skin == nil) + return -1; + if(skin->platformData == nil) + return -1; + NativeSkin *natskin = (NativeSkin*)skin->platformData; + return 12 + 8 + 2*256*4 + 4*4 + + natskin->stride*geometry->numVertices + skin->numBones*64 + + skinSplitDataSize(skin); +} + +void +skinInstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + defaultInstanceCB(geo, header); + + Skin *skin = Skin::get(geo); + if(skin == nil) + return; + NativeSkin *natskin = rwNewT(NativeSkin, 1, MEMDUR_EVENT | ID_SKIN); + skin->platformData = natskin; + + natskin->numUsedBones = skin->numUsedBones; + memset(natskin->table1, 0xFF, sizeof(natskin->table1)); + memset(natskin->table2, 0x00, sizeof(natskin->table2)); + for(int32 i = 0; i < skin->numUsedBones; i++){ + natskin->table1[i] = skin->usedBones[i]; + natskin->table2[skin->usedBones[i]] = i; + } + + natskin->stride = 3*skin->numWeights; + uint8 *vbuf = rwNewT(uint8, header->numVertices*natskin->stride, MEMDUR_EVENT | ID_SKIN); + natskin->vertexBuffer = vbuf; + + int32 w[4]; + int sum; + float32 *weights = skin->weights; + uint8 *p = vbuf; + int32 numVertices = header->numVertices; + while(numVertices--){ + sum = 0; + for(int i = 1; i < skin->numWeights; i++){ + w[i] = (int32)(weights[i]*255.0f + 0.5f); + sum += w[i]; + } + w[0] = 255 - sum; + for(int i = 0; i < skin->numWeights; i++) + p[i] = w[i]; + p += natskin->stride; + weights += 4; + } + + numVertices = header->numVertices; + p = vbuf + skin->numWeights; + uint8 *indices = skin->indices; + uint16 *idx; + while(numVertices--){ + idx = (uint16*)p; + for(int i = 0; i < skin->numWeights; i++) + idx[i] = 3*natskin->table2[indices[i]]; + p += natskin->stride; + indices += 4; + } +} + +void +skinUninstanceCB(Geometry *geo, InstanceDataHeader *header) +{ + defaultUninstanceCB(geo, header); + + Skin *skin = Skin::get(geo); + if(skin == nil) + return; + NativeSkin *natskin = (NativeSkin*)skin->platformData; + + uint8 *data = skin->data; + float *invMats = skin->inverseMatrices; + skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices); + memcpy(skin->inverseMatrices, invMats, skin->numBones*64); + rwFree(data); + + for(int32 j = 0; j < skin->numUsedBones; j++) + skin->usedBones[j] = natskin->table1[j]; + + float *weights = skin->weights; + uint8 *indices = skin->indices; + uint8 *p = (uint8*)natskin->vertexBuffer; + int32 numVertices = header->numVertices; + float w[4]; + uint8 i[4]; + uint16 *ip; + while(numVertices--){ + w[0] = w[1] = w[2] = w[3] = 0.0f; + i[0] = i[1] = i[2] = i[3] = 0; + + for(int32 j = 0; j < skin->numWeights; j++) + w[j] = *p++/255.0f; + + ip = (uint16*)p; + for(int32 j = 0; j < skin->numWeights; j++){ + i[j] = natskin->table1[*ip++/3]; + if(w[j] == 0.0f) i[j] = 0; // clean up a bit + } + p = (uint8*)ip; + + for(int32 j = 0; j < 4; j++){ + *weights++ = w[j]; + *indices++ = i[j]; + } + } + + rwFree(natskin->vertexBuffer); + rwFree(natskin); +} + +static void* +skinOpen(void *o, int32, int32) +{ + skinGlobals.pipelines[PLATFORM_XBOX] = makeSkinPipeline(); + return o; +} + +static void* +skinClose(void *o, int32, int32) +{ + ((ObjPipeline*)skinGlobals.pipelines[PLATFORM_XBOX])->destroy(); + skinGlobals.pipelines[PLATFORM_XBOX] = nil; + return o; +} + +void +initSkin(void) +{ + Driver::registerPlugin(PLATFORM_XBOX, 0, ID_SKIN, + skinOpen, skinClose); +} + +ObjPipeline* +makeSkinPipeline(void) +{ + ObjPipeline *pipe = ObjPipeline::create(); + pipe->instanceCB = skinInstanceCB; + pipe->uninstanceCB = skinUninstanceCB; + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; + return pipe; +} + +} +} diff --git a/src/d3d/xboxvfmt.cpp b/src/d3d/xboxvfmt.cpp new file mode 100644 index 0000000..b6569dc --- /dev/null +++ b/src/d3d/xboxvfmt.cpp @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwxbox.h" + +namespace rw { +namespace xbox { + +static int32 vertexFmtOffset; + +uint32 vertexFormatSizes[6] = { + 0, 1, 2, 2, 4, 4 +}; + +uint32* +getVertexFmt(Geometry *g) +{ + return PLUGINOFFSET(uint32, g, vertexFmtOffset); +} + +uint32 +makeVertexFmt(int32 flags, uint32 numTexSets) +{ + if(numTexSets > 4) + numTexSets = 4; + uint32 fmt = 0x5; // FLOAT3 + if(flags & Geometry::NORMALS) + fmt |= 0x40; // NORMPACKED3 + for(uint32 i = 0; i < numTexSets; i++) + fmt |= 0x500 << i*4; // FLOAT2 + if(flags & Geometry::PRELIT) + fmt |= 0x1000000; // D3DCOLOR + return fmt; +} + +uint32 +getVertexFmtStride(uint32 fmt) +{ + uint32 stride = 0; + uint32 v = fmt & 0xF; + uint32 n = (fmt >> 4) & 0xF; + stride += v == 4 ? 4 : 3*vertexFormatSizes[v]; + stride += n == 4 ? 4 : 3*vertexFormatSizes[n]; + if(fmt & 0x1000000) + stride += 4; + for(int i = 0; i < 4; i++){ + uint32 t = (fmt >> (i*4 + 8)) & 0xF; + stride += t == 4 ? 4 : 2*vertexFormatSizes[t]; + } + if(fmt & 0xE000000) + stride += 8; + return stride; +} + +static void* +createVertexFmt(void *object, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, object, offset) = 0; + return object; +} + +static void* +copyVertexFmt(void *dst, void *src, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset); + return dst; +} + +static Stream* +readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + uint32 fmt = stream->readU32(); + *PLUGINOFFSET(uint32, object, offset) = fmt; + // TODO: ? create and attach "vertex shader" + return stream; +} + +static Stream* +writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + stream->writeI32(*PLUGINOFFSET(uint32, object, offset)); + return stream; +} + +static int32 +getSizeVertexFmt(void*, int32, int32) +{ + if(rw::platform != PLATFORM_XBOX) + return -1; + return 4; +} + +void +registerVertexFormatPlugin(void) +{ + vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT, + createVertexFmt, nil, copyVertexFmt); + Geometry::registerPluginStream(ID_VERTEXFMT, + readVertexFmt, + writeVertexFmt, + getSizeVertexFmt); +} + +} +} |
