implemented im3d for gl3 and d3d

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

3
rw.h
View File

@ -4,10 +4,11 @@
#include "src/rwbase.h" #include "src/rwbase.h"
#include "src/rwerror.h" #include "src/rwerror.h"
#include "src/rwplg.h" #include "src/rwplg.h"
#include "src/rwrender.h"
#include "src/rwengine.h"
#include "src/rwpipeline.h" #include "src/rwpipeline.h"
#include "src/rwobjects.h" #include "src/rwobjects.h"
#include "src/rwanim.h" #include "src/rwanim.h"
#include "src/rwengine.h"
#include "src/rwplugins.h" #include "src/rwplugins.h"
#include "src/rwuserdata.h" #include "src/rwuserdata.h"
#include "src/ps2/rwps2.h" #include "src/ps2/rwps2.h"

View File

@ -18,42 +18,6 @@ namespace rw {
namespace d3d8 { namespace d3d8 {
using namespace d3d; 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* static void*
matfxOpen(void *o, int32, int32) matfxOpen(void *o, int32, int32)
{ {

View File

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

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

@ -0,0 +1,54 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwd3d.h"
#include "rwd3d8.h"
namespace rw {
namespace d3d8 {
using namespace d3d;
static void*
skinOpen(void *o, int32, int32)
{
skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline();
return o;
}
static void*
skinClose(void *o, int32, int32)
{
return o;
}
void
initSkin(void)
{
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
skinOpen, skinClose);
}
ObjPipeline*
makeSkinPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
}
}
}

View File

@ -18,42 +18,6 @@ namespace rw {
namespace d3d9 { namespace d3d9 {
using namespace d3d; 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* static void*
matfxOpen(void *o, int32, int32) matfxOpen(void *o, int32, int32)
{ {

View File

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

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

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

View File

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

View File

@ -48,6 +48,14 @@ openIm2D(void)
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16)); im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
} }
void
closeIm2D(void)
{
deleteObject(im2ddecl);
deleteObject(im2dvertbuf);
deleteObject(im2dindbuf);
}
void void
im2DRenderIndexedPrimitive(PrimitiveType primType, im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices) void *vertices, int32 numVertices, void *indices, int32 numIndices)
@ -97,6 +105,103 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
0, primCount); 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 #endif
} }
} }

View File

@ -22,6 +22,22 @@ extern Device renderdevice;
void lightingCB(void); 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 struct Im2DVertex
{ {
float32 x, y, z; float32 x, y, z;

View File

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

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

@ -0,0 +1,51 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwxbox.h"
namespace rw {
namespace xbox {
static void*
matfxOpen(void *o, int32, int32)
{
matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline();
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
}
}

View File

@ -13,13 +13,11 @@
#include "../rwplugins.h" #include "../rwplugins.h"
#include "rwxbox.h" #include "rwxbox.h"
#define PLUGIN_ID ID_SKIN // yeah right.... #define PLUGIN_ID ID_SKIN
namespace rw { namespace rw {
namespace xbox { namespace xbox {
// Skin
struct NativeSkin struct NativeSkin
{ {
int32 table1[256]; // maps indices to bones int32 table1[256]; // maps indices to bones
@ -246,135 +244,5 @@ makeSkinPipeline(void)
return pipe; return pipe;
} }
// MatFX
static void*
matfxOpen(void *o, int32, int32)
{
matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline();
return o;
}
static void*
matfxClose(void *o, int32, int32)
{
return o;
}
void
initMatFX(void)
{
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
matfxOpen, matfxClose);
}
ObjPipeline*
makeMatFXPipeline(void)
{
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;
}
// Vertex Format
static int32 vertexFmtOffset;
uint32 vertexFormatSizes[6] = {
0, 1, 2, 2, 4, 4
};
uint32*
getVertexFmt(Geometry *g)
{
return PLUGINOFFSET(uint32, g, vertexFmtOffset);
}
uint32
makeVertexFmt(int32 flags, uint32 numTexSets)
{
if(numTexSets > 4)
numTexSets = 4;
uint32 fmt = 0x5; // FLOAT3
if(flags & Geometry::NORMALS)
fmt |= 0x40; // NORMPACKED3
for(uint32 i = 0; i < numTexSets; i++)
fmt |= 0x500 << i*4; // FLOAT2
if(flags & Geometry::PRELIT)
fmt |= 0x1000000; // D3DCOLOR
return fmt;
}
uint32
getVertexFmtStride(uint32 fmt)
{
uint32 stride = 0;
uint32 v = fmt & 0xF;
uint32 n = (fmt >> 4) & 0xF;
stride += v == 4 ? 4 : 3*vertexFormatSizes[v];
stride += n == 4 ? 4 : 3*vertexFormatSizes[n];
if(fmt & 0x1000000)
stride += 4;
for(int i = 0; i < 4; i++){
uint32 t = (fmt >> (i*4 + 8)) & 0xF;
stride += t == 4 ? 4 : 2*vertexFormatSizes[t];
}
if(fmt & 0xE000000)
stride += 8;
return stride;
}
static void*
createVertexFmt(void *object, int32 offset, int32)
{
*PLUGINOFFSET(uint32, object, offset) = 0;
return object;
}
static void*
copyVertexFmt(void *dst, void *src, int32 offset, int32)
{
*PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
return dst;
}
static Stream*
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
uint32 fmt = stream->readU32();
*PLUGINOFFSET(uint32, object, offset) = fmt;
// TODO: ? create and attach "vertex shader"
return stream;
}
static Stream*
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
return stream;
}
static int32
getSizeVertexFmt(void*, int32, int32)
{
if(rw::platform != PLATFORM_XBOX)
return -1;
return 4;
}
void
registerVertexFormatPlugin(void)
{
vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT,
createVertexFmt, nil, copyVertexFmt);
Geometry::registerPluginStream(ID_VERTEXFMT,
readVertexFmt,
writeVertexFmt,
getSizeVertexFmt);
}
} }
} }

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

@ -0,0 +1,115 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h"
#include "rwxbox.h"
namespace rw {
namespace xbox {
static int32 vertexFmtOffset;
uint32 vertexFormatSizes[6] = {
0, 1, 2, 2, 4, 4
};
uint32*
getVertexFmt(Geometry *g)
{
return PLUGINOFFSET(uint32, g, vertexFmtOffset);
}
uint32
makeVertexFmt(int32 flags, uint32 numTexSets)
{
if(numTexSets > 4)
numTexSets = 4;
uint32 fmt = 0x5; // FLOAT3
if(flags & Geometry::NORMALS)
fmt |= 0x40; // NORMPACKED3
for(uint32 i = 0; i < numTexSets; i++)
fmt |= 0x500 << i*4; // FLOAT2
if(flags & Geometry::PRELIT)
fmt |= 0x1000000; // D3DCOLOR
return fmt;
}
uint32
getVertexFmtStride(uint32 fmt)
{
uint32 stride = 0;
uint32 v = fmt & 0xF;
uint32 n = (fmt >> 4) & 0xF;
stride += v == 4 ? 4 : 3*vertexFormatSizes[v];
stride += n == 4 ? 4 : 3*vertexFormatSizes[n];
if(fmt & 0x1000000)
stride += 4;
for(int i = 0; i < 4; i++){
uint32 t = (fmt >> (i*4 + 8)) & 0xF;
stride += t == 4 ? 4 : 2*vertexFormatSizes[t];
}
if(fmt & 0xE000000)
stride += 8;
return stride;
}
static void*
createVertexFmt(void *object, int32 offset, int32)
{
*PLUGINOFFSET(uint32, object, offset) = 0;
return object;
}
static void*
copyVertexFmt(void *dst, void *src, int32 offset, int32)
{
*PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
return dst;
}
static Stream*
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
uint32 fmt = stream->readU32();
*PLUGINOFFSET(uint32, object, offset) = fmt;
// TODO: ? create and attach "vertex shader"
return stream;
}
static Stream*
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
{
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
return stream;
}
static int32
getSizeVertexFmt(void*, int32, int32)
{
if(rw::platform != PLATFORM_XBOX)
return -1;
return 4;
}
void
registerVertexFormatPlugin(void)
{
vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT,
createVertexFmt, nil, copyVertexFmt);
Geometry::registerPluginStream(ID_VERTEXFMT,
readVertexFmt,
writeVertexFmt,
getSizeVertexFmt);
}
}
}

