Merge branch 'master' of github.com:aap/librw

This commit is contained in:
aap
2017-08-21 14:40:23 +02:00
67 changed files with 5108 additions and 807 deletions

43
src/base.cpp Normal file → Executable file
View File

@@ -261,6 +261,7 @@ Matrix::translate(V3d *translation, CombineOp op)
Matrix tmp;
Matrix trans = identMat;
trans.pos = *translation;
trans.flags &= ~IDENTITY;
switch(op){
case COMBINEREPLACE:
*this = trans;
@@ -301,6 +302,26 @@ Matrix::scale(V3d *scale, CombineOp op)
return this;
}
Matrix*
Matrix::transform(Matrix *mat, CombineOp op)
{
Matrix tmp;
switch(op){
case COMBINEREPLACE:
*this = *mat;
break;
case COMBINEPRECONCAT:
mult(&tmp, mat, this);
*this = tmp;
break;
case COMBINEPOSTCONCAT:
mult(&tmp, this, mat);
*this = tmp;
break;
}
return this;
}
void
Matrix::lookAt(const V3d &dir, const V3d &up)
{
@@ -457,28 +478,12 @@ Matrix::orthogonalError(void)
float32
Matrix::identityError(void)
{
V3d r { right.x-1.0f, right.y, right.z };
V3d u { up.x, up.y-1.0f, up.z };
V3d a { at.x, at.y, at.z-1.0f };
V3d r = { right.x-1.0f, right.y, right.z };
V3d u = { up.x, up.y-1.0f, up.z };
V3d a = { at.x, at.y, at.z-1.0f };
return dot(r,r) + dot(u,u) + dot(a,a) + dot(pos,pos);
}
#if 0
bool32
Matrix::isIdentity(void)
{
return matrixIsIdentity((float32*)this);
}
void
Matrix::transpose(Matrix *m1, Matrix *m2)
{
matrixTranspose((float32*)m1, (float32*)m2);
}
#endif
#define PSEP_C '/'
#define PSEP_S "/"
#ifndef _WIN32

View File

@@ -10,3 +10,11 @@ ECODE(ERR_VERSION,
"Unsupported version %X")
ECODE(ERR_PLATFORM,
"Unsupported platform %d")
ECODE(ERR_ENGINEINIT,
"Engine could not be initialized")
ECODE(ERR_ENGINEOPEN,
"Engine could not be opened")
ECODE(ERR_ENGINESTART,
"Engine could not be started")
ECODE(ERR_INVRASTER,
"Invalid raster format")

75
src/camera.cpp Normal file → Executable file
View File

@@ -12,18 +12,20 @@
namespace rw {
PluginList Camera::s_plglist = { sizeof(Camera), sizeof(Camera), nil, nil };
void
defaultBeginUpdateCB(Camera *cam)
{
engine->currentCamera = cam;
Frame::syncDirty();
engine->beginUpdate(cam);
engine->device.beginUpdate(cam);
}
void
defaultEndUpdateCB(Camera *cam)
{
engine->endUpdate(cam);
engine->device.endUpdate(cam);
}
static void
@@ -182,7 +184,21 @@ cameraSync(ObjectWithFrame *obj)
* and to clip space are handled by separate matrices there.
* On these platforms the two matrices are built in the platform's
* beginUpdate function.
* On the PS2 the 1/2 translation/shear is removed again on the VU1.
* On the PS2 the z- and w-rows are the same and the
* 1/2 translation/shear is removed again on the VU1 by
* subtracting the w-row/2 from the x- and y-rows.
*
* perspective:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 1 0
*
* parallel:
* 1/2w 0 ox/2w -ox/2w
* 0 -1/2h -oy/2h oy/2h
* 0 0 1 0
* 0 0 0 1
*
* RW builds this matrix directly without using explicit
* inversion and matrix multiplication.
@@ -191,8 +207,8 @@ cameraSync(ObjectWithFrame *obj)
Camera *cam = (Camera*)obj;
Matrix inv, proj;
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
float32 xscl = 2.0f/cam->viewWindow.x;
float32 yscl = 2.0f/cam->viewWindow.y;
float32 xscl = 1.0f/(2.0f*cam->viewWindow.x);
float32 yscl = 1.0f/(2.0f*cam->viewWindow.y);
proj.flags = 0;
proj.right.x = xscl;
@@ -315,7 +331,14 @@ Camera::destroy(void)
void
Camera::clear(RGBA *col, uint32 mode)
{
engine->clearCamera(this, col, mode);
engine->device.clearCamera(this, col, mode);
}
void
Camera::showRaster(void)
{
// TODO: camera raster
engine->device.showRaster(nil);
}
void
@@ -323,8 +346,8 @@ calczShiftScale(Camera *cam)
{
float32 n = cam->nearPlane;
float32 f = cam->farPlane;
float32 N = engine->zNear;
float32 F = engine->zFar;
float32 N = engine->device.zNear;
float32 F = engine->device.zFar;
// RW does this
N += (F - N)/10000.0f;
F -= (F - N)/10000.0f;
@@ -342,6 +365,8 @@ Camera::setNearPlane(float32 near)
{
this->nearPlane = near;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
@@ -349,6 +374,32 @@ Camera::setFarPlane(float32 far)
{
this->farPlane = far;
calczShiftScale(this);
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewWindow(const V2d *window)
{
this->viewWindow = *window;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setViewOffset(const V2d *offset)
{
this->viewOffset = *offset;
if(this->getFrame())
this->getFrame()->updateObjects();
}
void
Camera::setProjection(int32 proj)
{
this->projection = proj;
if(this->getFrame())
this->getFrame()->updateObjects();
}
int32
@@ -424,10 +475,12 @@ Camera::streamGetSize(void)
void
Camera::setFOV(float32 fov, float32 ratio)
{
V2d v;
float32 a = tan(fov*3.14159f/360.0f);
this->viewWindow.x = a;
this->viewWindow.y = a/ratio;
this->viewOffset.set(0.0f, 0.0f);
v.set(a, a/ratio);
this->setViewWindow(&v);
v.set(0.0f, 0.0f);
this->setViewOffset(&v);
}
}

View File

@@ -13,6 +13,9 @@
namespace rw {
PluginList Clump::s_plglist = { sizeof(Clump), sizeof(Clump), nil, nil };
PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil };
//
// Clump
//
@@ -523,7 +526,7 @@ Atomic::getPipeline(void)
{
return this->pipeline ?
this->pipeline :
driver[platform]->defaultPipeline;
engine->driver[platform]->defaultPipeline;
}
void

View File

@@ -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

View File

@@ -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();

View File

@@ -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++;
}
}

View File

@@ -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();

View File

@@ -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++;
}
}

562
src/d3d/d3ddevice.cpp Executable file
View File

@@ -0,0 +1,562 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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
#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET
static int32 numDirtyStates;
static uint32 dirtyStates[MAXNUMSTATES];
static struct {
uint32 value;
bool32 dirty;
} stateCache[MAXNUMSTATES];
static uint32 d3dStates[MAXNUMSTATES];
static int32 numDirtyTextureStageStates;
static struct {
uint32 stage;
uint32 type;
} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES];
static struct {
uint32 value;
bool32 dirty;
} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES];
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)
{
if(stateCache[state].value != value){
stateCache[state].value = value;
if(!stateCache[state].dirty){
stateCache[state].dirty = 1;
dirtyStates[numDirtyStates++] = state;
}
}
}
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
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;
}
void
setSamplerState(uint32 stage, uint32 type, uint32 value)
{
if(d3dSamplerStates[type][stage] != 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);
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);
}
}
}
}
}
void
setTexture(uint32 stage, Texture *tex)
{
static DWORD filternomip[] = {
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
D3DTEXF_POINT, D3DTEXF_LINEAR,
D3DTEXF_POINT, D3DTEXF_LINEAR
};
static DWORD wrap[] = {
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
};
if(tex == nil){
setRasterStage(stage, nil);
return;
}
if(tex->raster){
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
}
setRasterStage(stage, tex->raster);
}
void
setMaterial(Material *mat)
{
D3DMATERIAL9 mat9;
D3DCOLORVALUE black = { 0, 0, 0, 0 };
float ambmult = mat->surfaceProps.ambient/255.0f;
float diffmult = mat->surfaceProps.diffuse/255.0f;
mat9.Ambient.r = mat->color.red*ambmult;
mat9.Ambient.g = mat->color.green*ambmult;
mat9.Ambient.b = mat->color.blue*ambmult;
mat9.Ambient.a = mat->color.alpha*ambmult;
mat9.Diffuse.r = mat->color.red*diffmult;
mat9.Diffuse.g = mat->color.green*diffmult;
mat9.Diffuse.b = mat->color.blue*diffmult;
mat9.Diffuse.a = mat->color.alpha*diffmult;
mat9.Power = 0.0f;
mat9.Emissive = black;
mat9.Specular = black;
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){
d3ddevice->SetMaterial(&mat9);
d3dmaterial = mat9;
}
}
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;
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];
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();
}
static void
endUpdate(Camera *cam)
{
// 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
}
}

