diff --git a/src/core/Color.h b/src/core/Color.h index b432c8b..6941a10 100644 --- a/src/core/Color.h +++ b/src/core/Color.h @@ -33,7 +33,7 @@ public: std::vector getAsVectorDouble() const { - return {mR/255.0, mG/255.0, mB/255.0, mAlpha/255.0}; + return {mR/255.0, mG/255.0, mB/255.0, mAlpha}; } uint32_t getAsUInt32() const diff --git a/src/geometry/Point.cpp b/src/geometry/Point.cpp index b556ad2..bab525a 100644 --- a/src/geometry/Point.cpp +++ b/src/geometry/Point.cpp @@ -1,21 +1,24 @@ #include "Point.h" -Point::Point(double x, double y) +Point::Point(double x, double y, double z) : mX(x), - mY(y) + mY(y), + mZ(z) { } Point::Point(const DiscretePoint& point) : mX(point.GetX()), - mY(point.GetY()) + mY(point.GetY()), + mZ(0) { } -Point::Point(const Point& reference, double offSetX, double offSetY) +Point::Point(const Point& reference, double offSetX, double offSetY, double offSetZ) : mX(reference.getX() + offSetX), - mY(reference.getY() + offSetY) + mY(reference.getY() + offSetY), + mZ(reference.getZ() + offSetZ) { } @@ -24,9 +27,9 @@ Point::~Point() { }; -std::shared_ptr Point::Create(double x, double y) +std::shared_ptr Point::Create(double x, double y, double z) { - return std::make_shared(x, y); + return std::make_shared(x, y, z); } double Point::getX() const @@ -39,14 +42,19 @@ double Point::getY() const return mY; } +double Point::getZ() const +{ + return mZ; +} + double Point::getDistance(const Point& point) const { - return std::sqrt(mX*point.getX() + mY*point.getY()); + return std::sqrt(mX*point.getX() + mY*point.getY() + mZ*point.getZ()); } double Point::getDistance(Point* point) const { - return std::sqrt(mX*point->getX() + mY*point->getY()); + return std::sqrt(mX*point->getX() + mY*point->getY() + mZ*point->getZ()); } double Point::getDeltaX(const Point& point) const diff --git a/src/geometry/Point.h b/src/geometry/Point.h index 740eb6c..ac5c549 100644 --- a/src/geometry/Point.h +++ b/src/geometry/Point.h @@ -9,20 +9,22 @@ class Point { public: - Point(double x, double y); + Point(double x, double y, double z = 0); Point(const DiscretePoint& point); - Point(const Point& reference, double offSetX, double offSetY); + Point(const Point& reference, double offSetX, double offSetY, double offSetZ = 0); ~Point(); - static std::shared_ptr Create(double x, double y); + static std::shared_ptr Create(double x, double y, double z = 0); double getX() const; double getY() const; + double getZ() const; + double getDistance(const Point& point) const; double getDistance(Point* point) const; diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt index 94f78ca..bcaf193 100644 --- a/src/graphics/CMakeLists.txt +++ b/src/graphics/CMakeLists.txt @@ -7,12 +7,14 @@ list(APPEND graphics_LIB_INCLUDES DrawingContext.cpp DrawingSurface.cpp RasterPainter.cpp + PainterFactory.cpp ${platform_LIB_INCLUDES} ) list(APPEND graphics_HEADERS ${platform_HEADERS} RasterPainter.h + PainterFactory.h ) set(OpenGL_GL_PREFERENCE "GLVND") @@ -21,10 +23,15 @@ if (OpenGL_FOUND) list(APPEND platform_LIBS OpenGL::GL OpenGL::GLU) list(APPEND graphics_LIB_INCLUDES opengl/OpenGlPainter.cpp + opengl/OpenGlTextPainter.cpp + opengl/OpenGlMeshPainter.cpp opengl/OpenGlFontTexture.cpp - opengl/OpenGlShaderProgram.cpp) + opengl/OpenGlShaderProgram.cpp + ) list(APPEND graphics_HEADERS opengl/OpenGlPainter.h + opengl/OpenGlTextPainter.h + opengl/OpenGlMeshPainter.h opengl/OpenGlFontTexture.h opengl/OpenGlShaderProgram.h) else() diff --git a/src/graphics/DrawingContext.cpp b/src/graphics/DrawingContext.cpp index c81ae0e..d7b4d1d 100644 --- a/src/graphics/DrawingContext.cpp +++ b/src/graphics/DrawingContext.cpp @@ -1,10 +1,8 @@ #include "DrawingContext.h" #include "AbstractPainter.h" -#include "OpenGlPainter.h" -#include "OpenGlShaderProgram.h" -#include "OpenGlFontTexture.h" -#include "RasterPainter.h" +#include "PainterFactory.h" + #include "Grid.h" #include "TriMesh.h" @@ -17,14 +15,7 @@ DrawingContext::DrawingContext(DrawingSurface* surface, FontsManager* fontsManag mScene(std::make_unique()), mFontsManager(fontsManager) { - if (mDrawingMode == DrawingMode::GRAPH) - { - mPainter = std::make_unique(); - } - else - { - mPainter = std::make_unique(); - } + mPainter = PainterFactory::Create(mDrawingMode); } std::unique_ptr DrawingContext::Create(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode) diff --git a/src/graphics/PainterFactory.cpp b/src/graphics/PainterFactory.cpp new file mode 100644 index 0000000..e360819 --- /dev/null +++ b/src/graphics/PainterFactory.cpp @@ -0,0 +1,27 @@ +#include "PainterFactory.h" + +#include "OpenGlPainter.h" +#include "OpenGlMeshPainter.h" +#include "OpenGlTextPainter.h" +#include "OpenGlShaderProgram.h" +#include "OpenGlFontTexture.h" + +#include "Grid.h" + +#include "RasterPainter.h" + +#include "DrawingContext.h" + +std::unique_ptr PainterFactory::Create(DrawingMode drawMode) +{ + if (drawMode == DrawingMode::GRAPH) + { + return std::make_unique(); + } + else + { + return std::make_unique(); + } +} + + diff --git a/src/graphics/PainterFactory.h b/src/graphics/PainterFactory.h new file mode 100644 index 0000000..9204a0b --- /dev/null +++ b/src/graphics/PainterFactory.h @@ -0,0 +1,13 @@ +#pragma once + +#include "AbstractPainter.h" + +#include + +enum class DrawingMode; + +class PainterFactory +{ +public: + static std::unique_ptr Create(DrawingMode drawMode); +}; diff --git a/src/graphics/opengl/OpenGlMeshPainter.cpp b/src/graphics/opengl/OpenGlMeshPainter.cpp new file mode 100644 index 0000000..d0d903e --- /dev/null +++ b/src/graphics/opengl/OpenGlMeshPainter.cpp @@ -0,0 +1,111 @@ +#include "OpenGlMeshPainter.h" + +#include "DrawingContext.h" +#include "DrawingSurface.h" +#include "TriMesh.h" + +#include "OpenGlShaderProgram.h" + +#ifdef _WIN32 +#include +#endif + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include + +#include +#include +#include + +#include + +OpenGlMeshPainter::OpenGlMeshPainter() +{ + +} + +void OpenGlMeshPainter::initializeShader() +{ + auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.vert"; + auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.frag"; + mShaderProgram = std::make_unique(vert_shader_path, frag_shader_path); +} + +void OpenGlMeshPainter::initializeBuffers() +{ + glGenBuffers(1, &mVertexBuffer); + + glGenBuffers(1, &mElementBuffer); + + glGenVertexArrays(1, &mVertexArray); +} + +void OpenGlMeshPainter::paint(const std::vector& verts, const std::vector& elements, const std::vector& color) +{ + glBindVertexArray(mVertexArray); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(float), verts.data(), GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(unsigned), elements.data(), GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + //glm::mat4 projection = glm::ortho(0.0f, width, 0.0f, height); + //glUniformMatrix4fv(glGetUniformLocation(mShaderProgram->getHandle(), "projection"), 1, GL_FALSE, glm::value_ptr(projection)); + + glUseProgram(mShaderProgram->getHandle()); + glBindVertexArray(mVertexArray); + + int vertexColorLocation = glGetUniformLocation(mShaderProgram->getHandle(), "ourColor"); + glUniform4f(vertexColorLocation, float(color[0]), float(color[1]), float(color[2]), float(color[3])); + + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); +} + +void OpenGlMeshPainter::paint(TriMesh* mesh, DrawingContext* context) +{ + if (!mShaderProgram) + { + initializeShader(); + } + + if (mVertexArray == 0) + { + initializeBuffers(); + } + + auto surface = context->getSurface(); + const auto width = float(surface->getWidth()); + const auto height = float(surface->getHeight()); + + auto vertices = mesh->getVerticesFlat(); + for (std::size_t idx = 0; idxgetFaceNodeIds(); + + std::vector color(4, 1.0f); + if (mesh->hasVectorAttribute("Color")) + { + auto mesh_color = mesh->getVectorAttribute("Color"); + color = {float(mesh_color[0]), float(mesh_color[1]), float(mesh_color[2]), float(mesh_color[3])}; + } + + paint(vertices, indices, color); +} diff --git a/src/graphics/opengl/OpenGlMeshPainter.h b/src/graphics/opengl/OpenGlMeshPainter.h new file mode 100644 index 0000000..c59f14c --- /dev/null +++ b/src/graphics/opengl/OpenGlMeshPainter.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +class DrawingContext; +class OpenGlShaderProgram; +class TriMesh; + +class OpenGlMeshPainter +{ +public: + OpenGlMeshPainter(); + + void paint(TriMesh* mesh, DrawingContext* context); + +private: + void initializeShader(); + void initializeBuffers(); + + void paint(const std::vector& verts, const std::vector& elements, const std::vector& color); + + unsigned mVertexBuffer{0}; + unsigned mElementBuffer{0}; + unsigned mVertexArray{0}; + std::unique_ptr mShaderProgram; +}; diff --git a/src/graphics/opengl/OpenGlPainter.cpp b/src/graphics/opengl/OpenGlPainter.cpp index bc13bb1..838bce2 100644 --- a/src/graphics/opengl/OpenGlPainter.cpp +++ b/src/graphics/opengl/OpenGlPainter.cpp @@ -3,15 +3,18 @@ #include "DrawingContext.h" #include "DrawingSurface.h" #include "Scene.h" + #include "TriMesh.h" #include "FontsManager.h" #include "FontGlyph.h" - -#include "OpenGlFontTexture.h" -#include "OpenGlShaderProgram.h" #include "TextData.h" +#include "OpenGlShaderProgram.h" +#include "OpenGlMeshPainter.h" +#include "OpenGlTextPainter.h" +#include "OpenGlFontTexture.h" + #include "File.h" #ifdef _WIN32 @@ -30,218 +33,12 @@ #include OpenGlPainter::OpenGlPainter() + : mMeshPainter(std::make_unique()), + mTextPainter(std::make_unique()) { } -void OpenGlPainter::initializeMeshShader() -{ - if (auto context = glXGetCurrentContext()) - { - std::cout << "has valid context" << std::endl; - } - else - { - std::cout << "no valid context" << std::endl; - } - - int major_version{0}; - int minor_version{0}; - glGetIntegerv(GL_MAJOR_VERSION, &major_version); - glGetIntegerv(GL_MINOR_VERSION, &minor_version); - std::cout << "Using opengl version " << major_version << "|" << minor_version << std::endl; - - auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.vert"; - auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/default.frag"; - - mMeshShaderProgram = std::make_unique(vert_shader_path, frag_shader_path); -} - -void OpenGlPainter::initializeTextShader() -{ - auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.vert"; - auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.frag"; - - mTextShaderProgram = std::make_unique(vert_shader_path, frag_shader_path); -} - -void OpenGlPainter::renderTextLayer(const TextData& textData, DrawingContext* context) -{ - if (!mTextShaderProgram) - { - initializeTextShader(); - } - - for (auto c : textData.mContent) - { - if (auto iter = mFontTextures.find(c); iter == mFontTextures.end()) - { - auto glyph = context->getFontsManager()->getGlyph(textData.mFont.getFaceName(), textData.mFont.getSize(), c); - auto new_texture = std::make_unique(glyph); - mFontTextures[c] = std::move(new_texture); - } - } - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - const auto width = float(context->getSurface()->getWidth()); - const auto height = float(context->getSurface()->getHeight()); - - glm::mat4 projection = glm::ortho(0.0f, width, 0.0f, height); - - unsigned int VAO, VBO; - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - - glUseProgram(mTextShaderProgram->getHandle()); - glUniform3f(glGetUniformLocation(mTextShaderProgram->getHandle(), "textColor"), 0.0, 0.0, 0.0); - glUniformMatrix4fv(glGetUniformLocation(mTextShaderProgram->getHandle(), "projection"), 1, GL_FALSE, glm::value_ptr(projection)); - glActiveTexture(GL_TEXTURE0); - glBindVertexArray(VAO); - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - // iterate through all characters - float x = textData.mLocation.GetX(); - const float y = textData.mLocation.GetY(); - - for (auto c : textData.mContent) - { - auto texture = mFontTextures[c].get(); - - float xpos = x + texture->getGlyph()->getBearingX(); - float ypos = y - (texture->getGlyph()->getHeight() - texture->getGlyph()->getBearingY()); - - float w = texture->getGlyph()->getWidth(); - float h = texture->getGlyph()->getHeight(); - // update VBO for each character - float vertices[6][4] = { - { xpos, ypos + h, 0.0f, 0.0f }, - { xpos, ypos, 0.0f, 1.0f }, - { xpos + w, ypos, 1.0f, 1.0f }, - - { xpos, ypos + h, 0.0f, 0.0f }, - { xpos + w, ypos, 1.0f, 1.0f }, - { xpos + w, ypos + h, 1.0f, 0.0f } - }; - - // render glyph texture over quad - glBindTexture(GL_TEXTURE_2D, texture->getHandle()); - // update content of VBO memory - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); - glBindBuffer(GL_ARRAY_BUFFER, 0); - // render quad - glDrawArrays(GL_TRIANGLES, 0, 6); - // now advance cursors for next glyph (note that advance is number of 1/64 pixels) - x += (texture->getGlyph()->getAdvanceX() >> 6); // bitshift by 6 to get value in pixels (2^6 = 64) - } - glBindVertexArray(0); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void OpenGlPainter::renderMeshLayer(TriMesh* mesh, DrawingContext* context) -{ - if (!mMeshShaderProgram) - { - initializeMeshShader(); - } - - float vertices[] = { - 0.5f, 0.5f, 0.0f, // top right - 0.5f, -0.5f, 0.0f, // bottom right - -0.5f, -0.5f, 0.0f, // bottom left - -0.5f, 0.5f, 0.0f // top left - }; - - unsigned int indices[] = { // note that we start from 0! - 0, 1, 3, // first triangle - 1, 2, 3 // second triangle - }; - unsigned int vbo{0}; - glGenBuffers(1, &vbo); - - unsigned int EBO; - glGenBuffers(1, &EBO); - - unsigned int VAO; - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - int vertexColorLocation = glGetUniformLocation(mMeshShaderProgram->getHandle(), "ourColor"); - - glUseProgram(mMeshShaderProgram->getHandle()); - glBindVertexArray(VAO); - - glUniform4f(vertexColorLocation, 0.0f, 1.0, 0.0f, 1.0f); - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - /* - std::cout << "Bounds are : " << width << " | " << height << std::endl; - - for (std::size_t idx=0; idxgetScene()->getMesh(idx); - const auto faces = mesh->getFaceVertices(); - const auto colors = mesh->getFaceVectorAttributes("Color"); - - std::size_t counter{0}; - for (const auto& face : faces) - { - const auto r = colors[counter][0]; - const auto g = colors[counter][1]; - const auto b = colors[counter][2]; - - glColor3f(r, g, b); - - glBegin(GL_TRIANGLES); - double x0 = 2.0*face[0].getX()/width - 1.0; - double y0 = 1.0 - 2.0*face[0].getY()/height; - - double x1 = 2.0*face[1].getX()/width - 1.0; - double y1 = 1.0 - 2.0*face[1].getY()/height; - - double x2 = 2.0*face[2].getX()/width - 1.0; - double y2 = 1.0 - 2.0*face[2].getY()/height; - - glVertex3f(x0, y0, 0); - glVertex3f(x1, y1, 0); - glVertex3f(x2, y2, 0); - - std::cout << "Verts0| " << x0 << " | " << y0 << " | "<< std::endl; - std::cout << "Verts1| " << x1 << " | " << y1 << " | "<< std::endl; - std::cout << "Verts2| " << x2 << " | " << y2 << " | "<< std::endl; - std::cout << "****************" << std::endl; - - glEnd(); - - counter++; - break; - } - break; - } - */ -} - void OpenGlPainter::paint(DrawingContext* context) { auto surface = context->getSurface(); @@ -249,24 +46,23 @@ void OpenGlPainter::paint(DrawingContext* context) const auto height = double(surface->getHeight()); glViewport(0, 0, width, height); - //glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glOrtho(0, width, 0, height, -1.0, 1.0); - //glScissor(0, 0, width, height); - //glMatrixMode(GL_PROJECTION); - //glLoadIdentity(); - glClearColor(0.5, 0.5, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - //glMatrixMode(GL_MODELVIEW); - //glLoadIdentity(); - const auto num_mesh = context->getScene()->getNumMeshes(); - //renderMeshLayer(nullptr, context); + for (std::size_t idx=0 ; idx< num_mesh; idx++) + { + auto mesh = context->getScene()->getMesh(idx); + mMeshPainter->paint(mesh, context); + } auto text_data = context->getScene()->getTextData(); - renderTextLayer(text_data[0], context); - + for (const auto& text_item : context->getScene()->getTextData()) + { + mTextPainter->paint(text_item, context); + break; + } glFlush(); } diff --git a/src/graphics/opengl/OpenGlPainter.h b/src/graphics/opengl/OpenGlPainter.h index d848cd7..e5a362a 100644 --- a/src/graphics/opengl/OpenGlPainter.h +++ b/src/graphics/opengl/OpenGlPainter.h @@ -6,29 +6,20 @@ #include class DrawingContext; -class OpenGlFontTexture; -class OpenGlShaderProgram; +class OpenGlMeshPainter; +class OpenGlTextPainter; -class TextData; class TriMesh; class OpenGlPainter : public AbstractPainter { public: OpenGlPainter(); - void paint(DrawingContext* context) override; private: - void initializeMeshShader(); - void initializeTextShader(); - - void renderTextLayer(const TextData& textData, DrawingContext* context); - void renderMeshLayer(TriMesh* mesh, DrawingContext* context); - - std::unique_ptr mMeshShaderProgram; - std::unique_ptr mTextShaderProgram; - std::unordered_map > mFontTextures; + std::unique_ptr mMeshPainter; + std::unique_ptr mTextPainter; }; diff --git a/src/graphics/opengl/OpenGlTextPainter.cpp b/src/graphics/opengl/OpenGlTextPainter.cpp new file mode 100644 index 0000000..ce79d69 --- /dev/null +++ b/src/graphics/opengl/OpenGlTextPainter.cpp @@ -0,0 +1,134 @@ +#include "OpenGlTextPainter.h" + +#include "DrawingContext.h" +#include "DrawingSurface.h" + +#include "FontsManager.h" +#include "FontGlyph.h" + +#include "OpenGlFontTexture.h" +#include "OpenGlShaderProgram.h" +#include "TextData.h" + +#include "File.h" + +#ifdef _WIN32 +#include +#endif + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include + +#include +#include +#include + +#include + +OpenGlTextPainter::OpenGlTextPainter() +{ + +} + +void OpenGlTextPainter::initializeShader() +{ + auto vert_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.vert"; + auto frag_shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders/text.frag"; + + mShaderProgram = std::make_unique(vert_shader_path, frag_shader_path); +} + +void OpenGlTextPainter::initializeTextures(const TextData& textData, DrawingContext* context) +{ + for (auto c : textData.mContent) + { + if (auto iter = mFontTextures.find(c); iter == mFontTextures.end()) + { + auto glyph = context->getFontsManager()->getGlyph(textData.mFont.getFaceName(), textData.mFont.getSize(), c); + auto new_texture = std::make_unique(glyph); + mFontTextures[c] = std::move(new_texture); + } + } +} + +void OpenGlTextPainter::initializeBuffers() +{ + glGenVertexArrays(1, &mVertexArray); + glGenBuffers(1, &mVertexBuffer); + + glBindVertexArray(mVertexArray); + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, nullptr, GL_DYNAMIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void OpenGlTextPainter::paint(const TextData& textData, DrawingContext* context) +{ + if (!mShaderProgram) + { + initializeShader(); + } + + if (mVertexArray == 0) + { + initializeBuffers(); + } + + initializeTextures(textData, context); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUseProgram(mShaderProgram->getHandle()); + glUniform3f(glGetUniformLocation(mShaderProgram->getHandle(), "textColor"), 0.0, 0.0, 0.0); + + const auto width = float(context->getSurface()->getWidth()); + const auto height = float(context->getSurface()->getHeight()); + glm::mat4 projection = glm::ortho(0.0f, width, 0.0f, height); + + glUniformMatrix4fv(glGetUniformLocation(mShaderProgram->getHandle(), "projection"), 1, GL_FALSE, glm::value_ptr(projection)); + glActiveTexture(GL_TEXTURE0); + glBindVertexArray(mVertexArray); + + float x = textData.mLocation.GetX(); + const float y = height - textData.mLocation.GetY(); + for (auto c : textData.mContent) + { + auto texture = mFontTextures[c].get(); + + float xpos = x + texture->getGlyph()->getBearingX(); + float ypos = y - (texture->getGlyph()->getHeight() - texture->getGlyph()->getBearingY()); + + float w = texture->getGlyph()->getWidth(); + float h = texture->getGlyph()->getHeight(); + float vertices[6][4] = { + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos, ypos, 0.0f, 1.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + { xpos + w, ypos + h, 1.0f, 0.0f } + }; + + glBindTexture(GL_TEXTURE_2D, texture->getHandle()); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + x += (texture->getGlyph()->getAdvanceX() >> 6); // bitshift by 6 to get value in pixels (2^6 = 64) + } + + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/src/graphics/opengl/OpenGlTextPainter.h b/src/graphics/opengl/OpenGlTextPainter.h new file mode 100644 index 0000000..8c425ba --- /dev/null +++ b/src/graphics/opengl/OpenGlTextPainter.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +class DrawingContext; +class OpenGlFontTexture; +class OpenGlShaderProgram; + +class TextData; + +class OpenGlTextPainter +{ +public: + OpenGlTextPainter(); + + void paint(const TextData& textData, DrawingContext* context); + +private: + void initializeShader(); + void initializeTextures(const TextData& textData, DrawingContext* context); + + void initializeBuffers(); + + unsigned mVertexBuffer{0}; + unsigned mVertexArray{0}; + std::unique_ptr mShaderProgram; + std::unordered_map > mFontTextures; +}; diff --git a/src/graphics/opengl/shaders/default.vert b/src/graphics/opengl/shaders/default.vert index 6ba1af4..b4b9ecb 100644 --- a/src/graphics/opengl/shaders/default.vert +++ b/src/graphics/opengl/shaders/default.vert @@ -1,10 +1,7 @@ #version 330 core -layout (location = 0) in vec3 aPos; // the position variable has attribute position 0 +layout (location = 0) in vec3 aPos; -out vec4 vertexColor; // specify a color output to the fragment shader - void main() { - gl_Position = vec4(aPos, 1.0); // see how we directly give a vec3 to vec4's constructor - vertexColor = vec4(aPos.x, aPos.y, 0.0, 1.0); // set the output variable to a dark-red color + gl_Position = vec4(aPos, 1.0); } diff --git a/src/mesh/TriMesh.cpp b/src/mesh/TriMesh.cpp index 22264d6..c5ce6f0 100644 --- a/src/mesh/TriMesh.cpp +++ b/src/mesh/TriMesh.cpp @@ -16,16 +16,20 @@ void TriMesh::populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces) mFaces = std::move(faces); } -std::vector > TriMesh::getFaceVertices() const +std::vector TriMesh::getFaceNodeIds() const { - std::vector > verts(mFaces.size()); + unsigned nodes_per_face = 3; + std::vector ids(nodes_per_face*mFaces.size()); for(std::size_t idx=0; idxgetNodeIds(); - verts[idx] = {mNodes[nodeIds[0]]->getPoint(), mNodes[nodeIds[1]]->getPoint(), mNodes[nodeIds[2]]->getPoint()}; + for(std::size_t jdx=0; jdx > TriMesh::getFaceVectorAttributes(const std::string& tag) @@ -45,3 +49,34 @@ void TriMesh::addConstantFaceVectorAttribute(const std::string& tag, const std:: face->addVectorAttribute(tag, values); } } + +void TriMesh::addConstantNodeVectorAttribute(const std::string& tag, const std::vector& values) +{ + +} + +std::vector > TriMesh::getNodeVectorAttributes(const std::string& tag) +{ + std::vector > attribs(mNodes.size()); + return attribs; +} + +void TriMesh::addVectorAttribute(const std::string& tag, const std::vector& values) +{ + mVectorAttributes[tag] = values; +} + +bool TriMesh::hasVectorAttribute(const std::string& tag) const +{ + return mVectorAttributes.find(tag) != mVectorAttributes.end(); +} + +std::vector TriMesh::getVectorAttribute(const std::string& tag) const +{ + auto iter = mVectorAttributes.find(tag); + if (iter != mVectorAttributes.end()) + { + return iter->second; + } + return {}; +} diff --git a/src/mesh/TriMesh.h b/src/mesh/TriMesh.h index 1bc1d02..c310e20 100644 --- a/src/mesh/TriMesh.h +++ b/src/mesh/TriMesh.h @@ -2,11 +2,13 @@ #include "AbstractMesh.h" #include "Point.h" +#include "Node.h" #include #include +#include +#include -class Node; class Edge; class TriFace; @@ -27,13 +29,38 @@ public: void populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces); - std::vector > getFaceVertices() const; + template + std::vector getVerticesFlat(T scaleX = 1.0, T scaleY = 1.0, T scaleZ = 1.0) const + { + std::vector ret(3*mNodes.size()); + for(std::size_t idx = 0; idxgetPoint().getX()/scaleX; + ret[3*idx + 1] = node->getPoint().getY()/scaleY; + ret[3*idx + 2] = node->getPoint().getZ()/scaleZ; + } + return ret; + } + + std::vector getFaceNodeIds() const; void addConstantFaceVectorAttribute(const std::string& tag, const std::vector& values); + void addConstantNodeVectorAttribute(const std::string& tag, const std::vector& values); + std::vector > getFaceVectorAttributes(const std::string& tag); + std::vector > getNodeVectorAttributes(const std::string& tag); + + void addVectorAttribute(const std::string& tag, const std::vector& values); + + bool hasVectorAttribute(const std::string& tag) const; + + std::vector getVectorAttribute(const std::string& tag) const; + private: + std::unordered_map > mVectorAttributes; VecNodes mNodes; VecEdges mEdges; VecFaces mFaces; diff --git a/src/visual_elements/RectangleNode.cpp b/src/visual_elements/RectangleNode.cpp index a9415c7..d682bb6 100644 --- a/src/visual_elements/RectangleNode.cpp +++ b/src/visual_elements/RectangleNode.cpp @@ -45,6 +45,6 @@ void RectangleNode::updateMesh() auto mesh = MeshPrimitives::build(rect); auto color = getFillColor(); - mesh->addConstantFaceVectorAttribute("Color", color.getAsVectorDouble()); + mesh->addVectorAttribute("Color", color.getAsVectorDouble()); mMesh = std::move(mesh); } diff --git a/src/windows/ui_interfaces/x11/XcbGlInterface.cpp b/src/windows/ui_interfaces/x11/XcbGlInterface.cpp index 6c9813e..0c034fd 100644 --- a/src/windows/ui_interfaces/x11/XcbGlInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbGlInterface.cpp @@ -60,7 +60,6 @@ void XcbGlInterface::setupContext(int default_screen) glXGetFBConfigAttrib(mDisplay, mConfig, GLX_VISUAL_ID, &visualID); /* Create OpenGL context */ - std::cout << "Creating opengl context" << std::endl; mContext = glXCreateNewContext(mDisplay, mConfig, GLX_RGBA_TYPE, 0, True); if (!mContext) { diff --git a/src/windows/ui_interfaces/x11/XcbGlWindowInterface.cpp b/src/windows/ui_interfaces/x11/XcbGlWindowInterface.cpp index 5f5dd0b..f2d3cad 100644 --- a/src/windows/ui_interfaces/x11/XcbGlWindowInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbGlWindowInterface.cpp @@ -55,6 +55,21 @@ bool XcbGlWindowInterface::initialize(xcb_window_t window) return false; } + if (auto context = glXGetCurrentContext()) + { + MLOG_INFO("Has valid GL context"); + } + else + { + MLOG_INFO("No valid GL context"); + } + + int major_version{0}; + int minor_version{0}; + glGetIntegerv(GL_MAJOR_VERSION, &major_version); + glGetIntegerv(GL_MINOR_VERSION, &minor_version); + MLOG_INFO("Using opengl version " << major_version << "|" << minor_version); + return true; }