mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Added instancing support to Meshes via Mesh:setInstanceCount. Added a new built-in variable to vertex shaders: int love_InstanceID.
love.graphics.draw(mesh) will draw the mesh instancecount times, using hardware instancing when available. The only way to draw individual instances differently from each other is to use the love_InstanceID variable in a vertex shader. Added love.graphics.isSupported(“instancing”). Hardware instancing is supported if true, otherwise a (slower) pseudo-instancing fallback is used internally when drawing instanced meshes.
This commit is contained in:
@@ -175,6 +175,7 @@ StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::suppor
|
|||||||
{ "mipmap", Graphics::SUPPORT_MIPMAP },
|
{ "mipmap", Graphics::SUPPORT_MIPMAP },
|
||||||
{ "dxt", Graphics::SUPPORT_DXT },
|
{ "dxt", Graphics::SUPPORT_DXT },
|
||||||
{ "bc5", Graphics::SUPPORT_BC5 },
|
{ "bc5", Graphics::SUPPORT_BC5 },
|
||||||
|
{ "instancing", Graphics::SUPPORT_INSTANCING },
|
||||||
};
|
};
|
||||||
|
|
||||||
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
|
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public:
|
|||||||
SUPPORT_MIPMAP,
|
SUPPORT_MIPMAP,
|
||||||
SUPPORT_DXT,
|
SUPPORT_DXT,
|
||||||
SUPPORT_BC5,
|
SUPPORT_BC5,
|
||||||
|
SUPPORT_INSTANCING,
|
||||||
SUPPORT_MAX_ENUM
|
SUPPORT_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ Mesh::Mesh(const std::vector<Vertex> &verts, Mesh::DrawMode mode)
|
|||||||
, vertex_count(0)
|
, vertex_count(0)
|
||||||
, ibo(nullptr)
|
, ibo(nullptr)
|
||||||
, element_count(0)
|
, element_count(0)
|
||||||
|
, instance_count(1)
|
||||||
, draw_mode(mode)
|
, draw_mode(mode)
|
||||||
, texture(nullptr)
|
, texture(nullptr)
|
||||||
, colors_enabled(false)
|
, colors_enabled(false)
|
||||||
@@ -51,8 +52,8 @@ Mesh::~Mesh()
|
|||||||
|
|
||||||
void Mesh::setVertices(const std::vector<Vertex> &verts)
|
void Mesh::setVertices(const std::vector<Vertex> &verts)
|
||||||
{
|
{
|
||||||
if (verts.size() < 3)
|
if (verts.size() == 0)
|
||||||
throw love::Exception("At least 3 vertices are required.");
|
throw love::Exception("At least one vertex is required.");
|
||||||
|
|
||||||
size_t size = sizeof(Vertex) * verts.size();
|
size_t size = sizeof(Vertex) * verts.size();
|
||||||
|
|
||||||
@@ -170,6 +171,19 @@ size_t Mesh::getVertexMapCount() const
|
|||||||
return element_count;
|
return element_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::setInstanceCount(int count)
|
||||||
|
{
|
||||||
|
if (count < 1)
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
instance_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mesh::getInstanceCount() const
|
||||||
|
{
|
||||||
|
return instance_count;
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::setTexture(Texture *tex)
|
void Mesh::setTexture(Texture *tex)
|
||||||
{
|
{
|
||||||
tex->retain();
|
tex->retain();
|
||||||
@@ -270,18 +284,27 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
|||||||
|
|
||||||
if (ibo && element_count > 0)
|
if (ibo && element_count > 0)
|
||||||
{
|
{
|
||||||
|
// Use the custom vertex map (index buffer) to draw the vertices.
|
||||||
VertexBuffer::Bind ibo_bind(*ibo);
|
VertexBuffer::Bind ibo_bind(*ibo);
|
||||||
|
|
||||||
// Make sure the index buffer isn't mapped (sends data to GPU if needed.)
|
// Make sure the index buffer isn't mapped (sends data to GPU if needed.)
|
||||||
ibo->unmap();
|
ibo->unmap();
|
||||||
|
|
||||||
// Use the custom vertex map to draw the vertices.
|
const void *indices = ibo->getPointer(0);
|
||||||
glDrawElements(mode, element_count, GL_UNSIGNED_INT, ibo->getPointer(0));
|
const GLenum type = GL_UNSIGNED_INT;
|
||||||
|
|
||||||
|
if (instance_count > 1)
|
||||||
|
gl.drawElementsInstanced(mode, element_count, type, indices, instance_count);
|
||||||
|
else
|
||||||
|
glDrawElements(mode, element_count, type, indices);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal non-indexed drawing (no custom vertex map.)
|
// Normal non-indexed drawing (no custom vertex map.)
|
||||||
glDrawArrays(mode, 0, vertex_count);
|
if (instance_count > 1)
|
||||||
|
gl.drawArraysInstanced(mode, 0, vertex_count, instance_count);
|
||||||
|
else
|
||||||
|
glDrawArrays(mode, 0, vertex_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wireframe)
|
if (wireframe)
|
||||||
|
|||||||
@@ -109,6 +109,15 @@ public:
|
|||||||
**/
|
**/
|
||||||
size_t getVertexMapCount() const;
|
size_t getVertexMapCount() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of instances of this Mesh to draw (uses hardware
|
||||||
|
* instancing when possible.)
|
||||||
|
* A custom vertex shader is necessary in order to introduce differences
|
||||||
|
* in each instance.
|
||||||
|
**/
|
||||||
|
void setInstanceCount(int count);
|
||||||
|
int getInstanceCount() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the texture used when drawing the Mesh.
|
* Sets the texture used when drawing the Mesh.
|
||||||
**/
|
**/
|
||||||
@@ -165,6 +174,8 @@ private:
|
|||||||
VertexBuffer *ibo;
|
VertexBuffer *ibo;
|
||||||
size_t element_count;
|
size_t element_count;
|
||||||
|
|
||||||
|
int instance_count;
|
||||||
|
|
||||||
DrawMode draw_mode;
|
DrawMode draw_mode;
|
||||||
|
|
||||||
Texture *texture;
|
Texture *texture;
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ void OpenGL::initContext()
|
|||||||
initMaxValues();
|
initMaxValues();
|
||||||
createDefaultTexture();
|
createDefaultTexture();
|
||||||
|
|
||||||
|
state.lastPseudoInstanceID = -1;
|
||||||
|
|
||||||
contextInitialized = true;
|
contextInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +216,69 @@ void OpenGL::createDefaultTexture()
|
|||||||
|
|
||||||
void OpenGL::prepareDraw()
|
void OpenGL::prepareDraw()
|
||||||
{
|
{
|
||||||
// Make sure the active shader has the correct values for the built-in
|
Shader *shader = Shader::current;
|
||||||
// screen params uniform.
|
if (shader != nullptr)
|
||||||
if (Shader::current)
|
{
|
||||||
Shader::current->checkSetScreenParams();
|
// Make sure the active shader has the correct values for its
|
||||||
|
// love-provided uniforms.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGL::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
|
||||||
|
{
|
||||||
|
Shader *shader = Shader::current;
|
||||||
|
|
||||||
|
if (GLEE_ARB_draw_instanced)
|
||||||
|
glDrawArraysInstancedARB(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGL::drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
|
||||||
|
{
|
||||||
|
Shader *shader = Shader::current;
|
||||||
|
|
||||||
|
if (GLEE_ARB_draw_instanced)
|
||||||
|
glDrawElementsInstancedARB(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL::setColor(const Color &c)
|
void OpenGL::setColor(const Color &c)
|
||||||
|
|||||||
@@ -63,6 +63,17 @@ public:
|
|||||||
VENDOR_UNKNOWN
|
VENDOR_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vertex attributes used in shaders by LOVE. The values map to OpenGL
|
||||||
|
// generic vertex attribute indices, when applicable.
|
||||||
|
// LOVE uses the old hard-coded attribute APIs for positions, colors, etc.
|
||||||
|
// (for now.)
|
||||||
|
enum VertexAttrib
|
||||||
|
{
|
||||||
|
// Instance ID when pseudo-instancing is used.
|
||||||
|
ATTRIB_PSEUDO_INSTANCE_ID = 1,
|
||||||
|
ATTRIB_MAX_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
// A rectangle representing an OpenGL viewport or a scissor box.
|
// A rectangle representing an OpenGL viewport or a scissor box.
|
||||||
struct Viewport
|
struct Viewport
|
||||||
{
|
{
|
||||||
@@ -99,6 +110,16 @@ public:
|
|||||||
**/
|
**/
|
||||||
void prepareDraw();
|
void prepareDraw();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* glDrawArraysInstanced with a pseudo-instancing fallback.
|
||||||
|
**/
|
||||||
|
void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* glDrawElementsInstanced with a pseudo-instancing fallback.
|
||||||
|
**/
|
||||||
|
void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current constant color.
|
* Sets the current constant color.
|
||||||
**/
|
**/
|
||||||
@@ -230,6 +251,9 @@ private:
|
|||||||
Viewport viewport;
|
Viewport viewport;
|
||||||
Viewport scissor;
|
Viewport scissor;
|
||||||
|
|
||||||
|
// The last ID value used for pseudo-instancing.
|
||||||
|
int lastPseudoInstanceID;
|
||||||
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
}; // OpenGL
|
}; // OpenGL
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ Shader::Shader(const ShaderSources &sources)
|
|||||||
: shaderSources(sources)
|
: shaderSources(sources)
|
||||||
, program(0)
|
, program(0)
|
||||||
, builtinUniforms()
|
, builtinUniforms()
|
||||||
|
, vertexAttributes()
|
||||||
, lastCanvas((Canvas *) -1)
|
, lastCanvas((Canvas *) -1)
|
||||||
{
|
{
|
||||||
if (shaderSources.empty())
|
if (shaderSources.empty())
|
||||||
@@ -181,6 +182,14 @@ void Shader::createProgram(const std::vector<GLuint> &shaderids)
|
|||||||
for (it = shaderids.begin(); it != shaderids.end(); ++it)
|
for (it = shaderids.begin(); it != shaderids.end(); ++it)
|
||||||
glAttachShader(program, *it);
|
glAttachShader(program, *it);
|
||||||
|
|
||||||
|
// Bind generic vertex attribute indices to names in the shader.
|
||||||
|
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)
|
||||||
|
{
|
||||||
|
const char *name = nullptr;
|
||||||
|
if (attribNames.find((OpenGL::VertexAttrib) i, name))
|
||||||
|
glBindAttribLocation(program, i, (const GLchar *) name);
|
||||||
|
}
|
||||||
|
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
// flag shaders for auto-deletion when the program object is deleted.
|
// flag shaders for auto-deletion when the program object is deleted.
|
||||||
@@ -273,6 +282,15 @@ bool Shader::loadVolatile()
|
|||||||
// Retreive all active uniform variables in this shader from OpenGL.
|
// Retreive all active uniform variables in this shader from OpenGL.
|
||||||
mapActiveUniforms();
|
mapActiveUniforms();
|
||||||
|
|
||||||
|
for (int i = 0; i < int(OpenGL::ATTRIB_MAX_ENUM); i++)
|
||||||
|
{
|
||||||
|
const char *name = nullptr;
|
||||||
|
if (attribNames.find(OpenGL::VertexAttrib(i), name))
|
||||||
|
vertexAttributes[i] = glGetAttribLocation(program, name);
|
||||||
|
else
|
||||||
|
vertexAttributes[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (current == this)
|
if (current == this)
|
||||||
{
|
{
|
||||||
// make sure glUseProgram gets called.
|
// make sure glUseProgram gets called.
|
||||||
@@ -633,6 +651,11 @@ int Shader::getTextureUnit(const std::string &name)
|
|||||||
return texunit;
|
return texunit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Shader::hasVertexAttrib(OpenGL::VertexAttrib attrib) const
|
||||||
|
{
|
||||||
|
return vertexAttributes[int(attrib)] != -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool Shader::hasBuiltinExtern(BuiltinExtern builtin) const
|
bool Shader::hasBuiltinExtern(BuiltinExtern builtin) const
|
||||||
{
|
{
|
||||||
return builtinUniforms[int(builtin)] != -1;
|
return builtinUniforms[int(builtin)] != -1;
|
||||||
@@ -730,6 +753,13 @@ StringMap<Shader::ShaderType, Shader::TYPE_MAX_ENUM>::Entry Shader::typeNameEntr
|
|||||||
|
|
||||||
StringMap<Shader::ShaderType, Shader::TYPE_MAX_ENUM> Shader::typeNames(Shader::typeNameEntries, sizeof(Shader::typeNameEntries));
|
StringMap<Shader::ShaderType, Shader::TYPE_MAX_ENUM> Shader::typeNames(Shader::typeNameEntries, sizeof(Shader::typeNameEntries));
|
||||||
|
|
||||||
|
StringMap<OpenGL::VertexAttrib, OpenGL::ATTRIB_MAX_ENUM>::Entry Shader::attribNameEntries[] =
|
||||||
|
{
|
||||||
|
{"love_PseudoInstanceID", OpenGL::ATTRIB_PSEUDO_INSTANCE_ID},
|
||||||
|
};
|
||||||
|
|
||||||
|
StringMap<OpenGL::VertexAttrib, OpenGL::ATTRIB_MAX_ENUM> Shader::attribNames(Shader::attribNameEntries, sizeof(Shader::attribNameEntries));
|
||||||
|
|
||||||
StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
|
StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
|
||||||
{
|
{
|
||||||
{"love_ScreenParams", Shader::BUILTIN_SCREEN_PARAMS},
|
{"love_ScreenParams", Shader::BUILTIN_SCREEN_PARAMS},
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Internal use only.
|
* Internal use only.
|
||||||
**/
|
**/
|
||||||
|
bool hasVertexAttrib(OpenGL::VertexAttrib attrib) const;
|
||||||
bool hasBuiltinExtern(BuiltinExtern builtin) const;
|
bool hasBuiltinExtern(BuiltinExtern builtin) const;
|
||||||
bool sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *m, int count);
|
bool sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *m, int count);
|
||||||
void checkSetScreenParams();
|
void checkSetScreenParams();
|
||||||
@@ -198,6 +199,9 @@ private:
|
|||||||
// Location values for any built-in uniform variables.
|
// Location values for any built-in uniform variables.
|
||||||
GLint builtinUniforms[BUILTIN_MAX_ENUM];
|
GLint builtinUniforms[BUILTIN_MAX_ENUM];
|
||||||
|
|
||||||
|
// Location values for any generic vertex attribute variables.
|
||||||
|
GLint vertexAttributes[OpenGL::ATTRIB_MAX_ENUM];
|
||||||
|
|
||||||
// Uniform location buffer map
|
// Uniform location buffer map
|
||||||
std::map<std::string, Uniform> uniforms;
|
std::map<std::string, Uniform> uniforms;
|
||||||
|
|
||||||
@@ -220,6 +224,10 @@ private:
|
|||||||
static StringMap<ShaderType, TYPE_MAX_ENUM>::Entry typeNameEntries[];
|
static StringMap<ShaderType, TYPE_MAX_ENUM>::Entry typeNameEntries[];
|
||||||
static StringMap<ShaderType, TYPE_MAX_ENUM> typeNames;
|
static StringMap<ShaderType, TYPE_MAX_ENUM> typeNames;
|
||||||
|
|
||||||
|
// Names for the generic vertex attributes used by love.
|
||||||
|
static StringMap<OpenGL::VertexAttrib, OpenGL::ATTRIB_MAX_ENUM>::Entry attribNameEntries[];
|
||||||
|
static StringMap<OpenGL::VertexAttrib, OpenGL::ATTRIB_MAX_ENUM> attribNames;
|
||||||
|
|
||||||
// Names for the built-in uniform variables.
|
// Names for the built-in uniform variables.
|
||||||
static StringMap<BuiltinExtern, BUILTIN_MAX_ENUM>::Entry builtinNameEntries[];
|
static StringMap<BuiltinExtern, BUILTIN_MAX_ENUM>::Entry builtinNameEntries[];
|
||||||
static StringMap<BuiltinExtern, BUILTIN_MAX_ENUM> builtinNames;
|
static StringMap<BuiltinExtern, BUILTIN_MAX_ENUM> builtinNames;
|
||||||
|
|||||||
@@ -984,6 +984,10 @@ int w_isSupported(lua_State *L)
|
|||||||
if (!Image::hasCompressedTextureSupport(image::CompressedData::FORMAT_BC5))
|
if (!Image::hasCompressedTextureSupport(image::CompressedData::FORMAT_BC5))
|
||||||
supported = false;
|
supported = false;
|
||||||
break;
|
break;
|
||||||
|
case Graphics::SUPPORT_INSTANCING:
|
||||||
|
if (!GLEE_ARB_draw_instanced)
|
||||||
|
supported = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
supported = false;
|
supported = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,6 +236,20 @@ int w_Mesh_getVertexMap(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_Mesh_setInstanceCount(lua_State *L)
|
||||||
|
{
|
||||||
|
Mesh *t = luax_checkmesh(L, 1);
|
||||||
|
t->setInstanceCount(luaL_checkint(L, 2));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w_Mesh_getInstanceCount(lua_State *L)
|
||||||
|
{
|
||||||
|
Mesh *t = luax_checkmesh(L, 1);
|
||||||
|
lua_pushinteger(L, t->getInstanceCount());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int w_Mesh_setTexture(lua_State *L)
|
int w_Mesh_setTexture(lua_State *L)
|
||||||
{
|
{
|
||||||
Mesh *t = luax_checkmesh(L, 1);
|
Mesh *t = luax_checkmesh(L, 1);
|
||||||
@@ -338,6 +352,8 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getVertexCount", w_Mesh_getVertexCount },
|
{ "getVertexCount", w_Mesh_getVertexCount },
|
||||||
{ "setVertexMap", w_Mesh_setVertexMap },
|
{ "setVertexMap", w_Mesh_setVertexMap },
|
||||||
{ "getVertexMap", w_Mesh_getVertexMap },
|
{ "getVertexMap", w_Mesh_getVertexMap },
|
||||||
|
{ "setInstanceCount", w_Mesh_setInstanceCount },
|
||||||
|
{ "getInstanceCount", w_Mesh_getInstanceCount },
|
||||||
{ "setTexture", w_Mesh_setTexture },
|
{ "setTexture", w_Mesh_setTexture },
|
||||||
{ "getTexture", w_Mesh_getTexture },
|
{ "getTexture", w_Mesh_getTexture },
|
||||||
{ "setDrawMode", w_Mesh_setDrawMode },
|
{ "setDrawMode", w_Mesh_setDrawMode },
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ int w_Mesh_getVertices(lua_State *L);
|
|||||||
int w_Mesh_getVertexCount(lua_State *L);
|
int w_Mesh_getVertexCount(lua_State *L);
|
||||||
int w_Mesh_setVertexMap(lua_State *L);
|
int w_Mesh_setVertexMap(lua_State *L);
|
||||||
int w_Mesh_getVertexMap(lua_State *L);
|
int w_Mesh_getVertexMap(lua_State *L);
|
||||||
|
int w_Mesh_setInstanceCount(lua_State *L);
|
||||||
|
int w_Mesh_getInstanceCount(lua_State *L);
|
||||||
int w_Mesh_setTexture(lua_State *L);
|
int w_Mesh_setTexture(lua_State *L);
|
||||||
int w_Mesh_getTexture(lua_State *L);
|
int w_Mesh_getTexture(lua_State *L);
|
||||||
int w_Mesh_setDrawMode(lua_State *L);
|
int w_Mesh_setDrawMode(lua_State *L);
|
||||||
|
|||||||
@@ -1315,7 +1315,15 @@ uniform vec2 love_ScreenParams;]]
|
|||||||
#define VertexColor gl_Color
|
#define VertexColor gl_Color
|
||||||
|
|
||||||
#define VaryingTexCoord gl_TexCoord[0]
|
#define VaryingTexCoord gl_TexCoord[0]
|
||||||
#define VaryingColor gl_FrontColor]],
|
#define VaryingColor gl_FrontColor
|
||||||
|
|
||||||
|
#if defined(GL_ARB_draw_instanced)
|
||||||
|
#extension GL_ARB_draw_instanced : enable
|
||||||
|
#define love_InstanceID gl_InstanceIDARB
|
||||||
|
#else
|
||||||
|
attribute float love_PseudoInstanceID;
|
||||||
|
int love_InstanceID = int(love_PseudoInstanceID);
|
||||||
|
#endif]],
|
||||||
|
|
||||||
FOOTER = [[
|
FOOTER = [[
|
||||||
void main() {
|
void main() {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const unsigned char graphics_lua[] =
|
|||||||
|
|
||||||
0x2d, 0x2d, 0x5b, 0x5b, 0x0a,
|
0x2d, 0x2d, 0x5b, 0x5b, 0x0a,
|
||||||
0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36,
|
0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36,
|
||||||
0x2d, 0x32, 0x30, 0x31, 0x33, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
|
0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
|
||||||
0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a,
|
0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a,
|
||||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70,
|
0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70,
|
||||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77,
|
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77,
|
||||||
@@ -6312,8 +6312,23 @@ const unsigned char graphics_lua[] =
|
|||||||
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b,
|
0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b,
|
||||||
0x30, 0x5d, 0x0a,
|
0x30, 0x5d, 0x0a,
|
||||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c,
|
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c,
|
||||||
0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x5d, 0x5d,
|
0x6f, 0x72, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x0a,
|
||||||
0x2c, 0x0a,
|
0x23, 0x69, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x28, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42,
|
||||||
|
0x5f, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x29, 0x0a,
|
||||||
|
0x09, 0x23, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42,
|
||||||
|
0x5f, 0x64, 0x72, 0x61, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x3a, 0x20,
|
||||||
|
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x0a,
|
||||||
|
0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x49, 0x6e, 0x73, 0x74,
|
||||||
|
0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x20, 0x67, 0x6c, 0x5f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||||
|
0x49, 0x44, 0x41, 0x52, 0x42, 0x0a,
|
||||||
|
0x23, 0x65, 0x6c, 0x73, 0x65, 0x0a,
|
||||||
|
0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6c,
|
||||||
|
0x6f, 0x76, 0x65, 0x5f, 0x50, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||||
|
0x49, 0x44, 0x3b, 0x0a,
|
||||||
|
0x09, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
|
||||||
|
0x49, 0x44, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x50, 0x73, 0x65, 0x75,
|
||||||
|
0x64, 0x6f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x29, 0x3b, 0x0a,
|
||||||
|
0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5d, 0x5d, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
|
0x09, 0x09, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
|
||||||
0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
|
0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
|
||||||
0x09, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
0x09, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
||||||
|
|||||||
Reference in New Issue
Block a user