diff --git a/include/Graphics/BartaSprite.h b/include/Graphics/BartaSprite.h index d2a93bd..b1029d8 100644 --- a/include/Graphics/BartaSprite.h +++ b/include/Graphics/BartaSprite.h @@ -12,9 +12,17 @@ enum class SpriteType { /* x, y, z, // center coordinates radius, - color (rgba) + color (rgba), + meshDensity */ CIRCLE, + /* + x, y, z, // center coordinates + radius, + color (rgba), + meshDensity + */ + BALL, /* x, y, z, // top-left coordinates font_size, @@ -56,20 +64,21 @@ class BartaSprite { BartaSprite() = default; ~BartaSprite() = default; - inline int getResourceId() const { return this->resource; } + int getResourceId() const { return this->resource; } - inline bool reloadCache() const { return this->doReloadCache; } + bool reloadCache() const { return this->doReloadCache; } - inline const std::vector& getData() const { return this->data; } + const std::vector& getData() const { return this->data; } - inline const std::vector& getSpriteType() const { return this->spriteTypes; } + const std::vector& getSpriteType() const { return this->spriteTypes; } static unsigned int getSpriteTypeSize( SpriteType type ) { switch (type) { case SpriteType::RECTANGLE_WITH_COLORS: return 6 + 4 * 4; - case SpriteType::CIRCLE: return 8; + case SpriteType::CIRCLE: return 9; + case SpriteType::BALL: return 9; case SpriteType::VARCHAR256: return 256 / 4 + 4; case SpriteType::TRIANGLE: return 9 + 3 * 4; } diff --git a/include/Graphics/OpenGL_Bridge/TrianglePrimitive.h b/include/Graphics/OpenGL_Bridge/TrianglePrimitive.h index 29aa3a8..48462e1 100644 --- a/include/Graphics/OpenGL_Bridge/TrianglePrimitive.h +++ b/include/Graphics/OpenGL_Bridge/TrianglePrimitive.h @@ -3,9 +3,9 @@ namespace Barta::Graphics::OpenGL_Bridge { struct TrianglePrimitive { - GLubyte index1; - GLubyte index2; - GLubyte index3; + GLuint index1; + GLuint index2; + GLuint index3; }; } diff --git a/include/Graphics/OpenGL_Bridge/VertexArray.h b/include/Graphics/OpenGL_Bridge/VertexArray.h index 06385b6..43d1c14 100644 --- a/include/Graphics/OpenGL_Bridge/VertexArray.h +++ b/include/Graphics/OpenGL_Bridge/VertexArray.h @@ -18,9 +18,9 @@ class VertexArray { void addVertices(const std::vector& vertices) noexcept; - GLubyte getNextVertexIndex() const noexcept { return this->vertices.size(); } + GLuint getNextVertexIndex() const noexcept { return this->triangles.size(); } - void addTrianglePrimitive(TrianglePrimitive t) noexcept; + void addTrianglePrimitive(unsigned int i1, unsigned int i2, unsigned int i3) noexcept; void addTrianglePrimitives(std::vector primitives) noexcept; diff --git a/include/Graphics/SpriteBuilder/CircleSprite.h b/include/Graphics/SpriteBuilder/CircleSprite.h index fe26d11..9054a84 100644 --- a/include/Graphics/SpriteBuilder/CircleSprite.h +++ b/include/Graphics/SpriteBuilder/CircleSprite.h @@ -7,12 +7,15 @@ namespace Barta { struct CircleSprite { CircleSprite( Circle circle, - Color color + Color color, + float meshDensity ) noexcept: circle(std::move(circle)), - color(color) {} + color(color), + meshDensity(meshDensity) {} Circle circle; Color color; + float meshDensity; }; } diff --git a/include/Graphics/SpriteBuilder/SpriteBuilder.h b/include/Graphics/SpriteBuilder/SpriteBuilder.h index 000a363..2a174e4 100644 --- a/include/Graphics/SpriteBuilder/SpriteBuilder.h +++ b/include/Graphics/SpriteBuilder/SpriteBuilder.h @@ -31,10 +31,13 @@ class SpriteBuilder { std::string string; int fontSize; + float meshDensity; + CircleSprite buildCircleSprite() const { return { {this->radius, this->center}, this->color, + this->meshDensity }; } @@ -128,5 +131,9 @@ inline void from_json( if (j.contains("fontSize")) { j.at("fontSize").get_to(sprite.fontSize); } + + if (j.contains("meshDensity")) { + j.at("meshDensity").get_to(sprite.meshDensity); + } } } diff --git a/include/Graphics/SpriteBuilder/SpriteMerger.h b/include/Graphics/SpriteBuilder/SpriteMerger.h index 68601c2..3ea073e 100644 --- a/include/Graphics/SpriteBuilder/SpriteMerger.h +++ b/include/Graphics/SpriteBuilder/SpriteMerger.h @@ -16,6 +16,8 @@ class SpriteMerger { SpriteMerger* addCircleSprite(const CircleSprite& circleSprite); + SpriteMerger* addBallSprite(const CircleSprite& ballSprite); + SpriteMerger* addString(const StringSprite& stringSprite); SpriteMerger* addTriangle(const TriangleSprite& triangleSprite); diff --git a/lib/Graphics/OpenGL_Bridge.cpp b/lib/Graphics/OpenGL_Bridge.cpp index ce39720..817a639 100644 --- a/lib/Graphics/OpenGL_Bridge.cpp +++ b/lib/Graphics/OpenGL_Bridge.cpp @@ -75,7 +75,6 @@ void OpenGL_Bridge::createWindow( void OpenGL_Bridge::drawObjects( std::list& objects ) { - auto xd = 0; for (const auto& object: objects) { for (auto graphicsData_ptr: object->getGraphicsData()) { if (graphicsData_ptr->resource.getResourceId() != 0) { @@ -90,6 +89,7 @@ void OpenGL_Bridge::drawObjects( Point center(data[0], data[1], data[2]); float radius = data[3]; Color color(data[4], data[5], data[6], data[7]); + float meshDensity = data[8]; // TODO auto segmentCount = static_cast(2.f * M_PI * radius); auto initialIndex = this->vertexArray->getNextVertexIndex(); @@ -99,11 +99,69 @@ void OpenGL_Bridge::drawObjects( float angle = 2.f * static_cast(i) * M_PI / segmentCount; vertices.emplace_back(center + Vector(radius * cos(angle), radius * sin(angle), 0.f), color); - this->vertexArray->addTrianglePrimitive({ - initialIndex, - static_cast(initialIndex + 1u + i), - static_cast(initialIndex + 1u + (i + 1u) % segmentCount), - }); + this->vertexArray->addTrianglePrimitive(initialIndex, initialIndex + 1u + i, initialIndex + 1u + (i + 1u) % segmentCount); + } + } else if (type == SpriteType::BALL) { + Point center(data[0], data[1], data[2]); + float radius = data[3]; + Color color(data[4], data[5], data[6], data[7]); + float meshDensity = data[8]; + + auto latitudeLineCount = static_cast(M_PI * radius * meshDensity) + 1u; // +1 is a UV seam + auto longitudeLineCount = static_cast(.5 * M_PI * radius * meshDensity) - 2u; + auto totalVertexCount = latitudeLineCount * longitudeLineCount + 2u; + auto initialIndex = this->vertexArray->getNextVertexIndex(); + Vertex northPole{ + center + Vector{0, 0, radius}, + color + }; + vertices.push_back(northPole); + for (int i = 0; i < longitudeLineCount; i++) { + auto alpha = static_cast(i + 1) * M_PI / static_cast(longitudeLineCount + 1); + auto cosAlpha = std::cos(alpha); + auto sinAlpha = std::sin(alpha); + for (int j = 0; j < latitudeLineCount; j++) { + auto beta = 2. * static_cast(j) * M_PI / static_cast(latitudeLineCount - 1); + Point p{ + radius * sinAlpha * std::cos(beta), + radius * sinAlpha * std::sin(beta), + radius * cosAlpha, + }; + + vertices.emplace_back(p, color); + } + } + + Vertex southPole{ + center + Vector{0, 0, -radius}, + color + }; + vertices.push_back(southPole); + + for (int j = 0; j < latitudeLineCount - 1; j++) { + this->vertexArray->addTrianglePrimitive(initialIndex, initialIndex + 1u + j, initialIndex + 2u + j); + + this->vertexArray->addTrianglePrimitive( + initialIndex + totalVertexCount - 1u, + initialIndex + totalVertexCount - 2u - j, + initialIndex + totalVertexCount - 3u - j + ); + } + + for (int i = 0; i < longitudeLineCount - 1; i++) { + for (int j = 0; j < latitudeLineCount - 1; j++) { + this->vertexArray->addTrianglePrimitive( + initialIndex + 1u + i * latitudeLineCount + j, + initialIndex + 1u + (i + 1u) * latitudeLineCount + j, + initialIndex + 1u + i * latitudeLineCount + j + 1u + ); + + this->vertexArray->addTrianglePrimitive( + initialIndex + 1u + (i + 1u) * latitudeLineCount + j, + initialIndex + 1u + (i + 1u) * latitudeLineCount + j + 1u, + initialIndex + 1u + i * latitudeLineCount + j + 1 + ); + } } } else if (type == SpriteType::TRIANGLE) { Point p1(data[0], data[1], data[2]); @@ -119,10 +177,7 @@ void OpenGL_Bridge::drawObjects( {p3, c3} }; - this->vertexArray->addTrianglePrimitive( - {initialIndex, static_cast(initialIndex + 1u), static_cast(initialIndex + 2)} - ); - xd++; + this->vertexArray->addTrianglePrimitive(initialIndex, initialIndex + 1u, initialIndex + 2); } else if (type == SpriteType::RECTANGLE_WITH_COLORS) { Point p1(data[0], data[1], data[2]); Point p2(data[0] + data[3], data[1], data[2]); @@ -140,12 +195,8 @@ void OpenGL_Bridge::drawObjects( {p4, c4} }; - this->vertexArray->addTrianglePrimitive( - {initialIndex, static_cast(initialIndex + 1u), static_cast(initialIndex + 2)} - ); - this->vertexArray->addTrianglePrimitive( - {initialIndex, static_cast(initialIndex + 2u), static_cast(initialIndex + 3)} - ); + this->vertexArray->addTrianglePrimitive(initialIndex, initialIndex + 1u, initialIndex + 2); + this->vertexArray->addTrianglePrimitive(initialIndex, initialIndex + 2u, initialIndex + 3); } for (auto& vertex: vertices) { @@ -186,7 +237,7 @@ void OpenGL_Bridge::drawObjects( { AttributeArrayGuard attributeArrayGuard(*this->attributeArray); - glDrawElements(GL_TRIANGLES, 3 * this->vertexArray->getNextVertexIndex(), GL_UNSIGNED_BYTE, reinterpret_cast(0)); + glDrawElements(GL_TRIANGLES, 3 * this->vertexArray->getNextVertexIndex(), GL_UNSIGNED_INT, reinterpret_cast(0)); } glfwSwapBuffers(this->window); diff --git a/lib/Graphics/OpenGL_Bridge/VertexArray.cpp b/lib/Graphics/OpenGL_Bridge/VertexArray.cpp index 294a8d2..0065bbd 100644 --- a/lib/Graphics/OpenGL_Bridge/VertexArray.cpp +++ b/lib/Graphics/OpenGL_Bridge/VertexArray.cpp @@ -38,9 +38,15 @@ void VertexArray::clear() { } void VertexArray::addTrianglePrimitive( - TrianglePrimitive t + unsigned int i1, + unsigned int i2, + unsigned int i3 ) noexcept { - this->triangles.push_back(t); + this->triangles.push_back({ + static_cast(i1), + static_cast(i2), + static_cast(i3), + }); } } diff --git a/lib/Graphics/SpriteBuilder/SpriteMerger.cpp b/lib/Graphics/SpriteBuilder/SpriteMerger.cpp index 8d52c7b..d84f5ef 100644 --- a/lib/Graphics/SpriteBuilder/SpriteMerger.cpp +++ b/lib/Graphics/SpriteBuilder/SpriteMerger.cpp @@ -47,6 +47,28 @@ Barta::SpriteMerger* Barta::SpriteMerger::addCircleSprite( this->data.push_back(circleSprite.color.b); this->data.push_back(circleSprite.color.a); + this->data.push_back(circleSprite.meshDensity); + + return this; +} + +Barta::SpriteMerger* Barta::SpriteMerger::addBallSprite( + const CircleSprite& ballSprite +) { + this->types.push_back(SpriteType::BALL); + + this->data.push_back(ballSprite.circle.getCenter().x()); + this->data.push_back(ballSprite.circle.getCenter().y()); + this->data.push_back(ballSprite.circle.getCenter().z()); + this->data.push_back(ballSprite.circle.getRadius()); + + this->data.push_back(ballSprite.color.r); + this->data.push_back(ballSprite.color.g); + this->data.push_back(ballSprite.color.b); + this->data.push_back(ballSprite.color.a); + + this->data.push_back(ballSprite.meshDensity); + return this; } diff --git a/lib/SceneLoader/JsonDecoderRepository.cpp b/lib/SceneLoader/JsonDecoderRepository.cpp index b066d59..9d94266 100644 --- a/lib/SceneLoader/JsonDecoderRepository.cpp +++ b/lib/SceneLoader/JsonDecoderRepository.cpp @@ -20,7 +20,7 @@ std::unique_ptr JsonDecoderRepository::decodeHitbox( } const auto& type = jsonType.get(); - if (type == "CIRCLE") { + if (type == "CIRCLE" || type == "BALL") { return std::make_unique(hitboxJson.get()); } @@ -61,6 +61,12 @@ GraphicsData JsonDecoderRepository::decodeGraphicsData( continue; } + if (type == "BALL") { + merger.addBallSprite(spriteBuilder.buildCircleSprite()); + + continue; + } + if (type == "RECTANGLE") { merger.addRectangleWithColors(spriteBuilder.buildRectangleSprite());