anisotropy plugin

This commit is contained in:
aap 2021-01-21 22:02:49 +01:00
parent 9260bddc66
commit 60a5ace163
9 changed files with 133 additions and 17 deletions

View File

@ -471,6 +471,19 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
Raster *ras = nil; Raster *ras = nil;
for(int i = 0; i < numLevels; i++){ for(int i = 0; i < numLevels; i++){
uint32 size = stream->readU32();
// don't read levels that don't exist
if(ras && i >= ras->getNumLevels()){
stream->seek(size);
continue;
}
// one allocation is enough, first level is largest
if(data == nil)
data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE);
stream->read8(data, size);
if(ras){ if(ras){
ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH); ras->lock(i, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
img->width = ras->width; img->width = ras->width;
@ -478,13 +491,6 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
img->stride = img->width*img->bpp; img->stride = img->width*img->bpp;
} }
uint32 size = stream->readU32();
// one allocation is enough, first level is largest
if(data == nil)
data = rwNewT(uint8, size, MEMDUR_FUNCTION | ID_IMAGE);
stream->read8(data, size);
if(format & (Raster::PAL4 | Raster::PAL8)){ if(format & (Raster::PAL4 | Raster::PAL8)){
uint8 *idx = data; uint8 *idx = data;
uint8 *pixels = img->pixels; uint8 *pixels = img->pixels;

View File

@ -63,6 +63,7 @@ struct RwRasterStateCache {
Texture::Addressing addressingU; Texture::Addressing addressingU;
Texture::Addressing addressingV; Texture::Addressing addressingV;
Texture::FilterMode filter; Texture::FilterMode filter;
int32 maxAniso;
}; };
#define MAXNUMSTAGES 8 #define MAXNUMSTAGES 8
@ -342,7 +343,10 @@ restoreD3d9Device(void)
setSamplerState(i, D3DSAMP_ADDRESSU, addressConvMap[rwStateCache.texstage[i].addressingU]); setSamplerState(i, D3DSAMP_ADDRESSU, addressConvMap[rwStateCache.texstage[i].addressingU]);
setSamplerState(i, D3DSAMP_ADDRESSV, addressConvMap[rwStateCache.texstage[i].addressingV]); setSamplerState(i, D3DSAMP_ADDRESSV, addressConvMap[rwStateCache.texstage[i].addressingV]);
setSamplerState(i, D3DSAMP_MAGFILTER, filterConvMap[rwStateCache.texstage[i].filter]); setSamplerState(i, D3DSAMP_MAGFILTER, filterConvMap[rwStateCache.texstage[i].filter]);
if(rwStateCache.texstage[i].maxAniso == 1)
setSamplerState(i, D3DSAMP_MINFILTER, filterConvMap[rwStateCache.texstage[i].filter]); setSamplerState(i, D3DSAMP_MINFILTER, filterConvMap[rwStateCache.texstage[i].filter]);
else
setSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
setSamplerState(i, D3DSAMP_MIPFILTER, filterConvMap_MIP[rwStateCache.texstage[i].filter]); setSamplerState(i, D3DSAMP_MIPFILTER, filterConvMap_MIP[rwStateCache.texstage[i].filter]);
} }
for(s = 0; s < MAXNUMSTATES; s++) for(s = 0; s < MAXNUMSTATES; s++)
@ -474,14 +478,25 @@ setRasterStage(uint32 stage, Raster *raster)
} }
static void static void
setFilterMode(uint32 stage, int32 filter) setFilterMode(uint32 stage, int32 filter, int32 maxAniso = 1)
{ {
if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){ if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){
rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter; rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter;
setSamplerState(stage, D3DSAMP_MAGFILTER, filterConvMap[filter]); setSamplerState(stage, D3DSAMP_MAGFILTER, filterConvMap[filter]);
if(maxAniso == 1)
setSamplerState(stage, D3DSAMP_MINFILTER, filterConvMap[filter]); setSamplerState(stage, D3DSAMP_MINFILTER, filterConvMap[filter]);
else
setSamplerState(stage, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
setSamplerState(stage, D3DSAMP_MIPFILTER, filterConvMap_MIP[filter]); setSamplerState(stage, D3DSAMP_MIPFILTER, filterConvMap_MIP[filter]);
} }
if(rwStateCache.texstage[stage].maxAniso != maxAniso){
rwStateCache.texstage[stage].maxAniso = maxAniso;
if(maxAniso == 1)
setSamplerState(stage, D3DSAMP_MINFILTER, filterConvMap[filter]);
else
setSamplerState(stage, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
setSamplerState(stage, D3DSAMP_MAXANISOTROPY, maxAniso);
}
} }
static void static void
@ -510,7 +525,7 @@ setTexture(uint32 stage, Texture *tex)
return; return;
} }
if(tex->raster){ if(tex->raster){
setFilterMode(stage, tex->getFilter()); setFilterMode(stage, tex->getFilter(), tex->getMaxAnisotropy());
setAddressU(stage, tex->getAddressU()); setAddressU(stage, tex->getAddressU());
setAddressV(stage, tex->getAddressV()); setAddressV(stage, tex->getAddressV());
} }

View File

@ -527,7 +527,7 @@ static GLint addressConvMap[] = {
}; };
static void static void
setFilterMode(uint32 stage, int32 filter) setFilterMode(uint32 stage, int32 filter, int32 maxAniso = 1)
{ {
if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){ if(rwStateCache.texstage[stage].filter != (Texture::FilterMode)filter){
rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter; rwStateCache.texstage[stage].filter = (Texture::FilterMode)filter;
@ -545,6 +545,11 @@ setFilterMode(uint32 stage, int32 filter)
} }
natras->filterMode = filter; natras->filterMode = filter;
} }
if(natras->maxAnisotropy != maxAniso){
setActiveTexture(stage);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)maxAniso);
natras->maxAnisotropy = maxAniso;
}
} }
} }
} }
@ -675,7 +680,7 @@ setTexture(int32 stage, Texture *tex)
return; return;
} }
setRasterStageOnly(stage, tex->raster); setRasterStageOnly(stage, tex->raster);
setFilterMode(stage, tex->getFilter()); setFilterMode(stage, tex->getFilter(), tex->getMaxAnisotropy());
setAddressU(stage, tex->getAddressU()); setAddressU(stage, tex->getAddressU());
setAddressV(stage, tex->getAddressV()); setAddressV(stage, tex->getAddressV());
} }
@ -1787,6 +1792,8 @@ initOpenGL(void)
// printf("%d %s\n", i, ext); // printf("%d %s\n", i, ext);
} }
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl3Caps.maxAnisotropy);
if(gl3Caps.gles){ if(gl3Caps.gles){
if(gl3Caps.glversion >= 30) if(gl3Caps.glversion >= 30)
shaderDecl = shaderDecl310es; shaderDecl = shaderDecl310es;

View File

@ -132,9 +132,7 @@ rasterCreateTexture(Raster *raster)
natras->filterMode = 0; natras->filterMode = 0;
natras->addressU = 0; natras->addressU = 0;
natras->addressV = 0; natras->addressV = 0;
natras->maxAnisotropy = 1;
// TEST
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
bindTexture(prev); bindTexture(prev);
return raster; return raster;
@ -196,6 +194,7 @@ rasterCreateCameraTexture(Raster *raster)
natras->filterMode = 0; natras->filterMode = 0;
natras->addressU = 0; natras->addressU = 0;
natras->addressV = 0; natras->addressV = 0;
natras->maxAnisotropy = 1;
bindTexture(prev); bindTexture(prev);
@ -259,6 +258,7 @@ rasterCreateZbuffer(Raster *raster)
natras->filterMode = 0; natras->filterMode = 0;
natras->addressU = 0; natras->addressU = 0;
natras->addressV = 0; natras->addressV = 0;
natras->maxAnisotropy = 1;
bindTexture(prev); bindTexture(prev);
} }
@ -329,6 +329,7 @@ allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha)
natras->filterMode = 0; natras->filterMode = 0;
natras->addressU = 0; natras->addressU = 0;
natras->addressV = 0; natras->addressV = 0;
natras->maxAnisotropy = 1;
bindTexture(prev); bindTexture(prev);

View File

@ -239,6 +239,7 @@ struct Gl3Raster
uint8 filterMode; uint8 filterMode;
uint8 addressU; uint8 addressU;
uint8 addressV; uint8 addressV;
int32 maxAnisotropy;
uint32 fbo; // used for camera texture only! uint32 fbo; // used for camera texture only!
Raster *fboMate; // color or zbuffer raster mate of this one Raster *fboMate; // color or zbuffer raster mate of this one
@ -251,6 +252,7 @@ struct Gl3Caps
int glversion; int glversion;
bool dxtSupported; bool dxtSupported;
bool astcSupported; // not used yet bool astcSupported; // not used yet
float maxAnisotropy;
}; };
extern Gl3Caps gl3Caps; extern Gl3Caps gl3Caps;
// GLES can't read back textures very nicely. // GLES can't read back textures very nicely.

View File

@ -408,6 +408,7 @@ registerHAnimPlugin(void)
Frame::registerPluginStream(ID_HANIM, Frame::registerPluginStream(ID_HANIM,
readHAnim, readHAnim,
writeHAnim, writeHAnim,
getSizeHAnim);} getSizeHAnim);
}
} }

View File

@ -592,6 +592,7 @@ enum PluginID
ID_HANIM = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E), ID_HANIM = MAKEPLUGINID(VEND_CRITERIONTK, 0x1E),
ID_USERDATA = MAKEPLUGINID(VEND_CRITERIONTK, 0x1F), ID_USERDATA = MAKEPLUGINID(VEND_CRITERIONTK, 0x1F),
ID_MATFX = MAKEPLUGINID(VEND_CRITERIONTK, 0x20), ID_MATFX = MAKEPLUGINID(VEND_CRITERIONTK, 0x20),
ID_ANISOT = MAKEPLUGINID(VEND_CRITERIONTK, 0x27),
ID_PDS = MAKEPLUGINID(VEND_CRITERIONTK, 0x31), ID_PDS = MAKEPLUGINID(VEND_CRITERIONTK, 0x31),
ID_ADC = MAKEPLUGINID(VEND_CRITERIONTK, 0x34), ID_ADC = MAKEPLUGINID(VEND_CRITERIONTK, 0x34),
ID_UVANIMATION = MAKEPLUGINID(VEND_CRITERIONTK, 0x35), ID_UVANIMATION = MAKEPLUGINID(VEND_CRITERIONTK, 0x35),

View File

@ -404,11 +404,18 @@ struct Texture
static bool32 getMipmapping(void); static bool32 getMipmapping(void);
static bool32 getAutoMipmapping(void); static bool32 getAutoMipmapping(void);
void setMaxAnisotropy(int32 maxaniso); // only if plugin is attached
int32 getMaxAnisotropy(void);
#ifndef RWPUBLIC #ifndef RWPUBLIC
static void registerModule(void); static void registerModule(void);
#endif #endif
}; };
extern int32 anisotOffset;
#define GETANISOTROPYEXT(texture) PLUGINOFFSET(int32, texture, rw::anisotOffset)
void registerAnisotropyPlugin(void);
int32 getMaxSupportedMaxAnisotropy(void);
struct SurfaceProperties struct SurfaceProperties
{ {

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#define WITH_D3D
#include "rwbase.h" #include "rwbase.h"
#include "rwerror.h" #include "rwerror.h"
#include "rwplg.h" #include "rwplg.h"
@ -14,6 +15,7 @@
#include "d3d/rwxbox.h" #include "d3d/rwxbox.h"
#include "d3d/rwd3d8.h" #include "d3d/rwd3d8.h"
#include "d3d/rwd3d9.h" #include "d3d/rwd3d9.h"
#include "d3d/rwd3dimpl.h"
#include "gl/rwgl3.h" #include "gl/rwgl3.h"
#define PLUGIN_ID 0 #define PLUGIN_ID 0
@ -517,4 +519,78 @@ Texture::streamGetSizeNative(void)
return 0; return 0;
} }
int32 anisotOffset;
static void*
createAnisot(void *object, int32 offset, int32)
{
*GETANISOTROPYEXT(object) = 1;
return object;
}
static void*
copyAnisot(void *dst, void *src, int32 offset, int32)
{
*GETANISOTROPYEXT(dst) = *GETANISOTROPYEXT(src);
return dst;
}
static Stream*
readAnisot(Stream *stream, int32, void *object, int32 offset, int32)
{
*GETANISOTROPYEXT(object) = stream->readI32();
return stream;
}
static Stream*
writeAnisot(Stream *stream, int32, void *object, int32 offset, int32)
{
stream->writeI32(*GETANISOTROPYEXT(object));
return stream;
}
static int32
getSizeAnisot(void *object, int32 offset, int32)
{
if(*GETANISOTROPYEXT(object) == 1)
return 0;
return sizeof(int32);
}
void
registerAnisotropyPlugin(void)
{
anisotOffset = Texture::registerPlugin(sizeof(int32), ID_ANISOT, createAnisot, nil, copyAnisot);
Texture::registerPluginStream(ID_ANISOT, readAnisot, writeAnisot, getSizeAnisot);
}
void
Texture::setMaxAnisotropy(int32 maxaniso)
{
if(anisotOffset > 0)
*GETANISOTROPYEXT(this) = maxaniso;
}
int32
Texture::getMaxAnisotropy(void)
{
if(anisotOffset > 0)
return *GETANISOTROPYEXT(this);
return 1;
}
int32
getMaxSupportedMaxAnisotropy(void)
{
#ifdef RW_D3D9
return d3d::d3d9Globals.caps.MaxAnisotropy;
#endif
#ifdef RW_GL3
return (int32)gl3::gl3Caps.maxAnisotropy;
#endif
return 1;
}
} }