Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 4 files). Show all
Unified · Split
| @@ -254,15 +254,22 @@ void PointBuffer::render() { · 253 unmodified lines | ||
| 254 | 254 | _buffer.release(); |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | −HeightfieldBuffer::HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal) : | |
| 257 | +HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale, | |
| 258 | + const QByteArray& height, const QByteArray& color) : | |
| 259 | + _translation(translation), | |
| 260 | + _scale(scale), | |
| 258 | 261 | _height(height), |
| 259 | 262 | _color(color), |
| 260 | − _normal(normal), | |
| 261 | 263 | _heightTexture(QOpenGLTexture::Target2D), |
| 262 | − _colorTexture(QOpenGLTexture::Target2D), | |
| 263 | − _normalTexture(QOpenGLTexture::Target2D) { | |
| 264 | + _colorTexture(QOpenGLTexture::Target2D) { | |
| 264 | 265 | } |
| 265 | 266 | |
| 267 | +class HeightfieldPoint { | |
| 268 | +public: | |
| 269 | + glm::vec2 textureCoord; | |
| 270 | + glm::vec3 vertex; | |
| 271 | +}; | |
| 272 | + | |
| 266 | 273 | void HeightfieldBuffer::render() { |
| 267 | 274 | // initialize textures, etc. on first render |
| 268 | 275 | if (!_heightTexture.isCreated()) { |
| @@ -273,21 +280,116 @@ void HeightfieldBuffer::render() { · 4 unmodified lines | ||
| 273 | 280 | _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data()); |
| 274 | 281 | _height.clear(); |
| 275 | 282 | |
| 276 | − int colorSize = glm::sqrt(_color.size() / 3); | |
| 277 | − _colorTexture.setSize(colorSize, colorSize); | |
| 283 | + if (!_color.isEmpty()) { | |
| 284 | + int colorSize = glm::sqrt(_color.size() / 3); | |
| 285 | + _colorTexture.setSize(colorSize, colorSize); | |
| 286 | + } | |
| 278 | 287 | _colorTexture.setFormat(QOpenGLTexture::RGBFormat); |
| 279 | 288 | _colorTexture.allocateStorage(); |
| 280 | − _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data()); | |
| 281 | − _color.clear(); | |
| 289 | + if (!_color.isEmpty()) { | |
| 290 | + _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data()); | |
| 291 | + _color.clear(); | |
| 292 | + | |
| 293 | + } else { | |
| 294 | + const quint8 WHITE_COLOR[] = { 255, 255, 255 }; | |
| 295 | + _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, const_cast<quint8*>(WHITE_COLOR)); | |
| 296 | + } | |
| 297 | + } | |
| 298 | + // create the buffer objects lazily | |
| 299 | + int size = _heightTexture.width(); | |
| 300 | + int sizeWithSkirt = size + 2; | |
| 301 | + int vertexCount = sizeWithSkirt * sizeWithSkirt; | |
| 302 | + int rows = sizeWithSkirt - 1; | |
| 303 | + int indexCount = rows * rows * 4; | |
| 304 | + BufferPair& bufferPair = _bufferPairs[size]; | |
| 305 | + if (!bufferPair.first.isCreated()) { | |
| 306 | + QVector<HeightfieldPoint> vertices(vertexCount); | |
| 307 | + HeightfieldPoint* point = vertices.data(); | |
| 308 | + | |
| 309 | + float step = 1.0f / (size - 1); | |
| 310 | + float z = -step; | |
| 311 | + for (int i = 0; i < sizeWithSkirt; i++, z += step) { | |
| 312 | + float x = -step; | |
| 313 | + const float SKIRT_LENGTH = 1.0f; | |
| 314 | + float baseY = (i == 0 || i == sizeWithSkirt - 1) ? -SKIRT_LENGTH : 0.0f; | |
| 315 | + for (int j = 0; j < sizeWithSkirt; j++, point++, x += step) { | |
| 316 | + point->vertex = glm::vec3(x, (j == 0 || j == sizeWithSkirt - 1) ? -SKIRT_LENGTH : baseY, z); | |
| 317 | + point->textureCoord = glm::vec2(x, z); | |
| 318 | + } | |
| 319 | + } | |
| 320 | + | |
| 321 | + bufferPair.first.setUsagePattern(QOpenGLBuffer::StaticDraw); | |
| 322 | + bufferPair.first.create(); | |
| 323 | + bufferPair.first.bind(); | |
| 324 | + bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint)); | |
| 325 | + | |
| 326 | + QVector<int> indices(indexCount); | |
| 327 | + int* index = indices.data(); | |
| 328 | + for (int i = 0; i < rows; i++) { | |
| 329 | + int lineIndex = i * sizeWithSkirt; | |
| 330 | + int nextLineIndex = (i + 1) * sizeWithSkirt; | |
| 331 | + for (int j = 0; j < rows; j++) { | |
| 332 | + *index++ = lineIndex + j; | |
| 333 | + *index++ = lineIndex + j + 1; | |
| 334 | + *index++ = nextLineIndex + j; | |
| 335 | + *index++ = nextLineIndex + j + 1; | |
| 336 | + } | |
| 337 | + } | |
| 338 | + | |
| 339 | + bufferPair.second = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); | |
| 340 | + bufferPair.second.create(); | |
| 341 | + bufferPair.second.bind(); | |
| 342 | + bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); | |
| 282 | 343 | |
| 283 | − int normalSize = glm::sqrt(_normal.size() / 3); | |
| 284 | − _normalTexture.setSize(normalSize, normalSize); | |
| 285 | − _normalTexture.setFormat(QOpenGLTexture::RGBFormat); | |
| 286 | − _normalTexture.allocateStorage(); | |
| 287 | − _normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data()); | |
| 288 | − _normal.clear(); | |
| 344 | + } else { | |
| 345 | + bufferPair.first.bind(); | |
| 346 | + bufferPair.second.bind(); | |
| 347 | + } | |
| 348 | + | |
| 349 | + HeightfieldPoint* point = 0; | |
| 350 | + glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | |
| 351 | + glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | |
| 352 | + | |
| 353 | + glPushMatrix(); | |
| 354 | + glTranslatef(_translation.x, _translation.y, _translation.z); | |
| 355 | + glScalef(_scale, _scale, _scale); | |
| 356 | + | |
| 357 | + _heightTexture.bind(0); | |
| 358 | + _colorTexture.bind(1); | |
| 359 | + | |
| 360 | + glDrawRangeElements(GL_QUADS, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); | |
| 361 | + | |
| 362 | + _colorTexture.release(1); | |
| 363 | + _heightTexture.release(0); | |
| 364 | + | |
| 365 | + glPopMatrix(); | |
| 366 | + | |
| 367 | + bufferPair.first.release(); | |
| 368 | + bufferPair.second.release(); | |
| 369 | +} | |
| 370 | + | |
| 371 | +QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs; | |
| 372 | + | |
| 373 | +void HeightfieldPreview::render(const glm::vec3& translation, float scale) const { | |
| 374 | + glEnableClientState(GL_VERTEX_ARRAY); | |
| 375 | + glEnableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 376 | + | |
| 377 | + DefaultMetavoxelRendererImplementation::getHeightfieldProgram().bind(); | |
| 378 | + | |
| 379 | + glPushMatrix(); | |
| 380 | + glTranslatef(translation.x, translation.y, translation.z); | |
| 381 | + glScalef(scale, scale, scale); | |
| 382 | + | |
| 383 | + foreach (const BufferDataPointer& buffer, _buffers) { | |
| 384 | + buffer->render(); | |
| 289 | 385 | } |
| 290 | 386 | |
| 387 | + glPopMatrix(); | |
| 388 | + | |
| 389 | + DefaultMetavoxelRendererImplementation::getHeightfieldProgram().release(); | |
| 390 | + | |
| 391 | + glDisableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 392 | + glDisableClientState(GL_VERTEX_ARRAY); | |
| 291 | 393 | } |
| 292 | 394 | |
| 293 | 395 | BufferDataAttribute::BufferDataAttribute(const QString& name) : |
| @@ -368,11 +470,14 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) { · 74 unmodified lines | ||
| 368 | 470 | { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } }; |
| 369 | 471 | _points.append(point); |
| 370 | 472 | } |
| 371 | − if (info.size >= _pointLeafSize) { | |
| 372 | − BufferPointVector swapPoints; | |
| 373 | − _points.swap(swapPoints); | |
| 374 | − info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( | |
| 375 | − new PointBuffer(swapPoints)))); | |
| 473 | + if (info.size >= _pointLeafSize) { | |
| 474 | + PointBuffer* buffer = NULL; | |
| 475 | + if (!_points.isEmpty()) { | |
| 476 | + BufferPointVector swapPoints; | |
| 477 | + _points.swap(swapPoints); | |
| 478 | + buffer = new PointBuffer(swapPoints); | |
| 479 | + } | |
| 480 | + info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer))); | |
| 376 | 481 | } |
| 377 | 482 | return STOP_RECURSION; |
| 378 | 483 | } |
| @@ -381,10 +486,13 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 2 unmodified lines | ||
| 381 | 486 | if (info.size != _pointLeafSize) { |
| 382 | 487 | return false; |
| 383 | 488 | } |
| 384 | − BufferPointVector swapPoints; | |
| 385 | − _points.swap(swapPoints); | |
| 386 | − info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( | |
| 387 | − new PointBuffer(swapPoints)))); | |
| 489 | + PointBuffer* buffer = NULL; | |
| 490 | + if (!_points.isEmpty()) { | |
| 491 | + BufferPointVector swapPoints; | |
| 492 | + _points.swap(swapPoints); | |
| 493 | + buffer = new PointBuffer(swapPoints); | |
| 494 | + } | |
| 495 | + info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer))); | |
| 388 | 496 | return true; |
| 389 | 497 | } |
| 390 | 498 | |
| @@ -403,7 +511,18 @@ HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : · 12 unmodified lines | ||
| 403 | 511 | } |
| 404 | 512 | |
| 405 | 513 | int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) { |
| 406 | − return STOP_RECURSION; | |
| 514 | + if (info.isLeaf) { | |
| 515 | + HeightfieldBuffer* buffer = NULL; | |
| 516 | + HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>(); | |
| 517 | + if (height) { | |
| 518 | + HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>(); | |
| 519 | + buffer = new HeightfieldBuffer(info.minimum, info.size, height->getContents(), | |
| 520 | + color ? color->getContents() : QByteArray()); | |
| 521 | + } | |
| 522 | + info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer))); | |
| 523 | + return STOP_RECURSION; | |
| 524 | + } | |
| 525 | + return DEFAULT_ORDER; | |
| 407 | 526 | } |
| 408 | 527 | |
| 409 | 528 | void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, |
| @@ -419,11 +538,19 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 9 unmodified lines | ||
| 419 | 538 | data.setRoot(pointBufferAttribute, root); |
| 420 | 539 | root->incrementReferenceCount(); |
| 421 | 540 | } |
| 541 | + const AttributePointer& heightfieldBufferAttribute = | |
| 542 | + Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(); | |
| 543 | + root = expandedPrevious.getRoot(heightfieldBufferAttribute); | |
| 544 | + if (root) { | |
| 545 | + data.setRoot(heightfieldBufferAttribute, root); | |
| 546 | + root->incrementReferenceCount(); | |
| 547 | + } | |
| 422 | 548 | |
| 423 | − PointAugmentVisitor visitor(lod); | |
| 424 | − data.guideToDifferent(expandedPrevious, visitor); | |
| 425 | − | |
| 549 | + PointAugmentVisitor pointAugmentVisitor(lod); | |
| 550 | + data.guideToDifferent(expandedPrevious, pointAugmentVisitor); | |
| 426 | 551 | |
| 552 | + HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod); | |
| 553 | + data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor); | |
| 427 | 554 | } |
| 428 | 555 | |
| 429 | 556 | class SpannerSimulateVisitor : public SpannerVisitor { |
| @@ -530,16 +657,24 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 100 unmodified lines | ||
| 530 | 657 | |
| 531 | 658 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
| 532 | 659 | |
| 533 | − glDisableClientState(GL_VERTEX_ARRAY); | |
| 534 | 660 | glDisableClientState(GL_COLOR_ARRAY); |
| 535 | 661 | glDisableClientState(GL_NORMAL_ARRAY); |
| 536 | 662 | |
| 537 | 663 | _pointProgram.release(); |
| 538 | 664 | |
| 665 | + _heightfieldProgram.bind(); | |
| 666 | + | |
| 667 | + glEnableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 668 | + | |
| 539 | 669 | BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), |
| 540 | 670 | lod); |
| 541 | 671 | data.guide(heightfieldRenderVisitor); |
| 542 | 672 | |
| 673 | + _heightfieldProgram.release(); | |
| 674 | + | |
| 675 | + glDisableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 676 | + glDisableClientState(GL_VERTEX_ARRAY); | |
| 677 | + | |
| 543 | 678 | glEnable(GL_BLEND); |
| 544 | 679 | } |
| 545 | 680 | |