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)
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
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,
|
||||
g_vertbuf+vtx_offset, cmd_list->VtxBuffer.Size,
|
||||
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;
|
||||
out = raster->lock(0);
|
||||
if(pallength)
|
||||
|
@ -38,21 +38,32 @@ static VidmemRaster *vidmemRasters;
|
||||
void addVidmemRaster(Raster *raster);
|
||||
void removeVidmemRaster(Raster *raster);
|
||||
|
||||
// cached RW render states
|
||||
static bool32 vertexAlpha;
|
||||
static bool32 textureAlpha;
|
||||
static uint32 srcblend, destblend;
|
||||
static uint32 zwrite;
|
||||
static uint32 ztest;
|
||||
static uint32 fogenable;
|
||||
static RGBA fogcolor;
|
||||
static uint32 cullmode;
|
||||
static uint32 alphafunc;
|
||||
static uint32 alpharef;
|
||||
struct RwRasterStateCache {
|
||||
Raster *raster;
|
||||
Texture::Addressing addressingU;
|
||||
Texture::Addressing addressingV;
|
||||
Texture::FilterMode filter;
|
||||
};
|
||||
|
||||
#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 MAXNUMSTAGES 8
|
||||
#define MAXNUMTEXSTATES (D3DTSS_CONSTANT+1)
|
||||
#define MAXNUMSAMPLERSTATES (D3DSAMP_DMAPOFFSET+1)
|
||||
|
||||
@ -77,15 +88,50 @@ static uint32 d3dTextureStageStates[MAXNUMTEXSTATES][MAXNUMSTAGES];
|
||||
|
||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||
|
||||
// TODO: not only rasters, make a struct
|
||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
||||
|
||||
|
||||
static bool validStates[MAXNUMSTATES];
|
||||
static bool validTexStates[MAXNUMTEXSTATES];
|
||||
|
||||
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
|
||||
|
||||
void
|
||||
@ -176,8 +222,16 @@ resetD3d9Device(void)
|
||||
int32 i;
|
||||
uint32 s, t;
|
||||
for(i = 0; i < MAXNUMSTAGES; i++){
|
||||
d3dRaster[i] = nil;
|
||||
d3ddevice->SetTexture(i, nil);
|
||||
Raster *raster = rwStateCache.texstage[i].raster;
|
||||
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++)
|
||||
if(validStates[s])
|
||||
@ -197,146 +251,25 @@ resetD3d9Device(void)
|
||||
static void
|
||||
setVertexAlpha(bool32 enable)
|
||||
{
|
||||
if(vertexAlpha != enable){
|
||||
if(!textureAlpha){
|
||||
if(rwStateCache.vertexAlpha != enable){
|
||||
if(!rwStateCache.textureAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, 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
|
||||
setRasterStage(uint32 stage, Raster *raster)
|
||||
{
|
||||
bool32 alpha;
|
||||
D3dRaster *d3draster = nil;
|
||||
if(raster != d3dRaster[stage]){
|
||||
d3dRaster[stage] = raster;
|
||||
if(raster != rwStateCache.texstage[stage].raster){
|
||||
rwStateCache.texstage[stage].raster = raster;
|
||||
if(raster){
|
||||
assert(raster->platform == PLATFORM_D3D8 ||
|
||||
raster->platform == PLATFORM_D3D9);
|
||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||
d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
alpha = d3draster->hasAlpha;
|
||||
@ -345,9 +278,9 @@ setRasterStage(uint32 stage, Raster *raster)
|
||||
alpha = 0;
|
||||
}
|
||||
if(stage == 0){
|
||||
if(textureAlpha != alpha){
|
||||
textureAlpha = alpha;
|
||||
if(!vertexAlpha){
|
||||
if(rwStateCache.textureAlpha != alpha){
|
||||
rwStateCache.textureAlpha = alpha;
|
||||
if(!rwStateCache.vertexAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, 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
|
||||
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){
|
||||
setRasterStage(stage, nil);
|
||||
return;
|
||||
}
|
||||
if(tex->raster){
|
||||
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()]);
|
||||
setFilterMode(stage, tex->getFilter());
|
||||
setAddressU(stage, tex->getAddressU());
|
||||
setAddressV(stage, tex->getAddressV());
|
||||
}
|
||||
setRasterStage(stage, tex->raster);
|
||||
}
|
||||
@ -428,6 +379,152 @@ setMaterial(SurfaceProperties surfProps, rw::RGBA color)
|
||||
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
|
||||
|
||||
void
|
||||
@ -750,26 +847,26 @@ initD3D(void)
|
||||
// TODO: do some real stuff here
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||
alphafunc = ALPHAGREATEREQUAL;
|
||||
rwStateCache.alphafunc = ALPHAGREATEREQUAL;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10);
|
||||
alpharef = 10;
|
||||
rwStateCache.alpharef = 10;
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
fogenable = 0;
|
||||
rwStateCache.fogenable = 0;
|
||||
d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
|
||||
// TODO: more fog stuff
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
cullmode = CULLNONE;
|
||||
rwStateCache.cullmode = CULLNONE;
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
srcblend = BLENDSRCALPHA;
|
||||
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
destblend = BLENDINVSRCALPHA;
|
||||
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
|
||||
vertexAlpha = 0;
|
||||
textureAlpha = 0;
|
||||
rwStateCache.vertexAlpha = 0;
|
||||
rwStateCache.textureAlpha = 0;
|
||||
|
||||
setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
// setTextureStageState(0, D3DTSS_CONSTANT, 0xFFFFFFFF);
|
||||
|
@ -76,7 +76,6 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
d3ddevice->SetStreamSource(0, im2dvertbuf, 0, sizeof(Im2DVertex));
|
||||
d3ddevice->SetIndices(im2dindbuf);
|
||||
d3ddevice->SetVertexDeclaration(im2ddecl);
|
||||
d3d::setTexture(0, engine->imtexture);
|
||||
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
@ -175,7 +174,6 @@ im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
|
||||
unlockIndices(im3dindbuf);
|
||||
|
||||
d3ddevice->SetIndices(im3dindbuf);
|
||||
d3d::setTexture(0, engine->imtexture);
|
||||
setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
setTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
|
@ -112,7 +112,6 @@ Engine::open(void)
|
||||
engine = (Engine*)rwNew(Engine::s_plglist.size, MEMDUR_GLOBAL);
|
||||
engine->currentCamera = nil;
|
||||
engine->currentWorld = nil;
|
||||
engine->imtexture = nil;
|
||||
|
||||
// Initialize device
|
||||
// Device and possibly OS specific!
|
||||
@ -207,8 +206,8 @@ void endUpdate(Camera*) { }
|
||||
void clearCamera(Camera*,RGBA*,uint32) { }
|
||||
void showRaster(Raster*) { }
|
||||
|
||||
void setRenderState(int32, uint32) { }
|
||||
uint32 getRenderState(int32) { return 0; }
|
||||
void setRenderState(int32, void*) { }
|
||||
void *getRenderState(int32) { return 0; }
|
||||
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType, void*, int32, void*, int32) { }
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
@ -83,15 +84,28 @@ static bool32 stateDirty = 1;
|
||||
static bool32 sceneDirty = 1;
|
||||
static bool32 objectDirty = 1;
|
||||
|
||||
// cached render states
|
||||
static bool32 vertexAlpha;
|
||||
static uint32 alphaTestEnable;
|
||||
static uint32 alphaFunc;
|
||||
static bool32 textureAlpha;
|
||||
static uint32 srcblend, destblend;
|
||||
static uint32 zwrite;
|
||||
static uint32 ztest;
|
||||
static uint32 cullmode;
|
||||
struct RwRasterStateCache {
|
||||
Raster *raster;
|
||||
Texture::Addressing addressingU;
|
||||
Texture::Addressing addressingV;
|
||||
Texture::FilterMode filter;
|
||||
};
|
||||
|
||||
#define MAXNUMSTAGES 8
|
||||
|
||||
// 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;
|
||||
|
||||
@ -113,9 +127,9 @@ static void
|
||||
setAlphaTest(bool32 enable)
|
||||
{
|
||||
uint32 shaderfunc;
|
||||
if(alphaTestEnable != enable){
|
||||
alphaTestEnable = enable;
|
||||
shaderfunc = alphaTestEnable ? alphaFunc : ALPHAALWAYS;
|
||||
if(rwStateCache.alphaTestEnable != enable){
|
||||
rwStateCache.alphaTestEnable = enable;
|
||||
shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS;
|
||||
if(uniformState.alphaFunc != shaderfunc){
|
||||
uniformState.alphaFunc = shaderfunc;
|
||||
stateDirty = 1;
|
||||
@ -127,9 +141,9 @@ static void
|
||||
setAlphaTestFunction(uint32 function)
|
||||
{
|
||||
uint32 shaderfunc;
|
||||
if(alphaFunc != function){
|
||||
alphaFunc = function;
|
||||
shaderfunc = alphaTestEnable ? alphaFunc : ALPHAALWAYS;
|
||||
if(rwStateCache.alphaFunc != function){
|
||||
rwStateCache.alphaFunc = function;
|
||||
shaderfunc = rwStateCache.alphaTestEnable ? rwStateCache.alphaFunc : ALPHAALWAYS;
|
||||
if(uniformState.alphaFunc != shaderfunc){
|
||||
uniformState.alphaFunc = shaderfunc;
|
||||
stateDirty = 1;
|
||||
@ -140,47 +154,201 @@ setAlphaTestFunction(uint32 function)
|
||||
static void
|
||||
setVertexAlpha(bool32 enable)
|
||||
{
|
||||
if(vertexAlpha != enable){
|
||||
if(!textureAlpha){
|
||||
if(rwStateCache.vertexAlpha != enable){
|
||||
if(!rwStateCache.textureAlpha){
|
||||
(enable ? glEnable : glDisable)(GL_BLEND);
|
||||
setAlphaTest(enable);
|
||||
}
|
||||
vertexAlpha = enable;
|
||||
rwStateCache.vertexAlpha = enable;
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
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(value);
|
||||
break;
|
||||
case SRCBLEND:
|
||||
if(srcblend != value){
|
||||
srcblend = value;
|
||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
||||
if(rwStateCache.srcblend != value){
|
||||
rwStateCache.srcblend = value;
|
||||
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||
}
|
||||
break;
|
||||
case DESTBLEND:
|
||||
if(destblend != value){
|
||||
destblend = value;
|
||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
||||
if(rwStateCache.destblend != value){
|
||||
rwStateCache.destblend = value;
|
||||
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||
}
|
||||
break;
|
||||
case ZTESTENABLE:
|
||||
if(ztest != value){
|
||||
ztest = value;
|
||||
if(ztest)
|
||||
if(rwStateCache.ztest != value){
|
||||
rwStateCache.ztest = value;
|
||||
if(rwStateCache.ztest)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
break;
|
||||
case ZWRITEENABLE:
|
||||
if(zwrite != (value ? GL_TRUE : GL_FALSE)){
|
||||
zwrite = value ? GL_TRUE : GL_FALSE;
|
||||
glDepthMask(zwrite);
|
||||
if(rwStateCache.zwrite != (value ? GL_TRUE : GL_FALSE)){
|
||||
rwStateCache.zwrite = value ? GL_TRUE : GL_FALSE;
|
||||
glDepthMask(rwStateCache.zwrite);
|
||||
}
|
||||
break;
|
||||
case FOGENABLE:
|
||||
@ -200,13 +368,13 @@ setRenderState(int32 state, uint32 value)
|
||||
stateDirty = 1;
|
||||
break;
|
||||
case CULLMODE:
|
||||
if(cullmode != value){
|
||||
cullmode = value;
|
||||
if(cullmode == CULLNONE)
|
||||
if(rwStateCache.cullmode != value){
|
||||
rwStateCache.cullmode = value;
|
||||
if(rwStateCache.cullmode == CULLNONE)
|
||||
glDisable(GL_CULL_FACE);
|
||||
else{
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(cullmode == CULLBACK ? GL_BACK : GL_FRONT);
|
||||
glCullFace(rwStateCache.cullmode == CULLBACK ? GL_BACK : GL_FRONT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -223,41 +391,72 @@ setRenderState(int32 state, uint32 value)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
static void*
|
||||
getRenderState(int32 state)
|
||||
{
|
||||
uint32 val;
|
||||
RGBA rgba;
|
||||
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:
|
||||
return vertexAlpha;
|
||||
val = rwStateCache.vertexAlpha;
|
||||
break;
|
||||
case SRCBLEND:
|
||||
return srcblend;
|
||||
val = rwStateCache.srcblend;
|
||||
break;
|
||||
case DESTBLEND:
|
||||
return destblend;
|
||||
val = rwStateCache.destblend;
|
||||
break;
|
||||
case ZTESTENABLE:
|
||||
return ztest;
|
||||
val = rwStateCache.ztest;
|
||||
break;
|
||||
case ZWRITEENABLE:
|
||||
return zwrite;
|
||||
val = rwStateCache.zwrite;
|
||||
break;
|
||||
case FOGENABLE:
|
||||
return uniformState.fogEnable;
|
||||
val = uniformState.fogEnable;
|
||||
break;
|
||||
case 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:
|
||||
return cullmode;
|
||||
val = rwStateCache.cullmode;
|
||||
break;
|
||||
|
||||
case ALPHATESTFUNC:
|
||||
return alphaFunc;
|
||||
val = rwStateCache.alphaFunc;
|
||||
break;
|
||||
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
|
||||
resetRenderState(void)
|
||||
{
|
||||
alphaFunc = ALPHAGREATEREQUAL;
|
||||
{
|
||||
rwStateCache.alphaFunc = ALPHAGREATEREQUAL;
|
||||
uniformState.alphaFunc = 0;
|
||||
uniformState.alphaRef = 10.0f/255.0f;
|
||||
uniformState.fogEnable = 0;
|
||||
@ -265,28 +464,28 @@ resetRenderState(void)
|
||||
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
stateDirty = 1;
|
||||
|
||||
vertexAlpha = 0;
|
||||
textureAlpha = 0;
|
||||
rwStateCache.vertexAlpha = 0;
|
||||
rwStateCache.textureAlpha = 0;
|
||||
glDisable(GL_BLEND);
|
||||
alphaTestEnable = 0;
|
||||
rwStateCache.alphaTestEnable = 0;
|
||||
|
||||
srcblend = BLENDSRCALPHA;
|
||||
destblend = BLENDINVSRCALPHA;
|
||||
glBlendFunc(blendMap[srcblend], blendMap[destblend]);
|
||||
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||
|
||||
zwrite = GL_TRUE;
|
||||
glDepthMask(zwrite);
|
||||
rwStateCache.zwrite = GL_TRUE;
|
||||
glDepthMask(rwStateCache.zwrite);
|
||||
|
||||
ztest = 1;
|
||||
rwStateCache.ztest = 1;
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
cullmode = CULLNONE;
|
||||
rwStateCache.cullmode = CULLNONE;
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
for(int i = 0; i < 8; i++){
|
||||
for(int i = 0; i < MAXNUMSTAGES; i++){
|
||||
glActiveTexture(GL_TEXTURE0+i);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,61 +546,6 @@ setViewMatrix(float32 *mat)
|
||||
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
|
||||
flushCache(void)
|
||||
{
|
||||
@ -593,6 +737,14 @@ initOpenGL(void)
|
||||
|
||||
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();
|
||||
|
||||
glGenVertexArrays(1, &vao);
|
||||
@ -619,14 +771,6 @@ initOpenGL(void)
|
||||
GL_DYNAMIC_DRAW);
|
||||
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_fs_gl3.inc"
|
||||
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
|
||||
|
@ -100,7 +100,6 @@ im2DRenderIndexedPrimitive(PrimitiveType primType,
|
||||
setAttribPointers(im2dattribDesc, 3);
|
||||
|
||||
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||
setTexture(0, engine->imtexture);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(primTypeMap[primType], numIndices,
|
||||
@ -179,8 +178,6 @@ im3DRenderIndexed(PrimitiveType primType, void *indices, int32 numIndices)
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*2,
|
||||
indices, GL_DYNAMIC_DRAW);
|
||||
|
||||
setTexture(0, engine->imtexture);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(primTypeMap[primType], numIndices,
|
||||
GL_UNSIGNED_SHORT, nil);
|
||||
|
@ -86,7 +86,9 @@ rasterCreate(Raster *raster)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat,
|
||||
raster->width, raster->height,
|
||||
0, natras->format, natras->type, nil);
|
||||
natras->filterAddressing = ~0;
|
||||
natras->filterMode = 0;
|
||||
natras->addressU = 0;
|
||||
natras->addressV = 0;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#endif
|
||||
|
@ -172,7 +172,9 @@ struct Gl3Raster
|
||||
|
||||
bool32 hasAlpha;
|
||||
// cached filtermode and addressing
|
||||
uint32 filterAddressing;
|
||||
uint8 filterMode;
|
||||
uint8 addressU;
|
||||
uint8 addressV;
|
||||
};
|
||||
|
||||
void registerNativeRaster(void);
|
||||
|
@ -33,6 +33,7 @@ Image::create(int32 width, int32 height, int32 depth)
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->depth = depth;
|
||||
img->bpp = depth < 8 ? 1 : depth/8;
|
||||
img->stride = 0;
|
||||
img->pixels = nil;
|
||||
img->palette = nil;
|
||||
@ -50,7 +51,7 @@ void
|
||||
Image::allocate(void)
|
||||
{
|
||||
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->flags |= 1;
|
||||
}
|
||||
|
33
src/prim.cpp
33
src/prim.cpp
@ -12,6 +12,31 @@
|
||||
|
||||
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
|
||||
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 {
|
||||
|
||||
void SetRenderState(int32 state, uint32 value){
|
||||
engine->device.setRenderState(state, (void*)(uintptr)value); }
|
||||
|
||||
void SetRenderStatePtr(int32 state, void *value){
|
||||
engine->device.setRenderState(state, value); }
|
||||
|
||||
uint32 GetRenderState(int32 state){
|
||||
return (uint32)(uintptr)engine->device.getRenderState(state); }
|
||||
|
||||
void *GetRenderStatePtr(int32 state){
|
||||
return engine->device.getRenderState(state); }
|
||||
|
||||
// Im2D
|
||||
@ -17,7 +23,7 @@ uint32 GetRenderState(int32 state){
|
||||
namespace im2d {
|
||||
|
||||
float32 GetNearZ(void) { return engine->device.zNear; }
|
||||
float32 GetFarZ(void) { return engine->device.zNear; }
|
||||
float32 GetFarZ(void) { return engine->device.zFar; }
|
||||
void
|
||||
RenderIndexedPrimitive(PrimitiveType type, void *verts, int32 numVerts, void *indices, int32 numIndices)
|
||||
{
|
||||
|
@ -384,7 +384,10 @@ struct BBox
|
||||
V3d sup;
|
||||
V3d inf;
|
||||
|
||||
void initialize(V3d *point);
|
||||
void addPoint(V3d *point);
|
||||
void calculate(V3d *points, int32 n);
|
||||
bool containsPoint(V3d *point);
|
||||
};
|
||||
|
||||
enum PrimitiveType
|
||||
|
@ -29,12 +29,12 @@ class ObjPipeline;
|
||||
struct Device
|
||||
{
|
||||
float32 zNear, zFar;
|
||||
void (*beginUpdate)(Camera*);
|
||||
void (*endUpdate)(Camera*);
|
||||
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
|
||||
void (*showRaster)(Raster *raster);
|
||||
void (*setRenderState)(int32 state, uint32 value);
|
||||
uint32 (*getRenderState)(int32 state);
|
||||
void (*beginUpdate)(Camera*);
|
||||
void (*endUpdate)(Camera*);
|
||||
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
|
||||
void (*showRaster)(Raster *raster);
|
||||
void (*setRenderState)(int32 state, void *value);
|
||||
void *(*getRenderState)(int32 state);
|
||||
|
||||
// TODO: render line
|
||||
// TODO: render triangle
|
||||
@ -110,7 +110,6 @@ struct Engine
|
||||
};
|
||||
void *currentCamera;
|
||||
void *currentWorld;
|
||||
Texture *imtexture;
|
||||
LinkList frameDirtyList;
|
||||
|
||||
// Dynamically allocated because of plugins
|
||||
@ -154,8 +153,8 @@ namespace null {
|
||||
void clearCamera(Camera*, RGBA *col, uint32 mode);
|
||||
void showRaster(Raster*);
|
||||
|
||||
void setRenderState(int32 state, uint32 value);
|
||||
uint32 getRenderState(int32 state);
|
||||
void setRenderState(int32 state, void *value);
|
||||
void *getRenderState(int32 state);
|
||||
|
||||
void rasterCreate(Raster*);
|
||||
uint8 *rasterLock(Raster*, int32 level);
|
||||
|
@ -125,6 +125,7 @@ struct Image
|
||||
int32 flags;
|
||||
int32 width, height;
|
||||
int32 depth;
|
||||
int32 bpp; // bytes per pixel
|
||||
int32 stride;
|
||||
uint8 *pixels;
|
||||
uint8 *palette;
|
||||
|
@ -4,7 +4,12 @@ namespace rw {
|
||||
|
||||
enum RenderState
|
||||
{
|
||||
VERTEXALPHA = 0,
|
||||
TEXTURERASTER,
|
||||
TEXTUREADDRESS,
|
||||
TEXTUREADDRESSU,
|
||||
TEXTUREADDRESSV,
|
||||
TEXTUREFILTER,
|
||||
VERTEXALPHA,
|
||||
SRCBLEND,
|
||||
DESTBLEND,
|
||||
ZTESTENABLE,
|
||||
@ -53,7 +58,9 @@ enum BlendFunction
|
||||
};
|
||||
|
||||
void SetRenderState(int32 state, uint32 value);
|
||||
void SetRenderStatePtr(int32 state, void *value);
|
||||
uint32 GetRenderState(int32 state);
|
||||
void *GetRenderStatePtr(int32 state);
|
||||
|
||||
// Im2D
|
||||
|
||||
|
@ -262,6 +262,8 @@ defaultFindCB(const char *name)
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
// TODO: actually read the mask!
|
||||
static Texture*
|
||||
defaultReadCB(const char *name, const char *mask)
|
||||
{
|
||||
|
@ -96,7 +96,11 @@ printScreen(const char *s, float32 x, float32 y)
|
||||
|
||||
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,
|
||||
vertices, curVert, indices, curIndex);
|
||||
|
||||
|
@ -263,7 +263,9 @@ im2dtest(void)
|
||||
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::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
&verts, 4, &indices, 4);
|
||||
@ -305,7 +307,9 @@ im3dtest(void)
|
||||
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);
|
||||
@ -325,9 +329,9 @@ Draw(float timeDelta)
|
||||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
// Scene.clump->render();
|
||||
Scene.clump->render();
|
||||
// im2dtest();
|
||||
tlTest(Scene.clump);
|
||||
// tlTest(Scene.clump);
|
||||
// im3dtest();
|
||||
// printScreen("Hello, World!", 10, 10);
|
||||
|
||||
|
@ -116,7 +116,15 @@ drawAtomic(Atomic *a)
|
||||
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,
|
||||
im2dverts, g->numVertices, m[i].indices, m[i].numIndices);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user