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 | _buffer.release(); | 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 | _height(height), | 261 | _height(height), |
| 259 | _color(color), | 262 | _color(color), |
| 260 | _normal(normal), | ||
| 261 | _heightTexture(QOpenGLTexture::Target2D), | 263 | _heightTexture(QOpenGLTexture::Target2D), |
| 262 | _colorTexture(QOpenGLTexture::Target2D), | 264 | _colorTexture(QOpenGLTexture::Target2D) { |
| 263 | _normalTexture(QOpenGLTexture::Target2D) { | ||
| 264 | } | 265 | } |
| 265 | 266 | ||
| 267 | class HeightfieldPoint { | ||
| 268 | public: | ||
| 269 | glm::vec2 textureCoord; | ||
| 270 | glm::vec3 vertex; | ||
| 271 | }; | ||
| 272 | |||
| 266 | void HeightfieldBuffer::render() { | 273 | void HeightfieldBuffer::render() { |
| 267 | // initialize textures, etc. on first render | 274 | // initialize textures, etc. on first render |
| 268 | if (!_heightTexture.isCreated()) { | 275 | if (!_heightTexture.isCreated()) { |
| @@ -273,21 +280,116 @@ void HeightfieldBuffer::render() { · 4 unmodified lines | |||
| 273 | _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data()); | 280 | _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data()); |
| 274 | _height.clear(); | 281 | _height.clear(); |
| 275 | 282 | ||
| 276 | int colorSize = glm::sqrt(_color.size() / 3); | 283 | if (!_color.isEmpty()) { |
| 277 | _colorTexture.setSize(colorSize, colorSize); | 284 | int colorSize = glm::sqrt(_color.size() / 3); |
| 285 | _colorTexture.setSize(colorSize, colorSize); | ||
| 286 | } | ||
| 278 | _colorTexture.setFormat(QOpenGLTexture::RGBFormat); | 287 | _colorTexture.setFormat(QOpenGLTexture::RGBFormat); |
| 279 | _colorTexture.allocateStorage(); | 288 | _colorTexture.allocateStorage(); |
| 280 | _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data()); | 289 | if (!_color.isEmpty()) { |
| 281 | _color.clear(); | 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); | 344 | } else { |
| 284 | _normalTexture.setSize(normalSize, normalSize); | 345 | bufferPair.first.bind(); |
| 285 | _normalTexture.setFormat(QOpenGLTexture::RGBFormat); | 346 | bufferPair.second.bind(); |
| 286 | _normalTexture.allocateStorage(); | 347 | } |
| 287 | _normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data()); | 348 | |
| 288 | _normal.clear(); | 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 | BufferDataAttribute::BufferDataAttribute(const QString& name) : | 395 | BufferDataAttribute::BufferDataAttribute(const QString& name) : |
| @@ -368,11 +470,14 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) { · 74 unmodified lines | |||
| 368 | { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } }; | 470 | { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } }; |
| 369 | _points.append(point); | 471 | _points.append(point); |
| 370 | } | 472 | } |
| 371 | if (info.size >= _pointLeafSize) { | 473 | if (info.size >= _pointLeafSize) { |
| 372 | BufferPointVector swapPoints; | 474 | PointBuffer* buffer = NULL; |
| 373 | _points.swap(swapPoints); | 475 | if (!_points.isEmpty()) { |
| 374 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( | 476 | BufferPointVector swapPoints; |
| 375 | new PointBuffer(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 | return STOP_RECURSION; | 482 | return STOP_RECURSION; |
| 378 | } | 483 | } |
| @@ -381,10 +486,13 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 2 unmodified lines | |||
| 381 | if (info.size != _pointLeafSize) { | 486 | if (info.size != _pointLeafSize) { |
| 382 | return false; | 487 | return false; |
| 383 | } | 488 | } |
| 384 | BufferPointVector swapPoints; | 489 | PointBuffer* buffer = NULL; |
| 385 | _points.swap(swapPoints); | 490 | if (!_points.isEmpty()) { |
| 386 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( | 491 | BufferPointVector swapPoints; |
| 387 | new PointBuffer(swapPoints)))); | 492 | _points.swap(swapPoints); |
| 493 | buffer = new PointBuffer(swapPoints); | ||
| 494 | } | ||
| 495 | info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer))); | ||
| 388 | return true; | 496 | return true; |
| 389 | } | 497 | } |
| 390 | 498 | ||
| @@ -403,7 +511,18 @@ HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : · 12 unmodified lines | |||
| 403 | } | 511 | } |
| 404 | 512 | ||
| 405 | int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) { | 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 | void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, | 528 | void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, |
| @@ -419,11 +538,19 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 9 unmodified lines | |||
| 419 | data.setRoot(pointBufferAttribute, root); | 538 | data.setRoot(pointBufferAttribute, root); |
| 420 | root->incrementReferenceCount(); | 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); | 549 | PointAugmentVisitor pointAugmentVisitor(lod); |
| 424 | data.guideToDifferent(expandedPrevious, visitor); | 550 | data.guideToDifferent(expandedPrevious, pointAugmentVisitor); |
| 425 | |||
| 426 | 551 | ||
| 552 | HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod); | ||
| 553 | data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor); | ||
| 427 | } | 554 | } |
| 428 | 555 | ||
| 429 | class SpannerSimulateVisitor : public SpannerVisitor { | 556 | class SpannerSimulateVisitor : public SpannerVisitor { |
| @@ -530,16 +657,24 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 100 unmodified lines | |||
| 530 | 657 | ||
| 531 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); | 658 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); |
| 532 | 659 | ||
| 533 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 534 | glDisableClientState(GL_COLOR_ARRAY); | 660 | glDisableClientState(GL_COLOR_ARRAY); |
| 535 | glDisableClientState(GL_NORMAL_ARRAY); | 661 | glDisableClientState(GL_NORMAL_ARRAY); |
| 536 | 662 | ||
| 537 | _pointProgram.release(); | 663 | _pointProgram.release(); |
| 538 | 664 | ||
| 665 | _heightfieldProgram.bind(); | ||
| 666 | |||
| 667 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 668 | |||
| 539 | BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), | 669 | BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), |
| 540 | lod); | 670 | lod); |
| 541 | data.guide(heightfieldRenderVisitor); | 671 | data.guide(heightfieldRenderVisitor); |
| 542 | 672 | ||
| 673 | _heightfieldProgram.release(); | ||
| 674 | |||
| 675 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 676 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 677 | |||
| 543 | glEnable(GL_BLEND); | 678 | glEnable(GL_BLEND); |
| 544 | } | 679 | } |
| 545 | 680 | ||