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.

This commit is contained in:
Alex Szpakowski
2014-01-27 02:58:34 -04:00
parent 3a24e73891
commit c5c788e976
5 changed files with 35 additions and 21 deletions
+5
View File
@@ -87,6 +87,11 @@ public:
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();
+17 -9
View File
@@ -72,6 +72,7 @@ Shader::Shader(const ShaderSources &sources)
, builtinUniforms()
, vertexAttributes()
, lastCanvas((Canvas *) -1)
, lastViewport()
{
if (shaderSources.empty())
throw love::Exception("Cannot create shader: no source code!");
@@ -693,30 +694,37 @@ bool Shader::sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *ve
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
@@ -767,7 +775,7 @@ StringMap<OpenGL::VertexAttrib, OpenGL::ATTRIB_MAX_ENUM> Shader::attribNames(Sha
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));
+2 -1
View File
@@ -59,7 +59,7 @@ public:
// Built-in extern (uniform) variables.
enum BuiltinExtern
{
BUILTIN_SCREEN_PARAMS,
BUILTIN_SCREEN_SIZE,
BUILTIN_MAX_ENUM
};
@@ -216,6 +216,7 @@ private:
// 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;