From d286f78ec721f2ca6e6680312a742ddad3b6729d Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 9 Jun 2013 18:24:19 -0300 Subject: [PATCH] Improved error messages when canvas/image creation fails because the size is too big for the system --- src/modules/graphics/opengl/Canvas.cpp | 4 ++++ src/modules/graphics/opengl/Graphics.cpp | 5 +++++ src/modules/graphics/opengl/Image.cpp | 17 +++++++++++++++-- src/modules/graphics/opengl/OpenGL.cpp | 24 ++++++++++++++++++------ src/modules/graphics/opengl/OpenGL.h | 8 ++++++++ 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index faf2369fd..45b7394c4 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -704,6 +704,10 @@ Image::Wrap Canvas::getWrap() const bool Canvas::loadVolatile() { + // glTexImage2D is guaranteed to error in this case. + if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize()) + return false; + status = strategy->createFBO(fbo, img, width, height, texture_type); if (status != GL_FRAMEBUFFER_COMPLETE) return false; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 3dc593299..5147b76d9 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -468,6 +468,11 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_t if (texture_type == Canvas::TYPE_HDR && !Canvas::isHDRSupported()) throw Exception("HDR Canvases are not supported by your OpenGL implementation"); + if (width > gl.getMaxTextureSize()) + throw Exception("Cannot create canvas: width of %d pixels is too large for this system.", width); + else if (height > gl.getMaxTextureSize()) + throw Exception("Cannot create canvas: height of %d pixels is too large for this system.", height); + while (GL_NO_ERROR != glGetError()) /* clear opengl error flag */; diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 16513baeb..fd19b1df8 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -320,6 +320,18 @@ void Image::unload() bool Image::loadVolatile() { + // glTexImage2D is guaranteed to throw an error in this case. + if (width > gl.getMaxTextureSize()) + { + throw love::Exception("Cannot create image: " + "width of %d pixels is too large for this system.", (int) width); + } + else if (height > gl.getMaxTextureSize()) + { + throw love::Exception("Cannot create image:" + "height of %d pixels is too large for this system.", (int) height); + } + if (isCompressed() && cdata && !hasCompressedTextureSupport(cdata->getType())) { const char *str; @@ -614,9 +626,10 @@ bool Image::hasCompressedTextureSupport(image::CompressedData::TextureType type) case image::CompressedData::TYPE_BC5s: return (GLEE_VERSION_3_0 || GLEE_ARB_texture_compression_rgtc || GLEE_EXT_texture_compression_rgtc); default: - return false; - + break; } + + return false; } } // opengl diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 363e0c10c..28ec3f7cd 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -38,6 +38,7 @@ namespace opengl OpenGL::OpenGL() : contextInitialized(false) , maxAnisotropy(1.0f) + , maxTextureSize(0) , state() { } @@ -103,12 +104,7 @@ void OpenGL::initContext() glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &state.textureUnits[0]); } - // We'll need this value to clamp anisotropy. - if (GLEE_EXT_texture_filter_anisotropic) - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); - else - maxAnisotropy = 1.0f; - + initMaxValues(); createDefaultTexture(); contextInitialized = true; @@ -151,6 +147,17 @@ void OpenGL::initOpenGLFunctions() } } +void OpenGL::initMaxValues() +{ + // We'll need this value to clamp anisotropy. + if (GLEE_EXT_texture_filter_anisotropic) + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); + else + maxAnisotropy = 1.0f; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); +} + void OpenGL::createDefaultTexture() { // Set the 'default' texture (id 0) as a repeating white pixel. Otherwise, @@ -449,6 +456,11 @@ graphics::Image::Wrap OpenGL::getTextureWrap() return w; } +int OpenGL::getMaxTextureSize() const +{ + return maxTextureSize; +} + // OpenGL class instance singleton. OpenGL gl; diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 3fba36432..4ebc2d6d8 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -168,13 +168,21 @@ public: **/ graphics::Image::Wrap getTextureWrap(); + /** + * Returns the maximum supported width or height of a texture. + **/ + int getMaxTextureSize() const; + private: void initOpenGLFunctions(); + void initMaxValues(); void createDefaultTexture(); bool contextInitialized; + float maxAnisotropy; + int maxTextureSize; // Tracked OpenGL state. struct