From 5243fb5a858b98fb55d0c02f0de53d95b28e5cc1 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 5 Jan 2017 19:40:18 -0400 Subject: [PATCH] Allow disabling stencil capabilities for the main screen in love.window.setMode. --HG-- branch : minor --- src/modules/graphics/Graphics.h | 2 +- src/modules/graphics/opengl/Graphics.cpp | 21 +++++++++++++----- src/modules/graphics/opengl/Graphics.h | 4 +++- src/modules/graphics/opengl/wrap_Graphics.cpp | 2 +- src/modules/window/Window.cpp | 2 ++ src/modules/window/Window.h | 4 ++++ src/modules/window/sdl/Window.cpp | 22 +++++++++++-------- src/modules/window/sdl/Window.h | 4 ++-- src/modules/window/wrap_Window.cpp | 8 +++++++ src/scripts/boot.lua | 2 ++ src/scripts/boot.lua.h | 6 ++++- 11 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 0d45d71e2..35787e855 100644 --- a/src/modules/graphics/Graphics.h +++ b/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 diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index b76fe2700..d22eee97b 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/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) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 1a0df46e8..c05ce7151 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/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 diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 02a7a70e3..9e3a26f75 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/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)) diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index 96a14b9e8..eac579a34 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -70,6 +70,8 @@ StringMap::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}, diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 2d9de8779..890efdb54 100644 --- a/src/modules/window/Window.h +++ b/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; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 7b54de242..b3ed774f1 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/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::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 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); diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 2f64511cc..ebf9e660a 100644 --- a/src/modules/window/sdl/Window.h +++ b/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 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); diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 1b1cd8321..52d8c8165 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/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)); diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index 06d9cba8e..004d7f159 100644 --- a/src/scripts/boot.lua +++ b/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, diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index ad163e92e..8d26fb3ec 100644 --- a/src/scripts/boot.lua.h +++ b/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,