65 AxesVertex{{0, 10000, 0}, {0, 1, 0}}, |
65 AxesVertex{{0, 10000, 0}, {0, 1, 0}}, |
66 AxesVertex{{0, 0, -10000}, {0, 0, 1}}, |
66 AxesVertex{{0, 0, -10000}, {0, 0, 1}}, |
67 AxesVertex{{0, 0, 10000}, {0, 0, 1}}, |
67 AxesVertex{{0, 0, 10000}, {0, 0, 1}}, |
68 }; |
68 }; |
69 |
69 |
70 AxesProgram::AxesProgram(QObject* parent) : |
70 const char* AxesProgram::vertexShaderSource() const |
71 QObject{parent}, |
|
72 buffer{QOpenGLBuffer::VertexBuffer}, |
|
73 vertexShader{QOpenGLShader::Vertex}, |
|
74 fragmentShader{QOpenGLShader::Fragment} |
|
75 { |
71 { |
|
72 return ::vertexShaderSource; |
76 } |
73 } |
77 |
74 |
78 void AxesProgram::initialize() |
75 const char* AxesProgram::fragmentShaderSource() const |
79 { |
76 { |
80 if (not isInitialized) |
77 return ::fragmentShaderSource; |
81 { |
|
82 this->initializeOpenGLFunctions(); |
|
83 this->isInitialized = true; |
|
84 this->program.emplace(this); |
|
85 gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource); |
|
86 this->program->bind(); |
|
87 this->buffer.create(); |
|
88 this->buffer.bind(); |
|
89 this->buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
|
90 this->buffer.allocate(data, countof(data) * sizeof data[0]); |
|
91 this->vertexArrayObject.create(); |
|
92 this->vertexArrayObject.bind(); |
|
93 this->program->enableAttributeArray(0); |
|
94 this->program->setAttributeBuffer(0, GL_FLOAT, 0, 2, 0); |
|
95 this->program->setUniformVector("gridColor", this->gridColor); |
|
96 this->vertexArrayObject.release(); |
|
97 this->buffer.release(); |
|
98 this->program->release(); |
|
99 this->checkForGLErrors(); |
|
100 } |
|
101 } |
78 } |
102 |
79 |
103 void AxesProgram::setViewMatrix(const glm::mat4& newViewMatrix) |
80 const void* AxesProgram::vertexData() const |
104 { |
81 { |
105 this->setMatrix("view", newViewMatrix); |
82 return ::data; |
106 } |
83 } |
107 |
84 |
108 void AxesProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix) |
85 GLenum AxesProgram::drawMode() const |
109 { |
86 { |
110 this->setMatrix("projection", newProjectionMatrix); |
87 return GL_LINES; |
111 } |
88 } |
112 |
89 |
113 void AxesProgram::setModelMatrix(const glm::mat4& newModelMatrix) |
90 int AxesProgram::vertexSize() const |
114 { |
91 { |
115 this->setMatrix("model", newModelMatrix); |
92 return sizeof data[0]; |
116 } |
93 } |
117 |
94 |
118 void AxesProgram::setGridMatrix(const glm::mat4& newGridMatrix) |
95 int AxesProgram::vertexCount() const |
119 { |
96 { |
120 this->setMatrix("grid", newGridMatrix); |
97 return countof(data); |
121 } |
98 } |
122 |
99 |
123 void AxesProgram::setMatrix(const char* name, const glm::mat4& matrix) |
100 void AxesProgram::setupVertexArrays() |
124 { |
101 { |
125 Q_ASSERT(this->isInitialized); |
102 for (int i : {0, 1}) |
126 this->program->bind(); |
103 { |
127 this->program->setUniformMatrix(name, matrix); |
104 this->program->enableAttributeArray(i); |
128 this->program->release(); |
105 } |
129 this->checkForGLErrors(); |
106 const int stride = this->vertexSize(); |
|
107 this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(AxesVertex, position), 3, stride); |
|
108 this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(AxesVertex, color), 3, stride); |
130 } |
109 } |
131 |
|
132 void GridProgram::setGridColor(const QColor& newGridColor) |
|
133 { |
|
134 const glm::vec4 vec = gl::colorToVector4(newGridColor); |
|
135 if (this->isInitialized) |
|
136 { |
|
137 this->program->bind(); |
|
138 this->program->setUniformVector("gridColor", vec); |
|
139 this->program->release(); |
|
140 this->checkForGLErrors(); |
|
141 } |
|
142 else |
|
143 { |
|
144 this->gridColor = vec; |
|
145 } |
|
146 } |
|
147 |
|
148 void GridProgram::draw() |
|
149 { |
|
150 this->program->bind(); |
|
151 this->vertexArrayObject.bind(); |
|
152 glDrawArrays(GL_QUADS, 0, countof(data)); |
|
153 this->vertexArrayObject.release(); |
|
154 this->program->release(); |
|
155 this->checkForGLErrors(); |
|
156 } |
|
157 |
|
158 void GridProgram::teardown() |
|
159 { |
|
160 this->vertexArrayObject.destroy(); |
|
161 this->buffer.destroy(); |
|
162 this->program.reset(); |
|
163 } |
|
164 |
|
165 void GridProgram::checkForGLErrors() |
|
166 { |
|
167 gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); |
|
168 } |
|