View File

@ -158,7 +158,8 @@ Engine::start(EngineStartParams *p)
return 0; 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->device.system(DEVICEINIT, nil);
Engine::s_plglist.construct(engine); Engine::s_plglist.construct(engine);
@ -191,7 +192,8 @@ Engine::close(void)
void void
Engine::stop(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++) for(uint i = 0; i < NUM_PLATFORMS; i++)
Driver::s_plglist[i].destruct(rw::engine->driver[i]); Driver::s_plglist[i].destruct(rw::engine->driver[i]);
Engine::s_plglist.destruct(engine); Engine::s_plglist.destruct(engine);
@ -210,6 +212,10 @@ uint32 getRenderState(int32) { return 0; }
void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { } 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 void
rasterCreate(Raster*) rasterCreate(Raster*)
{ {
@ -264,6 +270,9 @@ Device renderdevice = {
null::setRenderState, null::setRenderState,
null::getRenderState, null::getRenderState,
null::im2DRenderIndexedPrimitive, null::im2DRenderIndexedPrimitive,
null::im3DTransform,
null::im3DRenderIndexed,
null::im3DEnd,
null::deviceSystem null::deviceSystem
}; };

View File

@ -5,9 +5,10 @@
#include "../rwbase.h" #include "../rwbase.h"
#include "../rwerror.h" #include "../rwerror.h"
#include "../rwplg.h" #include "../rwplg.h"
#include "../rwrender.h"
#include "../rwengine.h"
#include "../rwpipeline.h" #include "../rwpipeline.h"
#include "../rwobjects.h" #include "../rwobjects.h"
#include "../rwengine.h"
#ifdef RW_OPENGL #ifdef RW_OPENGL
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -467,7 +468,7 @@ beginUpdate(Camera *cam)
} }
static int static int
startGLFW(EngineStartParams *startparams) openGLFW(EngineStartParams *startparams)
{ {
GLenum status; GLenum status;
GLFWwindow *win; GLFWwindow *win;
@ -512,7 +513,7 @@ startGLFW(EngineStartParams *startparams)
} }
static int static int
stopGLFW(void) closeGLFW(void)
{ {
glfwDestroyWindow(glfwwindow); glfwDestroyWindow(glfwwindow);
glfwTerminate(); glfwTerminate();
@ -564,14 +565,24 @@ initOpenGL(void)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel); 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); simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
openIm2D(); openIm2D();
openIm3D();
return 1; return 1;
} }
static int
termOpenGL(void)
{
closeIm3D();
closeIm2D();
return 1;
}
static int static int
finalizeOpenGL(void) finalizeOpenGL(void)
{ {
@ -582,14 +593,18 @@ static int
deviceSystem(DeviceReq req, void *arg0) deviceSystem(DeviceReq req, void *arg0)
{ {
switch(req){ switch(req){
case DEVICESTART: case DEVICEOPEN:
return startGLFW((EngineStartParams*)arg0); return openGLFW((EngineStartParams*)arg0);
case DEVICECLOSE:
return closeGLFW();
case DEVICEINIT: case DEVICEINIT:
return initOpenGL(); return initOpenGL();
case DEVICETERM:
return termOpenGL();
case DEVICEFINALIZE: case DEVICEFINALIZE:
return finalizeOpenGL(); return finalizeOpenGL();
case DEVICESTOP:
return stopGLFW();
} }
return 1; return 1;
} }
@ -603,6 +618,9 @@ Device renderdevice = {
gl3::setRenderState, gl3::setRenderState,
gl3::getRenderState, gl3::getRenderState,
gl3::im2DRenderIndexedPrimitive, gl3::im2DRenderIndexedPrimitive,
gl3::im3DTransform,
gl3::im3DRenderIndexed,
gl3::im3DEnd,
gl3::deviceSystem gl3::deviceSystem
}; };

View File

@ -1,104 +0,0 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#ifdef RW_OPENGL
#include <GL/glew.h>
#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

199
src/gl/gl3immed.cpp Normal file
View File

@ -0,0 +1,199 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "../rwbase.h"
#include "../rwerror.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#ifdef RW_OPENGL
#include <GL/glew.h>
#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

242
src/gl/gl3matfx.cpp Normal file
View File

@ -0,0 +1,242 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#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 <GL/glew.h>
#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
}
}

