From 2cffb3f494e37faf1a6cc37c28da2c0dde700cad Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 2 Jul 2018 07:01:34 +0200 Subject: [PATCH] implemented texture raster renderstates --- skeleton/imgui/imgui_impl_rw.cpp | 9 +- src/d3d/d3d.cpp | 2 +- src/d3d/d3ddevice.cpp | 437 +++++++++++++++++++------------ src/d3d/d3dimmed.cpp | 2 - src/engine.cpp | 5 +- src/gl/gl3device.cpp | 392 ++++++++++++++++++--------- src/gl/gl3immed.cpp | 3 - src/gl/gl3raster.cpp | 4 +- src/gl/rwgl3.h | 4 +- src/image.cpp | 3 +- src/prim.cpp | 33 +++ src/render.cpp | 8 +- src/rwbase.h | 3 + src/rwengine.h | 17 +- src/rwobjects.h | 1 + src/rwrender.h | 9 +- src/texture.cpp | 2 + tools/clumpview/font.cpp | 6 +- tools/clumpview/main.cpp | 12 +- tools/clumpview/tests.cpp | 10 +- 20 files changed, 638 insertions(+), 324 deletions(-) diff --git a/skeleton/imgui/imgui_impl_rw.cpp b/skeleton/imgui/imgui_impl_rw.cpp index c326eba..6ea726f 100644 --- a/skeleton/imgui/imgui_impl_rw.cpp +++ b/skeleton/imgui/imgui_impl_rw.cpp @@ -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); diff --git a/src/d3d/d3d.cpp b/src/d3d/d3d.cpp index 31e3c59..c5c5153 100644 --- a/src/d3d/d3d.cpp +++ b/src/d3d/d3d.cpp @@ -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) diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index dbf677e..2177161 100755 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -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); diff --git a/src/d3d/d3dimmed.cpp b/src/d3d/d3dimmed.cpp index bd1e1ab..3d9cdfb 100644 --- a/src/d3d/d3dimmed.cpp +++ b/src/d3d/d3dimmed.cpp @@ -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); diff --git a/src/engine.cpp b/src/engine.cpp index 1af90e1..3a98fcf 100755 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -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) { } diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index b4c328a..b05d3b7 100755 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #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); diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp index 892f6dc..1d24fb0 100644 --- a/src/gl/gl3immed.cpp +++ b/src/gl/gl3immed.cpp @@ -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); diff --git a/src/gl/gl3raster.cpp b/src/gl/gl3raster.cpp index 99af13e..a3f7591 100644 --- a/src/gl/gl3raster.cpp +++ b/src/gl/gl3raster.cpp @@ -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 diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index 4a917cc..ac3150a 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -172,7 +172,9 @@ struct Gl3Raster bool32 hasAlpha; // cached filtermode and addressing - uint32 filterAddressing; + uint8 filterMode; + uint8 addressU; + uint8 addressV; }; void registerNativeRaster(void); diff --git a/src/image.cpp b/src/image.cpp index ab4cf18..7316b4a 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -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; } diff --git a/src/prim.cpp b/src/prim.cpp index 4c94a99..3735342 100644 --- a/src/prim.cpp +++ b/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; +} + } diff --git a/src/render.cpp b/src/render.cpp index 656f13d..0bdefc8 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -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) { diff --git a/src/rwbase.h b/src/rwbase.h index 96a6abe..1e871bc 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -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 diff --git a/src/rwengine.h b/src/rwengine.h index 3bf30fe..d886b96 100755 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -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); diff --git a/src/rwobjects.h b/src/rwobjects.h index 87a2420..017c4ee 100755 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -125,6 +125,7 @@ struct Image int32 flags; int32 width, height; int32 depth; + int32 bpp; // bytes per pixel int32 stride; uint8 *pixels; uint8 *palette; diff --git a/src/rwrender.h b/src/rwrender.h index 0a1fa81..207c232 100644 --- a/src/rwrender.h +++ b/src/rwrender.h @@ -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 diff --git a/src/texture.cpp b/src/texture.cpp index e3d19da..0a9517c 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -262,6 +262,8 @@ defaultFindCB(const char *name) return nil; } + +// TODO: actually read the mask! static Texture* defaultReadCB(const char *name, const char *mask) { diff --git a/tools/clumpview/font.cpp b/tools/clumpview/font.cpp index 86c8ecb..f95a01e 100644 --- a/tools/clumpview/font.cpp +++ b/tools/clumpview/font.cpp @@ -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); diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index 186cd23..32ef445 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -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); diff --git a/tools/clumpview/tests.cpp b/tools/clumpview/tests.cpp index b8158f5..2e52d7e 100644 --- a/tools/clumpview/tests.cpp +++ b/tools/clumpview/tests.cpp @@ -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); }