GLES: Fixed OES_texture_half_float incomplete texture.

This commit is contained in:
Branimir Karadžić 2015-03-28 21:25:40 -07:00
parent 0d99f1b35c
commit 3039c9a040
2 changed files with 70 additions and 18 deletions

View file

@ -174,7 +174,12 @@ int _main_(int /*_argc*/, char** /*_argv*/)
bgfx::setViewName(8, "Blur vertical");
bgfx::setViewName(9, "Blur horizontal + tonemap");
bgfx::TextureHandle uffizi = loadTexture("uffizi_lod.dds", BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);
bgfx::TextureHandle uffizi = loadTexture("uffizi.dds"
, 0
| BGFX_TEXTURE_U_CLAMP
| BGFX_TEXTURE_V_CLAMP
| BGFX_TEXTURE_W_CLAMP
);
bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox");
bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum");
@ -371,6 +376,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
// Render skybox into view 0.
bgfx::setTexture(0, u_texCube, uffizi);
bgfx::setProgram(skyProgram);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
screenSpaceQuad( (float)width, (float)height, true);

View file

@ -237,6 +237,8 @@ namespace bgfx { namespace gl
};
BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );
static bool s_textureFilter[TextureFormat::Count+1];
static GLenum s_rboFormat[] =
{
GL_ZERO, // BC1
@ -921,6 +923,15 @@ namespace bgfx { namespace gl
return 0 == err;
}
static void getFilters(uint32_t _flags, bool _hasMips, GLenum& _magFilter, GLenum& _minFilter)
{
const uint32_t mag = (_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
const uint32_t min = (_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
const uint32_t mip = (_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
_magFilter = s_textureFilterMag[mag];
_minFilter = s_textureFilterMin[min][_hasMips ? mip+1 : 0];
}
struct RendererContextGL : public RendererContextI
{
RendererContextGL()
@ -1100,6 +1111,9 @@ namespace bgfx { namespace gl
}
}
// Allow all texture filters.
memset(s_textureFilter, true, BX_COUNTOF(s_textureFilter) );
bool bc123Supported = 0
|| s_extension[Extension::EXT_texture_compression_s3tc ].m_supported
|| s_extension[Extension::MOZ_WEBGL_compressed_texture_s3tc ].m_supported
@ -1192,6 +1206,15 @@ namespace bgfx { namespace gl
{
setTextureFormat(TextureFormat::RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT);
if (s_extension[Extension::OES_texture_half_float].m_supported
|| s_extension[Extension::OES_texture_float ].m_supported)
{
// https://www.khronos.org/registry/gles/extensions/OES/OES_texture_float.txt
// When RGBA16F is available via extensions texture will be marked as
// incomplete if it uses anything other than nearest filter.
s_textureFilter[TextureFormat::RGBA16F] = false;
}
if (BX_ENABLED(BX_PLATFORM_IOS) )
{
setTextureFormat(TextureFormat::D16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
@ -2054,16 +2077,25 @@ namespace bgfx { namespace gl
{
sampler = m_samplerStateCache.add(_flags);
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
GL_CHECK(glSamplerParameteri(sampler
, GL_TEXTURE_WRAP_S
, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]
) );
GL_CHECK(glSamplerParameteri(sampler
, GL_TEXTURE_WRAP_T
, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]
) );
GL_CHECK(glSamplerParameteri(sampler
, GL_TEXTURE_WRAP_R
, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]
) );
const uint32_t mag = (_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
const uint32_t min = (_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
const uint32_t mip = (_flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
GLenum minFilter = s_textureFilterMin[min][1 < _numMips ? mip+1 : 0];
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, s_textureFilterMag[mag]) );
GLenum minFilter;
GLenum magFilter;
getFilters(_flags, 1 < _numMips, magFilter, minFilter);
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, magFilter) );
GL_CHECK(glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, minFilter) );
if (0 != (_flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) )
&& 0.0f < m_maxAnisotropy)
{
@ -3210,8 +3242,6 @@ namespace bgfx { namespace gl
BX_CHECK(0 != m_id, "Failed to generate texture id.");
GL_CHECK(glBindTexture(_target, m_id) );
setSamplerState(_flags);
const TextureFormatInfo& tfi = s_textureFormat[_format];
m_fmt = tfi.m_fmt;
m_type = tfi.m_type;
@ -3227,6 +3257,8 @@ namespace bgfx { namespace gl
m_type = tfi.m_type;
}
setSamplerState(_flags);
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
&& TextureFormat::BGRA8 == m_textureFormat
&& GL_RGBA == m_fmt
@ -3591,6 +3623,21 @@ namespace bgfx { namespace gl
void TextureGL::setSamplerState(uint32_t _flags)
{
if (!s_textureFilter[m_textureFormat])
{
// Force point sampling when texture format doesn't support linear sampling.
_flags &= 0
| BGFX_TEXTURE_MIN_MASK
| BGFX_TEXTURE_MAG_MASK
| BGFX_TEXTURE_MIP_MASK
;
_flags |= 0
| BGFX_TEXTURE_MIN_POINT
| BGFX_TEXTURE_MAG_POINT
| BGFX_TEXTURE_MIP_POINT
;
}
const uint32_t flags = (0 != (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) ? m_flags : _flags) & BGFX_TEXTURE_SAMPLER_BITS_MASK;
if (flags != m_currentFlags)
{
@ -3611,11 +3658,10 @@ namespace bgfx { namespace gl
GL_CHECK(glTexParameteri(target, GL_TEXTURE_WRAP_R, s_textureAddress[(flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
}
const uint32_t mag = (flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
const uint32_t min = (flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
const uint32_t mip = (flags&BGFX_TEXTURE_MIP_MASK)>>BGFX_TEXTURE_MIP_SHIFT;
const GLenum minFilter = s_textureFilterMin[min][1 < numMips ? mip+1 : 0];
GL_CHECK(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, s_textureFilterMag[mag]) );
GLenum magFilter;
GLenum minFilter;
getFilters(flags, 1 < numMips, magFilter, minFilter);
GL_CHECK(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter) );
GL_CHECK(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
if (0 != (flags & (BGFX_TEXTURE_MIN_ANISOTROPIC|BGFX_TEXTURE_MAG_ANISOTROPIC) )
&& 0.0f < s_renderGL->m_maxAnisotropy)