Commits

Alex Szpakowski  committed 17d21f1

Added a built-in variable readable in shaders: ‘love_ScreenSize’. Its x and y components contain the width and height of the current viewport. Resolves issue #841.

  • Participants
  • Parent commits d32f273

Comments (0)

Files changed (5)

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

 		Viewport(int _x, int _y, int _w, int _h)
 			: x(_x), y(_y), w(_w), h(_h)
 		{}
+
+		bool operator == (const Viewport &rhs) const
+		{
+			return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
+		}
 	};
 
 	OpenGL();

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

 	, builtinUniforms()
 	, vertexAttributes()
 	, lastCanvas((Canvas *) -1)
+	, lastViewport()
 {
 	if (shaderSources.empty())
 		throw love::Exception("Cannot create shader: no source code!");
 
 void Shader::checkSetScreenParams()
 {
-	if (lastCanvas == Canvas::current)
+	OpenGL::Viewport view = gl.getViewport();
+
+	if (view == lastViewport && lastCanvas == Canvas::current)
 		return;
 
-	// In the shader, we do pixcoord.y = gl_FragCoord.y * params[0] + params[1].
+	// In the shader, we do pixcoord.y = gl_FragCoord.y * params.z + params.w.
 	// This lets us flip pixcoord.y when needed, to be consistent (Canvases
 	// have flipped y-values for pixel coordinates.)
-	GLfloat params[] = {0.0f, 0.0f};
+	GLfloat params[] = {
+		(GLfloat) view.w, (GLfloat) view.h,
+		0.0f, 0.0f,
+	};
 
 	if (Canvas::current != nullptr)
 	{
 		// gl_FragCoord.y is flipped in Canvases, so we un-flip:
 		// pixcoord.y = gl_FragCoord.y * -1.0 + height.
-		params[0] = -1.0f;
-		params[1] = (float) Canvas::current->getHeight();
+		params[2] = -1.0f;
+		params[3] = (GLfloat) view.h;
 	}
 	else
 	{
 		// No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0.
-		params[0] = 1.0f;
-		params[1] = 0.0f;
+		params[2] = 1.0f;
+		params[3] = 0.0f;
 	}
 
-	sendBuiltinFloat(BUILTIN_SCREEN_PARAMS, 2, params, 1);
+	sendBuiltinFloat(BUILTIN_SCREEN_SIZE, 4, params, 1);
+
 	lastCanvas = Canvas::current;
+	lastViewport = view;
 }
 
 const std::map<std::string, Object *> &Shader::getBoundRetainables() const
 
 StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
 {
-	{"love_ScreenParams", Shader::BUILTIN_SCREEN_PARAMS},
+	{"love_ScreenSize", Shader::BUILTIN_SCREEN_SIZE},
 };
 
 StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM> Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries));

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

 	// Built-in extern (uniform) variables.
 	enum BuiltinExtern
 	{
-		BUILTIN_SCREEN_PARAMS,
+		BUILTIN_SCREEN_SIZE,
 		BUILTIN_MAX_ENUM
 	};
 
 
 	// Pointer to the active Canvas when the screen params were last checked.
 	Canvas *lastCanvas;
+	OpenGL::Viewport lastViewport;
 
 	// Max GPU texture units available for sent images
 	static GLint maxTexUnits;

File src/scripts/graphics.lua

 #define TransformProjectionMatrix gl_ModelViewProjectionMatrix
 #define NormalMatrix gl_NormalMatrix
 uniform sampler2D _tex0_;
-uniform vec2 love_ScreenParams;]]
+uniform vec4 love_ScreenSize;]]
 
 	local GLSL_VERTEX = {
 		HEADER = [[
 	float dummy = texture2D(_tex0_, vec2(.5)).r;
 
 	// See Shader::checkSetScreenParams in Shader.cpp.
-	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]);
+	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
 
 	gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
 }]],
 	float dummy = texture2D(_tex0_, vec2(.5)).r;
 
 	// See Shader::checkSetScreenParams in Shader.cpp.
-	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]);
+	vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
 
 	effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
 }]],

File src/scripts/graphics.lua.h

 	0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a,
 	0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 
 	0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a,
-	0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 
-	0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3b, 0x5d, 0x5d, 0x0a,
+	0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 
+	0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x5d, 0x5d, 0x0a,
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 
 	0x20, 0x3d, 0x20, 0x7b, 0x0a,
 	0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
 	0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 
 	0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 
 	0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 
-	0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 
-	0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 
-	0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a,
+	0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a, 
+	0x65, 0x2e, 0x7a, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 
+	0x53, 0x69, 0x7a, 0x65, 0x2e, 0x77, 0x29, 0x3b, 0x0a,
 	0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 0x66, 
 	0x66, 0x65, 0x63, 0x74, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 
 	0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 
 	0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 
 	0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 
 	0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 
-	0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 
-	0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 
-	0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a,
+	0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a, 
+	0x65, 0x2e, 0x7a, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 
+	0x53, 0x69, 0x7a, 0x65, 0x2e, 0x77, 0x29, 0x3b, 0x0a,
 	0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 
 	0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 
 	0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x70, 0x69, 0x78,