mirror of
https://github.com/aap/librw.git
synced 2025-12-20 17:39:49 +00:00
worked on engine and d3ddriver
This commit is contained in:
@@ -15,9 +15,7 @@ namespace d3d {
|
||||
|
||||
bool32 isP8supported = 1;
|
||||
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DDevice9 *device = nil;
|
||||
#else
|
||||
#ifndef RW_D3D9
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
|
||||
((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
|
||||
@@ -186,7 +184,7 @@ createIndexBuffer(uint32 length)
|
||||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DIndexBuffer9 *ibuf;
|
||||
device->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
||||
d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
||||
return ibuf;
|
||||
#else
|
||||
return new uint8[length];
|
||||
@@ -227,7 +225,7 @@ createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
|
||||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DVertexBuffer9 *vbuf;
|
||||
device->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0);
|
||||
d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0);
|
||||
return vbuf;
|
||||
#else
|
||||
(void)fvf;
|
||||
@@ -270,7 +268,7 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
||||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DTexture9 *tex;
|
||||
device->CreateTexture(width, height, numlevels, 0,
|
||||
d3ddevice->CreateTexture(width, height, numlevels, 0,
|
||||
(D3DFORMAT)format, D3DPOOL_MANAGED, &tex, nil);
|
||||
return tex;
|
||||
#else
|
||||
|
||||
@@ -23,15 +23,15 @@ using namespace d3d;
|
||||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_D3D8]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_D3D8]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_D3D8]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_D3D8]->rasterNumLevels = rasterNumLevels;
|
||||
driver[PLATFORM_D3D8]->rasterFromImage = rasterFromImage;
|
||||
driver[PLATFORM_D3D8]->rasterToImage = rasterToImage;
|
||||
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]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_D3D8]->rasterToImage = rasterToImage;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
@@ -359,26 +359,26 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst)
|
||||
|
||||
uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
|
||||
instV3d(VERT_FLOAT3, dst,
|
||||
&geo->morphTargets[0].vertices[3*inst->minVert],
|
||||
&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[3*inst->minVert],
|
||||
&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[4*inst->minVert],
|
||||
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][2*inst->minVert],
|
||||
instTexCoords(VERT_FLOAT2, dst, &geo->texCoords[i][inst->minVert],
|
||||
inst->numVertices, inst->stride);
|
||||
dst += 8;
|
||||
}
|
||||
@@ -390,26 +390,26 @@ defaultUninstanceCB(Geometry *geo, InstanceData *inst)
|
||||
{
|
||||
uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
|
||||
uninstV3d(VERT_FLOAT3,
|
||||
&geo->morphTargets[0].vertices[3*inst->minVert],
|
||||
&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[3*inst->minVert],
|
||||
&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[4*inst->minVert], src,
|
||||
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][2*inst->minVert], src,
|
||||
uninstTexCoords(VERT_FLOAT2, &geo->texCoords[i][inst->minVert], src,
|
||||
inst->numVertices, inst->stride);
|
||||
src += 8;
|
||||
}
|
||||
@@ -481,7 +481,7 @@ readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d8.h"
|
||||
|
||||
@@ -23,28 +24,31 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
RawMatrix world;
|
||||
|
||||
d3d::lightingCB();
|
||||
|
||||
Geometry *geo = atomic->geometry;
|
||||
d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT));
|
||||
|
||||
Frame *f = atomic->getFrame();
|
||||
convMatrix(&world, f->getLTM());
|
||||
device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
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(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
|
||||
device->SetFVF(inst->vertexShader);
|
||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||
d3ddevice->SetFVF(inst->vertexShader);
|
||||
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
d3ddevice->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||
0, inst->numVertices, 0, numPrim);
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||
0, inst->numVertices, 0, numPrim);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,15 +31,15 @@ static VertexElement _d3ddec_end = {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0};
|
||||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_D3D9]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_D3D9]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_D3D9]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_D3D9]->rasterNumLevels = rasterNumLevels;
|
||||
driver[PLATFORM_D3D9]->rasterFromImage = rasterFromImage;
|
||||
driver[PLATFORM_D3D9]->rasterToImage = rasterToImage;
|
||||
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]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_D3D9]->rasterToImage = rasterToImage;
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ createVertexDeclaration(VertexElement *elements)
|
||||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DVertexDeclaration9 *decl = 0;
|
||||
device->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl);
|
||||
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl);
|
||||
return decl;
|
||||
#else
|
||||
int n = 0;
|
||||
@@ -122,7 +122,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
@@ -592,7 +592,7 @@ readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d9.h"
|
||||
|
||||
@@ -23,29 +24,32 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
RawMatrix world;
|
||||
|
||||
d3d::lightingCB();
|
||||
|
||||
Geometry *geo = atomic->geometry;
|
||||
d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT));
|
||||
|
||||
Frame *f = atomic->getFrame();
|
||||
convMatrix(&world, f->getLTM());
|
||||
device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
|
||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
|
||||
0, header->vertexStream[0].stride);
|
||||
device->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
|
||||
device->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
|
||||
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
|
||||
0, header->vertexStream[0].stride);
|
||||
d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
|
||||
d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
d3d::setTexture(0, inst->material->texture);
|
||||
d3d::setMaterial(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
inst->startIndex, inst->numPrimitives);
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
inst->startIndex, inst->numPrimitives);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,31 @@
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
|
||||
// cached RW render states
|
||||
static bool32 vertexAlpha;
|
||||
static bool32 textureAlpha;
|
||||
static uint32 srcblend, destblend;
|
||||
static uint32 zwrite;
|
||||
static uint32 ztest;
|
||||
static uint32 fogenable;
|
||||
static RGBA fogcolor;
|
||||
static uint32 alphafunc;
|
||||
static uint32 alpharef;
|
||||
|
||||
|
||||
#define MAXNUMSTATES D3DRS_BLENDOPALPHA
|
||||
#define MAXNUMSTAGES 8
|
||||
#define MAXNUMTEXSTATES D3DTSS_CONSTANT
|
||||
@@ -41,10 +56,13 @@ static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
|
||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||
|
||||
// TODO: not only rasters, make a struct
|
||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
||||
|
||||
static D3DMATERIAL9 d3dmaterial;
|
||||
|
||||
// D3D render state
|
||||
|
||||
void
|
||||
setRenderState(uint32 state, uint32 value)
|
||||
{
|
||||
@@ -81,7 +99,7 @@ flushCache(void)
|
||||
v = stateCache[s].value;
|
||||
stateCache[s].dirty = 0;
|
||||
if(d3dStates[s] != v){
|
||||
device->SetRenderState((D3DRENDERSTATETYPE)s, v);
|
||||
d3ddevice->SetRenderState((D3DRENDERSTATETYPE)s, v);
|
||||
d3dStates[s] = v;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +110,7 @@ flushCache(void)
|
||||
v = textureStageStateCache[t][s].value;
|
||||
textureStageStateCache[t][s].dirty = 0;
|
||||
if(d3dTextureStageStates[t][s] != v){
|
||||
device->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
|
||||
d3ddevice->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
|
||||
d3dTextureStageStates[t][s] = v;
|
||||
}
|
||||
}
|
||||
@@ -103,22 +121,154 @@ void
|
||||
setSamplerState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(d3dSamplerStates[type][stage] != value){
|
||||
device->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
|
||||
d3ddevice->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
|
||||
d3dSamplerStates[type][stage] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// RW render state
|
||||
|
||||
static void
|
||||
setVertexAlpha(bool32 enable)
|
||||
{
|
||||
if(vertexAlpha != enable){
|
||||
if(!textureAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, enable);
|
||||
setRenderState(D3DRS_ALPHATESTENABLE, enable);
|
||||
}
|
||||
vertexAlpha = enable;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 blendMap[] = {
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_SRCCOLOR,
|
||||
D3DBLEND_INVSRCCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA,
|
||||
D3DBLEND_DESTCOLOR,
|
||||
D3DBLEND_INVDESTCOLOR,
|
||||
D3DBLEND_SRCALPHASAT
|
||||
};
|
||||
|
||||
uint32 alphafuncMap[] = {
|
||||
D3DCMP_ALWAYS,
|
||||
D3DCMP_GREATEREQUAL,
|
||||
D3DCMP_LESS
|
||||
};
|
||||
|
||||
static void
|
||||
setRwRenderState(int32 state, uint32 value)
|
||||
{
|
||||
uint32 bval = value ? TRUE : FALSE;
|
||||
switch(state){
|
||||
case VERTEXALPHA:
|
||||
setVertexAlpha(bval);
|
||||
break;
|
||||
case SRCBLEND:
|
||||
if(srcblend != value){
|
||||
srcblend = value;
|
||||
setRenderState(D3DRS_SRCBLEND, blendMap[value]);
|
||||
}
|
||||
break;
|
||||
case DESTBLEND:
|
||||
if(destblend != value){
|
||||
destblend = value;
|
||||
setRenderState(D3DRS_DESTBLEND, blendMap[value]);
|
||||
}
|
||||
break;
|
||||
case ZTESTENABLE:
|
||||
if(ztest != bval){
|
||||
ztest = bval;
|
||||
setRenderState(D3DRS_ZENABLE, ztest);
|
||||
}
|
||||
break;
|
||||
case ZWRITEENABLE:
|
||||
if(zwrite != bval){
|
||||
zwrite = bval;
|
||||
setRenderState(D3DRS_ZWRITEENABLE, zwrite);
|
||||
}
|
||||
break;
|
||||
case FOGENABLE:
|
||||
if(fogenable != bval){
|
||||
fogenable = bval;
|
||||
setRenderState(D3DRS_FOGENABLE, fogenable);
|
||||
};
|
||||
break;
|
||||
case FOGCOLOR:{
|
||||
RGBA c = *(RGBA*)&value;
|
||||
if(!equal(fogcolor, c)){
|
||||
fogcolor = c;
|
||||
setRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(c.red, c.green, c.blue, c.alpha));
|
||||
}} break;
|
||||
case ALPHATESTFUNC:
|
||||
if(alphafunc != value){
|
||||
alphafunc = value;
|
||||
setRenderState(D3DRS_ALPHAFUNC, alphafuncMap[alphafunc]);
|
||||
}
|
||||
break;
|
||||
case ALPHATESTREF:
|
||||
if(alpharef != value){
|
||||
alpharef = value;
|
||||
setRenderState(D3DRS_ALPHAREF, alpharef);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
getRwRenderState(int32 state)
|
||||
{
|
||||
switch(state){
|
||||
case VERTEXALPHA:
|
||||
return vertexAlpha;
|
||||
case SRCBLEND:
|
||||
return srcblend;
|
||||
case DESTBLEND:
|
||||
return destblend;
|
||||
case ZTESTENABLE:
|
||||
return ztest;
|
||||
case ZWRITEENABLE:
|
||||
return zwrite;
|
||||
case FOGENABLE:
|
||||
return fogenable;
|
||||
case FOGCOLOR:
|
||||
return *(uint32*)&fogcolor;
|
||||
case ALPHATESTFUNC:
|
||||
return alphafunc;
|
||||
case ALPHATESTREF:
|
||||
return alpharef;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
setRasterStage(uint32 stage, Raster *raster)
|
||||
{
|
||||
bool32 alpha;
|
||||
D3dRaster *d3draster = nil;
|
||||
if(raster != d3dRaster[stage]){
|
||||
d3dRaster[stage] = raster;
|
||||
if(raster){
|
||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||
device->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
}else
|
||||
device->SetTexture(stage, nil);
|
||||
d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
alpha = d3draster->hasAlpha;
|
||||
}else{
|
||||
d3ddevice->SetTexture(stage, nil);
|
||||
alpha = 0;
|
||||
}
|
||||
if(stage == 0){
|
||||
if(textureAlpha != alpha){
|
||||
textureAlpha = alpha;
|
||||
if(!vertexAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, alpha);
|
||||
setRenderState(D3DRS_ALPHATESTENABLE, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,19 +323,19 @@ setMaterial(Material *mat)
|
||||
d3dmaterial.Ambient.g != mat9.Ambient.g ||
|
||||
d3dmaterial.Ambient.b != mat9.Ambient.b ||
|
||||
d3dmaterial.Ambient.a != mat9.Ambient.a){
|
||||
device->SetMaterial(&mat9);
|
||||
d3ddevice->SetMaterial(&mat9);
|
||||
d3dmaterial = mat9;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
beginUpdate(Camera *cam)
|
||||
{
|
||||
float view[16], proj[16];
|
||||
|
||||
// View Matrix
|
||||
Matrix inv;
|
||||
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
|
||||
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;
|
||||
@@ -204,7 +354,7 @@ beginUpdate(Camera *cam)
|
||||
view[13] = inv.pos.y;
|
||||
view[14] = inv.pos.z;
|
||||
view[15] = 1.0f;
|
||||
device->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
|
||||
d3ddevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
|
||||
|
||||
// Projection Matrix
|
||||
float32 invwx = 1.0f/cam->viewWindow.x;
|
||||
@@ -237,15 +387,176 @@ beginUpdate(Camera *cam)
|
||||
proj[15] = 1.0f;
|
||||
}
|
||||
proj[14] = -cam->nearPlane*proj[10];
|
||||
device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
|
||||
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);
|
||||
|
||||
// TODO: figure out when to call this
|
||||
d3ddevice->BeginScene();
|
||||
}
|
||||
|
||||
void
|
||||
initializeRender(void)
|
||||
static void
|
||||
endUpdate(Camera *cam)
|
||||
{
|
||||
engine->beginUpdate = beginUpdate;
|
||||
// TODO: figure out when to call this
|
||||
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;
|
||||
D3DCOLOR c = D3DCOLOR_RGBA(col->red, col->green, col->blue, col->alpha);
|
||||
d3ddevice->Clear(0, 0, mode, c, 1.0f, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
showRaster(Raster *raster)
|
||||
{
|
||||
// TODO: do this properly!
|
||||
d3ddevice->Present(nil, nil, 0, nil);
|
||||
}
|
||||
|
||||
// taken from Frank Luna's d3d9 book
|
||||
static int
|
||||
startD3D(EngineStartParams *params)
|
||||
{
|
||||
HWND win = params->window;
|
||||
bool windowed = true;
|
||||
|
||||
HRESULT hr = 0;
|
||||
IDirect3D9 *d3d9 = 0;
|
||||
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if(!d3d9){
|
||||
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
|
||||
int vp = 0;
|
||||
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
|
||||
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||||
else
|
||||
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(win, &rect);
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3dpp.BackBufferWidth = width;
|
||||
d3dpp.BackBufferHeight = height;
|
||||
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = win;
|
||||
d3dpp.Windowed = windowed;
|
||||
d3dpp.EnableAutoDepthStencil = true;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
IDirect3DDevice9 *dev;
|
||||
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, win,
|
||||
vp, &d3dpp, &dev);
|
||||
if(FAILED(hr)){
|
||||
// try again using a 16-bit depth buffer
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
|
||||
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
|
||||
win, vp, &d3dpp, &dev);
|
||||
|
||||
if(FAILED(hr)){
|
||||
RWERROR((ERR_GENERAL, "CreateDevice() failed"));
|
||||
d3d9->Release();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
d3d9->Release();
|
||||
d3d::d3ddevice = dev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
stopD3D(void)
|
||||
{
|
||||
d3d::d3ddevice->Release();
|
||||
d3d::d3ddevice = nil;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
initD3D(void)
|
||||
{
|
||||
// TODO: do some real stuff here
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||
alphafunc = ALPHAGREATEREQUAL;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10);
|
||||
alpharef = 10;
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
fogenable = 0;
|
||||
d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
|
||||
// TODO: more fog stuff
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
srcblend = BLENDSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
destblend = BLENDINVSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
|
||||
vertexAlpha = 0;
|
||||
textureAlpha = 0;
|
||||
|
||||
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);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
switch(req){
|
||||
case DEVICESTART:
|
||||
return startD3D((EngineStartParams*)arg0);
|
||||
case DEVICEINIT:
|
||||
return initD3D();
|
||||
case DEVICESTOP:
|
||||
return stopD3D();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Device renderdevice = {
|
||||
0.0f, 1.0f,
|
||||
d3d::beginUpdate,
|
||||
d3d::endUpdate,
|
||||
d3d::clearCamera,
|
||||
d3d::showRaster,
|
||||
d3d::setRwRenderState,
|
||||
d3d::getRwRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
d3d::deviceSystem,
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
70
src/d3d/d3drender.cpp
Normal file
70
src/d3d/d3drender.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#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
|
||||
|
||||
void
|
||||
lightingCB(void)
|
||||
{
|
||||
World *world;
|
||||
RGBAf ambLight = { 0.0, 0.0, 0.0, 1.0 };
|
||||
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;
|
||||
int n = 0;
|
||||
|
||||
world = (World*)engine->currentWorld;
|
||||
// only unpositioned lights right now
|
||||
FORLIST(lnk, world->directionalLights){
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
if(l->getType() == Light::DIRECTIONAL){
|
||||
if(n >= MAX_LIGHTS)
|
||||
continue;
|
||||
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
|
||||
light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at;
|
||||
d3ddevice->SetLight(n, &light);
|
||||
d3ddevice->LightEnable(n, TRUE);
|
||||
n++;
|
||||
}else if(l->getType() == Light::AMBIENT){
|
||||
ambLight.red += l->color.red;
|
||||
ambLight.green += l->color.green;
|
||||
ambLight.blue += l->color.blue;
|
||||
}
|
||||
}
|
||||
for(; n < MAX_LIGHTS; n++)
|
||||
d3ddevice->LightEnable(n, FALSE);
|
||||
convColor(&amb, &ambLight);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,23 @@
|
||||
#endif
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
void initializeRender(void);
|
||||
#ifdef RW_D3D9
|
||||
struct EngineStartParams
|
||||
{
|
||||
HWND window;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace d3d {
|
||||
|
||||
extern bool32 isP8supported;
|
||||
|
||||
#ifdef RW_D3D9
|
||||
extern IDirect3DDevice9 *device;
|
||||
extern IDirect3DDevice9 *d3ddevice;
|
||||
extern Device renderdevice;
|
||||
|
||||
void lightingCB(void);
|
||||
#else
|
||||
enum {
|
||||
D3DLOCK_NOSYSLOCK = 0, // ignored
|
||||
|
||||
@@ -21,13 +21,13 @@ namespace xbox {
|
||||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_XBOX]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_XBOX]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_XBOX]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels;
|
||||
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;
|
||||
// TODO: from image
|
||||
|
||||
return o;
|
||||
@@ -71,7 +71,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
uint32 vers;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
@@ -622,7 +622,7 @@ readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 vers, platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
||||
@@ -35,7 +35,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers, platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
||||
Reference in New Issue
Block a user