1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "meshloader_p.h"
31#include "vertexindexer_p.h"
32#include "objecthelper_p.h"
33
34QT_BEGIN_NAMESPACE_DATAVISUALIZATION
35
36ObjectHelper::ObjectHelper(const QString &objectFile)
37 : m_objectFile(objectFile)
38{
39 load();
40}
41
42struct ObjectHelperRef {
43 int refCount;
44 ObjectHelper *obj;
45};
46
47// The "Abstract3DRenderer *" key identifies the renderer
48static QHash<const Abstract3DRenderer *, QHash<QString, ObjectHelperRef *> *> cacheTable;
49
50ObjectHelper::~ObjectHelper()
51{
52}
53
54void ObjectHelper::resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj,
55 const QString &meshFile)
56{
57 Q_ASSERT(cacheId);
58
59 if (obj) {
60 const QString &oldFile = obj->objectFile();
61 if (meshFile == oldFile)
62 return; // same file, do nothing
63 releaseObjectHelper(cacheId, obj);
64 }
65 obj = getObjectHelper(cacheId, objectFile: meshFile);
66}
67
68void ObjectHelper::releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj)
69{
70 Q_ASSERT(cacheId);
71
72 if (obj) {
73 QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(akey: cacheId, adefaultValue: 0);
74 if (objectTable) {
75 // Delete object if last reference is released
76 ObjectHelperRef *objRef = objectTable->value(akey: obj->m_objectFile, adefaultValue: 0);
77 if (objRef) {
78 objRef->refCount--;
79 if (objRef->refCount <= 0) {
80 objectTable->remove(akey: obj->m_objectFile);
81 delete objRef->obj;
82 delete objRef;
83 }
84 }
85 if (objectTable->isEmpty()) {
86 // Remove the entire cache if last object was removed
87 cacheTable.remove(akey: cacheId);
88 delete objectTable;
89 }
90 } else {
91 // Just delete the object if unknown cache
92 delete obj;
93 }
94 obj = 0;
95 }
96}
97
98ObjectHelper *ObjectHelper::getObjectHelper(const Abstract3DRenderer *cacheId,
99 const QString &objectFile)
100{
101 if (objectFile.isEmpty())
102 return 0;
103
104 QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(akey: cacheId, adefaultValue: 0);
105 if (!objectTable) {
106 objectTable = new QHash<QString, ObjectHelperRef *>;
107 cacheTable.insert(akey: cacheId, avalue: objectTable);
108 }
109
110 // Check if object helper for this mesh already exists
111 ObjectHelperRef *objRef = objectTable->value(akey: objectFile, adefaultValue: 0);
112 if (!objRef) {
113 objRef = new ObjectHelperRef;
114 objRef->refCount = 0;
115 objRef->obj = new ObjectHelper(objectFile);
116 objectTable->insert(akey: objectFile, avalue: objRef);
117 }
118 objRef->refCount++;
119 return objRef->obj;
120}
121
122void ObjectHelper::load()
123{
124 if (m_meshDataLoaded) {
125 // Delete old data
126 glDeleteBuffers(n: 1, buffers: &m_vertexbuffer);
127 glDeleteBuffers(n: 1, buffers: &m_uvbuffer);
128 glDeleteBuffers(n: 1, buffers: &m_normalbuffer);
129 glDeleteBuffers(n: 1, buffers: &m_elementbuffer);
130 m_indices.clear();
131 m_indexedVertices.clear();
132 m_indexedUVs.clear();
133 m_indexedNormals.clear();
134 m_vertexbuffer = 0;
135 m_uvbuffer = 0;
136 m_normalbuffer = 0;
137 m_elementbuffer = 0;
138 }
139 QVector<QVector3D> vertices;
140 QVector<QVector2D> uvs;
141 QVector<QVector3D> normals;
142 bool loadOk = MeshLoader::loadOBJ(path: m_objectFile, out_vertices&: vertices, out_uvs&: uvs, out_normals&: normals);
143 if (!loadOk)
144 qFatal(msg: "loading failed");
145
146 // Index vertices
147 VertexIndexer::indexVBO(in_vertices: vertices, in_uvs: uvs, in_normals: normals, out_indices&: m_indices, out_vertices&: m_indexedVertices, out_uvs&: m_indexedUVs,
148 out_normals&: m_indexedNormals);
149
150 m_indexCount = m_indices.size();
151
152 glGenBuffers(n: 1, buffers: &m_vertexbuffer);
153 glBindBuffer(GL_ARRAY_BUFFER, buffer: m_vertexbuffer);
154 glBufferData(GL_ARRAY_BUFFER, size: m_indexedVertices.size() * sizeof(QVector3D),
155 data: &m_indexedVertices.at(i: 0),
156 GL_STATIC_DRAW);
157
158 glGenBuffers(n: 1, buffers: &m_normalbuffer);
159 glBindBuffer(GL_ARRAY_BUFFER, buffer: m_normalbuffer);
160 glBufferData(GL_ARRAY_BUFFER, size: m_indexedNormals.size() * sizeof(QVector3D),
161 data: &m_indexedNormals.at(i: 0),
162 GL_STATIC_DRAW);
163
164 glGenBuffers(n: 1, buffers: &m_uvbuffer);
165 glBindBuffer(GL_ARRAY_BUFFER, buffer: m_uvbuffer);
166 glBufferData(GL_ARRAY_BUFFER, size: m_indexedUVs.size() * sizeof(QVector2D),
167 data: &m_indexedUVs.at(i: 0), GL_STATIC_DRAW);
168
169 glGenBuffers(n: 1, buffers: &m_elementbuffer);
170 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer: m_elementbuffer);
171 glBufferData(GL_ELEMENT_ARRAY_BUFFER, size: m_indices.size() * sizeof(GLuint),
172 data: &m_indices.at(i: 0), GL_STATIC_DRAW);
173
174 glBindBuffer(GL_ARRAY_BUFFER, buffer: 0);
175 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer: 0);
176
177 m_meshDataLoaded = true;
178}
179
180QT_END_NAMESPACE_DATAVISUALIZATION
181

source code of qtdatavis3d/src/datavisualization/utils/objecthelper.cpp