mirror of https://github.com/aap/librw.git
implemented texture raster renderstates
This commit is contained in:
parent
e6d01b1159
commit
2cffb3f494
|
@ -69,7 +69,14 @@ ImGui_ImplRW_RenderDrawLists(ImDrawData* draw_data)
|
||||||
if(pcmd->UserCallback)
|
if(pcmd->UserCallback)
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
else{
|
else{
|
||||||
rw::engine->imtexture = (rw::Texture*)pcmd->TextureId;
|
rw::Texture *tex = (rw::Texture*)pcmd->TextureId;
|
||||||
|
if(tex && tex->raster){
|
||||||
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESSV, tex->getAddressV());
|
||||||
|
rw::SetRenderState(rw::TEXTUREFILTER, tex->getFilter());
|
||||||
|
}else
|
||||||
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||||
g_vertbuf+vtx_offset, cmd_list->VtxBuffer.Size,
|
g_vertbuf+vtx_offset, cmd_list->VtxBuffer.Size,
|
||||||
cmd_list->IdxBuffer.Data+idx_offset, pcmd->ElemCount);
|
cmd_list->IdxBuffer.Data+idx_offset, pcmd->ElemCount);
|
||||||
|
|
|
@ -543,7 +543,7 @@ rasterFromImage(Raster *raster, Image *image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 inc = image->depth/8;
|
int32 inc = image->bpp;
|
||||||
in = image->pixels;
|
in = image->pixels;
|
||||||
out = raster->lock(0);
|
out = raster->lock(0);
|
||||||
if(pallength)
|
if(pallength)
|
||||||
|
|
|
@ -38,21 +38,32 @@ static VidmemRaster *vidmemRasters;
|
||||||
void addVidmemRaster(Raster *raster);
|
void addVidmemRaster(Raster *raster);
|
||||||
void removeVidmemRaster(Raster *raster);
|
void removeVidmemRaster(Raster *raster);
|
||||||
|
|
||||||
// cached RW render states
|
struct RwRasterStateCache {
|
||||||
static bool32 vertexAlpha;
|
Raster *raster;
|
||||||
static bool32 textureAlpha;
|
Texture::Addressing addressingU;
|
||||||
static uint32 srcblend, destblend;
|
Texture::Addressing addressingV;
|
||||||
static uint32 zwrite;
|
Texture::FilterMode filter;
|
||||||
static uint32 ztest;
|
};
|
||||||
static uint32 fogenable;
|
|
||||||
static RGBA fogcolor;
|
|
||||||
static uint32 cullmode;
|
|
||||||
static uint32 alphafunc;
|
|
||||||
static uint32 alpharef;
|
|
||||||
|
|
||||||
|
#define MAXNUMSTAGES 8
|
||||||
|
|
||||||
|
// cached RW render states
|
||||||
|
struct RwStateCache {
|
||||||
|
bool32 vertexAlpha;
|
||||||
|
bool32 textureAlpha;
|
||||||
|
uint32 srcblend, destblend;
|
||||||
|
uint32 zwrite;
|
||||||
|
uint32 ztest;
|
||||||
|
uint32 fogenable;
|
||||||
|
RGBA fogcolor;
|
||||||
|
uint32 cullmode;
|
||||||
|
uint32 alphafunc;
|
||||||
|
uint32 alpharef;
|
||||||
|
RwRasterStateCache texstage[MAXNUMSTAGES];
|
||||||
|
};
|
||||||
|
static RwStateCache rwStateCache;
|
||||||
|
|
||||||
#define MAXNUMSTATES (D3DRS_BLENDOPALPHA+1)
|
#define MAXNUMSTATES (D3DRS_BLENDOPALPHA+1)
|
||||||
#define MAXNUMSTAGES 8
|
|
||||||
#define MAXNUMTEXSTATES (D3DTSS_CONSTANT+1)
|
#define MAXNUMTEXSTATES (D3DTSS_CONSTANT+1)
|
||||||
#define MAXNUMSAMPLERSTATES (D3DSAMP_DMAPOFFSET+1)
|
#define MAXNUMSAMPLERSTATES (D3DSAMP_DMAPOFFSET+1)
|
||||||
|
|
||||||
|
@ -77,15 +88,50 @@ static uint32 d3dTextureStageStates[MAXNUMTEXSTATES][MAXNUMSTAGES];
|
||||||
|
|
||||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||||
|
|
||||||
// TODO: not only rasters, make a struct
|
|
||||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
|
||||||
|
|
||||||
|
|
||||||
static bool validStates[MAXNUMSTATES];
|
static bool validStates[MAXNUMSTATES];
|
||||||
static bool validTexStates[MAXNUMTEXSTATES];
|
static bool validTexStates[MAXNUMTEXSTATES];
|
||||||
|
|
||||||
static D3DMATERIAL9 d3dmaterial;
|
static D3DMATERIAL9 d3dmaterial;
|
||||||
|
|
||||||
|
|
||||||
|
static uint32 blendMap[] = {
|
||||||
|
D3DBLEND_ZERO,
|
||||||
|
D3DBLEND_ONE,
|
||||||
|
D3DBLEND_SRCCOLOR,
|
||||||
|
D3DBLEND_INVSRCCOLOR,
|
||||||
|
D3DBLEND_SRCALPHA,
|
||||||
|
D3DBLEND_INVSRCALPHA,
|
||||||
|
D3DBLEND_DESTALPHA,
|
||||||
|
D3DBLEND_INVDESTALPHA,
|
||||||
|
D3DBLEND_DESTCOLOR,
|
||||||
|
D3DBLEND_INVDESTCOLOR,
|
||||||
|
D3DBLEND_SRCALPHASAT
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32 alphafuncMap[] = {
|
||||||
|
D3DCMP_ALWAYS,
|
||||||
|
D3DCMP_GREATEREQUAL,
|
||||||
|
D3DCMP_LESS
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32 cullmodeMap[] = {
|
||||||
|
D3DCULL_NONE,
|
||||||
|
D3DCULL_CW,
|
||||||
|
D3DCULL_CCW
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: support mipmaps
|
||||||
|
static uint32 filterConvMap_NoMIP[] = {
|
||||||
|
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||||
|
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||||
|
D3DTEXF_POINT, D3DTEXF_LINEAR
|
||||||
|
};
|
||||||
|
static uint32 addressConvMap[] = {
|
||||||
|
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
||||||
|
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||||
|
};
|
||||||
|
|
||||||
// D3D render state
|
// D3D render state
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -176,8 +222,16 @@ resetD3d9Device(void)
|
||||||
int32 i;
|
int32 i;
|
||||||
uint32 s, t;
|
uint32 s, t;
|
||||||
for(i = 0; i < MAXNUMSTAGES; i++){
|
for(i = 0; i < MAXNUMSTAGES; i++){
|
||||||
d3dRaster[i] = nil;
|
Raster *raster = rwStateCache.texstage[i].raster;
|
||||||
d3ddevice->SetTexture(i, nil);
|
if(raster){
|
||||||
|
D3dRaster *d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
|
d3ddevice->SetTexture(i, (IDirect3DTexture9*)d3draster->texture);
|
||||||
|
}else
|
||||||
|
d3ddevice->SetTexture(i, nil);
|
||||||
|
setSamplerState(i, D3DSAMP_ADDRESSU, addressConvMap[rwStateCache.texstage[i].addressingU]);
|
||||||
|
setSamplerState(i, D3DSAMP_ADDRESSV, addressConvMap[rwStateCache.texstage[i].addressingV]);
|
||||||
|
setSamplerState(i, D3DSAMP_MAGFILTER, filterConvMap_NoMIP[rwStateCache.texstage[i].filter]);
|
||||||
|
setSamplerState(i, D3DSAMP_MINFILTER, filterConvMap_NoMIP[rwStateCache.texstage[i].filter]);
|
||||||
}
|
}
|
||||||
for(s = 0; s < MAXNUMSTATES; s++)
|
for(s = 0; s < MAXNUMSTATES; s++)
|
||||||
if(validStates[s])
|
if(validStates[s])
|
||||||
|
@ -197,146 +251,25 @@ resetD3d9Device(void)
|
||||||
static void
|
static void
|
||||||
setVertexAlpha(bool32 enable)
|
setVertexAlpha(bool32 enable)
|
||||||
{
|
{
|
||||||
if(vertexAlpha != enable){
|
if(rwStateCache.vertexAlpha != enable){
|
||||||
if(!textureAlpha){
|
if(!rwStateCache.textureAlpha){
|
||||||
setRenderState(D3DRS_ALPHABLENDENABLE, enable);
|
setRenderState(D3DRS_ALPHABLENDENABLE, enable);
|
||||||
setRenderState(D3DRS_ALPHATESTENABLE, enable);
|
setRenderState(D3DRS_ALPHATESTENABLE, enable);
|
||||||
}
|
}
|
||||||
vertexAlpha = enable;
|
rwStateCache.vertexAlpha = enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 blendMap[] = {
|
|
||||||
D3DBLEND_ZERO,
|
|
||||||
D3DBLEND_ONE,
|
|
||||||
D3DBLEND_SRCCOLOR,
|
|
||||||
D3DBLEND_INVSRCCOLOR,
|
|
||||||
D3DBLEND_SRCALPHA,
|
|
||||||
D3DBLEND_INVSRCALPHA,
|
|
||||||
D3DBLEND_DESTALPHA,
|
|
||||||
D3DBLEND_INVDESTALPHA,
|
|
||||||
D3DBLEND_DESTCOLOR,
|
|
||||||
D3DBLEND_INVDESTCOLOR,
|
|
||||||
D3DBLEND_SRCALPHASAT
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 alphafuncMap[] = {
|
|
||||||
D3DCMP_ALWAYS,
|
|
||||||
D3DCMP_GREATEREQUAL,
|
|
||||||
D3DCMP_LESS
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 cullmodeMap[] = {
|
|
||||||
D3DCULL_NONE,
|
|
||||||
D3DCULL_CW,
|
|
||||||
D3DCULL_CCW
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
setRwRenderState(int32 state, uint32 value)
|
|
||||||
{
|
|
||||||
uint32 bval = value ? TRUE : FALSE;
|
|
||||||
switch(state){
|
|
||||||
case VERTEXALPHA:
|
|
||||||
setVertexAlpha(bval);
|
|
||||||
break;
|
|
||||||
case SRCBLEND:
|
|
||||||
if(srcblend != value){
|
|
||||||
srcblend = value;
|
|
||||||
setRenderState(D3DRS_SRCBLEND, blendMap[value]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DESTBLEND:
|
|
||||||
if(destblend != value){
|
|
||||||
destblend = value;
|
|
||||||
setRenderState(D3DRS_DESTBLEND, blendMap[value]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZTESTENABLE:
|
|
||||||
if(ztest != bval){
|
|
||||||
ztest = bval;
|
|
||||||
setRenderState(D3DRS_ZENABLE, ztest);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ZWRITEENABLE:
|
|
||||||
if(zwrite != bval){
|
|
||||||
zwrite = bval;
|
|
||||||
setRenderState(D3DRS_ZWRITEENABLE, zwrite);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FOGENABLE:
|
|
||||||
if(fogenable != bval){
|
|
||||||
fogenable = bval;
|
|
||||||
setRenderState(D3DRS_FOGENABLE, fogenable);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case FOGCOLOR:{
|
|
||||||
RGBA c;
|
|
||||||
c.red = value;
|
|
||||||
c.green = value>>8;
|
|
||||||
c.blue = value>>16;
|
|
||||||
c.alpha = value>>24;
|
|
||||||
if(!equal(fogcolor, c)){
|
|
||||||
fogcolor = c;
|
|
||||||
setRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(c.red, c.green, c.blue, c.alpha));
|
|
||||||
}} break;
|
|
||||||
case CULLMODE:
|
|
||||||
if(cullmode != value){
|
|
||||||
cullmode = value;
|
|
||||||
setRenderState(D3DRS_CULLMODE, cullmodeMap[value]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ALPHATESTFUNC:
|
|
||||||
if(alphafunc != value){
|
|
||||||
alphafunc = value;
|
|
||||||
setRenderState(D3DRS_ALPHAFUNC, alphafuncMap[alphafunc]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ALPHATESTREF:
|
|
||||||
if(alpharef != value){
|
|
||||||
alpharef = value;
|
|
||||||
setRenderState(D3DRS_ALPHAREF, alpharef);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32
|
|
||||||
getRwRenderState(int32 state)
|
|
||||||
{
|
|
||||||
switch(state){
|
|
||||||
case VERTEXALPHA:
|
|
||||||
return vertexAlpha;
|
|
||||||
case SRCBLEND:
|
|
||||||
return srcblend;
|
|
||||||
case DESTBLEND:
|
|
||||||
return destblend;
|
|
||||||
case ZTESTENABLE:
|
|
||||||
return ztest;
|
|
||||||
case ZWRITEENABLE:
|
|
||||||
return zwrite;
|
|
||||||
case FOGENABLE:
|
|
||||||
return fogenable;
|
|
||||||
case FOGCOLOR:
|
|
||||||
return RWRGBAINT(fogcolor.red, fogcolor.green, fogcolor.blue, fogcolor.alpha);
|
|
||||||
case CULLMODE:
|
|
||||||
return cullmode;
|
|
||||||
case ALPHATESTFUNC:
|
|
||||||
return alphafunc;
|
|
||||||
case ALPHATESTREF:
|
|
||||||
return alpharef;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
setRasterStage(uint32 stage, Raster *raster)
|
setRasterStage(uint32 stage, Raster *raster)
|
||||||
{
|
{
|
||||||
bool32 alpha;
|
bool32 alpha;
|
||||||
D3dRaster *d3draster = nil;
|
D3dRaster *d3draster = nil;
|
||||||
if(raster != d3dRaster[stage]){
|
if(raster != rwStateCache.texstage[stage].raster){
|
||||||
d3dRaster[stage] = raster;
|
rwStateCache.texstage[stage].raster = raster;
|
||||||
if(raster){
|
if(raster){
|
||||||
|
assert(raster->platform == PLATFORM_D3D8 ||
|
||||||
|
raster->platform == PLATFORM_D3D9);
|
||||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||||
d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||||
alpha = d3draster->hasAlpha;
|
alpha = d3draster->hasAlpha;
|
||||||
|
@ -345,9 +278,9 @@ setRasterStage(uint32 stage, Raster *raster)
|
||||||
alpha = 0;
|
alpha = 0;
|
||||||
}
|
}
|
||||||
if(stage == 0){
|
if(stage == 0){
|
||||||
if(textureAlpha != alpha){
|
if(rwStateCache.textureAlpha != alpha){
|
||||||
textureAlpha = alpha;
|
rwStateCache.textureAlpha = alpha;
|
||||||
if(!vertexAlpha){
|
if(!rwStateCache.vertexAlpha){
|
||||||
setRenderState(D3DRS_ALPHABLENDENABLE, alpha);
|
setRenderState(D3DRS_ALPHABLENDENABLE, alpha);
|
||||||
setRenderState(D3DRS_ALPHATESTENABLE, alpha);
|
setRenderState(D3DRS_ALPHATESTENABLE, alpha);
|
||||||
}
|
}
|
||||||
|
@ -356,28 +289,46 @@ setRasterStage(uint32 stage, Raster *raster)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setFilterMode(uint32 stage, int32 filter)
|
||||||
|
{
|
||||||
|
// TODO: mip mapping
|
||||||
|
if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){
|
||||||
|
rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter;
|
||||||
|
setSamplerState(0, D3DSAMP_MAGFILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
setSamplerState(0, D3DSAMP_MINFILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setAddressU(uint32 stage, int32 addressing)
|
||||||
|
{
|
||||||
|
if(rwStateCache.texstage[stage].addressingU != (Texture::Addressing)addressing){
|
||||||
|
rwStateCache.texstage[stage].addressingU = (Texture::Addressing)addressing;
|
||||||
|
setSamplerState(0, D3DSAMP_ADDRESSU, addressConvMap[addressing]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setAddressV(uint32 stage, int32 addressing)
|
||||||
|
{
|
||||||
|
if(rwStateCache.texstage[stage].addressingV != (Texture::Addressing)addressing){
|
||||||
|
rwStateCache.texstage[stage].addressingV = (Texture::Addressing)addressing;
|
||||||
|
setSamplerState(0, D3DSAMP_ADDRESSV, addressConvMap[addressing]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setTexture(uint32 stage, Texture *tex)
|
setTexture(uint32 stage, Texture *tex)
|
||||||
{
|
{
|
||||||
// TODO: support mipmaps
|
|
||||||
static DWORD filternomip[] = {
|
|
||||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
|
||||||
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
|
||||||
D3DTEXF_POINT, D3DTEXF_LINEAR
|
|
||||||
};
|
|
||||||
static DWORD wrap[] = {
|
|
||||||
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
|
||||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
|
||||||
};
|
|
||||||
if(tex == nil){
|
if(tex == nil){
|
||||||
setRasterStage(stage, nil);
|
setRasterStage(stage, nil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(tex->raster){
|
if(tex->raster){
|
||||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->getFilter()]);
|
setFilterMode(stage, tex->getFilter());
|
||||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->getFilter()]);
|
setAddressU(stage, tex->getAddressU());
|
||||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[tex->getAddressU()]);
|
setAddressV(stage, tex->getAddressV());
|
||||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[tex->getAddressV()]);
|
|
||||||
}
|
}
|
||||||
setRasterStage(stage, tex->raster);
|
setRasterStage(stage, tex->raster);
|
||||||
}
|
}
|
||||||
|
@ -428,6 +379,152 @@ setMaterial(SurfaceProperties surfProps, rw::RGBA color)
|
||||||
setD3dMaterial(&mat9);
|
setD3dMaterial(&mat9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setRwRenderState(int32 state, void *pvalue)
|
||||||
|
{
|
||||||
|
uint32 value = (uint32)(uintptr)pvalue;
|
||||||
|
uint32 bval = value ? TRUE : FALSE;
|
||||||
|
switch(state){
|
||||||
|
case TEXTURERASTER:
|
||||||
|
setRasterStage(0, (Raster*)pvalue);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESS:
|
||||||
|
setAddressU(0, value);
|
||||||
|
setAddressV(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSU:
|
||||||
|
setAddressU(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSV:
|
||||||
|
setAddressV(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREFILTER:
|
||||||
|
setFilterMode(0, value);
|
||||||
|
break;
|
||||||
|
case VERTEXALPHA:
|
||||||
|
setVertexAlpha(bval);
|
||||||
|
break;
|
||||||
|
case SRCBLEND:
|
||||||
|
if(rwStateCache.srcblend != value){
|
||||||
|
rwStateCache.srcblend = value;
|
||||||
|
setRenderState(D3DRS_SRCBLEND, blendMap[value]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DESTBLEND:
|
||||||
|
if(rwStateCache.destblend != value){
|
||||||
|
rwStateCache.destblend = value;
|
||||||
|
setRenderState(D3DRS_DESTBLEND, blendMap[value]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZTESTENABLE:
|
||||||
|
if(rwStateCache.ztest != bval){
|
||||||
|
rwStateCache.ztest = bval;
|
||||||
|
setRenderState(D3DRS_ZENABLE, rwStateCache.ztest);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZWRITEENABLE:
|
||||||
|
if(rwStateCache.zwrite != bval){
|
||||||
|
rwStateCache.zwrite = bval;
|
||||||
|
setRenderState(D3DRS_ZWRITEENABLE, rwStateCache.zwrite);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FOGENABLE:
|
||||||
|
if(rwStateCache.fogenable != bval){
|
||||||
|
rwStateCache.fogenable = bval;
|
||||||
|
setRenderState(D3DRS_FOGENABLE, rwStateCache.fogenable);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case FOGCOLOR:{
|
||||||
|
RGBA c;
|
||||||
|
c.red = value;
|
||||||
|
c.green = value>>8;
|
||||||
|
c.blue = value>>16;
|
||||||
|
c.alpha = value>>24;
|
||||||
|
if(!equal(rwStateCache.fogcolor, c)){
|
||||||
|
rwStateCache.fogcolor = c;
|
||||||
|
setRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(c.red, c.green, c.blue, c.alpha));
|
||||||
|
}} break;
|
||||||
|
case CULLMODE:
|
||||||
|
if(rwStateCache.cullmode != value){
|
||||||
|
rwStateCache.cullmode = value;
|
||||||
|
setRenderState(D3DRS_CULLMODE, cullmodeMap[value]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ALPHATESTFUNC:
|
||||||
|
if(rwStateCache.alphafunc != value){
|
||||||
|
rwStateCache.alphafunc = value;
|
||||||
|
setRenderState(D3DRS_ALPHAFUNC, alphafuncMap[rwStateCache.alphafunc]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ALPHATESTREF:
|
||||||
|
if(rwStateCache.alpharef != value){
|
||||||
|
rwStateCache.alpharef = value;
|
||||||
|
setRenderState(D3DRS_ALPHAREF, rwStateCache.alpharef);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
getRwRenderState(int32 state)
|
||||||
|
{
|
||||||
|
uint32 val;
|
||||||
|
switch(state){
|
||||||
|
case TEXTURERASTER:
|
||||||
|
return rwStateCache.texstage[0].raster;
|
||||||
|
case TEXTUREADDRESS:
|
||||||
|
if(rwStateCache.texstage[0].addressingU == rwStateCache.texstage[0].addressingV)
|
||||||
|
val = rwStateCache.texstage[0].addressingU;
|
||||||
|
else
|
||||||
|
val = 0; // invalid
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSU:
|
||||||
|
val = rwStateCache.texstage[0].addressingU;
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSV:
|
||||||
|
val = rwStateCache.texstage[0].addressingV;
|
||||||
|
break;
|
||||||
|
case TEXTUREFILTER:
|
||||||
|
val = rwStateCache.texstage[0].filter;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VERTEXALPHA:
|
||||||
|
val = rwStateCache.vertexAlpha;
|
||||||
|
break;
|
||||||
|
case SRCBLEND:
|
||||||
|
val = rwStateCache.srcblend;
|
||||||
|
break;
|
||||||
|
case DESTBLEND:
|
||||||
|
val = rwStateCache.destblend;
|
||||||
|
break;
|
||||||
|
case ZTESTENABLE:
|
||||||
|
val = rwStateCache.ztest;
|
||||||
|
break;
|
||||||
|
case ZWRITEENABLE:
|
||||||
|
val = rwStateCache.zwrite;
|
||||||
|
break;
|
||||||
|
case FOGENABLE:
|
||||||
|
val = rwStateCache.fogenable;
|
||||||
|
break;
|
||||||
|
case FOGCOLOR:
|
||||||
|
val = RWRGBAINT(rwStateCache.fogcolor.red, rwStateCache.fogcolor.green,
|
||||||
|
rwStateCache.fogcolor.blue, rwStateCache.fogcolor.alpha);
|
||||||
|
break;
|
||||||
|
case CULLMODE:
|
||||||
|
val = rwStateCache.cullmode;
|
||||||
|
break;
|
||||||
|
case ALPHATESTFUNC:
|
||||||
|
val = rwStateCache.alphafunc;
|
||||||
|
break;
|
||||||
|
case ALPHATESTREF:
|
||||||
|
val = rwStateCache.alpharef;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
return (void*)(uintptr)val;
|
||||||
|
}
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -750,26 +847,26 @@ initD3D(void)
|
||||||
// TODO: do some real stuff here
|
// TODO: do some real stuff here
|
||||||
|
|
||||||
d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||||
alphafunc = ALPHAGREATEREQUAL;
|
rwStateCache.alphafunc = ALPHAGREATEREQUAL;
|
||||||
d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10);
|
d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10);
|
||||||
alpharef = 10;
|
rwStateCache.alpharef = 10;
|
||||||
|
|
||||||
d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||||
fogenable = 0;
|
rwStateCache.fogenable = 0;
|
||||||
d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
|
d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
|
||||||
// TODO: more fog stuff
|
// TODO: more fog stuff
|
||||||
|
|
||||||
d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||||
cullmode = CULLNONE;
|
rwStateCache.cullmode = CULLNONE;
|
||||||
|
|
||||||
d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||||
d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
srcblend = BLENDSRCALPHA;
|
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||||
d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
destblend = BLENDINVSRCALPHA;
|
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||||
d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
|
d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
|
||||||
vertexAlpha = 0;
|
rwStateCache.vertexAlpha = 0;
|
||||||
textureAlpha = 0;
|
rwStateCache.textureAlpha = 0;
|
||||||
|
|
||||||
setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||||
// setTextureStageState(0, D3DTSS_CONSTANT, 0xFFFFFFFF);
|
// setTextureStageState(0, D3DTSS_CONSTANT, 0xFFFFFFFF);
|
||||||
|
|
|
@ -76,7 +76,6 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||||
d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
|
d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
|
||||||
d3ddevice->SetIndices(im2dindbuf);
|
d3ddevice->SetIndices(im2dindbuf);
|
||||||
d3ddevice->SetVertexDeclaration(im2ddecl);
|
d3ddevice->SetVertexDeclaration(im2ddecl);
|
||||||
d3d::setTexture(0, engine->imtexture);
|
|
||||||
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||||
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||||
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||||
|
@ -175,7 +174,6 @@ im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
|
||||||
unlockIndices(im3dindbuf);
|
unlockIndices(im3dindbuf);
|
||||||
|
|
||||||
d3ddevice->SetIndices(im3dindbuf);
|
d3ddevice->SetIndices(im3dindbuf);
|
||||||
d3d::setTexture(0, engine->imtexture);
|
|
||||||
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||||
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||||
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||||
|
|
|
@ -112,7 +112,6 @@ Engine::open(void)
|
||||||
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
||||||
engine->currentCamera = nil;
|
engine->currentCamera = nil;
|
||||||
engine->currentWorld = nil;
|
engine->currentWorld = nil;
|
||||||
engine->imtexture = nil;
|
|
||||||
|
|
||||||
// Initialize device
|
// Initialize device
|
||||||
// Device and possibly OS specific!
|
// Device and possibly OS specific!
|
||||||
|
@ -207,8 +206,8 @@ void endUpdate(Camera*) { }
|
||||||
void clearCamera(Camera*,RGBA*,uint32) { }
|
void clearCamera(Camera*,RGBA*,uint32) { }
|
||||||
void showRaster(Raster*) { }
|
void showRaster(Raster*) { }
|
||||||
|
|
||||||
void setRenderState(int32, uint32) { }
|
void setRenderState(int32, void*) { }
|
||||||
uint32 getRenderState(int32) { return 0; }
|
void *getRenderState(int32) { return 0; }
|
||||||
|
|
||||||
void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { }
|
void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { }
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include "../rwbase.h"
|
#include "../rwbase.h"
|
||||||
#include "../rwerror.h"
|
#include "../rwerror.h"
|
||||||
|
@ -83,15 +84,28 @@ static bool32 stateDirty = 1;
|
||||||
static bool32 sceneDirty = 1;
|
static bool32 sceneDirty = 1;
|
||||||
static bool32 objectDirty = 1;
|
static bool32 objectDirty = 1;
|
||||||
|
|
||||||
// cached render states
|
struct RwRasterStateCache {
|
||||||
static bool32 vertexAlpha;
|
Raster *raster;
|
||||||
static uint32 alphaTestEnable;
|
Texture::Addressing addressingU;
|
||||||
static uint32 alphaFunc;
|
Texture::Addressing addressingV;
|
||||||
static bool32 textureAlpha;
|
Texture::FilterMode filter;
|
||||||
static uint32 srcblend, destblend;
|
};
|
||||||
static uint32 zwrite;
|
|
||||||
static uint32 ztest;
|
#define MAXNUMSTAGES 8
|
||||||
static uint32 cullmode;
|
|
||||||
|
// cached RW render states
|
||||||
|
struct RwStateCache {
|
||||||
|
bool32 vertexAlpha;
|
||||||
|
uint32 alphaTestEnable;
|
||||||
|
uint32 alphaFunc;
|
||||||
|
bool32 textureAlpha;
|
||||||
|
uint32 srcblend, destblend;
|
||||||
|
uint32 zwrite;
|
||||||
|
uint32 ztest;
|
||||||
|
uint32 cullmode;
|
||||||
|
RwRasterStateCache texstage[MAXNUMSTAGES];
|
||||||
|
};
|
||||||
|
static RwStateCache rwStateCache;
|
||||||
|
|
||||||
static int32 activeTexture;
|
static int32 activeTexture;
|
||||||
|
|
||||||
|
@ -113,9 +127,9 @@ static void
|
||||||
setAlphaTest(bool32 enable)
|
setAlphaTest(bool32 enable)
|
||||||
{
|
{
|
||||||
uint32 shaderfunc;
|
uint32 shaderfunc;
|
||||||
if(alphaTestEnable != enable){
|
if(rwStateCache.alphaTestEnable != enable){
|
||||||
alphaTestEnable = enable;
|
rwStateCache.alphaTestEnable = enable;
|
||||||
shaderfunc = alphaTestEnable ? alphaFunc : ALPHAALWAYS;
|
shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS;
|
||||||
if(uniformState.alphaFunc != shaderfunc){
|
if(uniformState.alphaFunc != shaderfunc){
|
||||||
uniformState.alphaFunc = shaderfunc;
|
uniformState.alphaFunc = shaderfunc;
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
|
@ -127,9 +141,9 @@ static void
|
||||||
setAlphaTestFunction(uint32 function)
|
setAlphaTestFunction(uint32 function)
|
||||||
{
|
{
|
||||||
uint32 shaderfunc;
|
uint32 shaderfunc;
|
||||||
if(alphaFunc != function){
|
if(rwStateCache.alphaFunc != function){
|
||||||
alphaFunc = function;
|
rwStateCache.alphaFunc = function;
|
||||||
shaderfunc = alphaTestEnable ? alphaFunc : ALPHAALWAYS;
|
shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS;
|
||||||
if(uniformState.alphaFunc != shaderfunc){
|
if(uniformState.alphaFunc != shaderfunc){
|
||||||
uniformState.alphaFunc = shaderfunc;
|
uniformState.alphaFunc = shaderfunc;
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
|
@ -140,47 +154,201 @@ setAlphaTestFunction(uint32 function)
|
||||||
static void
|
static void
|
||||||
setVertexAlpha(bool32 enable)
|
setVertexAlpha(bool32 enable)
|
||||||
{
|
{
|
||||||
if(vertexAlpha != enable){
|
if(rwStateCache.vertexAlpha != enable){
|
||||||
if(!textureAlpha){
|
if(!rwStateCache.textureAlpha){
|
||||||
(enable ? glEnable : glDisable)(GL_BLEND);
|
(enable ? glEnable : glDisable)(GL_BLEND);
|
||||||
setAlphaTest(enable);
|
setAlphaTest(enable);
|
||||||
}
|
}
|
||||||
vertexAlpha = enable;
|
rwStateCache.vertexAlpha = enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setRenderState(int32 state, uint32 value)
|
setActiveTexture(int32 n)
|
||||||
{
|
{
|
||||||
|
if(activeTexture != n){
|
||||||
|
activeTexture = n;
|
||||||
|
glActiveTexture(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: support mipmaps
|
||||||
|
static GLint filterConvMap_NoMIP[] = {
|
||||||
|
0, GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR
|
||||||
|
};
|
||||||
|
|
||||||
|
static GLint addressConvMap[] = {
|
||||||
|
0, GL_REPEAT, GL_MIRRORED_REPEAT,
|
||||||
|
GL_CLAMP, GL_CLAMP_TO_BORDER
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
setFilterMode(uint32 stage, int32 filter)
|
||||||
|
{
|
||||||
|
if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){
|
||||||
|
rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter;
|
||||||
|
Raster *raster = rwStateCache.texstage[stage].raster;
|
||||||
|
if(raster){
|
||||||
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, rwStateCache.texstage[stage].raster, nativeRasterOffset);
|
||||||
|
if(natras->filterMode != filter){
|
||||||
|
setActiveTexture(stage);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
natras->filterMode = filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setAddressU(uint32 stage, int32 addressing)
|
||||||
|
{
|
||||||
|
if(rwStateCache.texstage[stage].addressingU != (Texture::Addressing)addressing){
|
||||||
|
rwStateCache.texstage[stage].addressingU = (Texture::Addressing)addressing;
|
||||||
|
Raster *raster = rwStateCache.texstage[stage].raster;
|
||||||
|
if(raster){
|
||||||
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
|
if(natras->addressU == addressing){
|
||||||
|
setActiveTexture(stage);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, addressConvMap[addressing]);
|
||||||
|
natras->addressU = addressing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setAddressV(uint32 stage, int32 addressing)
|
||||||
|
{
|
||||||
|
if(rwStateCache.texstage[stage].addressingV != (Texture::Addressing)addressing){
|
||||||
|
rwStateCache.texstage[stage].addressingV = (Texture::Addressing)addressing;
|
||||||
|
Raster *raster = rwStateCache.texstage[stage].raster;
|
||||||
|
if(raster){
|
||||||
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, rwStateCache.texstage[stage].raster, nativeRasterOffset);
|
||||||
|
if(natras->addressV == addressing){
|
||||||
|
setActiveTexture(stage);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, addressConvMap[addressing]);
|
||||||
|
natras->addressV = addressing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setRasterStage(uint32 stage, Raster *raster)
|
||||||
|
{
|
||||||
|
bool32 alpha;
|
||||||
|
if(raster != rwStateCache.texstage[stage].raster){
|
||||||
|
rwStateCache.texstage[stage].raster = raster;
|
||||||
|
setActiveTexture(GL_TEXTURE0+stage);
|
||||||
|
if(raster){
|
||||||
|
assert(raster->platform == PLATFORM_GL3);
|
||||||
|
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, raster, nativeRasterOffset);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
||||||
|
uint32 filter = rwStateCache.texstage[stage].filter;
|
||||||
|
uint32 addrU = rwStateCache.texstage[stage].addressingU;
|
||||||
|
uint32 addrV = rwStateCache.texstage[stage].addressingV;
|
||||||
|
if(natras->filterMode != filter){
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterConvMap_NoMIP[filter]);
|
||||||
|
natras->filterMode = filter;
|
||||||
|
}
|
||||||
|
if(natras->addressU != addrU){
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, addressConvMap[addrU]);
|
||||||
|
natras->addressU = addrU;
|
||||||
|
}
|
||||||
|
if(natras->addressU != addrV){
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, addressConvMap[addrV]);
|
||||||
|
natras->addressV = addrV;
|
||||||
|
}
|
||||||
|
alpha = natras->hasAlpha;
|
||||||
|
}else{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
alpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stage == 0){
|
||||||
|
if(alpha != rwStateCache.textureAlpha){
|
||||||
|
rwStateCache.textureAlpha = alpha;
|
||||||
|
if(!rwStateCache.vertexAlpha){
|
||||||
|
(alpha ? glEnable : glDisable)(GL_BLEND);
|
||||||
|
setAlphaTest(alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setTexture(int32 stage, Texture *tex)
|
||||||
|
{
|
||||||
|
if(tex == nil){
|
||||||
|
setRasterStage(stage, nil);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(tex->raster){
|
||||||
|
setFilterMode(stage, tex->getFilter());
|
||||||
|
setAddressU(stage, tex->getAddressU());
|
||||||
|
setAddressV(stage, tex->getAddressV());
|
||||||
|
}
|
||||||
|
setRasterStage(stage, tex->raster);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setRenderState(int32 state, void *pvalue)
|
||||||
|
{
|
||||||
|
uint32 value = (uint32)(uintptr)pvalue;
|
||||||
switch(state){
|
switch(state){
|
||||||
|
case TEXTURERASTER:
|
||||||
|
setRasterStage(0, (Raster*)pvalue);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESS:
|
||||||
|
setAddressU(0, value);
|
||||||
|
setAddressV(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSU:
|
||||||
|
setAddressU(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSV:
|
||||||
|
setAddressV(0, value);
|
||||||
|
break;
|
||||||
|
case TEXTUREFILTER:
|
||||||
|
setFilterMode(0, value);
|
||||||
|
break;
|
||||||
case VERTEXALPHA:
|
case VERTEXALPHA:
|
||||||
setVertexAlpha(value);
|
setVertexAlpha(value);
|
||||||
break;
|
break;
|
||||||
case SRCBLEND:
|
case SRCBLEND:
|
||||||
if(srcblend != value){
|
if(rwStateCache.srcblend != value){
|
||||||
srcblend = value;
|
rwStateCache.srcblend = value;
|
||||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DESTBLEND:
|
case DESTBLEND:
|
||||||
if(destblend != value){
|
if(rwStateCache.destblend != value){
|
||||||
destblend = value;
|
rwStateCache.destblend = value;
|
||||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZTESTENABLE:
|
case ZTESTENABLE:
|
||||||
if(ztest != value){
|
if(rwStateCache.ztest != value){
|
||||||
ztest = value;
|
rwStateCache.ztest = value;
|
||||||
if(ztest)
|
if(rwStateCache.ztest)
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
else
|
else
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZWRITEENABLE:
|
case ZWRITEENABLE:
|
||||||
if(zwrite != (value ? GL_TRUE : GL_FALSE)){
|
if(rwStateCache.zwrite != (value ? GL_TRUE : GL_FALSE)){
|
||||||
zwrite = value ? GL_TRUE : GL_FALSE;
|
rwStateCache.zwrite = value ? GL_TRUE : GL_FALSE;
|
||||||
glDepthMask(zwrite);
|
glDepthMask(rwStateCache.zwrite);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FOGENABLE:
|
case FOGENABLE:
|
||||||
|
@ -200,13 +368,13 @@ setRenderState(int32 state, uint32 value)
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
break;
|
break;
|
||||||
case CULLMODE:
|
case CULLMODE:
|
||||||
if(cullmode != value){
|
if(rwStateCache.cullmode != value){
|
||||||
cullmode = value;
|
rwStateCache.cullmode = value;
|
||||||
if(cullmode == CULLNONE)
|
if(rwStateCache.cullmode == CULLNONE)
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
else{
|
else{
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(cullmode == CULLBACK ? GL_BACK : GL_FRONT);
|
glCullFace(rwStateCache.cullmode == CULLBACK ? GL_BACK : GL_FRONT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -223,41 +391,72 @@ setRenderState(int32 state, uint32 value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32
|
static void*
|
||||||
getRenderState(int32 state)
|
getRenderState(int32 state)
|
||||||
{
|
{
|
||||||
|
uint32 val;
|
||||||
RGBA rgba;
|
RGBA rgba;
|
||||||
switch(state){
|
switch(state){
|
||||||
|
case TEXTURERASTER:
|
||||||
|
return rwStateCache.texstage[0].raster;
|
||||||
|
case TEXTUREADDRESS:
|
||||||
|
if(rwStateCache.texstage[0].addressingU == rwStateCache.texstage[0].addressingV)
|
||||||
|
val = rwStateCache.texstage[0].addressingU;
|
||||||
|
else
|
||||||
|
val = 0; // invalid
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSU:
|
||||||
|
val = rwStateCache.texstage[0].addressingU;
|
||||||
|
break;
|
||||||
|
case TEXTUREADDRESSV:
|
||||||
|
val = rwStateCache.texstage[0].addressingV;
|
||||||
|
break;
|
||||||
|
case TEXTUREFILTER:
|
||||||
|
val = rwStateCache.texstage[0].filter;
|
||||||
|
break;
|
||||||
|
|
||||||
case VERTEXALPHA:
|
case VERTEXALPHA:
|
||||||
return vertexAlpha;
|
val = rwStateCache.vertexAlpha;
|
||||||
|
break;
|
||||||
case SRCBLEND:
|
case SRCBLEND:
|
||||||
return srcblend;
|
val = rwStateCache.srcblend;
|
||||||
|
break;
|
||||||
case DESTBLEND:
|
case DESTBLEND:
|
||||||
return destblend;
|
val = rwStateCache.destblend;
|
||||||
|
break;
|
||||||
case ZTESTENABLE:
|
case ZTESTENABLE:
|
||||||
return ztest;
|
val = rwStateCache.ztest;
|
||||||
|
break;
|
||||||
case ZWRITEENABLE:
|
case ZWRITEENABLE:
|
||||||
return zwrite;
|
val = rwStateCache.zwrite;
|
||||||
|
break;
|
||||||
case FOGENABLE:
|
case FOGENABLE:
|
||||||
return uniformState.fogEnable;
|
val = uniformState.fogEnable;
|
||||||
|
break;
|
||||||
case FOGCOLOR:
|
case FOGCOLOR:
|
||||||
convColor(&rgba, &uniformState.fogColor);
|
convColor(&rgba, &uniformState.fogColor);
|
||||||
return RWRGBAINT(rgba.red, rgba.green, rgba.blue, rgba.alpha);
|
val = RWRGBAINT(rgba.red, rgba.green, rgba.blue, rgba.alpha);
|
||||||
|
break;
|
||||||
case CULLMODE:
|
case CULLMODE:
|
||||||
return cullmode;
|
val = rwStateCache.cullmode;
|
||||||
|
break;
|
||||||
|
|
||||||
case ALPHATESTFUNC:
|
case ALPHATESTFUNC:
|
||||||
return alphaFunc;
|
val = rwStateCache.alphaFunc;
|
||||||
|
break;
|
||||||
case ALPHATESTREF:
|
case ALPHATESTREF:
|
||||||
return (uint32)(uniformState.alphaRef*255.0f);
|
val = (uint32)(uniformState.alphaRef*255.0f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
val = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return (void*)(uintptr)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resetRenderState(void)
|
resetRenderState(void)
|
||||||
{
|
{
|
||||||
alphaFunc = ALPHAGREATEREQUAL;
|
rwStateCache.alphaFunc = ALPHAGREATEREQUAL;
|
||||||
uniformState.alphaFunc = 0;
|
uniformState.alphaFunc = 0;
|
||||||
uniformState.alphaRef = 10.0f/255.0f;
|
uniformState.alphaRef = 10.0f/255.0f;
|
||||||
uniformState.fogEnable = 0;
|
uniformState.fogEnable = 0;
|
||||||
|
@ -265,28 +464,28 @@ resetRenderState(void)
|
||||||
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
|
|
||||||
vertexAlpha = 0;
|
rwStateCache.vertexAlpha = 0;
|
||||||
textureAlpha = 0;
|
rwStateCache.textureAlpha = 0;
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
alphaTestEnable = 0;
|
rwStateCache.alphaTestEnable = 0;
|
||||||
|
|
||||||
srcblend = BLENDSRCALPHA;
|
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||||
destblend = BLENDINVSRCALPHA;
|
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||||
|
|
||||||
zwrite = GL_TRUE;
|
rwStateCache.zwrite = GL_TRUE;
|
||||||
glDepthMask(zwrite);
|
glDepthMask(rwStateCache.zwrite);
|
||||||
|
|
||||||
ztest = 1;
|
rwStateCache.ztest = 1;
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
|
||||||
cullmode = CULLNONE;
|
rwStateCache.cullmode = CULLNONE;
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++){
|
for(int i = 0; i < MAXNUMSTAGES; i++){
|
||||||
glActiveTexture(GL_TEXTURE0+i);
|
glActiveTexture(GL_TEXTURE0+i);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,61 +546,6 @@ setViewMatrix(float32 *mat)
|
||||||
sceneDirty = 1;
|
sceneDirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
setActiveTexture(int32 n)
|
|
||||||
{
|
|
||||||
if(activeTexture != n){
|
|
||||||
activeTexture = n;
|
|
||||||
glActiveTexture(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
setTexture(int32 n, Texture *tex)
|
|
||||||
{
|
|
||||||
// TODO: support mipmaps
|
|
||||||
static GLint filternomip[] = {
|
|
||||||
0, GL_NEAREST, GL_LINEAR,
|
|
||||||
GL_NEAREST, GL_LINEAR,
|
|
||||||
GL_NEAREST, GL_LINEAR
|
|
||||||
};
|
|
||||||
|
|
||||||
static GLint wrap[] = {
|
|
||||||
0, GL_REPEAT, GL_MIRRORED_REPEAT,
|
|
||||||
GL_CLAMP, GL_CLAMP_TO_BORDER
|
|
||||||
};
|
|
||||||
bool32 alpha;
|
|
||||||
setActiveTexture(GL_TEXTURE0+n);
|
|
||||||
if(tex == nil || tex->raster == nil ||
|
|
||||||
tex->raster->platform != PLATFORM_GL3 ||
|
|
||||||
tex->raster->width == 0){
|
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
|
||||||
alpha = 0;
|
|
||||||
}else{
|
|
||||||
Gl3Raster *natras = PLUGINOFFSET(Gl3Raster, tex->raster,
|
|
||||||
nativeRasterOffset);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, natras->texid);
|
|
||||||
alpha = natras->hasAlpha;
|
|
||||||
if(tex->filterAddressing != natras->filterAddressing){
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filternomip[tex->getFilter()]);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filternomip[tex->getFilter()]);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap[tex->getAddressU()]);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap[tex->getAddressV()]);
|
|
||||||
natras->filterAddressing = tex->filterAddressing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n == 0){
|
|
||||||
if(alpha != textureAlpha){
|
|
||||||
textureAlpha = alpha;
|
|
||||||
if(!vertexAlpha){
|
|
||||||
(alpha ? glEnable : glDisable)(GL_BLEND);
|
|
||||||
setAlphaTest(alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
flushCache(void)
|
flushCache(void)
|
||||||
{
|
{
|
||||||
|
@ -593,6 +737,14 @@ initOpenGL(void)
|
||||||
|
|
||||||
glClearColor(0.25, 0.25, 0.25, 1.0);
|
glClearColor(0.25, 0.25, 0.25, 1.0);
|
||||||
|
|
||||||
|
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
glGenTextures(1, &whitetex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
||||||
|
|
||||||
resetRenderState();
|
resetRenderState();
|
||||||
|
|
||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
|
@ -619,14 +771,6 @@ initOpenGL(void)
|
||||||
GL_DYNAMIC_DRAW);
|
GL_DYNAMIC_DRAW);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
|
||||||
glGenTextures(1, &whitetex);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
|
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
|
||||||
|
|
||||||
#include "shaders/simple_vs_gl3.inc"
|
#include "shaders/simple_vs_gl3.inc"
|
||||||
#include "shaders/simple_fs_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);
|
||||||
|
|
|
@ -100,7 +100,6 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||||
setAttribPointers(im2dattribDesc, 3);
|
setAttribPointers(im2dattribDesc, 3);
|
||||||
|
|
||||||
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||||
setTexture(0, engine->imtexture);
|
|
||||||
|
|
||||||
flushCache();
|
flushCache();
|
||||||
glDrawElements(primTypeMap[primType], numIndices,
|
glDrawElements(primTypeMap[primType], numIndices,
|
||||||
|
@ -179,8 +178,6 @@ im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
||||||
indices, GL_DYNAMIC_DRAW);
|
indices, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
setTexture(0, engine->imtexture);
|
|
||||||
|
|
||||||
flushCache();
|
flushCache();
|
||||||
glDrawElements(primTypeMap[primType], numIndices,
|
glDrawElements(primTypeMap[primType], numIndices,
|
||||||
GL_UNSIGNED_SHORT, nil);
|
GL_UNSIGNED_SHORT, nil);
|
||||||
|
|
|
@ -86,7 +86,9 @@ rasterCreate(Raster *raster)
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
||||||
raster->width, raster->height,
|
raster->width, raster->height,
|
||||||
0, natras->format, natras->type, nil);
|
0, natras->format, natras->type, nil);
|
||||||
natras->filterAddressing = ~0;
|
natras->filterMode = 0;
|
||||||
|
natras->addressU = 0;
|
||||||
|
natras->addressV = 0;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,7 +172,9 @@ struct Gl3Raster
|
||||||
|
|
||||||
bool32 hasAlpha;
|
bool32 hasAlpha;
|
||||||
// cached filtermode and addressing
|
// cached filtermode and addressing
|
||||||
uint32 filterAddressing;
|
uint8 filterMode;
|
||||||
|
uint8 addressU;
|
||||||
|
uint8 addressV;
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerNativeRaster(void);
|
void registerNativeRaster(void);
|
||||||
|
|
|
@ -33,6 +33,7 @@ Image::create(int32 width, int32 height, int32 depth)
|
||||||
img->width = width;
|
img->width = width;
|
||||||
img->height = height;
|
img->height = height;
|
||||||
img->depth = depth;
|
img->depth = depth;
|
||||||
|
img->bpp = depth < 8 ? 1 : depth/8;
|
||||||
img->stride = 0;
|
img->stride = 0;
|
||||||
img->pixels = nil;
|
img->pixels = nil;
|
||||||
img->palette = nil;
|
img->palette = nil;
|
||||||
|
@ -50,7 +51,7 @@ void
|
||||||
Image::allocate(void)
|
Image::allocate(void)
|
||||||
{
|
{
|
||||||
if(this->pixels == nil){
|
if(this->pixels == nil){
|
||||||
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
|
this->stride = this->width*this->bpp;
|
||||||
this->pixels = rwNewT(uint8, this->stride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
this->pixels = rwNewT(uint8, this->stride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
this->flags |= 1;
|
this->flags |= 1;
|
||||||
}
|
}
|
||||||
|
|
33
src/prim.cpp
33
src/prim.cpp
|
@ -12,6 +12,31 @@
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BBox::initialize(V3d *point)
|
||||||
|
{
|
||||||
|
this->inf = *point;
|
||||||
|
this->sup = *point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BBox::addPoint(V3d *point)
|
||||||
|
{
|
||||||
|
if(point->x < this->inf.x)
|
||||||
|
this->inf.x = point->x;
|
||||||
|
if(point->y < this->inf.y)
|
||||||
|
this->inf.y = point->y;
|
||||||
|
if(point->z < this->inf.z)
|
||||||
|
this->inf.z = point->z;
|
||||||
|
if(point->x > this->sup.x)
|
||||||
|
this->sup.x = point->x;
|
||||||
|
if(point->y > this->sup.y)
|
||||||
|
this->sup.y = point->y;
|
||||||
|
if(point->z > this->sup.z)
|
||||||
|
this->sup.z = point->z;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BBox::calculate(V3d *points, int32 n)
|
BBox::calculate(V3d *points, int32 n)
|
||||||
{
|
{
|
||||||
|
@ -34,4 +59,12 @@ BBox::calculate(V3d *points, int32 n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BBox::containsPoint(V3d *point)
|
||||||
|
{
|
||||||
|
return point->x >= this->inf.x && point->x <= this->sup.x &&
|
||||||
|
point->y >= this->inf.y && point->y <= this->sup.y &&
|
||||||
|
point->z >= this->inf.z && point->z <= this->sup.z;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,15 @@
|
||||||
namespace rw {
|
namespace rw {
|
||||||
|
|
||||||
void SetRenderState(int32 state, uint32 value){
|
void SetRenderState(int32 state, uint32 value){
|
||||||
|
engine->device.setRenderState(state, (void*)(uintptr)value); }
|
||||||
|
|
||||||
|
void SetRenderStatePtr(int32 state, void *value){
|
||||||
engine->device.setRenderState(state, value); }
|
engine->device.setRenderState(state, value); }
|
||||||
|
|
||||||
uint32 GetRenderState(int32 state){
|
uint32 GetRenderState(int32 state){
|
||||||
|
return (uint32)(uintptr)engine->device.getRenderState(state); }
|
||||||
|
|
||||||
|
void *GetRenderStatePtr(int32 state){
|
||||||
return engine->device.getRenderState(state); }
|
return engine->device.getRenderState(state); }
|
||||||
|
|
||||||
// Im2D
|
// Im2D
|
||||||
|
@ -17,7 +23,7 @@ uint32 GetRenderState(int32 state){
|
||||||
namespace im2d {
|
namespace im2d {
|
||||||
|
|
||||||
float32 GetNearZ(void) { return engine->device.zNear; }
|
float32 GetNearZ(void) { return engine->device.zNear; }
|
||||||
float32 GetFarZ(void) { return engine->device.zNear; }
|
float32 GetFarZ(void) { return engine->device.zFar; }
|
||||||
void
|
void
|
||||||
RenderIndexedPrimitive(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices)
|
RenderIndexedPrimitive(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices)
|
||||||
{
|
{
|
||||||
|
|
|
@ -384,7 +384,10 @@ struct BBox
|
||||||
V3d sup;
|
V3d sup;
|
||||||
V3d inf;
|
V3d inf;
|
||||||
|
|
||||||
|
void initialize(V3d *point);
|
||||||
|
void addPoint(V3d *point);
|
||||||
void calculate(V3d *points, int32 n);
|
void calculate(V3d *points, int32 n);
|
||||||
|
bool containsPoint(V3d *point);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PrimitiveType
|
enum PrimitiveType
|
||||||
|
|
|
@ -29,12 +29,12 @@ class ObjPipeline;
|
||||||
struct Device
|
struct Device
|
||||||
{
|
{
|
||||||
float32 zNear, zFar;
|
float32 zNear, zFar;
|
||||||
void (*beginUpdate)(Camera*);
|
void (*beginUpdate)(Camera*);
|
||||||
void (*endUpdate)(Camera*);
|
void (*endUpdate)(Camera*);
|
||||||
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
|
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
|
||||||
void (*showRaster)(Raster *raster);
|
void (*showRaster)(Raster *raster);
|
||||||
void (*setRenderState)(int32 state, uint32 value);
|
void (*setRenderState)(int32 state, void *value);
|
||||||
uint32 (*getRenderState)(int32 state);
|
void *(*getRenderState)(int32 state);
|
||||||
|
|
||||||
// TODO: render line
|
// TODO: render line
|
||||||
// TODO: render triangle
|
// TODO: render triangle
|
||||||
|
@ -110,7 +110,6 @@ struct Engine
|
||||||
};
|
};
|
||||||
void *currentCamera;
|
void *currentCamera;
|
||||||
void *currentWorld;
|
void *currentWorld;
|
||||||
Texture *imtexture;
|
|
||||||
LinkList frameDirtyList;
|
LinkList frameDirtyList;
|
||||||
|
|
||||||
// Dynamically allocated because of plugins
|
// Dynamically allocated because of plugins
|
||||||
|
@ -154,8 +153,8 @@ namespace null {
|
||||||
void clearCamera(Camera*, RGBA *col, uint32 mode);
|
void clearCamera(Camera*, RGBA *col, uint32 mode);
|
||||||
void showRaster(Raster*);
|
void showRaster(Raster*);
|
||||||
|
|
||||||
void setRenderState(int32 state, uint32 value);
|
void setRenderState(int32 state, void *value);
|
||||||
uint32 getRenderState(int32 state);
|
void *getRenderState(int32 state);
|
||||||
|
|
||||||
void rasterCreate(Raster*);
|
void rasterCreate(Raster*);
|
||||||
uint8 *rasterLock(Raster*, int32 level);
|
uint8 *rasterLock(Raster*, int32 level);
|
||||||
|
|
|
@ -125,6 +125,7 @@ struct Image
|
||||||
int32 flags;
|
int32 flags;
|
||||||
int32 width, height;
|
int32 width, height;
|
||||||
int32 depth;
|
int32 depth;
|
||||||
|
int32 bpp; // bytes per pixel
|
||||||
int32 stride;
|
int32 stride;
|
||||||
uint8 *pixels;
|
uint8 *pixels;
|
||||||
uint8 *palette;
|
uint8 *palette;
|
||||||
|
|
|
@ -4,7 +4,12 @@ namespace rw {
|
||||||
|
|
||||||
enum RenderState
|
enum RenderState
|
||||||
{
|
{
|
||||||
VERTEXALPHA = 0,
|
TEXTURERASTER,
|
||||||
|
TEXTUREADDRESS,
|
||||||
|
TEXTUREADDRESSU,
|
||||||
|
TEXTUREADDRESSV,
|
||||||
|
TEXTUREFILTER,
|
||||||
|
VERTEXALPHA,
|
||||||
SRCBLEND,
|
SRCBLEND,
|
||||||
DESTBLEND,
|
DESTBLEND,
|
||||||
ZTESTENABLE,
|
ZTESTENABLE,
|
||||||
|
@ -53,7 +58,9 @@ enum BlendFunction
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetRenderState(int32 state, uint32 value);
|
void SetRenderState(int32 state, uint32 value);
|
||||||
|
void SetRenderStatePtr(int32 state, void *value);
|
||||||
uint32 GetRenderState(int32 state);
|
uint32 GetRenderState(int32 state);
|
||||||
|
void *GetRenderStatePtr(int32 state);
|
||||||
|
|
||||||
// Im2D
|
// Im2D
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,8 @@ defaultFindCB(const char *name)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: actually read the mask!
|
||||||
static Texture*
|
static Texture*
|
||||||
defaultReadCB(const char *name, const char *mask)
|
defaultReadCB(const char *name, const char *mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,7 +96,11 @@ printScreen(const char *s, float32 x, float32 y)
|
||||||
|
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
engine->imtexture = curfont->tex;
|
|
||||||
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, curfont->tex->raster);
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||||
|
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||||
|
|
||||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||||
vertices, curVert, indices, curIndex);
|
vertices, curVert, indices, curIndex);
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,9 @@ im2dtest(void)
|
||||||
verts[i].setV(vs[i].v, recipZ);
|
verts[i].setV(vs[i].v, recipZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
rw::engine->imtexture = tex2;
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex2->raster);
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||||
|
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||||
&verts, 4, &indices, 4);
|
&verts, 4, &indices, 4);
|
||||||
|
@ -305,7 +307,9 @@ im3dtest(void)
|
||||||
verts[i].setV(vs[i].v);
|
verts[i].setV(vs[i].v);
|
||||||
}
|
}
|
||||||
|
|
||||||
rw::engine->imtexture = tex;
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||||
|
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
genIm3DTransform(verts, 8, nil);
|
genIm3DTransform(verts, 8, nil);
|
||||||
|
@ -325,9 +329,9 @@ 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();
|
// im3dtest();
|
||||||
// printScreen("Hello, World!", 10, 10);
|
// printScreen("Hello, World!", 10, 10);
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,15 @@ drawAtomic(Atomic *a)
|
||||||
im2dverts[idx].setColor(col.red, col.green, col.blue, col.alpha);
|
im2dverts[idx].setColor(col.red, col.green, col.blue, col.alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine->imtexture = m[i].material->texture;
|
rw::Texture *tex = m[i].material->texture;
|
||||||
|
if(tex && tex->raster){
|
||||||
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESSU, tex->getAddressU());
|
||||||
|
rw::SetRenderState(rw::TEXTUREADDRESSV, tex->getAddressV());
|
||||||
|
rw::SetRenderState(rw::TEXTUREFILTER, tex->getFilter());
|
||||||
|
}else
|
||||||
|
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||||
|
|
||||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||||
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue