From 021237f258c5d8b2b6ebfbbbded20717764c1ec3 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Tue, 14 Aug 2018 09:49:31 +0100 Subject: [PATCH] Fix a number of issues with texture loading --- GL/draw.c | 18 +++++++++++++----- GL/private.h | 8 ++++++-- GL/state.c | 43 ++++++++++++++++++++++++++++++++++++------- GL/texture.c | 12 ++++++++++-- include/gl.h | 1 + 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index 9becdbf..c5e22c4 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -435,7 +435,7 @@ typedef struct { #define MAX_LISTS 5 -static void push(const AlignedVector* vertices, PolyList* activePolyList, TextureObject* textureObject) { +static void push(const AlignedVector* vertices, PolyList* activePolyList, GLshort textureUnit) { /* Copy the vertices to the active poly list */ static GLuint LIST_COUNTER = 0; @@ -455,7 +455,7 @@ static void push(const AlignedVector* vertices, PolyList* activePolyList, Textur pvr_poly_cxt_t cxt = *getPVRContext(); cxt.list_type = activePolyList->list_type; - updatePVRTextureContext(&cxt, textureObject); + _glUpdatePVRTextureContext(&cxt, textureUnit); pvr_poly_compile(hdr, &cxt); @@ -567,7 +567,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ } divide(buffer); - push(buffer, activePolyList(), getTexture0()); + push(buffer, activePolyList(), 0); /* Now, if multitexturing is enabled, we want to send exactly the same vertices again, except: @@ -577,10 +577,18 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ - We want to set the uv coordinates to the passed st ones */ + GLboolean doMultitexture; + glGetBooleanv(GL_TEXTURE_2D, &doMultitexture); + + if(!doMultitexture) { + /* Multitexture actively disabled */ + return; + } + TextureObject* texture1 = getTexture1(); if(!texture1 || ((ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) != ST_ENABLED_FLAG)) { - /* Multitexture disabled */ + /* Multitexture implicitly disabled */ return; } @@ -607,7 +615,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Send the buffer again to the transparent list */ - push(buffer, transparentPolyList(), texture1); + push(buffer, transparentPolyList(), 1); /* Reset state */ glDepthFunc(depthFunc); diff --git a/GL/private.h b/GL/private.h index 594ffa4..64f8161 100644 --- a/GL/private.h +++ b/GL/private.h @@ -88,12 +88,16 @@ GLubyte checkImmediateModeInactive(const char* func); pvr_poly_cxt_t* getPVRContext(); GLubyte _glKosInitTextures(); -void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject* tx1); + +void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit); + TextureObject* getTexture0(); TextureObject* getTexture1(); TextureObject* getBoundTexture(); +GLubyte _glGetActiveTexture(); + GLboolean isBlendingEnabled(); -GLboolean _glIsMipmapComplete(TextureObject* obj); +GLboolean _glIsMipmapComplete(const TextureObject* obj); GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level); GLuint _glGetMipmapLevelCount(TextureObject* obj); diff --git a/GL/state.c b/GL/state.c index f90f240..330a867 100644 --- a/GL/state.c +++ b/GL/state.c @@ -1,3 +1,4 @@ +#include #include #include @@ -115,11 +116,15 @@ static void _updatePVRBlend(pvr_poly_cxt_t* context) { } } -static GLboolean TEXTURES_ENABLED = GL_FALSE; +static GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE}; -void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { - if(!TEXTURES_ENABLED) { - context->txr2.enable = context->txr.enable = PVR_TEXTURE_DISABLE; +void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { + const TextureObject *tx1 = (textureUnit == 0) ? getTexture0() : getTexture1(); + + if(!TEXTURES_ENABLED[textureUnit] || !tx1) { + context->txr.enable = PVR_TEXTURE_DISABLE; + context->txr.base = 0; + context->txr.format = 0; return; } @@ -136,6 +141,9 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { case GL_LINEAR_MIPMAP_NEAREST: enableMipmaps = GL_TRUE; break; + default: + enableMipmaps = GL_FALSE; + break; } if(enableMipmaps) { @@ -154,7 +162,17 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { } } - if(tx1) { + /* If we don't have complete mipmaps, and yet mipmapping was enabled, we disable texturing. + * This is effectively what standard GL does (it renders a white texture) + */ + if(!_glIsMipmapComplete(tx1) && enableMipmaps) { + context->txr.enable = PVR_TEXTURE_DISABLE; + context->txr.base = 0; + context->txr.format = 0; + return; + } + + if(tx1->data) { context->txr.enable = PVR_TEXTURE_ENABLE; context->txr.filter = filter; context->txr.mipmap = (enableMipmaps) ? PVR_MIPMAP_ENABLE : PVR_MIPMAP_DISABLE; @@ -217,7 +235,7 @@ void initContext() { GLAPI void APIENTRY glEnable(GLenum cap) { switch(cap) { case GL_TEXTURE_2D: - TEXTURES_ENABLED = GL_TRUE; + TEXTURES_ENABLED[_glGetActiveTexture()] = GL_TRUE; break; case GL_CULL_FACE: { CULLING_ENABLED = GL_TRUE; @@ -261,7 +279,7 @@ GLAPI void APIENTRY glEnable(GLenum cap) { GLAPI void APIENTRY glDisable(GLenum cap) { switch(cap) { case GL_TEXTURE_2D: { - TEXTURES_ENABLED = GL_FALSE; + TEXTURES_ENABLED[_glGetActiveTexture()] = GL_FALSE; } break; case GL_CULL_FACE: { CULLING_ENABLED = GL_FALSE; @@ -458,6 +476,17 @@ static GLenum COMPRESSED_FORMATS [] = { static GLint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum); +void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { + switch(pname) { + case GL_TEXTURE_2D: + *params = TEXTURES_ENABLED[_glGetActiveTexture()]; + break; + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { switch(pname) { case GL_MAX_LIGHTS: diff --git a/GL/texture.c b/GL/texture.c index 3f22b7c..2bdb749 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -1,5 +1,6 @@ #include "private.h" +#include #include #include "../include/glext.h" @@ -16,6 +17,10 @@ static GLubyte ACTIVE_TEXTURE = 0; static GLuint _determinePVRFormat(GLint internalFormat, GLenum type); +GLubyte _glGetActiveTexture() { + return ACTIVE_TEXTURE; +} + static GLint _determineStride(GLenum format, GLenum type) { switch(type) { case GL_BYTE: @@ -178,6 +183,7 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { if(txr->data) { pvr_mem_free(txr->data); + txr->data = NULL; } named_array_release(&TEXTURE_OBJECTS, *textures++); @@ -532,7 +538,7 @@ static GLboolean _isSupportedFormat(GLenum format) { } } -GLboolean _glIsMipmapComplete(TextureObject* obj) { +GLboolean _glIsMipmapComplete(const TextureObject* obj) { if(!obj->mipmap || !obj->mipmapCount) { return GL_FALSE; } @@ -628,8 +634,10 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, active->color = pvr_format; /* Set the required mipmap count */ active->mipmapCount = _glGetMipmapLevelCount(active); - active->data = pvr_mem_malloc(_glGetMipmapDataSize(active)); active->dataStride = sizeof(GLshort); + + GLuint size = _glGetMipmapDataSize(active); + active->data = pvr_mem_malloc(size); } /* Mark this level as set in the mipmap bitmask */ diff --git a/include/gl.h b/include/gl.h index ef284c7..5b75312 100644 --- a/include/gl.h +++ b/include/gl.h @@ -596,6 +596,7 @@ GLAPI void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *param GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height); /* glGet Functions */ +GLAPI void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params); GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params); GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap);