implemented im2d for d3d, fun little software T&L renderer

This commit is contained in:
aap
2017-08-27 17:13:10 +02:00
parent ea48c140c1
commit c53d29b1cf
24 changed files with 618 additions and 142 deletions

View File

@@ -10,6 +10,7 @@
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3dimpl.h"
#define PLUGIN_ID 0
@@ -275,6 +276,7 @@ setRasterStage(uint32 stage, Raster *raster)
void
setTexture(uint32 stage, Texture *tex)
{
// TODO: support mipmaps
static DWORD filternomip[] = {
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
D3DTEXF_POINT, D3DTEXF_LINEAR,
@@ -289,10 +291,10 @@ setTexture(uint32 stage, Texture *tex)
return;
}
if(tex->raster){
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->getFilter()]);
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->getFilter()]);
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[tex->getAddressU()]);
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[tex->getAddressV()]);
}
setRasterStage(stage, tex->raster);
}
@@ -528,6 +530,14 @@ initD3D(void)
// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
openIm2D();
return 1;
}
static int
finalizeD3D(void)
{
return 1;
}
@@ -539,6 +549,8 @@ deviceSystem(DeviceReq req, void *arg0)
return startD3D((EngineStartParams*)arg0);
case DEVICEINIT:
return initD3D();
case DEVICEFINALIZE:
return finalizeD3D();
case DEVICESTOP:
return stopD3D();
}
@@ -553,7 +565,7 @@ Device renderdevice = {
d3d::showRaster,
d3d::setRwRenderState,
d3d::getRwRenderState,
null::im2DRenderIndexedPrimitive,
d3d::im2DRenderIndexedPrimitive,
d3d::deviceSystem,
};

102
src/d3d/d3dim2d.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "../rwbase.h"
#include "../rwplg.h"
#include "../rwpipeline.h"
#include "../rwobjects.h"
#include "../rwengine.h"
#include "rwd3d.h"
#include "rwd3d9.h"
namespace rw {
namespace d3d {
#ifdef RW_D3D9
// might want to tweak this
#define NUMINDICES 10000
#define NUMVERTICES 10000
static int primTypeMap[] = {
D3DPT_POINTLIST, // invalid
D3DPT_LINELIST,
D3DPT_LINESTRIP,
D3DPT_TRIANGLELIST,
D3DPT_TRIANGLESTRIP,
D3DPT_TRIANGLEFAN,
D3DPT_POINTLIST, // actually not supported!
};
static IDirect3DVertexDeclaration9 *im2ddecl;
static IDirect3DVertexBuffer9 *im2dvertbuf;
static IDirect3DIndexBuffer9 *im2dindbuf;
void
openIm2D(void)
{
D3DVERTEXELEMENT9 elements[4] = {
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
{ 0, offsetof(Im2DVertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, offsetof(Im2DVertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &im2ddecl);
im2dvertbuf = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertex), 0, D3DPOOL_MANAGED);
im2dindbuf = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(uint16));
}
void
im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices)
{
if(numVertices > NUMVERTICES ||
numIndices > NUMINDICES){
// TODO: error
return;
}
uint16 *lockedindices = lockIndices(im2dindbuf, 0, numIndices*sizeof(uint16), 0);
memcpy(lockedindices, indices, numIndices*sizeof(uint16));
unlockIndices(im2dindbuf);
uint8 *lockedvertices = lockVertices(im2dvertbuf, 0, numVertices*sizeof(Im2DVertex), D3DLOCK_NOSYSLOCK);
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertex));
unlockVertices(im2dvertbuf);
d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
d3ddevice->SetIndices(im2dindbuf);
d3ddevice->SetVertexDeclaration(im2ddecl);
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;
}
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
0, numVertices,
0, primCount);
}
#endif
}
}

View File

@@ -21,6 +21,24 @@ extern IDirect3DDevice9 *d3ddevice;
extern Device renderdevice;
void lightingCB(void);
struct Im2DVertex
{
float32 x, y, z;
float32 w;
D3DCOLOR color;
float32 u, v;
void setScreenX(float32 x) { this->x = x; }
void setScreenY(float32 y) { this->y = y; }
void setScreenZ(float32 z) { this->z = z; }
void setCameraZ(float32 z) { }
void setRecipCameraZ(float32 recipz) { this->w = recipz; }
void setColor(uint8 r, uint8 g, uint8 b, uint8 a) { this->color = D3DCOLOR_ARGB(a, r, g, b); }
void setU(float32 u) { this->u = u; }
void setV(float32 v) { this->v = v; }
};
#else
enum {
D3DLOCK_NOSYSLOCK = 0, // ignored

View File

@@ -1,6 +1,12 @@
namespace rw {
namespace d3d {
#ifdef RW_D3D9
void openIm2D(void);
void im2DRenderIndexedPrimitive(PrimitiveType primType,
void *vertices, int32 numVertices, void *indices, int32 numIndices);
#endif
void rasterCreate(Raster *raster);
uint8 *rasterLock(Raster *raster, int32 level);
void rasterUnlock(Raster *raster, int32 level);