From 11fe64d6fd160a3db52f28692df54388d0fc9017 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Thu, 19 Jun 2025 22:07:32 -0300 Subject: [PATCH] opengl: clean up some texture initialization code --- src/modules/graphics/opengl/OpenGL.cpp | 28 ++++++++++++++++++----- src/modules/graphics/opengl/Texture.cpp | 30 +------------------------ 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 363bf871a..470ed9c3c 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -1174,12 +1174,12 @@ bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelform { GLenum gltarget = getGLTextureType(target); TextureFormat fmt = convertPixelFormat(pixelformat); + bool compressed = isPixelFormatCompressed(pixelformat); // This shouldn't be needed for glTexStorage, but some drivers don't follow // the spec apparently. // https://stackoverflow.com/questions/13859061/does-an-immutable-texture-need-a-gl-texture-max-level - if (GLAD_VERSION_1_2 || GLAD_ES_VERSION_3_0) - glTexParameteri(gltarget, GL_TEXTURE_MAX_LEVEL, levels - 1); + glTexParameteri(gltarget, GL_TEXTURE_MAX_LEVEL, levels - 1); if (fmt.swizzled) { @@ -1222,14 +1222,30 @@ bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelform if (target == TEXTURE_CUBE) gltarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - glTexImage2D(gltarget, level, fmt.internalformat, w, h, 0, - fmt.externalformat, fmt.type, nullptr); + if (compressed) + { + size_t mipsize = faces * getPixelFormatSliceSize(pixelformat, w, h); + glCompressedTexImage2D(gltarget, level, fmt.internalformat, w, h, 0, mipsize, nullptr); + } + else + { + glTexImage2D(gltarget, level, fmt.internalformat, w, h, 0, + fmt.externalformat, fmt.type, nullptr); + } } } else if (target == TEXTURE_2D_ARRAY || target == TEXTURE_VOLUME) { - glTexImage3D(gltarget, level, fmt.internalformat, w, h, d, - 0, fmt.externalformat, fmt.type, nullptr); + if (compressed) + { + size_t mipsize = d * getPixelFormatSliceSize(pixelformat, w, h); + glCompressedTexImage3D(gltarget, level, fmt.internalformat, w, h, d, 0, mipsize, nullptr); + } + else + { + glTexImage3D(gltarget, level, fmt.internalformat, w, h, d, + 0, fmt.externalformat, fmt.type, nullptr); + } } w = std::max(w / 2, 1); diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index 571708f23..d7b54e003 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -300,42 +300,14 @@ void Texture::createTexture() else if (texType == TEXTURE_CUBE) slicecount = 6; - // For a couple flimsy reasons, we don't initialize the texture here if it's - // compressed. I need to verify that getPixelFormatSliceSize will return the - // correct value for all compressed texture formats, and I also vaguely - // remember some driver issues on some old Android systems, maybe... - // For now, the base class enforces data on init for compressed textures. - if (!isCompressed()) - gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers); - - // rawTexStorage handles this for uncompressed textures. - if (isCompressed()) - glTexParameteri(gltype, GL_TEXTURE_MAX_LEVEL, mipcount - 1); + gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers); int w = pixelWidth; int h = pixelHeight; int d = depth; - OpenGL::TextureFormat fmt = gl.convertPixelFormat(format); - for (int mip = 0; mip < mipcount; mip++) { - if (isCompressed() && (texType == TEXTURE_2D_ARRAY || texType == TEXTURE_VOLUME)) - { - int slicecount = slices.getSliceCount(mip); - size_t mipsize = 0; - - for (int slice = 0; slice < slicecount; slice++) - { - auto id = slices.get(slice, mip); - if (id != nullptr) - mipsize += id->getSize(); - } - - if (mipsize > 0) - glCompressedTexImage3D(gltype, mip, fmt.internalformat, w, h, slicecount, 0, mipsize, nullptr); - } - for (int slice = 0; slice < slicecount; slice++) { love::image::ImageDataBase *id = slices.get(slice, mip);