Browse Source

Allow disabling stencil capabilities for the main screen in love.window.setMode.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
5243fb5a85

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

@@ -338,7 +338,7 @@ public:
 	 * @param width The viewport width.
 	 * @param height The viewport height.
 	 **/
-	virtual bool setMode(int width, int height, int pixelwidth, int pixelheight) = 0;
+	virtual bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) = 0;
 
 	/**
 	 * Un-sets the current graphics display mode (uninitializing objects if

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

@@ -55,6 +55,7 @@ namespace opengl
 
 Graphics::Graphics()
 	: quadIndices(nullptr)
+	, windowHasStencil(false)
 {
 	gl = OpenGL();
 
@@ -69,11 +70,15 @@ Graphics::Graphics()
 
 		if (window->isOpen())
 		{
-			double w = window->getWidth();
-			double h = window->getHeight();
-			window->windowToDPICoords(&w, &h);
+			int w, h;
+			love::window::WindowSettings settings;
+			window->getWindow(w, h, settings);
 
-			setMode((int) w, (int) h, window->getPixelWidth(), window->getPixelHeight());
+			double dpiW = w;
+			double dpiH = h;
+			window->windowToDPICoords(&dpiW, &dpiH);
+
+			setMode((int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil);
 		}
 	}
 }
@@ -200,7 +205,7 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh
 	}
 }
 
-bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight)
+bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil)
 {
 	this->width = width;
 	this->height = height;
@@ -1103,6 +1108,9 @@ void Graphics::setScissor()
 
 void Graphics::drawToStencilBuffer(StencilAction action, int value)
 {
+	if (states.back().canvases.empty() && !windowHasStencil)
+		throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer.");
+
 	flushStreamDraws();
 
 	writingToStencil = true;
@@ -1161,6 +1169,9 @@ void Graphics::stopDrawToStencilBuffer()
 
 void Graphics::setStencilTest(CompareMode compare, int value)
 {
+	if (compare != COMPARE_ALWAYS && states.back().canvases.empty() && !windowHasStencil)
+		throw love::Exception("The window must have stenciling enabled to use setStencilTest on the main screen.");
+
 	DisplayState &state = states.back();
 
 	if (state.stencilCompare != compare || state.stencilTestValue != value)

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

@@ -89,7 +89,7 @@ public:
 	Video *newVideo(love::video::VideoStream *stream, float pixeldensity);
 
 	void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
-	bool setMode(int width, int height, int pixelwidth, int pixelheight) override;
+	bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override;
 	void unSetMode() override;
 
 	void setActive(bool active) override;
@@ -155,6 +155,8 @@ private:
 
 	QuadIndices *quadIndices;
 
+	bool windowHasStencil;
+
 }; // Graphics
 
 } // opengl

+ 1 - 1
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -204,7 +204,7 @@ int w_getPixelDensity(lua_State *L)
 int w_setCanvas(lua_State *L)
 {
 	// Disable stencil writes.
-	instance()->stopDrawToStencilBuffer();
+	luax_catchexcept(L, [](){ instance()->stopDrawToStencilBuffer(); });
 
 	// called with none -> reset to default buffer
 	if (lua_isnoneornil(L, 1))

+ 2 - 0
src/modules/window/Window.cpp

@@ -70,6 +70,8 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
 	{"fullscreentype", SETTING_FULLSCREEN_TYPE},
 	{"vsync", SETTING_VSYNC},
 	{"msaa", SETTING_MSAA},
+	{"stencil", SETTING_STENCIL},
+	{"depth", SETTING_DEPTH},
 	{"resizable", SETTING_RESIZABLE},
 	{"minwidth", SETTING_MIN_WIDTH},
 	{"minheight", SETTING_MIN_HEIGHT},

+ 4 - 0
src/modules/window/Window.h

@@ -56,6 +56,8 @@ public:
 		SETTING_FULLSCREEN_TYPE,
 		SETTING_VSYNC,
 		SETTING_MSAA,
+		SETTING_STENCIL,
+		SETTING_DEPTH,
 		SETTING_RESIZABLE,
 		SETTING_MIN_WIDTH,
 		SETTING_MIN_HEIGHT,
@@ -219,6 +221,8 @@ struct WindowSettings
 	Window::FullscreenType fstype = Window::FULLSCREEN_DESKTOP;
 	int vsync = 1;
 	int msaa = 0;
+	bool stencil = true;
+	int depth = 0;
 	bool resizable = false;
 	int minwidth = 1;
 	int minheight = 1;

+ 13 - 9
src/modules/window/sdl/Window.cpp

@@ -89,7 +89,7 @@ void Window::setGraphics(graphics::Graphics *graphics)
 	this->graphics.set(graphics);
 }
 
-void Window::setGLFramebufferAttributes(int msaa, bool sRGB)
+void Window::setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth)
 {
 	// Set GL window / framebuffer attributes.
 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@@ -97,7 +97,8 @@ void Window::setGLFramebufferAttributes(int msaa, bool sRGB)
 	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
 	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil ? 8 : 0);
+	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth);
 	SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
 
 	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0);
@@ -267,7 +268,7 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
 	return attribslist;
 }
 
-bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa)
+bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool stencil, int depth)
 {
 	std::vector<ContextAttribs> attribslist = getContextAttribsList();
 
@@ -332,7 +333,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 		int curMSAA  = msaa;
 		bool curSRGB = love::graphics::isGammaCorrect();
 
-		setGLFramebufferAttributes(curMSAA, curSRGB);
+		setGLFramebufferAttributes(curMSAA, curSRGB, stencil, depth);
 		setGLContextAttributes(attribs);
 
 		windowerror.clear();
@@ -343,7 +344,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 		if (!window && curMSAA > 0)
 		{
 			// The MSAA setting could have caused the failure.
-			setGLFramebufferAttributes(0, curSRGB);
+			setGLFramebufferAttributes(0, curSRGB, stencil, depth);
 			if (create(attribs))
 				curMSAA = 0;
 		}
@@ -351,7 +352,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 		if (!window && curSRGB)
 		{
 			// same with sRGB.
-			setGLFramebufferAttributes(curMSAA, false);
+			setGLFramebufferAttributes(curMSAA, false, stencil, depth);
 			if (create(attribs))
 				curSRGB = false;
 		}
@@ -359,7 +360,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 		if (!window && curMSAA > 0 && curSRGB)
 		{
 			// Or both!
-			setGLFramebufferAttributes(0, false);
+			setGLFramebufferAttributes(0, false, stencil, depth);
 			if (create(attribs))
 			{
 				curMSAA = 0;
@@ -494,7 +495,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 
 	close();
 
-	if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa))
+	if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa, f.stencil, f.depth))
 		return false;
 
 	// Make sure the window keeps any previously set icon.
@@ -524,7 +525,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 	{
 		double scaledw, scaledh;
 		fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh);
-		graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight);
+		graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil);
 	}
 
 #ifdef LOVE_ANDROID
@@ -609,6 +610,9 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi
 	settings.msaa = (buffers > 0 ? samples : 0);
 	settings.vsync = SDL_GL_GetSwapInterval();
 
+	settings.stencil = newsettings.stencil;
+	settings.depth = newsettings.depth;
+
 	SDL_DisplayMode dmode = {};
 	SDL_GetCurrentDisplayMode(settings.display, &dmode);
 

+ 2 - 2
src/modules/window/sdl/Window.h

@@ -127,11 +127,11 @@ private:
 		bool debug;
 	};
 
-	void setGLFramebufferAttributes(int msaa, bool sRGB);
+	void setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth);
 	void setGLContextAttributes(const ContextAttribs &attribs);
 	bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion);
 	std::vector<ContextAttribs> getContextAttribsList() const;
-	bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa);
+	bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool stencil, int depth);
 
 	// Update the saved window settings based on the window's actual state.
 	void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport);

+ 8 - 0
src/modules/window/wrap_Window.cpp

@@ -83,6 +83,8 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings)
 
 	settings.fullscreen = luax_boolflag(L, idx, settingName(Window::SETTING_FULLSCREEN), settings.fullscreen);
 	settings.msaa = luax_intflag(L, idx, settingName(Window::SETTING_MSAA), settings.msaa);
+	settings.stencil = luax_boolflag(L, idx, settingName(Window::SETTING_STENCIL), settings.stencil);
+	settings.depth = luax_intflag(L, idx, settingName(Window::SETTING_DEPTH), settings.depth);
 	settings.resizable = luax_boolflag(L, idx, settingName(Window::SETTING_RESIZABLE), settings.resizable);
 	settings.minwidth = luax_intflag(L, idx, settingName(Window::SETTING_MIN_WIDTH), settings.minwidth);
 	settings.minheight = luax_intflag(L, idx, settingName(Window::SETTING_MIN_HEIGHT), settings.minheight);
@@ -186,6 +188,12 @@ int w_getMode(lua_State *L)
 	lua_pushinteger(L, settings.msaa);
 	lua_setfield(L, -2, settingName(Window::SETTING_MSAA));
 
+	luax_pushboolean(L, settings.stencil);
+	lua_setfield(L, -2, settingName(Window::SETTING_STENCIL));
+
+	lua_pushinteger(L, settings.depth);
+	lua_setfield(L, -2, settingName(Window::SETTING_DEPTH));
+
 	luax_pushboolean(L, settings.resizable);
 	lua_setfield(L, -2, settingName(Window::SETTING_RESIZABLE));
 

+ 2 - 0
src/scripts/boot.lua

@@ -473,6 +473,8 @@ function love.init()
 			fullscreentype = c.window.fullscreentype,
 			vsync = c.window.vsync,
 			msaa = c.window.msaa,
+			stencil = c.window.stencil,
+			depth = c.window.depth,
 			resizable = c.window.resizable,
 			minwidth = c.window.minwidth,
 			minheight = c.window.minheight,

+ 5 - 1
src/scripts/boot.lua.h

@@ -27,7 +27,7 @@ const unsigned char boot_lua[] =
 
 	0x2d, 0x2d, 0x5b, 0x5b, 0x0a,
 	0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 
-	0x2d, 0x32, 0x30, 0x31, 0x36, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 
+	0x2d, 0x32, 0x30, 0x31, 0x37, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 
 	0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a,
 	0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 
 	0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77, 
@@ -874,6 +874,10 @@ const unsigned char boot_lua[] =
 	0x77, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 
 	0x2e, 0x6d, 0x73, 0x61, 0x61, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 
+	0x64, 0x6f, 0x77, 0x2e, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x69, 0x6c, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 
+	0x77, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 
 	0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69,