--- /dev/null
+#include "axis.h"
+
+const float xLet[] = {
+ -0.1, -0.2, 0,
+ 0.1, 0.2, 0,
+ 0.1, -0.2, 0,
+ -0.1, 0.2, 0
+};
+const float yLet[] = {
+ 0, -0.2, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0.1, 0.2, 0,
+ 0, 0, 0,
+ -0.1, 0.2, 0
+};
+const float zLet[] = {
+ -0.1, -0.2, 0,
+ 0.1, -0.2, 0,
+ 0.1, -0.2, 0,
+ -0.1, 0.2, 0,
+ -0.1, 0.2, 0,
+ 0.1, 0.2, 0
+};
+const int axisSegCount[] = {2, 3, 3};
+const float* axisLabels[] = {xLet, yLet, zLet};
+
+Axis::Axis()
+{
+ initializeOpenGLFunctions();
+
+ shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl/colored_lines.vert");
+ shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/colored_lines.frag");
+ shader.link();
+ const int ptSize = 6*sizeof(float);
+ for(int lIdx = 0; lIdx < 3; lIdx++)
+ {
+ const float* l = axisLabels[lIdx];
+ const int ptCount = axisSegCount[lIdx]*2;
+ float c[3] = {0.0};
+ c[lIdx] = 1.0;//set color
+ QOpenGLBuffer b = flowerLabelVertices[lIdx];
+ b.create();
+ b.bind();
+ b.allocate(ptCount*ptSize);
+ for(int pIdx = 0; pIdx < ptCount; pIdx++)
+ {
+ b.write(pIdx*ptSize, &(l[pIdx*3]), ptSize/2);//write coords
+ b.write(pIdx*ptSize + ptSize/2, c, ptSize/2);//write color
+ }
+ b.release();
+ }
+ //Axis buffer: 6 floats per vertex, 2 vert per line, 3 lines
+ float aBuf[6*2*3] = {0.0};
+ for(int aIdx = 0; aIdx < 3; aIdx++)
+ {
+ aBuf[(2*aIdx)*6+3+aIdx] = 1.0;//Set color (last 3 floats)
+ aBuf[(2*aIdx+1)*6+3+aIdx] = 1.0;//Set color (last 3 floats)
+ aBuf[(2*aIdx+1)*6+aIdx] = 1.0;//Extend line in axis
+ }
+ //The lines which form the 'axis-flower' in the corner
+ flowerAxisVertices.create();
+ flowerAxisVertices.bind();
+ flowerAxisVertices.allocate(aBuf, sizeof(aBuf));
+ flowerAxisVertices.release();
+ //The lines which form the model-space axes
+ vertices.create();
+ vertices.bind();
+ vertices.allocate(aBuf, sizeof(aBuf));
+ vertices.release();
+}
+void Axis::setScale(QVector3D min, QVector3D max)
+{
+ //Max function. not worth importing <algorithm> just for max
+ auto Max = [](float a, float b)
+ {
+ return (a > b) ? a : b;
+ };
+ //This is how much the axes extend beyond the model
+ //We want it to be dependent on the model's size, but uniform on all axes.
+ const float axismargin = 0.25*Max(Max(max[0]-min[0], max[1]-min[1]), max[2]-min[2]);
+ vertices.bind();
+ //Manually rewrite coordinates to control axis draw lengths
+ float s = sizeof(float);
+ //aIdx*12+aIdx gets us to the set of 2 points of the axis line, plus the offset for that dimension
+ //+6 gets us to the other end of the line in that dimension
+ for(int aIdx = 0; aIdx < 3; aIdx++)
+ {
+ float t = min[aIdx]-axismargin;
+ vertices.write(s*(aIdx*12+aIdx), &t, s);
+ t = max[aIdx]+axismargin;
+ vertices.write(s*(aIdx*12+aIdx+6), &t, s);
+ }
+ vertices.release();
+}
+void Axis::draw(QMatrix4x4 transMat, QMatrix4x4 viewMat,
+ QMatrix4x4 orientMat, QMatrix4x4 aspectMat, float aspectRatio)
+{
+ shader.bind();
+ vertices.bind();
+ // Load the transform and view matrices into the shader
+ auto loadMatrixUniforms = [&](QMatrix4x4 transform, QMatrix4x4 view)
+ {
+ glUniformMatrix4fv(
+ shader.uniformLocation("transform_matrix"),
+ 1, GL_FALSE, transform.data());
+ glUniformMatrix4fv(
+ shader.uniformLocation("view_matrix"),
+ 1, GL_FALSE, view.data());
+ };
+ const GLuint vp = shader.attributeLocation("vertex_position");
+ const GLuint vc = shader.attributeLocation("vertex_color");
+ glEnableVertexAttribArray(vp);
+ glEnableVertexAttribArray(vc);
+ auto loadAttribPtr = [&]()
+ {
+ glVertexAttribPointer(vp, 3, GL_FLOAT, false,
+ 6 * sizeof(GLfloat), 0);
+ glVertexAttribPointer(vc, 3, GL_FLOAT, false,
+ 6 * sizeof(GLfloat),
+ (GLvoid*)(3 * sizeof(GLfloat)));
+ };
+ loadMatrixUniforms(transMat, viewMat);
+ loadAttribPtr();
+
+ glDrawArrays(GL_LINES, 0, 3*6);
+
+ vertices.release();
+ //Next, we draw the hud axis-flower
+ flowerAxisVertices.bind();
+ glClear(GL_DEPTH_BUFFER_BIT);//Ensure hud draws over everything
+ const float hudSize = 0.2;
+ QMatrix4x4 hudMat;
+ //Move the hud to the bottom left corner with margin
+ if (aspectRatio > 1.0)
+ {
+ hudMat.translate(aspectRatio-2*hudSize, -1.0+2*hudSize, 0);
+ }
+ else
+ {
+ hudMat.translate(1.0-2*hudSize, -1.0/aspectRatio+2*hudSize, 0);
+ }
+ //Scale the hud to be small
+ hudMat.scale(hudSize, hudSize, 1);
+ loadMatrixUniforms(orientMat, aspectMat*hudMat);
+ loadAttribPtr();
+ glDrawArrays(GL_LINES, 0, 3*6);
+ flowerAxisVertices.release();
+ for(int aIdx = 0; aIdx < 3; aIdx++){
+ QVector3D transVec = QVector3D();
+ transVec[aIdx] = 1.25;//This is how far we want the letters to be extended out
+ QOpenGLBuffer b = flowerLabelVertices[aIdx];
+ //The only transform we want is to translate the letters to the ends of the axis lines
+ QMatrix4x4 labelTransMat = QMatrix4x4();
+ labelTransMat.translate(orientMat * transVec);
+ b.bind();
+ loadMatrixUniforms(labelTransMat, aspectMat * hudMat);
+ loadAttribPtr();
+ glDrawArrays(GL_LINES, 0, axisSegCount[aIdx]*2*6);
+ b.release();
+ }
+ shader.release();
+}