xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/opengl/glwidget.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include "glwidget.h"
2 #include <QPainter>
3 #include <QPaintEngine>
4 #include <QOpenGLShaderProgram>
5 #include <QCoreApplication>
6 #include <qmath.h>
7 #include <QFile>
8 #ifndef GL_SRGB8_ALPHA8
9 #define GL_SRGB8_ALPHA8 0x8C43
10 #endif
11 
GLWidget(const QColor & background)12 GLWidget::GLWidget( const QColor &background)
13     :
14       m_frames(0),
15       m_program1(0),
16       m_transparent(false),
17       m_background(background)
18 {
19     // setTextureFormat(GL_SRGB8_ALPHA8);
20 }
21 
~GLWidget()22 GLWidget::~GLWidget()
23 {
24     // And now release all OpenGL resources.
25     makeCurrent();
26     delete m_program1;
27     delete m_vshader1;
28     delete m_fshader1;
29     m_vbo1.destroy();
30     doneCurrent();
31 }
32 
paintFLLogo()33 void GLWidget::paintFLLogo()
34 {
35     m_program1->enableAttributeArray(m_vertexAttr1);
36     m_program1->enableAttributeArray(m_normalAttr1);
37 
38     m_vbo1.bind();
39     // The data in the buffer is placed like this:
40     // vertex1.x, vertex1.y, vertex1.z, normal1.x, normal1.y, normal1.z, vertex2.x, ...
41     m_program1->setAttributeBuffer(m_vertexAttr1, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
42     m_program1->setAttributeBuffer(m_normalAttr1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
43     m_vbo1.release();
44 
45     glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
46 
47     m_program1->disableAttributeArray(m_normalAttr1);
48     m_program1->disableAttributeArray(m_vertexAttr1);
49 }
50 
initializeGL()51 void GLWidget::initializeGL()
52 {
53     initializeOpenGLFunctions();
54 
55     m_vshader1 = new QOpenGLShader(QOpenGLShader::Vertex);
56     const char *vsrc1 =
57             "attribute highp vec4 vertex;\n"
58             "attribute mediump vec3 normal;\n"
59             "uniform mediump mat4 matrix;\n"
60             "varying mediump vec4 color;\n"
61             "void main(void)\n"
62             "{\n"
63             "    vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
64             "    float angle = max(dot(normal, toLight), 0.0);\n"
65             "    vec3 col = vec3(0.0, 0.87, 2.66);\n"
66             "    color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
67             "    color = clamp(color, 0.0, 1.0);\n"
68             "    gl_Position = matrix * vertex;\n"
69             "}\n";
70     m_vshader1->compileSourceCode(vsrc1);
71 
72     m_fshader1 = new QOpenGLShader(QOpenGLShader::Fragment);
73     const char *fsrc1 =
74             "varying mediump vec4 color;\n"
75             "void main(void)\n"
76             "{\n"
77             "    gl_FragColor = color;\n"
78             "}\n";
79     m_fshader1->compileSourceCode(fsrc1);
80 
81     m_program1 = new QOpenGLShaderProgram;
82     m_program1->addShader(m_vshader1);
83     m_program1->addShader(m_fshader1);
84     m_program1->link();
85 
86     m_vertexAttr1 = m_program1->attributeLocation("vertex");
87     m_normalAttr1 = m_program1->attributeLocation("normal");
88     m_matrixUniform1 = m_program1->uniformLocation("matrix");
89 
90     m_fAngle = 0;
91     m_fScale = 1.0;
92 
93     createGeometry();
94 
95     // Use a vertex buffer object. Client-side pointers are old-school and should be avoided.
96     m_vbo1.create();
97     m_vbo1.bind();
98     // For the cube all the data belonging to the texture coordinates and
99     // normals is placed separately, after the vertices. Here, for the Qt logo,
100     // let's do something different and potentially more efficient: create a
101     // properly interleaved data set.
102     const int vertexCount = m_vertices.count();
103     QVector<GLfloat> buf;
104     buf.resize(vertexCount * 3 * 2);
105     GLfloat *p = buf.data();
106     for (int i = 0; i < vertexCount; ++i) {
107         *p++ = m_vertices[i].x();
108         *p++ = m_vertices[i].y();
109         *p++ = m_vertices[i].z();
110         *p++ = m_normals[i].x();
111         *p++ = m_normals[i].y();
112         *p++ = m_normals[i].z();
113     }
114     m_vbo1.allocate(buf.constData(), buf.count() * sizeof(GLfloat));
115     m_vbo1.release();
116 }
117 
paintGL()118 void GLWidget::paintGL()
119 {
120     QPainter painter;
121     painter.begin(this);
122 
123     painter.beginNativePainting();
124 
125     glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), m_transparent ? 0.0f : 1.0f);
126     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
127 
128     glFrontFace(GL_CW);
129     glCullFace(GL_FRONT);
130     glEnable(GL_CULL_FACE);
131     glEnable(GL_DEPTH_TEST);
132 
133     QMatrix4x4 modelview;
134     modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
135     modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
136     modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
137     modelview.scale(m_fScale);
138     modelview.translate(0.0f, -0.2f, 0.0f);
139 
140 
141     m_program1->bind();
142     m_program1->setUniformValue(m_matrixUniform1, modelview);
143     paintFLLogo();
144     m_program1->release();
145 
146     glDisable(GL_DEPTH_TEST);
147     glDisable(GL_CULL_FACE);
148 
149     painter.endNativePainting();
150 
151     if (const int elapsed = m_time.elapsed()) {
152         QString framesPerSecond;
153         framesPerSecond.setNum(m_frames /(elapsed / 1000.0), 'f', 2);
154         painter.setPen(Qt::blue);
155         painter.drawText(20, 40, framesPerSecond + " paintGL calls / s");
156     }
157 
158     painter.end();
159 
160 
161     if (!(m_frames % 100)) {
162         m_time.start();
163         m_frames = 0;
164     }
165     m_fAngle += 1.0f;
166     ++m_frames;
167 
168     update();
169 }
170 
loadAscllStl(QString filename,qreal ratio)171 void GLWidget::loadAscllStl(QString filename, qreal ratio)
172 {
173     qDebug() << "load text file:" << filename;
174     QVector3D Normal;
175     QFile file(filename);
176     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
177     {
178         qDebug() << "Open stl_file failed." << endl;
179     }
180     while (!file.atEnd())
181     {
182         QString line = file.readLine().trimmed();
183         QStringList  words = line.split(' ', QString::SkipEmptyParts);
184         if (words[0] == "facet") {
185             Normal = QVector3D(ratio*words[2].toFloat(), ratio*words[3].toFloat(),ratio*words[4].toFloat());
186         }
187         else if (words[0] == "vertex") {
188             m_vertices << QVector3D(ratio*words[1].toFloat(), ratio*words[2].toFloat(),ratio*words[3].toFloat());
189             m_normals <<Normal;
190 
191         }
192     }
193 }
194 
195 
createGeometry()196 void GLWidget::createGeometry()
197 {
198     m_vertices.clear();
199     m_normals.clear();
200     this->loadAscllStl(":/logo-3.STL", 0.1);
201 }
202