Wed, 17 Feb 2021 16:49:35 +0200
stuff
102 | 1 | #include "geometrypreview.h" |
2 | ||
3 | const char vertexShaderSource[] = R"( | |
4 | #version 330 core | |
5 | ||
6 | layout (location = 0) in vec3 in_position; | |
7 | layout (location = 1) in vec3 in_color; | |
8 | uniform mat4 view; | |
9 | uniform mat4 projection; | |
10 | uniform mat4 model; | |
11 | smooth out vec3 ex_color; | |
12 | ||
13 | void main() | |
14 | { | |
15 | gl_Position = projection * view * model * vec4(in_position, 1.0); | |
16 | ex_color = in_color; | |
17 | } | |
18 | )"; | |
19 | ||
20 | const char fragmentShaderSource[] = R"( | |
21 | #version 330 core | |
22 | ||
23 | out vec4 color; | |
24 | smooth in vec3 ex_color; | |
25 | ||
26 | void main(void) | |
27 | { | |
28 | color = vec4(ex_color, 1); | |
29 | } | |
30 | )"; | |
31 | ||
32 | constexpr std::size_t vertexSize = sizeof(GeometryPreview::Vertex); | |
33 | ||
34 | GeometryPreview::GeometryPreview(QObject *parent) : | |
35 | AbstractShaderProgram{{ | |
36 | {GL_LINES, vertexSize, QOpenGLBuffer::DynamicDraw}, | |
37 | {GL_TRIANGLES, vertexSize, QOpenGLBuffer::DynamicDraw} | |
38 | }, parent} | |
39 | { | |
40 | } | |
41 | ||
42 | GeometryPreview::~GeometryPreview() | |
43 | { | |
44 | } | |
45 | ||
46 | QVector<GeometryPreview::Vertex>& GeometryPreview::modifyLinesBuffer() | |
47 | { | |
48 | this->needRebuild = true; | |
49 | return this->lines; | |
50 | } | |
51 | ||
52 | QVector<GeometryPreview::Vertex>& GeometryPreview::modifyTrianglesBuffer() | |
53 | { | |
54 | this->needRebuild = true; | |
55 | return this->triangles; | |
56 | } | |
57 | ||
58 | void GeometryPreview::initialize() | |
59 | { | |
60 | if (not this->isInitialized) | |
61 | { | |
62 | this->isInitialized = true; | |
63 | this->program.emplace(this); | |
64 | gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource); | |
65 | this->program->bind(); | |
66 | for (QOpenGLBuffer* buffer : {&this->linesBuffer, &this->trianglesBuffer}) | |
67 | { | |
68 | buffer->create(); | |
69 | buffer->bind(); | |
70 | buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw); | |
71 | } | |
72 | this->vertexArrayObject.create(); | |
73 | this->vertexArrayObject.bind(); | |
74 | this->setupVertexArrays(); | |
75 | this->vertexArrayObject.release(); | |
76 | for (auto& buffer : {this->linesBuffer, this->trianglesBuffer}) | |
77 | { | |
78 | buffer->release(); | |
79 | } | |
80 | this->program->release(); | |
81 | this->checkForGLErrors(); | |
82 | } | |
83 | } | |
84 | ||
85 | void GeometryPreview::rebuildIfNecessary() | |
86 | { | |
87 | if (this->needRebuild) | |
88 | { | |
89 | this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); | |
90 | this->needRebuild = false; | |
91 | } | |
92 | } | |
93 | ||
94 | void GeometryPreview::checkForGLErrors() | |
95 | { | |
96 | gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); | |
97 | } | |
98 | ||
99 | void GeometryPreview::setupVertexArrays() | |
100 | { | |
101 | for (int i : {0, 1}) | |
102 | { | |
103 | this->program->enableAttributeArray(i); | |
104 | } | |
105 | const int stride = this->vertexSize(); | |
106 | this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); | |
107 | this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride); | |
108 | } |