mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
Prevent redundant calls to glEnable/DisableVertexAttribArray. This should hopefully fix a performance regression compared to 0.9.2 as well.
This commit is contained in:
@@ -307,31 +307,25 @@ void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||
|
||||
gl.bindTexture(texture);
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD);
|
||||
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &v[0].x);
|
||||
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &v[0].s);
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
}
|
||||
|
||||
void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
static Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
drawv(t, vertices);
|
||||
}
|
||||
|
||||
void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
static Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
const Vertex *v = quad->getVertices();
|
||||
drawv(t, v);
|
||||
|
||||
@@ -564,25 +564,12 @@ void Font::printv(const Matrix &t, const std::vector<DrawCommand> &drawcommands,
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD);
|
||||
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(GlyphVertex), &vertices[0].x);
|
||||
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(GlyphVertex), &vertices[0].s);
|
||||
|
||||
try
|
||||
{
|
||||
drawVertices(drawcommands);
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
throw;
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
drawVertices(drawcommands);
|
||||
}
|
||||
|
||||
void Font::print(const std::string &text, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
@@ -590,8 +577,7 @@ void Font::print(const std::string &text, float x, float y, float angle, float s
|
||||
std::vector<GlyphVertex> vertices;
|
||||
std::vector<DrawCommand> drawcommands = generateVertices(text, vertices);
|
||||
|
||||
Matrix t;
|
||||
t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
printv(t, drawcommands, vertices);
|
||||
}
|
||||
@@ -601,8 +587,7 @@ void Font::printf(const std::string &text, float x, float y, float wrap, AlignMo
|
||||
std::vector<GlyphVertex> vertices;
|
||||
std::vector<DrawCommand> drawcommands = generateVerticesFormatted(text, wrap, align, vertices);
|
||||
|
||||
Matrix t;
|
||||
t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
printv(t, drawcommands, vertices);
|
||||
}
|
||||
|
||||
@@ -1088,10 +1088,9 @@ void Graphics::point(float x, float y)
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.bindTexture(gl.getDefaultTexture());
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, coord);
|
||||
gl.drawArrays(GL_POINTS, 0, 1);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
}
|
||||
|
||||
void Graphics::polyline(const float *coords, size_t count)
|
||||
@@ -1247,10 +1246,9 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1,
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.bindTexture(gl.getDefaultTexture());
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, coords);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, points + 2);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
}
|
||||
|
||||
delete[] coords;
|
||||
@@ -1273,10 +1271,9 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.bindTexture(gl.getDefaultTexture());
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, coords);
|
||||
gl.drawArrays(GL_TRIANGLE_FAN, 0, (int)count/2-1); // opengl will close the polygon for us
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -360,31 +360,25 @@ void Image::drawv(const Matrix &t, const Vertex *v)
|
||||
|
||||
gl.bindTexture(texture);
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD);
|
||||
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &v[0].x);
|
||||
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &v[0].s);
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
}
|
||||
|
||||
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
drawv(t, vertices);
|
||||
}
|
||||
|
||||
void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||
{
|
||||
Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
drawv(t, quad->getVertices());
|
||||
}
|
||||
|
||||
@@ -546,10 +546,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
{
|
||||
OpenGL::TempDebugGroup debuggroup("Mesh draw");
|
||||
|
||||
std::vector<GLint> attriblocations;
|
||||
attriblocations.reserve(attachedAttributes.size());
|
||||
|
||||
bool hasposattrib = false;
|
||||
uint32 enabledattribs = 0;
|
||||
|
||||
for (const auto &attrib : attachedAttributes)
|
||||
{
|
||||
@@ -585,24 +582,19 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
GLenum datatype = getGLDataType(format.type);
|
||||
GLboolean normalized = (datatype == GL_UNSIGNED_BYTE);
|
||||
|
||||
glEnableVertexAttribArray(attriblocation);
|
||||
glVertexAttribPointer(attriblocation, format.components, datatype, normalized, mesh->vertexStride, gloffset);
|
||||
|
||||
attriblocations.push_back(attriblocation);
|
||||
|
||||
if (attriblocation == ATTRIB_POS)
|
||||
hasposattrib = true;
|
||||
enabledattribs |= 1 << uint32(attriblocation);
|
||||
}
|
||||
|
||||
if (!hasposattrib)
|
||||
if (!(enabledattribs & ATTRIBFLAG_POS))
|
||||
{
|
||||
for (GLint attrib : attriblocations)
|
||||
glDisableVertexAttribArray(attrib);
|
||||
|
||||
// Not supported on all platforms or GL versions at least, I believe.
|
||||
throw love::Exception("Mesh must have an enabled VertexPosition attribute to be drawn.");
|
||||
}
|
||||
|
||||
gl.useVertexAttribArrays(enabledattribs);
|
||||
|
||||
if (texture.get())
|
||||
gl.bindTexture(*(GLuint *) texture->getHandle());
|
||||
else
|
||||
@@ -649,13 +641,6 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
// Normal non-indexed drawing (no custom vertex map.)
|
||||
gl.drawArrays(getGLDrawMode(drawMode), min, max - min + 1);
|
||||
}
|
||||
|
||||
for (GLint attrib : attriblocations)
|
||||
{
|
||||
glDisableVertexAttribArray(attrib);
|
||||
if (attrib == ATTRIB_COLOR)
|
||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Mesh::getAttribFormatSize(const AttribFormat &format)
|
||||
|
||||
@@ -90,6 +90,11 @@ void OpenGL::setupContext()
|
||||
glVertexAttrib4fv(ATTRIB_COLOR, glcolor);
|
||||
glVertexAttrib4fv(ATTRIB_CONSTANTCOLOR, glcolor);
|
||||
|
||||
GLint maxvertexattribs = 1;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxvertexattribs);
|
||||
state.enabledAttribArrays = 1u << uint32(maxvertexattribs - 1);
|
||||
useVertexAttribArrays(0);
|
||||
|
||||
// Get the current viewport.
|
||||
glGetIntegerv(GL_VIEWPORT, (GLint *) &state.viewport.x);
|
||||
|
||||
@@ -375,6 +380,38 @@ void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const void *i
|
||||
++stats.drawCalls;
|
||||
}
|
||||
|
||||
void OpenGL::useVertexAttribArrays(uint32 arraybits)
|
||||
{
|
||||
uint32 diff = arraybits ^ state.enabledAttribArrays;
|
||||
|
||||
if (diff == 0)
|
||||
return;
|
||||
|
||||
// Max 32 attributes. As of when this was written, no GL driver exposes more
|
||||
// than 32. Lets hope that doesn't change...
|
||||
for (uint32 i = 0; i < 32; i++)
|
||||
{
|
||||
uint32 bit = 1 << i;
|
||||
|
||||
if (diff & bit)
|
||||
{
|
||||
if (arraybits & bit)
|
||||
glEnableVertexAttribArray(i);
|
||||
else
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
state.enabledAttribArrays = arraybits;
|
||||
|
||||
// glDisableVertexAttribArray will make the constant value for a vertex
|
||||
// attribute undefined. We rely on the per-vertex color attribte being white
|
||||
// when no per-vertex color is used, so we set it here.
|
||||
// FIXME: Is there a better place to do this?
|
||||
if ((diff & ATTRIBFLAG_COLOR) && !(arraybits & ATTRIBFLAG_COLOR))
|
||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void OpenGL::setViewport(const OpenGL::Viewport &v)
|
||||
{
|
||||
glViewport(v.x, v.y, v.w, v.h);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
// LOVE
|
||||
#include "common/config.h"
|
||||
#include "common/int.h"
|
||||
#include "graphics/Color.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "common/Matrix.h"
|
||||
@@ -60,6 +61,14 @@ enum VertexAttribID
|
||||
ATTRIB_MAX_ENUM
|
||||
};
|
||||
|
||||
enum VertexAttribFlags
|
||||
{
|
||||
ATTRIBFLAG_POS = 1 << ATTRIB_POS,
|
||||
ATTRIBFLAG_TEXCOORD = 1 << ATTRIB_TEXCOORD,
|
||||
ATTRIBFLAG_COLOR = 1 << ATTRIB_COLOR,
|
||||
ATTRIBFLAG_CONSTANTCOLOR = 1 << ATTRIB_CONSTANTCOLOR
|
||||
};
|
||||
|
||||
/**
|
||||
* Thin layer between OpenGL and the rest of the program.
|
||||
* Internally shadows some OpenGL context state for improved efficiency and
|
||||
@@ -197,6 +206,15 @@ public:
|
||||
void drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
|
||||
/**
|
||||
* Sets the enabled vertex attribute arrays based on the specified attribute
|
||||
* bits. Each bit in the uint32 represents an enabled attribute array index.
|
||||
* For example, useVertexAttribArrays(1 << 0) will enable attribute index 0.
|
||||
* See the VertexAttribFlags enum for the standard vertex attributes.
|
||||
* This function *must* be used instead of glEnable/DisableVertexAttribArray.
|
||||
**/
|
||||
void useVertexAttribArrays(uint32 arraybits);
|
||||
|
||||
/**
|
||||
* Sets the OpenGL rendering viewport to the specified rectangle.
|
||||
* The y-coordinate starts at the top.
|
||||
@@ -353,6 +371,8 @@ private:
|
||||
// Currently active texture unit.
|
||||
int curTextureUnit;
|
||||
|
||||
uint32 enabledAttribArrays;
|
||||
|
||||
Viewport viewport;
|
||||
Viewport scissor;
|
||||
|
||||
|
||||
@@ -854,8 +854,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
|
||||
OpenGL::TempDebugGroup debuggroup("ParticleSystem draw");
|
||||
|
||||
static Matrix t;
|
||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
@@ -896,9 +895,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
gl.bindTexture(*(GLuint *) texture->getHandle());
|
||||
gl.prepareDraw();
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_COLOR);
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR);
|
||||
|
||||
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), &particleVerts[0].r);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &particleVerts[0].x);
|
||||
@@ -909,12 +906,6 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
|
||||
GLBuffer::Bind ibo_bind(*quadIndices.getBuffer());
|
||||
gl.drawElements(GL_TRIANGLES, count, quadIndices.getType(), quadIndices.getPointer(0));
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
glDisableVertexAttribArray(ATTRIB_COLOR);
|
||||
|
||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void ParticleSystem::update(float dt)
|
||||
|
||||
@@ -402,21 +402,26 @@ void Polyline::draw()
|
||||
gl.prepareDraw();
|
||||
|
||||
gl.bindTexture(gl.getDefaultTexture());
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, vertices + vertex_start);
|
||||
|
||||
uint32 enabledattribs = ATTRIBFLAG_POS;
|
||||
|
||||
if (overdraw)
|
||||
{
|
||||
// Prepare colors. Set the core line's colors to white, and the overdraw
|
||||
// Prepare per-vertex colors. Set the core to white, and the overdraw
|
||||
// line's colors to white on one side and transparent on the other.
|
||||
colors = new Color[total_vertex_count];
|
||||
memset(colors, 255, overdraw_vertex_start * sizeof(Color));
|
||||
fill_color_array(colors + overdraw_vertex_start);
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_COLOR);
|
||||
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors);
|
||||
|
||||
enabledattribs |= ATTRIBFLAG_COLOR;
|
||||
}
|
||||
|
||||
gl.useVertexAttribArrays(enabledattribs);
|
||||
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, vertices + vertex_start);
|
||||
|
||||
// Draw the core line and the overdraw in a single draw call. We can do this
|
||||
// because the vertex array contains both the core line and the overdraw
|
||||
// vertices.
|
||||
@@ -425,15 +430,8 @@ void Polyline::draw()
|
||||
else
|
||||
gl.drawArrays(draw_mode, 0, (int) total_vertex_count);
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
|
||||
if (overdraw)
|
||||
{
|
||||
glDisableVertexAttribArray(ATTRIB_COLOR);
|
||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
delete[] colors;
|
||||
}
|
||||
|
||||
if (indices)
|
||||
delete[] indices;
|
||||
|
||||
@@ -236,30 +236,22 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
|
||||
array_buf->unmap(buffer_used_offset, buffer_used_size);
|
||||
buffer_used_offset = buffer_used_size = 0;
|
||||
|
||||
uint32 enabledattribs = ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD;
|
||||
|
||||
// Apply per-sprite color, if a color is set.
|
||||
if (color)
|
||||
{
|
||||
glEnableVertexAttribArray(ATTRIB_COLOR);
|
||||
enabledattribs |= ATTRIBFLAG_COLOR;
|
||||
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), array_buf->getPointer(color_offset));
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), array_buf->getPointer(pos_offset));
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), array_buf->getPointer(texel_offset));
|
||||
|
||||
gl.useVertexAttribArrays(enabledattribs);
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.drawElements(GL_TRIANGLES, (GLsizei) quad_indices.getIndexCount(next), quad_indices.getType(), quad_indices.getPointer(0));
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
|
||||
if (color)
|
||||
{
|
||||
glDisableVertexAttribArray(ATTRIB_COLOR);
|
||||
glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteBatch::addv(const Vertex *v, const Matrix &m, int index)
|
||||
|
||||
@@ -232,8 +232,7 @@ void Text::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
const size_t tex_offset = offsetof(Font::GlyphVertex, s);
|
||||
const size_t stride = sizeof(Font::GlyphVertex);
|
||||
|
||||
Matrix t;
|
||||
t.setTransformation(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
Matrix t(ceilf(x), ceilf(y), angle, sx, sy, ox, oy, kx, ky);
|
||||
|
||||
OpenGL::TempTransform transform(gl);
|
||||
transform.get() *= t;
|
||||
@@ -247,22 +246,9 @@ void Text::draw(float x, float y, float angle, float sx, float sy, float ox, flo
|
||||
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, vbo->getPointer(tex_offset));
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(ATTRIB_POS);
|
||||
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD);
|
||||
|
||||
try
|
||||
{
|
||||
font->drawVertices(draw_commands);
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
throw;
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(ATTRIB_TEXCOORD);
|
||||
glDisableVertexAttribArray(ATTRIB_POS);
|
||||
font->drawVertices(draw_commands);
|
||||
}
|
||||
|
||||
void Text::setFont(Font *f)
|
||||
|
||||
Reference in New Issue
Block a user