소스 검색

Add optional ‘readable’ boolean field to the table passed into love.graphics.newCanvas. Added new variant of love.graphics.getCanvasFormats which takes a ‘readable’ boolean.

--HG--
branch : minor
Alex Szpakowski 8 년 전
부모
커밋
43172bd3f6

+ 8 - 0
src/modules/graphics/Canvas.h

@@ -39,6 +39,13 @@ public:
 
 
 	struct Settings
 	struct Settings
 	{
 	{
+		// Defaults to true for color pixel formats, and false for depth/stencil.
+		struct Readable
+		{
+			bool set = false;
+			bool value = false;
+		};
+
 		int width  = 1;
 		int width  = 1;
 		int height = 1;
 		int height = 1;
 		int layers = 1; // depth for 3D textures
 		int layers = 1; // depth for 3D textures
@@ -46,6 +53,7 @@ public:
 		TextureType type = TEXTURE_2D;
 		TextureType type = TEXTURE_2D;
 		float pixeldensity = 1.0f;
 		float pixeldensity = 1.0f;
 		int msaa = 0;
 		int msaa = 0;
+		Readable readable;
 	};
 	};
 
 
 	Canvas(TextureType textype);
 	Canvas(TextureType textype);

+ 1 - 0
src/modules/graphics/Graphics.h

@@ -723,6 +723,7 @@ public:
 	 * Images.
 	 * Images.
 	 **/
 	 **/
 	virtual bool isCanvasFormatSupported(PixelFormat format) const = 0;
 	virtual bool isCanvasFormatSupported(PixelFormat format) const = 0;
