imported changes from love-0.9.2

This commit is contained in:
fysx
2015-02-16 00:37:14 +01:00
parent 3cfecd46d9
commit d6f1d8bd70
65 changed files with 7033 additions and 7858 deletions
+18
View File
@@ -157,6 +157,24 @@ public:
size_t textureMemory;
};
struct ColorMask
{
bool r;
bool g;
bool b;
bool a;
bool operator == (const ColorMask &m) const
{
return r == m.r && g == m.g && b == m.b && a == m.a;
}
bool operator != (const ColorMask &m) const
{
return !(operator == (m));
}
};
virtual ~Graphics();
// Implements Module.
@@ -595,7 +595,9 @@ bool Canvas::loadVolatile()
if (glGetError() != GL_NO_ERROR)
{
status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
gl.deleteTexture(texture);
texture = 0;
status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
return false;
}
@@ -619,7 +621,14 @@ bool Canvas::loadVolatile()
status = strategy->createFBO(fbo, texture);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
if (fbo != 0)
{
strategy->deleteFBO(fbo, 0, 0);
fbo = 0;
}
return false;
}
clear(Color(0, 0, 0, 0));
+1 -1
View File
@@ -186,7 +186,7 @@ private:
Glyph *addGlyph(uint32 glyph);
Glyph *findGlyph(uint32 glyph);
Object::StrongRef<love::font::Rasterizer> rasterizer;
StrongRef<love::font::Rasterizer> rasterizer;
VertexIndex *indexBuffer;
@@ -25,6 +25,7 @@
#include "Graphics.h"
#include "window/sdl/Window.h"
#include "font/Font.h"
#include "Polyline.h"
// C++
@@ -71,6 +72,7 @@ Graphics::~Graphics()
{
// We do this manually so the love objects get released before the window.
states.clear();
defaultFont.set(nullptr);
if (Shader::defaultShader)
{
@@ -160,14 +162,8 @@ void Graphics::restoreStateChecked(const DisplayState &s)
}
}
for (int i = 0; i < 4; i++)
{
if (s.colorMask[i] != cur.colorMask[i])
{
setColorMask(s.colorMask);
break;
}
}
if (s.colorMask != cur.colorMask)
setColorMask(s.colorMask);
if (s.wireframe != cur.wireframe)
setWireframe(s.wireframe);
@@ -176,6 +172,29 @@ void Graphics::restoreStateChecked(const DisplayState &s)
setDefaultMipmapFilter(s.defaultMipmapFilter, s.defaultMipmapSharpness);
}
void Graphics::checkSetDefaultFont()
{
// We don't create or set the default Font if an existing font is in use.
if (states.back().font.get() != nullptr)
return;
// Create a new default font if we don't have one yet.
if (!defaultFont.get())
{
font::Font *fontmodule = Module::getInstance<font::Font>(M_FONT);
if (!fontmodule)
throw love::Exception("Font module has not been loaded.");
StrongRef<font::Rasterizer> r(fontmodule->newRasterizer(12));
r->release();
defaultFont.set(newFont(r.get()));
defaultFont->release();
}
states.back().font.set(defaultFont.get());
}
void Graphics::setViewportSize(int width, int height)
{
this->width = width;
@@ -186,7 +205,7 @@ void Graphics::setViewportSize(int width, int height)
// We want to affect the main screen, not any Canvas that's currently active
// (not that any *should* be active when this is called.)
std::vector<Object::StrongRef<Canvas>> canvases = states.back().canvases;
std::vector<StrongRef<Canvas>> canvases = states.back().canvases;
setCanvas();
// Set the viewport to top-left corner.
@@ -233,17 +252,8 @@ bool Graphics::setMode(int width, int height, bool &sRGB)
// Enable blending
glEnable(GL_BLEND);
// Enable all color component writes.
bool colormask[] = {true, true, true, true};
setColorMask(colormask);
// Enable line/point smoothing.
setLineStyle(LINE_SMOOTH);
if (GLAD_VERSION_1_0)
{
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
}
// Auto-generated mipmaps should be the best quality possible
if (GLAD_ES_VERSION_2_0 || GLAD_VERSION_1_4 || GLAD_SGIS_generate_mipmap)
@@ -429,7 +439,7 @@ void Graphics::present()
return;
// Make sure we don't have a canvas active.
std::vector<Object::StrongRef<Canvas>> canvases = states.back().canvases;
std::vector<StrongRef<Canvas>> canvases = states.back().canvases;
setCanvas();
if (GLAD_EXT_discard_framebuffer)
@@ -710,18 +720,16 @@ Color Graphics::getBackgroundColor() const
void Graphics::setFont(Font *font)
{
// Hack: the Lua-facing love.graphics.print function will set the current
// font if needed, but only on its first call... we want to make sure a nil
// font is never accidentally set (e.g. via love.graphics.reset.)
if (font == nullptr)
return;
// We don't need to set a default font here if null is passed in, since we
// only care about the default font in getFont and print.
DisplayState &state = states.back();
state.font.set(font);
}
Font *Graphics::getFont() const
Font *Graphics::getFont()
{
checkSetDefaultFont();
return states.back().font.get();
}
@@ -760,7 +768,7 @@ void Graphics::setCanvas(Canvas *canvas)
canvas->startGrab();
std::vector<Object::StrongRef<Canvas>> canvasref;
std::vector<StrongRef<Canvas>> canvasref;
canvasref.push_back(canvas);
std::swap(state.canvases, canvasref);
@@ -778,7 +786,7 @@ void Graphics::setCanvas(const std::vector<Canvas *> &canvases)
auto attachments = std::vector<Canvas *>(canvases.begin() + 1, canvases.end());
canvases[0]->startGrab(attachments);
std::vector<Object::StrongRef<Canvas>> canvasrefs;
std::vector<StrongRef<Canvas>> canvasrefs;
canvasrefs.reserve(canvases.size());
for (Canvas *c : canvases)
@@ -787,12 +795,12 @@ void Graphics::setCanvas(const std::vector<Canvas *> &canvases)
std::swap(state.canvases, canvasrefs);
}
void Graphics::setCanvas(const std::vector<Object::StrongRef<Canvas>> &canvases)
void Graphics::setCanvas(const std::vector<StrongRef<Canvas>> &canvases)
{
std::vector<Canvas *> canvaslist;
canvaslist.reserve(canvases.size());
for (const Object::StrongRef<Canvas> &c : canvases)
for (const StrongRef<Canvas> &c : canvases)
canvaslist.push_back(c.get());
return setCanvas(canvaslist);
@@ -813,21 +821,18 @@ std::vector<Canvas *> Graphics::getCanvas() const
std::vector<Canvas *> canvases;
canvases.reserve(states.back().canvases.size());
for (const Object::StrongRef<Canvas> &c : states.back().canvases)
for (const StrongRef<Canvas> &c : states.back().canvases)
canvases.push_back(c.get());
return canvases;
}
void Graphics::setColorMask(const bool mask[4])
void Graphics::setColorMask(ColorMask mask)
{
for (int i = 0; i < 4; i++)
states.back().colorMask[i] = mask[i];
glColorMask(mask[0], mask[1], mask[2], mask[3]);
glColorMask(mask.r, mask.g, mask.b, mask.a);
}
const bool *Graphics::getColorMask() const
Graphics::ColorMask Graphics::getColorMask() const
{
return states.back().colorMask;
}
@@ -990,6 +995,8 @@ bool Graphics::isWireframe() const
void Graphics::print(const std::string &str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{
checkSetDefaultFont();
DisplayState &state = states.back();
if (state.font.get() != nullptr)
@@ -998,6 +1005,8 @@ void Graphics::print(const std::string &str, float x, float y , float angle, flo
void Graphics::printf(const std::string &str, float x, float y, float wrap, AlignMode align, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{
checkSetDefaultFont();
DisplayState &state = states.back();
if (state.font.get() == nullptr)
@@ -1231,7 +1240,7 @@ love::image::ImageData *Graphics::newScreenshot(love::image::Image *image, bool
{
// Temporarily unbind the currently active canvas (glReadPixels reads the
// active framebuffer, not the main one.)
std::vector<Object::StrongRef<Canvas>> canvases = states.back().canvases;
std::vector<StrongRef<Canvas>> canvases = states.back().canvases;
setCanvas();
int w = getWidth();
@@ -1486,14 +1495,12 @@ Graphics::DisplayState::DisplayState()
, scissorBox()
, font(nullptr)
, shader(nullptr)
, colorMask({true, true, true, true})
, wireframe(false)
, defaultFilter()
, defaultMipmapFilter(Texture::FILTER_NONE)
, defaultMipmapSharpness(0.0f)
{
// We should just directly initialize the array in the initializer list, but
// that feature of C++11 is broken in Visual Studio 2013...
colorMask[0] = colorMask[1] = colorMask[2] = colorMask[3] = true;
}
Graphics::DisplayState::DisplayState(const DisplayState &other)
@@ -1510,13 +1517,12 @@ Graphics::DisplayState::DisplayState(const DisplayState &other)
, font(other.font)
, shader(other.shader)
, canvases(other.canvases)
, colorMask(other.colorMask)
, wireframe(other.wireframe)
, defaultFilter(other.defaultFilter)
, defaultMipmapFilter(other.defaultMipmapFilter)
, defaultMipmapSharpness(other.defaultMipmapSharpness)
{
for (int i = 0; i < 4; i++)
colorMask[i] = other.colorMask[i];
}
Graphics::DisplayState::~DisplayState()
@@ -1540,8 +1546,7 @@ Graphics::DisplayState &Graphics::DisplayState::operator = (const DisplayState &
shader = other.shader;
canvases = other.canvases;
for (int i = 0; i < 4; i++)
colorMask[i] = other.colorMask[i];
colorMask = other.colorMask;
wireframe = other.wireframe;
+12 -24
View File
@@ -193,15 +193,8 @@ public:
**/
Color getBackgroundColor() const;
/**
* Sets the current font.
* @param font A Font object.
**/
void setFont(Font *font);
/**
* Gets the current Font, or nil if none.
**/
Font *getFont() const;
Font *getFont();
void setShader(Shader *shader);
void setShader();
@@ -210,7 +203,7 @@ public:
void setCanvas(Canvas *canvas);
void setCanvas(const std::vector<Canvas *> &canvases);
void setCanvas(const std::vector<Object::StrongRef<Canvas>> &canvases);
void setCanvas(const std::vector<StrongRef<Canvas>> &canvases);
void setCanvas();
std::vector<Canvas *> getCanvas() const;
@@ -218,13 +211,12 @@ public:
/**
* Sets the enabled color components when rendering.
**/
void setColorMask(const bool mask[4]);
void setColorMask(ColorMask mask);
/**
* Gets the current color mask.
* Returns an array of 4 booleans representing the mask.
**/
const bool *getColorMask() const;
ColorMask getColorMask() const;
/**
* Sets the current blend mode.
@@ -447,40 +439,32 @@ private:
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;
Object::StrongRef<Font> font;
Object::StrongRef<Shader> shader;
StrongRef<Font> font;
StrongRef<Shader> shader;
std::vector<Object::StrongRef<Canvas>> canvases;
std::vector<StrongRef<Canvas>> canvases;
// Color mask.
bool colorMask[4];
ColorMask colorMask;
bool wireframe;
// Default filter.
Texture::Filter defaultFilter;
// Default mipmap filter and sharpness.
Texture::FilterMode defaultMipmapFilter;
float defaultMipmapSharpness;
@@ -494,8 +478,12 @@ private:
void restoreState(const DisplayState &s);
void restoreStateChecked(const DisplayState &s);
void checkSetDefaultFont();
love::window::Window *currentWindow;
StrongRef<Font> defaultFont;
std::vector<double> pixel_size_stack; // stores current size of a pixel (needed for line drawing)
int width;
+2 -2
View File
@@ -157,11 +157,11 @@ private:
// The ImageData from which the texture is created. May be null if
// Compressed image data was used to create the texture.
Object::StrongRef<love::image::ImageData> data;
StrongRef<love::image::ImageData> data;
// Or the Compressed Image Data from which the texture is created. May be
// null if raw ImageData was used to create the texture.
Object::StrongRef<love::image::CompressedData> cdata;
StrongRef<love::image::CompressedData> cdata;
// Real dimensions of the texture, if it was auto-padded to POT size.
int paddedWidth, paddedHeight;
+1 -1
View File
@@ -178,7 +178,7 @@ private:
int range_min;
int range_max;
Object::StrongRef<Texture> texture;
StrongRef<Texture> texture;
// Whether the per-vertex colors are used when drawing.
bool colors_enabled;
@@ -137,8 +137,6 @@ bool OpenGL::initContext()
initMaxValues();
createDefaultTexture();
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);
@@ -305,14 +303,6 @@ void OpenGL::prepareDraw()
{
shader->checkSetScreenParams();
// Make sure the Instance ID variable is up-to-date when
// pseudo-instancing is used.
if (state.lastPseudoInstanceID != 0 && shader->hasVertexAttrib(ATTRIB_PSEUDO_INSTANCE_ID))
{
glVertexAttrib1f((GLuint) ATTRIB_PSEUDO_INSTANCE_ID, 0.0f);
state.lastPseudoInstanceID = 0;
}
// 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. :(
@@ -379,62 +369,6 @@ void OpenGL::drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, con
++stats.drawCalls;
}
void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
Shader *shader = Shader::current;
if (GLAD_ARB_draw_instanced)
glDrawArraysInstancedARB(mode, first, count, primcount);
else if (GLAD_EXT_draw_instanced && GLAD_ES_VERSION_2_0)
glDrawArraysInstancedEXT(mode, first, count, primcount);
else
{
bool shaderHasID = shader && shader->hasVertexAttrib(ATTRIB_PSEUDO_INSTANCE_ID);
// Pseudo-instancing fallback.
for (int i = 0; i < primcount; i++)
{
if (shaderHasID)
glVertexAttrib1f((GLuint) ATTRIB_PSEUDO_INSTANCE_ID, (GLfloat) i);
glDrawArrays(mode, first, count);
}
if (shaderHasID)
state.lastPseudoInstanceID = primcount - 1;
}
++stats.drawCalls;
}
void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
{
Shader *shader = Shader::current;
if (GLAD_ARB_draw_instanced)
glDrawElementsInstancedARB(mode, count, type, indices, primcount);
else if (GLAD_EXT_draw_instanced && GLAD_ES_VERSION_2_0)
glDrawElementsInstancedEXT(mode, count, type, indices, primcount);
else
{
bool shaderHasID = shader && shader->hasVertexAttrib(ATTRIB_PSEUDO_INSTANCE_ID);
// Pseudo-instancing fallback.
for (int i = 0; i < primcount; i++)
{
if (shaderHasID)
glVertexAttrib1f((GLuint) ATTRIB_PSEUDO_INSTANCE_ID, (GLfloat) i);
glDrawElements(mode, count, type, indices);
}
if (shaderHasID)
state.lastPseudoInstanceID = primcount - 1;
}
++stats.drawCalls;
}
void OpenGL::setColor(const Color &c)
{
if (GLAD_ES_VERSION_2_0)
@@ -186,13 +186,6 @@ public:
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void drawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex);
/**
* glDrawArraysInstanced and glDrawElementsInstanced with pseudo-instancing
* fallbacks. They also increment the draw-call counter (once per call).
**/
void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
/**
* Sets the current constant color.
**/
@@ -388,9 +381,6 @@ private:
BlendState blend;
// The last ID value used for pseudo-instancing.
int lastPseudoInstanceID;
Matrix lastProjectionMatrix;
Matrix lastTransformMatrix;
@@ -749,7 +749,7 @@ std::vector<Quad *> ParticleSystem::getQuads() const
std::vector<Quad *> quadlist;
quadlist.reserve(quads.size());
for (const Object::StrongRef<Quad> &q : quads)
for (const StrongRef<Quad> &q : quads)
quadlist.push_back(q.get());
return quadlist;
@@ -580,7 +580,7 @@ protected:
VertexIndex *ibo;
// The texture to be drawn.
Object::StrongRef<Texture> texture;
StrongRef<Texture> texture;
// Whether the particle emitter is active.
bool active;
@@ -660,7 +660,7 @@ protected:
std::vector<Colorf> colors;
// Quads.
std::vector<Object::StrongRef<Quad>> quads;
std::vector<StrongRef<Quad>> quads;
bool relativeRotation;
@@ -124,7 +124,7 @@ private:
*/
void setColorv(Vertex *v, const Color &color);
Object::StrongRef<Texture> texture;
StrongRef<Texture> texture;
// Max number of sprites in the batch.
int size;
@@ -252,11 +252,19 @@ int w_newQuad(lua_State *L)
int w_newFont(lua_State *L)
{
// Convert to Rasterizer, if necessary.
if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_T))
// Convert to Rasterizer, if necessary. Note that lua_isstring returns true
// if the value is a number, which we rely on for the variant that uses the
// default Font rather than a font file.
if (lua_isnoneornil(L, 1) || lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_T))
{
int idxs[] = {1, 2};
luax_convobj(L, idxs, 2, "font", "newRasterizer");
if (lua_isnone(L, 1))
lua_pushnil(L);
std::vector<int> idxs;
for (int i = 0; i < lua_gettop(L); i++)
idxs.push_back(i + 1);
luax_convobj(L, &idxs[0], (int) idxs.size(), "font", "newRasterizer");
}
love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
@@ -640,6 +648,14 @@ int w_getBackgroundColor(lua_State *L)
return 4;
}
int w_setNewFont(lua_State *L)
{
int ret = w_newFont(L);
Font *font = luax_checktype<Font>(L, -1, "Font", GRAPHICS_FONT_T);
instance()->setFont(font);
return ret;
}
int w_setFont(lua_State *L)
{
Font *font = luax_checktype<Font>(L, 1, "Font", GRAPHICS_FONT_T);
@@ -649,10 +665,8 @@ int w_setFont(lua_State *L)
int w_getFont(lua_State *L)
{
Font *f = instance()->getFont();
if (f == 0)
return 0;
Font *f = nullptr;
luax_catchexcept(L, [&](){ f = instance()->getFont(); });
luax_pushtype(L, "Font", GRAPHICS_FONT_T, f);
return 1;
@@ -660,17 +674,19 @@ int w_getFont(lua_State *L)
int w_setColorMask(lua_State *L)
{
bool mask[4];
Graphics::ColorMask mask;
if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1))
{
// Enable all color components if no argument is given.
mask[0] = mask[1] = mask[2] = mask[3] = true;
mask.r = mask.g = mask.b = mask.a = true;
}
else
{
for (int i = 0; i < 4; i++)
mask[i] = luax_toboolean(L, i + 1);
mask.r = luax_toboolean(L, 1);
mask.g = luax_toboolean(L, 2);
mask.b = luax_toboolean(L, 3);
mask.a = luax_toboolean(L, 4);
}
instance()->setColorMask(mask);
@@ -680,10 +696,12 @@ int w_setColorMask(lua_State *L)
int w_getColorMask(lua_State *L)
{
const bool *mask = instance()->getColorMask();
Graphics::ColorMask mask = instance()->getColorMask();
for (int i = 0; i < 4; i++)
luax_pushboolean(L, mask[i]);
luax_pushboolean(L, mask.r);
luax_pushboolean(L, mask.g);
luax_pushboolean(L, mask.b);
luax_pushboolean(L, mask.a);
return 4;
}
@@ -1470,6 +1488,7 @@ static const luaL_Reg functions[] =
{ "setBackgroundColor", w_setBackgroundColor },
{ "getBackgroundColor", w_getBackgroundColor },
{ "setNewFont", w_setNewFont },
{ "setFont", w_setFont },
{ "getFont", w_getFont },
@@ -65,6 +65,7 @@ int w_setColor(lua_State *L);
int w_getColor(lua_State *L);
int w_setBackgroundColor(lua_State *L);
int w_getBackgroundColor(lua_State *L);
int w_setNewFont(lua_State *L);
int w_setFont(lua_State *L);
int w_getFont(lua_State *L);
int w_setColorMask(lua_State *L);