View File

@ -5,9 +5,10 @@
#include "../rwbase.h" #include "../rwbase.h"
#include "../rwerror.h" #include "../rwerror.h"
#include "../rwplg.h" #include "../rwplg.h"
#include "../rwrender.h"
#include "../rwengine.h"
#include "../rwpipeline.h" #include "../rwpipeline.h"
#include "../rwobjects.h" #include "../rwobjects.h"
#include "../rwengine.h"
#ifdef RW_OPENGL #ifdef RW_OPENGL
#include <GL/glew.h> #include <GL/glew.h>
#include "rwgl3.h" #include "rwgl3.h"
@ -72,7 +73,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
Material *m; Material *m;
RGBAf col; RGBAf col;
GLfloat surfProps[4]; GLfloat surfProps[4];
int id;
setWorldMatrix(atomic->getFrame()->getLTM()); setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB(); lightingCB();

View File

@ -201,6 +201,14 @@ Shader::use(void)
} }
} }
void
Shader::destroy(void)
{
glDeleteProgram(this->program);
rwFree(this->uniformLocations);
rwFree(this);
}
} }
} }

View File

@ -6,10 +6,11 @@
#include "../rwbase.h" #include "../rwbase.h"
#include "../rwerror.h" #include "../rwerror.h"
#include "../rwplg.h" #include "../rwplg.h"
#include "../rwrender.h"
#include "../rwengine.h"
#include "../rwpipeline.h" #include "../rwpipeline.h"
#include "../rwobjects.h" #include "../rwobjects.h"
#include "../rwanim.h" #include "../rwanim.h"
#include "../rwengine.h"
#include "../rwplugins.h" #include "../rwplugins.h"
#ifdef RW_OPENGL #ifdef RW_OPENGL
#include <GL/glew.h> #include <GL/glew.h>
@ -27,214 +28,6 @@ namespace gl3 {
#define U(i) currentShader->uniformLocations[i] #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 Shader *skinShader;
static int32 u_boneMatrices; static int32 u_boneMatrices;
@ -242,7 +35,7 @@ static void*
skinOpen(void *o, int32, int32) skinOpen(void *o, int32, int32)
{ {
u_boneMatrices = registerUniform("u_boneMatrices"); u_boneMatrices = registerUniform("u_boneMatrices");
#include "shaders/simple_gl3.inc" #include "shaders/simple_fs_gl3.inc"
#include "shaders/skin_gl3.inc" #include "shaders/skin_gl3.inc"
skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline(); skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline();
skinShader = Shader::fromStrings(skin_vert_src, simple_frag_src); skinShader = Shader::fromStrings(skin_vert_src, simple_frag_src);
@ -448,7 +241,6 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
Material *m; Material *m;
RGBAf col; RGBAf col;
GLfloat surfProps[4]; GLfloat surfProps[4];
int id;
setWorldMatrix(atomic->getFrame()->getLTM()); setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB(); lightingCB();
@ -507,7 +299,6 @@ makeSkinPipeline(void)
#else #else
void initMatFX(void) { }
void initSkin(void) { } void initSkin(void) { }
#endif #endif

View File

@ -80,6 +80,22 @@ struct InstanceDataHeader : rw::InstanceDataHeader
#ifdef RW_GL3 #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 struct Im2DVertex
{ {
float32 x, y, z, w; float32 x, y, z, w;

View File

@ -6,9 +6,15 @@ namespace gl3 {
extern Shader *simpleShader; extern Shader *simpleShader;
extern uint32 im2DVbo, im2DIbo; extern uint32 im2DVbo, im2DIbo;
void openIm2D(void); void openIm2D(void);
void closeIm2D(void);
void im2DRenderIndexedPrimitive(PrimitiveType primType, void im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices); 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 #endif
void rasterCreate(Raster *raster); void rasterCreate(Raster *raster);

View File

@ -35,6 +35,7 @@ public:
static Shader *fromFiles(const char *vs, const char *fs); static Shader *fromFiles(const char *vs, const char *fs);
static Shader *fromStrings(const char *vsrc, const char *fsrc); static Shader *fromStrings(const char *vsrc, const char *fsrc);
void use(void); void use(void);
void destroy(void);
}; };
extern Shader *currentShader; extern Shader *currentShader;

View File

@ -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 =';\ (echo 'const char *im2d_vert_src =';\
sed 's/..*/"&\\n"/' im2d.vert;\ sed 's/..*/"&\\n"/' im2d.vert;\
echo ';';\
echo 'const char *im2d_frag_src =';\
sed 's/..*/"&\\n"/' im2d.frag;\
echo ';') >im2d_gl3.inc 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 =';\ (echo 'const char *simple_vert_src =';\
sed 's/..*/"&\\n"/' simple.vert;\ sed 's/..*/"&\\n"/' simple.vert;\
echo ';';\ echo ';') >simple_vs_gl3.inc
echo 'const char *simple_frag_src =';\
simple_fs_gl3.inc: simple.frag
(echo 'const char *simple_frag_src =';\
sed 's/..*/"&\\n"/' simple.frag;\ sed 's/..*/"&\\n"/' simple.frag;\
echo ';') >simple_gl3.inc echo ';') >simple_fs_gl3.inc
matfx_gl3.inc: matfx_env.frag matfx_env.vert matfx_gl3.inc: matfx_env.frag matfx_env.vert
(echo 'const char *matfx_env_vert_src =';\ (echo 'const char *matfx_env_vert_src =';\

View File

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

View File

@ -1,11 +1,15 @@
#version 330 #version 330
//layout(std140) uniform Im2DState layout(std140) uniform State
//{ {
// int u_alphaTest; int u_alphaTest;
// float u_alphaRef; float u_alphaRef;
// mat4 u_xform;
//}; int u_fogEnable;
float u_fogStart;
float u_fogEnd;
vec4 u_fogColor;
};
uniform vec4 u_xform; uniform vec4 u_xform;
@ -15,6 +19,7 @@ layout(location = 3) in vec2 in_tex0;
out vec4 v_color; out vec4 v_color;
out vec2 v_tex0; out vec2 v_tex0;
out float v_fog;
void void
main(void) main(void)
@ -24,4 +29,5 @@ main(void)
gl_Position.xyz *= gl_Position.w; gl_Position.xyz *= gl_Position.w;
v_color = in_color; v_color = in_color;
v_tex0 = in_tex0; v_tex0 = in_tex0;
v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);
} }

View File

@ -1,12 +1,16 @@
const char *im2d_vert_src = const char *im2d_vert_src =
"#version 330\n" "#version 330\n"
"//layout(std140) uniform Im2DState\n" "layout(std140) uniform State\n"
"//{\n" "{\n"
"// int u_alphaTest;\n" " int u_alphaTest;\n"
"// float u_alphaRef;\n" " float u_alphaRef;\n"
"// mat4 u_xform;\n"
"//};\n" " int u_fogEnable;\n"
" float u_fogStart;\n"
" float u_fogEnd;\n"
" vec4 u_fogColor;\n"
"};\n"
"uniform vec4 u_xform;\n" "uniform vec4 u_xform;\n"
@ -16,6 +20,7 @@ const char *im2d_vert_src =
"out vec4 v_color;\n" "out vec4 v_color;\n"
"out vec2 v_tex0;\n" "out vec2 v_tex0;\n"
"out float v_fog;\n"
"void\n" "void\n"
"main(void)\n" "main(void)\n"
@ -25,22 +30,6 @@ const char *im2d_vert_src =
" gl_Position.xyz *= gl_Position.w;\n" " gl_Position.xyz *= gl_Position.w;\n"
" v_color = in_color;\n" " v_color = in_color;\n"
" v_tex0 = in_tex0;\n" " v_tex0 = in_tex0;\n"
" v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n"
"}\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"
;

42
src/gl/shaders/im3d.vert Normal file
View File

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

View File

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

View File

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

View File

@ -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" " v_fog = clamp((cV.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n"
"}\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"
;

51
src/render.cpp Normal file
View File

@ -0,0 +1,51 @@
#include <cstdio>
#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();
}
}
}

View File

@ -61,6 +61,66 @@ typedef uint32 uint;
#define nelem(A) (sizeof(A) / sizeof A[0]) #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 struct RGBA
{ {
uint8 red; uint8 red;
@ -68,6 +128,7 @@ struct RGBA
uint8 blue; uint8 blue;
uint8 alpha; 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; } 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 struct RGBAf

View File

@ -1,62 +1,30 @@
namespace rw { 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 enum DeviceReq
{ {
// Device/Context creation // Device/Context creation
DEVICESTART, DEVICEOPEN,
// Device/Context shutdown
DEVICECLOSE,
// Device initialization before Engine/Driver plugins are opened // Device initialization before Engine/Driver plugins are opened
DEVICEINIT, 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, DEVICEFINALIZE,
// Device/Context shutdown // TODO? counterpart to FINALIZE?
DEVICESTOP,
}; };
typedef int DeviceSystem(DeviceReq req, void *arg0); 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 // This is for the render device, we only have one
struct Device struct Device
{ {
@ -67,8 +35,18 @@ struct Device
void (*showRaster)(Raster *raster); void (*showRaster)(Raster *raster);
void (*setRenderState)(int32 state, uint32 value); void (*setRenderState)(int32 state, uint32 value);
uint32 (*getRenderState)(int32 state); uint32 (*getRenderState)(int32 state);
// TODO: render line
// TODO: render triangle
// TODO: render primitive
void (*im2DRenderIndexedPrimitive)(PrimitiveType, void (*im2DRenderIndexedPrimitive)(PrimitiveType,
void*, int32, void*, int32); 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; DeviceSystem *system;
}; };
@ -159,15 +137,6 @@ struct Engine
extern Engine *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 // 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 rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),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 im2DRenderIndexedPrimitive(PrimitiveType,
void*, int32, void*, int32); 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*); int deviceSystem(DeviceReq req, void*);
extern Device renderdevice; extern Device renderdevice;

View File

@ -2,62 +2,6 @@
namespace rw { 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 struct Object
{ {
uint8 type; uint8 type;

71
src/rwrender.h Normal file
View File

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

View File

@ -43,7 +43,7 @@ printScreen(const char *s, float32 x, float32 y)
vert->setScreenX(x); vert->setScreenX(x);
vert->setScreenY(y); vert->setScreenY(y);
vert->setScreenZ(rw::GetNearZ()); vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane); vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane);
vert->setColor(255, 255, 255, 255); vert->setColor(255, 255, 255, 255);
@ -53,7 +53,7 @@ printScreen(const char *s, float32 x, float32 y)
vert->setScreenX(x+curfont->glyphwidth); vert->setScreenX(x+curfont->glyphwidth);
vert->setScreenY(y); vert->setScreenY(y);
vert->setScreenZ(rw::GetNearZ()); vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane); vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane);
vert->setColor(255, 255, 255, 255); vert->setColor(255, 255, 255, 255);
@ -63,7 +63,7 @@ printScreen(const char *s, float32 x, float32 y)
vert->setScreenX(x); vert->setScreenX(x);
vert->setScreenY(y+curfont->glyphheight); vert->setScreenY(y+curfont->glyphheight);
vert->setScreenZ(rw::GetNearZ()); vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane); vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane);
vert->setColor(255, 255, 255, 255); vert->setColor(255, 255, 255, 255);
@ -73,7 +73,7 @@ printScreen(const char *s, float32 x, float32 y)
vert->setScreenX(x+curfont->glyphwidth); vert->setScreenX(x+curfont->glyphwidth);
vert->setScreenY(y+curfont->glyphheight); vert->setScreenY(y+curfont->glyphheight);
vert->setScreenZ(rw::GetNearZ()); vert->setScreenZ(rw::im2d::GetNearZ());
vert->setCameraZ(cam->nearPlane); vert->setCameraZ(cam->nearPlane);
vert->setRecipCameraZ(1.0f/cam->nearPlane); vert->setRecipCameraZ(1.0f/cam->nearPlane);
vert->setColor(255, 255, 255, 255); vert->setColor(255, 255, 255, 255);
@ -95,7 +95,7 @@ printScreen(const char *s, float32 x, float32 y)
s++; s++;
} }
engine->imtexture = curfont->tex; engine->imtexture = curfont->tex;
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST, im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
vertices, curVert, indices, curIndex); vertices, curVert, indices, curIndex);
} }