+	virtual bool isCanvasFormatSupported(PixelFormat format, bool readable) const = 0;
 	virtual bool isImageFormatSupported(PixelFormat format) const = 0;
 	virtual bool isImageFormatSupported(PixelFormat format) const = 0;
 
 
 	/**
 	/**

+ 12 - 6
src/modules/graphics/opengl/Canvas.cpp

@@ -165,7 +165,11 @@ Canvas::Canvas(const Settings &settings)
 		throw love::Exception("MSAA is only supported for Canvases with the 2D texture type.");
 		throw love::Exception("MSAA is only supported for Canvases with the 2D texture type.");
 
 
 	format = getSizedFormat(settings.format);
 	format = getSizedFormat(settings.format);
-	readable = !isPixelFormatDepthStencil(format);
+
+	if (settings.readable.set)
+		readable = settings.readable.value;
+	else
+		readable = !isPixelFormatDepthStencil(format);
 
 
 	initQuad();
 	initQuad();
 	loadVolatile();
 	loadVolatile();
@@ -187,7 +191,7 @@ bool Canvas::loadVolatile()
 	if (!Canvas::isSupported())
 	if (!Canvas::isSupported())
 		throw love::Exception("Canvases are not supported by your OpenGL drivers!");
 		throw love::Exception("Canvases are not supported by your OpenGL drivers!");
 
 
-	if (!Canvas::isFormatSupported(format))
+	if (!Canvas::isFormatSupported(format, readable))
 	{
 	{
 		const char *fstr = "rgba8";
 		const char *fstr = "rgba8";
 		love::getConstant(Canvas::getSizedFormat(format), fstr);
 		love::getConstant(Canvas::getSizedFormat(format), fstr);
@@ -488,6 +492,11 @@ Canvas::SupportedFormat Canvas::supportedFormats[] = {};
 Canvas::SupportedFormat Canvas::checkedFormats[] = {};
 Canvas::SupportedFormat Canvas::checkedFormats[] = {};
 
 
 bool Canvas::isFormatSupported(PixelFormat format)
 bool Canvas::isFormatSupported(PixelFormat format)
+{
+	return isFormatSupported(format, !isPixelFormatDepthStencil(format));
+}
+
+bool Canvas::isFormatSupported(PixelFormat format, bool readable)
 {
 {
 	if (!isSupported())
 	if (!isSupported())
 		return false;
 		return false;
@@ -498,9 +507,6 @@ bool Canvas::isFormatSupported(PixelFormat format)
 	bool supported = true;
 	bool supported = true;
 	format = getSizedFormat(format);
 	format = getSizedFormat(format);
 
 
-	bool depthstencil = isPixelFormatDepthStencil(format);
-	bool readable = !depthstencil;
-
 	if (!OpenGL::isPixelFormatSupported(format, true, readable, false))
 	if (!OpenGL::isPixelFormatSupported(format, true, readable, false))
 		return false;
 		return false;
 
 
@@ -525,7 +531,7 @@ bool Canvas::isFormatSupported(PixelFormat format)
 
 
 	// Make sure at least something is bound to a color attachment. I believe
 	// Make sure at least something is bound to a color attachment. I believe
 	// this is required on ES2 but I'm not positive.
 	// this is required on ES2 but I'm not positive.
-	if (depthstencil)
+	if (isPixelFormatDepthStencil(format))
 		gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, 0, 0);
 		gl.framebufferTexture(GL_COLOR_ATTACHMENT0, TEXTURE_2D, gl.getDefaultTexture(TEXTURE_2D), 0, 0, 0);
 
 
 	if (readable)
 	if (readable)

+ 1 - 0
src/modules/graphics/opengl/Canvas.h

@@ -82,6 +82,7 @@ public:
 	static PixelFormat getSizedFormat(PixelFormat format);
 	static PixelFormat getSizedFormat(PixelFormat format);
 	static bool isSupported();
 	static bool isSupported();
 	static bool isMultiFormatMultiCanvasSupported();
 	static bool isMultiFormatMultiCanvasSupported();
+	static bool isFormatSupported(PixelFormat format, bool readable);
 	static bool isFormatSupported(PixelFormat format);
 	static bool isFormatSupported(PixelFormat format);
 
 
 private:
 private:

+ 5 - 0
src/modules/graphics/opengl/Graphics.cpp

@@ -1487,6 +1487,11 @@ bool Graphics::isCanvasFormatSupported(PixelFormat format) const
 	return Canvas::isFormatSupported(format);
 	return Canvas::isFormatSupported(format);
 }
 }
 
 
+bool Graphics::isCanvasFormatSupported(PixelFormat format, bool readable) const
+{
+	return Canvas::isFormatSupported(format, readable);
+}
+
 bool Graphics::isImageFormatSupported(PixelFormat format) const
 bool Graphics::isImageFormatSupported(PixelFormat format) const
 {
 {
 	return Image::isFormatSupported(format);
 	return Image::isFormatSupported(format);

+ 1 - 0
src/modules/graphics/opengl/Graphics.h

@@ -122,6 +122,7 @@ public:
 	bool isSupported(Feature feature) const override;
 	bool isSupported(Feature feature) const override;
 	double getSystemLimit(SystemLimit limittype) const override;
 	double getSystemLimit(SystemLimit limittype) const override;
 	bool isCanvasFormatSupported(PixelFormat format) const override;
 	bool isCanvasFormatSupported(PixelFormat format) const override;
+	bool isCanvasFormatSupported(PixelFormat format, bool readable) const override;
 	bool isImageFormatSupported(PixelFormat format) const override;
 	bool isImageFormatSupported(PixelFormat format) const override;
 	Renderer getRenderer() const override;
 	Renderer getRenderer() const override;
 	RendererInfo getRendererInfo() const override;
 	RendererInfo getRendererInfo() const override;

+ 19 - 4
src/modules/graphics/opengl/OpenGL.cpp

@@ -1635,17 +1635,32 @@ bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget,
 		return rendertarget && !readable;
 		return rendertarget && !readable;
 
 
 	case PIXELFORMAT_DEPTH16:
 	case PIXELFORMAT_DEPTH16:
-		return rendertarget && !readable;
+		if (!rendertarget)
+			return false;
+		else if (readable)
+			return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth_texture;
+		else
+			return true;
 
 
 	case PIXELFORMAT_DEPTH24:
 	case PIXELFORMAT_DEPTH24:
-		return rendertarget && !readable && (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth24 || GLAD_OES_packed_depth_stencil);
+		if (!rendertarget)
+			return false;
+		else if (readable)
+			return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || (GLAD_OES_depth_texture && (GLAD_OES_depth24 || GLAD_OES_depth_texture));
+		else
+			return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth24 || GLAD_OES_depth_texture;
 
 
 	case PIXELFORMAT_DEPTH24_STENCIL8:
 	case PIXELFORMAT_DEPTH24_STENCIL8:
-		return rendertarget && !readable && (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil);
+		if (!rendertarget)
+			return false;
+		else if (readable)
+			return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || (GLAD_OES_depth_texture && GLAD_OES_packed_depth_stencil);
+		else
+			return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil;
 
 
 	case PIXELFORMAT_DEPTH32F:
 	case PIXELFORMAT_DEPTH32F:
 	case PIXELFORMAT_DEPTH32F_STENCIL8:
 	case PIXELFORMAT_DEPTH32F_STENCIL8:
-		return rendertarget && !readable && (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_depth_buffer_float);
+		return rendertarget && (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_depth_buffer_float);
 
 
 	case PIXELFORMAT_DXT1:
 	case PIXELFORMAT_DXT1:
 		return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1;
 		return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1;

+ 36 - 3
src/modules/graphics/wrap_Graphics.cpp

@@ -1039,6 +1039,15 @@ int w_newCanvas(lua_State *L)
 				return luaL_error(L, "Invalid texture type: %s", str);
 				return luaL_error(L, "Invalid texture type: %s", str);
 		}
 		}
 		lua_pop(L, 1);
 		lua_pop(L, 1);
+
+		lua_getfield(L, startidx, "readable");
+		if (!lua_isnoneornil(L, -1))
+		{
+			luaL_checktype(L, -1, LUA_TBOOLEAN);
+			settings.readable.set = true;
+			settings.readable.value = luax_toboolean(L, -1);
+		}
+		lua_pop(L, 1);
 	}
 	}
 
 
 	Canvas *canvas = nullptr;
 	Canvas *canvas = nullptr;
@@ -1873,10 +1882,34 @@ static int w__getFormats(lua_State *L, bool (*isFormatSupported)(PixelFormat), b
 
 
 int w_getCanvasFormats(lua_State *L)
 int w_getCanvasFormats(lua_State *L)
 {
 {
-	const auto supported = [](PixelFormat format) -> bool
+	bool (*supported)(PixelFormat);
+
+	if (!lua_isnoneornil(L, 1))
 	{
 	{
-		return instance()->isCanvasFormatSupported(format);
-	};
+		luaL_checktype(L, 1, LUA_TBOOLEAN);
+
+		if (luax_toboolean(L, 1))
+		{
+			supported = [](PixelFormat format) -> bool
+			{
+				return instance()->isCanvasFormatSupported(format, true);
+			};
+		}
+		else
+		{
+			supported = [](PixelFormat format) -> bool
+			{
+				return instance()->isCanvasFormatSupported(format, false);
+			};
+		}
+	}
+	else
+	{
+		supported = [](PixelFormat format) -> bool
+		{
+			return instance()->isCanvasFormatSupported(format);
+		};
+	}
 
 
 	return w__getFormats(L, supported, isPixelFormatCompressed);
 	return w__getFormats(L, supported, isPixelFormatCompressed);
 }
 }