#include "OpenGlPainter.h" #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 "File.h" #ifdef _WIN32 #include #endif #define GL_GLEXT_PROTOTYPES #include #include #include #include #include #include #include OpenGlPainter::OpenGlPainter() { } 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(); } auto first_char = textData.mContent[0]; auto iter = mFontTextures.find(first_char); OpenGlFontTexture* working_texture{nullptr}; if (iter == mFontTextures.end()) { auto glyph = context->getFontsManager()->getGlyph(first_char); auto new_texture = std::make_unique(nullptr); working_texture = new_texture.get(); mFontTextures[first_char] = std::move(new_texture); } else { working_texture = iter->second.get(); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } 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(); const auto width = double(surface->getWidth()); const auto height = double(surface->getHeight()); glViewport(0, 0, width, height); //glOrtho(-1.0, 1.0, -1.0, 1.0, -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); auto text_data = context->getScene()->getTextData(); renderTextLayer(text_data[0], context); glFlush(); }