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/rwerror.h"
|
||||
#include "src/rwplg.h"
|
||||
#include "src/rwrender.h"
|
||||
#include "src/rwengine.h"
|
||||
#include "src/rwpipeline.h"
|
||||
#include "src/rwobjects.h"
|
||||
#include "src/rwanim.h"
|
||||
#include "src/rwengine.h"
|
||||
#include "src/rwplugins.h"
|
||||
#include "src/rwuserdata.h"
|
||||
#include "src/ps2/rwps2.h"
|
||||
|
|
|
@ -18,42 +18,6 @@ namespace rw {
|
|||
namespace d3d8 {
|
||||
using namespace d3d;
|
||||
|
||||
// Skin
|
||||
|
||||
static void*
|
||||
skinOpen(void *o, int32, int32)
|
||||
{
|
||||
skinGlobals.pipelines[PLATFORM_D3D8] = makeSkinPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
skinClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initSkin(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_D3D8, 0, ID_SKIN,
|
||||
skinOpen, skinClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeSkinPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->renderCB = defaultRenderCB;
|
||||
pipe->pluginID = ID_SKIN;
|
||||
pipe->pluginData = 1;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// MatFX
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
|
@ -41,6 +41,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
else
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
|
||||
d3ddevice->SetFVF(inst->vertexShader);
|
||||
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
|
|
|
@ -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 {
|
||||
using namespace d3d;
|
||||
|
||||
// Skin
|
||||
|
||||
static void*
|
||||
skinOpen(void *o, int32, int32)
|
||||
{
|
||||
skinGlobals.pipelines[PLATFORM_D3D9] = makeSkinPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
skinClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initSkin(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_D3D9, 0, ID_SKIN,
|
||||
skinOpen, skinClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeSkinPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9);
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->renderCB = defaultRenderCB;
|
||||
pipe->pluginID = ID_SKIN;
|
||||
pipe->pluginData = 1;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// MatFX
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
|
@ -46,6 +46,8 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
else
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::flushCache();
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
|
|
|
@ -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 "../rwplg.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3dimpl.h"
|
||||
|
||||
|
@ -427,7 +428,7 @@ showRaster(Raster *raster)
|
|||
|
||||
// taken from Frank Luna's d3d9 book
|
||||
static int
|
||||
startD3D(EngineStartParams *params)
|
||||
openD3D(EngineStartParams *params)
|
||||
{
|
||||
HWND win = params->window;
|
||||
bool windowed = true;
|
||||
|
@ -491,7 +492,7 @@ startD3D(EngineStartParams *params)
|
|||
}
|
||||
|
||||
static int
|
||||
stopD3D(void)
|
||||
closeD3D(void)
|
||||
{
|
||||
d3d::d3ddevice->Release();
|
||||
d3d::d3ddevice = nil;
|
||||
|
@ -531,10 +532,19 @@ initD3D(void)
|
|||
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
|
||||
|
||||
openIm2D();
|
||||
openIm3D();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termD3D(void)
|
||||
{
|
||||
closeIm3D();
|
||||
closeIm2D();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
finalizeD3D(void)
|
||||
{
|
||||
|
@ -545,14 +555,18 @@ static int
|
|||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
switch(req){
|
||||
case DEVICESTART:
|
||||
return startD3D((EngineStartParams*)arg0);
|
||||
case DEVICEOPEN:
|
||||
return openD3D((EngineStartParams*)arg0);
|
||||
case DEVICECLOSE:
|
||||
return closeD3D();
|
||||
|
||||
case DEVICEINIT:
|
||||
return initD3D();
|
||||
case DEVICETERM:
|
||||
return termD3D();
|
||||
|
||||
case DEVICEFINALIZE:
|
||||
return finalizeD3D();
|
||||
case DEVICESTOP:
|
||||
return stopD3D();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -566,6 +580,9 @@ Device renderdevice = {
|
|||
d3d::setRwRenderState,
|
||||
d3d::getRwRenderState,
|
||||
d3d::im2DRenderIndexedPrimitive,
|
||||
d3d::im3DTransform,
|
||||
d3d::im3DRenderIndexed,
|
||||
d3d::im3DEnd,
|
||||
d3d::deviceSystem,
|
||||
};
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@ openIm2D(void)
|
|||
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
|
||||
}
|
||||
|
||||
void
|
||||
closeIm2D(void)
|
||||
{
|
||||
deleteObject(im2ddecl);
|
||||
deleteObject(im2dvertbuf);
|
||||
deleteObject(im2dindbuf);
|
||||
}
|
||||
|
||||
void
|
||||
im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices, void *indices, int32 numIndices)
|
||||
|
@ -97,6 +105,103 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
|||
0, primCount);
|
||||
}
|
||||
|
||||
|
||||
// Im3D
|
||||
|
||||
|
||||
static IDirect3DVertexDeclaration9 *im3ddecl;
|
||||
static IDirect3DVertexBuffer9 *im3dvertbuf;
|
||||
static IDirect3DIndexBuffer9 *im3dindbuf;
|
||||
static int32 num3DVertices;
|
||||
|
||||
void
|
||||
openIm3D(void)
|
||||
{
|
||||
D3DVERTEXELEMENT9 elements[4] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, offsetof(Im3DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
|
||||
{ 0, offsetof(Im3DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im3ddecl);
|
||||
im3dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im3DVertex), 0, D3DPOOL_MANAGED);
|
||||
im3dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
|
||||
}
|
||||
|
||||
void
|
||||
closeIm3D(void)
|
||||
{
|
||||
deleteObject(im3ddecl);
|
||||
deleteObject(im3dvertbuf);
|
||||
deleteObject(im3dindbuf);
|
||||
}
|
||||
|
||||
void
|
||||
im3DTransform(void *vertices, int32 numVertices, Matrix *world)
|
||||
{
|
||||
RawMatrix d3dworld;
|
||||
d3d::setRenderState(D3DRS_LIGHTING, 0);
|
||||
|
||||
if(world == nil){
|
||||
Matrix ident;
|
||||
ident.setIdentity();
|
||||
world = &ident;
|
||||
}
|
||||
convMatrix(&d3dworld, world);
|
||||
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&d3dworld);
|
||||
|
||||
uint8 *lockedvertices = lockVertices(im3dvertbuf, 0, numVertices*sizeof(Im3DVertex), D3DLOCK_NOSYSLOCK);
|
||||
memcpy(lockedvertices, vertices, numVertices*sizeof(Im3DVertex));
|
||||
unlockVertices(im3dvertbuf);
|
||||
|
||||
d3ddevice->SetStreamSource(0, im3dvertbuf, 0, sizeof(Im3DVertex));
|
||||
d3ddevice->SetVertexDeclaration(im3ddecl);
|
||||
|
||||
num3DVertices = numVertices;
|
||||
}
|
||||
|
||||
void
|
||||
im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
|
||||
{
|
||||
uint16 *lockedindices = lockIndices(im3dindbuf, 0, numIndices*sizeof(uint16), 0);
|
||||
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
|
||||
unlockIndices(im3dindbuf);
|
||||
|
||||
d3d::setTexture(0, engine->imtexture);
|
||||
d3d::flushCache();
|
||||
|
||||
uint32 primCount = 0;
|
||||
switch(primType){
|
||||
case PRIMTYPELINELIST:
|
||||
primCount = numIndices/2;
|
||||
break;
|
||||
case PRIMTYPEPOLYLINE:
|
||||
primCount = numIndices-1;
|
||||
break;
|
||||
case PRIMTYPETRILIST:
|
||||
primCount = numIndices/3;
|
||||
break;
|
||||
case PRIMTYPETRISTRIP:
|
||||
primCount = numIndices-2;
|
||||
break;
|
||||
case PRIMTYPETRIFAN:
|
||||
primCount = numIndices-2;
|
||||
break;
|
||||
case PRIMTYPEPOINTLIST:
|
||||
primCount = numIndices;
|
||||
break;
|
||||
}
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
|
||||
0, num3DVertices,
|
||||
0, primCount);
|
||||
}
|
||||
|
||||
void
|
||||
im3DEnd(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -22,6 +22,22 @@ extern Device renderdevice;
|
|||
|
||||
void lightingCB(void);
|
||||
|
||||
struct Im3DVertex
|
||||
{
|
||||
V3d position;
|
||||
D3DCOLOR color;
|
||||
float32 u, v;
|
||||
|
||||
void setX(float32 x) { this->position.x = x; }
|
||||
void setY(float32 y) { this->position.y = y; }
|
||||
void setZ(float32 z) { this->position.z = z; }
|
||||
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); }
|
||||
RGBA getColor(void) { return makeRGBA(this->color>>16 & 0xFF, this->color>>8 & 0xFF,
|
||||
this->color & 0xFF, this->color>>24 & 0xFF); }
|
||||
void setU(float32 u) { this->u = u; }
|
||||
void setV(float32 v) { this->v = v; }
|
||||
};
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
float32 x, y, z;
|
||||
|
|
|
@ -3,8 +3,15 @@ namespace d3d {
|
|||
|
||||
#ifdef RW_D3D9
|
||||
void openIm2D(void);
|
||||
void closeIm2D(void);
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||
|
||||
void openIm3D(void);
|
||||
void closeIm3D(void);
|
||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *world);
|
||||
void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices);
|
||||
void im3DEnd(void);
|
||||
#endif
|
||||
|
||||
void rasterCreate(Raster *raster);
|
||||
|
|
|
@ -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 "rwxbox.h"
|
||||
|
||||
#define PLUGIN_ID ID_SKIN // yeah right....
|
||||
#define PLUGIN_ID ID_SKIN
|
||||
|
||||
namespace rw {
|
||||
namespace xbox {
|
||||
|
||||
// Skin
|
||||
|
||||
struct NativeSkin
|
||||
{
|
||||
int32 table1[256]; // maps indices to bones
|
||||
|
@ -246,135 +244,5 @@ makeSkinPipeline(void)
|
|||
return pipe;
|
||||
}
|
||||
|
||||
// MatFX
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
||||
matFXGlobals.pipelines[PLATFORM_XBOX] = makeMatFXPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
matfxClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initMatFX(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_XBOX, 0, ID_MATFX,
|
||||
matfxOpen, matfxClose);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeMatFXPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX);
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->pluginID = ID_MATFX;
|
||||
pipe->pluginData = 0;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// Vertex Format
|
||||
|
||||
static int32 vertexFmtOffset;
|
||||
|
||||
uint32 vertexFormatSizes[6] = {
|
||||
0, 1, 2, 2, 4, 4
|
||||
};
|
||||
|
||||
uint32*
|
||||
getVertexFmt(Geometry *g)
|
||||
{
|
||||
return PLUGINOFFSET(uint32, g, vertexFmtOffset);
|
||||
}
|
||||
|
||||
uint32
|
||||
makeVertexFmt(int32 flags, uint32 numTexSets)
|
||||
{
|
||||
if(numTexSets > 4)
|
||||
numTexSets = 4;
|
||||
uint32 fmt = 0x5; // FLOAT3
|
||||
if(flags & Geometry::NORMALS)
|
||||
fmt |= 0x40; // NORMPACKED3
|
||||
for(uint32 i = 0; i < numTexSets; i++)
|
||||
fmt |= 0x500 << i*4; // FLOAT2
|
||||
if(flags & Geometry::PRELIT)
|
||||
fmt |= 0x1000000; // D3DCOLOR
|
||||
return fmt;
|
||||
}
|
||||
|
||||
uint32
|
||||
getVertexFmtStride(uint32 fmt)
|
||||
{
|
||||
uint32 stride = 0;
|
||||
uint32 v = fmt & 0xF;
|
||||
uint32 n = (fmt >> 4) & 0xF;
|
||||
stride += v == 4 ? 4 : 3*vertexFormatSizes[v];
|
||||
stride += n == 4 ? 4 : 3*vertexFormatSizes[n];
|
||||
if(fmt & 0x1000000)
|
||||
stride += 4;
|
||||
for(int i = 0; i < 4; i++){
|
||||
uint32 t = (fmt >> (i*4 + 8)) & 0xF;
|
||||
stride += t == 4 ? 4 : 2*vertexFormatSizes[t];
|
||||
}
|
||||
if(fmt & 0xE000000)
|
||||
stride += 8;
|
||||
return stride;
|
||||
}
|
||||
|
||||
static void*
|
||||
createVertexFmt(void *object, int32 offset, int32)
|
||||
{
|
||||
*PLUGINOFFSET(uint32, object, offset) = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
copyVertexFmt(void *dst, void *src, int32 offset, int32)
|
||||
{
|
||||
*PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static Stream*
|
||||
readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
uint32 fmt = stream->readU32();
|
||||
*PLUGINOFFSET(uint32, object, offset) = fmt;
|
||||
// TODO: ? create and attach "vertex shader"
|
||||
return stream;
|
||||
}
|
||||
|
||||
static Stream*
|
||||
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
getSizeVertexFmt(void*, int32, int32)
|
||||
{
|
||||
if(rw::platform != PLATFORM_XBOX)
|
||||
return -1;
|
||||
return 4;
|
||||
}
|
||||
|
||||
void
|
||||
registerVertexFormatPlugin(void)
|
||||
{
|
||||
vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT,
|
||||
createVertexFmt, nil, copyVertexFmt);
|
||||
Geometry::registerPluginStream(ID_VERTEXFMT,
|
||||
readVertexFmt,
|
||||
writeVertexFmt,
|
||||
getSizeVertexFmt);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
engine->device.system(DEVICESTART, (void*)p);
|
||||
// TODO: put this into Open?
|
||||
engine->device.system(DEVICEOPEN, (void*)p);
|
||||
engine->device.system(DEVICEINIT, nil);
|
||||
|
||||
Engine::s_plglist.construct(engine);
|
||||
|
@ -191,7 +192,8 @@ Engine::close(void)
|
|||
void
|
||||
Engine::stop(void)
|
||||
{
|
||||
engine->device.system(DEVICESTOP, nil);
|
||||
engine->device.system(DEVICETERM, nil);
|
||||
engine->device.system(DEVICECLOSE, nil);
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||
Driver::s_plglist[i].destruct(rw::engine->driver[i]);
|
||||
Engine::s_plglist.destruct(engine);
|
||||
|
@ -210,6 +212,10 @@ uint32 getRenderState(int32) { return 0; }
|
|||
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { }
|
||||
|
||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *world) { }
|
||||
void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices) { }
|
||||
void im3DEnd(void) { }
|
||||
|
||||
void
|
||||
rasterCreate(Raster*)
|
||||
{
|
||||
|
@ -264,6 +270,9 @@ Device renderdevice = {
|
|||
null::setRenderState,
|
||||
null::getRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
null::im3DTransform,
|
||||
null::im3DRenderIndexed,
|
||||
null::im3DEnd,
|
||||
null::deviceSystem
|
||||
};
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
@ -467,7 +468,7 @@ beginUpdate(Camera *cam)
|
|||
}
|
||||
|
||||
static int
|
||||
startGLFW(EngineStartParams *startparams)
|
||||
openGLFW(EngineStartParams *startparams)
|
||||
{
|
||||
GLenum status;
|
||||
GLFWwindow *win;
|
||||
|
@ -512,7 +513,7 @@ startGLFW(EngineStartParams *startparams)
|
|||
}
|
||||
|
||||
static int
|
||||
stopGLFW(void)
|
||||
closeGLFW(void)
|
||||
{
|
||||
glfwDestroyWindow(glfwwindow);
|
||||
glfwTerminate();
|
||||
|
@ -564,14 +565,24 @@ initOpenGL(void)
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
||||
|
||||
#include "shaders/simple_gl3.inc"
|
||||
#include "shaders/simple_vs_gl3.inc"
|
||||
#include "shaders/simple_fs_gl3.inc"
|
||||
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
|
||||
|
||||
openIm2D();
|
||||
openIm3D();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
termOpenGL(void)
|
||||
{
|
||||
closeIm3D();
|
||||
closeIm2D();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
finalizeOpenGL(void)
|
||||
{
|
||||
|
@ -582,14 +593,18 @@ static int
|
|||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
switch(req){
|
||||
case DEVICESTART:
|
||||
return startGLFW((EngineStartParams*)arg0);
|
||||
case DEVICEOPEN:
|
||||
return openGLFW((EngineStartParams*)arg0);
|
||||
case DEVICECLOSE:
|
||||
return closeGLFW();
|
||||
|
||||
case DEVICEINIT:
|
||||
return initOpenGL();
|
||||
case DEVICETERM:
|
||||
return termOpenGL();
|
||||
|
||||
case DEVICEFINALIZE:
|
||||
return finalizeOpenGL();
|
||||
case DEVICESTOP:
|
||||
return stopGLFW();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -603,6 +618,9 @@ Device renderdevice = {
|
|||
gl3::setRenderState,
|
||||
gl3::getRenderState,
|
||||
gl3::im2DRenderIndexedPrimitive,
|
||||
gl3::im3DTransform,
|
||||
gl3::im3DRenderIndexed,
|
||||
gl3::im3DEnd,
|
||||
gl3::deviceSystem
|
||||
};
|
||||
|
||||
|
|
|
@ -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 "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include <GL/glew.h>
|
||||
#include "rwgl3.h"
|
||||
|
@ -72,7 +73,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
Material *m;
|
||||
RGBAf col;
|
||||
GLfloat surfProps[4];
|
||||
int id;
|
||||
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
lightingCB();
|
||||
|
|
|
@ -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 "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwrender.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwplugins.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include <GL/glew.h>
|
||||
|
@ -27,214 +28,6 @@ namespace gl3 {
|
|||
|
||||
#define U(i) currentShader->uniformLocations[i]
|
||||
|
||||
// MatFX
|
||||
|
||||
static Shader *envShader;
|
||||
static int32 u_texMatrix;
|
||||
static int32 u_coefficient;
|
||||
|
||||
static void*
|
||||
matfxOpen(void *o, int32, int32)
|
||||
{
|
||||
u_texMatrix = registerUniform("u_texMatrix");
|
||||
u_coefficient = registerUniform("u_coefficient");
|
||||
#include "shaders/matfx_gl3.inc"
|
||||
matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline();
|
||||
envShader = Shader::fromStrings(matfx_env_vert_src, matfx_env_frag_src);
|
||||
return o;
|
||||
}
|
||||
|
||||
static void*
|
||||
matfxClose(void *o, int32, int32)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
void
|
||||
initMatFX(void)
|
||||
{
|
||||
Driver::registerPlugin(PLATFORM_GL3, 0, ID_MATFX,
|
||||
matfxOpen, matfxClose);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
Material *m;
|
||||
RGBAf col;
|
||||
GLfloat surfProps[4];
|
||||
m = inst->material;
|
||||
|
||||
simpleShader->use();
|
||||
|
||||
convColor(&col, &m->color);
|
||||
glUniform4fv(U(u_matColor), 1, (GLfloat*)&col);
|
||||
|
||||
surfProps[0] = m->surfaceProps.ambient;
|
||||
surfProps[1] = m->surfaceProps.specular;
|
||||
surfProps[2] = m->surfaceProps.diffuse;
|
||||
surfProps[3] = 0.0f;
|
||||
glUniform4fv(U(u_surfaceProps), 1, surfProps);
|
||||
|
||||
setTexture(0, m->texture);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
}
|
||||
|
||||
void
|
||||
calcEnvTexMatrix(Frame *f, float32 *mat)
|
||||
{
|
||||
Matrix cam;
|
||||
if(f){
|
||||
// PS2 style - could be simplified by the shader
|
||||
cam = *((Camera*)engine->currentCamera)->getFrame()->getLTM();
|
||||
cam.pos = { 0.0, 0.0, 0.0 };
|
||||
cam.right.x = -cam.right.x;
|
||||
cam.right.y = -cam.right.y;
|
||||
cam.right.z = -cam.right.z;
|
||||
|
||||
Matrix inv;
|
||||
Matrix::invert(&inv, f->getLTM());
|
||||
inv.pos = { -1.0, -1.0, -1.0 };
|
||||
inv.right.x *= -0.5f;
|
||||
inv.right.y *= -0.5f;
|
||||
inv.right.z *= -0.5f;
|
||||
inv.up.x *= -0.5f;
|
||||
inv.up.y *= -0.5f;
|
||||
inv.up.z *= -0.5f;
|
||||
inv.at.x *= -0.5f;
|
||||
inv.at.y *= -0.5f;
|
||||
inv.at.z *= -0.5f;
|
||||
inv.pos.x *= -0.5f;
|
||||
inv.pos.y *= -0.5f;
|
||||
inv.pos.z *= -0.5f;
|
||||
|
||||
Matrix m;
|
||||
Matrix::mult(&m, &cam, &inv);
|
||||
|
||||
memcpy(mat, &m, 64);
|
||||
mat[3] = mat[7] = mat[11] = 0.0f;
|
||||
mat[15] = 1.0f;
|
||||
|
||||
}else{
|
||||
// D3D - TODO: find out what PS2 does
|
||||
mat[0] = 0.5f;
|
||||
mat[1] = 0.0f;
|
||||
mat[2] = 0.0f;
|
||||
mat[3] = 0.0f;
|
||||
|
||||
mat[4] = 0.0f;
|
||||
mat[5] = -0.5f;
|
||||
mat[6] = 0.0f;
|
||||
mat[7] = 0.0f;
|
||||
|
||||
mat[8] = 0.0f;
|
||||
mat[9] = 0.0f;
|
||||
mat[10] = 1.0f;
|
||||
mat[11] = 0.0f;
|
||||
|
||||
mat[12] = 0.5f;
|
||||
mat[13] = 0.5f;
|
||||
mat[14] = 0.0f;
|
||||
mat[15] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
matfxEnvRender(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
Material *m;
|
||||
RGBAf col;
|
||||
GLfloat surfProps[4];
|
||||
float32 texMat[16];
|
||||
m = inst->material;
|
||||
|
||||
matfxDefaultRender(header, inst);
|
||||
|
||||
MatFX *fx = MatFX::get(m);
|
||||
int32 idx = fx->getEffectIndex(MatFX::ENVMAP);
|
||||
MatFX::Env *env = &fx->fx[idx].env;
|
||||
|
||||
envShader->use();
|
||||
|
||||
convColor(&col, &m->color);
|
||||
glUniform4fv(U(u_matColor), 1, (GLfloat*)&col);
|
||||
|
||||
surfProps[0] = m->surfaceProps.ambient;
|
||||
surfProps[1] = m->surfaceProps.specular;
|
||||
surfProps[2] = m->surfaceProps.diffuse;
|
||||
surfProps[3] = 0.0f;
|
||||
glUniform4fv(U(u_surfaceProps), 1, surfProps);
|
||||
|
||||
glUniform1fv(U(u_coefficient), 1, &env->coefficient);
|
||||
|
||||
calcEnvTexMatrix(env->frame, texMat);
|
||||
glUniformMatrix4fv(U(u_texMatrix), 1, GL_FALSE, texMat);
|
||||
|
||||
setTexture(0, env->tex);
|
||||
|
||||
rw::SetRenderState(VERTEXALPHA, 1);
|
||||
rw::SetRenderState(SRCBLEND, BLENDONE);
|
||||
rw::SetRenderState(DESTBLEND, BLENDONE);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
|
||||
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||
rw::SetRenderState(DESTBLEND, BLENDINVSRCALPHA);
|
||||
}
|
||||
|
||||
void
|
||||
matfxRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||
{
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
lightingCB();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, header->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo);
|
||||
setAttribPointers(header->attribDesc, header->numAttribs);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
int32 n = header->numMeshes;
|
||||
|
||||
// rw::SetRenderState(ALPHATESTFUNC, 1);
|
||||
// rw::SetRenderState(ALPHATESTREF, 50);
|
||||
|
||||
int32 fx;
|
||||
while(n--){
|
||||
fx = MatFX::getEffects(inst->material);
|
||||
switch(fx){
|
||||
case MatFX::ENVMAP:
|
||||
matfxEnvRender(header, inst);
|
||||
break;
|
||||
default:
|
||||
matfxDefaultRender(header, inst);
|
||||
}
|
||||
inst++;
|
||||
}
|
||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||
}
|
||||
|
||||
ObjPipeline*
|
||||
makeMatFXPipeline(void)
|
||||
{
|
||||
ObjPipeline *pipe = new ObjPipeline(PLATFORM_GL3);
|
||||
pipe->instanceCB = defaultInstanceCB;
|
||||
pipe->uninstanceCB = defaultUninstanceCB;
|
||||
pipe->renderCB = matfxRenderCB;
|
||||
pipe->pluginID = ID_MATFX;
|
||||
pipe->pluginData = 0;
|
||||
return pipe;
|
||||
}
|
||||
|
||||
// Skin
|
||||
|
||||
static Shader *skinShader;
|
||||
static int32 u_boneMatrices;
|
||||
|
||||
|
@ -242,7 +35,7 @@ static void*
|
|||
skinOpen(void *o, int32, int32)
|
||||
{
|
||||
u_boneMatrices = registerUniform("u_boneMatrices");
|
||||
#include "shaders/simple_gl3.inc"
|
||||
#include "shaders/simple_fs_gl3.inc"
|
||||
#include "shaders/skin_gl3.inc"
|
||||
skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline();
|
||||
skinShader = Shader::fromStrings(skin_vert_src, simple_frag_src);
|
||||
|
@ -448,7 +241,6 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
Material *m;
|
||||
RGBAf col;
|
||||
GLfloat surfProps[4];
|
||||
int id;
|
||||
|
||||
setWorldMatrix(atomic->getFrame()->getLTM());
|
||||
lightingCB();
|
||||
|
@ -507,7 +299,6 @@ makeSkinPipeline(void)
|
|||
|
||||
#else
|
||||
|
||||
void initMatFX(void) { }
|
||||
void initSkin(void) { }
|
||||
|
||||
#endif
|
|
@ -80,6 +80,22 @@ struct InstanceDataHeader : rw::InstanceDataHeader
|
|||
|
||||
#ifdef RW_GL3
|
||||
|
||||
struct Im3DVertex
|
||||
{
|
||||
V3d position;
|
||||
uint8 r, g, b, a;
|
||||
float32 u, v;
|
||||
|
||||
void setX(float32 x) { this->position.x = x; }
|
||||
void setY(float32 y) { this->position.y = y; }
|
||||
void setZ(float32 z) { this->position.z = z; }
|
||||
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) {
|
||||
this->r = r; this->g = g; this->b = b; this->a = a; }
|
||||
RGBA getColor(void) { return makeRGBA(this->r, this->g, this->b, this->a); }
|
||||
void setU(float32 u) { this->u = u; }
|
||||
void setV(float32 v) { this->v = v; }
|
||||
};
|
||||
|
||||
struct Im2DVertex
|
||||
{
|
||||
float32 x, y, z, w;
|
||||
|
|
|
@ -6,9 +6,15 @@ namespace gl3 {
|
|||
extern Shader *simpleShader;
|
||||
extern uint32 im2DVbo, im2DIbo;
|
||||
void openIm2D(void);
|
||||
void closeIm2D(void);
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
void *vertices, int32 numVertices, void *indices, int32 numIndices);
|
||||
|
||||
void openIm3D(void);
|
||||
void closeIm3D(void);
|
||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *world);
|
||||
void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices);
|
||||
void im3DEnd(void);
|
||||
#endif
|
||||
|
||||
void rasterCreate(Raster *raster);
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
static Shader *fromFiles(const char *vs, const char *fs);
|
||||
static Shader *fromStrings(const char *vsrc, const char *fsrc);
|
||||
void use(void);
|
||||
void destroy(void);
|
||||
};
|
||||
|
||||
extern Shader *currentShader;
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
all: im2d_gl3.inc simple_gl3.inc matfx_gl3.inc skin_gl3.inc
|
||||
all: im2d_gl3.inc im3d_gl3.inc simple_vs_gl3.inc simple_fs_gl3.inc matfx_gl3.inc skin_gl3.inc
|
||||
|
||||
im2d_gl3.inc: im2d.frag im2d.vert
|
||||
im2d_gl3.inc: im2d.vert
|
||||
(echo 'const char *im2d_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' im2d.vert;\
|
||||
echo ';';\
|
||||
echo 'const char *im2d_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' im2d.frag;\
|
||||
echo ';') >im2d_gl3.inc
|
||||
|
||||
simple_gl3.inc: simple.frag simple.vert
|
||||
im3d_gl3.inc: im3d.vert
|
||||
(echo 'const char *im3d_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' im3d.vert;\
|
||||
echo ';') >im3d_gl3.inc
|
||||
|
||||
simple_vs_gl3.inc: simple.vert
|
||||
(echo 'const char *simple_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' simple.vert;\
|
||||
echo ';';\
|
||||
echo 'const char *simple_frag_src =';\
|
||||
echo ';') >simple_vs_gl3.inc
|
||||
|
||||
simple_fs_gl3.inc: simple.frag
|
||||
(echo 'const char *simple_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' simple.frag;\
|
||||
echo ';') >simple_gl3.inc
|
||||
echo ';') >simple_fs_gl3.inc
|
||||
|
||||
matfx_gl3.inc: matfx_env.frag matfx_env.vert
|
||||
(echo 'const char *matfx_env_vert_src =';\
|
||||
|
|
|
@ -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
|
||||
|
||||
//layout(std140) uniform Im2DState
|
||||
//{
|
||||
// int u_alphaTest;
|
||||
// float u_alphaRef;
|
||||
// mat4 u_xform;
|
||||
//};
|
||||
layout(std140) uniform State
|
||||
{
|
||||
int u_alphaTest;
|
||||
float u_alphaRef;
|
||||
|
||||
int u_fogEnable;
|
||||
float u_fogStart;
|
||||
float u_fogEnd;
|
||||
vec4 u_fogColor;
|
||||
};
|
||||
|
||||
uniform vec4 u_xform;
|
||||
|
||||
|
@ -15,6 +19,7 @@ layout(location = 3) in vec2 in_tex0;
|
|||
|
||||
out vec4 v_color;
|
||||
out vec2 v_tex0;
|
||||
out float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
|
@ -24,4 +29,5 @@ main(void)
|
|||
gl_Position.xyz *= gl_Position.w;
|
||||
v_color = in_color;
|
||||
v_tex0 = in_tex0;
|
||||
v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
const char *im2d_vert_src =
|
||||
"#version 330\n"
|
||||
|
||||
"//layout(std140) uniform Im2DState\n"
|
||||
"//{\n"
|
||||
"// int u_alphaTest;\n"
|
||||
"// float u_alphaRef;\n"
|
||||
"// mat4 u_xform;\n"
|
||||
"//};\n"
|
||||
"layout(std140) uniform State\n"
|
||||
"{\n"
|
||||
" int u_alphaTest;\n"
|
||||
" float u_alphaRef;\n"
|
||||
|
||||
" int u_fogEnable;\n"
|
||||
" float u_fogStart;\n"
|
||||
" float u_fogEnd;\n"
|
||||
" vec4 u_fogColor;\n"
|
||||
"};\n"
|
||||
|
||||
"uniform vec4 u_xform;\n"
|
||||
|
||||
|
@ -16,6 +20,7 @@ const char *im2d_vert_src =
|
|||
|
||||
"out vec4 v_color;\n"
|
||||
"out vec2 v_tex0;\n"
|
||||
"out float v_fog;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
|
@ -25,22 +30,6 @@ const char *im2d_vert_src =
|
|||
" gl_Position.xyz *= gl_Position.w;\n"
|
||||
" v_color = in_color;\n"
|
||||
" v_tex0 = in_tex0;\n"
|
||||
" v_fog = clamp((gl_Position.z - u_fogEnd)/(u_fogStart - u_fogEnd), 0.0, 1.0);\n"
|
||||
"}\n"
|
||||
;
|
||||
const char *im2d_frag_src =
|
||||
"#version 330\n"
|
||||
|
||||
"uniform sampler2D tex;\n"
|
||||
|
||||
"in vec4 v_color;\n"
|
||||
"in vec2 v_tex0;\n"
|
||||
|
||||
"out vec4 color;\n"
|
||||
|
||||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
"}\n"
|
||||
|
||||
;
|
||||
|
|
|
@ -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"
|
||||
"}\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])
|
||||
|
||||
// Lists
|
||||
|
||||
struct LLLink
|
||||
{
|
||||
LLLink *next;
|
||||
LLLink *prev;
|
||||
void init(void){
|
||||
this->next = nil;
|
||||
this->prev = nil;
|
||||
}
|
||||
void remove(void){
|
||||
this->prev->next = this->next;
|
||||
this->next->prev = this->prev;
|
||||
}
|
||||
};
|
||||
|
||||
#define LLLinkGetData(linkvar,type,entry) \
|
||||
((type*)(((uint8*)(linkvar))-offsetof(type,entry)))
|
||||
|
||||
// Have to be careful since the link might be deleted.
|
||||
#define FORLIST(_link, _list) \
|
||||
for(rw::LLLink *_next = nil, *_link = (_list).link.next; \
|
||||
_next = (_link)->next, (_link) != (_list).end(); \
|
||||
(_link) = _next)
|
||||
|
||||
struct LinkList
|
||||
{
|
||||
LLLink link;
|
||||
void init(void){
|
||||
this->link.next = &this->link;
|
||||
this->link.prev = &this->link;
|
||||
}
|
||||
bool32 isEmpty(void){
|
||||
return this->link.next == &this->link;
|
||||
}
|
||||
void add(LLLink *link){
|
||||
link->next = this->link.next;
|
||||
link->prev = &this->link;
|
||||
this->link.next->prev = link;
|
||||
this->link.next = link;
|
||||
}
|
||||
void append(LLLink *link){
|
||||
link->next = &this->link;
|
||||
link->prev = this->link.prev;
|
||||
this->link.prev->next = link;
|
||||
this->link.prev = link;
|
||||
}
|
||||
LLLink *end(void){
|
||||
return &this->link;
|
||||
}
|
||||
int32 count(void){
|
||||
int32 n = 0;
|
||||
FORLIST(lnk, (*this))
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
// Mathematical types
|
||||
|
||||
struct RGBA
|
||||
{
|
||||
uint8 red;
|
||||
|
@ -68,6 +128,7 @@ struct RGBA
|
|||
uint8 blue;
|
||||
uint8 alpha;
|
||||
};
|
||||
inline RGBA makeRGBA(uint8 r, uint8 g, uint8 b, uint8 a) { RGBA c = { r, g, b, a }; return c; }
|
||||
inline bool32 equal(const RGBA &c1, const RGBA &c2) { return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue && c1.alpha == c2.alpha; }
|
||||
|
||||
struct RGBAf
|
||||
|
|
|
@ -1,62 +1,30 @@
|
|||
namespace rw {
|
||||
|
||||
enum RenderState
|
||||
{
|
||||
VERTEXALPHA = 0,
|
||||
SRCBLEND,
|
||||
DESTBLEND,
|
||||
ZTESTENABLE,
|
||||
ZWRITEENABLE,
|
||||
FOGENABLE,
|
||||
FOGCOLOR,
|
||||
// TODO:
|
||||
// fog type, density ?
|
||||
// ? cullmode
|
||||
// ? shademode
|
||||
// ???? stencil
|
||||
|
||||
// platform specific or opaque?
|
||||
ALPHATESTFUNC,
|
||||
ALPHATESTREF,
|
||||
};
|
||||
|
||||
enum AlphaTestFunc
|
||||
{
|
||||
ALPHAALWAYS = 0,
|
||||
ALPHAGREATEREQUAL,
|
||||
ALPHALESS
|
||||
};
|
||||
|
||||
enum BlendFunction
|
||||
{
|
||||
BLENDZERO = 0,
|
||||
BLENDONE,
|
||||
BLENDSRCCOLOR,
|
||||
BLENDINVSRCCOLOR,
|
||||
BLENDSRCALPHA,
|
||||
BLENDINVSRCALPHA,
|
||||
BLENDDESTALPHA,
|
||||
BLENDINVDESTALPHA,
|
||||
BLENDDESTCOLOR,
|
||||
BLENDINVDESTCOLOR,
|
||||
BLENDSRCALPHASAT,
|
||||
// TODO: add more perhaps
|
||||
};
|
||||
|
||||
enum DeviceReq
|
||||
{
|
||||
// Device/Context creation
|
||||
DEVICESTART,
|
||||
DEVICEOPEN,
|
||||
// Device/Context shutdown
|
||||
DEVICECLOSE,
|
||||
|
||||
// Device initialization before Engine/Driver plugins are opened
|
||||
DEVICEINIT,
|
||||
// Device initialization after plugins are opened
|
||||
// Device de-initialization after Engine/Driver plugins are closed
|
||||
DEVICETERM,
|
||||
|
||||
// Device initialization after Engine/Driver plugins are opened
|
||||
DEVICEFINALIZE,
|
||||
// Device/Context shutdown
|
||||
DEVICESTOP,
|
||||
// TODO? counterpart to FINALIZE?
|
||||
};
|
||||
|
||||
typedef int DeviceSystem(DeviceReq req, void *arg0);
|
||||
|
||||
struct Camera;
|
||||
struct Image;
|
||||
struct Texture;
|
||||
struct Raster;
|
||||
class ObjPipeline;
|
||||
|
||||
// This is for the render device, we only have one
|
||||
struct Device
|
||||
{
|
||||
|
@ -67,8 +35,18 @@ struct Device
|
|||
void (*showRaster)(Raster *raster);
|
||||
void (*setRenderState)(int32 state, uint32 value);
|
||||
uint32 (*getRenderState)(int32 state);
|
||||
|
||||
// TODO: render line
|
||||
// TODO: render triangle
|
||||
// TODO: render primitive
|
||||
void (*im2DRenderIndexedPrimitive)(PrimitiveType,
|
||||
void*, int32, void*, int32);
|
||||
|
||||
// Not sure if this will stay...
|
||||
void (*im3DTransform)(void *vertices, int32 numVertices, Matrix *world);
|
||||
void (*im3DRenderIndexed)(PrimitiveType primType, void *indices, int32 numIndices);
|
||||
void (*im3DEnd)(void);
|
||||
|
||||
DeviceSystem *system;
|
||||
};
|
||||
|
||||
|
@ -159,15 +137,6 @@ struct Engine
|
|||
|
||||
extern Engine *engine;
|
||||
|
||||
inline void SetRenderState(int32 state, uint32 value){
|
||||
engine->device.setRenderState(state, value); }
|
||||
|
||||
inline uint32 GetRenderState(int32 state){
|
||||
return engine->device.getRenderState(state); }
|
||||
|
||||
inline float32 GetNearZ(void) { return engine->device.zNear; }
|
||||
inline float32 GetFarZ(void) { return engine->device.zNear; }
|
||||
|
||||
// These must be macros because we might want to pass __FILE__ and __LINE__ later
|
||||
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h)
|
||||
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h)
|
||||
|
@ -198,6 +167,10 @@ namespace null {
|
|||
void im2DRenderIndexedPrimitive(PrimitiveType,
|
||||
void*, int32, void*, int32);
|
||||
|
||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *world);
|
||||
void im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices);
|
||||
void im3DEnd(void);
|
||||
|
||||
int deviceSystem(DeviceReq req, void*);
|
||||
|
||||
extern Device renderdevice;
|
||||
|
|
|
@ -2,62 +2,6 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
struct LLLink
|
||||
{
|
||||
LLLink *next;
|
||||
LLLink *prev;
|
||||
void init(void){
|
||||
this->next = nil;
|
||||
this->prev = nil;
|
||||
}
|
||||
void remove(void){
|
||||
this->prev->next = this->next;
|
||||
this->next->prev = this->prev;
|
||||
}
|
||||
};
|
||||
|
||||
#define LLLinkGetData(linkvar,type,entry) \
|
||||
((type*)(((uint8*)(linkvar))-offsetof(type,entry)))
|
||||
|
||||
// Have to be careful since the link might be deleted.
|
||||
#define FORLIST(_link, _list) \
|
||||
for(rw::LLLink *_next = nil, *_link = (_list).link.next; \
|
||||
_next = (_link)->next, (_link) != (_list).end(); \
|
||||
(_link) = _next)
|
||||
|
||||
struct LinkList
|
||||
{
|
||||
LLLink link;
|
||||
void init(void){
|
||||
this->link.next = &this->link;
|
||||
this->link.prev = &this->link;
|
||||
}
|
||||
bool32 isEmpty(void){
|
||||
return this->link.next == &this->link;
|
||||
}
|
||||
void add(LLLink *link){
|
||||
link->next = this->link.next;
|
||||
link->prev = &this->link;
|
||||
this->link.next->prev = link;
|
||||
this->link.next = link;
|
||||
}
|
||||
void append(LLLink *link){
|
||||
link->next = &this->link;
|
||||
link->prev = this->link.prev;
|
||||
this->link.prev->next = link;
|
||||
this->link.prev = link;
|
||||
}
|
||||
LLLink *end(void){
|
||||
return &this->link;
|
||||
}
|
||||
int32 count(void){
|
||||
int32 n = 0;
|
||||
FORLIST(lnk, (*this))
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
struct Object
|
||||
{
|
||||
uint8 type;
|
||||
|
|
|
@ -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->setScreenY(y);
|
||||
vert->setScreenZ(rw::GetNearZ());
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(1.0f/cam->nearPlane);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
|
@ -53,7 +53,7 @@ printScreen(const char *s, float32 x, float32 y)
|
|||
|
||||
vert->setScreenX(x+curfont->glyphwidth);
|
||||
vert->setScreenY(y);
|
||||
vert->setScreenZ(rw::GetNearZ());
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(1.0f/cam->nearPlane);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
|
@ -63,7 +63,7 @@ printScreen(const char *s, float32 x, float32 y)
|
|||
|
||||
vert->setScreenX(x);
|
||||
vert->setScreenY(y+curfont->glyphheight);
|
||||
vert->setScreenZ(rw::GetNearZ());
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(1.0f/cam->nearPlane);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
|
@ -73,7 +73,7 @@ printScreen(const char *s, float32 x, float32 y)
|
|||
|
||||
vert->setScreenX(x+curfont->glyphwidth);
|
||||
vert->setScreenY(y+curfont->glyphheight);
|
||||
vert->setScreenZ(rw::GetNearZ());
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(1.0f/cam->nearPlane);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
|
@ -95,7 +95,7 @@ printScreen(const char *s, float32 x, float32 y)
|
|||
s++;
|
||||
}
|
||||
engine->imtexture = curfont->tex;
|
||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
vertices, curVert, indices, curIndex);
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ rw::Texture *tex;
|
|||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void tlTest(rw::Clump *clump);
|
||||
void genIm3DTransform(void *vertices, rw::int32 numVertices, rw::Matrix *xform);
|
||||
void genIm3DRenderIndexed(rw::PrimitiveType prim, void *indices, rw::int32 numIndices);
|
||||
void genIm3DEnd(void);
|
||||
void initFont(void);
|
||||
void printScreen(const char *s, float x, float y);
|
||||
|
||||
|
@ -241,7 +244,7 @@ im2dtest(void)
|
|||
{ 0.0f, 480.0f, 0, 0, 255, 128, 0.0f, 1.0f },
|
||||
{ 640.0f, 480.0f, 0, 255, 255, 128, 1.0f, 1.0f },
|
||||
};
|
||||
static Im2DVertex verts[4];
|
||||
Im2DVertex verts[4];
|
||||
static short indices[] = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
@ -249,7 +252,7 @@ im2dtest(void)
|
|||
for(i = 0; i < 4; i++){
|
||||
verts[i].setScreenX(vs[i].x);
|
||||
verts[i].setScreenY(vs[i].y);
|
||||
verts[i].setScreenZ(rw::GetNearZ());
|
||||
verts[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
verts[i].setCameraZ(Scene.camera->nearPlane);
|
||||
verts[i].setRecipCameraZ(1.0f/Scene.camera->nearPlane);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
|
@ -259,10 +262,58 @@ im2dtest(void)
|
|||
|
||||
rw::engine->imtexture = tex;
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
&verts, 4, &indices, 4);
|
||||
}
|
||||
|
||||
void
|
||||
im3dtest(void)
|
||||
{
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
static struct
|
||||
{
|
||||
float x, y, z;
|
||||
rw::uint8 r, g, b, a;
|
||||
float u, v;
|
||||
} vs[8] = {
|
||||
{ -1.0f, -1.0f, -1.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, -1.0f, 0, 255, 0, 128, 0.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, -1.0f, 0, 0, 255, 128, 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, -1.0f, 255, 0, 255, 128, 1.0f, 1.0f },
|
||||
|
||||
{ -1.0f, -1.0f, 1.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, 1.0f, 0, 255, 0, 128, 0.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 0, 0, 255, 128, 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 255, 0, 255, 128, 1.0f, 1.0f },
|
||||
};
|
||||
Im3DVertex verts[8];
|
||||
static short indices[2*6] = {
|
||||
0, 1, 2, 2, 1, 3,
|
||||
4, 5, 6, 6, 5, 7
|
||||
};
|
||||
|
||||
for(i = 0; i < 8; i++){
|
||||
verts[i].setX(vs[i].x);
|
||||
verts[i].setY(vs[i].y);
|
||||
verts[i].setZ(vs[i].z);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
verts[i].setU(vs[i].u);
|
||||
verts[i].setV(vs[i].v);
|
||||
}
|
||||
|
||||
rw::engine->imtexture = tex;
|
||||
|
||||
/*
|
||||
genIm3DTransform(verts, 8, nil);
|
||||
genIm3DRenderIndexed(rw::PRIMTYPETRILIST, indices, 12);
|
||||
genIm3DEnd();
|
||||
*/
|
||||
rw::im3d::Transform(verts, 8, nil);
|
||||
rw::im3d::RenderIndexed(rw::PRIMTYPETRILIST, indices, 12);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
Draw(float timeDelta)
|
||||
{
|
||||
|
@ -271,9 +322,10 @@ Draw(float timeDelta)
|
|||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
Scene.clump->render();
|
||||
im2dtest();
|
||||
// Scene.clump->render();
|
||||
// im2dtest();
|
||||
// tlTest(Scene.clump);
|
||||
im3dtest();
|
||||
printScreen("Hello, World!", 10, 10);
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
|
|
|
@ -5,6 +5,7 @@ using namespace rw;
|
|||
|
||||
//
|
||||
// This is a test to implement T&L in software and render with Im2D
|
||||
//
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
|
@ -90,7 +91,7 @@ drawAtomic(Atomic *a)
|
|||
im2dverts[i].setV(texcoords[i].v);
|
||||
}
|
||||
for(int32 i = 0; i < mh->numMeshes; i++){
|
||||
for(int32 j = 0; j < m[i].numIndices; j++){
|
||||
for(uint32 j = 0; j < m[i].numIndices; j++){
|
||||
int32 idx = m[i].indices[j];
|
||||
RGBA col;
|
||||
RGBAf colf, color;
|
||||
|
@ -116,7 +117,7 @@ drawAtomic(Atomic *a)
|
|||
}
|
||||
|
||||
engine->imtexture = m[i].material->texture;
|
||||
rw::engine->device.im2DRenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
||||
}
|
||||
|
||||
|
@ -132,3 +133,60 @@ tlTest(Clump *clump)
|
|||
drawAtomic(a);
|
||||
}
|
||||
}
|
||||
|
||||
static RWDEVICE::Im2DVertex *clipverts;
|
||||
static int32 numClipverts;
|
||||
|
||||
void
|
||||
genIm3DTransform(void *vertices, int32 numVertices, Matrix *world)
|
||||
{
|
||||
using namespace RWDEVICE;
|
||||
Im3DVertex *objverts;
|
||||
V3d pos;
|
||||
Matrix xform;
|
||||
Camera *cam;
|
||||
int32 i;
|
||||
objverts = (Im3DVertex*)vertices;
|
||||
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
|
||||
|
||||
xform = cam->viewMatrix;
|
||||
if(world)
|
||||
xform.transform(world, COMBINEPRECONCAT);
|
||||
|
||||
clipverts = rwNewT(Im2DVertex, numVertices, MEMDUR_EVENT);
|
||||
numClipverts = numVertices;
|
||||
|
||||
for(i = 0; i < numVertices; i++){
|
||||
V3d::transformPoints(&pos, &objverts[i].position, 1, &xform);
|
||||
|
||||
float32 recipZ = 1.0f/pos.z;
|
||||
RGBA c = objverts[i].getColor();
|
||||
|
||||
clipverts[i].setScreenX(pos.x * recipZ * width);
|
||||
clipverts[i].setScreenY((pos.y * recipZ * height));
|
||||
clipverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
clipverts[i].setCameraZ(pos.z);
|
||||
clipverts[i].setRecipCameraZ(recipZ);
|
||||
clipverts[i].setColor(c.red, c.green, c.blue, c.alpha);
|
||||
clipverts[i].setU(objverts[i].u);
|
||||
clipverts[i].setV(objverts[i].v);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DRenderIndexed(PrimitiveType prim, void *indices, int32 numIndices)
|
||||
{
|
||||
im2d::RenderIndexedPrimitive(prim, clipverts, numClipverts, indices, numIndices);
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DEnd(void)
|
||||
{
|
||||
rwFree(clipverts);
|
||||
clipverts = nil;
|
||||
numClipverts = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue