mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Cleaned up some love.graphics code.
--HG-- branch : minor
This commit is contained in:
@@ -61,6 +61,17 @@
|
|||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct Rect
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
bool operator == (const Rect &rhs) const
|
||||||
|
{
|
||||||
|
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|||||||
@@ -224,17 +224,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScissorRect
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
bool operator == (const ScissorRect &rhs) const
|
|
||||||
{
|
|
||||||
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~Graphics();
|
virtual ~Graphics();
|
||||||
|
|
||||||
// Implements Module.
|
// Implements Module.
|
||||||
|
|||||||
@@ -21,9 +21,7 @@
|
|||||||
#include "Canvas.h"
|
#include "Canvas.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "common/Matrix.h"
|
|
||||||
|
|
||||||
#include <cstring> // For memcpy
|
|
||||||
#include <algorithm> // For min/max
|
#include <algorithm> // For min/max
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ void Graphics::restoreState(const DisplayState &s)
|
|||||||
setPointSize(s.pointSize);
|
setPointSize(s.pointSize);
|
||||||
|
|
||||||
if (s.scissor)
|
if (s.scissor)
|
||||||
setScissor(s.scissorRect.x, s.scissorRect.y, s.scissorRect.w, s.scissorRect.h);
|
setScissor(s.scissorRect);
|
||||||
else
|
else
|
||||||
setScissor();
|
setScissor();
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ void Graphics::restoreStateChecked(const DisplayState &s)
|
|||||||
if (s.scissor != cur.scissor || (s.scissor && !(s.scissorRect == cur.scissorRect)))
|
if (s.scissor != cur.scissor || (s.scissor && !(s.scissorRect == cur.scissorRect)))
|
||||||
{
|
{
|
||||||
if (s.scissor)
|
if (s.scissor)
|
||||||
setScissor(s.scissorRect.x, s.scissorRect.y, s.scissorRect.w, s.scissorRect.h);
|
setScissor(s.scissorRect);
|
||||||
else
|
else
|
||||||
setScissor();
|
setScissor();
|
||||||
}
|
}
|
||||||
@@ -829,7 +829,7 @@ void Graphics::bindCachedFBOForPass(const PassInfo &pass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (drawbuffers.size() > 1)
|
if (drawbuffers.size() > 1)
|
||||||
glDrawBuffers(1, &drawbuffers[0]);
|
glDrawBuffers((int) drawbuffers.size(), &drawbuffers[0]);
|
||||||
|
|
||||||
GLuint stencil = attachCachedStencilBuffer(w, h, info.canvases[0]->getRequestedMSAA());
|
GLuint stencil = attachCachedStencilBuffer(w, h, info.canvases[0]->getRequestedMSAA());
|
||||||
|
|
||||||
@@ -1085,10 +1085,8 @@ bool Graphics::isCreated() const
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setScissor(int x, int y, int width, int height)
|
void Graphics::setScissor(const Rect &rect)
|
||||||
{
|
{
|
||||||
ScissorRect rect = {x, y, width, height};
|
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
// OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor.
|
// OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor.
|
||||||
gl.setScissor({rect.x, rect.y, rect.w, rect.h}, currentPass.info.colorAttachmentCount > 0);
|
gl.setScissor({rect.x, rect.y, rect.w, rect.h}, currentPass.info.colorAttachmentCount > 0);
|
||||||
@@ -1097,25 +1095,26 @@ void Graphics::setScissor(int x, int y, int width, int height)
|
|||||||
states.back().scissorRect = rect;
|
states.back().scissorRect = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::intersectScissor(int x, int y, int width, int height)
|
void Graphics::intersectScissor(const Rect &rect)
|
||||||
{
|
{
|
||||||
ScissorRect rect = states.back().scissorRect;
|
Rect currect = states.back().scissorRect;
|
||||||
|
|
||||||
if (!states.back().scissor)
|
if (!states.back().scissor)
|
||||||
{
|
{
|
||||||
rect.x = 0;
|
currect.x = 0;
|
||||||
rect.y = 0;
|
currect.y = 0;
|
||||||
rect.w = std::numeric_limits<int>::max();
|
currect.w = std::numeric_limits<int>::max();
|
||||||
rect.h = std::numeric_limits<int>::max();
|
currect.h = std::numeric_limits<int>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
int x1 = std::max(rect.x, x);
|
int x1 = std::max(currect.x, rect.x);
|
||||||
int y1 = std::max(rect.y, y);
|
int y1 = std::max(currect.y, rect.y);
|
||||||
|
|
||||||
int x2 = std::min(rect.x + rect.w, x + width);
|
int x2 = std::min(currect.x + currect.w, rect.x + rect.w);
|
||||||
int y2 = std::min(rect.y + rect.h, y + height);
|
int y2 = std::min(currect.y + currect.h, rect.y + rect.h);
|
||||||
|
|
||||||
setScissor(x1, y1, std::max(0, x2 - x1), std::max(0, y2 - y1));
|
Rect newrect = {x1, y1, std::max(0, x2 - x1), std::max(0, y2 - y1)};
|
||||||
|
setScissor(newrect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setScissor()
|
void Graphics::setScissor()
|
||||||
@@ -1124,15 +1123,10 @@ void Graphics::setScissor()
|
|||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::getScissor(int &x, int &y, int &width, int &height) const
|
bool Graphics::getScissor(Rect &rect) const
|
||||||
{
|
{
|
||||||
const DisplayState &state = states.back();
|
const DisplayState &state = states.back();
|
||||||
|
rect = state.scissorRect;
|
||||||
x = state.scissorRect.x;
|
|
||||||
y = state.scissorRect.y;
|
|
||||||
width = state.scissorRect.w;
|
|
||||||
height = state.scissorRect.h;
|
|
||||||
|
|
||||||
return state.scissor;
|
return state.scissor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,14 +170,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Scissor defines a box such that everything outside that box is discarded and not drawn.
|
* Scissor defines a box such that everything outside that box is discarded and not drawn.
|
||||||
* Scissoring is automatically enabled.
|
* Scissoring is automatically enabled.
|
||||||
* @param x The x-coordinate of the top-left corner.
|
* @param rect The rectangle defining the scissor area.
|
||||||
* @param y The y-coordinate of the top-left corner.
|
|
||||||
* @param width The width of the box.
|
|
||||||
* @param height The height of the box.
|
|
||||||
**/
|
**/
|
||||||
void setScissor(int x, int y, int width, int height);
|
void setScissor(const Rect &rect);
|
||||||
|
void intersectScissor(const Rect &rect);
|
||||||
void intersectScissor(int x, int y, int width, int height);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any scissor that has been created.
|
* Clears any scissor that has been created.
|
||||||
@@ -188,7 +184,7 @@ public:
|
|||||||
* Gets the current scissor box.
|
* Gets the current scissor box.
|
||||||
* @return Whether the scissor is enabled.
|
* @return Whether the scissor is enabled.
|
||||||
*/
|
*/
|
||||||
bool getScissor(int &x, int &y, int &width, int &height) const;
|
bool getScissor(Rect &rect) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables drawing to the stencil buffer. When enabled, the
|
* Enables or disables drawing to the stencil buffer. When enabled, the
|
||||||
@@ -514,7 +510,7 @@ private:
|
|||||||
float pointSize = 1.0f;
|
float pointSize = 1.0f;
|
||||||
|
|
||||||
bool scissor = false;
|
bool scissor = false;
|
||||||
ScissorRect scissorRect = ScissorRect();
|
Rect scissorRect = Rect();
|
||||||
|
|
||||||
// Stencil.
|
// Stencil.
|
||||||
CompareMode stencilCompare = COMPARE_ALWAYS;
|
CompareMode stencilCompare = COMPARE_ALWAYS;
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ void OpenGL::useVertexAttribArrays(uint32 arraybits)
|
|||||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL::setViewport(const OpenGL::Viewport &v, bool canvasActive)
|
void OpenGL::setViewport(const Rect &v, bool canvasActive)
|
||||||
{
|
{
|
||||||
glViewport(v.x, v.y, v.w, v.h);
|
glViewport(v.x, v.y, v.w, v.h);
|
||||||
state.viewport = v;
|
state.viewport = v;
|
||||||
@@ -486,12 +486,12 @@ void OpenGL::setViewport(const OpenGL::Viewport &v, bool canvasActive)
|
|||||||
setScissor(state.scissor, canvasActive);
|
setScissor(state.scissor, canvasActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL::Viewport OpenGL::getViewport() const
|
Rect OpenGL::getViewport() const
|
||||||
{
|
{
|
||||||
return state.viewport;
|
return state.viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL::setScissor(const OpenGL::Viewport &v, bool canvasActive)
|
void OpenGL::setScissor(const Rect &v, bool canvasActive)
|
||||||
{
|
{
|
||||||
if (canvasActive)
|
if (canvasActive)
|
||||||
glScissor(v.x, v.y, v.w, v.h);
|
glScissor(v.x, v.y, v.w, v.h);
|
||||||
@@ -505,7 +505,7 @@ void OpenGL::setScissor(const OpenGL::Viewport &v, bool canvasActive)
|
|||||||
state.scissor = v;
|
state.scissor = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL::Viewport OpenGL::getScissor() const
|
Rect OpenGL::getScissor() const
|
||||||
{
|
{
|
||||||
return state.scissor;
|
return state.scissor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
// LOVE
|
// LOVE
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
|
#include "common/math.h"
|
||||||
#include "graphics/Color.h"
|
#include "graphics/Color.h"
|
||||||
#include "graphics/Texture.h"
|
#include "graphics/Texture.h"
|
||||||
#include "common/Matrix.h"
|
#include "common/Matrix.h"
|
||||||
@@ -111,18 +112,6 @@ public:
|
|||||||
FRAMEBUFFER_ALL = (FRAMEBUFFER_READ | FRAMEBUFFER_DRAW),
|
FRAMEBUFFER_ALL = (FRAMEBUFFER_READ | FRAMEBUFFER_DRAW),
|
||||||
};
|
};
|
||||||
|
|
||||||
// A rectangle representing an OpenGL viewport or a scissor box.
|
|
||||||
struct Viewport
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
bool operator == (const Viewport &rhs) const
|
|
||||||
{
|
|
||||||
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureFormat
|
struct TextureFormat
|
||||||
{
|
{
|
||||||
GLenum internalformat = 0;
|
GLenum internalformat = 0;
|
||||||
@@ -295,23 +284,23 @@ public:
|
|||||||
* Sets the OpenGL rendering viewport to the specified rectangle.
|
* Sets the OpenGL rendering viewport to the specified rectangle.
|
||||||
* The y-coordinate starts at the top.
|
* The y-coordinate starts at the top.
|
||||||
**/
|
**/
|
||||||
void setViewport(const Viewport &v, bool canvasActive);
|
void setViewport(const Rect &v, bool canvasActive);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current OpenGL rendering viewport rectangle.
|
* Gets the current OpenGL rendering viewport rectangle.
|
||||||
**/
|
**/
|
||||||
Viewport getViewport() const;
|
Rect getViewport() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the scissor box to the specified rectangle.
|
* Sets the scissor box to the specified rectangle.
|
||||||
* The y-coordinate starts at the top and is flipped internally.
|
* The y-coordinate starts at the top and is flipped internally.
|
||||||
**/
|
**/
|
||||||
void setScissor(const Viewport &v, bool canvasActive);
|
void setScissor(const Rect &v, bool canvasActive);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current scissor box (regardless of whether scissoring is enabled.)
|
* Gets the current scissor box (regardless of whether scissoring is enabled.)
|
||||||
**/
|
**/
|
||||||
Viewport getScissor() const;
|
Rect getScissor() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the global point size.
|
* Sets the global point size.
|
||||||
@@ -479,8 +468,8 @@ private:
|
|||||||
|
|
||||||
uint32 enabledAttribArrays;
|
uint32 enabledAttribArrays;
|
||||||
|
|
||||||
Viewport viewport;
|
Rect viewport;
|
||||||
Viewport scissor;
|
Rect scissor;
|
||||||
|
|
||||||
float pointSize;
|
float pointSize;
|
||||||
|
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ bool Shader::loadVolatile()
|
|||||||
|
|
||||||
// Recreating the shader program will invalidate uniforms that rely on these.
|
// Recreating the shader program will invalidate uniforms that rely on these.
|
||||||
canvasWasActive = false;
|
canvasWasActive = false;
|
||||||
lastViewport = OpenGL::Viewport();
|
lastViewport = Rect();
|
||||||
|
|
||||||
lastPointSize = -1.0f;
|
lastPointSize = -1.0f;
|
||||||
|
|
||||||
@@ -803,7 +803,7 @@ void Shader::setVideoTextures(GLuint ytexture, GLuint cbtexture, GLuint crtextur
|
|||||||
|
|
||||||
void Shader::checkSetScreenParams()
|
void Shader::checkSetScreenParams()
|
||||||
{
|
{
|
||||||
OpenGL::Viewport view = gl.getViewport();
|
Rect view = gl.getViewport();
|
||||||
|
|
||||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||||
bool canvasActive = gfx->getActivePass().colorAttachmentCount > 0;
|
bool canvasActive = gfx->getActivePass().colorAttachmentCount > 0;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ private:
|
|||||||
std::vector<TextureUnit> textureUnits;
|
std::vector<TextureUnit> textureUnits;
|
||||||
|
|
||||||
bool canvasWasActive;
|
bool canvasWasActive;
|
||||||
OpenGL::Viewport lastViewport;
|
Rect lastViewport;
|
||||||
|
|
||||||
float lastPointSize;
|
float lastPointSize;
|
||||||
|
|
||||||
|
|||||||
@@ -384,42 +384,44 @@ int w_setScissor(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = (int) luaL_checknumber(L, 1);
|
Rect rect;
|
||||||
int y = (int) luaL_checknumber(L, 2);
|
rect.x = (int) luaL_checknumber(L, 1);
|
||||||
int w = (int) luaL_checknumber(L, 3);
|
rect.y = (int) luaL_checknumber(L, 2);
|
||||||
int h = (int) luaL_checknumber(L, 4);
|
rect.w = (int) luaL_checknumber(L, 3);
|
||||||
|
rect.h = (int) luaL_checknumber(L, 4);
|
||||||
|
|
||||||
if (w < 0 || h < 0)
|
if (rect.w < 0 || rect.h < 0)
|
||||||
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
||||||
|
|
||||||
instance()->setScissor(x, y, w, h);
|
instance()->setScissor(rect);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_intersectScissor(lua_State *L)
|
int w_intersectScissor(lua_State *L)
|
||||||
{
|
{
|
||||||
int x = (int) luaL_checknumber(L, 1);
|
Rect rect;
|
||||||
int y = (int) luaL_checknumber(L, 2);
|
rect.x = (int) luaL_checknumber(L, 1);
|
||||||
int w = (int) luaL_checknumber(L, 3);
|
rect.y = (int) luaL_checknumber(L, 2);
|
||||||
int h = (int) luaL_checknumber(L, 4);
|
rect.w = (int) luaL_checknumber(L, 3);
|
||||||
|
rect.h = (int) luaL_checknumber(L, 4);
|
||||||
|
|
||||||
if (w < 0 || h < 0)
|
if (rect.w < 0 || rect.h < 0)
|
||||||
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
||||||
|
|
||||||
instance()->intersectScissor(x, y, w, h);
|
instance()->intersectScissor(rect);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_getScissor(lua_State *L)
|
int w_getScissor(lua_State *L)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
Rect rect;
|
||||||
if (!instance()->getScissor(x, y, w, h))
|
if (!instance()->getScissor(rect))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lua_pushinteger(L, x);
|
lua_pushinteger(L, rect.x);
|
||||||
lua_pushinteger(L, y);
|
lua_pushinteger(L, rect.y);
|
||||||
lua_pushinteger(L, w);
|
lua_pushinteger(L, rect.w);
|
||||||
lua_pushinteger(L, h);
|
lua_pushinteger(L, rect.h);
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user