Browse Source

Fixed lazy-loading of stencil buffers in Canvases sometimes failing due to uninitialized variables

Alex Szpakowski 12 years ago
parent
commit
3725b4122f

+ 2 - 2
platform/macosx/love-framework.xcodeproj/project.pbxproj

@@ -2188,6 +2188,7 @@
 					/Library/Frameworks/Lua.framework/Headers,
 					/Library/Frameworks/SDL.framework/Headers,
 				);
+				LD_RUNPATH_SEARCH_PATHS = "@rpath";
 				LIBRARY_SEARCH_PATHS = "";
 				MACOSX_DEPLOYMENT_TARGET = 10.5;
 				ONLY_ACTIVE_ARCH = NO;
@@ -2220,6 +2221,7 @@
 					/Library/Frameworks/Lua.framework/Headers,
 					/Library/Frameworks/SDL.framework/Headers,
 				);
+				LD_RUNPATH_SEARCH_PATHS = "@rpath";
 				LIBRARY_SEARCH_PATHS = "";
 				MACOSX_DEPLOYMENT_TARGET = 10.5;
 				ONLY_ACTIVE_ARCH = YES;
@@ -2242,7 +2244,6 @@
 				);
 				INFOPLIST_FILE = "Info-Framework.plist";
 				LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
-				LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
 				PRODUCT_NAME = love;
 				SKIP_INSTALL = YES;
 				WRAPPER_EXTENSION = framework;
@@ -2260,7 +2261,6 @@
 				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
 				INFOPLIST_FILE = "Info-Framework.plist";
 				LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)";
-				LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks";
 				PRODUCT_NAME = love;
 				SKIP_INSTALL = YES;
 				WRAPPER_EXTENSION = framework;

+ 2 - 2
platform/macosx/love.xcodeproj/project.pbxproj

@@ -350,7 +350,7 @@
 					/Library/Frameworks/SDL.framework/Headers,
 				);
 				INFOPLIST_FILE = "love-Info.plist";
-				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries";
+				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
 				MACOSX_DEPLOYMENT_TARGET = 10.5;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "";
@@ -404,7 +404,7 @@
 					/Library/Frameworks/SDL.framework/Headers,
 				);
 				INFOPLIST_FILE = "love-Info.plist";
-				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/../Libraries";
+				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
 				LLVM_LTO = YES;
 				MACOSX_DEPLOYMENT_TARGET = 10.5;
 				ONLY_ACTIVE_ARCH = NO;

+ 25 - 22
src/modules/graphics/opengl/Canvas.cpp

@@ -139,9 +139,7 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
 		glBindRenderbuffer(GL_RENDERBUFFER, stencil);
 		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
 
-		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-								  GL_RENDERBUFFER, stencil);
-		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
 								  GL_RENDERBUFFER, stencil);
 
 		glBindRenderbuffer(GL_RENDERBUFFER, 0);
@@ -153,8 +151,10 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
 	virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil,  GLuint img)
 	{
 		gl.deleteTexture(img);
-		glDeleteRenderbuffers(1, &depth_stencil);
-		glDeleteFramebuffers(1, &framebuffer);
+		if (depth_stencil != 0)
+			glDeleteRenderbuffers(1, &depth_stencil);
+		if (framebuffer != 0)
+			glDeleteFramebuffers(1, &framebuffer);
 	}
 
 	virtual void bindFBO(GLuint framebuffer)
@@ -192,8 +192,6 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
 			glDrawBuffers(drawbuffers.size(), &drawbuffers[0]);
 		else if (GLEE_ARB_draw_buffers)
 			glDrawBuffersARB(drawbuffers.size(), &drawbuffers[0]);
-		else if (GLEE_ATI_draw_buffers)
-			glDrawBuffersATI(drawbuffers.size(), &drawbuffers[0]);
 	}
 };
 
@@ -252,8 +250,6 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
 								 width, height);
 		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
 									 GL_RENDERBUFFER_EXT, stencil);
-		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-									 GL_RENDERBUFFER_EXT, stencil);
 
 		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
 
@@ -264,8 +260,10 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
 	virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img)
 	{
 		gl.deleteTexture(img);
-		glDeleteRenderbuffersEXT(1, &depth_stencil);
-		glDeleteFramebuffersEXT(1, &framebuffer);
+		if (depth_stencil != 0)
+			glDeleteRenderbuffersEXT(1, &depth_stencil);
+		if (framebuffer != 0)
+			glDeleteFramebuffersEXT(1, &framebuffer);
 	}
 
 	virtual void bindFBO(GLuint framebuffer)