View File

@ -14,6 +14,9 @@ rw::Texture *tex;
rw::EngineStartParams engineStartParams; rw::EngineStartParams engineStartParams;
void tlTest(rw::Clump *clump); 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 initFont(void);
void printScreen(const char *s, float x, float y); 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 }, { 0.0f, 480.0f, 0, 0, 255, 128, 0.0f, 1.0f },
{ 640.0f, 480.0f, 0, 255, 255, 128, 1.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[] = { static short indices[] = {
0, 1, 2, 3 0, 1, 2, 3
}; };
@ -249,7 +252,7 @@ im2dtest(void)
for(i = 0; i < 4; i++){ for(i = 0; i < 4; i++){
verts[i].setScreenX(vs[i].x); verts[i].setScreenX(vs[i].x);
verts[i].setScreenY(vs[i].y); 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].setCameraZ(Scene.camera->nearPlane);
verts[i].setRecipCameraZ(1.0f/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); 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::engine->imtexture = tex;
rw::SetRenderState(rw::VERTEXALPHA, 1); rw::SetRenderState(rw::VERTEXALPHA, 1);
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
&verts, 4, &indices, 4); &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 void
Draw(float timeDelta) Draw(float timeDelta)
{ {
@ -271,9 +322,10 @@ Draw(float timeDelta)
camera->update(); camera->update();
camera->m_rwcam->beginUpdate(); camera->m_rwcam->beginUpdate();
Scene.clump->render(); // Scene.clump->render();
im2dtest(); // im2dtest();
// tlTest(Scene.clump); // tlTest(Scene.clump);
im3dtest();
printScreen("Hello, World!", 10, 10); printScreen("Hello, World!", 10, 10);
camera->m_rwcam->endUpdate(); camera->m_rwcam->endUpdate();

View File

@ -5,6 +5,7 @@ using namespace rw;
// //
// This is a test to implement T&L in software and render with Im2D // This is a test to implement T&L in software and render with Im2D
//
#define MAX_LIGHTS 8 #define MAX_LIGHTS 8
@ -90,7 +91,7 @@ drawAtomic(Atomic *a)
im2dverts[i].setV(texcoords[i].v); im2dverts[i].setV(texcoords[i].v);
} }
for(int32 i = 0; i < mh->numMeshes; i++){ 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]; int32 idx = m[i].indices[j];
RGBA col; RGBA col;
RGBAf colf, color; RGBAf colf, color;
@ -116,7 +117,7 @@ drawAtomic(Atomic *a)
} }
engine->imtexture = m[i].material->texture; 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); im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
} }
@ -132,3 +133,60 @@ tlTest(Clump *clump)
drawAtomic(a); 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;
}