Browse Source

Improved error messages when canvas/image creation fails because the size is too big for the system

Alex Szpakowski 12 years ago
parent
commit
d286f78ec7

+ 4 - 0
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;

+ 5 - 0
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 */;
 

+ 15 - 2
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

+ 18 - 6
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;
 

+ 8 - 0
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