mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Add love.graphics.drawShaderVertices (name subject to change).
It draws a number of vertices, or a number of indices from an index buffer, without using any vertex data from a vertex buffer. A custom shader is required while using it. It is useful when a custom GLSL3 vertex shader which uses love_VertexID is used to pull or compute per-vertex information from other sources.
This commit is contained in:
@@ -1516,6 +1516,75 @@ void Graphics::drawInstanced(Mesh *mesh, const Matrix4 &m, int instancecount)
|
||||
mesh->drawInstanced(this, m, instancecount);
|
||||
}
|
||||
|
||||
void Graphics::drawShaderVertices(PrimitiveType primtype, int vertexcount, int instancecount, Texture *maintexture)
|
||||
{
|
||||
flushBatchedDraws();
|
||||
|
||||
if (!capabilities.features[FEATURE_GLSL3])
|
||||
throw love::Exception("drawShaderVertices is not supported on this system (GLSL3 support is required.)");
|
||||
|
||||
if (Shader::isDefaultActive() || !Shader::current)
|
||||
throw love::Exception("drawShaderVertices can only be used with a custom shader.");
|
||||
|
||||
if (vertexcount < 0 || instancecount < 0)
|
||||
throw love::Exception("drawShaderVertices vertex and instance count parameters must not be negative.");
|
||||
|
||||
Shader::current->validateDrawState(PRIMITIVE_TRIANGLES, maintexture);
|
||||
|
||||
VertexAttributes attributes;
|
||||
BufferBindings buffers;
|
||||
|
||||
DrawCommand cmd(&attributes, &buffers);
|
||||
|
||||
cmd.primitiveType = primtype;
|
||||
cmd.vertexCount = vertexcount;
|
||||
cmd.instanceCount = std::max(1, instancecount);
|
||||
cmd.texture = maintexture;
|
||||
|
||||
draw(cmd);
|
||||
}
|
||||
|
||||
void Graphics::drawShaderVertices(Buffer *indexbuffer, int indexcount, int instancecount, int startindex, Texture *maintexture)
|
||||
{
|
||||
flushBatchedDraws();
|
||||
|
||||
if (!capabilities.features[FEATURE_GLSL3])
|
||||
throw love::Exception("drawShaderVertices is not supported on this system (GLSL3 support is required.)");
|
||||
|
||||
if (!(indexbuffer->getUsageFlags() & BUFFERUSAGEFLAG_INDEX))
|
||||
throw love::Exception("The buffer passed to drawShaderVertices must be an index buffer.");
|
||||
|
||||
if (startindex < 0)
|
||||
throw love::Exception("drawShaderVertices startindex parameter must not be negative.");
|
||||
|
||||
if (indexcount < 0 || instancecount < 0)
|
||||
throw love::Exception("drawShaderVertices index and instance count parameters must not be negative.");
|
||||
|
||||
if ((size_t)(startindex + indexcount) > indexbuffer->getArrayLength())
|
||||
throw love::Exception("drawShaderVertices startindex and index count parameters do not fit in the given index buffer.");
|
||||
|
||||
if (Shader::isDefaultActive() || !Shader::current)
|
||||
throw love::Exception("drawShaderVertices can only be used with a custom shader.");
|
||||
|
||||
Shader::current->validateDrawState(PRIMITIVE_TRIANGLES, maintexture);
|
||||
|
||||
VertexAttributes attributes;
|
||||
BufferBindings buffers;
|
||||
|
||||
DrawIndexedCommand cmd(&attributes, &buffers, indexbuffer);
|
||||
|
||||
cmd.primitiveType = PRIMITIVE_TRIANGLES;
|
||||
cmd.indexCount = indexcount;
|
||||
cmd.instanceCount = std::max(1, instancecount);
|
||||
|
||||
cmd.indexType = getIndexDataType(indexbuffer->getDataMember(0).decl.format);
|
||||
cmd.indexBufferOffset = startindex * getIndexDataSize(cmd.indexType);
|
||||
|
||||
cmd.texture = maintexture;
|
||||
|
||||
draw(cmd);
|
||||
}
|
||||
|
||||
void Graphics::print(const std::vector<Font::ColoredString> &str, const Matrix4 &m)
|
||||
{
|
||||
checkSetDefaultFont();
|
||||
|
||||
@@ -688,6 +688,9 @@ public:
|
||||
void drawLayer(Texture *texture, int layer, Quad *quad, const Matrix4 &m);
|
||||
void drawInstanced(Mesh *mesh, const Matrix4 &m, int instancecount);
|
||||
|
||||
void drawShaderVertices(PrimitiveType primtype, int vertexcount, int instancecount, Texture *maintexture);
|
||||
void drawShaderVertices(Buffer *indexbuffer, int indexcount, int instancecount, int startindex, Texture *maintexture);
|
||||
|
||||
/**
|
||||
* Draws text at the specified coordinates
|
||||
**/
|
||||
|
||||
@@ -2938,6 +2938,42 @@ int w_drawInstanced(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_drawShaderVertices(lua_State *L)
|
||||
{
|
||||
if (luax_istype(L, 1, Buffer::type))
|
||||
{
|
||||
// Indexed drawing.
|
||||
Buffer *t = luax_checkbuffer(L, 1);
|
||||
|
||||
int indexcount = (int) luaL_checkinteger(L, 2);
|
||||
int instancecount = (int) luaL_optinteger(L, 3, 1);
|
||||
int indexstart = (int) luaL_optinteger(L, 4, 1) - 1;
|
||||
|
||||
Texture *tex = nullptr;
|
||||
if (!lua_isnoneornil(L, 5))
|
||||
tex = luax_checktexture(L, 5);
|
||||
|
||||
luax_catchexcept(L, [&]() { instance()->drawShaderVertices(t, indexcount, instancecount, indexstart, tex); });
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *primstr = luaL_checkstring(L, 1);
|
||||
PrimitiveType primtype = PRIMITIVE_TRIANGLES;
|
||||
if (!getConstant(primstr, primtype))
|
||||
return luax_enumerror(L, "primitive type", getConstants(primtype), primstr);
|
||||
|
||||
int vertexcount = (int) luaL_checkinteger(L, 2);
|
||||
int instancecount = (int) luaL_optinteger(L, 3, 1);
|
||||
|
||||
Texture *tex = nullptr;
|
||||
if (!lua_isnoneornil(L, 4))
|
||||
tex = luax_checktexture(L, 4);
|
||||
|
||||
luax_catchexcept(L, [&]() { instance()->drawShaderVertices(primtype, vertexcount, instancecount, tex); });
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_print(lua_State *L)
|
||||
{
|
||||
std::vector<Font::ColoredString> str;
|
||||
@@ -3614,6 +3650,7 @@ static const luaL_Reg functions[] =
|
||||
{ "draw", w_draw },
|
||||
{ "drawLayer", w_drawLayer },
|
||||
{ "drawInstanced", w_drawInstanced },
|
||||
{ "drawShaderVertices", w_drawShaderVertices },
|
||||
|
||||
{ "print", w_print },
|
||||
{ "printf", w_printf },
|
||||
|
||||
Reference in New Issue
Block a user