@@ -303,8 +301,6 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
 			glDrawBuffers(drawbuffers.size(), &drawbuffers[0]);
 		else if (GLEE_ARB_draw_buffers)
 			glDrawBuffersARB(drawbuffers.size(), &drawbuffers[0]);
-		else if (GLEE_ATI_draw_buffers)
-			glDrawBuffersATI(drawbuffers.size(), &drawbuffers[0]);
 	}
 };
 
@@ -369,6 +365,9 @@ static int maxDrawBuffers = 0;
 Canvas::Canvas(int width, int height, TextureType texture_type)
 	: width(width)
 	, height(height)
+	, fbo(0)
+	, depth_stencil(0)
+	, img(0)
 	, texture_type(texture_type)
 {
 	float w = static_cast<float>(width);
@@ -423,7 +422,7 @@ bool Canvas::isHDRSupported()
 
 bool Canvas::isMultiCanvasSupported()
 {
-	if (!(isSupported() && (GLEE_VERSION_2_0 || GLEE_ARB_draw_buffers || GLEE_ATI_draw_buffers)))
+	if (!(isSupported() && (GLEE_VERSION_2_0 || GLEE_ARB_draw_buffers)))
 		return false;
 
 	if (maxFBOColorAttachments == 0 || maxDrawBuffers == 0)
@@ -548,8 +547,11 @@ void Canvas::stopGrab()
 	current = NULL;
 }
 
-void Canvas::clear(const Color &c)
+void Canvas::clear(Color c)
 {
+	if (strategy == &strategyNone)
+		return;
+
 	GLuint previous = 0;
 
 	if (current != this)
@@ -717,8 +719,9 @@ const std::vector<Canvas *> &Canvas::getAttachedCanvases() const
 
 void Canvas::setFilter(const Image::Filter &f)
 {
+	settings.filter = f;
 	gl.bindTexture(img);
-	gl.setTextureFilter(f);
+	settings.filter.anisotropy = gl.setTextureFilter(f);
 }
 
 Image::Filter Canvas::getFilter() const
@@ -729,21 +732,24 @@ Image::Filter Canvas::getFilter() const
 
 void Canvas::setWrap(const Image::Wrap &w)
 {
+	settings.wrap = w;
 	gl.bindTexture(img);
 	gl.setTextureWrap(w);
 }
 
 Image::Wrap Canvas::getWrap() const
 {
-	gl.bindTexture(img);
-	return gl.getTextureWrap();
+	return settings.wrap;
 }
 
 bool Canvas::loadVolatile()
 {
 	// glTexImage2D is guaranteed to error in this case.
 	if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize())
+	{
+		status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
 		return false;
+	}
 
 	status = strategy->createFBO(fbo, img, width, height, texture_type);
 	if (status != GL_FRAMEBUFFER_COMPLETE)
@@ -751,15 +757,12 @@ bool Canvas::loadVolatile()
 
 	setFilter(settings.filter);
 	setWrap(settings.wrap);
-	Color c(0, 0, 0, 0);
-	clear(c);
+	clear(Color(0, 0, 0, 0));
 	return true;
 }
 
 void Canvas::unloadVolatile()
 {
-	settings.filter = getFilter();
-	settings.wrap   = getWrap();
 	strategy->deleteFBO(fbo, depth_stencil, img);
 
 	for (size_t i = 0; i < attachedCanvases.size(); i++)

+ 4 - 4
src/modules/graphics/opengl/Canvas.h

@@ -60,7 +60,7 @@ public:
 	void startGrab();
 	void stopGrab();
 
-	void clear(const Color &c);
+	void clear(Color c);
 
 	virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
@@ -80,7 +80,7 @@ public:
 
 	const std::vector<Canvas *> &getAttachedCanvases() const;
 
-void setFilter(const Image::Filter &f);
+	void setFilter(const Image::Filter &f);
 	Image::Filter getFilter() const;
 
 	void setWrap(const Image::Wrap &w);
@@ -89,12 +89,12 @@ void setFilter(const Image::Filter &f);
 	int getWidth();
 	int getHeight();
 
-	unsigned int getStatus() const
+	inline GLenum getStatus() const
 	{
 		return status;
 	}
 
-	TextureType getTextureType() const
+	inline TextureType getTextureType() const
 	{
 		return texture_type;
 	}