mirror of
https://github.com/aap/librw.git
synced 2024-11-28 22:55:42 +00:00
revised initialization again and restructured code for that
This commit is contained in:
parent
454e7b8ac6
commit
d3cff5c06c
5
Makefile
5
Makefile
@ -10,8 +10,9 @@ SRC := $(wildcard $(SRCDIR)/*.cpp $(SRCDIR)/*/*.cpp)
|
|||||||
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC))
|
||||||
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC))
|
DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC))
|
||||||
INC := -I/usr/local/include
|
INC := -I/usr/local/include
|
||||||
CFLAGS=-Wall -Wextra -g $(BUILDDEF) -Wno-parentheses -Wno-invalid-offsetof -fno-diagnostics-show-caret -Wno-unused-parameter
|
CFLAGS=-Wall -Wextra -g $(BUILDDEF) -fno-diagnostics-show-caret \
|
||||||
#-Wconversion
|
-Wno-parentheses -Wno-invalid-offsetof \
|
||||||
|
-Wno-unused-parameter -Wno-sign-compare
|
||||||
LIB=librw-$(BUILD).a
|
LIB=librw-$(BUILD).a
|
||||||
|
|
||||||
$(LIB): $(OBJ)
|
$(LIB): $(OBJ)
|
||||||
|
@ -17,13 +17,13 @@ defaultBeginUpdateCB(Camera *cam)
|
|||||||
{
|
{
|
||||||
engine->currentCamera = cam;
|
engine->currentCamera = cam;
|
||||||
Frame::syncDirty();
|
Frame::syncDirty();
|
||||||
DRIVER.beginUpdate(cam);
|
DRIVER->beginUpdate(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
defaultEndUpdateCB(Camera *cam)
|
defaultEndUpdateCB(Camera *cam)
|
||||||
{
|
{
|
||||||
DRIVER.endUpdate(cam);
|
DRIVER->endUpdate(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -511,7 +511,7 @@ Atomic::getPipeline(void)
|
|||||||
{
|
{
|
||||||
return this->pipeline ?
|
return this->pipeline ?
|
||||||
this->pipeline :
|
this->pipeline :
|
||||||
driver[platform].defaultPipeline;
|
driver[platform]->defaultPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -348,7 +348,7 @@ deleteObject(void *object)
|
|||||||
|
|
||||||
int32 nativeRasterOffset;
|
int32 nativeRasterOffset;
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
@ -392,21 +392,21 @@ rasterCreate(Raster *raster)
|
|||||||
format);
|
format);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8*
|
uint8*
|
||||||
rasterLock(Raster *raster, int32 level)
|
rasterLock(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
return lockTexture(natras->texture, level);
|
return lockTexture(natras->texture, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterUnlock(Raster *raster, int32 level)
|
rasterUnlock(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
unlockTexture(natras->texture, level);
|
unlockTexture(natras->texture, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
int32
|
||||||
rasterNumLevels(Raster *raster)
|
rasterNumLevels(Raster *raster)
|
||||||
{
|
{
|
||||||
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
@ -419,7 +419,7 @@ rasterNumLevels(Raster *raster)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterFromImage(Raster *raster, Image *image)
|
rasterFromImage(Raster *raster, Image *image)
|
||||||
{
|
{
|
||||||
int32 format;
|
int32 format;
|
||||||
@ -586,34 +586,9 @@ copyNativeRaster(void *dst, void *, int32 offset, int32)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
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_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
printf("d3d native close\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
registerNativeRaster(void)
|
registerNativeRaster(void)
|
||||||
{
|
{
|
||||||
Engine::registerPlugin(0, ID_RASTERD3D9, nativeOpen, nativeClose);
|
|
||||||
nativeRasterOffset = Raster::registerPlugin(sizeof(D3dRaster),
|
nativeRasterOffset = Raster::registerPlugin(sizeof(D3dRaster),
|
||||||
ID_RASTERD3D9,
|
ID_RASTERD3D9,
|
||||||
createNativeRaster,
|
createNativeRaster,
|
||||||
|
@ -12,18 +12,43 @@
|
|||||||
#include "rwd3d.h"
|
#include "rwd3d.h"
|
||||||
#include "rwd3d8.h"
|
#include "rwd3d8.h"
|
||||||
|
|
||||||
|
#include "rwd3dimpl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 2
|
#define PLUGIN_ID 2
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace d3d8 {
|
namespace d3d8 {
|
||||||
using namespace d3d;
|
using namespace d3d;
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("d3d8 open\n");
|
||||||
|
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;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initializePlatform(void)
|
initializePlatform(void)
|
||||||
{
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D8, 0, PLATFORM_D3D8,
|
||||||
|
driverOpen, driverClose);
|
||||||
|
// shared between D3D8 and 9
|
||||||
if(nativeRasterOffset == 0)
|
if(nativeRasterOffset == 0)
|
||||||
registerNativeRaster();
|
registerNativeRaster();
|
||||||
driver[PLATFORM_D3D8].defaultPipeline = makeDefaultPipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
@ -401,30 +426,6 @@ makeDefaultPipeline(void)
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeSkinPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_SKIN;
|
|
||||||
pipe->pluginData = 1;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeMatFXPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_MATFX;
|
|
||||||
pipe->pluginData = 0;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
|
||||||
// only handles 4 and 8 bit textures right now
|
// only handles 4 and 8 bit textures right now
|
||||||
|
89
src/d3d/d3d8plugins.cpp
Normal file
89
src/d3d/d3d8plugins.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#include "rwd3d.h"
|
||||||
|
#include "rwd3d8.h"
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace d3d8 {
|
||||||
|
using namespace d3d;
|
||||||
|
|
||||||
|
// Skin
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeSkinPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = defaultRenderCB;
|
||||||
|
pipe->pluginID = ID_SKIN;
|
||||||
|
pipe->pluginData = 1;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatFX
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_D3D8] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeMatFXPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = defaultRenderCB;
|
||||||
|
pipe->pluginID = ID_MATFX;
|
||||||
|
pipe->pluginData = 0;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,8 @@
|
|||||||
#include "rwd3d.h"
|
#include "rwd3d.h"
|
||||||
#include "rwd3d9.h"
|
#include "rwd3d9.h"
|
||||||
|
|
||||||
|
#include "rwd3dimpl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 2
|
#define PLUGIN_ID 2
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
@ -25,12 +27,35 @@ using namespace d3d;
|
|||||||
|
|
||||||
#define NUMDECLELT 12
|
#define NUMDECLELT 12
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("d3d9 open\n");
|
||||||
|
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;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initializePlatform(void)
|
initializePlatform(void)
|
||||||
{
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D9, 0, PLATFORM_D3D9,
|
||||||
|
driverOpen, driverClose);
|
||||||
|
// shared between D3D8 and 9
|
||||||
if(nativeRasterOffset == 0)
|
if(nativeRasterOffset == 0)
|
||||||
registerNativeRaster();
|
registerNativeRaster();
|
||||||
driver[PLATFORM_D3D9].defaultPipeline = makeDefaultPipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
@ -559,30 +584,6 @@ makeDefaultPipeline(void)
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeSkinPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_SKIN;
|
|
||||||
pipe->pluginData = 1;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeMatFXPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_MATFX;
|
|
||||||
pipe->pluginData = 0;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
|
||||||
Texture*
|
Texture*
|
||||||
|
89
src/d3d/d3d9plugins.cpp
Normal file
89
src/d3d/d3d9plugins.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#include "rwd3d.h"
|
||||||
|
#include "rwd3d9.h"
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace d3d9 {
|
||||||
|
using namespace d3d;
|
||||||
|
|
||||||
|
// Skin
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeSkinPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = defaultRenderCB;
|
||||||
|
pipe->pluginID = ID_SKIN;
|
||||||
|
pipe->pluginData = 1;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatFX
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_D3D9] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeMatFXPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = defaultRenderCB;
|
||||||
|
pipe->pluginID = ID_MATFX;
|
||||||
|
pipe->pluginData = 0;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -47,14 +47,20 @@ public:
|
|||||||
ObjPipeline(uint32 platform);
|
ObjPipeline(uint32 platform);
|
||||||
};
|
};
|
||||||
|
|
||||||
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
|
void defaultInstanceCB(Geometry *geo, InstanceData *header);
|
||||||
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
void defaultUninstanceCB(Geometry *geo, InstanceData *header);
|
||||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
|
|
||||||
|
// Skin plugin
|
||||||
|
|
||||||
|
void initSkin(void);
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
|
||||||
|
// MatFX plugin
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
@ -76,8 +76,14 @@ void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
|||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
|
|
||||||
|
// Skin plugin
|
||||||
|
|
||||||
|
void initSkin(void);
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
|
||||||
|
// MatFX plugin
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
11
src/d3d/rwd3dimpl.h
Normal file
11
src/d3d/rwd3dimpl.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace rw {
|
||||||
|
namespace d3d {
|
||||||
|
|
||||||
|
void rasterCreate(Raster *raster);
|
||||||
|
uint8 *rasterLock(Raster *raster, int32 level);
|
||||||
|
void rasterUnlock(Raster *raster, int32 level);
|
||||||
|
int32 rasterNumLevels(Raster *raster);
|
||||||
|
void rasterFromImage(Raster *raster, Image *image);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -46,14 +46,21 @@ public:
|
|||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
|
|
||||||
|
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||||
|
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||||
|
|
||||||
// Skin plugin
|
// Skin plugin
|
||||||
|
|
||||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||||
int32 getSizeNativeSkin(void *object, int32 offset);
|
int32 getSizeNativeSkin(void *object, int32 offset);
|
||||||
|
|
||||||
|
void initSkin(void);
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
|
||||||
|
// MatFX plugin
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
// Vertex Format plugin
|
// Vertex Format plugin
|
||||||
|
10
src/d3d/rwxboximpl.h
Normal file
10
src/d3d/rwxboximpl.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace rw {
|
||||||
|
namespace xbox {
|
||||||
|
|
||||||
|
void rasterCreate(Raster *raster);
|
||||||
|
uint8 *rasterLock(Raster *raster, int32 level);
|
||||||
|
void rasterUnlock(Raster*, int32);
|
||||||
|
int32 rasterNumLevels(Raster *raster);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
368
src/d3d/xbox.cpp
368
src/d3d/xbox.cpp
@ -12,16 +12,41 @@
|
|||||||
#include "../rwplugins.h"
|
#include "../rwplugins.h"
|
||||||
#include "rwxbox.h"
|
#include "rwxbox.h"
|
||||||
|
|
||||||
|
#include "rwxboximpl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 2
|
#define PLUGIN_ID 2
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace xbox {
|
namespace xbox {
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("xbox open\n");
|
||||||
|
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;
|
||||||
|
// TODO: from image
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initializePlatform(void)
|
initializePlatform(void)
|
||||||
{
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_XBOX, 0, PLATFORM_XBOX,
|
||||||
|
driverOpen, driverClose);
|
||||||
registerNativeRaster();
|
registerNativeRaster();
|
||||||
driver[PLATFORM_XBOX].defaultPipeline = makeDefaultPipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
@ -352,322 +377,6 @@ makeDefaultPipeline(void)
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skin plugin
|
|
||||||
|
|
||||||
struct NativeSkin
|
|
||||||
{
|
|
||||||
int32 table1[256]; // maps indices to bones
|
|
||||||
int32 table2[256]; // maps bones to indices
|
|
||||||
int32 numUsedBones;
|
|
||||||
void *vertexBuffer;
|
|
||||||
int32 stride;
|
|
||||||
};
|
|
||||||
|
|
||||||
Stream*
|
|
||||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
uint32 vers, platform;
|
|
||||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
|
||||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
platform = stream->readU32();
|
|
||||||
if(platform != PLATFORM_XBOX){
|
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
if(vers < 0x35000){
|
|
||||||
RWERROR((ERR_VERSION, vers));
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
Skin *skin = new Skin;
|
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
|
||||||
|
|
||||||
int32 numBones = stream->readI32();
|
|
||||||
skin->init(numBones, 0, 0);
|
|
||||||
NativeSkin *natskin = new NativeSkin;
|
|
||||||
skin->platformData = natskin;
|
|
||||||
stream->read(natskin->table1, 256*sizeof(int32));
|
|
||||||
stream->read(natskin->table2, 256*sizeof(int32));
|
|
||||||
natskin->numUsedBones = stream->readI32();
|
|
||||||
skin->numWeights = stream->readI32();
|
|
||||||
stream->seek(4); // skip pointer to vertexBuffer
|
|
||||||
natskin->stride = stream->readI32();
|
|
||||||
int32 size = geometry->numVertices*natskin->stride;
|
|
||||||
natskin->vertexBuffer = new uint8[size];
|
|
||||||
stream->read(natskin->vertexBuffer, size);
|
|
||||||
stream->read(skin->inverseMatrices, skin->numBones*64);
|
|
||||||
|
|
||||||
// no split skins in GTA
|
|
||||||
stream->seek(12);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream*
|
|
||||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
|
||||||
assert(skin->platformData);
|
|
||||||
assert(rw::version >= 0x35000 && "can't handle native xbox skin < 0x35000");
|
|
||||||
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
|
||||||
|
|
||||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
|
||||||
stream->writeU32(PLATFORM_XBOX);
|
|
||||||
stream->writeI32(skin->numBones);
|
|
||||||
stream->write(natskin->table1, 256*sizeof(int32));
|
|
||||||
stream->write(natskin->table2, 256*sizeof(int32));
|
|
||||||
stream->writeI32(natskin->numUsedBones);
|
|
||||||
stream->writeI32(skin->numWeights);
|
|
||||||
stream->writeU32(0xBADEAFFE); // pointer to vertexBuffer
|
|
||||||
stream->writeI32(natskin->stride);
|
|
||||||
stream->write(natskin->vertexBuffer,
|
|
||||||
geometry->numVertices*natskin->stride);
|
|
||||||
stream->write(skin->inverseMatrices, skin->numBones*64);
|
|
||||||
int32 buffer[3] = { 0, 0, 0};
|
|
||||||
stream->write(buffer, 12);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32
|
|
||||||
getSizeNativeSkin(void *object, int32 offset)
|
|
||||||
{
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return -1;
|
|
||||||
if(skin->platformData == nil)
|
|
||||||
return -1;
|
|
||||||
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
|
||||||
return 12 + 8 + 2*256*4 + 4*4 +
|
|
||||||
natskin->stride*geometry->numVertices + skin->numBones*64 + 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|
||||||
{
|
|
||||||
defaultInstanceCB(geo, header);
|
|
||||||
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return;
|
|
||||||
NativeSkin *natskin = new NativeSkin;
|
|
||||||
skin->platformData = natskin;
|
|
||||||
|
|
||||||
natskin->numUsedBones = skin->numUsedBones;
|
|
||||||
memset(natskin->table1, 0xFF, sizeof(natskin->table1));
|
|
||||||
memset(natskin->table2, 0x00, sizeof(natskin->table2));
|
|
||||||
for(int32 i = 0; i < skin->numUsedBones; i++){
|
|
||||||
natskin->table1[i] = skin->usedBones[i];
|
|
||||||
natskin->table2[skin->usedBones[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
natskin->stride = 3*skin->numWeights;
|
|
||||||
uint8 *vbuf = new uint8[header->numVertices*natskin->stride];
|
|
||||||
natskin->vertexBuffer = vbuf;
|
|
||||||
|
|
||||||
int32 w[4];
|
|
||||||
int sum;
|
|
||||||
float *weights = skin->weights;
|
|
||||||
uint8 *p = vbuf;
|
|
||||||
int32 numVertices = header->numVertices;
|
|
||||||
while(numVertices--){
|
|
||||||
sum = 0;
|
|
||||||
for(int i = 1; i < skin->numWeights; i++){
|
|
||||||
w[i] = weights[i]*255.0f + 0.5f;
|
|
||||||
sum += w[i];
|
|
||||||
}
|
|
||||||
w[0] = 255 - sum;
|
|
||||||
for(int i = 0; i < skin->numWeights; i++)
|
|
||||||
p[i] = w[i];
|
|
||||||
p += natskin->stride;
|
|
||||||
weights += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
numVertices = header->numVertices;
|
|
||||||
p = vbuf + skin->numWeights;
|
|
||||||
uint8 *indices = skin->indices;
|
|
||||||
uint16 *idx;
|
|
||||||
while(numVertices--){
|
|
||||||
idx = (uint16*)p;
|
|
||||||
for(int i = 0; i < skin->numWeights; i++)
|
|
||||||
idx[i] = 3*natskin->table2[indices[i]];
|
|
||||||
p += natskin->stride;
|
|
||||||
indices += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
|
||||||
{
|
|
||||||
defaultUninstanceCB(geo, header);
|
|
||||||
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return;
|
|
||||||
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
|
||||||
|
|
||||||
uint8 *data = skin->data;
|
|
||||||
float *invMats = skin->inverseMatrices;
|
|
||||||
skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices);
|
|
||||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
for(int32 j = 0; j < skin->numUsedBones; j++)
|
|
||||||
skin->usedBones[j] = natskin->table1[j];
|
|
||||||
|
|
||||||
float *weights = skin->weights;
|
|
||||||
uint8 *indices = skin->indices;
|
|
||||||
uint8 *p = (uint8*)natskin->vertexBuffer;
|
|
||||||
int32 numVertices = header->numVertices;
|
|
||||||
float w[4];
|
|
||||||
uint8 i[4];
|
|
||||||
uint16 *ip;
|
|
||||||
while(numVertices--){
|
|
||||||
w[0] = w[1] = w[2] = w[3] = 0.0f;
|
|
||||||
i[0] = i[1] = i[2] = i[3] = 0;
|
|
||||||
|
|
||||||
for(int32 j = 0; j < skin->numWeights; j++)
|
|
||||||
w[j] = *p++/255.0f;
|
|
||||||
|
|
||||||
ip = (uint16*)p;
|
|
||||||
for(int32 j = 0; j < skin->numWeights; j++){
|
|
||||||
i[j] = natskin->table1[*ip++/3];
|
|
||||||
if(w[j] == 0.0f) i[j] = 0; // clean up a bit
|
|
||||||
}
|
|
||||||
p = (uint8*)ip;
|
|
||||||
|
|
||||||
for(int32 j = 0; j < 4; j++){
|
|
||||||
*weights++ = w[j];
|
|
||||||
*indices++ = i[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] (uint8*)natskin->vertexBuffer;
|
|
||||||
delete natskin;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeSkinPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
|
|
||||||
pipe->instanceCB = skinInstanceCB;
|
|
||||||
pipe->uninstanceCB = skinUninstanceCB;
|
|
||||||
pipe->pluginID = ID_SKIN;
|
|
||||||
pipe->pluginData = 1;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeMatFXPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->pluginID = ID_MATFX;
|
|
||||||
pipe->pluginData = 0;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertex Format Plugin
|
|
||||||
|
|
||||||
static int32 vertexFmtOffset;
|
|
||||||
|
|
||||||
uint32 vertexFormatSizes[6] = {
|
|
||||||
0, 1, 2, 2, 4, 4
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32*
|
|
||||||
getVertexFmt(Geometry *g)
|
|
||||||
{
|
|
||||||
return PLUGINOFFSET(uint32, g, vertexFmtOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
makeVertexFmt(int32 flags, uint32 numTexSets)
|
|
||||||
{
|
|
||||||
if(numTexSets > 4)
|
|
||||||
numTexSets = 4;
|
|
||||||
uint32 fmt = 0x5; // FLOAT3
|
|
||||||
if(flags & Geometry::NORMALS)
|
|
||||||
fmt |= 0x40; // NORMPACKED3
|
|
||||||
for(uint32 i = 0; i < numTexSets; i++)
|
|
||||||
fmt |= 0x500 << i*4; // FLOAT2
|
|
||||||
if(flags & Geometry::PRELIT)
|
|
||||||
fmt |= 0x1000000; // D3DCOLOR
|
|
||||||
return fmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
getVertexFmtStride(uint32 fmt)
|
|
||||||
{
|
|
||||||
uint32 stride = 0;
|
|
||||||
uint32 v = fmt & 0xF;
|
|
||||||
uint32 n = (fmt >> 4) & 0xF;
|
|
||||||
stride += v == 4 ? 4 : 3*vertexFormatSizes[v];
|
|
||||||
stride += n == 4 ? 4 : 3*vertexFormatSizes[n];
|
|
||||||
if(fmt & 0x1000000)
|
|
||||||
stride += 4;
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
uint32 t = (fmt >> (i*4 + 8)) & 0xF;
|
|
||||||
stride += t == 4 ? 4 : 2*vertexFormatSizes[t];
|
|
||||||
}
|
|
||||||
if(fmt & 0xE000000)
|
|
||||||
stride += 8;
|
|
||||||
return stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
createVertexFmt(void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
*PLUGINOFFSET(uint32, object, offset) = 0;
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
copyVertexFmt(void *dst, void *src, int32 offset, int32)
|
|
||||||
{
|
|
||||||
*PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Stream*
|
|
||||||
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
uint32 fmt = stream->readU32();
|
|
||||||
*PLUGINOFFSET(uint32, object, offset) = fmt;
|
|
||||||
// TODO: ? create and attach "vertex shader"
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Stream*
|
|
||||||
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
|
||||||
{
|
|
||||||
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32
|
|
||||||
getSizeVertexFmt(void*, int32, int32)
|
|
||||||
{
|
|
||||||
if(rw::platform != PLATFORM_XBOX)
|
|
||||||
return -1;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
registerVertexFormatPlugin(void)
|
|
||||||
{
|
|
||||||
vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT,
|
|
||||||
createVertexFmt, nil, copyVertexFmt);
|
|
||||||
Geometry::registerPluginStream(ID_VERTEXFMT,
|
|
||||||
readVertexFmt,
|
|
||||||
writeVertexFmt,
|
|
||||||
getSizeVertexFmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
|
||||||
int32 nativeRasterOffset;
|
int32 nativeRasterOffset;
|
||||||
@ -790,7 +499,7 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
|||||||
return levels;
|
return levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||||
@ -840,7 +549,7 @@ rasterCreate(Raster *raster)
|
|||||||
format);
|
format);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8*
|
uint8*
|
||||||
rasterLock(Raster *raster, int32 level)
|
rasterLock(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||||
@ -848,12 +557,12 @@ rasterLock(Raster *raster, int32 level)
|
|||||||
return levels->levels[level].data;
|
return levels->levels[level].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterUnlock(Raster*, int32)
|
rasterUnlock(Raster*, int32)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
int32
|
||||||
rasterNumLevels(Raster *raster)
|
rasterNumLevels(Raster *raster)
|
||||||
{
|
{
|
||||||
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||||
@ -900,26 +609,9 @@ copyNativeRaster(void *dst, void *, int32 offset, int32)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
printf("xbox native close\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
registerNativeRaster(void)
|
registerNativeRaster(void)
|
||||||
{
|
{
|
||||||
Engine::registerPlugin(0, ID_RASTERXBOX, nativeOpen, nativeClose);
|
|
||||||
nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster),
|
nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster),
|
||||||
ID_RASTERXBOX,
|
ID_RASTERXBOX,
|
||||||
createNativeRaster,
|
createNativeRaster,
|
||||||
|
379
src/d3d/xboxplugins.cpp
Normal file
379
src/d3d/xboxplugins.cpp
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#include "rwxbox.h"
|
||||||
|
|
||||||
|
#define PLUGIN_ID ID_SKIN // yeah right....
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace xbox {
|
||||||
|
|
||||||
|
// Skin
|
||||||
|
|
||||||
|
struct NativeSkin
|
||||||
|
{
|
||||||
|
int32 table1[256]; // maps indices to bones
|
||||||
|
int32 table2[256]; // maps bones to indices
|
||||||
|
int32 numUsedBones;
|
||||||
|
void *vertexBuffer;
|
||||||
|
int32 stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
Stream*
|
||||||
|
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
uint32 vers, platform;
|
||||||
|
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||||
|
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
platform = stream->readU32();
|
||||||
|
if(platform != PLATFORM_XBOX){
|
||||||
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(vers < 0x35000){
|
||||||
|
RWERROR((ERR_VERSION, vers));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
Skin *skin = new Skin;
|
||||||
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
|
int32 numBones = stream->readI32();
|
||||||
|
skin->init(numBones, 0, 0);
|
||||||
|
NativeSkin *natskin = new NativeSkin;
|
||||||
|
skin->platformData = natskin;
|
||||||
|
stream->read(natskin->table1, 256*sizeof(int32));
|
||||||
|
stream->read(natskin->table2, 256*sizeof(int32));
|
||||||
|
natskin->numUsedBones = stream->readI32();
|
||||||
|
skin->numWeights = stream->readI32();
|
||||||
|
stream->seek(4); // skip pointer to vertexBuffer
|
||||||
|
natskin->stride = stream->readI32();
|
||||||
|
int32 size = geometry->numVertices*natskin->stride;
|
||||||
|
natskin->vertexBuffer = new uint8[size];
|
||||||
|
stream->read(natskin->vertexBuffer, size);
|
||||||
|
stream->read(skin->inverseMatrices, skin->numBones*64);
|
||||||
|
|
||||||
|
// no split skins in GTA
|
||||||
|
stream->seek(12);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream*
|
||||||
|
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||||
|
assert(skin->platformData);
|
||||||
|
assert(rw::version >= 0x35000 && "can't handle native xbox skin < 0x35000");
|
||||||
|
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
||||||
|
|
||||||
|
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||||
|
stream->writeU32(PLATFORM_XBOX);
|
||||||
|
stream->writeI32(skin->numBones);
|
||||||
|
stream->write(natskin->table1, 256*sizeof(int32));
|
||||||
|
stream->write(natskin->table2, 256*sizeof(int32));
|
||||||
|
stream->writeI32(natskin->numUsedBones);
|
||||||
|
stream->writeI32(skin->numWeights);
|
||||||
|
stream->writeU32(0xBADEAFFE); // pointer to vertexBuffer
|
||||||
|
stream->writeI32(natskin->stride);
|
||||||
|
stream->write(natskin->vertexBuffer,
|
||||||
|
geometry->numVertices*natskin->stride);
|
||||||
|
stream->write(skin->inverseMatrices, skin->numBones*64);
|
||||||
|
int32 buffer[3] = { 0, 0, 0};
|
||||||
|
stream->write(buffer, 12);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
getSizeNativeSkin(void *object, int32 offset)
|
||||||
|
{
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return -1;
|
||||||
|
if(skin->platformData == nil)
|
||||||
|
return -1;
|
||||||
|
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
||||||
|
return 12 + 8 + 2*256*4 + 4*4 +
|
||||||
|
natskin->stride*geometry->numVertices + skin->numBones*64 + 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
|
{
|
||||||
|
defaultInstanceCB(geo, header);
|
||||||
|
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return;
|
||||||
|
NativeSkin *natskin = new NativeSkin;
|
||||||
|
skin->platformData = natskin;
|
||||||
|
|
||||||
|
natskin->numUsedBones = skin->numUsedBones;
|
||||||
|
memset(natskin->table1, 0xFF, sizeof(natskin->table1));
|
||||||
|
memset(natskin->table2, 0x00, sizeof(natskin->table2));
|
||||||
|
for(int32 i = 0; i < skin->numUsedBones; i++){
|
||||||
|
natskin->table1[i] = skin->usedBones[i];
|
||||||
|
natskin->table2[skin->usedBones[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
natskin->stride = 3*skin->numWeights;
|
||||||
|
uint8 *vbuf = new uint8[header->numVertices*natskin->stride];
|
||||||
|
natskin->vertexBuffer = vbuf;
|
||||||
|
|
||||||
|
int32 w[4];
|
||||||
|
int sum;
|
||||||
|
float *weights = skin->weights;
|
||||||
|
uint8 *p = vbuf;
|
||||||
|
int32 numVertices = header->numVertices;
|
||||||
|
while(numVertices--){
|
||||||
|
sum = 0;
|
||||||
|
for(int i = 1; i < skin->numWeights; i++){
|
||||||
|
w[i] = weights[i]*255.0f + 0.5f;
|
||||||
|
sum += w[i];
|
||||||
|
}
|
||||||
|
w[0] = 255 - sum;
|
||||||
|
for(int i = 0; i < skin->numWeights; i++)
|
||||||
|
p[i] = w[i];
|
||||||
|
p += natskin->stride;
|
||||||
|
weights += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
numVertices = header->numVertices;
|
||||||
|
p = vbuf + skin->numWeights;
|
||||||
|
uint8 *indices = skin->indices;
|
||||||
|
uint16 *idx;
|
||||||
|
while(numVertices--){
|
||||||
|
idx = (uint16*)p;
|
||||||
|
for(int i = 0; i < skin->numWeights; i++)
|
||||||
|
idx[i] = 3*natskin->table2[indices[i]];
|
||||||
|
p += natskin->stride;
|
||||||
|
indices += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||||
|
{
|
||||||
|
defaultUninstanceCB(geo, header);
|
||||||
|
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return;
|
||||||
|
NativeSkin *natskin = (NativeSkin*)skin->platformData;
|
||||||
|
|
||||||
|
uint8 *data = skin->data;
|
||||||
|
float *invMats = skin->inverseMatrices;
|
||||||
|
skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices);
|
||||||
|
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||||
|
delete[] data;
|
||||||
|
|
||||||
|
for(int32 j = 0; j < skin->numUsedBones; j++)
|
||||||
|
skin->usedBones[j] = natskin->table1[j];
|
||||||
|
|
||||||
|
float *weights = skin->weights;
|
||||||
|
uint8 *indices = skin->indices;
|
||||||
|
uint8 *p = (uint8*)natskin->vertexBuffer;
|
||||||
|
int32 numVertices = header->numVertices;
|
||||||
|
float w[4];
|
||||||
|
uint8 i[4];
|
||||||
|
uint16 *ip;
|
||||||
|
while(numVertices--){
|
||||||
|
w[0] = w[1] = w[2] = w[3] = 0.0f;
|
||||||
|
i[0] = i[1] = i[2] = i[3] = 0;
|
||||||
|
|
||||||
|
for(int32 j = 0; j < skin->numWeights; j++)
|
||||||
|
w[j] = *p++/255.0f;
|
||||||
|
|
||||||
|
ip = (uint16*)p;
|
||||||
|
for(int32 j = 0; j < skin->numWeights; j++){
|
||||||
|
i[j] = natskin->table1[*ip++/3];
|
||||||
|
if(w[j] == 0.0f) i[j] = 0; // clean up a bit
|
||||||
|
}
|
||||||
|
p = (uint8*)ip;
|
||||||
|
|
||||||
|
for(int32 j = 0; j < 4; j++){
|
||||||
|
*weights++ = w[j];
|
||||||
|
*indices++ = i[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] (uint8*)natskin->vertexBuffer;
|
||||||
|
delete natskin;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_XBOX] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeSkinPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
|
||||||
|
pipe->instanceCB = skinInstanceCB;
|
||||||
|
pipe->uninstanceCB = skinUninstanceCB;
|
||||||
|
pipe->pluginID = ID_SKIN;
|
||||||
|
pipe->pluginData = 1;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatFX
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeMatFXPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->pluginID = ID_MATFX;
|
||||||
|
pipe->pluginData = 0;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertex Format
|
||||||
|
|
||||||
|
static int32 vertexFmtOffset;
|
||||||
|
|
||||||
|
uint32 vertexFormatSizes[6] = {
|
||||||
|
0, 1, 2, 2, 4, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32*
|
||||||
|
getVertexFmt(Geometry *g)
|
||||||
|
{
|
||||||
|
return PLUGINOFFSET(uint32, g, vertexFmtOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
makeVertexFmt(int32 flags, uint32 numTexSets)
|
||||||
|
{
|
||||||
|
if(numTexSets > 4)
|
||||||
|
numTexSets = 4;
|
||||||
|
uint32 fmt = 0x5; // FLOAT3
|
||||||
|
if(flags & Geometry::NORMALS)
|
||||||
|
fmt |= 0x40; // NORMPACKED3
|
||||||
|
for(uint32 i = 0; i < numTexSets; i++)
|
||||||
|
fmt |= 0x500 << i*4; // FLOAT2
|
||||||
|
if(flags & Geometry::PRELIT)
|
||||||
|
fmt |= 0x1000000; // D3DCOLOR
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
getVertexFmtStride(uint32 fmt)
|
||||||
|
{
|
||||||
|
uint32 stride = 0;
|
||||||
|
uint32 v = fmt & 0xF;
|
||||||
|
uint32 n = (fmt >> 4) & 0xF;
|
||||||
|
stride += v == 4 ? 4 : 3*vertexFormatSizes[v];
|
||||||
|
stride += n == 4 ? 4 : 3*vertexFormatSizes[n];
|
||||||
|
if(fmt & 0x1000000)
|
||||||
|
stride += 4;
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
uint32 t = (fmt >> (i*4 + 8)) & 0xF;
|
||||||
|
stride += t == 4 ? 4 : 2*vertexFormatSizes[t];
|
||||||
|
}
|
||||||
|
if(fmt & 0xE000000)
|
||||||
|
stride += 8;
|
||||||
|
return stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
createVertexFmt(void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
*PLUGINOFFSET(uint32, object, offset) = 0;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
copyVertexFmt(void *dst, void *src, int32 offset, int32)
|
||||||
|
{
|
||||||
|
*PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream*
|
||||||
|
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
uint32 fmt = stream->readU32();
|
||||||
|
*PLUGINOFFSET(uint32, object, offset) = fmt;
|
||||||
|
// TODO: ? create and attach "vertex shader"
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream*
|
||||||
|
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
||||||
|
{
|
||||||
|
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
getSizeVertexFmt(void*, int32, int32)
|
||||||
|
{
|
||||||
|
if(rw::platform != PLATFORM_XBOX)
|
||||||
|
return -1;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
registerVertexFormatPlugin(void)
|
||||||
|
{
|
||||||
|
vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT,
|
||||||
|
createVertexFmt, nil, copyVertexFmt);
|
||||||
|
Geometry::registerPluginStream(ID_VERTEXFMT,
|
||||||
|
readVertexFmt,
|
||||||
|
writeVertexFmt,
|
||||||
|
getSizeVertexFmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -18,26 +18,16 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
Engine *engine;
|
Engine *engine;
|
||||||
Driver driver[NUM_PLATFORMS];
|
Driver *driver[NUM_PLATFORMS];
|
||||||
|
|
||||||
PluginList Engine::s_plglist = {sizeof(Engine), sizeof(Engine), nil, nil};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Engine::init(void)
|
Engine::init(void)
|
||||||
{
|
{
|
||||||
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
engine = new Engine;
|
||||||
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
|
||||||
driver[i].defaultPipeline = defpipe;
|
|
||||||
|
|
||||||
driver[i].beginUpdate = null::beginUpdate;
|
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||||
driver[i].endUpdate = null::endUpdate;
|
Driver::s_plglist[i] = { sizeof(Driver), sizeof(Driver), nil, nil };
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
Frame::dirtyList.init();
|
Frame::dirtyList.init();
|
||||||
|
|
||||||
ps2::initializePlatform();
|
ps2::initializePlatform();
|
||||||
@ -48,11 +38,29 @@ Engine::init(void)
|
|||||||
gl3::initializePlatform();
|
gl3::initializePlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PluginList Driver::s_plglist[NUM_PLATFORMS];
|
||||||
|
|
||||||
void
|
void
|
||||||
Engine::open(void)
|
Driver::open(void)
|
||||||
{
|
{
|
||||||
rw::engine = (Engine*)malloc(s_plglist.size);
|
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
||||||
s_plglist.construct(rw::engine);
|
|
||||||
|
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
||||||
|
rw::driver[i] = (Driver*)malloc(s_plglist[i].size);
|
||||||
|
|
||||||
|
driver[i]->defaultPipeline = defpipe;
|
||||||
|
|
||||||
|
driver[i]->beginUpdate = null::beginUpdate;
|
||||||
|
driver[i]->endUpdate = null::endUpdate;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
s_plglist[i].construct(rw::driver[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace null {
|
namespace null {
|
||||||
|
70
src/gl/gl3.cpp
Normal file
70
src/gl/gl3.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#endif
|
||||||
|
#include "rwgl3.h"
|
||||||
|
#include "rwgl3shader.h"
|
||||||
|
|
||||||
|
#include "rwgl3impl.h"
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace gl3 {
|
||||||
|
|
||||||
|
// TODO: make some of these things platform-independent
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("gl3 open\n");
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
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;
|
||||||
|
|
||||||
|
initializeRender();
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initializePlatform(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_GL3, 0, PLATFORM_GL3,
|
||||||
|
driverOpen, driverClose);
|
||||||
|
|
||||||
|
registerNativeRaster();
|
||||||
|
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
// uniforms need to be registered before any shaders are created
|
||||||
|
registerBlock("Scene");
|
||||||
|
registerBlock("Object");
|
||||||
|
registerBlock("State");
|
||||||
|
registerUniform("u_matColor");
|
||||||
|
registerUniform("u_surfaceProps");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -21,23 +21,6 @@ namespace gl3 {
|
|||||||
|
|
||||||
// TODO: make some of these things platform-independent
|
// TODO: make some of these things platform-independent
|
||||||
|
|
||||||
void
|
|
||||||
initializePlatform(void)
|
|
||||||
{
|
|
||||||
registerNativeRaster();
|
|
||||||
#ifdef RW_OPENGL
|
|
||||||
driver[PLATFORM_GL3].defaultPipeline = makeDefaultPipeline();
|
|
||||||
|
|
||||||
// uniforms need to be registered before any shaders are created
|
|
||||||
registerBlock("Scene");
|
|
||||||
registerBlock("Object");
|
|
||||||
registerUniform("u_matColor");
|
|
||||||
registerUniform("u_surfaceProps");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
initializeRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RW_OPENGL
|
#ifdef RW_OPENGL
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -251,30 +234,6 @@ makeDefaultPipeline(void)
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeSkinPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_GL3);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_SKIN;
|
|
||||||
pipe->pluginData = 1;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeMatFXPipeline(void)
|
|
||||||
{
|
|
||||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_GL3);
|
|
||||||
pipe->instanceCB = defaultInstanceCB;
|
|
||||||
pipe->uninstanceCB = defaultUninstanceCB;
|
|
||||||
pipe->renderCB = defaultRenderCB;
|
|
||||||
pipe->pluginID = ID_MATFX;
|
|
||||||
pipe->pluginData = 0;
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
95
src/gl/gl3plugins.cpp
Normal file
95
src/gl/gl3plugins.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#endif
|
||||||
|
#include "rwgl3.h"
|
||||||
|
#include "rwgl3shader.h"
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace gl3 {
|
||||||
|
|
||||||
|
#ifdef RW_OPENGL
|
||||||
|
|
||||||
|
// MatFX
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeMatFXPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_GL3);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = matfxRenderCB;
|
||||||
|
pipe->pluginID = ID_MATFX;
|
||||||
|
pipe->pluginData = 0;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skin
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_GL3, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeSkinPipeline(void)
|
||||||
|
{
|
||||||
|
ObjPipeline *pipe = new ObjPipeline(PLATFORM_GL3);
|
||||||
|
pipe->instanceCB = defaultInstanceCB;
|
||||||
|
pipe->uninstanceCB = defaultUninstanceCB;
|
||||||
|
pipe->renderCB = defaultRenderCB;
|
||||||
|
pipe->pluginID = ID_SKIN;
|
||||||
|
pipe->pluginData = 1;
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ namespace gl3 {
|
|||||||
|
|
||||||
int32 nativeRasterOffset;
|
int32 nativeRasterOffset;
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
@ -42,27 +42,27 @@ rasterCreate(Raster *raster)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8*
|
uint8*
|
||||||
rasterLock(Raster*, int32 level)
|
rasterLock(Raster*, int32 level)
|
||||||
{
|
{
|
||||||
printf("locking\n");
|
printf("locking\n");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterUnlock(Raster*, int32)
|
rasterUnlock(Raster*, int32)
|
||||||
{
|
{
|
||||||
printf("unlocking\n");
|
printf("unlocking\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
int32
|
||||||
rasterNumLevels(Raster*)
|
rasterNumLevels(Raster*)
|
||||||
{
|
{
|
||||||
printf("numlevels\n");
|
printf("numlevels\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterFromImage(Raster *raster, Image *image)
|
rasterFromImage(Raster *raster, Image *image)
|
||||||
{
|
{
|
||||||
int32 format;
|
int32 format;
|
||||||
@ -112,26 +112,8 @@ copyNativeRaster(void *dst, void *, int32 offset, int32)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
printf("gl3 native close\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerNativeRaster(void)
|
void registerNativeRaster(void)
|
||||||
{
|
{
|
||||||
Engine::registerPlugin(0, ID_RASTERGL3, nativeOpen, nativeClose);
|
|
||||||
nativeRasterOffset = Raster::registerPlugin(sizeof(Gl3Raster),
|
nativeRasterOffset = Raster::registerPlugin(sizeof(Gl3Raster),
|
||||||
ID_RASTERGL3,
|
ID_RASTERGL3,
|
||||||
createNativeRaster,
|
createNativeRaster,
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
namespace gl3 {
|
namespace gl3 {
|
||||||
|
|
||||||
|
struct UniformState
|
||||||
|
{
|
||||||
|
int alphaFunc;
|
||||||
|
float32 alphaRef;
|
||||||
|
};
|
||||||
|
|
||||||
struct UniformScene
|
struct UniformScene
|
||||||
{
|
{
|
||||||
float32 proj[16];
|
float32 proj[16];
|
||||||
@ -47,8 +53,9 @@ struct UniformObject
|
|||||||
};
|
};
|
||||||
|
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
GLuint ubo_scene, ubo_object;
|
GLuint ubo_state, ubo_scene, ubo_object;
|
||||||
GLuint whitetex;
|
GLuint whitetex;
|
||||||
|
UniformState uniformState;
|
||||||
UniformScene uniformScene;
|
UniformScene uniformScene;
|
||||||
UniformObject uniformObject;
|
UniformObject uniformObject;
|
||||||
|
|
||||||
@ -113,7 +120,7 @@ beginUpdate(Camera *cam)
|
|||||||
void
|
void
|
||||||
initializeRender(void)
|
initializeRender(void)
|
||||||
{
|
{
|
||||||
driver[PLATFORM_GL3].beginUpdate = beginUpdate;
|
driver[PLATFORM_GL3]->beginUpdate = beginUpdate;
|
||||||
|
|
||||||
glClearColor(0.25, 0.25, 0.25, 1.0);
|
glClearColor(0.25, 0.25, 0.25, 1.0);
|
||||||
|
|
||||||
@ -125,6 +132,14 @@ initializeRender(void)
|
|||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
glGenBuffers(1, &ubo_state);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("State"), ubo_state);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformState), &uniformState,
|
||||||
|
GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
|
|
||||||
glGenBuffers(1, &ubo_scene);
|
glGenBuffers(1, &ubo_scene);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
|
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
|
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
|
||||||
@ -163,6 +178,7 @@ setAttribPointers(InstanceDataHeader *header)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool32 stateDirty = 1;
|
||||||
static bool32 sceneDirty = 1;
|
static bool32 sceneDirty = 1;
|
||||||
static bool32 objectDirty = 1;
|
static bool32 objectDirty = 1;
|
||||||
|
|
||||||
@ -262,6 +278,21 @@ setVertexAlpha(bool32 alpha)
|
|||||||
vertexAlpha = alpha;
|
vertexAlpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setAlphaTestFunc(int32 f)
|
||||||
|
{
|
||||||
|
uniformState.alphaFunc = f;
|
||||||
|
stateDirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setAlphaRef(float32 f)
|
||||||
|
{
|
||||||
|
uniformState.alphaRef = f;
|
||||||
|
stateDirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define U(s) currentShader->uniformLocations[findUniform(s)]
|
||||||
|
|
||||||
void
|
void
|
||||||
flushCache(void)
|
flushCache(void)
|
||||||
@ -278,6 +309,12 @@ flushCache(void)
|
|||||||
&uniformScene);
|
&uniformScene);
|
||||||
sceneDirty = 0;
|
sceneDirty = 0;
|
||||||
}
|
}
|
||||||
|
if(stateDirty){
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, ubo_state);
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformState),
|
||||||
|
&uniformState);
|
||||||
|
stateDirty = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -305,6 +342,56 @@ lightingCB(void)
|
|||||||
setAmbientLight(&ambLight);
|
setAmbientLight(&ambLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
matfxRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||||
|
{
|
||||||
|
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||||
|
lightingCB();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||||
|
setAttribPointers(header);
|
||||||
|
|
||||||
|
Material *m;
|
||||||
|
RGBAf col;
|
||||||
|
GLfloat surfProps[4];
|
||||||
|
int id;
|
||||||
|
InstanceData *inst = header->inst;
|
||||||
|
int32 n = header->numMeshes;
|
||||||
|
|
||||||
|
setAlphaTestFunc(1);
|
||||||
|
setAlphaRef(0.2);
|
||||||
|
|
||||||
|
while(n--){
|
||||||
|
m = inst->material;
|
||||||
|
|
||||||
|
convColor(&col, &m->color);
|
||||||
|
glUniform4fv(U("u_matColor"), 1, (GLfloat*)&col);
|
||||||
|
|
||||||
|
surfProps[0] = m->surfaceProps.ambient;
|
||||||
|
surfProps[1] = m->surfaceProps.specular;
|
||||||
|
surfProps[2] = m->surfaceProps.diffuse;
|
||||||
|
surfProps[3] = 0.0f;
|
||||||
|
glUniform4fv(U("u_surfaceProps"), 1, surfProps);
|
||||||
|
|
||||||
|
setTexture(0, m->texture);
|
||||||
|
/*
|
||||||
|
if(MatFX::getEffects(m) == MatFX::ENVMAP){
|
||||||
|
MatFX *fx = MatFX::get(m);
|
||||||
|
int32 idx = fx->getEffectIndex(MatFX::ENVMAP);
|
||||||
|
setTexture(0, fx->fx[idx].env.tex);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
setVertexAlpha(inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||||
|
|
||||||
|
flushCache();
|
||||||
|
glDrawElements(header->primType, inst->numIndex,
|
||||||
|
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||||
|
inst++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||||
{
|
{
|
||||||
@ -322,11 +409,12 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||||||
InstanceData *inst = header->inst;
|
InstanceData *inst = header->inst;
|
||||||
int32 n = header->numMeshes;
|
int32 n = header->numMeshes;
|
||||||
|
|
||||||
|
setAlphaTestFunc(1);
|
||||||
|
setAlphaRef(0.2);
|
||||||
|
|
||||||
while(n--){
|
while(n--){
|
||||||
m = inst->material;
|
m = inst->material;
|
||||||
|
|
||||||
#define U(s) currentShader->uniformLocations[findUniform(s)]
|
|
||||||
|
|
||||||
convColor(&col, &m->color);
|
convColor(&col, &m->color);
|
||||||
glUniform4fv(U("u_matColor"), 1, (GLfloat*)&col);
|
glUniform4fv(U("u_matColor"), 1, (GLfloat*)&col);
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@ struct InstanceDataHeader : rw::InstanceDataHeader
|
|||||||
|
|
||||||
void setAttribPointers(InstanceDataHeader *header);
|
void setAttribPointers(InstanceDataHeader *header);
|
||||||
|
|
||||||
|
// Render state
|
||||||
|
void setAlphaTestFunc(int32 f);
|
||||||
|
void setAlphaRef(float32 f);
|
||||||
|
|
||||||
// per Scene
|
// per Scene
|
||||||
void setProjectionMatrix(float32*);
|
void setProjectionMatrix(float32*);
|
||||||
void setViewMatrix(float32*);
|
void setViewMatrix(float32*);
|
||||||
@ -88,6 +92,8 @@ void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
|
|||||||
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
|
|
||||||
|
void matfxRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
11
src/gl/rwgl3impl.h
Normal file
11
src/gl/rwgl3impl.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace rw {
|
||||||
|
namespace gl3 {
|
||||||
|
|
||||||
|
void rasterCreate(Raster *raster);
|
||||||
|
uint8 *rasterLock(Raster*, int32 level);
|
||||||
|
void rasterUnlock(Raster*, int32);
|
||||||
|
int32 rasterNumLevels(Raster*);
|
||||||
|
void rasterFromImage(Raster *raster, Image *image);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
13
src/gl/rwgl3plg.h
Normal file
13
src/gl/rwgl3plg.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace rw {
|
||||||
|
namespace gl3 {
|
||||||
|
|
||||||
|
void matfxRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
|
|
||||||
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
|
void initSkin(void);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -60,12 +60,16 @@ ObjPipeline *makeDefaultPipeline(void);
|
|||||||
|
|
||||||
// Skin plugin
|
// Skin plugin
|
||||||
|
|
||||||
|
void initSkin(void);
|
||||||
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||||
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||||
int32 getSizeNativeSkin(void *object, int32 offset);
|
int32 getSizeNativeSkin(void *object, int32 offset);
|
||||||
|
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
|
||||||
|
// MatFX plugin
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
// Raster
|
// Raster
|
||||||
|
@ -21,10 +21,25 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
namespace wdgl {
|
namespace wdgl {
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("wdgl open\n");
|
||||||
|
driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initializePlatform(void)
|
initializePlatform(void)
|
||||||
{
|
{
|
||||||
driver[PLATFORM_WDGL].defaultPipeline = makeDefaultPipeline();
|
Driver::registerPlugin(PLATFORM_WDGL, 0, PLATFORM_WDGL,
|
||||||
|
driverOpen, driverClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -659,6 +674,28 @@ skinUninstanceCB(Geometry *geo)
|
|||||||
skin->findUsedBones(geo->numVertices);
|
skin->findUsedBones(geo->numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skin
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_WDGL] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_WDGL, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
ObjPipeline*
|
||||||
makeSkinPipeline(void)
|
makeSkinPipeline(void)
|
||||||
{
|
{
|
||||||
@ -671,6 +708,28 @@ makeSkinPipeline(void)
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatFX
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_WDGL] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_WDGL, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
ObjPipeline*
|
||||||
makeMatFXPipeline(void)
|
makeMatFXPipeline(void)
|
||||||
{
|
{
|
||||||
|
@ -691,7 +691,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
|
|||||||
raster->texels = raster->palette = nil;
|
raster->texels = raster->palette = nil;
|
||||||
s_plglist.construct(raster);
|
s_plglist.construct(raster);
|
||||||
|
|
||||||
driver[raster->platform].rasterCreate(raster);
|
driver[raster->platform]->rasterCreate(raster);
|
||||||
return raster;
|
return raster;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,19 +707,19 @@ Raster::destroy(void)
|
|||||||
uint8*
|
uint8*
|
||||||
Raster::lock(int32 level)
|
Raster::lock(int32 level)
|
||||||
{
|
{
|
||||||
return driver[this->platform].rasterLock(this, level);
|
return driver[this->platform]->rasterLock(this, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Raster::unlock(int32 level)
|
Raster::unlock(int32 level)
|
||||||
{
|
{
|
||||||
driver[this->platform].rasterUnlock(this, level);
|
driver[this->platform]->rasterUnlock(this, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Raster::getNumLevels(void)
|
Raster::getNumLevels(void)
|
||||||
{
|
{
|
||||||
return driver[this->platform].rasterNumLevels(this);
|
return driver[this->platform]->rasterNumLevels(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
@ -737,7 +737,7 @@ Raster::createFromImage(Image *image)
|
|||||||
{
|
{
|
||||||
Raster *raster = Raster::create(image->width, image->height,
|
Raster *raster = Raster::create(image->width, image->height,
|
||||||
image->depth, 4 | 0x80);
|
image->depth, 4 | 0x80);
|
||||||
driver[raster->platform].rasterFromImage(raster, image);
|
driver[raster->platform]->rasterFromImage(raster, image);
|
||||||
return raster;
|
return raster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "d3d/rwd3d9.h"
|
#include "d3d/rwd3d9.h"
|
||||||
#include "gl/rwwdgl.h"
|
#include "gl/rwwdgl.h"
|
||||||
#include "gl/rwgl3.h"
|
#include "gl/rwgl3.h"
|
||||||
|
#include "gl/rwgl3plg.h"
|
||||||
|
|
||||||
#define PLUGIN_ID ID_MATFX
|
#define PLUGIN_ID ID_MATFX
|
||||||
|
|
||||||
@ -128,6 +129,12 @@ MatFX::getEffects(Material *m)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MatFX*
|
||||||
|
MatFX::get(Material *m)
|
||||||
|
{
|
||||||
|
return *PLUGINOFFSET(MatFX*, m, matFXGlobals.materialOffset);
|
||||||
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
MatFX::getEffectIndex(uint32 type)
|
MatFX::getEffectIndex(uint32 type)
|
||||||
{
|
{
|
||||||
@ -410,28 +417,6 @@ MatFX::enableEffects(Atomic *atomic)
|
|||||||
atomic->pipeline = matFXGlobals.pipelines[rw::platform];
|
atomic->pipeline = matFXGlobals.pipelines[rw::platform];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
matfxOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
matFXGlobals.pipelines[PLATFORM_PS2] =
|
|
||||||
ps2::makeMatFXPipeline();
|
|
||||||
matFXGlobals.pipelines[PLATFORM_XBOX] =
|
|
||||||
xbox::makeMatFXPipeline();
|
|
||||||
matFXGlobals.pipelines[PLATFORM_D3D8] =
|
|
||||||
d3d8::makeMatFXPipeline();
|
|
||||||
matFXGlobals.pipelines[PLATFORM_D3D9] =
|
|
||||||
d3d9::makeMatFXPipeline();
|
|
||||||
matFXGlobals.pipelines[PLATFORM_WDGL] =
|
|
||||||
wdgl::makeMatFXPipeline();
|
|
||||||
matFXGlobals.pipelines[PLATFORM_GL3] =
|
|
||||||
gl3::makeMatFXPipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
matfxClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
registerMatFXPlugin(void)
|
registerMatFXPlugin(void)
|
||||||
{
|
{
|
||||||
@ -442,10 +427,12 @@ registerMatFXPlugin(void)
|
|||||||
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)
|
for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++)
|
||||||
matFXGlobals.pipelines[i] = defpipe;
|
matFXGlobals.pipelines[i] = defpipe;
|
||||||
|
|
||||||
// TODO: call platform specific init functions?
|
ps2::initMatFX();
|
||||||
// have platform specific open functions?
|
xbox::initMatFX();
|
||||||
|
d3d8::initMatFX();
|
||||||
Engine::registerPlugin(0, ID_MATFX, matfxOpen, matfxClose);
|
d3d9::initMatFX();
|
||||||
|
wdgl::initMatFX();
|
||||||
|
gl3::initMatFX();
|
||||||
|
|
||||||
matFXGlobals.atomicOffset =
|
matFXGlobals.atomicOffset =
|
||||||
Atomic::registerPlugin(sizeof(int32), ID_MATFX,
|
Atomic::registerPlugin(sizeof(int32), ID_MATFX,
|
||||||
|
335
src/ps2/ps2.cpp
335
src/ps2/ps2.cpp
@ -13,16 +13,40 @@
|
|||||||
#include "rwps2.h"
|
#include "rwps2.h"
|
||||||
#include "rwps2plg.h"
|
#include "rwps2plg.h"
|
||||||
|
|
||||||
|
#include "rwps2impl.h"
|
||||||
|
|
||||||
#define PLUGIN_ID 2
|
#define PLUGIN_ID 2
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace ps2 {
|
namespace ps2 {
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
printf("ps2 open\n");
|
||||||
|
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;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
driverClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initializePlatform(void)
|
initializePlatform(void)
|
||||||
{
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_PS2, 0, PLATFORM_PS2,
|
||||||
|
driverOpen, driverClose);
|
||||||
|
|
||||||
registerNativeRaster();
|
registerNativeRaster();
|
||||||
driver[PLATFORM_PS2].defaultPipeline = makeDefaultPipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline *defaultObjPipe;
|
ObjPipeline *defaultObjPipe;
|
||||||
@ -1068,315 +1092,6 @@ makeDefaultPipeline(void)
|
|||||||
return defaultObjPipe;
|
return defaultObjPipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeSkinPipeline(void)
|
|
||||||
{
|
|
||||||
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
|
|
||||||
pipe->pluginID = ID_SKIN;
|
|
||||||
pipe->pluginData = 1;
|
|
||||||
pipe->attribs[AT_XYZ] = &attribXYZ;
|
|
||||||
pipe->attribs[AT_UV] = &attribUV;
|
|
||||||
pipe->attribs[AT_RGBA] = &attribRGBA;
|
|
||||||
pipe->attribs[AT_NORMAL] = &attribNormal;
|
|
||||||
pipe->attribs[AT_NORMAL+1] = &attribWeights;
|
|
||||||
uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
|
|
||||||
pipe->setTriBufferSizes(5, vertCount);
|
|
||||||
pipe->vifOffset = pipe->inputStride*vertCount;
|
|
||||||
pipe->instanceCB = skinInstanceCB;
|
|
||||||
pipe->uninstanceCB = genericUninstanceCB;
|
|
||||||
pipe->preUninstCB = skinPreCB;
|
|
||||||
pipe->postUninstCB = skinPostCB;
|
|
||||||
|
|
||||||
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
|
||||||
opipe->pluginID = ID_SKIN;
|
|
||||||
opipe->pluginData = 1;
|
|
||||||
opipe->groupPipeline = pipe;
|
|
||||||
return opipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjPipeline*
|
|
||||||
makeMatFXPipeline(void)
|
|
||||||
{
|
|
||||||
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
|
|
||||||
pipe->pluginID = ID_MATFX;
|
|
||||||
pipe->pluginData = 0;
|
|
||||||
pipe->attribs[AT_XYZ] = &attribXYZ;
|
|
||||||
pipe->attribs[AT_UV] = &attribUV;
|
|
||||||
pipe->attribs[AT_RGBA] = &attribRGBA;
|
|
||||||
pipe->attribs[AT_NORMAL] = &attribNormal;
|
|
||||||
uint32 vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
|
|
||||||
pipe->setTriBufferSizes(4, vertCount);
|
|
||||||
pipe->vifOffset = pipe->inputStride*vertCount;
|
|
||||||
pipe->uninstanceCB = genericUninstanceCB;
|
|
||||||
|
|
||||||
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
|
||||||
opipe->pluginID = ID_MATFX;
|
|
||||||
opipe->pluginData = 0;
|
|
||||||
opipe->groupPipeline = pipe;
|
|
||||||
return opipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skin
|
|
||||||
|
|
||||||
Stream*
|
|
||||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
|
||||||
{
|
|
||||||
uint8 header[4];
|
|
||||||
Geometry *geometry = (Geometry*)object;
|
|
||||||
uint32 platform;
|
|
||||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
|
||||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
platform = stream->readU32();
|
|
||||||
if(platform != PLATFORM_PS2){
|
|
||||||
RWERROR((ERR_PLATFORM, platform));
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
stream->read(header, 4);
|
|
||||||
Skin *skin = new Skin;
|
|
||||||
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
|
||||||
|
|
||||||
// numUsedBones and numWeights appear in/after 34003 but not in/before 33002
|
|
||||||
// (probably rw::version >= 0x34000)
|
|
||||||
bool oldFormat = header[1] == 0;
|
|
||||||
|
|
||||||
// Use numBones for numUsedBones to allocate data
|
|
||||||
if(oldFormat)
|
|
||||||
skin->init(header[0], header[0], 0);
|
|
||||||
else
|
|
||||||
skin->init(header[0], header[1], 0);
|
|
||||||
skin->numWeights = header[2];
|
|
||||||
|
|
||||||
if(!oldFormat)
|
|
||||||
stream->read(skin->usedBones, skin->numUsedBones);
|
|
||||||
if(skin->numBones)
|
|
||||||
stream->read(skin->inverseMatrices, skin->numBones*64);
|
|
||||||
|
|
||||||
// dummy data in case we need to write data in the new format
|
|
||||||
if(oldFormat){
|
|
||||||
skin->numWeights = 4;
|
|
||||||
for(int32 i = 0; i < skin->numUsedBones; i++)
|
|
||||||
skin->usedBones[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!oldFormat)
|
|
||||||
// last 3 ints are split data as in the other formats
|
|
||||||
// TODO: what are the other 4?
|
|
||||||
stream->seek(7*4);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream*
|
|
||||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
|
||||||
{
|
|
||||||
uint8 header[4];
|
|
||||||
|
|
||||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
|
||||||
stream->writeU32(PLATFORM_PS2);
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
|
||||||
// not sure which version introduced the new format
|
|
||||||
bool oldFormat = version < 0x34000;
|
|
||||||
header[0] = skin->numBones;
|
|
||||||
if(oldFormat){
|
|
||||||
header[1] = 0;
|
|
||||||
header[2] = 0;
|
|
||||||
}else{
|
|
||||||
header[1] = skin->numUsedBones;
|
|
||||||
header[2] = skin->numWeights;
|
|
||||||
}
|
|
||||||
header[3] = 0;
|
|
||||||
stream->write(header, 4);
|
|
||||||
|
|
||||||
if(!oldFormat)
|
|
||||||
stream->write(skin->usedBones, skin->numUsedBones);
|
|
||||||
stream->write(skin->inverseMatrices, skin->numBones*64);
|
|
||||||
if(!oldFormat){
|
|
||||||
uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
stream->write(buffer, 7*4);
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32
|
|
||||||
getSizeNativeSkin(void *object, int32 offset)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return -1;
|
|
||||||
int32 size = 12 + 4 + 4 + skin->numBones*64;
|
|
||||||
// not sure which version introduced the new format
|
|
||||||
if(version >= 0x34000)
|
|
||||||
size += skin->numUsedBones + 16 + 12;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
instanceSkinData(Geometry*, Mesh *m, Skin *skin, uint32 *data)
|
|
||||||
{
|
|
||||||
uint16 j;
|
|
||||||
float32 *weights = (float32*)data;
|
|
||||||
uint32 *indices = data;
|
|
||||||
for(uint32 i = 0; i < m->numIndices; i++){
|
|
||||||
j = m->indices[i];
|
|
||||||
for(int32 k = 0; k < 4; k++){
|
|
||||||
*weights++ = skin->weights[j*4+k];
|
|
||||||
*indices &= ~0x3FF;
|
|
||||||
*indices++ |= skin->indices[j*4+k] && skin->weights[j*4+k] ?
|
|
||||||
(skin->indices[j*4+k]+1) << 2 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return;
|
|
||||||
instanceSkinData(g, m, skin, (uint32*)data[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: call base function perhaps?
|
|
||||||
int32
|
|
||||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
|
||||||
float32 *wghts = nil;
|
|
||||||
uint8 *inds = nil;
|
|
||||||
if(skin){
|
|
||||||
wghts = skin->weights;
|
|
||||||
inds = skin->indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
float32 *verts = g->morphTargets[0].vertices;
|
|
||||||
float32 *tex = g->texCoords[0];
|
|
||||||
float32 *tex1 = g->texCoords[1];
|
|
||||||
float32 *norms = g->morphTargets[0].normals;
|
|
||||||
uint8 *cols = g->colors;
|
|
||||||
|
|
||||||
for(int32 i = 0; i < g->numVertices; i++){
|
|
||||||
uint32 flag = flags ? flags[i] : ~0;
|
|
||||||
if(mask & flag & 0x1 &&
|
|
||||||
!(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
|
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x10 &&
|
|
||||||
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x100 &&
|
|
||||||
!(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3]))
|
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x1000 &&
|
|
||||||
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x2000 &&
|
|
||||||
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x10000 &&
|
|
||||||
!(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
|
|
||||||
wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
|
|
||||||
inds[0] == v->i[0] && inds[1] == v->i[1] &&
|
|
||||||
inds[2] == v->i[2] && inds[3] == v->i[3]))
|
|
||||||
goto cont;
|
|
||||||
return i;
|
|
||||||
cont:
|
|
||||||
verts += 3;
|
|
||||||
tex += 2;
|
|
||||||
norms += 3;
|
|
||||||
cols += 4;
|
|
||||||
wghts += 4;
|
|
||||||
inds += 4;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
|
||||||
insertVertex(geo, i, mask, v);
|
|
||||||
if(mask & 0x10000){
|
|
||||||
memcpy(&skin->weights[i*4], v->w, 16);
|
|
||||||
memcpy(&skin->indices[i*4], v->i, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void
|
|
||||||
skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
|
|
||||||
{
|
|
||||||
float32 *verts = (float32*)data[AT_XYZ];
|
|
||||||
float32 *texcoords = (float32*)data[AT_UV];
|
|
||||||
uint8 *colors = (uint8*)data[AT_RGBA];
|
|
||||||
int8 *norms = (int8*)data[AT_NORMAL];
|
|
||||||
uint32 *wghts = (uint32*)data[AT_NORMAL+1];
|
|
||||||
uint32 mask = 0x1; // vertices
|
|
||||||
if(geo->geoflags & Geometry::NORMALS)
|
|
||||||
mask |= 0x10;
|
|
||||||
if(geo->geoflags & Geometry::PRELIT)
|
|
||||||
mask |= 0x100;
|
|
||||||
if(geo->numTexCoordSets > 0)
|
|
||||||
mask |= 0x1000;
|
|
||||||
mask |= 0x10000;
|
|
||||||
|
|
||||||
Vertex v;
|
|
||||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
|
||||||
if(mask & 0x1)
|
|
||||||
memcpy(&v.p, verts, 12);
|
|
||||||
if(mask & 0x10){
|
|
||||||
v.n[0] = norms[0]/127.0f;
|
|
||||||
v.n[1] = norms[1]/127.0f;
|
|
||||||
v.n[2] = norms[2]/127.0f;
|
|
||||||
}
|
|
||||||
if(mask & 0x100)
|
|
||||||
memcpy(&v.c, colors, 4);
|
|
||||||
if(mask & 0x1000)
|
|
||||||
memcpy(&v.t, texcoords, 8);
|
|
||||||
for(int j = 0; j < 4; j++){
|
|
||||||
((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
|
|
||||||
v.i[j] = (wghts[j] & 0x3FF) >> 2;
|
|
||||||
if(v.i[j]) v.i[j]--;
|
|
||||||
if(v.w[j] == 0.0f) v.i[j] = 0;
|
|
||||||
}
|
|
||||||
int32 idx = findVertexSkin(geo, flags, mask, &v);
|
|
||||||
if(idx < 0)
|
|
||||||
idx = geo->numVertices++;
|
|
||||||
mesh->indices[i] = idx;
|
|
||||||
flags[idx] = mask;
|
|
||||||
insertVertexSkin(geo, idx, mask, &v);
|
|
||||||
verts += 3;
|
|
||||||
texcoords += 2;
|
|
||||||
colors += 4;
|
|
||||||
norms += 3;
|
|
||||||
wghts += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
skinPreCB(MatPipeline*, Geometry *geo)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
|
||||||
if(skin == nil)
|
|
||||||
return;
|
|
||||||
uint8 *data = skin->data;
|
|
||||||
float *invMats = skin->inverseMatrices;
|
|
||||||
// meshHeader->totalIndices is highest possible number of vertices again
|
|
||||||
skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices);
|
|
||||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
skinPostCB(MatPipeline*, Geometry *geo)
|
|
||||||
{
|
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
|
||||||
if(skin){
|
|
||||||
skin->findNumWeights(geo->numVertices);
|
|
||||||
skin->findUsedBones(geo->numVertices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
|
|
||||||
int32 adcOffset;
|
int32 adcOffset;
|
||||||
|
64
src/ps2/ps2matfx.cpp
Normal file
64
src/ps2/ps2matfx.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#include "rwps2.h"
|
||||||
|
#include "rwps2plg.h"
|
||||||
|
|
||||||
|
#define PLUGIN_ID ID_MATFX
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace ps2 {
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
matFXGlobals.pipelines[PLATFORM_PS2] = makeMatFXPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
matfxClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initMatFX(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_PS2, 0, ID_MATFX,
|
||||||
|
matfxOpen, matfxClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeMatFXPipeline(void)
|
||||||
|
{
|
||||||
|
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_MATFX;
|
||||||
|
pipe->pluginData = 0;
|
||||||
|
pipe->attribs[AT_XYZ] = &attribXYZ;
|
||||||
|
pipe->attribs[AT_UV] = &attribUV;
|
||||||
|
pipe->attribs[AT_RGBA] = &attribRGBA;
|
||||||
|
pipe->attribs[AT_NORMAL] = &attribNormal;
|
||||||
|
uint32 vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
|
||||||
|
pipe->setTriBufferSizes(4, vertCount);
|
||||||
|
pipe->vifOffset = pipe->inputStride*vertCount;
|
||||||
|
pipe->uninstanceCB = genericUninstanceCB;
|
||||||
|
|
||||||
|
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
||||||
|
opipe->pluginID = ID_MATFX;
|
||||||
|
opipe->pluginData = 0;
|
||||||
|
opipe->groupPipeline = pipe;
|
||||||
|
return opipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -61,15 +61,9 @@ ps2MinSize(int32 psm, int32 flags, int32 *minw, int32 *minh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dword
|
|
||||||
{
|
|
||||||
uint32 lo;
|
|
||||||
uint32 hi;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ALIGN64(x) ((x) + 0x3F & ~0x3F)
|
#define ALIGN64(x) ((x) + 0x3F & ~0x3F)
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterCreate(Raster *raster)
|
rasterCreate(Raster *raster)
|
||||||
{
|
{
|
||||||
uint64 bufferWidth[7], bufferBase[7];
|
uint64 bufferWidth[7], bufferBase[7];
|
||||||
@ -380,7 +374,7 @@ rasterCreate(Raster *raster)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8*
|
uint8*
|
||||||
rasterLock(Raster *raster, int32 level)
|
rasterLock(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@ -389,7 +383,7 @@ rasterLock(Raster *raster, int32 level)
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
rasterUnlock(Raster *raster, int32 level)
|
rasterUnlock(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@ -397,7 +391,7 @@ rasterUnlock(Raster *raster, int32 level)
|
|||||||
(void)level;
|
(void)level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
int32
|
||||||
rasterNumLevels(Raster *raster)
|
rasterNumLevels(Raster *raster)
|
||||||
{
|
{
|
||||||
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
|
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
|
||||||
@ -476,26 +470,9 @@ getSizeMipmap(void*, int32, int32)
|
|||||||
return rw::platform == PLATFORM_PS2 ? 4 : 0;
|
return rw::platform == PLATFORM_PS2 ? 4 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
nativeClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
printf("ps2 native close\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
registerNativeRaster(void)
|
registerNativeRaster(void)
|
||||||
{
|
{
|
||||||
Engine::registerPlugin(0, ID_RASTERPS2, nativeOpen, nativeClose);
|
|
||||||
nativeRasterOffset = Raster::registerPlugin(sizeof(Ps2Raster),
|
nativeRasterOffset = Raster::registerPlugin(sizeof(Ps2Raster),
|
||||||
ID_RASTERPS2,
|
ID_RASTERPS2,
|
||||||
createNativeRaster,
|
createNativeRaster,
|
||||||
|
329
src/ps2/ps2skin.cpp
Normal file
329
src/ps2/ps2skin.cpp
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
#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 "../rwplugins.h"
|
||||||
|
#include "rwps2.h"
|
||||||
|
#include "rwps2plg.h"
|
||||||
|
|
||||||
|
#include "rwps2impl.h"
|
||||||
|
|
||||||
|
#define PLUGIN_ID ID_SKIN
|
||||||
|
|
||||||
|
namespace rw {
|
||||||
|
namespace ps2 {
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinOpen(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
skinGlobals.pipelines[PLATFORM_PS2] = makeSkinPipeline();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
skinClose(void *o, int32, int32)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initSkin(void)
|
||||||
|
{
|
||||||
|
Driver::registerPlugin(PLATFORM_PS2, 0, ID_SKIN,
|
||||||
|
skinOpen, skinClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjPipeline*
|
||||||
|
makeSkinPipeline(void)
|
||||||
|
{
|
||||||
|
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
|
||||||
|
pipe->pluginID = ID_SKIN;
|
||||||
|
pipe->pluginData = 1;
|
||||||
|
pipe->attribs[AT_XYZ] = &attribXYZ;
|
||||||
|
pipe->attribs[AT_UV] = &attribUV;
|
||||||
|
pipe->attribs[AT_RGBA] = &attribRGBA;
|
||||||
|
pipe->attribs[AT_NORMAL] = &attribNormal;
|
||||||
|
pipe->attribs[AT_NORMAL+1] = &attribWeights;
|
||||||
|
uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
|
||||||
|
pipe->setTriBufferSizes(5, vertCount);
|
||||||
|
pipe->vifOffset = pipe->inputStride*vertCount;
|
||||||
|
pipe->instanceCB = skinInstanceCB;
|
||||||
|
pipe->uninstanceCB = genericUninstanceCB;
|
||||||
|
pipe->preUninstCB = skinPreCB;
|
||||||
|
pipe->postUninstCB = skinPostCB;
|
||||||
|
|
||||||
|
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
||||||
|
opipe->pluginID = ID_SKIN;
|
||||||
|
opipe->pluginData = 1;
|
||||||
|
opipe->groupPipeline = pipe;
|
||||||
|
return opipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream*
|
||||||
|
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||||
|
{
|
||||||
|
uint8 header[4];
|
||||||
|
Geometry *geometry = (Geometry*)object;
|
||||||
|
uint32 platform;
|
||||||
|
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||||
|
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
platform = stream->readU32();
|
||||||
|
if(platform != PLATFORM_PS2){
|
||||||
|
RWERROR((ERR_PLATFORM, platform));
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
stream->read(header, 4);
|
||||||
|
Skin *skin = new Skin;
|
||||||
|
*PLUGINOFFSET(Skin*, geometry, offset) = skin;
|
||||||
|
|
||||||
|
// numUsedBones and numWeights appear in/after 34003 but not in/before 33002
|
||||||
|
// (probably rw::version >= 0x34000)
|
||||||
|
bool oldFormat = header[1] == 0;
|
||||||
|
|
||||||
|
// Use numBones for numUsedBones to allocate data
|
||||||
|
if(oldFormat)
|
||||||
|
skin->init(header[0], header[0], 0);
|
||||||
|
else
|
||||||
|
skin->init(header[0], header[1], 0);
|
||||||
|
skin->numWeights = header[2];
|
||||||
|
|
||||||
|
if(!oldFormat)
|
||||||
|
stream->read(skin->usedBones, skin->numUsedBones);
|
||||||
|
if(skin->numBones)
|
||||||
|
stream->read(skin->inverseMatrices, skin->numBones*64);
|
||||||
|
|
||||||
|
// dummy data in case we need to write data in the new format
|
||||||
|
if(oldFormat){
|
||||||
|
skin->numWeights = 4;
|
||||||
|
for(int32 i = 0; i < skin->numUsedBones; i++)
|
||||||
|
skin->usedBones[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!oldFormat)
|
||||||
|
// last 3 ints are split data as in the other formats
|
||||||
|
// TODO: what are the other 4?
|
||||||
|
stream->seek(7*4);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream*
|
||||||
|
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||||
|
{
|
||||||
|
uint8 header[4];
|
||||||
|
|
||||||
|
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||||
|
stream->writeU32(PLATFORM_PS2);
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||||
|
// not sure which version introduced the new format
|
||||||
|
bool oldFormat = version < 0x34000;
|
||||||
|
header[0] = skin->numBones;
|
||||||
|
if(oldFormat){
|
||||||
|
header[1] = 0;
|
||||||
|
header[2] = 0;
|
||||||
|
}else{
|
||||||
|
header[1] = skin->numUsedBones;
|
||||||
|
header[2] = skin->numWeights;
|
||||||
|
}
|
||||||
|
header[3] = 0;
|
||||||
|
stream->write(header, 4);
|
||||||
|
|
||||||
|
if(!oldFormat)
|
||||||
|
stream->write(skin->usedBones, skin->numUsedBones);
|
||||||
|
stream->write(skin->inverseMatrices, skin->numBones*64);
|
||||||
|
if(!oldFormat){
|
||||||
|
uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
stream->write(buffer, 7*4);
|
||||||
|
}
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
getSizeNativeSkin(void *object, int32 offset)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return -1;
|
||||||
|
int32 size = 12 + 4 + 4 + skin->numBones*64;
|
||||||
|
// not sure which version introduced the new format
|
||||||
|
if(version >= 0x34000)
|
||||||
|
size += skin->numUsedBones + 16 + 12;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
instanceSkinData(Geometry*, Mesh *m, Skin *skin, uint32 *data)
|
||||||
|
{
|
||||||
|
uint16 j;
|
||||||
|
float32 *weights = (float32*)data;
|
||||||
|
uint32 *indices = data;
|
||||||
|
for(uint32 i = 0; i < m->numIndices; i++){
|
||||||
|
j = m->indices[i];
|
||||||
|
for(int32 k = 0; k < 4; k++){
|
||||||
|
*weights++ = skin->weights[j*4+k];
|
||||||
|
*indices &= ~0x3FF;
|
||||||
|
*indices++ |= skin->indices[j*4+k] && skin->weights[j*4+k] ?
|
||||||
|
(skin->indices[j*4+k]+1) << 2 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return;
|
||||||
|
instanceSkinData(g, m, skin, (uint32*)data[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: call base function perhaps?
|
||||||
|
int32
|
||||||
|
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||||
|
float32 *wghts = nil;
|
||||||
|
uint8 *inds = nil;
|
||||||
|
if(skin){
|
||||||
|
wghts = skin->weights;
|
||||||
|
inds = skin->indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
float32 *verts = g->morphTargets[0].vertices;
|
||||||
|
float32 *tex = g->texCoords[0];
|
||||||
|
float32 *tex1 = g->texCoords[1];
|
||||||
|
float32 *norms = g->morphTargets[0].normals;
|
||||||
|
uint8 *cols = g->colors;
|
||||||
|
|
||||||
|
for(int32 i = 0; i < g->numVertices; i++){
|
||||||
|
uint32 flag = flags ? flags[i] : ~0;
|
||||||
|
if(mask & flag & 0x1 &&
|
||||||
|
!(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flag & 0x10 &&
|
||||||
|
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flag & 0x100 &&
|
||||||
|
!(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flag & 0x1000 &&
|
||||||
|
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flag & 0x2000 &&
|
||||||
|
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
||||||
|
goto cont;
|
||||||
|
if(mask & flag & 0x10000 &&
|
||||||
|
!(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
|
||||||
|
wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
|
||||||
|
inds[0] == v->i[0] && inds[1] == v->i[1] &&
|
||||||
|
inds[2] == v->i[2] && inds[3] == v->i[3]))
|
||||||
|
goto cont;
|
||||||
|
return i;
|
||||||
|
cont:
|
||||||
|
verts += 3;
|
||||||
|
tex += 2;
|
||||||
|
norms += 3;
|
||||||
|
cols += 4;
|
||||||
|
wghts += 4;
|
||||||
|
inds += 4;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
insertVertex(geo, i, mask, v);
|
||||||
|
if(mask & 0x10000){
|
||||||
|
memcpy(&skin->weights[i*4], v->w, 16);
|
||||||
|
memcpy(&skin->indices[i*4], v->i, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void
|
||||||
|
skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
|
||||||
|
{
|
||||||
|
float32 *verts = (float32*)data[AT_XYZ];
|
||||||
|
float32 *texcoords = (float32*)data[AT_UV];
|
||||||
|
uint8 *colors = (uint8*)data[AT_RGBA];
|
||||||
|
int8 *norms = (int8*)data[AT_NORMAL];
|
||||||
|
uint32 *wghts = (uint32*)data[AT_NORMAL+1];
|
||||||
|
uint32 mask = 0x1; // vertices
|
||||||
|
if(geo->geoflags & Geometry::NORMALS)
|
||||||
|
mask |= 0x10;
|
||||||
|
if(geo->geoflags & Geometry::PRELIT)
|
||||||
|
mask |= 0x100;
|
||||||
|
if(geo->numTexCoordSets > 0)
|
||||||
|
mask |= 0x1000;
|
||||||
|
mask |= 0x10000;
|
||||||
|
|
||||||
|
Vertex v;
|
||||||
|
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||||
|
if(mask & 0x1)
|
||||||
|
memcpy(&v.p, verts, 12);
|
||||||
|
if(mask & 0x10){
|
||||||
|
v.n[0] = norms[0]/127.0f;
|
||||||
|
v.n[1] = norms[1]/127.0f;
|
||||||
|
v.n[2] = norms[2]/127.0f;
|
||||||
|
}
|
||||||
|
if(mask & 0x100)
|
||||||
|
memcpy(&v.c, colors, 4);
|
||||||
|
if(mask & 0x1000)
|
||||||
|
memcpy(&v.t, texcoords, 8);
|
||||||
|
for(int j = 0; j < 4; j++){
|
||||||
|
((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
|
||||||
|
v.i[j] = (wghts[j] & 0x3FF) >> 2;
|
||||||
|
if(v.i[j]) v.i[j]--;
|
||||||
|
if(v.w[j] == 0.0f) v.i[j] = 0;
|
||||||
|
}
|
||||||
|
int32 idx = findVertexSkin(geo, flags, mask, &v);
|
||||||
|
if(idx < 0)
|
||||||
|
idx = geo->numVertices++;
|
||||||
|
mesh->indices[i] = idx;
|
||||||
|
flags[idx] = mask;
|
||||||
|
insertVertexSkin(geo, idx, mask, &v);
|
||||||
|
verts += 3;
|
||||||
|
texcoords += 2;
|
||||||
|
colors += 4;
|
||||||
|
norms += 3;
|
||||||
|
wghts += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
skinPreCB(MatPipeline*, Geometry *geo)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
if(skin == nil)
|
||||||
|
return;
|
||||||
|
uint8 *data = skin->data;
|
||||||
|
float *invMats = skin->inverseMatrices;
|
||||||
|
// meshHeader->totalIndices is highest possible number of vertices again
|
||||||
|
skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices);
|
||||||
|
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
skinPostCB(MatPipeline*, Geometry *geo)
|
||||||
|
{
|
||||||
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
|
if(skin){
|
||||||
|
skin->findNumWeights(geo->numVertices);
|
||||||
|
skin->findUsedBones(geo->numVertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
11
src/ps2/rwps2impl.h
Normal file
11
src/ps2/rwps2impl.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace rw {
|
||||||
|
namespace ps2 {
|
||||||
|
|
||||||
|
void rasterCreate(Raster *raster);
|
||||||
|
uint8 *rasterLock(Raster*, int32 level);
|
||||||
|
void rasterUnlock(Raster*, int32);
|
||||||
|
int32 rasterNumLevels(Raster*);
|
||||||
|
void rasterFromImage(Raster *raster, Image *image);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
namespace ps2 {
|
namespace ps2 {
|
||||||
|
|
||||||
ObjPipeline *makeSkinPipeline(void);
|
// MatFX plugin
|
||||||
|
|
||||||
|
void initMatFX(void);
|
||||||
ObjPipeline *makeMatFXPipeline(void);
|
ObjPipeline *makeMatFXPipeline(void);
|
||||||
|
|
||||||
// Skin plugin
|
// Skin plugin
|
||||||
|
|
||||||
|
void initSkin(void);
|
||||||
|
ObjPipeline *makeSkinPipeline(void);
|
||||||
|
|
||||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
||||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v);
|
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v);
|
||||||
|
|
||||||
|
@ -1,22 +1,18 @@
|
|||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
|
// This is for platform independent things
|
||||||
// TODO: move more stuff into this
|
// TODO: move more stuff into this
|
||||||
struct Engine
|
struct Engine
|
||||||
{
|
{
|
||||||
void *currentCamera;
|
void *currentCamera;
|
||||||
void *currentWorld;
|
void *currentWorld;
|
||||||
|
|
||||||
static PluginList s_plglist;
|
|
||||||
static void init(void);
|
static void init(void);
|
||||||
static void open(void);
|
|
||||||
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
|
|
||||||
Destructor dtor){
|
|
||||||
return s_plglist.registerPlugin(size, id, ctor, dtor, nil);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Engine *engine;
|
extern Engine *engine;
|
||||||
|
|
||||||
|
// This is for platform driver implementations
|
||||||
struct Driver
|
struct Driver
|
||||||
{
|
{
|
||||||
ObjPipeline *defaultPipeline;
|
ObjPipeline *defaultPipeline;
|
||||||
@ -30,9 +26,17 @@ struct Driver
|
|||||||
void (*rasterUnlock)(Raster*, int32 level);
|
void (*rasterUnlock)(Raster*, int32 level);
|
||||||
int32 (*rasterNumLevels)(Raster*);
|
int32 (*rasterNumLevels)(Raster*);
|
||||||
void (*rasterFromImage)(Raster*, Image*);
|
void (*rasterFromImage)(Raster*, Image*);
|
||||||
|
|
||||||
|
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,
|
||||||
|
ctor, dtor, nil);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Driver driver[NUM_PLATFORMS];
|
extern Driver *driver[NUM_PLATFORMS];
|
||||||
#define DRIVER driver[rw::platform]
|
#define DRIVER driver[rw::platform]
|
||||||
|
|
||||||
namespace null {
|
namespace null {
|
||||||
|
@ -110,6 +110,7 @@ struct MatFX
|
|||||||
|
|
||||||
void setEffects(uint32 flags);
|
void setEffects(uint32 flags);
|
||||||
static uint32 getEffects(Material *m);
|
static uint32 getEffects(Material *m);
|
||||||
|
static MatFX *get(Material *m);
|
||||||
uint32 getEffectIndex(uint32 type);
|
uint32 getEffectIndex(uint32 type);
|
||||||
void setBumpTexture(Texture *t);
|
void setBumpTexture(Texture *t);
|
||||||
void setBumpCoefficient(float32 coef);
|
void setBumpCoefficient(float32 coef);
|
||||||
|
33
src/skin.cpp
33
src/skin.cpp
@ -17,6 +17,7 @@
|
|||||||
#include "d3d/rwd3d9.h"
|
#include "d3d/rwd3d9.h"
|
||||||
#include "gl/rwwdgl.h"
|
#include "gl/rwwdgl.h"
|
||||||
#include "gl/rwgl3.h"
|
#include "gl/rwgl3.h"
|
||||||
|
#include "gl/rwgl3plg.h"
|
||||||
|
|
||||||
#define PLUGIN_ID ID_SKIN
|
#define PLUGIN_ID ID_SKIN
|
||||||
|
|
||||||
@ -227,28 +228,6 @@ skinRights(void *object, int32, int32, uint32)
|
|||||||
Skin::setPipeline((Atomic*)object, 1);
|
Skin::setPipeline((Atomic*)object, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
|
||||||
skinOpen(void*, int32, int32)
|
|
||||||
{
|
|
||||||
skinGlobals.pipelines[PLATFORM_PS2] =
|
|
||||||
ps2::makeSkinPipeline();
|
|
||||||
skinGlobals.pipelines[PLATFORM_XBOX] =
|
|
||||||
xbox::makeSkinPipeline();
|
|
||||||
skinGlobals.pipelines[PLATFORM_D3D8] =
|
|
||||||
d3d8::makeSkinPipeline();
|
|
||||||
skinGlobals.pipelines[PLATFORM_D3D9] =
|
|
||||||
d3d9::makeSkinPipeline();
|
|
||||||
skinGlobals.pipelines[PLATFORM_WDGL] =
|
|
||||||
wdgl::makeSkinPipeline();
|
|
||||||
skinGlobals.pipelines[PLATFORM_GL3] =
|
|
||||||
gl3::makeSkinPipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void*
|
|
||||||
skinClose(void*, int32, int32)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
registerSkinPlugin(void)
|
registerSkinPlugin(void)
|
||||||
{
|
{
|
||||||
@ -259,10 +238,12 @@ registerSkinPlugin(void)
|
|||||||
for(uint i = 0; i < nelem(skinGlobals.pipelines); i++)
|
for(uint i = 0; i < nelem(skinGlobals.pipelines); i++)
|
||||||
skinGlobals.pipelines[i] = defpipe;
|
skinGlobals.pipelines[i] = defpipe;
|
||||||
|
|
||||||
// TODO: call platform specific init functions?
|
ps2::initSkin();
|
||||||
// have platform specific open functions?
|
xbox::initSkin();
|
||||||
|
d3d8::initSkin();
|
||||||
Engine::registerPlugin(0, ID_SKIN, skinOpen, skinClose);
|
d3d9::initSkin();
|
||||||
|
wdgl::initSkin();
|
||||||
|
gl3::initSkin();
|
||||||
|
|
||||||
skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN,
|
skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN,
|
||||||
createSkin,
|
createSkin,
|
||||||
|
Loading…
Reference in New Issue
Block a user