View File

@@ -1,251 +0,0 @@
#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
#define MAXNUMSTATES D3DRS_BLENDOPALPHA
#define MAXNUMSTAGES 8
#define MAXNUMTEXSTATES D3DTSS_CONSTANT
#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET
static int32 numDirtyStates;
static uint32 dirtyStates[MAXNUMSTATES];
static struct {
uint32 value;
bool32 dirty;
} stateCache[MAXNUMSTATES];
static uint32 d3dStates[MAXNUMSTATES];
static int32 numDirtyTextureStageStates;
static struct {
uint32 stage;
uint32 type;
} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES];
static struct {
uint32 value;
bool32 dirty;
} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES];
static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES];
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
static Raster *d3dRaster[MAXNUMSTAGES];
static D3DMATERIAL9 d3dmaterial;
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
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
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){
device->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){
device->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
d3dTextureStageStates[t][s] = v;
}
}
numDirtyTextureStageStates = 0;
}
void
setSamplerState(uint32 stage, uint32 type, uint32 value)
{
if(d3dSamplerStates[type][stage] != value){
device->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
d3dSamplerStates[type][stage] = value;
}
}
void
setRasterStage(uint32 stage, Raster *raster)
{
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);
}
}
void
setTexture(uint32 stage, Texture *tex)
{
static DWORD filternomip[] = {
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
D3DTEXF_POINT, D3DTEXF_LINEAR,
D3DTEXF_POINT, D3DTEXF_LINEAR
};
static DWORD wrap[] = {
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
};
if(tex == nil){
setRasterStage(stage, nil);
return;
}
if(tex->raster){
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
}
setRasterStage(stage, tex->raster);
}
void
setMaterial(Material *mat)
{
D3DMATERIAL9 mat9;
D3DCOLORVALUE black = { 0, 0, 0, 0 };
float ambmult = mat->surfaceProps.ambient/255.0f;
float diffmult = mat->surfaceProps.diffuse/255.0f;
mat9.Ambient.r = mat->color.red*ambmult;
mat9.Ambient.g = mat->color.green*ambmult;
mat9.Ambient.b = mat->color.blue*ambmult;
mat9.Ambient.a = mat->color.alpha*ambmult;
mat9.Diffuse.r = mat->color.red*diffmult;
mat9.Diffuse.g = mat->color.green*diffmult;
mat9.Diffuse.b = mat->color.blue*diffmult;
mat9.Diffuse.a = mat->color.alpha*diffmult;
mat9.Power = 0.0f;
mat9.Emissive = black;
mat9.Specular = black;
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){
device->SetMaterial(&mat9);
d3dmaterial = mat9;
}
}
void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
// View Matrix
Matrix inv;
Matrix::invertOrthonormal(&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;
device->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];
device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
}
void
initializeRender(void)
{
engine->beginUpdate = beginUpdate;
}
#endif
}
}

70
src/d3d/d3drender.cpp Normal file
View 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
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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();

158
src/engine.cpp Normal file → Executable file
View File

