mirror of https://github.com/aap/librw.git
implemented im3d for gl3 and d3d
This commit is contained in:
parent
b7f643a632
commit
d00ab2f526
3
rw.h
3
rw.h
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
{
|
{
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
|
@ -201,6 +201,14 @@ Shader::use(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Shader::destroy(void)
|
||||||
|
{
|
||||||
|
glDeleteProgram(this->program);
|
||||||
|
rwFree(this->uniformLocations);
|
||||||
|
rwFree(this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 =';\
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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"
|
||||||
|
;
|
|
@ -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"
|
||||||
|
|
||||||
|
;
|
|
@ -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"
|
|
||||||
|
|
||||||
;
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
src/rwbase.h
61
src/rwbase.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue