mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Refactor sampler state parameters for textures.
This commit is contained in:
@@ -239,10 +239,7 @@ bool Canvas::loadVolatile()
|
||||
if (GLAD_ANGLE_texture_usage)
|
||||
glTexParameteri(gltype, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
|
||||
|
||||
setFilter(filter);
|
||||
setWrap(wrap);
|
||||
setMipmapSharpness(mipmapSharpness);
|
||||
setDepthSampleMode(depthCompareMode);
|
||||
setSamplerState(samplerState);
|
||||
|
||||
while (glGetError() != GL_NO_ERROR)
|
||||
/* Clear the error buffer. */;
|
||||
@@ -320,113 +317,30 @@ void Canvas::unloadVolatile()
|
||||
setGraphicsMemorySize(0);
|
||||
}
|
||||
|
||||
void Canvas::setFilter(const Texture::Filter &f)
|
||||
void Canvas::setSamplerState(const SamplerState &s)
|
||||
{
|
||||
Texture::setFilter(f);
|
||||
Texture::setSamplerState(s);
|
||||
|
||||
if (samplerState.depthSampleMode.hasValue && !gl.isDepthCompareSampleSupported())
|
||||
throw love::Exception("Depth comparison sampling in shaders is not supported on this system.");
|
||||
|
||||
if (!OpenGL::hasTextureFilteringSupport(getPixelFormat()))
|
||||
{
|
||||
filter.mag = filter.min = FILTER_NEAREST;
|
||||
samplerState.magFilter = samplerState.minFilter = SamplerState::FILTER_NEAREST;
|
||||
|
||||
if (filter.mipmap == FILTER_LINEAR)
|
||||
filter.mipmap = FILTER_NEAREST;
|
||||
if (samplerState.mipmapFilter == SamplerState::MIPMAP_FILTER_LINEAR)
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
gl.setTextureFilter(texType, filter);
|
||||
}
|
||||
|
||||
bool Canvas::setWrap(const Texture::Wrap &w)
|
||||
{
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
bool success = true;
|
||||
bool forceclamp = texType == TEXTURE_CUBE;
|
||||
wrap = w;
|
||||
|
||||
// If we only have limited NPOT support then the wrap mode must be CLAMP.
|
||||
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
|
||||
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight) || depth != nextP2(depth)))
|
||||
{
|
||||
forceclamp = true;
|
||||
}
|
||||
|
||||
if (forceclamp)
|
||||
{
|
||||
if (wrap.s != WRAP_CLAMP || wrap.t != WRAP_CLAMP || wrap.r != WRAP_CLAMP)
|
||||
success = false;
|
||||
|
||||
wrap.s = wrap.t = wrap.r = WRAP_CLAMP;
|
||||
}
|
||||
|
||||
if (!gl.isClampZeroOneTextureWrapSupported())
|
||||
{
|
||||
if (isClampZeroOrOne(wrap.s)) wrap.s = WRAP_CLAMP;
|
||||
if (isClampZeroOrOne(wrap.t)) wrap.t = WRAP_CLAMP;
|
||||
if (isClampZeroOrOne(wrap.r)) wrap.r = WRAP_CLAMP;
|
||||
samplerState.wrapU = samplerState.wrapV = samplerState.wrapW = SamplerState::WRAP_CLAMP;
|
||||
}
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
gl.setTextureWrap(texType, wrap);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Canvas::setMipmapSharpness(float sharpness)
|
||||
{
|
||||
if (!gl.isSamplerLODBiasSupported())
|
||||
return false;
|
||||
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
float maxbias = gl.getMaxLODBias();
|
||||
if (maxbias > 0.01f)
|
||||
maxbias -= 0.0f;
|
||||
|
||||
mipmapSharpness = std::min(std::max(sharpness, -maxbias), maxbias);
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
|
||||
// negative bias is sharper
|
||||
glTexParameterf(gl.getGLTextureType(texType), GL_TEXTURE_LOD_BIAS, -mipmapSharpness);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Canvas::setDepthSampleMode(Optional<CompareMode> mode)
|
||||
{
|
||||
Texture::setDepthSampleMode(mode);
|
||||
|
||||
bool supported = gl.isDepthCompareSampleSupported();
|
||||
|
||||
if (mode.hasValue)
|
||||
{
|
||||
if (!supported)
|
||||
throw love::Exception("Depth comparison sampling in shaders is not supported on this system.");
|
||||
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
gl.bindTextureToUnit(texType, texture, 0, false);
|
||||
GLenum gltextype = OpenGL::getGLTextureType(texType);
|
||||
|
||||
// See the comment in renderstate.h
|
||||
GLenum glmode = OpenGL::getGLCompareMode(getReversedCompareMode(mode.value));
|
||||
|
||||
glTexParameteri(gltextype, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(gltextype, GL_TEXTURE_COMPARE_FUNC, glmode);
|
||||
|
||||
}
|
||||
else if (isPixelFormatDepth(format) && supported)
|
||||
{
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
gl.bindTextureToUnit(texType, texture, 0, false);
|
||||
GLenum gltextype = OpenGL::getGLTextureType(texType);
|
||||
|
||||
glTexParameteri(gltextype, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
|
||||
depthCompareMode = mode;
|
||||
gl.setSamplerState(texType, samplerState);
|
||||
}
|
||||
|
||||
ptrdiff_t Canvas::getHandle() const
|
||||
|
||||
@@ -47,10 +47,7 @@ public:
|
||||
void unloadVolatile() override;
|
||||
|
||||
// Implements Texture.
|
||||
void setFilter(const Texture::Filter &f) override;
|
||||
bool setWrap(const Texture::Wrap &w) override;
|
||||
bool setMipmapSharpness(float sharpness) override;
|
||||
void setDepthSampleMode(Optional<CompareMode> mode) override;
|
||||
void setSamplerState(const SamplerState &s) override;
|
||||
ptrdiff_t getHandle() const override;
|
||||
|
||||
love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect) override;
|
||||
|
||||
@@ -1470,12 +1470,9 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
|
||||
glGenTextures(1, &texture);
|
||||
gl.bindTextureToUnit(TEXTURE_2D, texture, 0, false);
|
||||
|
||||
Texture::Filter f;
|
||||
f.min = f.mag = Texture::FILTER_NEAREST;
|
||||
gl.setTextureFilter(TEXTURE_2D, f);
|
||||
|
||||
Texture::Wrap w;
|
||||
gl.setTextureWrap(TEXTURE_2D, w);
|
||||
SamplerState s;
|
||||
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
|
||||
gl.setSamplerState(TEXTURE_2D, s);
|
||||
|
||||
gl.rawTexStorage(TEXTURE_2D, 1, format, sRGB, 1, 1);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ void Image::loadDefaultTexture()
|
||||
usingDefaultTexture = true;
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
setFilter(filter);
|
||||
setSamplerState(samplerState);
|
||||
|
||||
bool isSRGB = false;
|
||||
gl.rawTexStorage(texType, 1, PIXELFORMAT_RGBA8_UNORM, isSRGB, 2, 2, 1);
|
||||
@@ -204,7 +204,7 @@ bool Image::loadVolatile()
|
||||
&& mipmapsType != MIPMAPS_DATA)
|
||||
{
|
||||
mipmapsType = MIPMAPS_NONE;
|
||||
filter.mipmap = FILTER_NONE;
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ bool Image::loadVolatile()
|
||||
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight)))
|
||||
{
|
||||
mipmapsType = MIPMAPS_NONE;
|
||||
filter.mipmap = FILTER_NONE;
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
|
||||
}
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
@@ -226,9 +226,7 @@ bool Image::loadVolatile()
|
||||
return true;
|
||||
}
|
||||
|
||||
setFilter(filter);
|
||||
setWrap(wrap);
|
||||
setMipmapSharpness(mipmapSharpness);
|
||||
setSamplerState(samplerState);
|
||||
|
||||
GLenum gltextype = OpenGL::getGLTextureType(texType);
|
||||
|
||||
@@ -282,85 +280,34 @@ ptrdiff_t Image::getHandle() const
|
||||
return texture;
|
||||
}
|
||||
|
||||
void Image::setFilter(const Texture::Filter &f)
|
||||
void Image::setSamplerState(const SamplerState &s)
|
||||
{
|
||||
Texture::setFilter(f);
|
||||
Texture::setSamplerState(s);
|
||||
|
||||
if (!OpenGL::hasTextureFilteringSupport(getPixelFormat()))
|
||||
{
|
||||
filter.mag = filter.min = FILTER_NEAREST;
|
||||
samplerState.magFilter = samplerState.minFilter = SamplerState::FILTER_NEAREST;
|
||||
|
||||
if (filter.mipmap == FILTER_LINEAR)
|
||||
filter.mipmap = FILTER_NEAREST;
|
||||
if (samplerState.mipmapFilter == SamplerState::MIPMAP_FILTER_LINEAR)
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
// We don't want filtering or (attempted) mipmaps on the default texture.
|
||||
if (usingDefaultTexture)
|
||||
{
|
||||
filter.mipmap = FILTER_NONE;
|
||||
filter.min = filter.mag = FILTER_NEAREST;
|
||||
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
|
||||
samplerState.minFilter = samplerState.magFilter = SamplerState::FILTER_NEAREST;
|
||||
}
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
gl.setTextureFilter(texType, filter);
|
||||
}
|
||||
|
||||
bool Image::setWrap(const Texture::Wrap &w)
|
||||
{
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
bool success = true;
|
||||
bool forceclamp = texType == TEXTURE_CUBE;
|
||||
wrap = w;
|
||||
|
||||
// If we only have limited NPOT support then the wrap mode must be CLAMP.
|
||||
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
|
||||
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight) || depth != nextP2(depth)))
|
||||
{
|
||||
forceclamp = true;
|
||||
}
|
||||
|
||||
if (forceclamp)
|
||||
{
|
||||
if (wrap.s != WRAP_CLAMP || wrap.t != WRAP_CLAMP || wrap.r != WRAP_CLAMP)
|
||||
success = false;
|
||||
|
||||
wrap.s = wrap.t = wrap.r = WRAP_CLAMP;
|
||||
}
|
||||
|
||||
if (!gl.isClampZeroOneTextureWrapSupported())
|
||||
{
|
||||
if (isClampZeroOrOne(wrap.s)) wrap.s = WRAP_CLAMP;
|
||||
if (isClampZeroOrOne(wrap.t)) wrap.t = WRAP_CLAMP;
|
||||
if (isClampZeroOrOne(wrap.r)) wrap.r = WRAP_CLAMP;
|
||||
samplerState.wrapU = samplerState.wrapV = samplerState.wrapW = SamplerState::WRAP_CLAMP;
|
||||
}
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
gl.setTextureWrap(texType, wrap);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Image::setMipmapSharpness(float sharpness)
|
||||
{
|
||||
if (!gl.isSamplerLODBiasSupported())
|
||||
return false;
|
||||
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
float maxbias = gl.getMaxLODBias();
|
||||
|
||||
if (maxbias > 0.01f)
|
||||
maxbias -= 0.01f;
|
||||
|
||||
mipmapSharpness = std::min(std::max(sharpness, -maxbias), maxbias);
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
|
||||
// negative bias is sharper
|
||||
glTexParameterf(gl.getGLTextureType(texType), GL_TEXTURE_LOD_BIAS, -mipmapSharpness);
|
||||
|
||||
return true;
|
||||
gl.setSamplerState(texType, samplerState);
|
||||
}
|
||||
|
||||
} // opengl
|
||||
|
||||
@@ -49,10 +49,7 @@ public:
|
||||
|
||||
ptrdiff_t getHandle() const override;
|
||||
|
||||
void setFilter(const Texture::Filter &f) override;
|
||||
bool setWrap(const Texture::Wrap &w) override;
|
||||
|
||||
bool setMipmapSharpness(float sharpness) override;
|
||||
void setSamplerState(const SamplerState &s) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -502,11 +502,9 @@ void OpenGL::createDefaultTexture()
|
||||
// untextured primitives vs images.
|
||||
const GLubyte pix[] = {255, 255, 255, 255};
|
||||
|
||||
Texture::Filter filter;
|
||||
filter.min = filter.mag = Texture::FILTER_NEAREST;
|
||||
|
||||
Texture::Wrap wrap;
|
||||
wrap.s = wrap.t = wrap.r = Texture::WRAP_CLAMP;
|
||||
SamplerState s;
|
||||
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
|
||||
s.wrapU = s.wrapV = s.wrapW = SamplerState::WRAP_CLAMP;
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
{
|
||||
@@ -522,8 +520,7 @@ void OpenGL::createDefaultTexture()
|
||||
glGenTextures(1, &state.defaultTexture[type]);
|
||||
bindTextureToUnit(type, state.defaultTexture[type], 0, false);
|
||||
|
||||
setTextureWrap(type, wrap);
|
||||
setTextureFilter(type, filter);
|
||||
setSamplerState(type, s);
|
||||
|
||||
bool isSRGB = false;
|
||||
rawTexStorage(type, 1, PIXELFORMAT_RGBA8_UNORM, isSRGB, 1, 1);
|
||||
@@ -1050,52 +1047,19 @@ void OpenGL::deleteTexture(GLuint texture)
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
|
||||
void OpenGL::setTextureFilter(TextureType target, graphics::Texture::Filter &f)
|
||||
{
|
||||
GLint gmin = f.min == Texture::FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
|
||||
GLint gmag = f.mag == Texture::FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
|
||||
|
||||
if (f.mipmap != Texture::FILTER_NONE)
|
||||
{
|
||||
if (f.min == Texture::FILTER_NEAREST && f.mipmap == Texture::FILTER_NEAREST)
|
||||
gmin = GL_NEAREST_MIPMAP_NEAREST;
|
||||
else if (f.min == Texture::FILTER_NEAREST && f.mipmap == Texture::FILTER_LINEAR)
|
||||
gmin = GL_NEAREST_MIPMAP_LINEAR;
|
||||
else if (f.min == Texture::FILTER_LINEAR && f.mipmap == Texture::FILTER_NEAREST)
|
||||
gmin = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else if (f.min == Texture::FILTER_LINEAR && f.mipmap == Texture::FILTER_LINEAR)
|
||||
gmin = GL_LINEAR_MIPMAP_LINEAR;
|
||||
else
|
||||
gmin = GL_LINEAR;
|
||||
}
|
||||
|
||||
GLenum gltarget = getGLTextureType(target);
|
||||
|
||||
glTexParameteri(gltarget, GL_TEXTURE_MIN_FILTER, gmin);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_MAG_FILTER, gmag);
|
||||
|
||||
if (GLAD_EXT_texture_filter_anisotropic)
|
||||
{
|
||||
f.anisotropy = std::min(std::max(f.anisotropy, 1.0f), maxAnisotropy);
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, f.anisotropy);
|
||||
}
|
||||
else
|
||||
f.anisotropy = 1.0f;
|
||||
}
|
||||
|
||||
GLint OpenGL::getGLWrapMode(Texture::WrapMode wmode)
|
||||
GLint OpenGL::getGLWrapMode(SamplerState::WrapMode wmode)
|
||||
{
|
||||
switch (wmode)
|
||||
{
|
||||
case Texture::WRAP_CLAMP:
|
||||
case SamplerState::WRAP_CLAMP:
|
||||
default:
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
case Texture::WRAP_CLAMP_ZERO:
|
||||
case Texture::WRAP_CLAMP_ONE:
|
||||
case SamplerState::WRAP_CLAMP_ZERO:
|
||||
case SamplerState::WRAP_CLAMP_ONE:
|
||||
return GL_CLAMP_TO_BORDER;
|
||||
case Texture::WRAP_REPEAT:
|
||||
case SamplerState::WRAP_REPEAT:
|
||||
return GL_REPEAT;
|
||||
case Texture::WRAP_MIRRORED_REPEAT:
|
||||
case SamplerState::WRAP_MIRRORED_REPEAT:
|
||||
return GL_MIRRORED_REPEAT;
|
||||
}
|
||||
}
|
||||
@@ -1125,29 +1089,111 @@ GLint OpenGL::getGLCompareMode(CompareMode mode)
|
||||
}
|
||||
}
|
||||
|
||||
static bool isClampOne(Texture::WrapMode mode)
|
||||
static bool isClampOne(SamplerState::WrapMode mode)
|
||||
{
|
||||
return mode == Texture::WRAP_CLAMP_ONE;
|
||||
return mode == SamplerState::WRAP_CLAMP_ONE;
|
||||
}
|
||||
|
||||
void OpenGL::setTextureWrap(TextureType target, const graphics::Texture::Wrap &w)
|
||||
void OpenGL::setSamplerState(TextureType target, SamplerState &s)
|
||||
{
|
||||
GLenum textype = getGLTextureType(target);
|
||||
GLenum gltarget = getGLTextureType(target);
|
||||
|
||||
if (Texture::isClampZeroOrOne(w.s) || Texture::isClampZeroOrOne(w.t) || Texture::isClampZeroOrOne(w.r))
|
||||
GLint gmin = s.minFilter == SamplerState::FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
|
||||
GLint gmag = s.magFilter == SamplerState::FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
|
||||
|
||||
if (s.mipmapFilter != SamplerState::MIPMAP_FILTER_NONE)
|
||||
{
|
||||
GLfloat c[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
if (isClampOne(w.s) || isClampOne(w.t) || isClampOne(w.r))
|
||||
c[0] = c[1] = c[2] = c[3] = 1.0f;
|
||||
|
||||
glTexParameterfv(textype, GL_TEXTURE_BORDER_COLOR, c);
|
||||
if (s.minFilter == SamplerState::FILTER_NEAREST && s.mipmapFilter == SamplerState::MIPMAP_FILTER_NEAREST)
|
||||
gmin = GL_NEAREST_MIPMAP_NEAREST;
|
||||
else if (s.minFilter == SamplerState::FILTER_NEAREST && s.mipmapFilter == SamplerState::MIPMAP_FILTER_LINEAR)
|
||||
gmin = GL_NEAREST_MIPMAP_LINEAR;
|
||||
else if (s.minFilter == SamplerState::FILTER_LINEAR && s.mipmapFilter == SamplerState::MIPMAP_FILTER_NEAREST)
|
||||
gmin = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else if (s.minFilter == SamplerState::FILTER_LINEAR && s.mipmapFilter == SamplerState::MIPMAP_FILTER_LINEAR)
|
||||
gmin = GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
glTexParameteri(textype, GL_TEXTURE_WRAP_S, getGLWrapMode(w.s));
|
||||
glTexParameteri(textype, GL_TEXTURE_WRAP_T, getGLWrapMode(w.t));
|
||||
glTexParameteri(gltarget, GL_TEXTURE_MIN_FILTER, gmin);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_MAG_FILTER, gmag);
|
||||
|
||||
if (!isClampZeroOneTextureWrapSupported())
|
||||
{
|
||||
if (SamplerState::isClampZeroOrOne(s.wrapU)) s.wrapU = SamplerState::WRAP_CLAMP;
|
||||
if (SamplerState::isClampZeroOrOne(s.wrapV)) s.wrapV = SamplerState::WRAP_CLAMP;
|
||||
if (SamplerState::isClampZeroOrOne(s.wrapW)) s.wrapW = SamplerState::WRAP_CLAMP;
|
||||
}
|
||||
|
||||
if (SamplerState::isClampZeroOrOne(s.wrapU) || SamplerState::isClampZeroOrOne(s.wrapV) || SamplerState::isClampZeroOrOne(s.wrapW))
|
||||
{
|
||||
GLfloat c[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
if (isClampOne(s.wrapU) || isClampOne(s.wrapU) || isClampOne(s.wrapV))
|
||||
c[0] = c[1] = c[2] = c[3] = 1.0f;
|
||||
|
||||
glTexParameterfv(gltarget, GL_TEXTURE_BORDER_COLOR, c);
|
||||
}
|
||||
|
||||
glTexParameteri(gltarget, GL_TEXTURE_WRAP_S, getGLWrapMode(s.wrapU));
|
||||
glTexParameteri(gltarget, GL_TEXTURE_WRAP_T, getGLWrapMode(s.wrapV));
|
||||
|
||||
if (target == TEXTURE_VOLUME)
|
||||
glTexParameteri(textype, GL_TEXTURE_WRAP_R, getGLWrapMode(w.r));
|
||||
glTexParameteri(gltarget, GL_TEXTURE_WRAP_R, getGLWrapMode(s.wrapW));
|
||||
|
||||
if (isSamplerLODBiasSupported())
|
||||
{
|
||||
float maxbias = getMaxLODBias();
|
||||
if (maxbias > 0.01f)
|
||||
maxbias -= 0.01f;
|
||||
|
||||
s.lodBias = std::min(std::max(s.lodBias, -maxbias), maxbias);
|
||||
|
||||
glTexParameterf(gltarget, GL_TEXTURE_LOD_BIAS, s.lodBias);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.lodBias = 0.0f;
|
||||
}
|
||||
|
||||
if (GLAD_EXT_texture_filter_anisotropic)
|
||||
{
|
||||
uint8 maxAniso = (uint8) std::min(maxAnisotropy, (float)LOVE_UINT8_MAX);
|
||||
s.maxAnisotropy = std::min(std::max(s.maxAnisotropy, (uint8)1), maxAniso);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, s.maxAnisotropy);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.maxAnisotropy = 1;
|
||||
}
|
||||
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
|
||||
{
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
|
||||
glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.minLod = 0;
|
||||
s.maxLod = LOVE_UINT8_MAX;
|
||||
}
|
||||
|
||||
if (isDepthCompareSampleSupported())
|
||||
{
|
||||
if (s.depthSampleMode.hasValue)
|
||||
{
|
||||
// See the comment in renderstate.h
|
||||
GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
|
||||
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s.depthSampleMode.hasValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, bool &isSRGB, int width, int height, int depth)
|
||||
|
||||
@@ -329,16 +329,9 @@ public:
|
||||
void deleteTexture(GLuint texture);
|
||||
|
||||
/**
|
||||
* Sets the texture filter mode for the currently bound texture.
|
||||
* The anisotropy parameter of the argument is set to the actual amount of
|
||||
* anisotropy that was used.
|
||||
* Sets sampler state parameters for the currently bound texture.
|
||||
**/
|
||||
void setTextureFilter(TextureType target, graphics::Texture::Filter &f);
|
||||
|
||||
/**
|
||||
* Sets the texture wrap mode for the currently bound texture.
|
||||
**/
|
||||
void setTextureWrap(TextureType target, const graphics::Texture::Wrap &w);
|
||||
void setSamplerState(TextureType target, SamplerState &s);
|
||||
|
||||
/**
|
||||
* Equivalent to glTexStorage2D/3D on platforms that support it. Equivalent
|
||||
@@ -407,7 +400,7 @@ public:
|
||||
static GLenum getGLVertexDataType(vertex::DataType type, GLboolean &normalized, bool &intformat);
|
||||
static GLenum getGLBufferUsage(vertex::Usage usage);
|
||||
static GLenum getGLTextureType(TextureType type);
|
||||
static GLint getGLWrapMode(Texture::WrapMode wmode);
|
||||
static GLint getGLWrapMode(SamplerState::WrapMode wmode);
|
||||
static GLint getGLCompareMode(CompareMode mode);
|
||||
|
||||
static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer, bool &isSRGB);
|
||||
|
||||
@@ -588,6 +588,7 @@ void Shader::sendTextures(const UniformInfo *info, Texture **textures, int count
|
||||
|
||||
if (tex != nullptr)
|
||||
{
|
||||
const SamplerState &sampler = tex->getSamplerState();
|
||||
if (!tex->isReadable())
|
||||
{
|
||||
if (internalUpdate)
|
||||
@@ -595,7 +596,7 @@ void Shader::sendTextures(const UniformInfo *info, Texture **textures, int count
|
||||
else
|
||||
throw love::Exception("Textures with non-readable formats cannot be sampled from in a shader.");
|
||||
}
|
||||
else if (info->isDepthSampler != tex->getDepthSampleMode().hasValue)
|
||||
else if (info->isDepthSampler != sampler.depthSampleMode.hasValue)
|
||||
{
|
||||
if (internalUpdate)
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user