]> git.sur5r.net Git - fstl/blob - src/axis.cpp
New upstream version 0.10.0
[fstl] / src / axis.cpp
1 #include "axis.h"
2
3 const float xLet[] = {
4     -0.1, -0.2, 0,
5     0.1, 0.2, 0,
6     0.1, -0.2, 0,
7     -0.1, 0.2, 0
8 };
9 const float yLet[] = {
10     0, -0.2, 0,
11     0, 0, 0,
12     0, 0, 0,
13     0.1, 0.2, 0,
14     0, 0, 0,
15     -0.1, 0.2, 0
16 };
17 const float zLet[] = {
18     -0.1, -0.2, 0,
19     0.1, -0.2, 0,
20     0.1, -0.2, 0,
21     -0.1, 0.2, 0,
22     -0.1, 0.2, 0,
23     0.1, 0.2, 0
24 };
25 const int axisSegCount[] = {2, 3, 3};
26 const float* axisLabels[] = {xLet, yLet, zLet};
27
28 Axis::Axis()
29 {
30     initializeOpenGLFunctions();
31
32     shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl/colored_lines.vert");
33     shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/colored_lines.frag");
34     shader.link();
35     const int ptSize = 6*sizeof(float);
36     for(int lIdx = 0; lIdx < 3; lIdx++)
37     {
38         const float* l = axisLabels[lIdx];
39         const int ptCount = axisSegCount[lIdx]*2;
40         float c[3] = {0.0};
41         c[lIdx] = 1.0;//set color
42         QOpenGLBuffer b = flowerLabelVertices[lIdx];
43         b.create();
44         b.bind();
45         b.allocate(ptCount*ptSize);
46         for(int pIdx = 0; pIdx < ptCount; pIdx++)
47         {
48             b.write(pIdx*ptSize, &(l[pIdx*3]), ptSize/2);//write coords
49             b.write(pIdx*ptSize + ptSize/2, c, ptSize/2);//write color
50         }
51         b.release();
52     }
53     //Axis buffer: 6 floats per vertex, 2 vert per line, 3 lines
54     float aBuf[6*2*3] = {0.0};
55     for(int aIdx = 0; aIdx < 3; aIdx++)
56     {
57         aBuf[(2*aIdx)*6+3+aIdx] = 1.0;//Set color (last 3 floats)
58         aBuf[(2*aIdx+1)*6+3+aIdx] = 1.0;//Set color (last 3 floats)
59         aBuf[(2*aIdx+1)*6+aIdx] = 1.0;//Extend line in axis
60     }
61     //The lines which form the 'axis-flower' in the corner
62     flowerAxisVertices.create();
63     flowerAxisVertices.bind();
64     flowerAxisVertices.allocate(aBuf, sizeof(aBuf));
65     flowerAxisVertices.release();
66     //The lines which form the model-space axes
67     vertices.create();
68     vertices.bind();
69     vertices.allocate(aBuf, sizeof(aBuf));
70     vertices.release();
71 }
72 void Axis::setScale(QVector3D min, QVector3D max)
73 {
74     //Max function. not worth importing <algorithm> just for max
75     auto Max = [](float a, float b)
76     {
77         return (a > b) ? a : b;
78     };
79     //This is how much the axes extend beyond the model
80     //We want it to be dependent on the model's size, but uniform on all axes.
81     const float axismargin = 0.25*Max(Max(max[0]-min[0], max[1]-min[1]), max[2]-min[2]);
82     vertices.bind();
83     //Manually rewrite coordinates to control axis draw lengths
84     float s = sizeof(float);
85     //aIdx*12+aIdx gets us to the set of 2 points of the axis line, plus the offset for that dimension
86     //+6 gets us to the other end of the line in that dimension
87     for(int aIdx = 0; aIdx < 3; aIdx++)
88     {
89         float t = min[aIdx]-axismargin;
90         vertices.write(s*(aIdx*12+aIdx), &t, s);
91         t = max[aIdx]+axismargin;
92         vertices.write(s*(aIdx*12+aIdx+6), &t, s);
93     }
94     vertices.release();
95 }
96 void Axis::draw(QMatrix4x4 transMat, QMatrix4x4 viewMat,
97     QMatrix4x4 orientMat, QMatrix4x4 aspectMat, float aspectRatio)
98 {
99     shader.bind();
100     vertices.bind();
101     // Load the transform and view matrices into the shader
102     auto loadMatrixUniforms = [&](QMatrix4x4 transform, QMatrix4x4 view)
103     {
104         glUniformMatrix4fv(
105                     shader.uniformLocation("transform_matrix"),
106                     1, GL_FALSE, transform.data());
107         glUniformMatrix4fv(
108                     shader.uniformLocation("view_matrix"),
109                     1, GL_FALSE, view.data());
110     };
111     const GLuint vp = shader.attributeLocation("vertex_position");
112     const GLuint vc = shader.attributeLocation("vertex_color");
113     glEnableVertexAttribArray(vp);
114     glEnableVertexAttribArray(vc);
115     auto loadAttribPtr = [&]()
116     {
117         glVertexAttribPointer(vp, 3, GL_FLOAT, false,
118                         6 * sizeof(GLfloat), 0);
119         glVertexAttribPointer(vc, 3, GL_FLOAT, false,
120                         6 * sizeof(GLfloat),
121                         (GLvoid*)(3 * sizeof(GLfloat)));
122     };
123     loadMatrixUniforms(transMat, viewMat);
124     loadAttribPtr();
125
126     glDrawArrays(GL_LINES, 0, 3*6);
127
128     vertices.release();
129     //Next, we draw the hud axis-flower
130     flowerAxisVertices.bind();
131     glClear(GL_DEPTH_BUFFER_BIT);//Ensure hud draws over everything
132     const float hudSize = 0.2;
133     QMatrix4x4 hudMat;
134     //Move the hud to the bottom left corner with margin
135     if (aspectRatio > 1.0)
136     {
137         hudMat.translate(aspectRatio-2*hudSize, -1.0+2*hudSize, 0);
138     }
139     else
140     {
141         hudMat.translate(1.0-2*hudSize, -1.0/aspectRatio+2*hudSize, 0);
142     }
143     //Scale the hud to be small
144     hudMat.scale(hudSize, hudSize, 1);
145     loadMatrixUniforms(orientMat, aspectMat*hudMat);
146     loadAttribPtr();
147     glDrawArrays(GL_LINES, 0, 3*6);
148     flowerAxisVertices.release();
149     for(int aIdx = 0; aIdx < 3; aIdx++){
150         QVector3D transVec = QVector3D();
151         transVec[aIdx] = 1.25;//This is how far we want the letters to be extended out
152         QOpenGLBuffer b = flowerLabelVertices[aIdx];
153         //The only transform we want is to translate the letters to the ends of the axis lines
154         QMatrix4x4 labelTransMat = QMatrix4x4();
155         labelTransMat.translate(orientMat * transVec);
156         b.bind();
157         loadMatrixUniforms(labelTransMat, aspectMat * hudMat);
158         loadAttribPtr();
159         glDrawArrays(GL_LINES, 0, axisSegCount[aIdx]*2*6);
160         b.release();
161     }
162     shader.release();
163 }