@@ -3,6 +3,7 @@
#include <cassert>
#include "rwbase.h"
#include "rwerror.h"
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
@@ -15,22 +16,55 @@
#include "gl/rwgl3.h"
#include "gl/rwwdgl.h"
#define PLUGIN_ID 0
namespace rw {
Engine *engine;
Driver *driver[NUM_PLATFORMS];
PluginList Driver::s_plglist[NUM_PLATFORMS];
Engine::State Engine::state = Dead;
void
// This function mainly registers engine plugins
// RW initializes memory related things here too and
// uses more plugins
// TODO: do this^ ?
bool32
Engine::init(void)
{
engine = new Engine;
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
if(engine || Engine::state != Dead){
RWERROR((ERR_ENGINEINIT));
return 0;
}
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i] = init;
Frame::dirtyList.init();
// Register plugins
// TODO: these are wrong
ps2::initializePlatform();
xbox::initializePlatform();
d3d8::initializePlatform();
d3d9::initializePlatform();
wdgl::initializePlatform();
gl3::initializePlatform();
Engine::state = Initialized;
return 1;
}
// This is where RW allocates the engine and e.g. opens d3d
// TODO: this will take an argument with device specific data (HWND &c.)
bool32
Engine::open(void)
{
if(engine || Engine::state != Initialized){
RWERROR((ERR_ENGINEOPEN));
return 0;
}
// Allocate engine
engine = (Engine*)malloc(sizeof(Engine));
engine->currentCamera = nil;
engine->currentWorld = nil;
engine->currentTexDictionary = nil;
@@ -38,45 +72,78 @@ Engine::init(void)
engine->loadTextures = 1;
engine->makeDummies = 1;
engine->beginUpdate = null::beginUpdate;
engine->endUpdate = null::endUpdate;
engine->clearCamera = null::clearCamera;
engine->setRenderState = null::setRenderState;
engine->getRenderState = null::getRenderState;
engine->im2DRenderIndexedPrimitive = null::im2DRenderIndexedPrimitive;
engine->zNear = 0.0f; // random values
engine->zFar = 1.0f;
// Initialize device
// Device and possibly OS specific!
#ifdef RW_PS2
engine->device = ps2::renderdevice;
#elif RW_GL3
engine->device = gl3::renderdevice;
#elif RW_D3D9
engine->device = d3d::renderdevice;
#else
engine->device = null::renderdevice;
#endif
ps2::initializePlatform();
xbox::initializePlatform();
d3d8::initializePlatform();
d3d9::initializePlatform();
wdgl::initializePlatform();
gl3::initializePlatform();
// TODO: open device; create d3d object/get video mode
// TODO: init driver functions
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
for(uint i = 0; i < NUM_PLATFORMS; i++){
rw::engine->driver[i] = (Driver*)malloc(Driver::s_plglist[i].size);
engine->driver[i]->defaultPipeline = defpipe;
engine->driver[i]->rasterCreate = null::rasterCreate;
engine->driver[i]->rasterLock = null::rasterLock;
engine->driver[i]->rasterUnlock = null::rasterUnlock;
engine->driver[i]->rasterNumLevels = null::rasterNumLevels;
engine->driver[i]->rasterFromImage = null::rasterFromImage;
engine->driver[i]->rasterToImage = null::rasterToImage;
}
Engine::state = Opened;
return 1;
}
PluginList Driver::s_plglist[NUM_PLATFORMS];
// This is where RW creates the actual rendering device
// ans calls the engine plugin ctors
bool32
Engine::start(EngineStartParams *p)
{
if(engine == nil || Engine::state != Opened){
RWERROR((ERR_ENGINESTART));
return 0;
}
// Start device
engine->device.system(DEVICESTART, (void*)p);
engine->device.system(DEVICEINIT, nil);
// TODO: construct engine plugins
Frame::dirtyList.init();
for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].construct(rw::engine->driver[i]);
// TODO: finalize device start
Engine::state = Started;
return 1;
}
void
Driver::open(void)
Engine::term(void)
{
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
}
for(uint i = 0; i < NUM_PLATFORMS; i++){
rw::driver[i] = (Driver*)malloc(s_plglist[i].size);
void
Engine::close(void)
{
}
driver[i]->defaultPipeline = defpipe;
driver[i]->rasterCreate = null::rasterCreate;
driver[i]->rasterLock = null::rasterLock;
driver[i]->rasterUnlock = null::rasterUnlock;
driver[i]->rasterNumLevels = null::rasterNumLevels;
driver[i]->rasterFromImage = null::rasterFromImage;
driver[i]->rasterToImage = null::rasterToImage;
s_plglist[i].construct(rw::driver[i]);
}
void
Engine::stop(void)
{
engine->device.system(DEVICESTOP, nil);
}
namespace null {
@@ -84,6 +151,7 @@ namespace null {
void beginUpdate(Camera*) { }
void endUpdate(Camera*) { }
void clearCamera(Camera*,RGBA*,uint32) { }
void showRaster(Raster*) { }
void setRenderState(int32, uint32) { }
uint32 getRenderState(int32) { return 0; }
@@ -129,5 +197,23 @@ rasterToImage(Raster*)
return nil;
}
int
deviceSystem(DeviceReq req, void *arg0)
{
return 1;
}
Device renderdevice = {
0.0f, 1.0f,
null::beginUpdate,
null::endUpdate,
null::clearCamera,
null::showRaster,
null::setRenderState,
null::getRenderState,
null::im2DRenderIndexedPrimitive,
null::deviceSystem
};
}
}

View File

