/
ArtemNech
/
simpleOpenGL
Обзор
Документация
Войти
/
ArtemNech
/
simpleOpenGL
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
backend/ogl_sys/drawing-sets/CLayerObjects.cpp
332 строки
10 KB
Artem Nechitaylenko
All objects are works and draggable
20 май 2026, 09:40
20 май 2026, 09:40
bf16523
Код
Авторство
О чём код?
// // Created by artem on 12.04.26. // #include <glm/ext/matrix_clip_space.hpp> #include <qdebug.h> #include "shaderprogram.h" #include "../CGlTransformator.h" #include "CLayerObjects.h" #include "../../CBacking.h" #include "COglImageManager.h" #include "COglTextManager.h" #include "../../diagram/CDiagram.h" #include "../../diagram/objects/CCircle.h" #include "../../diagram/objects/CTriangle.h" #include "../../diagram/objects/CText.h" CLayerObjects::CLayerObjects(COglImageManager * imgManager, COglTextManager *txtManager, float Z) : COglLayer(Z) { m_rectLineShaderProg = new ShaderProgram(); m_textureShaderProg = new ShaderProgram(); m_textShaderProgram = new ShaderProgram(); m_shaders[E_RECT] = m_rectLineShaderProg; m_shaders[E_TEXTURE]= m_textureShaderProg; m_shaders[E_ATLAS] = m_textShaderProgram; m_shaders_programs[E_RECT] = {"", ""}; m_shaders_programs[E_TEXTURE] = {"", ""}; m_shaders_programs[E_ATLAS] = {"", ""}; m_image_manager = imgManager; m_text_manager = txtManager; } CLayerObjects::~CLayerObjects() { m_rectLineShaderProg->unbind(); delete m_rectLineShaderProg; m_textureShaderProg->unbind(); delete m_textureShaderProg; m_textShaderProgram->unbind(); delete m_textShaderProgram; } bool CLayerObjects::init() { init_shaders(); bool res = compile_shaders(); if (!res) { return false; } m_vao->bind(); m_vbo->bind(); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)nullptr); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)(7 * sizeof(float))); m_vao->unbind(); m_vbo->unbind(); return true; } void CLayerObjects::init_shaders() { //------------------------------------------------------------------------------------------------------------------ // линии с прямоугольниками без градиентов //------------------------------------------------------------------------------------------------------------------ m_shaders_programs[E_RECT].first = R"( #version 330 core layout(location = 0) in vec3 in_position; layout(location = 1) in vec4 in_color; uniform mat4 model_projection; out vec4 v_color; void main() { gl_Position = model_projection * vec4(in_position, 1.0); v_color = in_color; } )"; m_shaders_programs[E_RECT].second = R"( #version 330 core in vec4 v_color; out vec4 out_color; void main() { out_color = v_color; if (out_color.a < 0.01) { discard; } } )"; //------------------------------------------------------------------------------------------------------------------ // картинки //------------------------------------------------------------------------------------------------------------------ m_shaders_programs[E_TEXTURE].first = R"( #version 330 core layout(location = 0) in vec3 in_position; layout(location = 1) in vec4 in_color; layout(location = 2) in vec2 tex_coord; uniform mat4 model_projection; out vec4 v_color; out vec2 v_texCoord; void main() { v_color = in_color; v_texCoord = tex_coord; gl_Position = model_projection * vec4(in_position, 1.0); } )"; m_shaders_programs[E_TEXTURE].second = R"( #version 330 core in vec4 v_color; in vec2 v_texCoord; uniform sampler2D textureSampler; out vec4 out_color; void main() { vec4 texColor = texture(textureSampler, v_texCoord); out_color = texColor; if (out_color.a < 0.01) discard; } )"; //------------------------------------------------------------------------------------------------------------------ // Текст //------------------------------------------------------------------------------------------------------------------ m_shaders_programs[E_ATLAS].first = R"( #version 330 core layout(location = 0) in vec3 in_position; layout(location = 1) in vec4 in_color; layout(location = 2) in vec2 tex_coord; uniform mat4 model_projection; out vec4 v_color; out vec2 v_texCoord; void main() { v_color = in_color; v_texCoord = tex_coord; gl_Position = model_projection * vec4(in_position, 1.0); } )"; m_shaders_programs[E_ATLAS].second = R"( #version 330 core in vec4 v_color; in vec2 v_texCoord; uniform sampler2D textureSampler; uniform vec2 u_TextureSize; uniform float u_Smoothing; out vec4 out_color; float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } void main() { vec3 msd = texture(textureSampler, v_texCoord).rgb; float sd = median(msd.r, msd.g, msd.b); vec2 unitRange = vec2(u_Smoothing) / u_TextureSize; vec2 screenTexSize = vec2(1.0) / fwidth(v_texCoord); float screenPxRange = max(0.5 * dot(unitRange, screenTexSize), 1.0); float thickness = -0.02; float alpha = clamp(screenPxRange * (sd - 0.5 - thickness) + 0.5, 0.0, 1.0); out_color = vec4(v_color.rgb, v_color.a * alpha); if (out_color.a < 0.01) discard; } )"; } bool CLayerObjects::compile_shaders() { for (auto & pair: m_shaders) { EShader type = pair.first; ShaderProgram *shader = pair.second; if (!shader->compile(m_shaders_programs[type].first, m_shaders_programs[type].second)) { qDebug() << "Fragment shader compilation in 'CObjectsLayer' failed: ", shader->errors(); return false; } } return true; } void CLayerObjects::render(CBacking *backing, const glm::mat4 & projection, const glm::mat4 & view) { m_batches.clear(); m_vertices.clear(); m_backing = backing; elem::CCircle *circle; elem::CTriangle * triangle; elem::CText * text; ngraph::NColor debugColor = {191,134,84,127}; for (auto & object : backing->diagram()->objects()) { auto objType = (EDiagramObjType)object->objectType(); switch (objType) { case EDiagramObjType::DT_Circle: circle = dynamic_cast<elem::CCircle*>(object); CGlTransformator::drawCircle(this, object->position(), circle->radius(), circle->horizonRadius(), circle->fillColor(), circle->borderColor()); break; case EDiagramObjType::DT_Square: CGlTransformator::drawRect(this, object->boundingRect(), object->fillColor(), object->borderColor()); break; case EDiagramObjType::DT_Triangle: triangle = dynamic_cast<elem::CTriangle*>(object); CGlTransformator::drawTriangle(this, object->position(), triangle->baseSideLen(), triangle->lateralSideLen(), triangle->fillColor(), triangle->borderColor()); break; case EDiagramObjType::DT_Text: text = dynamic_cast<elem::CText*>(object); m_text_manager->explodeText(this, text->textElements().front()); break; default: return; } /* /// эмблема объекта for (auto & img : object->imageElements()) { m_image_manager->explode_image(this, img); } /// имя объекта if (!m_text_manager->is_error()) { for (auto &item : object->textElements()) { m_text_manager->explodeText(this, item); } }*/ } if (m_batches.empty()) { return; } glm::mat4 model_matrix = projection * view; if (!m_batches.empty()) { m_shaders[E_RECT]->bind(); m_shaders[E_RECT]->setUniform("model_projection", model_matrix); m_vao->bind(); m_vbo->bind(); m_vbo->data(m_vertices.data(), m_vertices.size() * sizeof(vertex_t), BufferUsage::Dynamic); ShaderProgram * shader; for (auto &batch : m_batches) { EShader type = batch.useTexture ? E_TEXTURE : E_RECT; if (batch.useSDF) { type = E_ATLAS; } shader = m_shaders[type]; shader->bind(); shader->setUniform("model_projection", model_matrix); if (batch.useTexture) { shader->setUniform("model_projection", model_matrix); shader->setUniform("textureSampler", 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, batch.textureId); } if (batch.useSDF) { m_text_manager->setSDFUniforms(batch, shader->get()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, batch.textureId); } glDrawArrays(batch.primitive, batch.vertexOffset, batch.vertexCount); } } }