]> git.sur5r.net Git - fstl/blobdiff - src/axis.cpp
New upstream version 0.10.0
[fstl] / src / axis.cpp
diff --git a/src/axis.cpp b/src/axis.cpp
new file mode 100644 (file)
index 0000000..831f592
--- /dev/null
@@ -0,0 +1,163 @@
+#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();
+}