@@ -12,6 +12,7 @@
namespace rw {
LinkList Frame::dirtyList;
PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
Frame*
Frame::create(void)
@@ -269,6 +270,13 @@ Frame::scale(V3d *scl, CombineOp op)
updateObjects();
}
void
Frame::transform(Matrix *mat, CombineOp op)
{
this->matrix.transform(mat, op);
updateObjects();
}
void
Frame::updateObjects(void)
{

View File

@@ -14,6 +14,9 @@
namespace rw {
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil };
SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
Geometry*
@@ -288,8 +291,8 @@ Geometry::calculateBoundingSphere(void)
{
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i];
V3d min { 1000000.0f, 1000000.0f, 1000000.0f };
V3d max { -1000000.0f, -1000000.0f, -1000000.0f };
V3d min = { 1000000.0f, 1000000.0f, 1000000.0f };
V3d max = { -1000000.0f, -1000000.0f, -1000000.0f };
V3d *v = m->vertices;
for(int32 j = 0; j < this->numVertices; j++){
if(v->x > max.x) max.x = v->x;

View File

@@ -8,6 +8,7 @@
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "rwanim.h"
#include "rwplugins.h"
#include "ps2/rwps2.h"

View File

@@ -26,14 +26,14 @@ void*
driverOpen(void *o, int32, int32)
{
#ifdef RW_OPENGL
driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
engine->driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
#endif
driver[PLATFORM_GL3]->rasterNativeOffset = nativeRasterOffset;
driver[PLATFORM_GL3]->rasterCreate = rasterCreate;
driver[PLATFORM_GL3]->rasterLock = rasterLock;
driver[PLATFORM_GL3]->rasterUnlock = rasterUnlock;
driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
engine->driver[PLATFORM_GL3]->rasterNativeOffset = nativeRasterOffset;
engine->driver[PLATFORM_GL3]->rasterCreate = rasterCreate;
engine->driver[PLATFORM_GL3]->rasterLock = rasterLock;
engine->driver[PLATFORM_GL3]->rasterUnlock = rasterUnlock;
engine->driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
engine->driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
return o;
}

175
src/gl/gl3driver.cpp → src/gl/gl3device.cpp Normal file → Executable file
View File

@@ -10,10 +10,13 @@
#include "../rwengine.h"
#ifdef RW_OPENGL
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "rwgl3.h"
#include "rwgl3shader.h"
#include "rwgl3impl.h"
#define PLUGIN_ID 0
namespace rw {
namespace gl3 {
@@ -77,7 +80,9 @@ static uint32 srcblend, destblend;
static uint32 zwrite;
static uint32 ztest;
uint32 blendMap[] = {
static int32 activeTexture;
static uint32 blendMap[] = {
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
@@ -91,18 +96,26 @@ uint32 blendMap[] = {
GL_SRC_ALPHA_SATURATE,
};
void
static void
setVertexAlpha(bool32 enable)
{
if(vertexAlpha != enable){
vertexAlpha = enable;
if(!textureAlpha){
if(enable)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
}
}
}
static void
setRenderState(int32 state, uint32 value)
{
switch(state){
case VERTEXALPHA:
if(vertexAlpha != value){
vertexAlpha = value;
if(vertexAlpha)
glEnable(GL_BLEND);
else if(!textureAlpha)
glDisable(GL_BLEND);
}
setVertexAlpha(value);
break;
case SRCBLEND:
if(srcblend != value){
@@ -158,7 +171,7 @@ setRenderState(int32 state, uint32 value)
}
}
uint32
static uint32
getRenderState(int32 state)
{
RGBA rgba;
@@ -182,15 +195,15 @@ getRenderState(int32 state)
case ALPHATESTFUNC:
return uniformState.alphaFunc;
case ALPHATESTREF:
return uniformState.alphaRef*255.0f;
return (uint32)(uniformState.alphaRef*255.0f);
}
return 0;
}
void
static void
resetRenderState(void)
{
uniformState.alphaFunc = ALPHAGREATERTHAN;
uniformState.alphaFunc = ALPHAGREATEREQUAL;
uniformState.alphaRef = 10.0f/255.0f;
uniformState.fogEnable = 0;
uniformState.fogStart = 0.0f;
@@ -254,7 +267,7 @@ setLight(int32 n, Light *light)
l->direction = m->at;
}
// light has position
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0;
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0f;
l->color = light->color;
l->radius = light->radius;
l->minusCosAngle = light->minusCosAngle;
@@ -275,11 +288,20 @@ setViewMatrix(float32 *mat)
sceneDirty = 1;
}
static void
setActiveTexture(int32 n)
{
if(activeTexture != n){
activeTexture = n;
glActiveTexture(n);
}
}
void
setTexture(int32 n, Texture *tex)
{
bool32 alpha;
glActiveTexture(GL_TEXTURE0+n);
setActiveTexture(GL_TEXTURE0+n);
if(tex == nil || tex->raster->platform != PLATFORM_GL3 ||
tex->raster->width == 0){
glBindTexture(GL_TEXTURE_2D, whitetex);
@@ -291,12 +313,16 @@ setTexture(int32 n, Texture *tex)
alpha = natras->hasAlpha;
}
if(textureAlpha != alpha){
textureAlpha = alpha;
if(textureAlpha)
glEnable(GL_BLEND);
else if(!vertexAlpha)
glDisable(GL_BLEND);
if(n == 0){
if(alpha != textureAlpha){
textureAlpha = alpha;
if(!vertexAlpha){
if(alpha)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
}
}
}
}
@@ -323,7 +349,7 @@ flushCache(void)
}
}
void
static void
clearCamera(Camera *cam, RGBA *col, uint32 mode)
{
RGBAf colf;
@@ -339,7 +365,16 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
glClear(mask);
}
void
static GLFWwindow *glfwwindow;
static void
showRaster(Raster *raster)
{
// TODO: do this properly!
glfwSwapBuffers(glfwwindow);
}
static void
beginUpdate(Camera *cam)
{
float view[16], proj[16];
@@ -410,17 +445,62 @@ beginUpdate(Camera *cam)
}
}
void
initializeRender(void)
static int
startGLFW(EngineStartParams *startparams)
{
engine->beginUpdate = beginUpdate;
engine->clearCamera = clearCamera;
engine->setRenderState = setRenderState;
engine->getRenderState = getRenderState;
engine->im2DRenderIndexedPrimitive = im2DRenderIndexedPrimitive;
engine->zNear = -1.0f;
engine->zFar = 1.0f;
GLenum status;
GLFWwindow *win;
/* Init GLFW */
if(!glfwInit()){
RWERROR((ERR_GENERAL, "glfwInit() failed"));
return 0;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
win = glfwCreateWindow(startparams->width, startparams->height, startparams->windowtitle, 0, 0);
if(win == nil){
RWERROR((ERR_GENERAL, "glfwCreateWindow() failed"));
glfwTerminate();
return 0;
}
glfwMakeContextCurrent(win);
/* Init GLEW */
glewExperimental = GL_TRUE;
status = glewInit();
if(status != GLEW_OK){
RWERROR((ERR_GENERAL, glewGetErrorString(status)));
glfwDestroyWindow(win);
glfwTerminate();
return 0;
}
if(!GLEW_VERSION_3_3){
RWERROR((ERR_GENERAL, "OpenGL 3.3 needed"));
glfwDestroyWindow(win);
glfwTerminate();
return 0;
}
glfwwindow = win;
*startparams->window = win;
return 1;
}
static int
stopGLFW(void)
{
glfwDestroyWindow(glfwwindow);
glfwTerminate();
return 1;
}
static int
initOpenGL(void)
{
#include "shaders/simple_gl3.inc"
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
@@ -438,7 +518,6 @@ initializeRender(void)
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_scene);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
@@ -446,7 +525,6 @@ initializeRender(void)
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenBuffers(1, &ubo_object);
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Object"), ubo_object);
@@ -454,7 +532,6 @@ initializeRender(void)
GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
glGenTextures(1, &whitetex);
glBindTexture(GL_TEXTURE_2D, whitetex);
@@ -464,7 +541,35 @@ initializeRender(void)
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
im2DInit();
return 1;
}
static int
deviceSystem(DeviceReq req, void *arg0)
{
switch(req){
case DEVICESTART:
return startGLFW((EngineStartParams*)arg0);
case DEVICEINIT:
return initOpenGL();
case DEVICESTOP:
return stopGLFW();
}
return 1;
}
Device renderdevice = {
-1.0f, 1.0f,
gl3::beginUpdate,
null::endUpdate,
gl3::clearCamera,
gl3::showRaster,
gl3::setRenderState,
gl3::getRenderState,
gl3::im2DRenderIndexedPrimitive,
gl3::deviceSystem
};
}
}

View File

@@ -43,7 +43,7 @@ void
lightingCB(void)
{
World *world;
RGBAf ambLight = (RGBAf){0.0, 0.0, 0.0, 1.0};
RGBAf ambLight = { 0.0, 0.0, 0.0, 1.0 };
int n = 0;
world = (World*)engine->currentWorld;
@@ -84,9 +84,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
InstanceData *inst = header->inst;
int32 n = header->numMeshes;
// rw::setRenderState(ALPHATESTFUNC, 1);
// rw::setRenderState(ALPHATESTREF, 50);
simpleShader->use();
while(n--){

View File

@@ -189,8 +189,10 @@ Shader::fromFiles(const char *vspath, const char *fspath)
void
Shader::use(void)
{
glUseProgram(this->program);
currentShader = this;
if(currentShader != this){
glUseProgram(this->program);
currentShader = this;
}
}
}

View File

@@ -1,8 +1,24 @@
#ifdef RW_GL3
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#endif
namespace rw {
#ifdef RW_GL3
struct EngineStartParams
{
GLFWwindow **window;
int width, height;
const char *windowtitle;
};
#endif
namespace gl3 {
void initializePlatform(void);
void initializeRender(void);
extern Device renderdevice;
// arguments to glVertexAttribPointer basically
struct AttribDesc

View File

@@ -10,6 +10,6 @@ out vec4 color;
void
main(void)
{
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
}

View File

@@ -36,7 +36,7 @@ const char *im2d_frag_src =
"void\n"
"main(void)\n"
"{\n"
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
"}\n"
;

View File

@@ -17,7 +17,7 @@ out vec4 color;
void
main(void)
{
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
switch(u_alphaTest){
default:
case 0: break;

View File

@@ -78,7 +78,7 @@ const char *matfx_env_frag_src =
"void\n"
"main(void)\n"
"{\n"
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
" switch(u_alphaTest){\n"
" default:\n"
" case 0: break;\n"

View File

@@ -22,7 +22,7 @@ out vec4 color;
void
main(void)
{
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
if(u_fogEnable != 0)
color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
switch(u_alphaTest){

View File

@@ -95,7 +95,7 @@ const char *simple_frag_src =
"void\n"
"main(void)\n"
"{\n"
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
" if(u_fogEnable != 0)\n"
" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
" switch(u_alphaTest){\n"

View File

@@ -25,7 +25,7 @@ namespace wdgl {
void*
driverOpen(void *o, int32, int32)
{
driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
engine->driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
return o;
}
@@ -820,7 +820,7 @@ Texture::upload(void)
switch(r->format & 0xF00){
case Raster::C8888:
glTexImage2D(GL_TEXTURE_2D, 0, 4, r->width, r->height,
0, GL_RGBA, GL_UNSIGNED_BYTE, r->texels);
0, GL_RGBA, GL_UNSIGNED_BYTE, r->pixels);
break;
default:
printf("unsupported raster format: %x\n", r->format);

View File

@@ -8,6 +8,7 @@
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwengine.h"
#include "rwanim.h"
#include "rwplugins.h"
#include "ps2/rwps2.h"

View File

@@ -24,6 +24,10 @@
namespace rw {
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
//
// TexDictionary
//
@@ -904,6 +908,7 @@ Image::getFilename(const char *name)
Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{
// TODO: pass arguments through to the driver and create the raster there
Raster *raster = (Raster*)malloc(s_plglist.size);
assert(raster != nil);
raster->platform = platform ? platform : rw::platform;
@@ -913,11 +918,11 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
raster->width = width;
raster->height = height;
raster->depth = depth;
raster->texels = raster->palette = nil;
raster->pixels = raster->palette = nil;
s_plglist.construct(raster);
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
driver[raster->platform]->rasterCreate(raster);
engine->driver[raster->platform]->rasterCreate(raster);
return raster;
}
@@ -933,19 +938,19 @@ Raster::destroy(void)
uint8*
Raster::lock(int32 level)
{
return driver[this->platform]->rasterLock(this, level);
return engine->driver[this->platform]->rasterLock(this, level);
}
void
Raster::unlock(int32 level)
{
driver[this->platform]->rasterUnlock(this, level);
engine->driver[this->platform]->rasterUnlock(this, level);
}
int32
Raster::getNumLevels(void)
{
return driver[this->platform]->rasterNumLevels(this);
return engine->driver[this->platform]->rasterNumLevels(this);
}
int32
@@ -964,14 +969,14 @@ Raster::createFromImage(Image *image, int32 platform)
Raster *raster = Raster::create(image->width, image->height,
image->depth, TEXTURE | DONTALLOCATE,
platform);
driver[raster->platform]->rasterFromImage(raster, image);
engine->driver[raster->platform]->rasterFromImage(raster, image);
return raster;
}
Image*
Raster::toImage(void)
{
return driver[this->platform]->rasterToImage(this);
return engine->driver[this->platform]->rasterToImage(this);
}
}

View File

@@ -11,6 +11,8 @@
namespace rw {
PluginList Light::s_plglist = { sizeof(Light), sizeof(Light), nil, nil };
static void
lightSync(ObjectWithFrame*)
{

2
src/matfx.cpp Normal file → Executable file
View File

@@ -145,7 +145,7 @@ MatFX::get(Material *m)
return *PLUGINOFFSET(MatFX*, m, matFXGlobals.materialOffset);
}
uint32
int32
MatFX::getEffectIndex(uint32 type)
{
for(int i = 0; i < 2; i++)

1
src/pipeline.cpp Normal file → Executable file
View File

@@ -7,7 +7,6 @@
#include "rwplg.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "ps2/rwps2.h"
#define COLOR_ARGB(a,r,g,b) \
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))

1
src/ps2/pds.cpp Normal file → Executable file
View File

@@ -7,6 +7,7 @@
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "../rwanim.h"
#include "../rwplugins.h"
#include "rwps2.h"

63
src/ps2/ps2.cpp Normal file → Executable file
View File

@@ -24,13 +24,13 @@ namespace ps2 {
void*
driverOpen(void *o, int32, int32)
{
driver[PLATFORM_PS2]->defaultPipeline = makeDefaultPipeline();
engine->driver[PLATFORM_PS2]->defaultPipeline = makeDefaultPipeline();
driver[PLATFORM_PS2]->rasterNativeOffset = nativeRasterOffset;
driver[PLATFORM_PS2]->rasterCreate = rasterCreate;
driver[PLATFORM_PS2]->rasterLock = rasterLock;
driver[PLATFORM_PS2]->rasterUnlock = rasterUnlock;
driver[PLATFORM_PS2]->rasterNumLevels = rasterNumLevels;
engine->driver[PLATFORM_PS2]->rasterNativeOffset = nativeRasterOffset;
engine->driver[PLATFORM_PS2]->rasterCreate = rasterCreate;
engine->driver[PLATFORM_PS2]->rasterLock = rasterLock;
engine->driver[PLATFORM_PS2]->rasterUnlock = rasterUnlock;
engine->driver[PLATFORM_PS2]->rasterNumLevels = rasterNumLevels;
return o;
}
@@ -73,7 +73,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();
@@ -92,7 +92,6 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
uint32 buf[2];
stream->read(buf, 8);
instance->dataSize = buf[0];
instance->arePointersFixed = buf[1];
// TODO: force alignment
instance->data = new uint8[instance->dataSize];
#ifdef RW_PS2
@@ -100,6 +99,10 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
assert(a % 0x10 == 0);
#endif
stream->read(instance->data, instance->dataSize);
#ifdef RW_PS2
if(!buf[1])
fixDmaOffsets(instance);
#endif
instance->material = geometry->meshHeader->mesh[i].material;
// sizedebug(instance);
}
@@ -118,13 +121,15 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
for(uint32 i = 0; i < header->numMeshes; i++){
InstanceData *instance = &header->instanceMeshes[i];
if(instance->arePointersFixed == 2)
unfixDmaOffsets(instance);
uint32 buf[2];
buf[0] = instance->dataSize;
buf[1] = instance->arePointersFixed;
buf[1] = unfixDmaOffsets(instance);
stream->write(buf, 8);
stream->write(instance->data, instance->dataSize);
#ifdef RW_PS2
if(!buf[1])
fixDmaOffsets(instance);
#endif
}
return stream;
}
@@ -157,13 +162,11 @@ registerNativeDataPlugin(void)
getSizeNativeData);
}
// Patch DMA ref ADDR fields to point to the actual data.
#ifdef RW_PS2
void
fixDmaOffsets(InstanceData *inst)
{
if(inst->arePointersFixed)
return;
uint32 base = (uint32)inst->data;
uint32 *tag = (uint32*)inst->data;
for(;;){
@@ -184,7 +187,6 @@ fixDmaOffsets(InstanceData *inst)
// DMAret
case 0x60000000:
// we're done
inst->arePointersFixed = 2;
return;
default:
@@ -195,15 +197,17 @@ fixDmaOffsets(InstanceData *inst)
}
#endif
void
// Patch DMA ref ADDR fields to qword offsets and return whether
// no ref tags were found.
// Only under RW_PS2 are the addresses actually patched but we need
// the return value for streaming out.
bool32
unfixDmaOffsets(InstanceData *inst)
{
(void)inst;
bool32 norefs = 1;
#ifdef RW_PS2
if(inst->arePointersFixed != 2)
return;
uint32 base = (uint32)inst->data;
#endif
uint32 *tag = (uint32*)inst->data;
for(;;){
switch(tag[0]&0x70000000){
@@ -215,23 +219,23 @@ unfixDmaOffsets(InstanceData *inst)
// DMAref
case 0x30000000:
norefs = 0;
// unfix address and jump to next
#ifdef RW_PS2
tag[1] = (tag[1] - base)>>4;
#endif
tag += 4;
break;
// DMAret
case 0x60000000:
// we're done
inst->arePointersFixed = 0;
return;
return norefs;
default:
fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]);
return;
return norefs;
}
}
#endif
}
// Pipeline
@@ -586,7 +590,6 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
InstMeshInfo im = getInstMeshInfo(this, g, m);
inst->dataSize = (im.size+im.size2)<<4;
inst->arePointersFixed = im.numBrokenAttribs == 0;
// TODO: force alignment
inst->data = new uint8[inst->dataSize];
@@ -685,6 +688,10 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
if(this->instanceCB)
this->instanceCB(this, g, m, datap);
#ifdef RW_PS2
if(im.numBrokenAttribs)
fixDmaOffsets(inst);
#endif
}
uint8*
@@ -766,6 +773,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
geo->flags |= Geometry::NATIVE;
}
/*
static void
printVertCounts(InstanceData *inst, int flag)
{
@@ -794,6 +802,7 @@ printVertCounts(InstanceData *inst, int flag)
}
}
}
*/
static void
objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
@@ -1241,6 +1250,7 @@ registerADCPlugin(void)
}
// misc stuff
/*
void
printDMA(InstanceData *inst)
@@ -1300,6 +1310,7 @@ sizedebug(InstanceData *inst)
}
}
}
*/
}
}

