diff --git a/src/modules/graphics/Font.cpp b/src/modules/graphics/Font.cpp index d1537fba1..2ca76fc1c 100644 --- a/src/modules/graphics/Font.cpp +++ b/src/modules/graphics/Font.cpp @@ -45,6 +45,8 @@ static inline uint16 normToUint16(double n) love::Type Font::type("Font", &Object::type); int Font::fontCount = 0; +const vertex::CommonFormat Font::vertexFormat = vertex::CommonFormat::XYf_STus_RGBAub; + Font::Font(love::font::Rasterizer *r, const Texture::Filter &f) : rasterizers({r}) , height(r->getHeight()) @@ -603,7 +605,7 @@ void Font::printv(graphics::Graphics *gfx, const Matrix4 &t, const std::vector Codepoints; typedef vertex::XYf_STus_RGBAub GlyphVertex; + static const vertex::CommonFormat vertexFormat; + enum AlignMode { ALIGN_LEFT, diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index f5c586ef7..bece3b942 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -356,8 +356,7 @@ void Graphics::flushStreamDraws() if (sbstate.formats[i] == CommonFormat::NONE) continue; - GLsizei stride = (GLsizei) getFormatStride(sbstate.formats[i]); - usedsizes[i] = stride * sbstate.vertexCount; + usedsizes[i] = getFormatStride(sbstate.formats[i]) * sbstate.vertexCount; love::graphics::StreamBuffer *buffer = sbstate.vb[i]; @@ -366,36 +365,8 @@ void Graphics::flushStreamDraws() sbstate.vbMap[i] = StreamBuffer::MapInfo(); - switch (sbstate.formats[i]) - { - case CommonFormat::NONE: - break; - case CommonFormat::XYf: - attribs |= ATTRIBFLAG_POS; - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset)); - break; - case CommonFormat::RGBAub: - attribs |= ATTRIBFLAG_COLOR; - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset)); - break; - case CommonFormat::XYf_STf: - attribs |= ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD; - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf, s))); - break; - case CommonFormat::XYf_STf_RGBAub: - attribs |= ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR; - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, s))); - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, color.r))); - break; - case CommonFormat::XYf_STus_RGBAub: - attribs |= ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR; - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_UNSIGNED_SHORT, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, s))); - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, color.r))); - break; - } + gl.setVertexPointers(sbstate.formats[i], offset); + attribs |= getFormatFlags(sbstate.formats[i]); } if (attribs == 0) diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index f74e0663a..26bc61a2d 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -26,6 +26,7 @@ #include "common/Exception.h" #include "graphics/Graphics.h" +#include "graphics/Buffer.h" // C++ #include @@ -631,6 +632,54 @@ void OpenGL::useVertexAttribArrays(uint32 arraybits, uint32 instancedbits) glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); } +void OpenGL::setVertexPointers(vertex::CommonFormat format, size_t stride, size_t offset) +{ + using namespace vertex; + + switch (format) + { + case CommonFormat::NONE: + break; + case CommonFormat::XYf: + glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset)); + break; + case CommonFormat::RGBAub: + glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset)); + break; + case CommonFormat::XYf_STf: + glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf, x))); + glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf, s))); + break; + case CommonFormat::XYf_STf_RGBAub: + glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, x))); + glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, s))); + glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STf_RGBAub, color.r))); + break; + case CommonFormat::XYf_STus_RGBAub: + glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, x))); + glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_UNSIGNED_SHORT, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, s))); + glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offset + offsetof(XYf_STus_RGBAub, color.r))); + break; + } +} + +void OpenGL::setVertexPointers(vertex::CommonFormat format, size_t offset) +{ + setVertexPointers(format, getFormatStride(format), offset); +} + +void OpenGL::setVertexPointers(vertex::CommonFormat format, love::graphics::Buffer *buffer, size_t offset) +{ + bindBuffer(BUFFER_VERTEX, (GLuint) buffer->getHandle()); + setVertexPointers(format, offset); +} + +void OpenGL::setVertexPointers(vertex::CommonFormat format, love::graphics::Buffer *buffer, size_t stride, size_t offset) +{ + bindBuffer(BUFFER_VERTEX, (GLuint) buffer->getHandle()); + setVertexPointers(format, stride, offset); +} + void OpenGL::setViewport(const Rect &v) { glViewport(v.x, v.y, v.w, v.h); diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 9fb260174..c3c8f7c58 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -44,6 +44,9 @@ namespace love { namespace graphics { + +class Buffer; + namespace opengl { @@ -209,6 +212,15 @@ public: **/ void useVertexAttribArrays(uint32 arraybits, uint32 instancedbits = 0); + /** + * Calls glVertexAttribPointer appropriately for each attribute used in the + * specified format. + **/ + void setVertexPointers(vertex::CommonFormat format, size_t offset); + void setVertexPointers(vertex::CommonFormat format, size_t stride, size_t offset); + void setVertexPointers(vertex::CommonFormat format, love::graphics::Buffer *buffer, size_t offset); + void setVertexPointers(vertex::CommonFormat format, love::graphics::Buffer *buffer, size_t stride, size_t offset); + /** * Sets the OpenGL rendering viewport to the specified rectangle. * The y-coordinate starts at the top. diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index 85a9b0533..f80be1fa2 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -52,6 +52,8 @@ ParticleSystem *ParticleSystem::clone() void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m) { + using namespace vertex; + if (!prepareDraw(gfx, m)) return; @@ -63,12 +65,8 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m) gl.bindTextureToUnit(texture, 0, false); gl.prepareDraw(); - gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR); - - gl.bindBuffer(BUFFER_VERTEX, (GLuint) buffer->getHandle()); - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, color.r))); - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, s))); + gl.useVertexAttribArrays(getFormatFlags(CommonFormat::XYf_STf_RGBAub)); + gl.setVertexPointers(CommonFormat::XYf_STf_RGBAub, buffer, 0); GLsizei count = (GLsizei) quadIndices.getIndexCount(getCount()); GLenum gltype = OpenGL::getGLIndexDataType(quadIndices.getType()); diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index c97bae8c3..220283287 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -53,6 +53,8 @@ SpriteBatch::~SpriteBatch() void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) { + using namespace vertex; + if (next == 0) return; @@ -70,19 +72,13 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) array_buf->unmap(); - gl.bindBuffer(BUFFER_VERTEX, (GLuint) array_buf->getHandle()); + CommonFormat format = CommonFormat::XYf_STf_RGBAub; + if (color == nullptr) + format = CommonFormat::XYf_STf; - uint32 enabledattribs = ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD; + uint32 enabledattribs = getFormatFlags(format); - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, s))); - - // Apply per-sprite color, if a color is set. - if (color) - { - enabledattribs |= ATTRIBFLAG_COLOR; - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, color.r))); - } + gl.setVertexPointers(format, array_buf, getFormatStride(CommonFormat::XYf_STf_RGBAub), 0); for (const auto &it : attached_attributes) { diff --git a/src/modules/graphics/opengl/Text.cpp b/src/modules/graphics/opengl/Text.cpp index 8c5849b86..d9995498b 100644 --- a/src/modules/graphics/opengl/Text.cpp +++ b/src/modules/graphics/opengl/Text.cpp @@ -69,14 +69,8 @@ void Text::draw(Graphics *gfx, const Matrix4 &m) gl.prepareDraw(); - size_t stride = sizeof(Font::GlyphVertex); - - gl.bindBuffer(BUFFER_VERTEX, (GLuint) vbo->getHandle()); - glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(offsetof(Font::GlyphVertex, x))); - glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_UNSIGNED_SHORT, GL_TRUE, stride, BUFFER_OFFSET(offsetof(Font::GlyphVertex, s))); - glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, BUFFER_OFFSET(offsetof(Font::GlyphVertex, color.r))); - - gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR); + gl.setVertexPointers(Font::vertexFormat, vbo, 0); + gl.useVertexAttribArrays(vertex::getFormatFlags(Font::vertexFormat)); const GLenum gltype = OpenGL::getGLIndexDataType(quadIndices.getType()); const size_t elemsize = quadIndices.getElementSize(); diff --git a/src/modules/graphics/vertex.cpp b/src/modules/graphics/vertex.cpp index 2395e1c80..8c343217d 100644 --- a/src/modules/graphics/vertex.cpp +++ b/src/modules/graphics/vertex.cpp @@ -29,7 +29,6 @@ namespace vertex { static_assert(sizeof(Color) == 4, "sizeof(Color) incorrect!"); -static_assert(sizeof(Vertex) == sizeof(float)*2 + sizeof(float)*2 + sizeof(Color), "sizeof(Vertex) incorrect!"); static_assert(sizeof(XYf_STf) == sizeof(float)*2 + sizeof(float)*2, "sizeof(XYf_STf) incorrect!"); static_assert(sizeof(XYf_STf_RGBAub) == sizeof(float)*2 + sizeof(float)*2 + sizeof(Color), "sizeof(XYf_STf_RGBAub) incorrect!"); static_assert(sizeof(XYf_STus_RGBAub) == sizeof(float)*2 + sizeof(uint16)*2 + sizeof(Color), "sizeof(XYf_STus_RGBAub) incorrect!"); @@ -53,6 +52,25 @@ size_t getFormatStride(CommonFormat format) } } +uint32 getFormatFlags(CommonFormat format) +{ + switch (format) + { + case CommonFormat::NONE: + return 0; + case CommonFormat::XYf: + return ATTRIBFLAG_POS; + case CommonFormat::RGBAub: + return ATTRIBFLAG_COLOR; + case CommonFormat::XYf_STf: + return ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD; + case CommonFormat::XYf_STf_RGBAub: + case CommonFormat::XYf_STus_RGBAub: + return ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR; + + } +} + size_t getIndexDataSize(IndexDataType type) { switch (type) diff --git a/src/modules/graphics/vertex.h b/src/modules/graphics/vertex.h index 7f289a300..986663b80 100644 --- a/src/modules/graphics/vertex.h +++ b/src/modules/graphics/vertex.h @@ -122,6 +122,7 @@ struct XYf_STus_RGBAub }; size_t getFormatStride(CommonFormat format); +uint32 getFormatFlags(CommonFormat format); size_t getIndexDataSize(IndexDataType type); IndexDataType getIndexDataTypeFromMax(size_t maxvalue);