Browse Source

Merge branch 'master' into compatibility

Vladimír Vondruš 13 years ago
parent
commit
ac1337e9d8
  1. 16
      src/OpenGL.h
  2. 7
      src/Shaders/Flat.cpp
  3. 16
      src/Shaders/Flat.frag
  4. 5
      src/Shaders/Flat.h
  5. 27
      src/Text/AbstractFont.h
  6. 17
      src/Text/Renderer.cpp
  7. 61
      src/Text/Test/RendererGLTest.cpp

16
src/OpenGL.h

@ -33,7 +33,7 @@
/* Desktop OpenGL */ /* Desktop OpenGL */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
#include <OpenGL/GL/gl_magnum.h> #include "OpenGL/GL/gl_magnum.h"
/* NaCl has its own gl2.h, the official one causes linker issues. Additionaly /* NaCl has its own gl2.h, the official one causes linker issues. Additionaly
to NaCl's gl2ext.h we are including our own to prevent undeclared symbol to NaCl's gl2ext.h we are including our own to prevent undeclared symbol
@ -45,19 +45,19 @@
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#undef __gl2ext_h_ #undef __gl2ext_h_
#include <OpenGL/GLES2/gl2ext.h> #include "OpenGL/GLES2/gl2ext.h"
/* Generic OpenGL ES */ /* Generic OpenGL ES */
#else #else
#include <OpenGL/KHR/khrplatform.h> #include "OpenGL/KHR/khrplatform.h"
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
#include <OpenGL/GLES3/gl3platform.h> #include "OpenGL/GLES3/gl3platform.h"
#include <OpenGL/GLES3/gl3.h> #include "OpenGL/GLES3/gl3.h"
#else #else
#include <OpenGL/GLES2/gl2platform.h> #include "OpenGL/GLES2/gl2platform.h"
#include <OpenGL/GLES2/gl2.h> #include "OpenGL/GLES2/gl2.h"
#endif #endif
#include <OpenGL/GLES2/gl2ext.h> #include "OpenGL/GLES2/gl2ext.h"
#endif #endif
#endif #endif

7
src/Shaders/Flat.cpp

@ -81,7 +81,7 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): tran
#endif #endif
{ {
transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix"); transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(!(flags & Flag::Textured)) colorUniform = uniformLocation("color"); colorUniform = uniformLocation("color");
} }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -90,6 +90,11 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): tran
{ {
if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureLayer); if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureLayer);
} }
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
setColor(Color4(1.0f)); // Default to white, with full transperancy (so we can see the texture)
#endif
} }
template class Flat<2>; template class Flat<2>;

16
src/Shaders/Flat.frag

