Showing the changes to interface/src/renderer/GeometryCache.cpp (1 of 8 files). Show all
Unified · Split
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <cmath> |
| 9 | 9 | |
| 10 | +#include <QNetworkReply> | |
| 11 | + | |
| 12 | +#include "Application.h" | |
| 10 | 13 | #include "GeometryCache.h" |
| 11 | 14 | #include "world.h" |
| 12 | 15 | |
| @@ -236,4 +239,104 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) { · 223 unmodified lines | ||
| 236 | 239 | |
| 237 | 240 | glBindBuffer(GL_ARRAY_BUFFER, 0); |
| 238 | 241 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 239 | −} | |
| 242 | +} | |
| 243 | + | |
| 244 | +QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url) { | |
| 245 | + QSharedPointer<NetworkGeometry> geometry = _networkGeometry.value(url); | |
| 246 | + if (geometry.isNull()) { | |
| 247 | + geometry = QSharedPointer<NetworkGeometry>(new NetworkGeometry(url)); | |
| 248 | + _networkGeometry.insert(url, geometry); | |
| 249 | + } | |
| 250 | + return geometry; | |
| 251 | +} | |
| 252 | + | |
| 253 | +NetworkGeometry::NetworkGeometry(const QUrl& url) { | |
| 254 | + QNetworkRequest request(url); | |
| 255 | + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); | |
| 256 | + _reply = Application::getInstance()->getNetworkAccessManager()->get(request); | |
| 257 | + | |
| 258 | + connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); | |
| 259 | + connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); | |
| 260 | +} | |
| 261 | + | |
| 262 | +NetworkGeometry::~NetworkGeometry() { | |
| 263 | + foreach (const NetworkMesh& mesh, _meshes) { | |
| 264 | + glDeleteBuffers(1, &mesh.indexBufferID); | |
| 265 | + glDeleteBuffers(1, &mesh.vertexBufferID); | |
| 266 | + } | |
| 267 | +} | |
| 268 | + | |
| 269 | +void NetworkGeometry::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { | |
| 270 | + if (bytesReceived < bytesTotal && !_reply->isFinished()) { | |
| 271 | + return; | |
| 272 | + } | |
| 273 | + | |
| 274 | + QUrl url = _reply->url(); | |
| 275 | + QByteArray entirety = _reply->readAll(); | |
| 276 | + _reply->disconnect(this); | |
| 277 | + _reply->deleteLater(); | |
| 278 | + _reply = NULL; | |
| 279 | + | |
| 280 | + try { | |
| 281 | + _geometry = extractFBXGeometry(parseFBX(entirety)); | |
| 282 | + | |
| 283 | + } catch (const QString& error) { | |
| 284 | + qDebug() << "Error reading " << url << ": " << error << "\n"; | |
| 285 | + return; | |
| 286 | + } | |
| 287 | + | |
| 288 | + foreach (const FBXMesh& mesh, _geometry.meshes) { | |
| 289 | + NetworkMesh networkMesh; | |
| 290 | + | |
| 291 | + glGenBuffers(1, &networkMesh.indexBufferID); | |
| 292 | + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, networkMesh.indexBufferID); | |
| 293 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (mesh.quadIndices.size() + mesh.triangleIndices.size()) * sizeof(int), | |
| 294 | + NULL, GL_STATIC_DRAW); | |
| 295 | + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh.quadIndices.size() * sizeof(int), mesh.quadIndices.constData()); | |
| 296 | + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mesh.quadIndices.size() * sizeof(int), | |
| 297 | + mesh.triangleIndices.size() * sizeof(int), mesh.triangleIndices.constData()); | |
| 298 | + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 299 | + | |
| 300 | + glGenBuffers(1, &networkMesh.vertexBufferID); | |
| 301 | + glBindBuffer(GL_ARRAY_BUFFER, networkMesh.vertexBufferID); | |
| 302 | + | |
| 303 | + if (mesh.blendshapes.isEmpty()) { | |
| 304 | + glBufferData(GL_ARRAY_BUFFER, (mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3) + | |
| 305 | + mesh.texCoords.size() * sizeof(glm::vec2), NULL, GL_STATIC_DRAW); | |
| 306 | + glBufferSubData(GL_ARRAY_BUFFER, 0, mesh.vertices.size() * sizeof(glm::vec3), mesh.vertices.constData()); | |
| 307 | + glBufferSubData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(glm::vec3), | |
| 308 | + mesh.normals.size() * sizeof(glm::vec3), mesh.normals.constData()); | |
| 309 | + glBufferSubData(GL_ARRAY_BUFFER, (mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3), | |
| 310 | + mesh.texCoords.size() * sizeof(glm::vec2), mesh.texCoords.constData()); | |
| 311 | + | |
| 312 | + } else { | |
| 313 | + glBufferData(GL_ARRAY_BUFFER, mesh.texCoords.size() * sizeof(glm::vec2), | |
| 314 | + mesh.texCoords.constData(), GL_STATIC_DRAW); | |
| 315 | + } | |
| 316 | + | |
| 317 | + glBindBuffer(GL_ARRAY_BUFFER, 0); | |
| 318 | + | |
| 319 | + QString basePath = url.path(); | |
| 320 | + int idx = basePath.lastIndexOf('/'); | |
| 321 | + if (idx != -1) { | |
| 322 | + basePath = basePath.left(idx); | |
| 323 | + } | |
| 324 | + if (!mesh.diffuseFilename.isEmpty()) { | |
| 325 | + url.setPath(basePath + mesh.diffuseFilename); | |
| 326 | + networkMesh.diffuseTexture = Application::getInstance()->getTextureCache()->getTexture(url); | |
| 327 | + } | |
| 328 | + if (!mesh.normalFilename.isEmpty()) { | |
| 329 | + url.setPath(basePath + mesh.normalFilename); | |
| 330 | + networkMesh.normalTexture = Application::getInstance()->getTextureCache()->getTexture(url); | |
| 331 | + } | |
| 332 | + _meshes.append(networkMesh); | |
| 333 | + } | |
| 334 | +} | |
| 335 | + | |
| 336 | +void NetworkGeometry::handleReplyError() { | |
| 337 | + qDebug() << _reply->errorString() << "\n"; | |
| 338 | + | |
| 339 | + _reply->disconnect(this); | |
| 340 | + _reply->deleteLater(); | |
| 341 | + _reply = NULL; | |
| 342 | +} | |