implemented im3d for gl3 and d3d

This commit is contained in:
aap
2017-08-29 10:12:56 +02:00
parent b7f643a632
commit d00ab2f526
41 changed files with 1447 additions and 761 deletions

View File

@@ -18,42 +18,6 @@ namespace rw {
namespace d3d8 {
using namespace d3d;
// Skin
static void*
skinOpen(void *o, int32, int32)
{
skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
// MatFX
static void*
matfxOpen(void *o, int32, int32)
{

View File

@@ -41,6 +41,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
else
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
d3ddevice->SetFVF(inst->vertexShader);
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);

54
src/d3d/d3d8skin.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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)
{
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
}
}

View File

@@ -18,42 +18,6 @@ namespace rw {
namespace d3d9 {
using namespace d3d;
// Skin
static void*
skinOpen(void *o, int32, int32)
{
skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
// MatFX
static void*
matfxOpen(void *o, int32, int32)
{

View File

@@ -46,6 +46,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
else
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
d3d::flushCache();
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
0, inst->numVertices,

54
src/d3d/d3d9skin.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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 "rwd3d9.h"
namespace rw {
namespace d3d9 {
using namespace d3d;
static void*
skinOpen(void *o, int32, int32)
{
skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
}
}

View File

@@ -6,9 +6,10 @@
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwerror.h"
#include "../rwrender.h"
#include "../rwengine.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3dimpl.h"
@@ -427,7 +428,7 @@ showRaster(Raster *raster)
// taken from Frank Luna's d3d9 book
static int
startD3D(EngineStartParams *params)
openD3D(EngineStartParams *params)
{
HWND win = params->window;
bool windowed = true;
@@ -491,7 +492,7 @@ startD3D(EngineStartParams *params)
}
static int
stopD3D(void)
closeD3D(void)
{
d3d::d3ddevice->Release();
d3d::d3ddevice = nil;
@@ -531,10 +532,19 @@ initD3D(void)
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
openIm2D();
openIm3D();
return 1;
}
static int
termD3D(void)
{
closeIm3D();
closeIm2D();
return 1;
}
static int
finalizeD3D(void)
{
@@ -545,14 +555,18 @@ static int
deviceSystem(DeviceReq req, void *arg0)
{
switch(req){
case DEVICESTART:
return startD3D((EngineStartParams*)arg0);
case DEVICEOPEN:
return openD3D((EngineStartParams*)arg0);
case DEVICECLOSE:
return closeD3D();
case DEVICEINIT:
return initD3D();
case DEVICETERM:
return termD3D();
case DEVICEFINALIZE:
return finalizeD3D();
case DEVICESTOP:
return stopD3D();
}
return 1;
}
@@ -566,6 +580,9 @@ Device renderdevice = {
d3d::setRwRenderState,
d3d::getRwRenderState,
d3d::im2DRenderIndexedPrimitive,
d3d::im3DTransform,
d3d::im3DRenderIndexed,
d3d::im3DEnd,
d3d::deviceSystem,
};

View File

@@ -48,6 +48,14 @@ openIm2D(void)
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
}
void
closeIm2D(void)
{
deleteObject(im2ddecl);
deleteObject(im2dvertbuf);
deleteObject(im2dindbuf);
}
void
im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices)
@@ -97,6 +105,103 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
0, primCount);
}
// Im3D
static IDirect3DVertexDeclaration9 *im3ddecl;
static IDirect3DVertexBuffer9 *im3dvertbuf;
static IDirect3DIndexBuffer9 *im3dindbuf;
static int32 num3DVertices;
void
openIm3D(void)
{
D3DVERTEXELEMENT9 elements[4] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 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()
};
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im3ddecl);
im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, D3DPOOL_MANAGED);
im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
}
void
closeIm3D(void)
{
deleteObject(im3ddecl);
deleteObject(im3dvertbuf);
deleteObject(im3dindbuf);
}
void
im3DTransform(void *vertices, int32 numVertices, Matrix *world)
{
RawMatrix d3dworld;
d3d::setRenderState(D3DRS_LIGHTING, 0);
if(world == nil){
Matrix ident;
ident.setIdentity();
world = &ident;
}
convMatrix(&d3dworld, world);
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&d3dworld);
uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_NOSYSLOCK);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex));
unlockVertices(im3dvertbuf);
d3ddevice->SetStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex));
d3ddevice->SetVertexDeclaration(im3ddecl);
num3DVertices = numVertices;
}
void
im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
{
uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), 0);
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
unlockIndices(im3dindbuf);
d3d::setTexture(0, engine->imtexture);
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;
}
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
0, num3DVertices,
0, primCount);
}
void
im3DEnd(void)
{
}
#endif
}
}

View File

@@ -22,6 +22,22 @@ extern Device renderdevice;
void lightingCB(void);
struct Im3DVertex
{
V3d position;
D3DCOLOR 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 setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); }
RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF,
this->color & 0xFF, this->color>>24 & 0xFF); }
void setU(float32 u) { this->u = u; }
void setV(float32 v) { this->v = v; }
};
struct Im2DVertex
{
float32 x, y, z;

View File

@@ -3,8 +3,15 @@ namespace d3d {
#ifdef RW_D3D9
void openIm2D(void);
void closeIm2D(void);
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);
void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices);
void im3DEnd(void);
#endif
void rasterCreate(Raster *raster);

51
src/d3d/xboxmatx.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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)
{
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
}
}

View File

@@ -13,13 +13,11 @@
#include "../rwplugins.h"
#include "rwxbox.h"
#define PLUGIN_ID ID_SKIN // yeah right....
#define PLUGIN_ID ID_SKIN
namespace rw {
namespace xbox {
// Skin
struct NativeSkin
{
int32 table1[256]; // maps indices to bones
@@ -246,135 +244,5 @@ makeSkinPipeline(void)
return pipe;
}
// MatFX
static void*
matfxOpen(void *o, int32, int32)
{
matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline();
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
// Vertex Format
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);
}
}
}

115
src/d3d/xboxvfmt.cpp Normal file
View File

@@ -0,0 +1,115 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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);
}
}
}