@ -34,12 +34,20 @@ layout(binding = 0) uniform sampler2D textureData;
#else #else
uniform sampler2D textureData; uniform sampler2D textureData;
#endif #endif
#else #endif
#ifdef EXPLICIT_UNIFORM_LOCATION #ifdef EXPLICIT_UNIFORM_LOCATION
# ifndef GL_ES
layout(location = 1) uniform vec4 color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
# else
layout(location = 1) uniform vec4 color; layout(location = 1) uniform vec4 color;
# endif
#else #else
uniform lowp vec4 color; # ifndef GL_ES
#endif uniform lowp vec4 color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
# else
unfirom lowp vec4 color;
# endif
#endif #endif
#ifdef TEXTURED #ifdef TEXTURED
@ -52,7 +60,7 @@ out lowp vec4 fragmentColor;
void main() { void main() {
#ifdef TEXTURED #ifdef TEXTURED
fragmentColor = texture(textureData, interpolatedTextureCoordinates); fragmentColor = color * texture(textureData, interpolatedTextureCoordinates);
#else #else
fragmentColor = color; fragmentColor = color;
#endif #endif

5
src/Shaders/Flat.h

@ -124,7 +124,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
* @brief Set color * @brief Set color
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Has no effect if @ref Flag::Textured is set. * Color will be multiplied with texture
* if @ref Flag::Textured is set.
*/ */
Flat<dimensions>& setColor(const Color4& color); Flat<dimensions>& setColor(const Color4& color);
@ -144,7 +145,7 @@ typedef Flat<3> Flat3D;
CORRADE_ENUMSET_OPERATORS(Implementation::FlatFlags) CORRADE_ENUMSET_OPERATORS(Implementation::FlatFlags)
template<UnsignedInt dimensions> inline Flat<dimensions>& Flat<dimensions>::setColor(const Color4& color) { template<UnsignedInt dimensions> inline Flat<dimensions>& Flat<dimensions>::setColor(const Color4& color) {
if(!(_flags & Flag::Textured)) setUniform(colorUniform, color); setUniform(colorUniform, color);
return *this; return *this;
} }

27
src/Text/AbstractFont.h

@ -152,17 +152,28 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
/** @brief Close font */ /** @brief Close font */
void close(); void close();
/** @brief Font size */ /**
* @brief Font size
*
* Returns scale in which @ref lineHeight() and @ref glyphAdvance() is
* returned.
*/
Float size() const { return _size; } Float size() const { return _size; }
/** @brief Line height */ /**
* @brief Line height
*
* Returns line height scaled to font size.
* @see @ref size()
*/
Float lineHeight() const { return _lineHeight; } Float lineHeight() const { return _lineHeight; }
/** /**
* @brief Glyph ID for given character * @brief Glyph ID for given character
* *
* @note This function is not meant to be used in performance-critical * @note This function is meant to be used only for font observations
* code, only for font observations and conversions. * and conversions. In performance-critical code the @ref layout()
* function should be used instead.
*/ */
UnsignedInt glyphId(char32_t character); UnsignedInt glyphId(char32_t character);
@ -170,9 +181,11 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* @brief Glyph advance * @brief Glyph advance
* @param glyph Glyph ID * @param glyph Glyph ID
* *
* @note This function is not meant to be used in performance-critical * Returns glyph advance scaled to font size.
* code, only for font observations and conversions. * @note This function is meant to be used only for font observations
* @see @ref glyphId() * and conversions. In performance-critical code the @ref layout()
* function should be used instead.
* @see @ref glyphId(), @ref size()
*/ */
Vector2 glyphAdvance(UnsignedInt glyph); Vector2 glyphAdvance(UnsignedInt glyph);

17
src/Text/Renderer.cpp

@ -44,7 +44,7 @@ template<class T> void createIndices(void* output, const UnsignedInt glyphCount)
1---3 1 3---4 */ 1---3 1 3---4 */
const T vertex = T(i)*4; const T vertex = T(i)*4;
const T pos = T(i)*6; const UnsignedInt pos = T(i)*6;
out[pos] = vertex; out[pos] = vertex;
out[pos+1] = vertex+1; out[pos+1] = vertex+1;
out[pos+2] = vertex+2; out[pos+2] = vertex+2;
@ -61,16 +61,18 @@ struct Vertex {
Vector2 position, textureCoordinates; Vector2 position, textureCoordinates;
}; };
std::tuple<std::vector<Vertex>, Range2D> renderVerticesInternal(AbstractFont& font, const GlyphCache& cache, Float size, const std::string& text, const Alignment alignment) { std::tuple<std::vector<Vertex>, Range2D> renderVerticesInternal(AbstractFont& font, const GlyphCache& cache, const Float size, const std::string& text, const Alignment alignment) {
/* Output data, reserve memory as when the text would be ASCII-only. In /* Output data, reserve memory as when the text would be ASCII-only. In
reality the actual vertex count will be smaller, but allocating more at reality the actual vertex count will be smaller, but allocating more at
once is better than reallocating many times later. */ once is better than reallocating many times later. */
std::vector<Vertex> vertices; std::vector<Vertex> vertices;
vertices.reserve(text.size()*4); vertices.reserve(text.size()*4);
/* Total rendered bounds, intial line position, last+1 vertex on previous line */ /* Total rendered bounds, intial line position, line increment, last+1
vertex on previous line */
Range2D rectangle; Range2D rectangle;
Vector2 linePosition; Vector2 linePosition;
const Vector2 lineAdvance = Vector2::yAxis(font.lineHeight()*size/font.size());
std::size_t lastLineLastVertex = 0; std::size_t lastLineLastVertex = 0;
/* Temp buffer so we don't allocate for each new line */ /* Temp buffer so we don't allocate for each new line */
@ -149,7 +151,7 @@ std::tuple<std::vector<Vertex>, Range2D> renderVerticesInternal(AbstractFont& fo
/* Move to next line */ /* Move to next line */
} while(prevPos = pos+1, } while(prevPos = pos+1,
linePosition -= Vector2::yAxis(font.lineHeight()), linePosition -= lineAdvance,
lastLineLastVertex = vertices.size(), lastLineLastVertex = vertices.size(),
pos != std::string::npos); pos != std::string::npos);
@ -178,11 +180,11 @@ std::pair<Containers::Array<unsigned char>, Mesh::IndexType> renderIndicesIntern
Containers::Array<unsigned char> indices; Containers::Array<unsigned char> indices;
Mesh::IndexType indexType; Mesh::IndexType indexType;
if(vertexCount < 255) { if(vertexCount <= 256) {
indexType = Mesh::IndexType::UnsignedByte; indexType = Mesh::IndexType::UnsignedByte;
indices = Containers::Array<unsigned char>(indexCount*sizeof(UnsignedByte)); indices = Containers::Array<unsigned char>(indexCount*sizeof(UnsignedByte));
createIndices<UnsignedByte>(indices, glyphCount); createIndices<UnsignedByte>(indices, glyphCount);
} else if(vertexCount < 65535) { } else if(vertexCount <= 65536) {
indexType = Mesh::IndexType::UnsignedShort; indexType = Mesh::IndexType::UnsignedShort;
indices = Containers::Array<unsigned char>(indexCount*sizeof(UnsignedShort)); indices = Containers::Array<unsigned char>(indexCount*sizeof(UnsignedShort));
createIndices<UnsignedShort>(indices, glyphCount); createIndices<UnsignedShort>(indices, glyphCount);
@ -203,7 +205,6 @@ std::tuple<Mesh, Range2D> renderInternal(AbstractFont& font, const GlyphCache& c
vertexBuffer.setData(vertices, usage); vertexBuffer.setData(vertices, usage);
const UnsignedInt glyphCount = vertices.size()/4; const UnsignedInt glyphCount = vertices.size()/4;
const UnsignedInt vertexCount = glyphCount*4;
const UnsignedInt indexCount = glyphCount*6; const UnsignedInt indexCount = glyphCount*6;
/* Render indices and upload them */ /* Render indices and upload them */
@ -217,7 +218,7 @@ std::tuple<Mesh, Range2D> renderInternal(AbstractFont& font, const GlyphCache& c
Mesh mesh; Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles) mesh.setPrimitive(MeshPrimitive::Triangles)
.setIndexCount(indexCount) .setIndexCount(indexCount)
.setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount); .setIndexBuffer(indexBuffer, 0, indexType, 0, vertices.size());
return std::make_tuple(std::move(mesh), rectangle); return std::make_tuple(std::move(mesh), rectangle);
} }

61
src/Text/Test/RendererGLTest.cpp

@ -34,6 +34,7 @@ class RendererGLTest: public Magnum::Test::AbstractOpenGLTester {
void renderData(); void renderData();
void renderMesh(); void renderMesh();
void renderMeshIndexType();
void mutableText(); void mutableText();
void multiline(); void multiline();
@ -42,6 +43,7 @@ class RendererGLTest: public Magnum::Test::AbstractOpenGLTester {
RendererGLTest::RendererGLTest() { RendererGLTest::RendererGLTest() {
addTests({&RendererGLTest::renderData, addTests({&RendererGLTest::renderData,
&RendererGLTest::renderMesh, &RendererGLTest::renderMesh,
&RendererGLTest::renderMeshIndexType,
&RendererGLTest::mutableText, &RendererGLTest::mutableText,
&RendererGLTest::multiline}); &RendererGLTest::multiline});
@ -169,7 +171,8 @@ void RendererGLTest::renderMesh() {
Mesh mesh; Mesh mesh;
Buffer vertexBuffer, indexBuffer; Buffer vertexBuffer, indexBuffer;
Range2D bounds; Range2D bounds;
std::tie(mesh, bounds) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr), 0.25f, "abc", vertexBuffer, indexBuffer, BufferUsage::StaticDraw, Alignment::TopCenter); std::tie(mesh, bounds) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr),
0.25f, "abc", vertexBuffer, indexBuffer, BufferUsage::StaticDraw, Alignment::TopCenter);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
/* Alignment offset */ /* Alignment offset */
@ -181,7 +184,8 @@ void RendererGLTest::renderMesh() {
/** @todo How to verify this on ES? */ /** @todo How to verify this on ES? */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/* Vertex buffer contents */ /* Vertex buffer contents */
Containers::Array<Float> vertices = vertexBuffer.data<Float>(); const Containers::Array<Float> vertices = vertexBuffer.data<Float>();
CORRADE_COMPARE(vertices.size(), 3*4*(2 + 2));
CORRADE_COMPARE(std::vector<Float>(vertices.begin(), vertices.end()), (std::vector<Float>{ CORRADE_COMPARE(std::vector<Float>(vertices.begin(), vertices.end()), (std::vector<Float>{
0.0f + offset.x(), 0.5f + offset.y(), 0.0f, 10.0f, 0.0f + offset.x(), 0.5f + offset.y(), 0.0f, 10.0f,
0.0f + offset.x(), 0.0f + offset.y(), 0.0f, 0.0f, 0.0f + offset.x(), 0.0f + offset.y(), 0.0f, 0.0f,
@ -199,7 +203,8 @@ void RendererGLTest::renderMesh() {
5.0f + offset.x(), -0.5f + offset.y(), 18.0f, 0.0f 5.0f + offset.x(), -0.5f + offset.y(), 18.0f, 0.0f
})); }));
Containers::Array<UnsignedByte> indices = indexBuffer.data<UnsignedByte>(); const Containers::Array<UnsignedByte> indices = indexBuffer.data<UnsignedByte>();
CORRADE_COMPARE(indices.size(), 3*6);
CORRADE_COMPARE(std::vector<UnsignedByte>(indices.begin(), indices.end()), (std::vector<UnsignedByte>{ CORRADE_COMPARE(std::vector<UnsignedByte>(indices.begin(), indices.end()), (std::vector<UnsignedByte>{
0, 1, 2, 1, 3, 2, 0, 1, 2, 1, 3, 2,
4, 5, 6, 5, 7, 6, 4, 5, 6, 5, 7, 6,
@ -208,6 +213,45 @@ void RendererGLTest::renderMesh() {
#endif #endif
} }
void RendererGLTest::renderMeshIndexType() {
#ifndef MAGNUM_TARGET_GLES
TestFont font;
Mesh mesh;
Buffer vertexBuffer, indexBuffer;
/* Sizes: four vertices per glyph, each vertex has 2D position and 2D
texture coordinates, each float is four bytes; six indices per glyph. */
/* 8-bit indices (exactly 256 vertices) */
std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr),
1.0f, std::string(64, 'a'), vertexBuffer, indexBuffer, BufferUsage::StaticDraw);
MAGNUM_VERIFY_NO_ERROR();
Containers::Array<UnsignedByte> indicesByte = indexBuffer.data<UnsignedByte>();
CORRADE_COMPARE(vertexBuffer.size(), 256*(2 + 2)*4);
CORRADE_COMPARE(indicesByte.size(), 64*6);
CORRADE_COMPARE(std::vector<UnsignedByte>(indicesByte.begin(), indicesByte.begin()+18), (std::vector<UnsignedByte>{
0, 1, 2, 1, 3, 2,
4, 5, 6, 5, 7, 6,
8, 9, 10, 9, 11, 10
}));
/* 16-bit indices (260 vertices) */
std::tie(mesh, std::ignore) = Text::Renderer3D::render(font, *static_cast<GlyphCache*>(nullptr),
1.0f, std::string(65, 'a'), vertexBuffer, indexBuffer, BufferUsage::StaticDraw);
MAGNUM_VERIFY_NO_ERROR();
Containers::Array<UnsignedShort> indicesShort = indexBuffer.data<UnsignedShort>();
CORRADE_COMPARE(vertexBuffer.size(), 260*(2 + 2)*4);
CORRADE_COMPARE(indicesShort.size(), 65*6);
CORRADE_COMPARE(std::vector<UnsignedShort>(indicesShort.begin(), indicesShort.begin()+18), (std::vector<UnsignedShort>{
0, 1, 2, 1, 3, 2,
4, 5, 6, 5, 7, 6,
8, 9, 10, 9, 11, 10
}));
#else
CORRADE_SKIP("Can't verify buffer contents on OpenGL ES.");
#endif
}
void RendererGLTest::mutableText() { void RendererGLTest::mutableText() {
TestFont font; TestFont font;
Text::Renderer2D renderer(font, *static_cast<GlyphCache*>(nullptr), 0.25f); Text::Renderer2D renderer(font, *static_cast<GlyphCache*>(nullptr), 0.25f);
@ -264,7 +308,7 @@ void RendererGLTest::mutableText() {
void RendererGLTest::multiline() { void RendererGLTest::multiline() {
class Layouter: public Text::AbstractLayouter { class Layouter: public Text::AbstractLayouter {
public: public:
explicit Layouter(UnsignedInt glyphs): AbstractLayouter(glyphs) {} explicit Layouter(UnsignedInt glyphCount): AbstractLayouter(glyphCount) {}
private: private:
std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt) override { std::tuple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt) override {
@ -284,7 +328,7 @@ void RendererGLTest::multiline() {
std::pair<Float, Float> doOpenFile(const std::string&, Float) { std::pair<Float, Float> doOpenFile(const std::string&, Float) {
_opened = true; _opened = true;
return {0, 3.0f}; return {0.5f, 0.75f};
} }
UnsignedInt doGlyphId(char32_t) override { return 0; } UnsignedInt doGlyphId(char32_t) override { return 0; }
@ -303,7 +347,12 @@ void RendererGLTest::multiline() {
std::vector<UnsignedInt> indices; std::vector<UnsignedInt> indices;
std::vector<Vector2> positions, textureCoordinates; std::vector<Vector2> positions, textureCoordinates;
std::tie(positions, textureCoordinates, indices, rectangle) = Text::Renderer2D::render(font, std::tie(positions, textureCoordinates, indices, rectangle) = Text::Renderer2D::render(font,
*static_cast<GlyphCache*>(nullptr), 0.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter); *static_cast<GlyphCache*>(nullptr), 2.0f, "abcd\nef\n\nghi", Alignment::MiddleCenter);
/* We're rendering text at 2.0f size and the font is scaled to 0.3f, so the
line advance should be 0.75f*2.0f/0.5f = 3.0f */
CORRADE_COMPARE(font.size(), 0.5f);
CORRADE_COMPARE(font.lineHeight(), 0.75f);
/* Bounds */ /* Bounds */
CORRADE_COMPARE(rectangle, Range2D({-3.5f, -5.0f}, {3.5f, 5.0f})); CORRADE_COMPARE(rectangle, Range2D({-3.5f, -5.0f}, {3.5f, 5.0f}));

Loading…
Cancel
Save