mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
Added stack type enums to love.graphics.push (resolves issue #906.) Current enums are "transform" and "all". "transform" is the default (for compatibility.) When love.graphics.push("all") is used, love.graphics.pop() will restore all love.graphics module state to what it was when push was called.
Updated the graphics code to use a custom matrix stack rather than OpenGL1's APIs.
This commit is contained in:
@@ -109,6 +109,16 @@ bool Graphics::getConstant(SystemLimit in, const char *&out)
|
||||
return systemLimits.find(in, out);
|
||||
}
|
||||
|
||||
bool Graphics::getConstant(const char *in, StackType &out)
|
||||
{
|
||||
return stackTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Graphics::getConstant(StackType in, const char *&out)
|
||||
{
|
||||
return stackTypes.find(in, out);
|
||||
}
|
||||
|
||||
StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
|
||||
{
|
||||
{ "line", Graphics::DRAW_LINE },
|
||||
@@ -192,5 +202,13 @@ StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM>::Entry Graphics::syst
|
||||
|
||||
StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM> Graphics::systemLimits(Graphics::systemLimitEntries, sizeof(Graphics::systemLimitEntries));
|
||||
|
||||
StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM>::Entry Graphics::stackTypeEntries[] =
|
||||
{
|
||||
{"all", Graphics::STACK_ALL},
|
||||
{"transform", Graphics::STACK_TRANSFORM},
|
||||
};
|
||||
|
||||
StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -112,6 +112,13 @@ public:
|
||||
LIMIT_MAX_ENUM
|
||||
};
|
||||
|
||||
enum StackType
|
||||
{
|
||||
STACK_ALL,
|
||||
STACK_TRANSFORM,
|
||||
STACK_MAX_ENUM
|
||||
};
|
||||
|
||||
struct RendererInfo
|
||||
{
|
||||
std::string name;
|
||||
@@ -167,6 +174,9 @@ public:
|
||||
static bool getConstant(const char *in, SystemLimit &out);
|
||||
static bool getConstant(SystemLimit in, const char *&out);
|
||||
|
||||
static bool getConstant(const char *in, StackType &out);
|
||||
static bool getConstant(StackType in, const char *&out);
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
|
||||
@@ -193,6 +203,9 @@ private:
|
||||
static StringMap<SystemLimit, LIMIT_MAX_ENUM>::Entry systemLimitEntries[];
|
||||
static StringMap<SystemLimit, LIMIT_MAX_ENUM> systemLimits;
|
||||
|
||||
static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
|
||||
static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
|
||||
|
||||
}; // Graphics
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -594,16 +594,13 @@ void Canvas::unloadVolatile()
|
||||
fbo = depth_stencil = texture = 0;
|
||||
resolve_fbo = msaa_buffer = 0;
|
||||
|
||||
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
||||
attachedCanvases[i]->release();
|
||||
|
||||
attachedCanvases.clear();
|
||||
}
|
||||
|
||||
void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||
{
|
||||
glPushMatrix();
|
||||
glMultMatrixf((const GLfloat *)t.getElements());
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
predraw();
|
||||
|
||||
@@ -620,8 +617,6 @@ void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
postdraw();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
@@ -691,16 +686,8 @@ void Canvas::setupGrab()
|
||||
strategy->bindFBO(fbo);
|
||||
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
|
||||
|
||||
// Reset the projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// Set up orthographic view (no depth)
|
||||
glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
|
||||
|
||||
// Switch back to modelview matrix
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
// Set up the projection matrix
|
||||
gl.matrices.projection.push_back(Matrix::ortho(0.0, width, 0.0, height));
|
||||
|
||||
// Make sure the correct sRGB setting is used when drawing to the canvas.
|
||||
if (format == FORMAT_SRGB)
|
||||
@@ -754,11 +741,8 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
||||
// Attach the canvas textures to the active FBO and set up MRTs.
|
||||
strategy->setAttachments(canvases);
|
||||
|
||||
for (size_t i = 0; i < canvases.size(); i++)
|
||||
canvases[i]->retain();
|
||||
|
||||
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
||||
attachedCanvases[i]->release();
|
||||
// We want to avoid reference cycles, so we don't retain the attached
|
||||
// Canvases here. The code in Graphics::setCanvas retains them.
|
||||
|
||||
attachedCanvases = canvases;
|
||||
}
|
||||
@@ -773,10 +757,6 @@ void Canvas::startGrab()
|
||||
// make sure the FBO is only using a single canvas
|
||||
strategy->setAttachments();
|
||||
|
||||
// release any previously attached canvases
|
||||
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
||||
attachedCanvases[i]->release();
|
||||
|
||||
attachedCanvases.clear();
|
||||
}
|
||||
|
||||
@@ -786,9 +766,7 @@ void Canvas::stopGrab(bool switchingToOtherCanvas)
|
||||
if (current != this)
|
||||
return;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gl.matrices.projection.pop_back();
|
||||
|
||||
if (switchingToOtherCanvas)
|
||||
{
|
||||
@@ -1123,12 +1101,6 @@ bool Canvas::isFormatSupported(Canvas::Format format)
|
||||
return supported;
|
||||
}
|
||||
|
||||
void Canvas::bindDefaultCanvas()
|
||||
{
|
||||
if (current != nullptr)
|
||||
current->stopGrab();
|
||||
}
|
||||
|
||||
bool Canvas::getConstant(const char *in, Format &out)
|
||||
{
|
||||
return formats.find(in, out);
|
||||
|
||||
@@ -120,7 +120,6 @@ public:
|
||||
static bool isFormatSupported(Format format);
|
||||
|
||||
static Canvas *current;
|
||||
static void bindDefaultCanvas();
|
||||
|
||||
// The viewport dimensions of the system (default) framebuffer.
|
||||
static OpenGL::Viewport systemViewport;
|
||||
|
||||
@@ -368,11 +368,11 @@ void Font::print(const std::string &text, float x, float y, float extra_spacing,
|
||||
// second (using the struct's < operator).
|
||||
std::sort(glyphinfolist.begin(), glyphinfolist.end());
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
Matrix t;
|
||||
t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
glMultMatrixf((const GLfloat *)t.getElements());
|
||||
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
@@ -393,8 +393,6 @@ void Font::print(const std::string &text, float x, float y, float extra_spacing,
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
int Font::getWidth(const std::string &str)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,48 +57,7 @@ namespace opengl
|
||||
// During display mode changing, certain
|
||||
// variables about the OpenGL context are
|
||||
// lost.
|
||||
struct DisplayState
|
||||
{
|
||||
// Colors.
|
||||
Color color;
|
||||
Color backgroundColor;
|
||||
|
||||
// Blend mode.
|
||||
Graphics::BlendMode blendMode;
|
||||
|
||||
// Line.
|
||||
Graphics::LineStyle lineStyle;
|
||||
Graphics::LineJoin lineJoin;
|
||||
|
||||
// Point.
|
||||
float pointSize;
|
||||
Graphics::PointStyle pointStyle;
|
||||
|
||||
// Scissor.
|
||||
bool scissor;
|
||||
OpenGL::Viewport scissorBox;
|
||||
|
||||
// Color mask.
|
||||
bool colorMask[4];
|
||||
|
||||
bool wireframe;
|
||||
|
||||
// Default values.
|
||||
DisplayState()
|
||||
{
|
||||
color.set(255,255,255,255);
|
||||
backgroundColor.set(0, 0, 0, 255);
|
||||
blendMode = Graphics::BLEND_ALPHA;
|
||||
lineStyle = Graphics::LINE_SMOOTH;
|
||||
lineJoin = Graphics::LINE_JOIN_MITER;
|
||||
pointSize = 1.0f;
|
||||
pointStyle = Graphics::POINT_SMOOTH;
|
||||
scissor = false;
|
||||
colorMask[0] = colorMask[1] = colorMask[2] = colorMask[3] = true;
|
||||
wireframe = false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Graphics : public love::graphics::Graphics
|
||||
{
|
||||
@@ -110,10 +69,6 @@ public:
|
||||
// Implements Module.
|
||||
const char *getName() const;
|
||||
|
||||
DisplayState saveState();
|
||||
|
||||
void restoreState(const DisplayState &s);
|
||||
|
||||
virtual void setViewportSize(int width, int height);
|
||||
virtual bool setMode(int width, int height, bool &sRGB);
|
||||
virtual void unSetMode();
|
||||
@@ -246,10 +201,21 @@ public:
|
||||
**/
|
||||
Font *getFont() const;
|
||||
|
||||
void setShader(Shader *shader);
|
||||
void setShader();
|
||||
|
||||
Shader *getShader() const;
|
||||
|
||||
void setCanvas(Canvas *canvas);
|
||||
void setCanvas(const std::vector<Canvas *> &canvases);
|
||||
void setCanvas();
|
||||
|
||||
std::vector<Canvas *> getCanvas() const;
|
||||
|
||||
/**
|
||||
* Sets the enabled color components when rendering.
|
||||
**/
|
||||
void setColorMask(bool r, bool g, bool b, bool a);
|
||||
void setColorMask(const bool mask[4]);
|
||||
|
||||
/**
|
||||
* Gets the current color mask.
|
||||
@@ -460,8 +426,9 @@ public:
|
||||
**/
|
||||
bool isSupported(Support feature) const;
|
||||
|
||||
void push();
|
||||
void push(StackType type = STACK_TRANSFORM);
|
||||
void pop();
|
||||
|
||||
void rotate(float r);
|
||||
void scale(float x, float y = 1.0f);
|
||||
void translate(float x, float y);
|
||||
@@ -470,17 +437,50 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
Font *currentFont;
|
||||
struct DisplayState
|
||||
{
|
||||
// Colors.
|
||||
Color color;
|
||||
Color backgroundColor;
|
||||
|
||||
// Blend mode.
|
||||
BlendMode blendMode;
|
||||
|
||||
// Line.
|
||||
float lineWidth;
|
||||
LineStyle lineStyle;
|
||||
LineJoin lineJoin;
|
||||
|
||||
// Point.
|
||||
float pointSize;
|
||||
PointStyle pointStyle;
|
||||
|
||||
// Scissor.
|
||||
bool scissor;
|
||||
OpenGL::Viewport scissorBox;
|
||||
|
||||
Font *font;
|
||||
Shader *shader;
|
||||
std::vector<Canvas *> canvases;
|
||||
|
||||
// Color mask.
|
||||
bool colorMask[4];
|
||||
|
||||
bool wireframe;
|
||||
|
||||
DisplayState();
|
||||
DisplayState(const DisplayState &other);
|
||||
~DisplayState();
|
||||
|
||||
DisplayState &operator = (const DisplayState &other);
|
||||
};
|
||||
|
||||
void restoreState(const DisplayState &s);
|
||||
void restoreStateChecked(const DisplayState &s);
|
||||
|
||||
love::window::Window *currentWindow;
|
||||
|
||||
std::vector<double> pixel_size_stack; // stores current size of a pixel (needed for line drawing)
|
||||
LineStyle lineStyle;
|
||||
LineJoin lineJoin;
|
||||
float lineWidth;
|
||||
GLint matrixLimit;
|
||||
GLint userMatrices;
|
||||
bool colorMask[4];
|
||||
bool wireframe;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@@ -488,7 +488,10 @@ private:
|
||||
|
||||
bool activeStencil;
|
||||
|
||||
DisplayState savedState;
|
||||
std::vector<DisplayState> states;
|
||||
std::vector<StackType> stackTypes; // Keeps track of the pushed stack types.
|
||||
|
||||
static const size_t MAX_USER_STACK_DEPTH = 64;
|
||||
|
||||
}; // Graphics
|
||||
|
||||
|
||||
@@ -526,12 +526,11 @@ void Image::uploadDefaultTexture()
|
||||
|
||||
void Image::drawv(const Matrix &t, const Vertex *v)
|
||||
{
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
predraw();
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glMultMatrixf((const GLfloat *)t.getElements());
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
@@ -544,8 +543,6 @@ void Image::drawv(const Matrix &t, const Vertex *v)
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
postdraw();
|
||||
}
|
||||
|
||||
|
||||
@@ -342,8 +342,8 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
Matrix m;
|
||||
m.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf(m.getElements());
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= m;
|
||||
|
||||
VertexBuffer::Bind vbo_bind(*vbo);
|
||||
|
||||
@@ -412,8 +412,6 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
gl.setColor(gl.getColor());
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (texture)
|
||||
texture->postdraw();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
// C++
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
// C
|
||||
#include <cstring>
|
||||
@@ -47,6 +48,8 @@ OpenGL::OpenGL()
|
||||
, vendor(VENDOR_UNKNOWN)
|
||||
, state()
|
||||
{
|
||||
matrices.transform.reserve(10);
|
||||
matrices.projection.reserve(2);
|
||||
}
|
||||
|
||||
void OpenGL::initContext()
|
||||
@@ -56,6 +59,7 @@ void OpenGL::initContext()
|
||||
|
||||
initOpenGLFunctions();
|
||||
initVendor();
|
||||
initMatrices();
|
||||
|
||||
// Store the current color so we don't have to get it through GL later.
|
||||
GLfloat glcolor[4];
|
||||
@@ -119,6 +123,13 @@ void OpenGL::initContext()
|
||||
|
||||
state.lastPseudoInstanceID = -1;
|
||||
|
||||
// Invalidate the cached matrices by setting some elements to NaN.
|
||||
float nan = std::numeric_limits<float>::quiet_NaN();
|
||||
state.lastProjectionMatrix.setTranslation(nan, nan);
|
||||
state.lastTransformMatrix.setTranslation(nan, nan);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
contextInitialized = true;
|
||||
}
|
||||
|
||||
@@ -209,6 +220,15 @@ void OpenGL::initMaxValues()
|
||||
maxRenderTargets = 0;
|
||||
}
|
||||
|
||||
void OpenGL::initMatrices()
|
||||
{
|
||||
matrices.transform.clear();
|
||||
matrices.projection.clear();
|
||||
|
||||
matrices.transform.push_back(Matrix());
|
||||
matrices.projection.push_back(Matrix());
|
||||
}
|
||||
|
||||
void OpenGL::createDefaultTexture()
|
||||
{
|
||||
// Set the 'default' texture (id 0) as a repeating white pixel. Otherwise,
|
||||
@@ -231,6 +251,21 @@ void OpenGL::createDefaultTexture()
|
||||
bindTexture(curtexture);
|
||||
}
|
||||
|
||||
void OpenGL::pushTransform()
|
||||
{
|
||||
matrices.transform.push_back(matrices.transform.back());
|
||||
}
|
||||
|
||||
void OpenGL::popTransform()
|
||||
{
|
||||
matrices.transform.pop_back();
|
||||
}
|
||||
|
||||
Matrix &OpenGL::getTransform()
|
||||
{
|
||||
return matrices.transform.back();
|
||||
}
|
||||
|
||||
void OpenGL::prepareDraw()
|
||||
{
|
||||
Shader *shader = Shader::current;
|
||||
@@ -251,15 +286,37 @@ void OpenGL::prepareDraw()
|
||||
// We need to make sure antialiased Canvases are properly resolved
|
||||
// before sampling from their textures in a shader.
|
||||
// This is kind of a big hack. :(
|
||||
const std::map<std::string, Object *> &r = shader->getBoundRetainables();
|
||||
for (auto it = r.begin(); it != r.end(); ++it)
|
||||
for (auto &r : shader->getBoundRetainables())
|
||||
{
|
||||
// Even bigger hack! D:
|
||||
Canvas *canvas = dynamic_cast<Canvas *>(it->second);
|
||||
Canvas *canvas = dynamic_cast<Canvas *>(r.second);
|
||||
if (canvas != nullptr)
|
||||
canvas->resolveMSAA();
|
||||
}
|
||||
}
|
||||
|
||||
const float *curproj = matrices.projection.back().getElements();
|
||||
const float *lastproj = state.lastProjectionMatrix.getElements();
|
||||
|
||||
// We only need to re-upload the projection matrix if it's changed.
|
||||
if (memcmp(curproj, lastproj, sizeof(float) * 16) != 0)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(curproj);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
state.lastProjectionMatrix = matrices.projection.back();
|
||||
}
|
||||
|
||||
const float *curxform = matrices.transform.back().getElements();
|
||||
const float *lastxform = state.lastTransformMatrix.getElements();
|
||||
|
||||
// Same with the transform matrix.
|
||||
if (memcmp(curxform, lastxform, sizeof(float) * 16) != 0)
|
||||
{
|
||||
glLoadMatrixf(curxform);
|
||||
state.lastTransformMatrix = matrices.transform.back();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
// LOVE
|
||||
#include "graphics/Color.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "common/Matrix.h"
|
||||
|
||||
// C++
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
// The last argument to AttribPointer takes a buffer offset casted to a pointer.
|
||||
#define BUFFER_OFFSET(i) ((char *) NULL + (i))
|
||||
@@ -101,6 +103,36 @@ public:
|
||||
GLenum func;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector<Matrix> transform;
|
||||
std::vector<Matrix> projection;
|
||||
} matrices;
|
||||
|
||||
class TempTransform
|
||||
{
|
||||
public:
|
||||
|
||||
TempTransform(OpenGL &gl)
|
||||
: gl(gl)
|
||||
{
|
||||
gl.pushTransform();
|
||||
}
|
||||
|
||||
~TempTransform()
|
||||
{
|
||||
gl.popTransform();
|
||||
}
|
||||
|
||||
Matrix &get()
|
||||
{
|
||||
return gl.getTransform();
|
||||
}
|
||||
|
||||
private:
|
||||
OpenGL ≷
|
||||
};
|
||||
|
||||
OpenGL();
|
||||
|
||||
/**
|
||||
@@ -116,6 +148,10 @@ public:
|
||||
**/
|
||||
void deInitContext();
|
||||
|
||||
void pushTransform();
|
||||
void popTransform();
|
||||
Matrix &getTransform();
|
||||
|
||||
/**
|
||||
* Set up necessary state (LOVE-provided shader uniforms, etc.) for drawing.
|
||||
* This *MUST* be called directly before OpenGL drawing functions.
|
||||
@@ -258,6 +294,7 @@ private:
|
||||
void initVendor();
|
||||
void initOpenGLFunctions();
|
||||
void initMaxValues();
|
||||
void initMatrices();
|
||||
void createDefaultTexture();
|
||||
|
||||
bool contextInitialized;
|
||||
@@ -290,6 +327,9 @@ private:
|
||||
// The last ID value used for pseudo-instancing.
|
||||
int lastPseudoInstanceID;
|
||||
|
||||
Matrix lastProjectionMatrix;
|
||||
Matrix lastTransformMatrix;
|
||||
|
||||
} state;
|
||||
|
||||
}; // OpenGL
|
||||
|
||||
@@ -843,11 +843,11 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
|
||||
Color curcolor = gl.getColor();
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
static Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
glMultMatrixf((const GLfloat *)t.getElements());
|
||||
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
const Vertex *textureVerts = texture->getVertices();
|
||||
Vertex *pVerts = particleVerts;
|
||||
@@ -901,8 +901,6 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
|
||||
texture->postdraw();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
gl.setColor(curcolor);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,8 +97,8 @@ Shader::~Shader()
|
||||
if (current == this)
|
||||
detach();
|
||||
|
||||
for (auto it = boundRetainables.begin(); it != boundRetainables.end(); ++it)
|
||||
it->second->release();
|
||||
for (const auto &retainable : boundRetainables)
|
||||
retainable.second->release();
|
||||
|
||||
boundRetainables.clear();
|
||||
|
||||
@@ -178,9 +178,8 @@ void Shader::createProgram(const std::vector<GLuint> &shaderids)
|
||||
if (program == 0)
|
||||
throw love::Exception("Cannot create shader program object.");
|
||||
|
||||
std::vector<GLuint>::const_iterator it;
|
||||
for (it = shaderids.begin(); it != shaderids.end(); ++it)
|
||||
glAttachShader(program, *it);
|
||||
for (GLuint id : shaderids)
|
||||
glAttachShader(program, id);
|
||||
|
||||
// Bind generic vertex attribute indices to names in the shader.
|
||||
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)
|
||||
@@ -201,8 +200,8 @@ void Shader::createProgram(const std::vector<GLuint> &shaderids)
|
||||
glLinkProgram(program);
|
||||
|
||||
// flag shaders for auto-deletion when the program object is deleted.
|
||||
for (it = shaderids.begin(); it != shaderids.end(); ++it)
|
||||
glDeleteShader(*it);
|
||||
for (GLuint id : shaderids)
|
||||
glDeleteShader(id);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||
@@ -275,10 +274,9 @@ bool Shader::loadVolatile()
|
||||
|
||||
std::vector<GLuint> shaderids;
|
||||
|
||||
ShaderSources::const_iterator source;
|
||||
for (source = shaderSources.begin(); source != shaderSources.end(); ++source)
|
||||
for (const auto &source : shaderSources)
|
||||
{
|
||||
GLuint shaderid = compileCode(source->first, source->second);
|
||||
GLuint shaderid = compileCode(source.first, source.second);
|
||||
shaderids.push_back(shaderid);
|
||||
}
|
||||
|
||||
@@ -364,11 +362,10 @@ std::string Shader::getWarnings() const
|
||||
const char *typestr;
|
||||
|
||||
// Get the individual shader stage warnings
|
||||
std::map<ShaderType, std::string>::const_iterator it;
|
||||
for (it = shaderWarnings.begin(); it != shaderWarnings.end(); ++it)
|
||||
for (const auto &warning : shaderWarnings)
|
||||
{
|
||||
if (typeNames.find(it->first, typestr))
|
||||
warnings += std::string(typestr) + std::string(" shader:\n") + it->second;
|
||||
if (typeNames.find(warning.first, typestr))
|
||||
warnings += std::string(typestr) + std::string(" shader:\n") + warning.second;
|
||||
}
|
||||
|
||||
warnings += getProgramWarnings();
|
||||
@@ -380,13 +377,9 @@ void Shader::attach(bool temporary)
|
||||
{
|
||||
if (current != this)
|
||||
{
|
||||
if (current != nullptr)
|
||||
current->release();
|
||||
|
||||
glUseProgram(program);
|
||||
current = this;
|
||||
|
||||
current->retain();
|
||||
// retain/release happens in Graphics::setShader.
|
||||
}
|
||||
|
||||
if (!temporary)
|
||||
|
||||
@@ -271,11 +271,10 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
|
||||
return;
|
||||
|
||||
static Matrix t;
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
glMultMatrixf((const GLfloat *)t.getElements());
|
||||
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
texture->predraw();
|
||||
|
||||
@@ -314,8 +313,6 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
|
||||
}
|
||||
|
||||
texture->postdraw();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void SpriteBatch::addv(const Vertex *v, int index)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
**/
|
||||
|
||||
#include "wrap_Canvas.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -37,18 +38,26 @@ int w_Canvas_renderTo(lua_State *L)
|
||||
Canvas *canvas = luax_checkcanvas(L, 1);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
// Save the current Canvas so we can restore it when we're done.
|
||||
Canvas *oldcanvas = Canvas::current;
|
||||
Graphics *graphics = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
|
||||
luax_catchexcept(L, [&](){ canvas->startGrab(); });
|
||||
if (graphics)
|
||||
{
|
||||
// Save the current Canvas so we can restore it when we're done.
|
||||
std::vector<Canvas *> oldcanvases = graphics->getCanvas();
|
||||
|
||||
lua_settop(L, 2); // make sure the function is on top of the stack
|
||||
lua_call(L, 0, 0);
|
||||
for (Canvas *c : oldcanvases)
|
||||
c->retain();
|
||||
|
||||
if (oldcanvas != nullptr)
|
||||
oldcanvas->startGrab(oldcanvas->getAttachedCanvases());
|
||||
else
|
||||
Canvas::bindDefaultCanvas();
|
||||
luax_catchexcept(L, [&](){ graphics->setCanvas(canvas); });
|
||||
|
||||
lua_settop(L, 2); // make sure the function is on top of the stack
|
||||
lua_call(L, 0, 0);
|
||||
|
||||
graphics->setCanvas(oldcanvases);
|
||||
|
||||
for (Canvas *c : oldcanvases)
|
||||
c->release();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -651,8 +651,7 @@ int w_setColorMask(lua_State *L)
|
||||
mask[i] = luax_toboolean(L, i + 1);
|
||||
}
|
||||
|
||||
// r, g, b, a
|
||||
instance()->setColorMask(mask[0], mask[1], mask[2], mask[3]);
|
||||
instance()->setColorMask(mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -893,43 +892,35 @@ int w_setCanvas(lua_State *L)
|
||||
instance()->discardStencil();
|
||||
|
||||
// called with none -> reset to default buffer
|
||||
if (lua_isnoneornil(L,1))
|
||||
if (lua_isnoneornil(L, 1))
|
||||
{
|
||||
Canvas::bindDefaultCanvas();
|
||||
instance()->setCanvas();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_table = lua_istable(L, 1);
|
||||
std::vector<Canvas *> attachments;
|
||||
|
||||
Canvas *canvas = 0;
|
||||
std::vector<Canvas *> canvases;
|
||||
|
||||
if (is_table)
|
||||
{
|
||||
// grab the first canvas in the array and attach the rest
|
||||
lua_rawgeti(L, 1, 1);
|
||||
canvas = luax_checkcanvas(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
for (size_t i = 2; i <= lua_objlen(L, 1); i++)
|
||||
for (size_t i = 1; i <= lua_objlen(L, 1); i++)
|
||||
{
|
||||
lua_rawgeti(L, 1, i);
|
||||
attachments.push_back(luax_checkcanvas(L, -1));
|
||||
canvases.push_back(luax_checkcanvas(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas = luax_checkcanvas(L, 1);
|
||||
for (int i = 2; i <= lua_gettop(L); i++)
|
||||
attachments.push_back(luax_checkcanvas(L, i));
|
||||
for (int i = 1; i <= lua_gettop(L); i++)
|
||||
canvases.push_back(luax_checkcanvas(L, i));
|
||||
}
|
||||
|
||||
luax_catchexcept(L, [&]() {
|
||||
if (attachments.size() > 0)
|
||||
canvas->startGrab(attachments);
|
||||
if (canvases.size() > 0)
|
||||
instance()->setCanvas(canvases);
|
||||
else
|
||||
canvas->startGrab();
|
||||
instance()->setCanvas();
|
||||
});
|
||||
|
||||
return 0;
|
||||
@@ -937,24 +928,23 @@ int w_setCanvas(lua_State *L)
|
||||
|
||||
int w_getCanvas(lua_State *L)
|
||||
{
|
||||
Canvas *canvas = Canvas::current;
|
||||
int n = 1;
|
||||
const std::vector<Canvas *> canvases = instance()->getCanvas();
|
||||
int n = 0;
|
||||
|
||||
if (canvas)
|
||||
if (!canvases.empty())
|
||||
{
|
||||
canvas->retain();
|
||||
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas);
|
||||
|
||||
const std::vector<Canvas *> &attachments = canvas->getAttachedCanvases();
|
||||
for (size_t i = 0; i < attachments.size(); i++)
|
||||
for (Canvas *c : canvases)
|
||||
{
|
||||
attachments[i]->retain();
|
||||
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, attachments[i]);
|
||||
c->retain();
|
||||
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, c);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
n = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -963,18 +953,18 @@ int w_setShader(lua_State *L)
|
||||
{
|
||||
if (lua_isnoneornil(L,1))
|
||||
{
|
||||
Shader::detach();
|
||||
instance()->setShader();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Shader *shader = luax_checkshader(L, 1);
|
||||
shader->attach();
|
||||
instance()->setShader(shader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_getShader(lua_State *L)
|
||||
{
|
||||
Shader *shader = Shader::current;
|
||||
Shader *shader = instance()->getShader();
|
||||
if (shader)
|
||||
{
|
||||
shader->retain();
|
||||
@@ -1323,7 +1313,12 @@ int w_polygon(lua_State *L)
|
||||
|
||||
int w_push(lua_State *L)
|
||||
{
|
||||
luax_catchexcept(L, [&](){ instance()->push(); });
|
||||
Graphics::StackType stype = Graphics::STACK_TRANSFORM;
|
||||
const char *sname = lua_isnoneornil(L, 1) ? nullptr : luaL_checkstring(L, 1);
|
||||
if (sname && !Graphics::getConstant(sname, stype))
|
||||
return luaL_error(L, "Invalid graphics stack type: %s", sname);
|
||||
|
||||
luax_catchexcept(L, [&](){ instance()->push(stype); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user