41
src/ps2/ps2device.cpp Executable file
View File

@@ -0,0 +1,41 @@
#ifdef RW_PS2
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "../rwanim.h"
#include "../rwplugins.h"
#include "rwps2.h"
#include "rwps2plg.h"
#include "rwps2impl.h"
#define PLUGIN_ID 2
namespace rw {
namespace ps2 {
Device renderdevice = {
16777215.0f, 0.0f,
null::beginUpdate,
null::endUpdate,
null::clearCamera,
null::showRaster,
null::setRenderState,
null::getRenderState,
null::im2DRenderIndexedPrimitive,
null::deviceSystem
};
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -74,7 +74,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
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();

50
src/ps2/rwps2.h Normal file → Executable file
View File

@@ -1,15 +1,19 @@
namespace rw {
#ifdef RW_PS2
struct EngineStartParams
{
};
#endif
namespace ps2 {
void initializePlatform(void);
extern Device renderdevice;
struct InstanceData
{
// 0 - addresses in ref tags need fixing
// 1 - no ref tags, so no fixing
// set by the program:
// 2 - ref tags are fixed, need to unfix before stream write
uint32 arePointersFixed;
uint32 dataSize;
uint8 *data;
Material *material;
@@ -57,10 +61,8 @@ void registerNativeDataPlugin(void);
void printDMA(InstanceData *inst);
void sizedebug(InstanceData *inst);
// only RW_PS2
void fixDmaOffsets(InstanceData *inst);
void unfixDmaOffsets(InstanceData *inst);
//
void fixDmaOffsets(InstanceData *inst); // only RW_PS2
int32 unfixDmaOffsets(InstanceData *inst);
struct PipeAttribute
{
@@ -181,22 +183,30 @@ void registerPluginPDSPipes(void);
struct Ps2Raster
{
enum Flags {
HASGIFPACKETS = 0x1,
SWIZZLED8 = 0x2,
SWIZZLED4 = 0x4,
NEWSTYLE = 0x1, // has GIF tags and transfer DMA chain
SWIZZLED8 = 0x2,
SWIZZLED4 = 0x4,
};
struct PixelPtr {
// RW has pixels as second element but we don't want this struct
// to be longer than 16 bytes
uint8 *pixels;
// palette can be allocated in last level, in that case numTransfers is
// one less than numTotalTransfers.
int32 numTransfers;
int32 numTotalTransfers;
};
uint32 tex0[2];
uint32 paletteOffset; // from beginning of GS data;
// in words/64
uint64 tex0;
uint32 paletteBase; // block address from beginning of GS data (words/64)
uint16 kl;
uint8 tex1low; // MXL and LCM of TEX1
uint8 unk2;
uint32 miptbp1[2];
uint32 miptbp2[2];
uint32 texelSize;
uint32 paletteSize;
uint32 gsSize;
uint64 miptbp1;
uint64 miptbp2;
uint32 pixelSize; // in bytes
uint32 paletteSize; // in bytes
uint32 totalSize; // total size of texture on GS in words
int8 flags;
uint8 *data; //tmp

View File

@@ -231,6 +231,7 @@ struct Matrix
Matrix *rotate(const Quat &q, CombineOp op);
Matrix *translate(V3d *translation, CombineOp op);
Matrix *scale(V3d *scl, CombineOp op);
Matrix *transform(Matrix *mat, CombineOp op);
void lookAt(const V3d &dir, const V3d &up);
// helper functions. consider private

89
src/rwengine.h Normal file → Executable file
View File

@@ -22,9 +22,9 @@ enum RenderState
enum AlphaTestFunc
{
ALPHANEVER = 0,
ALPHALESS,
ALPHAGREATERTHAN
ALPHAALWAYS = 0,
ALPHAGREATEREQUAL,
ALPHALESS
};
enum BlendFunction
@@ -43,37 +43,35 @@ enum BlendFunction
// TODO: add more perhaps
};
// This is for platform independent things and the render device (of which
// there can only ever be one).
// TODO: move more stuff into this
struct Engine
enum DeviceReq
{
void *currentCamera;
void *currentWorld;
Texture *imtexture;
// Device/Context creation
DEVICESTART,
// Device initialization before Engine/Driver plugins are opened
DEVICEINIT,
// Device/Context shutdown
DEVICESTOP,
};
TexDictionary *currentTexDictionary;
bool32 loadTextures; // load textures from files
bool32 makeDummies; // create dummy textures to store just names
typedef int DeviceSystem(DeviceReq req, void *arg0);
// Device
// This is for the render device, we only have one
struct Device
{
float32 zNear, zFar;
void (*beginUpdate)(Camera*);
void (*endUpdate)(Camera*);
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
void (*showRaster)(Raster *raster);
void (*setRenderState)(int32 state, uint32 value);
uint32 (*getRenderState)(int32 state);
void (*im2DRenderIndexedPrimitive)(PrimitiveType,
void*, int32, void*, int32);
static void init(void);
DeviceSystem *system;
};
extern Engine *engine;
// This is for platform driver implementations which have to be available
// regardless of the render device.
// This is for platform-dependent but portable things
// so the engine has one for every platform
struct Driver
{
ObjPipeline *defaultPipeline;
@@ -87,7 +85,6 @@ struct Driver
Image *(*rasterToImage)(Raster*);
static PluginList s_plglist[NUM_PLATFORMS];
static void open(void);
static int32 registerPlugin(int32 platform, int32 size, uint32 id,
Constructor ctor, Destructor dtor){
return s_plglist[platform].registerPlugin(size, id,
@@ -95,19 +92,55 @@ struct Driver
}
};
extern Driver *driver[NUM_PLATFORMS];
#define DRIVER driver[rw::platform]
struct EngineStartParams;
// This is for platform independent things
// TODO: move more stuff into this
// TODO: make this have plugins and allocate in Engine::open
struct Engine
{
enum State {
Dead = 0,
Initialized,
Opened,
Started
};
void *currentCamera;
void *currentWorld;
Texture *imtexture;
TexDictionary *currentTexDictionary;
// load textures from files
bool32 loadTextures;
// create dummy textures to store just names
bool32 makeDummies;
// Dynamically allocated because of plugins
Driver *driver[NUM_PLATFORMS];
Device device;
static State state;
static bool32 init(void);
static bool32 open(void);
static bool32 start(EngineStartParams*);
static void term(void);
static void close(void);
static void stop(void);
};
extern Engine *engine;
inline void SetRenderState(int32 state, uint32 value){
engine->setRenderState(state, value); }
engine->device.setRenderState(state, value); }
inline uint32 GetRenderState(int32 state){
return engine->getRenderState(state); }
return engine->device.getRenderState(state); }
namespace null {
void beginUpdate(Camera*);
void endUpdate(Camera*);
void clearCamera(Camera*, RGBA *col, uint32 mode);
void showRaster(Raster*);
void setRenderState(int32 state, uint32 value);
uint32 getRenderState(int32 state);
@@ -121,6 +154,10 @@ namespace null {
void im2DRenderIndexedPrimitive(PrimitiveType,
void*, int32, void*, int32);
int deviceSystem(DeviceReq req, void*);
extern Device renderdevice;
}
}

View File

@@ -20,6 +20,6 @@ char *dbgsprint(int32 code, ...);
fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \
fprintf(stderr, "%s\n", rw::dbgsprint ecode); \
rw::setError(&_e); \
}while(0);
}while(0)
}

52
src/rwobjects.h Normal file → Executable file
View File

@@ -82,8 +82,9 @@ struct Object
}
};
struct Frame : PluginBase<Frame>
struct Frame
{
PLUGINBASE
typedef Frame *(*Callback)(Frame *f, void *data);
enum { ID = 0 };
enum { // private flags
@@ -125,7 +126,8 @@ struct Frame : PluginBase<Frame>
Matrix *getLTM(void);
void rotate(V3d *axis, float32 angle, CombineOp op);
void translate(V3d *trans, CombineOp op);
void scale(V3d *trans, CombineOp op);
void scale(V3d *scale, CombineOp op);
void transform(Matrix *mat, CombineOp op);
void updateObjects(void);
@@ -214,17 +216,26 @@ struct RasterLevels
} levels[1]; // 0 is illegal :/
};
struct Raster : PluginBase<Raster>
struct Raster
{
PLUGINBASE
int32 platform;
int32 type; // hardly used
// TODO: use bytes
int32 type;
int32 flags;
int32 format;
int32 width, height, depth;
int32 stride;
uint8 *texels;
uint8 *pixels;
uint8 *palette;
uint8 *originalPixels;
// TODO: use them (for locking mainly)
int32 originalWidth;
int32 originalHeight;
int32 originalStride;
// TODO:
// parent raster and offset
static Raster *create(int32 width, int32 height, int32 depth,
int32 format, int32 platform = 0);
@@ -267,8 +278,9 @@ struct Raster : PluginBase<Raster>
struct TexDictionary;
struct Texture : PluginBase<Texture>
struct Texture
{
PLUGINBASE
Raster *raster;
TexDictionary *dict;
LLLink inDict;
@@ -316,8 +328,9 @@ struct SurfaceProperties
float32 diffuse;
};
struct Material : PluginBase<Material>
struct Material
{
PLUGINBASE
Texture *texture;
RGBA color;
SurfaceProperties surfaceProps;
@@ -390,8 +403,9 @@ struct MaterialList
uint32 streamGetSize(void);
};
struct Geometry : PluginBase<Geometry>
struct Geometry
{
PLUGINBASE
enum { ID = 8 };
Object object;
uint32 flags;
@@ -452,8 +466,9 @@ void registerNativeDataPlugin(void);
struct Clump;
struct World;
struct Atomic : PluginBase<Atomic>
struct Atomic
{
PLUGINBASE
typedef void (*RenderCB)(Atomic *atomic);
enum { ID = 1 };
enum {
@@ -508,8 +523,9 @@ struct Atomic : PluginBase<Atomic>
void registerAtomicRightsPlugin(void);
struct Light : PluginBase<Light>
struct Light
{
PLUGINBASE
enum { ID = 3 };
ObjectWithFrame object;
float32 radius;
@@ -567,8 +583,9 @@ struct FrustumPlane
uint8 closestZ;
};
struct Camera : PluginBase<Camera>
struct Camera
{
PLUGINBASE
enum { ID = 4 };
enum { PERSPECTIVE = 1, PARALLEL };
enum { CLEARIMAGE = 0x1, CLEARZ = 0x2};
@@ -612,8 +629,12 @@ struct Camera : PluginBase<Camera>
void beginUpdate(void) { this->beginUpdateCB(this); }
void endUpdate(void) { this->endUpdateCB(this); }
void clear(RGBA *col, uint32 mode);
void showRaster(void);
void setNearPlane(float32);
void setFarPlane(float32);
void setViewWindow(const V2d *window);
void setViewOffset(const V2d *offset);
void setProjection(int32 proj);
int32 frustumTestSphere(Sphere *s);
static Camera *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
@@ -623,8 +644,9 @@ struct Camera : PluginBase<Camera>
void setFOV(float32 fov, float32 ratio);
};
struct Clump : PluginBase<Clump>
struct Clump
{
PLUGINBASE
enum { ID = 2 };
Object object;
LinkList atomics;
@@ -662,8 +684,9 @@ struct Clump : PluginBase<Clump>
};
// A bit of a stub right now
struct World : PluginBase<World>
struct World
{
PLUGINBASE
enum { ID = 7 };
Object object;
LinkList lights; // these have positions (type >= 0x80)
@@ -674,8 +697,9 @@ struct World : PluginBase<World>
void addCamera(Camera *cam);
};
struct TexDictionary : PluginBase<TexDictionary>
struct TexDictionary
{
PLUGINBASE
enum { ID = 6 };
Object object;
LinkList textures;

View File

@@ -49,27 +49,22 @@ struct PluginList
int32 getPluginOffset(uint32 id);
};
template <typename T>
struct PluginBase
{
static PluginList s_plglist;
#define PLUGINBASE \
static PluginList s_plglist; \
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor, \
Destructor dtor, CopyConstructor copy){ \
return s_plglist.registerPlugin(size, id, ctor, dtor, copy); \
} \
static int32 registerPluginStream(uint32 id, StreamRead read, \
StreamWrite write, StreamGetSize getSize){ \
return s_plglist.registerStream(id, read, write, getSize); \
} \
static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){ \
return s_plglist.setStreamRightsCallback(id, cb); \
} \
static int32 getPluginOffset(uint32 id){ \
return s_plglist.getPluginOffset(id); \
}
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
Destructor dtor, CopyConstructor copy){
return s_plglist.registerPlugin(size, id, ctor, dtor, copy);
}
static int32 registerPluginStream(uint32 id, StreamRead read,
StreamWrite write, StreamGetSize getSize){
return s_plglist.registerStream(id, read, write, getSize);
}
static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){
return s_plglist.setStreamRightsCallback(id, cb);
}
static int32 getPluginOffset(uint32 id){
return s_plglist.getPluginOffset(id);
}
};
template <typename T>
PluginList PluginBase<T>::s_plglist = { sizeof(T), sizeof(T), nil, nil };
}

2
src/rwplugins.h Normal file → Executable file
View File

@@ -130,7 +130,7 @@ struct MatFX
static void setEffects(Material *m, uint32 flags);
static uint32 getEffects(Material *m);
static MatFX *get(Material *m);
uint32 getEffectIndex(uint32 type);
int32 getEffectIndex(uint32 type);
void setBumpTexture(Texture *t);
void setBumpCoefficient(float32 coef);
void setEnvTexture(Texture *t);

9
src/world.cpp Normal file → Executable file
View File

@@ -13,6 +13,8 @@
namespace rw {
PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil };
World*
World::create(void)
{
@@ -33,14 +35,19 @@ World::addLight(Light *light)
light->world = this;
if(light->getType() < Light::POINT){
this->directionalLights.append(&light->inWorld);
}else
}else{
this->lights.append(&light->inWorld);
if(light->getFrame())
light->getFrame()->updateObjects();
}
}
void
World::addCamera(Camera *cam)
{
cam->world = this;
if(cam->getFrame())
cam->getFrame()->updateObjects();
}
}