From af460af119be4257d8ba515e9d05eb38418c0b73 Mon Sep 17 00:00:00 2001 From: GPF Date: Tue, 4 Feb 2025 14:27:18 -0700 Subject: [PATCH] Recreated glCompressedTexSubImage2D implementation --- GL/texture.c | 49 ++++++++++++++++++++++++++++++++++++++++ include/GL/glext.h | 10 ++++++++ samples/nehe06_vq/main.c | 9 +++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/GL/texture.c b/GL/texture.c index 6bcfae1..e546ea8 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -906,6 +906,55 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target, _glGPUStateMarkDirty(); } +void APIENTRY glCompressedTexSubImage2DARB(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data) { + TRACE(); + + if (target != GL_TEXTURE_2D) { + _glKosThrowError(GL_INVALID_ENUM, __func__); + return; + } + + if (xoffset < 0 || yoffset < 0 || width <= 0 || height <= 0) { + _glKosThrowError(GL_INVALID_VALUE, __func__); + return; + } + + gl_assert(ACTIVE_TEXTURE < MAX_GLDC_TEXTURE_UNITS); + TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; + + if (!active) { + _glKosThrowError(GL_INVALID_OPERATION, __func__); + return; + } + + GLuint original_id = active->index; + + // Ensure that we're modifying the correct texture + if (active->index != original_id) { + _glKosThrowError(GL_INVALID_OPERATION, __func__); + return; + } + + // Copy raw compressed texture data into the texture buffer. + GLubyte* targetData = active->data; + GLubyte* src = (GLubyte*)data; + + // Copy the compressed data directly to the texture + if (data) { + FASTCPY(targetData + (yoffset * active->width + xoffset), src, imageSize); + } + + _glGPUStateMarkDirty(); +} + /** * Takes an internal format, and returns a GL format matching how we'd store * it internally, so it'll return one of the following: diff --git a/include/GL/glext.h b/include/GL/glext.h index 565ed40..ca0ad10 100644 --- a/include/GL/glext.h +++ b/include/GL/glext.h @@ -185,6 +185,15 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexSubImage2DARB(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data); /* Core aliases */ #define GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT @@ -195,6 +204,7 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target, #define glGenerateMipmapEXT glGenerateMipmap #define glCompressedTexImage2D glCompressedTexImage2DARB +#define glCompressedTexSubImage2D glCompressedTexSubImage2DARB #ifndef GL_VERSION_1_4 #define GL_VERSION_1_4 1 diff --git a/samples/nehe06_vq/main.c b/samples/nehe06_vq/main.c index 754f458..bd0df56 100644 --- a/samples/nehe06_vq/main.c +++ b/samples/nehe06_vq/main.c @@ -165,9 +165,16 @@ void LoadGLTextures() { // 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, // border 0 (normal), rgb color data, unsigned byte data, and finally the data itself. + // Allocate texture memory (but don't upload compressed data yet) glCompressedTexImage2DARB( GL_TEXTURE_2D, 0, image1->internalFormat, image1->sizeX, image1->sizeY, 0, - image1->dataSize, image1->data + image1->dataSize, NULL // NULL here means we are not uploading data yet + ); + + // Now use glCompressedTexSubImage2DARB to upload the compressed data to the texture + glCompressedTexSubImage2DARB( + GL_TEXTURE_2D, 0, 0, 0, image1->sizeX, image1->sizeY, + image1->internalFormat, image1->dataSize, image1->data ); free(image1);