mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
Initial support for integer format textures.
They can't be rendered to and ImageData can't use the formats, for now.
This commit is contained in:
@@ -304,10 +304,13 @@ void OpenGL::deInitContext()
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
{
|
||||
if (state.defaultTexture[i] != 0)
|
||||
for (int datatype = DATA_BASETYPE_FLOAT; datatype <= DATA_BASETYPE_UINT; datatype++)
|
||||
{
|
||||
gl.deleteTexture(state.defaultTexture[i]);
|
||||
state.defaultTexture[i] = 0;
|
||||
if (state.defaultTexture[i][datatype] != 0)
|
||||
{
|
||||
gl.deleteTexture(state.defaultTexture[i][datatype]);
|
||||
state.defaultTexture[i][datatype] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,6 +572,7 @@ void OpenGL::createDefaultTexture()
|
||||
// which would create the need to use different "passthrough" shaders for
|
||||
// untextured primitives vs images.
|
||||
const GLubyte pix[] = {255, 255, 255, 255};
|
||||
const GLubyte intpix[] = {1, 1, 1, 1};
|
||||
|
||||
SamplerState s;
|
||||
s.minFilter = s.magFilter = SamplerState::FILTER_NEAREST;
|
||||
@@ -576,41 +580,55 @@ void OpenGL::createDefaultTexture()
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
{
|
||||
state.defaultTexture[i] = 0;
|
||||
|
||||
TextureType type = (TextureType) i;
|
||||
|
||||
if (!isTextureTypeSupported(type))
|
||||
continue;
|
||||
|
||||
GLuint curtexture = state.boundTextures[type][0];
|
||||
|
||||
glGenTextures(1, &state.defaultTexture[type]);
|
||||
bindTextureToUnit(type, state.defaultTexture[type], 0, false);
|
||||
|
||||
setSamplerState(type, s);
|
||||
|
||||
bool isSRGB = false;
|
||||
rawTexStorage(type, 1, PIXELFORMAT_RGBA8_UNORM, isSRGB, 1, 1);
|
||||
|
||||
TextureFormat fmt = convertPixelFormat(PIXELFORMAT_RGBA8_UNORM, false, isSRGB);
|
||||
|
||||
int slices = type == TEXTURE_CUBE ? 6 : 1;
|
||||
|
||||
for (int slice = 0; slice < slices; slice++)
|
||||
for (int datatype = (int)DATA_BASETYPE_FLOAT; datatype <= (int)DATA_BASETYPE_UINT; datatype++)
|
||||
{
|
||||
GLenum gltarget = getGLTextureType(type);
|
||||
state.defaultTexture[i][datatype] = 0;
|
||||
|
||||
if (type == TEXTURE_CUBE)
|
||||
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
|
||||
TextureType type = (TextureType) i;
|
||||
|
||||
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
|
||||
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, pix);
|
||||
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
|
||||
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, pix);
|
||||
if (!isTextureTypeSupported(type))
|
||||
continue;
|
||||
|
||||
if (datatype != DATA_BASETYPE_FLOAT && !(GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0))
|
||||
continue;
|
||||
|
||||
GLuint curtexture = state.boundTextures[type][0];
|
||||
|
||||
glGenTextures(1, &state.defaultTexture[type][datatype]);
|
||||
bindTextureToUnit(type, state.defaultTexture[type][datatype], 0, false);
|
||||
|
||||
setSamplerState(type, s);
|
||||
|
||||
PixelFormat format = PIXELFORMAT_RGBA8_UNORM;
|
||||
if (datatype == DATA_BASETYPE_INT)
|
||||
format = PIXELFORMAT_RGBA8_INT;
|
||||
else if (datatype == DATA_BASETYPE_UINT)
|
||||
format = PIXELFORMAT_RGBA8_UINT;
|
||||
|
||||
const GLubyte *p = datatype == DATA_BASETYPE_FLOAT ? pix : intpix;
|
||||
|
||||
bool isSRGB = false;
|
||||
rawTexStorage(type, 1, format, isSRGB, 1, 1);
|
||||
|
||||
TextureFormat fmt = convertPixelFormat(format, false, isSRGB);
|
||||
|
||||
int slices = type == TEXTURE_CUBE ? 6 : 1;
|
||||
|
||||
for (int slice = 0; slice < slices; slice++)
|
||||
{
|
||||
GLenum gltarget = getGLTextureType(type);
|
||||
|
||||
if (type == TEXTURE_CUBE)
|
||||
gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice;
|
||||
|
||||
if (type == TEXTURE_2D || type == TEXTURE_CUBE)
|
||||
glTexSubImage2D(gltarget, 0, 0, 0, 1, 1, fmt.externalformat, fmt.type, p);
|
||||
else if (type == TEXTURE_2D_ARRAY || type == TEXTURE_VOLUME)
|
||||
glTexSubImage3D(gltarget, 0, 0, 0, slice, 1, 1, 1, fmt.externalformat, fmt.type, p);
|
||||
}
|
||||
|
||||
bindTextureToUnit(type, curtexture, 0, false);
|
||||
}
|
||||
|
||||
bindTextureToUnit(type, curtexture, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,9 +1131,9 @@ GLuint OpenGL::getDefaultFBO() const
|
||||
#endif
|
||||
}
|
||||
|
||||
GLuint OpenGL::getDefaultTexture(TextureType type) const
|
||||
GLuint OpenGL::getDefaultTexture(TextureType type, DataBaseType datatype) const
|
||||
{
|
||||
return state.defaultTexture[type];
|
||||
return state.defaultTexture[type][datatype];
|
||||
}
|
||||
|
||||
void OpenGL::setTextureUnit(int textureunit)
|
||||
@@ -1166,14 +1184,19 @@ void OpenGL::bindTextureToUnit(Texture *texture, int textureunit, bool restorepr
|
||||
}
|
||||
else
|
||||
{
|
||||
DataBaseType datatype = DATA_BASETYPE_FLOAT;
|
||||
|
||||
if (textureunit == 0 && Shader::current != nullptr)
|
||||
{
|
||||
TextureType shadertex = Shader::current->getMainTextureType();
|
||||
if (shadertex != TEXTURE_MAX_ENUM)
|
||||
textype = shadertex;
|
||||
const Shader::UniformInfo *info = Shader::current->getMainTextureInfo();
|
||||
if (info != nullptr)
|
||||
{
|
||||
textype = info->textureType;
|
||||
datatype = info->dataBaseType;
|
||||
}
|
||||
}
|
||||
|
||||
handle = getDefaultTexture(textype);
|
||||
handle = getDefaultTexture(textype, datatype);
|
||||
}
|
||||
|
||||
bindTextureToUnit(textype, handle, textureunit, restoreprev, bindforedit);
|
||||
@@ -1662,6 +1685,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
f.externalformat = GL_RGBA;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R16_FLOAT:
|
||||
f.internalformat = GL_R16F;
|
||||
f.externalformat = GL_RED;
|
||||
@@ -1702,6 +1726,97 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
|
||||
f.type = GL_FLOAT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R8_INT:
|
||||
f.internalformat = GL_R8I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_R8_UINT:
|
||||
f.internalformat = GL_R8UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RG8_INT:
|
||||
f.internalformat = GL_RG8I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RG8_UINT:
|
||||
f.internalformat = GL_RG8UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_INT:
|
||||
f.internalformat = GL_RGBA8I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA8_UINT:
|
||||
f.internalformat = GL_RGBA8UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case PIXELFORMAT_R16_INT:
|
||||
f.internalformat = GL_R16I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_R16_UINT:
|
||||
f.internalformat = GL_R16UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RG16_INT:
|
||||
f.internalformat = GL_RG16I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RG16_UINT:
|
||||
f.internalformat = GL_RG16UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA16_INT:
|
||||
f.internalformat = GL_RGBA16I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA16_UINT:
|
||||
f.internalformat = GL_RGBA16UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case PIXELFORMAT_R32_INT:
|
||||
f.internalformat = GL_R32I;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_R32_UINT:
|
||||
f.internalformat = GL_R32UI;
|
||||
f.externalformat = GL_RED_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RG32_INT:
|
||||
f.internalformat = GL_RG32I;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RG32_UINT:
|
||||
f.internalformat = GL_RG32UI;
|
||||
f.externalformat = GL_RG_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA32_INT:
|
||||
f.internalformat = GL_RGBA32I;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_INT;
|
||||
break;
|
||||
case PIXELFORMAT_RGBA32_UINT:
|
||||
f.internalformat = GL_RGBA32UI;
|
||||
f.externalformat = GL_RGBA_INTEGER;
|
||||
f.type = GL_UNSIGNED_INT;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_LA8_UNORM:
|
||||
if (gl.isCoreProfile() || GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
@@ -2046,6 +2161,28 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
|
||||
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_R8_INT:
|
||||
case PIXELFORMAT_R8_UINT:
|
||||
case PIXELFORMAT_RG8_INT:
|
||||
case PIXELFORMAT_RG8_UINT:
|
||||
case PIXELFORMAT_RGBA8_INT:
|
||||
case PIXELFORMAT_RGBA8_UINT:
|
||||
case PIXELFORMAT_R16_INT:
|
||||
case PIXELFORMAT_R16_UINT:
|
||||
case PIXELFORMAT_RG16_INT:
|
||||
case PIXELFORMAT_RG16_UINT:
|
||||
case PIXELFORMAT_RGBA16_INT:
|
||||
case PIXELFORMAT_RGBA16_UINT:
|
||||
case PIXELFORMAT_R32_INT:
|
||||
case PIXELFORMAT_R32_UINT:
|
||||
case PIXELFORMAT_RG32_INT:
|
||||
case PIXELFORMAT_RG32_UINT:
|
||||
case PIXELFORMAT_RGBA32_INT:
|
||||
case PIXELFORMAT_RGBA32_UINT:
|
||||
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
|
||||
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
|
||||
break;
|
||||
|
||||
case PIXELFORMAT_LA8_UNORM:
|
||||
flags |= commonsample;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user