diff --git a/rw.h b/rw.h index a058c73..a000c55 100644 --- a/rw.h +++ b/rw.h @@ -4,10 +4,11 @@ #include "src/rwbase.h" #include "src/rwerror.h" #include "src/rwplg.h" +#include "src/rwrender.h" +#include "src/rwengine.h" #include "src/rwpipeline.h" #include "src/rwobjects.h" #include "src/rwanim.h" -#include "src/rwengine.h" #include "src/rwplugins.h" #include "src/rwuserdata.h" #include "src/ps2/rwps2.h" diff --git a/src/d3d/d3d8plugins.cpp b/src/d3d/d3d8matfx.cpp similarity index 61% rename from src/d3d/d3d8plugins.cpp rename to src/d3d/d3d8matfx.cpp index 16234d9..0fddbc4 100644 --- a/src/d3d/d3d8plugins.cpp +++ b/src/d3d/d3d8matfx.cpp @@ -18,42 +18,6 @@ namespace rw { namespace d3d8 { using namespace d3d; -// Skin - -static void* -skinOpen(void *o, int32, int32) -{ - skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline(); - return o; -} - -static void* -skinClose(void *o, int32, int32) -{ - return o; -} - -void -initSkin(void) -{ - Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN, - skinOpen, skinClose); -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - return pipe; -} - -// MatFX - static void* matfxOpen(void *o, int32, int32) { diff --git a/src/d3d/d3d8render.cpp b/src/d3d/d3d8render.cpp index c5aed73..63c5dc9 100644 --- a/src/d3d/d3d8render.cpp +++ b/src/d3d/d3d8render.cpp @@ -41,6 +41,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); if(geo->flags & Geometry::PRELIT) d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + else + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); d3ddevice->SetFVF(inst->vertexShader); d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride); diff --git a/src/d3d/d3d8skin.cpp b/src/d3d/d3d8skin.cpp new file mode 100644 index 0000000..e291751 --- /dev/null +++ b/src/d3d/d3d8skin.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d8.h" + +namespace rw { +namespace d3d8 { +using namespace d3d; + +static void* +skinOpen(void *o, int32, int32) +{ + skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline(); + return o; +} + +static void* +skinClose(void *o, int32, int32) +{ + return o; +} + +void +initSkin(void) +{ + Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN, + skinOpen, skinClose); +} + +ObjPipeline* +makeSkinPipeline(void) +{ + ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB; + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; + return pipe; +} + +} +} diff --git a/src/d3d/d3d9plugins.cpp b/src/d3d/d3d9matfx.cpp similarity index 61% rename from src/d3d/d3d9plugins.cpp rename to src/d3d/d3d9matfx.cpp index 906310d..4d3b9d0 100644 --- a/src/d3d/d3d9plugins.cpp +++ b/src/d3d/d3d9matfx.cpp @@ -18,42 +18,6 @@ namespace rw { namespace d3d9 { using namespace d3d; -// Skin - -static void* -skinOpen(void *o, int32, int32) -{ - skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline(); - return o; -} - -static void* -skinClose(void *o, int32, int32) -{ - return o; -} - -void -initSkin(void) -{ - Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN, - skinOpen, skinClose); -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - return pipe; -} - -// MatFX - static void* matfxOpen(void *o, int32, int32) { diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index 96dc440..ee4ddd2 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -46,6 +46,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); if(geo->flags & Geometry::PRELIT) d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + else + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); d3d::flushCache(); d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, 0, inst->numVertices, diff --git a/src/d3d/d3d9skin.cpp b/src/d3d/d3d9skin.cpp new file mode 100644 index 0000000..56700fa --- /dev/null +++ b/src/d3d/d3d9skin.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwd3d.h" +#include "rwd3d9.h" + +namespace rw { +namespace d3d9 { +using namespace d3d; + +static void* +skinOpen(void *o, int32, int32) +{ + skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline(); + return o; +} + +static void* +skinClose(void *o, int32, int32) +{ + return o; +} + +void +initSkin(void) +{ + Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN, + skinOpen, skinClose); +} + +ObjPipeline* +makeSkinPipeline(void) +{ + ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->renderCB = defaultRenderCB; + pipe->pluginID = ID_SKIN; + pipe->pluginData = 1; + return pipe; +} + +} +} diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index 783f8cc..8791686 100755 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -6,9 +6,10 @@ #include "../rwbase.h" #include "../rwplg.h" #include "../rwerror.h" +#include "../rwrender.h" +#include "../rwengine.h" #include "../rwpipeline.h" #include "../rwobjects.h" -#include "../rwengine.h" #include "rwd3d.h" #include "rwd3dimpl.h" @@ -427,7 +428,7 @@ showRaster(Raster *raster) // taken from Frank Luna's d3d9 book static int -startD3D(EngineStartParams *params) +openD3D(EngineStartParams *params) { HWND win = params->window; bool windowed = true; @@ -491,7 +492,7 @@ startD3D(EngineStartParams *params) } static int -stopD3D(void) +closeD3D(void) { d3d::d3ddevice->Release(); d3d::d3ddevice = nil; @@ -531,10 +532,19 @@ initD3D(void) // setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT); openIm2D(); + openIm3D(); return 1; } +static int +termD3D(void) +{ + closeIm3D(); + closeIm2D(); + return 1; +} + static int finalizeD3D(void) { @@ -545,14 +555,18 @@ static int deviceSystem(DeviceReq req, void *arg0) { switch(req){ - case DEVICESTART: - return startD3D((EngineStartParams*)arg0); + case DEVICEOPEN: + return openD3D((EngineStartParams*)arg0); + case DEVICECLOSE: + return closeD3D(); + case DEVICEINIT: return initD3D(); + case DEVICETERM: + return termD3D(); + case DEVICEFINALIZE: return finalizeD3D(); - case DEVICESTOP: - return stopD3D(); } return 1; } @@ -566,6 +580,9 @@ Device renderdevice = { d3d::setRwRenderState, d3d::getRwRenderState, d3d::im2DRenderIndexedPrimitive, + d3d::im3DTransform, + d3d::im3DRenderIndexed, + d3d::im3DEnd, d3d::deviceSystem, }; diff --git a/src/d3d/d3dim2d.cpp b/src/d3d/d3dimmed.cpp similarity index 50% rename from src/d3d/d3dim2d.cpp rename to src/d3d/d3dimmed.cpp index ae4182c..af57fdb 100644 --- a/src/d3d/d3dim2d.cpp +++ b/src/d3d/d3dimmed.cpp @@ -48,6 +48,14 @@ openIm2D(void) im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); } +void +closeIm2D(void) +{ + deleteObject(im2ddecl); + deleteObject(im2dvertbuf); + deleteObject(im2dindbuf); +} + void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices) @@ -97,6 +105,103 @@ im2DRenderIndexedPrimitive(PrimitiveType primType, 0, primCount); } + +// Im3D + + +static IDirect3DVertexDeclaration9 *im3ddecl; +static IDirect3DVertexBuffer9 *im3dvertbuf; +static IDirect3DIndexBuffer9 *im3dindbuf; +static int32 num3DVertices; + +void +openIm3D(void) +{ + D3DVERTEXELEMENT9 elements[4] = { + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, offsetof(Im3DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, + { 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() + }; + d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im3ddecl); + im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, D3DPOOL_MANAGED); + im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); +} + +void +closeIm3D(void) +{ + deleteObject(im3ddecl); + deleteObject(im3dvertbuf); + deleteObject(im3dindbuf); +} + +void +im3DTransform(void *vertices, int32 numVertices, Matrix *world) +{ + RawMatrix d3dworld; + d3d::setRenderState(D3DRS_LIGHTING, 0); + + if(world == nil){ + Matrix ident; + ident.setIdentity(); + world = &ident; + } + convMatrix(&d3dworld, world); + d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&d3dworld); + + uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_NOSYSLOCK); + memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex)); + unlockVertices(im3dvertbuf); + + d3ddevice->SetStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex)); + d3ddevice->SetVertexDeclaration(im3ddecl); + + num3DVertices = numVertices; +} + +void +im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +{ + uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), 0); + memcpy(lockedindices, indices, numIndices*sizeof(uint16)); + unlockIndices(im3dindbuf); + + d3d::setTexture(0, engine->imtexture); + d3d::flushCache(); + + uint32 primCount = 0; + switch(primType){ + case PRIMTYPELINELIST: + primCount = numIndices/2; + break; + case PRIMTYPEPOLYLINE: + primCount = numIndices-1; + break; + case PRIMTYPETRILIST: + primCount = numIndices/3; + break; + case PRIMTYPETRISTRIP: + primCount = numIndices-2; + break; + case PRIMTYPETRIFAN: + primCount = numIndices-2; + break; + case PRIMTYPEPOINTLIST: + primCount = numIndices; + break; + } + d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0, + 0, num3DVertices, + 0, primCount); +} + +void +im3DEnd(void) +{ +} + #endif } } diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index f3a89df..82aaa04 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -22,6 +22,22 @@ extern Device renderdevice; void lightingCB(void); +struct Im3DVertex +{ + V3d position; + D3DCOLOR color; + float32 u, v; + + void setX(float32 x) { this->position.x = x; } + void setY(float32 y) { this->position.y = y; } + void setZ(float32 z) { this->position.z = z; } + void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); } + RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF, + this->color & 0xFF, this->color>>24 & 0xFF); } + void setU(float32 u) { this->u = u; } + void setV(float32 v) { this->v = v; } +}; + struct Im2DVertex { float32 x, y, z; diff --git a/src/d3d/rwd3dimpl.h b/src/d3d/rwd3dimpl.h index a400119..7ad5827 100644 --- a/src/d3d/rwd3dimpl.h +++ b/src/d3d/rwd3dimpl.h @@ -3,8 +3,15 @@ namespace d3d { #ifdef RW_D3D9 void openIm2D(void); +void closeIm2D(void); void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices); + +void openIm3D(void); +void closeIm3D(void); +void im3DTransform(void *vertices, int32 numVertices, Matrix *world); +void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void im3DEnd(void); #endif void rasterCreate(Raster *raster); diff --git a/src/d3d/xboxmatx.cpp b/src/d3d/xboxmatx.cpp new file mode 100644 index 0000000..a4f7ad0 --- /dev/null +++ b/src/d3d/xboxmatx.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwxbox.h" + +namespace rw { +namespace xbox { + +static void* +matfxOpen(void *o, int32, int32) +{ + matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline(); + return o; +} + +static void* +matfxClose(void *o, int32, int32) +{ + return o; +} + +void +initMatFX(void) +{ + Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX, + matfxOpen, matfxClose); +} + +ObjPipeline* +makeMatFXPipeline(void) +{ + ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); + pipe->instanceCB = defaultInstanceCB; + pipe->uninstanceCB = defaultUninstanceCB; + pipe->pluginID = ID_MATFX; + pipe->pluginData = 0; + return pipe; +} + +} +} diff --git a/src/d3d/xboxplugins.cpp b/src/d3d/xboxskin.cpp similarity index 69% rename from src/d3d/xboxplugins.cpp rename to src/d3d/xboxskin.cpp index ae59de6..1aa8b66 100644 --- a/src/d3d/xboxplugins.cpp +++ b/src/d3d/xboxskin.cpp @@ -13,13 +13,11 @@ #include "../rwplugins.h" #include "rwxbox.h" -#define PLUGIN_ID ID_SKIN // yeah right.... +#define PLUGIN_ID ID_SKIN namespace rw { namespace xbox { -// Skin - struct NativeSkin { int32 table1[256]; // maps indices to bones @@ -246,135 +244,5 @@ makeSkinPipeline(void) return pipe; } -// MatFX - -static void* -matfxOpen(void *o, int32, int32) -{ - matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline(); - return o; -} - -static void* -matfxClose(void *o, int32, int32) -{ - return o; -} - -void -initMatFX(void) -{ - Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX, - matfxOpen, matfxClose); -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - return pipe; -} - -// Vertex Format - -static int32 vertexFmtOffset; - -uint32 vertexFormatSizes[6] = { - 0, 1, 2, 2, 4, 4 -}; - -uint32* -getVertexFmt(Geometry *g) -{ - return PLUGINOFFSET(uint32, g, vertexFmtOffset); -} - -uint32 -makeVertexFmt(int32 flags, uint32 numTexSets) -{ - if(numTexSets > 4) - numTexSets = 4; - uint32 fmt = 0x5; // FLOAT3 - if(flags & Geometry::NORMALS) - fmt |= 0x40; // NORMPACKED3 - for(uint32 i = 0; i < numTexSets; i++) - fmt |= 0x500 << i*4; // FLOAT2 - if(flags & Geometry::PRELIT) - fmt |= 0x1000000; // D3DCOLOR - return fmt; -} - -uint32 -getVertexFmtStride(uint32 fmt) -{ - uint32 stride = 0; - uint32 v = fmt & 0xF; - uint32 n = (fmt >> 4) & 0xF; - stride += v == 4 ? 4 : 3*vertexFormatSizes[v]; - stride += n == 4 ? 4 : 3*vertexFormatSizes[n]; - if(fmt & 0x1000000) - stride += 4; - for(int i = 0; i < 4; i++){ - uint32 t = (fmt >> (i*4 + 8)) & 0xF; - stride += t == 4 ? 4 : 2*vertexFormatSizes[t]; - } - if(fmt & 0xE000000) - stride += 8; - return stride; -} - -static void* -createVertexFmt(void *object, int32 offset, int32) -{ - *PLUGINOFFSET(uint32, object, offset) = 0; - return object; -} - -static void* -copyVertexFmt(void *dst, void *src, int32 offset, int32) -{ - *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset); - return dst; -} - -static Stream* -readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) -{ - uint32 fmt = stream->readU32(); - *PLUGINOFFSET(uint32, object, offset) = fmt; - // TODO: ? create and attach "vertex shader" - return stream; -} - -static Stream* -writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) -{ - stream->writeI32(*PLUGINOFFSET(uint32, object, offset)); - return stream; -} - -static int32 -getSizeVertexFmt(void*, int32, int32) -{ - if(rw::platform != PLATFORM_XBOX) - return -1; - return 4; -} - -void -registerVertexFormatPlugin(void) -{ - vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT, - createVertexFmt, nil, copyVertexFmt); - Geometry::registerPluginStream(ID_VERTEXFMT, - readVertexFmt, - writeVertexFmt, - getSizeVertexFmt); -} - } } diff --git a/src/d3d/xboxvfmt.cpp b/src/d3d/xboxvfmt.cpp new file mode 100644 index 0000000..ae88539 --- /dev/null +++ b/src/d3d/xboxvfmt.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwengine.h" +#include "../rwplugins.h" +#include "rwxbox.h" + +namespace rw { +namespace xbox { + +static int32 vertexFmtOffset; + +uint32 vertexFormatSizes[6] = { + 0, 1, 2, 2, 4, 4 +}; + +uint32* +getVertexFmt(Geometry *g) +{ + return PLUGINOFFSET(uint32, g, vertexFmtOffset); +} + +uint32 +makeVertexFmt(int32 flags, uint32 numTexSets) +{ + if(numTexSets > 4) + numTexSets = 4; + uint32 fmt = 0x5; // FLOAT3 + if(flags & Geometry::NORMALS) + fmt |= 0x40; // NORMPACKED3 + for(uint32 i = 0; i < numTexSets; i++) + fmt |= 0x500 << i*4; // FLOAT2 + if(flags & Geometry::PRELIT) + fmt |= 0x1000000; // D3DCOLOR + return fmt; +} + +uint32 +getVertexFmtStride(uint32 fmt) +{ + uint32 stride = 0; + uint32 v = fmt & 0xF; + uint32 n = (fmt >> 4) & 0xF; + stride += v == 4 ? 4 : 3*vertexFormatSizes[v]; + stride += n == 4 ? 4 : 3*vertexFormatSizes[n]; + if(fmt & 0x1000000) + stride += 4; + for(int i = 0; i < 4; i++){ + uint32 t = (fmt >> (i*4 + 8)) & 0xF; + stride += t == 4 ? 4 : 2*vertexFormatSizes[t]; + } + if(fmt & 0xE000000) + stride += 8; + return stride; +} + +static void* +createVertexFmt(void *object, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, object, offset) = 0; + return object; +} + +static void* +copyVertexFmt(void *dst, void *src, int32 offset, int32) +{ + *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset); + return dst; +} + +static Stream* +readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + uint32 fmt = stream->readU32(); + *PLUGINOFFSET(uint32, object, offset) = fmt; + // TODO: ? create and attach "vertex shader" + return stream; +} + +static Stream* +writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) +{ + stream->writeI32(*PLUGINOFFSET(uint32, object, offset)); + return stream; +} + +static int32 +getSizeVertexFmt(void*, int32, int32) +{ + if(rw::platform != PLATFORM_XBOX) + return -1; + return 4; +} + +void +registerVertexFormatPlugin(void) +{ + vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT, + createVertexFmt, nil, copyVertexFmt); + Geometry::registerPluginStream(ID_VERTEXFMT, + readVertexFmt, + writeVertexFmt, + getSizeVertexFmt); +} + +} +} diff --git a/src/engine.cpp b/src/engine.cpp index 3820295..1af90e1 100755 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -158,7 +158,8 @@ Engine::start(EngineStartParams *p) return 0; } - engine->device.system(DEVICESTART, (void*)p); + // TODO: put this into Open? + engine->device.system(DEVICEOPEN, (void*)p); engine->device.system(DEVICEINIT, nil); Engine::s_plglist.construct(engine); @@ -191,7 +192,8 @@ Engine::close(void) void Engine::stop(void) { - engine->device.system(DEVICESTOP, nil); + engine->device.system(DEVICETERM, nil); + engine->device.system(DEVICECLOSE, nil); for(uint i = 0; i < NUM_PLATFORMS; i++) Driver::s_plglist[i].destruct(rw::engine->driver[i]); Engine::s_plglist.destruct(engine); @@ -210,6 +212,10 @@ uint32 getRenderState(int32) { return 0; } void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { } +void im3DTransform(void *vertices, int32 numVertices, Matrix *world) { } +void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) { } +void im3DEnd(void) { } + void rasterCreate(Raster*) { @@ -264,6 +270,9 @@ Device renderdevice = { null::setRenderState, null::getRenderState, null::im2DRenderIndexedPrimitive, + null::im3DTransform, + null::im3DRenderIndexed, + null::im3DEnd, null::deviceSystem }; diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index cb2c647..6288535 100755 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -5,9 +5,10 @@ #include "../rwbase.h" #include "../rwerror.h" #include "../rwplg.h" +#include "../rwrender.h" +#include "../rwengine.h" #include "../rwpipeline.h" #include "../rwobjects.h" -#include "../rwengine.h" #ifdef RW_OPENGL #include #include @@ -467,7 +468,7 @@ beginUpdate(Camera *cam) } static int -startGLFW(EngineStartParams *startparams) +openGLFW(EngineStartParams *startparams) { GLenum status; GLFWwindow *win; @@ -512,7 +513,7 @@ startGLFW(EngineStartParams *startparams) } static int -stopGLFW(void) +closeGLFW(void) { glfwDestroyWindow(glfwwindow); glfwTerminate(); @@ -564,14 +565,24 @@ initOpenGL(void) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel); -#include "shaders/simple_gl3.inc" +#include "shaders/simple_vs_gl3.inc" +#include "shaders/simple_fs_gl3.inc" simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src); openIm2D(); + openIm3D(); return 1; } +static int +termOpenGL(void) +{ + closeIm3D(); + closeIm2D(); + return 1; +} + static int finalizeOpenGL(void) { @@ -582,14 +593,18 @@ static int deviceSystem(DeviceReq req, void *arg0) { switch(req){ - case DEVICESTART: - return startGLFW((EngineStartParams*)arg0); + case DEVICEOPEN: + return openGLFW((EngineStartParams*)arg0); + case DEVICECLOSE: + return closeGLFW(); + case DEVICEINIT: return initOpenGL(); + case DEVICETERM: + return termOpenGL(); + case DEVICEFINALIZE: return finalizeOpenGL(); - case DEVICESTOP: - return stopGLFW(); } return 1; } @@ -603,6 +618,9 @@ Device renderdevice = { gl3::setRenderState, gl3::getRenderState, gl3::im2DRenderIndexedPrimitive, + gl3::im3DTransform, + gl3::im3DRenderIndexed, + gl3::im3DEnd, gl3::deviceSystem }; diff --git a/src/gl/gl3im2d.cpp b/src/gl/gl3im2d.cpp deleted file mode 100644 index 60143a4..0000000 --- a/src/gl/gl3im2d.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include - -#include "../rwbase.h" -#include "../rwerror.h" -#include "../rwplg.h" -#include "../rwpipeline.h" -#include "../rwobjects.h" -#include "../rwengine.h" -#ifdef RW_OPENGL -#include -#include "rwgl3.h" -#include "rwgl3shader.h" - -namespace rw { -namespace gl3 { - -static uint32 im2DVbo, im2DIbo; -static int32 u_xform; - -#define STARTINDICES 10000 -#define STARTVERTICES 10000 - -static Shader *im2dShader; -static AttribDesc attribDesc[3] = { - { ATTRIB_POS, GL_FLOAT, GL_FALSE, 4, - sizeof(Im2DVertex), 0 }, - { ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4, - sizeof(Im2DVertex), offsetof(Im2DVertex, r) }, - { ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2, - sizeof(Im2DVertex), offsetof(Im2DVertex, u) }, -}; - -static int primTypeMap[] = { - GL_POINTS, // invalid - GL_LINES, - GL_LINE_STRIP, - GL_TRIANGLES, - GL_TRIANGLE_STRIP, - GL_TRIANGLE_FAN, - GL_POINTS -}; - -void -openIm2D(void) -{ - u_xform = registerUniform("u_xform"); - -#include "shaders/im2d_gl3.inc" - im2dShader = Shader::fromStrings(im2d_vert_src, im2d_frag_src); - - glGenBuffers(1, &im2DIbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, - nil, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - glGenBuffers(1, &im2DVbo); - glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); - glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), - nil, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void -im2DRenderIndexedPrimitive(PrimitiveType primType, - void *vertices, int32 numVertices, - void *indices, int32 numIndices) -{ - GLfloat xform[4]; - Camera *cam; - cam = (Camera*)engine->currentCamera; - - // TODO: fixed size - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, - indices, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); - glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex), - vertices, GL_DYNAMIC_DRAW); - - xform[0] = 2.0f/cam->frameBuffer->width; - xform[1] = -2.0f/cam->frameBuffer->height; - xform[2] = -1.0f; - xform[3] = 1.0f; - - im2dShader->use(); - setAttribPointers(attribDesc, 3); - - glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform); - setTexture(0, engine->imtexture); - - flushCache(); - glDrawElements(primTypeMap[primType], numIndices, - GL_UNSIGNED_SHORT, nil); - disableAttribPointers(attribDesc, 3); -} - -} -} - -#endif diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp new file mode 100644 index 0000000..892f6dc --- /dev/null +++ b/src/gl/gl3immed.cpp @@ -0,0 +1,199 @@ +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwengine.h" +#ifdef RW_OPENGL +#include +#include "rwgl3.h" +#include "rwgl3shader.h" + +namespace rw { +namespace gl3 { + +static uint32 im2DVbo, im2DIbo; +static int32 u_xform; + +#define STARTINDICES 10000 +#define STARTVERTICES 10000 + +static Shader *im2dShader; +static AttribDesc im2dattribDesc[3] = { + { ATTRIB_POS, GL_FLOAT, GL_FALSE, 4, + sizeof(Im2DVertex), 0 }, + { ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4, + sizeof(Im2DVertex), offsetof(Im2DVertex, r) }, + { ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2, + sizeof(Im2DVertex), offsetof(Im2DVertex, u) }, +}; + +static int primTypeMap[] = { + GL_POINTS, // invalid + GL_LINES, + GL_LINE_STRIP, + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_POINTS +}; + +void +openIm2D(void) +{ + u_xform = registerUniform("u_xform"); + +#include "shaders/im2d_gl3.inc" +#include "shaders/simple_fs_gl3.inc" + im2dShader = Shader::fromStrings(im2d_vert_src, simple_frag_src); + + glGenBuffers(1, &im2DIbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, + nil, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glGenBuffers(1, &im2DVbo); + glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im2DVertex), + nil, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void +closeIm2D(void) +{ + glDeleteBuffers(1, &im2DIbo); + glDeleteBuffers(1, &im2DVbo); + im2dShader->destroy(); + im2dShader = nil; +} + +void +im2DRenderIndexedPrimitive(PrimitiveType primType, + void *vertices, int32 numVertices, + void *indices, int32 numIndices) +{ + GLfloat xform[4]; + Camera *cam; + cam = (Camera*)engine->currentCamera; + + // TODO: fixed size + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2DIbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, + indices, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, im2DVbo); + glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im2DVertex), + vertices, GL_DYNAMIC_DRAW); + + xform[0] = 2.0f/cam->frameBuffer->width; + xform[1] = -2.0f/cam->frameBuffer->height; + xform[2] = -1.0f; + xform[3] = 1.0f; + + im2dShader->use(); + setAttribPointers(im2dattribDesc, 3); + + glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform); + setTexture(0, engine->imtexture); + + flushCache(); + glDrawElements(primTypeMap[primType], numIndices, + GL_UNSIGNED_SHORT, nil); + disableAttribPointers(im2dattribDesc, 3); +} + + +// Im3D + + +static Shader *im3dShader; +static AttribDesc im3dattribDesc[3] = { + { ATTRIB_POS, GL_FLOAT, GL_FALSE, 3, + sizeof(Im3DVertex), 0 }, + { ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4, + sizeof(Im3DVertex), offsetof(Im3DVertex, r) }, + { ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2, + sizeof(Im3DVertex), offsetof(Im3DVertex, u) }, +}; +static uint32 im3DVbo, im3DIbo; +static int32 num3DVertices; // not actually needed here + +void +openIm3D(void) +{ +#include "shaders/im3d_gl3.inc" +#include "shaders/simple_fs_gl3.inc" + im3dShader = Shader::fromStrings(im3d_vert_src, simple_frag_src); + + glGenBuffers(1, &im3DIbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, STARTINDICES*2, + nil, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glGenBuffers(1, &im3DVbo); + glBindBuffer(GL_ARRAY_BUFFER, im3DVbo); + glBufferData(GL_ARRAY_BUFFER, STARTVERTICES*sizeof(Im3DVertex), + nil, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void +closeIm3D(void) +{ + glDeleteBuffers(1, &im3DIbo); + glDeleteBuffers(1, &im3DVbo); + im3dShader->destroy(); + im3dShader = nil; +} + +void +im3DTransform(void *vertices, int32 numVertices, Matrix *world) +{ + if(world == nil){ + Matrix ident; + ident.setIdentity(); + world = &ident; + } + setWorldMatrix(world); + im3dShader->use(); + + // TODO: fixed size + glBindBuffer(GL_ARRAY_BUFFER, im3DVbo); + glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(Im3DVertex), + vertices, GL_DYNAMIC_DRAW); + setAttribPointers(im3dattribDesc, 3); + num3DVertices = numVertices; +} + +void +im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im3DIbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2, + indices, GL_DYNAMIC_DRAW); + + setTexture(0, engine->imtexture); + + flushCache(); + glDrawElements(primTypeMap[primType], numIndices, + GL_UNSIGNED_SHORT, nil); + disableAttribPointers(im3dattribDesc, 3); + +} + +void +im3DEnd(void) +{ +} + +} +} + +#endif diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp new file mode 100644 index 0000000..4a9f7ae --- /dev/null +++ b/src/gl/gl3matfx.cpp @@ -0,0 +1,242 @@ +#include +#include +#include +#include + +#include "../rwbase.h" +#include "../rwerror.h" +#include "../rwplg.h" +#include "../rwrender.h" +#include "../rwengine.h" +#include "../rwpipeline.h" +#include "../rwobjects.h" +#include "../rwanim.h" +#include "../rwplugins.h" +#ifdef RW_OPENGL +#include +#endif +#include "rwgl3.h" +#include "rwgl3shader.h" +#include "rwgl3plg.h" + +#include "rwgl3impl.h" + +namespace rw { +namespace gl3 { + +#ifdef RW_OPENGL + +#define U(i) currentShader->uniformLocations[i] + +static Shader *envShader; +static int32 u_texMatrix; +static int32 u_coefficient; + +static void* +matfxOpen(void *o, int32, int32) +{ + u_texMatrix = registerUniform("u_texMatrix"); + u_coefficient = registerUniform("u_coefficient"); +#include "shaders/matfx_gl3.inc" + matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline(); + envShader = Shader::fromStrings(matfx_env_vert_src, matfx_env_frag_src); + return o; +} + +static void* +matfxClose(void *o, int32, int32) +{ + return o; +} + +void +initMatFX(void) +{ + Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX, + matfxOpen, matfxClose); +} + + +void +matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst) +{ + Material *m; + RGBAf col; + GLfloat surfProps[4]; + m = inst->material; + + simpleShader->use(); + + 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); + + rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); + + flushCache(); + glDrawElements(header->primType, inst->numIndex, + GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset); +} + +void +calcEnvTexMatrix(Frame *f, float32 *mat) +{ + Matrix cam; + if(f){ + // PS2 style - could be simplified by the shader + cam = *((Camera*)engine->currentCamera)->getFrame()->getLTM(); + cam.pos = { 0.0, 0.0, 0.0 }; + cam.right.x = -cam.right.x; + cam.right.y = -cam.right.y; + cam.right.z = -cam.right.z; + + Matrix inv; + Matrix::invert(&inv, f->getLTM()); + inv.pos = { -1.0, -1.0, -1.0 }; + inv.right.x *= -0.5f; + inv.right.y *= -0.5f; + inv.right.z *= -0.5f; + inv.up.x *= -0.5f; + inv.up.y *= -0.5f; + inv.up.z *= -0.5f; + inv.at.x *= -0.5f; + inv.at.y *= -0.5f; + inv.at.z *= -0.5f; + inv.pos.x *= -0.5f; + inv.pos.y *= -0.5f; + inv.pos.z *= -0.5f; + + Matrix m; + Matrix::mult(&m, &cam, &inv); + + memcpy(mat, &m, 64); + mat[3] = mat[7] = mat[11] = 0.0f; + mat[15] = 1.0f; + + }else{ + // D3D - TODO: find out what PS2 does + mat[0] = 0.5f; + mat[1] = 0.0f; + mat[2] = 0.0f; + mat[3] = 0.0f; + + mat[4] = 0.0f; + mat[5] = -0.5f; + mat[6] = 0.0f; + mat[7] = 0.0f; + + mat[8] = 0.0f; + mat[9] = 0.0f; + mat[10] = 1.0f; + mat[11] = 0.0f; + + mat[12] = 0.5f; + mat[13] = 0.5f; + mat[14] = 0.0f; + mat[15] = 0.0f; + } +} + +void +matfxEnvRender(InstanceDataHeader *header, InstanceData *inst) +{ + Material *m; + RGBAf col; + GLfloat surfProps[4]; + float32 texMat[16]; + m = inst->material; + + matfxDefaultRender(header, inst); + + MatFX *fx = MatFX::get(m); + int32 idx = fx->getEffectIndex(MatFX::ENVMAP); + MatFX::Env *env = &fx->fx[idx].env; + + envShader->use(); + + 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); + + glUniform1fv(U(u_coefficient), 1, &env->coefficient); + + calcEnvTexMatrix(env->frame, texMat); + glUniformMatrix4fv(U(u_texMatrix), 1, GL_FALSE, texMat); + + setTexture(0, env->tex); + + rw::SetRenderState(VERTEXALPHA, 1); + rw::SetRenderState(SRCBLEND, BLENDONE); + rw::SetRenderState(DESTBLEND, BLENDONE); + + flushCache(); + glDrawElements(header->primType, inst->numIndex, + GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset); + + rw::SetRenderState(SRCBLEND, BLENDSRCALPHA); + rw::SetRenderState(DESTBLEND, BLENDINVSRCALPHA); +} + +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->attribDesc, header->numAttribs); + + InstanceData *inst = header->inst; + int32 n = header->numMeshes; + +// rw::SetRenderState(ALPHATESTFUNC, 1); +// rw::SetRenderState(ALPHATESTREF, 50); + + int32 fx; + while(n--){ + fx = MatFX::getEffects(inst->material); + switch(fx){ + case MatFX::ENVMAP: + matfxEnvRender(header, inst); + break; + default: + matfxDefaultRender(header, inst); + } + inst++; + } + disableAttribPointers(header->attribDesc, header->numAttribs); +} + +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; +} + +#else + +void initMatFX(void) { } + +#endif + +} +} diff --git a/src/gl/gl3render.cpp b/src/gl/gl3render.cpp index 16ac580..ec688ca 100644 --- a/src/gl/gl3render.cpp +++ b/src/gl/gl3render.cpp @@ -5,9 +5,10 @@ #include "../rwbase.h" #include "../rwerror.h" #include "../rwplg.h" +#include "../rwrender.h" +#include "../rwengine.h" #include "../rwpipeline.h" #include "../rwobjects.h" -#include "../rwengine.h" #ifdef RW_OPENGL #include #include "rwgl3.h" @@ -72,7 +73,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) Material *m; RGBAf col; GLfloat surfProps[4]; - int id; setWorldMatrix(atomic->getFrame()->getLTM()); lightingCB(); diff --git a/src/gl/gl3shader.cpp b/src/gl/gl3shader.cpp index 457f855..19dfc34 100644 --- a/src/gl/gl3shader.cpp +++ b/src/gl/gl3shader.cpp @@ -201,6 +201,14 @@ Shader::use(void) } } +void +Shader::destroy(void) +{ + glDeleteProgram(this->program); + rwFree(this->uniformLocations); + rwFree(this); +} + } } diff --git a/src/gl/gl3plugins.cpp b/src/gl/gl3skin.cpp similarity index 58% rename from src/gl/gl3plugins.cpp rename to src/gl/gl3skin.cpp index d716f6c..7d73d1e 100644 --- a/src/gl/gl3plugins.cpp +++ b/src/gl/gl3skin.cpp @@ -6,10 +6,11 @@ #include "../rwbase.h" #include "../rwerror.h" #include "../rwplg.h" +#include "../rwrender.h" +#include "../rwengine.h" #include "../rwpipeline.h" #include "../rwobjects.h" #include "../rwanim.h" -#include "../rwengine.h" #include "../rwplugins.h" #ifdef RW_OPENGL #include @@ -27,214 +28,6 @@ namespace gl3 { #define U(i) currentShader->uniformLocations[i] -// MatFX - -static Shader *envShader; -static int32 u_texMatrix; -static int32 u_coefficient; - -static void* -matfxOpen(void *o, int32, int32) -{ - u_texMatrix = registerUniform("u_texMatrix"); - u_coefficient = registerUniform("u_coefficient"); -#include "shaders/matfx_gl3.inc" - matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline(); - envShader = Shader::fromStrings(matfx_env_vert_src, matfx_env_frag_src); - return o; -} - -static void* -matfxClose(void *o, int32, int32) -{ - return o; -} - -void -initMatFX(void) -{ - Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX, - matfxOpen, matfxClose); -} - - -void -matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst) -{ - Material *m; - RGBAf col; - GLfloat surfProps[4]; - m = inst->material; - - simpleShader->use(); - - 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); - - rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); - - flushCache(); - glDrawElements(header->primType, inst->numIndex, - GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset); -} - -void -calcEnvTexMatrix(Frame *f, float32 *mat) -{ - Matrix cam; - if(f){ - // PS2 style - could be simplified by the shader - cam = *((Camera*)engine->currentCamera)->getFrame()->getLTM(); - cam.pos = { 0.0, 0.0, 0.0 }; - cam.right.x = -cam.right.x; - cam.right.y = -cam.right.y; - cam.right.z = -cam.right.z; - - Matrix inv; - Matrix::invert(&inv, f->getLTM()); - inv.pos = { -1.0, -1.0, -1.0 }; - inv.right.x *= -0.5f; - inv.right.y *= -0.5f; - inv.right.z *= -0.5f; - inv.up.x *= -0.5f; - inv.up.y *= -0.5f; - inv.up.z *= -0.5f; - inv.at.x *= -0.5f; - inv.at.y *= -0.5f; - inv.at.z *= -0.5f; - inv.pos.x *= -0.5f; - inv.pos.y *= -0.5f; - inv.pos.z *= -0.5f; - - Matrix m; - Matrix::mult(&m, &cam, &inv); - - memcpy(mat, &m, 64); - mat[3] = mat[7] = mat[11] = 0.0f; - mat[15] = 1.0f; - - }else{ - // D3D - TODO: find out what PS2 does - mat[0] = 0.5f; - mat[1] = 0.0f; - mat[2] = 0.0f; - mat[3] = 0.0f; - - mat[4] = 0.0f; - mat[5] = -0.5f; - mat[6] = 0.0f; - mat[7] = 0.0f; - - mat[8] = 0.0f; - mat[9] = 0.0f; - mat[10] = 1.0f; - mat[11] = 0.0f; - - mat[12] = 0.5f; - mat[13] = 0.5f; - mat[14] = 0.0f; - mat[15] = 0.0f; - } -} - -void -matfxEnvRender(InstanceDataHeader *header, InstanceData *inst) -{ - Material *m; - RGBAf col; - GLfloat surfProps[4]; - float32 texMat[16]; - m = inst->material; - - matfxDefaultRender(header, inst); - - MatFX *fx = MatFX::get(m); - int32 idx = fx->getEffectIndex(MatFX::ENVMAP); - MatFX::Env *env = &fx->fx[idx].env; - - envShader->use(); - - 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); - - glUniform1fv(U(u_coefficient), 1, &env->coefficient); - - calcEnvTexMatrix(env->frame, texMat); - glUniformMatrix4fv(U(u_texMatrix), 1, GL_FALSE, texMat); - - setTexture(0, env->tex); - - rw::SetRenderState(VERTEXALPHA, 1); - rw::SetRenderState(SRCBLEND, BLENDONE); - rw::SetRenderState(DESTBLEND, BLENDONE); - - flushCache(); - glDrawElements(header->primType, inst->numIndex, - GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset); - - rw::SetRenderState(SRCBLEND, BLENDSRCALPHA); - rw::SetRenderState(DESTBLEND, BLENDINVSRCALPHA); -} - -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->attribDesc, header->numAttribs); - - InstanceData *inst = header->inst; - int32 n = header->numMeshes; - -// rw::SetRenderState(ALPHATESTFUNC, 1); -// rw::SetRenderState(ALPHATESTREF, 50); - - int32 fx; - while(n--){ - fx = MatFX::getEffects(inst->material); - switch(fx){ - case MatFX::ENVMAP: - matfxEnvRender(header, inst); - break; - default: - matfxDefaultRender(header, inst); - } - inst++; - } - disableAttribPointers(header->attribDesc, header->numAttribs); -} - -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 Shader *skinShader; static int32 u_boneMatrices; @@ -242,7 +35,7 @@ static void* skinOpen(void *o, int32, int32) { u_boneMatrices = registerUniform("u_boneMatrices"); -#include "shaders/simple_gl3.inc" +#include "shaders/simple_fs_gl3.inc" #include "shaders/skin_gl3.inc" skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline(); skinShader = Shader::fromStrings(skin_vert_src, simple_frag_src); @@ -448,7 +241,6 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header) Material *m; RGBAf col; GLfloat surfProps[4]; - int id; setWorldMatrix(atomic->getFrame()->getLTM()); lightingCB(); @@ -507,7 +299,6 @@ makeSkinPipeline(void) #else -void initMatFX(void) { } void initSkin(void) { } #endif diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index 3a8de4c..4daf78b 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -80,6 +80,22 @@ struct InstanceDataHeader : rw::InstanceDataHeader #ifdef RW_GL3 +struct Im3DVertex +{ + V3d position; + uint8 r, g, b, a; + float32 u, v; + + void setX(float32 x) { this->position.x = x; } + void setY(float32 y) { this->position.y = y; } + void setZ(float32 z) { this->position.z = z; } + void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { + this->r = r; this->g = g; this->b = b; this->a = a; } + RGBA getColor(void) { return makeRGBA(this->r, this->g, this->b, this->a); } + void setU(float32 u) { this->u = u; } + void setV(float32 v) { this->v = v; } +}; + struct Im2DVertex { float32 x, y, z, w; diff --git a/src/gl/rwgl3impl.h b/src/gl/rwgl3impl.h index e79955a..d2725cc 100644 --- a/src/gl/rwgl3impl.h +++ b/src/gl/rwgl3impl.h @@ -6,9 +6,15 @@ namespace gl3 { extern Shader *simpleShader; extern uint32 im2DVbo, im2DIbo; void openIm2D(void); +void closeIm2D(void); void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices); +void openIm3D(void); +void closeIm3D(void); +void im3DTransform(void *vertices, int32 numVertices, Matrix *world); +void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void im3DEnd(void); #endif void rasterCreate(Raster *raster); diff --git a/src/gl/rwgl3shader.h b/src/gl/rwgl3shader.h index 1da5335..25e48fb 100644 --- a/src/gl/rwgl3shader.h +++ b/src/gl/rwgl3shader.h @@ -35,6 +35,7 @@ public: static Shader *fromFiles(const char *vs, const char *fs); static Shader *fromStrings(const char *vsrc, const char *fsrc); void use(void); + void destroy(void); }; extern Shader *currentShader; diff --git a/src/gl/shaders/Makefile b/src/gl/shaders/Makefile index e7be584..ecb2e5b 100644 --- a/src/gl/shaders/Makefile +++ b/src/gl/shaders/Makefile @@ -1,20 +1,24 @@ -all: im2d_gl3.inc simple_gl3.inc matfx_gl3.inc skin_gl3.inc +all: im2d_gl3.inc im3d_gl3.inc simple_vs_gl3.inc simple_fs_gl3.inc matfx_gl3.inc skin_gl3.inc -im2d_gl3.inc: im2d.frag im2d.vert +im2d_gl3.inc: im2d.vert (echo 'const char *im2d_vert_src =';\ sed 's/..*/"&\\n"/' im2d.vert;\ - echo ';';\ - echo 'const char *im2d_frag_src =';\ - sed 's/..*/"&\\n"/' im2d.frag;\ echo ';') >im2d_gl3.inc -simple_gl3.inc: simple.frag simple.vert +im3d_gl3.inc: im3d.vert + (echo 'const char *im3d_vert_src =';\ + sed 's/..*/"&\\n"/' im3d.vert;\ + echo ';') >im3d_gl3.inc + +simple_vs_gl3.inc: simple.vert (echo 'const char *simple_vert_src =';\ sed 's/..*/"&\\n"/' simple.vert;\ - echo ';';\ - echo 'const char *simple_frag_src =';\ + echo ';') >simple_vs_gl3.inc + +simple_fs_gl3.inc: simple.frag + (echo 'const char *simple_frag_src =';\ sed 's/..*/"&\\n"/' simple.frag;\ - echo ';') >simple_gl3.inc + echo ';') >simple_fs_gl3.inc matfx_gl3.inc: matfx_env.frag matfx_env.vert (echo 'const char *matfx_env_vert_src =';\ diff --git a/src/gl/shaders/im2d.frag b/src/gl/shaders/im2d.frag deleted file mode 100644 index 91bfc3e..0000000 --- a/src/gl/shaders/im2d.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D tex; - -in vec4 v_color; -in vec2 v_tex0; - -out vec4 color; - -void -main(void) -{ - color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y)); -} - diff --git a/src/gl/shaders/im2d.vert b/src/gl/shaders/im2d.vert index 6547571..46c5c20 100644 --- a/src/gl/shaders/im2d.vert +++ b/src/gl/shaders/im2d.vert @@ -1,11 +1,15 @@ #version 330 -//layout(std140) uniform Im2DState -//{ -// int u_alphaTest; -// float u_alphaRef; -// mat4 u_xform; -//}; +layout(std140) uniform State +{ + int u_alphaTest; + float u_alphaRef; + + int u_fogEnable; + float u_fogStart; + float u_fogEnd; + vec4 u_fogColor; +}; uniform vec4 u_xform; @@ -15,6 +19,7 @@ layout(location = 3) in vec2 in_tex0; out vec4 v_color; out vec2 v_tex0; +out float v_fog; void main(void) @@ -24,4 +29,5 @@ main(void) gl_Position.xyz *= gl_Position.w; v_color = in_color; v_tex0 = in_tex0; + v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0); } diff --git a/src/gl/shaders/im2d_gl3.inc b/src/gl/shaders/im2d_gl3.inc index ee1cbcb..11f2e80 100644 --- a/src/gl/shaders/im2d_gl3.inc +++ b/src/gl/shaders/im2d_gl3.inc @@ -1,12 +1,16 @@ const char *im2d_vert_src = "#version 330\n" -"//layout(std140) uniform Im2DState\n" -"//{\n" -"// int u_alphaTest;\n" -"// float u_alphaRef;\n" -"// mat4 u_xform;\n" -"//};\n" +"layout(std140) uniform State\n" +"{\n" +" int u_alphaTest;\n" +" float u_alphaRef;\n" + +" int u_fogEnable;\n" +" float u_fogStart;\n" +" float u_fogEnd;\n" +" vec4 u_fogColor;\n" +"};\n" "uniform vec4 u_xform;\n" @@ -16,6 +20,7 @@ const char *im2d_vert_src = "out vec4 v_color;\n" "out vec2 v_tex0;\n" +"out float v_fog;\n" "void\n" "main(void)\n" @@ -25,22 +30,6 @@ const char *im2d_vert_src = " gl_Position.xyz *= gl_Position.w;\n" " v_color = in_color;\n" " v_tex0 = in_tex0;\n" +" v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n" "}\n" ; -const char *im2d_frag_src = -"#version 330\n" - -"uniform sampler2D tex;\n" - -"in vec4 v_color;\n" -"in vec2 v_tex0;\n" - -"out vec4 color;\n" - -"void\n" -"main(void)\n" -"{\n" -" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n" -"}\n" - -; diff --git a/src/gl/shaders/im3d.vert b/src/gl/shaders/im3d.vert new file mode 100644 index 0000000..6cd5734 --- /dev/null +++ b/src/gl/shaders/im3d.vert @@ -0,0 +1,42 @@ +#version 330 + +layout(std140) uniform State +{ + int u_alphaTest; + float u_alphaRef; + + int u_fogEnable; + float u_fogStart; + float u_fogEnd; + vec4 u_fogColor; +}; + +layout(std140) uniform Scene +{ + mat4 u_proj; + mat4 u_view; +}; + +layout(std140) uniform Object +{ + mat4 u_world; +}; + +layout(location = 0) in vec3 in_pos; +layout(location = 2) in vec4 in_color; +layout(location = 3) in vec2 in_tex0; + +out vec4 v_color; +out vec2 v_tex0; +out float v_fog; + +void +main(void) +{ + vec4 V = u_world * vec4(in_pos, 1.0); + vec4 cV = u_view * V; + gl_Position = u_proj * cV; + v_color = in_color; + v_tex0 = in_tex0; + v_fog = clamp((cV.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0); +} diff --git a/src/gl/shaders/im3d_gl3.inc b/src/gl/shaders/im3d_gl3.inc new file mode 100644 index 0000000..2c878c0 --- /dev/null +++ b/src/gl/shaders/im3d_gl3.inc @@ -0,0 +1,44 @@ +const char *im3d_vert_src = +"#version 330\n" + +"layout(std140) uniform State\n" +"{\n" +" int u_alphaTest;\n" +" float u_alphaRef;\n" + +" int u_fogEnable;\n" +" float u_fogStart;\n" +" float u_fogEnd;\n" +" vec4 u_fogColor;\n" +"};\n" + +"layout(std140) uniform Scene\n" +"{\n" +" mat4 u_proj;\n" +" mat4 u_view;\n" +"};\n" + +"layout(std140) uniform Object\n" +"{\n" +" mat4 u_world;\n" +"};\n" + +"layout(location = 0) in vec3 in_pos;\n" +"layout(location = 2) in vec4 in_color;\n" +"layout(location = 3) in vec2 in_tex0;\n" + +"out vec4 v_color;\n" +"out vec2 v_tex0;\n" +"out float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 V = u_world * vec4(in_pos, 1.0);\n" +" vec4 cV = u_view * V; \n" +" gl_Position = u_proj * cV;\n" +" v_color = in_color;\n" +" v_tex0 = in_tex0;\n" +" v_fog = clamp((cV.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n" +"}\n" +; diff --git a/src/gl/shaders/simple_fs_gl3.inc b/src/gl/shaders/simple_fs_gl3.inc new file mode 100644 index 0000000..6cf1d7f --- /dev/null +++ b/src/gl/shaders/simple_fs_gl3.inc @@ -0,0 +1,43 @@ +const char *simple_frag_src = +"#version 330\n" + +"layout(std140) uniform State\n" +"{\n" +" int u_alphaTest;\n" +" float u_alphaRef;\n" + +" int u_fogEnable;\n" +" float u_fogStart;\n" +" float u_fogEnd;\n" +" vec4 u_fogColor;\n" +"};\n" + +"uniform sampler2D tex;\n" + +"in vec4 v_color;\n" +"in vec2 v_tex0;\n" +"in float v_fog;\n" + +"out vec4 color;\n" + +"void\n" +"main(void)\n" +"{\n" +" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n" +" if(u_fogEnable != 0)\n" +" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n" +" switch(u_alphaTest){\n" +" default:\n" +" case 0: break;\n" +" case 1:\n" +" if(color.a < u_alphaRef)\n" +" discard;\n" +" break;\n" +" case 2:\n" +" if(color.a >= u_alphaRef)\n" +" discard;\n" +" break;\n" +" }\n" +"}\n" + +; diff --git a/src/gl/shaders/simple_gl3.inc b/src/gl/shaders/simple_vs_gl3.inc similarity index 67% rename from src/gl/shaders/simple_gl3.inc rename to src/gl/shaders/simple_vs_gl3.inc index 76a21f8..5332b28 100644 --- a/src/gl/shaders/simple_gl3.inc +++ b/src/gl/shaders/simple_vs_gl3.inc @@ -70,46 +70,3 @@ const char *simple_vert_src = " v_fog = clamp((cV.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n" "}\n" ; -const char *simple_frag_src = -"#version 330\n" - -"layout(std140) uniform State\n" -"{\n" -" int u_alphaTest;\n" -" float u_alphaRef;\n" - -" int u_fogEnable;\n" -" float u_fogStart;\n" -" float u_fogEnd;\n" -" vec4 u_fogColor;\n" -"};\n" - -"uniform sampler2D tex;\n" - -"in vec4 v_color;\n" -"in vec2 v_tex0;\n" -"in float v_fog;\n" - -"out vec4 color;\n" - -"void\n" -"main(void)\n" -"{\n" -" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n" -" if(u_fogEnable != 0)\n" -" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n" -" switch(u_alphaTest){\n" -" default:\n" -" case 0: break;\n" -" case 1:\n" -" if(color.a < u_alphaRef)\n" -" discard;\n" -" break;\n" -" case 2:\n" -" if(color.a >= u_alphaRef)\n" -" discard;\n" -" break;\n" -" }\n" -"}\n" - -; diff --git a/src/render.cpp b/src/render.cpp new file mode 100644 index 0000000..543c910 --- /dev/null +++ b/src/render.cpp @@ -0,0 +1,51 @@ +#include + +#include "rwbase.h" +#include "rwplg.h" +#include "rwengine.h" + +namespace rw { + +void SetRenderState(int32 state, uint32 value){ + engine->device.setRenderState(state, value); } + +uint32 GetRenderState(int32 state){ + return engine->device.getRenderState(state); } + +// Im2D + +namespace im2d { + +float32 GetNearZ(void) { return engine->device.zNear; } +float32 GetFarZ(void) { return engine->device.zNear; } +void +RenderIndexedPrimitive(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices) +{ + engine->device.im2DRenderIndexedPrimitive(type, verts, numVerts, indices, numIndices); +} + +} + +// Im3D + +namespace im3d { + +void +Transform(void *vertices, int32 numVertices, Matrix *world) +{ + engine->device.im3DTransform(vertices, numVertices, world); +} +void +RenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) +{ + engine->device.im3DRenderIndexed(primType, indices, numIndices); +} +void +End(void) +{ + engine->device.im3DEnd(); +} + +} + +} \ No newline at end of file diff --git a/src/rwbase.h b/src/rwbase.h index 69a7922..f13a287 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -61,6 +61,66 @@ typedef uint32 uint; #define nelem(A) (sizeof(A) / sizeof A[0]) +// Lists + +struct LLLink +{ + LLLink *next; + LLLink *prev; + void init(void){ + this->next = nil; + this->prev = nil; + } + void remove(void){ + this->prev->next = this->next; + this->next->prev = this->prev; + } +}; + +#define LLLinkGetData(linkvar,type,entry) \ + ((type*)(((uint8*)(linkvar))-offsetof(type,entry))) + +// Have to be careful since the link might be deleted. +#define FORLIST(_link, _list) \ + for(rw::LLLink *_next = nil, *_link = (_list).link.next; \ + _next = (_link)->next, (_link) != (_list).end(); \ + (_link) = _next) + +struct LinkList +{ + LLLink link; + void init(void){ + this->link.next = &this->link; + this->link.prev = &this->link; + } + bool32 isEmpty(void){ + return this->link.next == &this->link; + } + void add(LLLink *link){ + link->next = this->link.next; + link->prev = &this->link; + this->link.next->prev = link; + this->link.next = link; + } + void append(LLLink *link){ + link->next = &this->link; + link->prev = this->link.prev; + this->link.prev->next = link; + this->link.prev = link; + } + LLLink *end(void){ + return &this->link; + } + int32 count(void){ + int32 n = 0; + FORLIST(lnk, (*this)) + n++; + return n; + } +}; + +// Mathematical types + struct RGBA { uint8 red; @@ -68,6 +128,7 @@ struct RGBA uint8 blue; uint8 alpha; }; +inline RGBA makeRGBA(uint8 r, uint8 g, uint8 b, uint8 a) { RGBA c = { r, g, b, a }; return c; } inline bool32 equal(const RGBA &c1, const RGBA &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; } struct RGBAf diff --git a/src/rwengine.h b/src/rwengine.h index 539c242..3bf30fe 100755 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -1,62 +1,30 @@ namespace rw { -enum RenderState -{ - VERTEXALPHA = 0, - SRCBLEND, - DESTBLEND, - ZTESTENABLE, - ZWRITEENABLE, - FOGENABLE, - FOGCOLOR, - // TODO: - // fog type, density ? - // ? cullmode - // ? shademode - // ???? stencil - - // platform specific or opaque? - ALPHATESTFUNC, - ALPHATESTREF, -}; - -enum AlphaTestFunc -{ - ALPHAALWAYS = 0, - ALPHAGREATEREQUAL, - ALPHALESS -}; - -enum BlendFunction -{ - BLENDZERO = 0, - BLENDONE, - BLENDSRCCOLOR, - BLENDINVSRCCOLOR, - BLENDSRCALPHA, - BLENDINVSRCALPHA, - BLENDDESTALPHA, - BLENDINVDESTALPHA, - BLENDDESTCOLOR, - BLENDINVDESTCOLOR, - BLENDSRCALPHASAT, - // TODO: add more perhaps -}; - enum DeviceReq { // Device/Context creation - DEVICESTART, + DEVICEOPEN, + // Device/Context shutdown + DEVICECLOSE, + // Device initialization before Engine/Driver plugins are opened DEVICEINIT, - // Device initialization after plugins are opened + // Device de-initialization after Engine/Driver plugins are closed + DEVICETERM, + + // Device initialization after Engine/Driver plugins are opened DEVICEFINALIZE, - // Device/Context shutdown - DEVICESTOP, + // TODO? counterpart to FINALIZE? }; typedef int DeviceSystem(DeviceReq req, void *arg0); +struct Camera; +struct Image; +struct Texture; +struct Raster; +class ObjPipeline; + // This is for the render device, we only have one struct Device { @@ -67,8 +35,18 @@ struct Device void (*showRaster)(Raster *raster); void (*setRenderState)(int32 state, uint32 value); uint32 (*getRenderState)(int32 state); + + // TODO: render line + // TODO: render triangle + // TODO: render primitive void (*im2DRenderIndexedPrimitive)(PrimitiveType, void*, int32, void*, int32); + + // Not sure if this will stay... + void (*im3DTransform)(void *vertices, int32 numVertices, Matrix *world); + void (*im3DRenderIndexed)(PrimitiveType primType, void *indices, int32 numIndices); + void (*im3DEnd)(void); + DeviceSystem *system; }; @@ -159,15 +137,6 @@ struct Engine extern Engine *engine; -inline void SetRenderState(int32 state, uint32 value){ - engine->device.setRenderState(state, value); } - -inline uint32 GetRenderState(int32 state){ - return engine->device.getRenderState(state); } - -inline float32 GetNearZ(void) { return engine->device.zNear; } -inline float32 GetFarZ(void) { return engine->device.zNear; } - // These must be macros because we might want to pass __FILE__ and __LINE__ later #define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h) #define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h) @@ -198,6 +167,10 @@ namespace null { void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32); + void im3DTransform(void *vertices, int32 numVertices, Matrix *world); + void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); + void im3DEnd(void); + int deviceSystem(DeviceReq req, void*); extern Device renderdevice; diff --git a/src/rwobjects.h b/src/rwobjects.h index d3ad3d3..f7af000 100755 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -2,62 +2,6 @@ namespace rw { -struct LLLink -{ - LLLink *next; - LLLink *prev; - void init(void){ - this->next = nil; - this->prev = nil; - } - void remove(void){ - this->prev->next = this->next; - this->next->prev = this->prev; - } -}; - -#define LLLinkGetData(linkvar,type,entry) \ - ((type*)(((uint8*)(linkvar))-offsetof(type,entry))) - -// Have to be careful since the link might be deleted. -#define FORLIST(_link, _list) \ - for(rw::LLLink *_next = nil, *_link = (_list).link.next; \ - _next = (_link)->next, (_link) != (_list).end(); \ - (_link) = _next) - -struct LinkList -{ - LLLink link; - void init(void){ - this->link.next = &this->link; - this->link.prev = &this->link; - } - bool32 isEmpty(void){ - return this->link.next == &this->link; - } - void add(LLLink *link){ - link->next = this->link.next; - link->prev = &this->link; - this->link.next->prev = link; - this->link.next = link; - } - void append(LLLink *link){ - link->next = &this->link; - link->prev = this->link.prev; - this->link.prev->next = link; - this->link.prev = link; - } - LLLink *end(void){ - return &this->link; - } - int32 count(void){ - int32 n = 0; - FORLIST(lnk, (*this)) - n++; - return n; - } -}; - struct Object { uint8 type; diff --git a/src/rwrender.h b/src/rwrender.h new file mode 100644 index 0000000..6277c84 --- /dev/null +++ b/src/rwrender.h @@ -0,0 +1,71 @@ +namespace rw { + +// Render states + +enum RenderState +{ + VERTEXALPHA = 0, + SRCBLEND, + DESTBLEND, + ZTESTENABLE, + ZWRITEENABLE, + FOGENABLE, + FOGCOLOR, + // TODO: + // fog type, density ? + // ? cullmode + // ? shademode + // ???? stencil + + // platform specific or opaque? + ALPHATESTFUNC, + ALPHATESTREF, +}; + +enum AlphaTestFunc +{ + ALPHAALWAYS = 0, + ALPHAGREATEREQUAL, + ALPHALESS +}; + +enum BlendFunction +{ + BLENDZERO = 0, + BLENDONE, + BLENDSRCCOLOR, + BLENDINVSRCCOLOR, + BLENDSRCALPHA, + BLENDINVSRCALPHA, + BLENDDESTALPHA, + BLENDINVDESTALPHA, + BLENDDESTCOLOR, + BLENDINVDESTCOLOR, + BLENDSRCALPHASAT, + // TODO: add more perhaps +}; + +void SetRenderState(int32 state, uint32 value); +uint32 GetRenderState(int32 state); + +// Im2D + +namespace im2d { + +float32 GetNearZ(void); +float32 GetFarZ(void); +void RenderIndexedPrimitive(PrimitiveType, void *verts, int32 numVerts, void *indices, int32 numIndices); + +} + +// Im3D + +namespace im3d { + +void Transform(void *vertices, int32 numVertices, Matrix *world); +void RenderIndexed(PrimitiveType primType, void *indices, int32 numIndices); +void End(void); + +} + +} \ No newline at end of file diff --git a/tools/clumpview/font.cpp b/tools/clumpview/font.cpp index fc17017..fa80204 100644 --- a/tools/clumpview/font.cpp +++ b/tools/clumpview/font.cpp @@ -43,7 +43,7 @@ printScreen(const char *s, float32 x, float32 y) vert->setScreenX(x); vert->setScreenY(y); - vert->setScreenZ(rw::GetNearZ()); + vert->setScreenZ(rw::im2d::GetNearZ()); vert->setCameraZ(cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setColor(255, 255, 255, 255); @@ -53,7 +53,7 @@ printScreen(const char *s, float32 x, float32 y) vert->setScreenX(x+curfont->glyphwidth); vert->setScreenY(y); - vert->setScreenZ(rw::GetNearZ()); + vert->setScreenZ(rw::im2d::GetNearZ()); vert->setCameraZ(cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setColor(255, 255, 255, 255); @@ -63,7 +63,7 @@ printScreen(const char *s, float32 x, float32 y) vert->setScreenX(x); vert->setScreenY(y+curfont->glyphheight); - vert->setScreenZ(rw::GetNearZ()); + vert->setScreenZ(rw::im2d::GetNearZ()); vert->setCameraZ(cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setColor(255, 255, 255, 255); @@ -73,7 +73,7 @@ printScreen(const char *s, float32 x, float32 y) vert->setScreenX(x+curfont->glyphwidth); vert->setScreenY(y+curfont->glyphheight); - vert->setScreenZ(rw::GetNearZ()); + vert->setScreenZ(rw::im2d::GetNearZ()); vert->setCameraZ(cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setColor(255, 255, 255, 255); @@ -95,7 +95,7 @@ printScreen(const char *s, float32 x, float32 y) s++; } engine->imtexture = curfont->tex; - rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST, + im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, vertices, curVert, indices, curIndex); } diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index d193f1e..ef85023 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -14,6 +14,9 @@ rw::Texture *tex; rw::EngineStartParams engineStartParams; void tlTest(rw::Clump *clump); +void genIm3DTransform(void *vertices, rw::int32 numVertices, rw::Matrix *xform); +void genIm3DRenderIndexed(rw::PrimitiveType prim, void *indices, rw::int32 numIndices); +void genIm3DEnd(void); void initFont(void); void printScreen(const char *s, float x, float y); @@ -241,7 +244,7 @@ im2dtest(void) { 0.0f, 480.0f, 0, 0, 255, 128, 0.0f, 1.0f }, { 640.0f, 480.0f, 0, 255, 255, 128, 1.0f, 1.0f }, }; - static Im2DVertex verts[4]; + Im2DVertex verts[4]; static short indices[] = { 0, 1, 2, 3 }; @@ -249,7 +252,7 @@ im2dtest(void) for(i = 0; i < 4; i++){ verts[i].setScreenX(vs[i].x); verts[i].setScreenY(vs[i].y); - verts[i].setScreenZ(rw::GetNearZ()); + verts[i].setScreenZ(rw::im2d::GetNearZ()); verts[i].setCameraZ(Scene.camera->nearPlane); verts[i].setRecipCameraZ(1.0f/Scene.camera->nearPlane); verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a); @@ -259,10 +262,58 @@ im2dtest(void) rw::engine->imtexture = tex; rw::SetRenderState(rw::VERTEXALPHA, 1); - rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, + rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, &verts, 4, &indices, 4); } +void +im3dtest(void) +{ + using namespace rw::RWDEVICE; + int i; + static struct + { + float x, y, z; + rw::uint8 r, g, b, a; + float u, v; + } vs[8] = { + { -1.0f, -1.0f, -1.0f, 255, 0, 0, 128, 0.0f, 0.0f }, + { -1.0f, 1.0f, -1.0f, 0, 255, 0, 128, 0.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, 0, 0, 255, 128, 1.0f, 0.0f }, + { 1.0f, 1.0f, -1.0f, 255, 0, 255, 128, 1.0f, 1.0f }, + + { -1.0f, -1.0f, 1.0f, 255, 0, 0, 128, 0.0f, 0.0f }, + { -1.0f, 1.0f, 1.0f, 0, 255, 0, 128, 0.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, 0, 0, 255, 128, 1.0f, 0.0f }, + { 1.0f, 1.0f, 1.0f, 255, 0, 255, 128, 1.0f, 1.0f }, + }; + Im3DVertex verts[8]; + static short indices[2*6] = { + 0, 1, 2, 2, 1, 3, + 4, 5, 6, 6, 5, 7 + }; + + for(i = 0; i < 8; i++){ + verts[i].setX(vs[i].x); + verts[i].setY(vs[i].y); + verts[i].setZ(vs[i].z); + verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a); + verts[i].setU(vs[i].u); + verts[i].setV(vs[i].v); + } + + rw::engine->imtexture = tex; + +/* + genIm3DTransform(verts, 8, nil); + genIm3DRenderIndexed(rw::PRIMTYPETRILIST, indices, 12); + genIm3DEnd(); +*/ + rw::im3d::Transform(verts, 8, nil); + rw::im3d::RenderIndexed(rw::PRIMTYPETRILIST, indices, 12); + rw::im3d::End(); +} + void Draw(float timeDelta) { @@ -271,9 +322,10 @@ Draw(float timeDelta) camera->update(); camera->m_rwcam->beginUpdate(); - Scene.clump->render(); - im2dtest(); +// Scene.clump->render(); +// im2dtest(); // tlTest(Scene.clump); + im3dtest(); printScreen("Hello, World!", 10, 10); camera->m_rwcam->endUpdate(); diff --git a/tools/clumpview/tests.cpp b/tools/clumpview/tests.cpp index b3fcb8d..68d159d 100644 --- a/tools/clumpview/tests.cpp +++ b/tools/clumpview/tests.cpp @@ -5,6 +5,7 @@ using namespace rw; // // This is a test to implement T&L in software and render with Im2D +// #define MAX_LIGHTS 8 @@ -90,7 +91,7 @@ drawAtomic(Atomic *a) im2dverts[i].setV(texcoords[i].v); } for(int32 i = 0; i < mh->numMeshes; i++){ - for(int32 j = 0; j < m[i].numIndices; j++){ + for(uint32 j = 0; j < m[i].numIndices; j++){ int32 idx = m[i].indices[j]; RGBA col; RGBAf colf, color; @@ -116,7 +117,7 @@ drawAtomic(Atomic *a) } engine->imtexture = m[i].material->texture; - rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST, + im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, im2dverts, g->numVertices, m[i].indices, m[i].numIndices); } @@ -132,3 +133,60 @@ tlTest(Clump *clump) drawAtomic(a); } } + +static RWDEVICE::Im2DVertex *clipverts; +static int32 numClipverts; + +void +genIm3DTransform(void *vertices, int32 numVertices, Matrix *world) +{ + using namespace RWDEVICE; + Im3DVertex *objverts; + V3d pos; + Matrix xform; + Camera *cam; + int32 i; + objverts = (Im3DVertex*)vertices; + + cam = (Camera*)engine->currentCamera; + int32 width = cam->frameBuffer->width; + int32 height = cam->frameBuffer->height; + + + xform = cam->viewMatrix; + if(world) + xform.transform(world, COMBINEPRECONCAT); + + clipverts = rwNewT(Im2DVertex, numVertices, MEMDUR_EVENT); + numClipverts = numVertices; + + for(i = 0; i < numVertices; i++){ + V3d::transformPoints(&pos, &objverts[i].position, 1, &xform); + + float32 recipZ = 1.0f/pos.z; + RGBA c = objverts[i].getColor(); + + clipverts[i].setScreenX(pos.x * recipZ * width); + clipverts[i].setScreenY((pos.y * recipZ * height)); + clipverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift); + clipverts[i].setCameraZ(pos.z); + clipverts[i].setRecipCameraZ(recipZ); + clipverts[i].setColor(c.red, c.green, c.blue, c.alpha); + clipverts[i].setU(objverts[i].u); + clipverts[i].setV(objverts[i].v); + } +} + +void +genIm3DRenderIndexed(PrimitiveType prim, void *indices, int32 numIndices) +{ + im2d::RenderIndexedPrimitive(prim, clipverts, numClipverts, indices, numIndices); +} + +void +genIm3DEnd(void) +{ + rwFree(clipverts); + clipverts = nil; + numClipverts = 0; +}