Commits

vrld  committed a7d0adb

Add framebuffer filter modes (issue #112)

  • Participants
  • Parent commits 64aa658

Comments (0)

Files changed (4)

File src/modules/graphics/opengl/Framebuffer.cpp

 
 		return img;
 	}
-	
+
+	void Framebuffer::setFilter(Image::Filter f)
+	{
+		GLint gmin = (f.min == Image::FILTER_NEAREST) ? GL_NEAREST : GL_LINEAR;
+		GLint gmag = (f.mag == Image::FILTER_NEAREST) ? GL_NEAREST : GL_LINEAR;
+
+		glBindTexture(GL_TEXTURE_2D, img);
+
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gmin);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gmag);
+	}
+
+	Image::Filter Framebuffer::getFilter() const
+	{
+		GLint gmin, gmag;
+
+		glBindTexture(GL_TEXTURE_2D, img);
+		glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &gmin);
+		glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &gmag);
+
+		Image::Filter f;
+		f.min = (gmin == GL_NEAREST) ? Image::FILTER_NEAREST : Image::FILTER_LINEAR;
+		f.mag = (gmag == GL_NEAREST) ? Image::FILTER_NEAREST : Image::FILTER_LINEAR;
+		return f;
+	}
+
 	bool Framebuffer::loadVolatile()
 	{
 		status = strategy->createFBO(fbo, depthbuffer, img, width, height);
+		if (status == GL_FRAMEBUFFER_COMPLETE)
+			setFilter(settings.filter);
+
 		return (status == GL_FRAMEBUFFER_COMPLETE);
 	}
 	
 	void Framebuffer::unloadVolatile()
 	{
+		settings.filter = getFilter();
 		strategy->deleteFBO(fbo, depthbuffer, img);
 	}
 

File src/modules/graphics/opengl/Framebuffer.h

 
 #include <graphics/Drawable.h>
 #include <graphics/Volatile.h>
+#include <graphics/Image.h>
 #include <image/Image.h>
 #include <image/ImageData.h>
 #include <common/math.h>
 
 		virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
 		love::image::ImageData * getImageData(love::image::Image * image);
-		
+
+		void setFilter(Image::Filter f);
+		Image::Filter getFilter() const;
+
 		bool loadVolatile();
 		void unloadVolatile();
 
 		vertex vertices[4];
 
 		GLenum status;
+
+		struct {
+			Image::Filter filter;
+		} settings;
 	};
 
 } // opengl

File src/modules/graphics/opengl/wrap_Framebuffer.cpp

 		return 1;
 	}
 
+	int w_Framebuffer_setFilter(lua_State * L)
+	{
+		Framebuffer * fbo = luax_checkfbo(L, 1);
+		const char * minstr = luaL_checkstring(L, 2);
+		const char * magstr = luaL_checkstring(L, 3);
+
+		Image::Filter f;
+		if (!Image::getConstant(minstr, f.min))
+			return luaL_error(L, "Invalid min filter mode: %s", minstr);
+		if (!Image::getConstant(magstr, f.mag))
+			return luaL_error(L, "Invalid max filter mode: %s", minstr);
+
+		fbo->setFilter(f);
+		return 0;
+	}
+
+	int w_Framebuffer_getFilter(lua_State * L)
+	{
+		Framebuffer * fbo = luax_checkfbo(L, 1);
+		Image::Filter f = fbo->getFilter();
+
+		const char * minstr;
+		const char * magstr;
+		Image::getConstant(f.min, minstr);
+		Image::getConstant(f.mag, magstr);
+
+		lua_pushstring(L, minstr);
+		lua_pushstring(L, magstr);
+
+		return 2;
+	}
+
 	static const luaL_Reg functions[] = {
 		{ "renderTo", w_Framebuffer_renderTo },
 		{ "getImageData", w_Framebuffer_getImageData },
+		{ "setFilter", w_Framebuffer_setFilter },
+		{ "getFilter", w_Framebuffer_getFilter },
 		{ 0, 0 }
 	};
 

File src/modules/graphics/opengl/wrap_Framebuffer.h

 	Framebuffer * luax_checkfbo(lua_State * L, int idx);
 	int w_Framebuffer_renderTo(lua_State * L);
 	int w_Framebuffer_getImageData(lua_State * L);
+	int w_Framebuffer_setFilter(lua_State * L);
+	int w_Framebuffer_getFilter(lua_State * L);
 	int luaopen_framebuffer(lua_State * L);
 
 } // opengl