Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 22 files). Show all
Unified · Split
| @@ -461,6 +461,34 @@ void MetavoxelSystem::render() { · 460 unmodified lines | |||
| 461 | _voxelBaseBatches.clear(); | 461 | _voxelBaseBatches.clear(); |
| 462 | } | 462 | } |
| 463 | 463 | ||
| 464 | if (!_hermiteBatches.isEmpty() && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { | ||
| 465 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); | ||
| 466 | |||
| 467 | glEnableClientState(GL_VERTEX_ARRAY); | ||
| 468 | |||
| 469 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | ||
| 470 | glNormal3f(0.0f, 1.0f, 0.0f); | ||
| 471 | |||
| 472 | Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram(); | ||
| 473 | |||
| 474 | foreach (const HermiteBatch& batch, _hermiteBatches) { | ||
| 475 | batch.vertexBuffer->bind(); | ||
| 476 | |||
| 477 | glVertexPointer(3, GL_FLOAT, 0, 0); | ||
| 478 | |||
| 479 | glDrawArrays(GL_LINES, 0, batch.vertexCount); | ||
| 480 | |||
| 481 | batch.vertexBuffer->release(); | ||
| 482 | } | ||
| 483 | |||
| 484 | Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram(); | ||
| 485 | |||
| 486 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 487 | |||
| 488 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); | ||
| 489 | } | ||
| 490 | _hermiteBatches.clear(); | ||
| 491 | |||
| 464 | // give external parties a chance to join in | 492 | // give external parties a chance to join in |
| 465 | emit rendering(); | 493 | emit rendering(); |
| 466 | } | 494 | } |
| @@ -550,10 +578,53 @@ void MetavoxelSystem::setVoxelMaterial(const SharedObjectPointer& spanner, const · 83 unmodified lines | |||
| 550 | applyMaterialEdit(edit, true); | 578 | applyMaterialEdit(edit, true); |
| 551 | } | 579 | } |
| 552 | 580 | ||
| 553 | class SpannerCursorRenderVisitor : public SpannerVisitor { | 581 | void MetavoxelSystem::deleteTextures(int heightTextureID, int colorTextureID, int materialTextureID) const { |
| 582 | glDeleteTextures(1, (const GLuint*)&heightTextureID); | ||
| 583 | glDeleteTextures(1, (const GLuint*)&colorTextureID); | ||
| 584 | glDeleteTextures(1, (const GLuint*)&materialTextureID); | ||
| 585 | } | ||
| 586 | |||
| 587 | class SpannerRenderVisitor : public SpannerVisitor { | ||
| 588 | public: | ||
| 589 | |||
| 590 | SpannerRenderVisitor(const MetavoxelLOD& lod); | ||
| 591 | |||
| 592 | virtual int visit(MetavoxelInfo& info); | ||
| 593 | virtual bool visit(Spanner* spanner); | ||
| 594 | |||
| 595 | protected: | ||
| 596 | |||
| 597 | int _containmentDepth; | ||
| 598 | }; | ||
| 599 | |||
| 600 | SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) : | ||
| 601 | SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(), | ||
| 602 | QVector<AttributePointer>(), QVector<AttributePointer>(), lod, | ||
| 603 | encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())), | ||
| 604 | _containmentDepth(INT_MAX) { | ||
| 605 | } | ||
| 606 | |||
| 607 | int SpannerRenderVisitor::visit(MetavoxelInfo& info) { | ||
| 608 | if (_containmentDepth >= _depth) { | ||
| 609 | Frustum::IntersectionType intersection = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType( | ||
| 610 | info.getBounds()); | ||
| 611 | if (intersection == Frustum::NO_INTERSECTION) { | ||
| 612 | return STOP_RECURSION; | ||
| 613 | } | ||
| 614 | _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX; | ||
| 615 | } | ||
| 616 | return SpannerVisitor::visit(info); | ||
| 617 | } | ||
| 618 | |||
| 619 | bool SpannerRenderVisitor::visit(Spanner* spanner) { | ||
| 620 | spanner->getRenderer()->render(_lod, _containmentDepth <= _depth); | ||
| 621 | return true; | ||
| 622 | } | ||
| 623 | |||
| 624 | class SpannerCursorRenderVisitor : public SpannerRenderVisitor { | ||
| 554 | public: | 625 | public: |
| 555 | 626 | ||
| 556 | SpannerCursorRenderVisitor(const Box& bounds); | 627 | SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds); |
| 557 | 628 | ||
| 558 | virtual bool visit(Spanner* spanner); | 629 | virtual bool visit(Spanner* spanner); |
| 559 | 630 | ||
| @@ -564,20 +635,20 @@ private: · 4 unmodified lines | |||
| 564 | Box _bounds; | 635 | Box _bounds; |
| 565 | }; | 636 | }; |
| 566 | 637 | ||
| 567 | SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const Box& bounds) : | 638 | SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) : |
| 568 | SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute()), | 639 | SpannerRenderVisitor(lod), |
| 569 | _bounds(bounds) { | 640 | _bounds(bounds) { |
| 570 | } | 641 | } |
| 571 | 642 | ||
| 572 | bool SpannerCursorRenderVisitor::visit(Spanner* spanner) { | 643 | bool SpannerCursorRenderVisitor::visit(Spanner* spanner) { |
| 573 | if (spanner->isHeightfield()) { | 644 | if (spanner->isHeightfield()) { |
| 574 | spanner->getRenderer()->render(true); | 645 | spanner->getRenderer()->render(_lod, _containmentDepth <= _depth, true); |
| 575 | } | 646 | } |
| 576 | return true; | 647 | return true; |
| 577 | } | 648 | } |
| 578 | 649 | ||
| 579 | int SpannerCursorRenderVisitor::visit(MetavoxelInfo& info) { | 650 | int SpannerCursorRenderVisitor::visit(MetavoxelInfo& info) { |
| 580 | return info.getBounds().intersects(_bounds) ? SpannerVisitor::visit(info) : STOP_RECURSION; | 651 | return info.getBounds().intersects(_bounds) ? SpannerRenderVisitor::visit(info) : STOP_RECURSION; |
| 581 | } | 652 | } |
| 582 | 653 | ||
| 583 | void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float radius) { | 654 | void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float radius) { |
| @@ -604,7 +675,7 @@ void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float r · 20 unmodified lines | |||
| 604 | glActiveTexture(GL_TEXTURE0); | 675 | glActiveTexture(GL_TEXTURE0); |
| 605 | 676 | ||
| 606 | glm::vec3 extents(radius, radius, radius); | 677 | glm::vec3 extents(radius, radius, radius); |
| 607 | SpannerCursorRenderVisitor visitor(Box(position - extents, position + extents)); | 678 | SpannerCursorRenderVisitor visitor(getLOD(), Box(position - extents, position + extents)); |
| 608 | guide(visitor); | 679 | guide(visitor); |
| 609 | 680 | ||
| 610 | _heightfieldCursorProgram.release(); | 681 | _heightfieldCursorProgram.release(); |
| @@ -678,7 +749,7 @@ void MetavoxelSystem::renderVoxelCursor(const glm::vec3& position, float radius) · 67 unmodified lines | |||
| 678 | 749 | ||
| 679 | _heightfieldCursorProgram.bind(); | 750 | _heightfieldCursorProgram.bind(); |
| 680 | 751 | ||
| 681 | SpannerCursorRenderVisitor spannerVisitor(bounds); | 752 | SpannerCursorRenderVisitor spannerVisitor(getLOD(), bounds); |
| 682 | guide(spannerVisitor); | 753 | guide(spannerVisitor); |
| 683 | 754 | ||
| 684 | _heightfieldCursorProgram.release(); | 755 | _heightfieldCursorProgram.release(); |
| @@ -1192,31 +1263,18 @@ void VoxelBuffer::render(bool cursor) { · 507 unmodified lines | |||
| 1192 | } | 1263 | } |
| 1193 | } | 1264 | } |
| 1194 | 1265 | ||
| 1195 | if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { | 1266 | if (_hermiteCount > 0) { |
| 1196 | if (!_hermiteBuffer.isCreated()) { | 1267 | if (!_hermiteBuffer.isCreated()) { |
| 1197 | _hermiteBuffer.create(); | 1268 | _hermiteBuffer.create(); |
| 1198 | _hermiteBuffer.bind(); | 1269 | _hermiteBuffer.bind(); |
| 1199 | _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); | 1270 | _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); |
| 1271 | _hermiteBuffer.release(); | ||
| 1200 | _hermite.clear(); | 1272 | _hermite.clear(); |
| 1201 | |||
| 1202 | } else { | ||
| 1203 | _hermiteBuffer.bind(); | ||
| 1204 | } | 1273 | } |
| 1205 | 1274 | HermiteBatch hermiteBatch; | |
| 1206 | glVertexPointer(3, GL_FLOAT, 0, 0); | 1275 | hermiteBatch.vertexBuffer = &_hermiteBuffer; |
| 1207 | 1276 | hermiteBatch.vertexCount = _hermiteCount; | |
| 1208 | Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); | 1277 | Application::getInstance()->getMetavoxels()->addHermiteBatch(hermiteBatch); |
| 1209 | |||
| 1210 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | ||
| 1211 | glNormal3f(0.0f, 1.0f, 0.0f); | ||
| 1212 | |||
| 1213 | glLineWidth(1.0f); | ||
| 1214 | |||
| 1215 | glDrawArrays(GL_LINES, 0, _hermiteCount); | ||
| 1216 | |||
| 1217 | Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().release(); | ||
| 1218 | |||
| 1219 | _hermiteBuffer.release(); | ||
| 1220 | } | 1278 | } |
| 1221 | } | 1279 | } |
| 1222 | 1280 | ||
| @@ -1880,43 +1938,6 @@ void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float · 657 unmodified lines | |||
| 1880 | data.guide(spannerSimulateVisitor); | 1938 | data.guide(spannerSimulateVisitor); |
| 1881 | } | 1939 | } |
| 1882 | 1940 | ||
| 1883 | class SpannerRenderVisitor : public SpannerVisitor { | ||
| 1884 | public: | ||
| 1885 | |||
| 1886 | SpannerRenderVisitor(const MetavoxelLOD& lod); | ||
| 1887 | |||
| 1888 | virtual int visit(MetavoxelInfo& info); | ||
| 1889 | virtual bool visit(Spanner* spanner); | ||
| 1890 | |||
| 1891 | private: | ||
| 1892 | |||
| 1893 | int _containmentDepth; | ||
| 1894 | }; | ||
| 1895 | |||
| 1896 | SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) : | ||
| 1897 | SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(), | ||
| 1898 | QVector<AttributePointer>(), QVector<AttributePointer>(), lod, | ||
| 1899 | encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())), | ||
| 1900 | _containmentDepth(INT_MAX) { | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | int SpannerRenderVisitor::visit(MetavoxelInfo& info) { | ||
| 1904 | if (_containmentDepth >= _depth) { | ||
| 1905 | Frustum::IntersectionType intersection = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType( | ||
| 1906 | info.getBounds()); | ||
| 1907 | if (intersection == Frustum::NO_INTERSECTION) { | ||
| 1908 | return STOP_RECURSION; | ||
| 1909 | } | ||
| 1910 | _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX; | ||
| 1911 | } | ||
| 1912 | return SpannerVisitor::visit(info); | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | bool SpannerRenderVisitor::visit(Spanner* spanner) { | ||
| 1916 | spanner->getRenderer()->render(); | ||
| 1917 | return true; | ||
| 1918 | } | ||
| 1919 | |||
| 1920 | class BufferRenderVisitor : public MetavoxelVisitor { | 1941 | class BufferRenderVisitor : public MetavoxelVisitor { |
| 1921 | public: | 1942 | public: |
| 1922 | 1943 | ||
| @@ -1970,7 +1991,7 @@ SphereRenderer::SphereRenderer() { · 47 unmodified lines | |||
| 1970 | } | 1991 | } |
| 1971 | 1992 | ||
| 1972 | 1993 | ||
| 1973 | void SphereRenderer::render(bool cursor) { | 1994 | void SphereRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) { |
| 1974 | Sphere* sphere = static_cast<Sphere*>(_spanner); | 1995 | Sphere* sphere = static_cast<Sphere*>(_spanner); |
| 1975 | const QColor& color = sphere->getColor(); | 1996 | const QColor& color = sphere->getColor(); |
| 1976 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); | 1997 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); |
| @@ -1990,7 +2011,7 @@ void SphereRenderer::render(bool cursor) { · 13 unmodified lines | |||
| 1990 | CuboidRenderer::CuboidRenderer() { | 2011 | CuboidRenderer::CuboidRenderer() { |
| 1991 | } | 2012 | } |
| 1992 | 2013 | ||
| 1993 | void CuboidRenderer::render(bool cursor) { | 2014 | void CuboidRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) { |
| 1994 | Cuboid* cuboid = static_cast<Cuboid*>(_spanner); | 2015 | Cuboid* cuboid = static_cast<Cuboid*>(_spanner); |
| 1995 | const QColor& color = cuboid->getColor(); | 2016 | const QColor& color = cuboid->getColor(); |
| 1996 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); | 2017 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); |
| @@ -2041,7 +2062,7 @@ void StaticModelRenderer::simulate(float deltaTime) { · 44 unmodified lines | |||
| 2041 | _model->simulate(deltaTime); | 2062 | _model->simulate(deltaTime); |
| 2042 | } | 2063 | } |
| 2043 | 2064 | ||
| 2044 | void StaticModelRenderer::render(bool cursor) { | 2065 | void StaticModelRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) { |
| 2045 | _model->render(); | 2066 | _model->render(); |
| 2046 | } | 2067 | } |
| 2047 | 2068 | ||
| @@ -2073,57 +2094,66 @@ void StaticModelRenderer::applyURL(const QUrl& url) { · 25 unmodified lines | |||
| 2073 | } | 2094 | } |
| 2074 | 2095 | ||
| 2075 | HeightfieldRenderer::HeightfieldRenderer() { | 2096 | HeightfieldRenderer::HeightfieldRenderer() { |
| 2076 | glGenTextures(1, &_heightTextureID); | ||
| 2077 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); | ||
| 2078 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 2079 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 2080 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2081 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2082 | |||
| 2083 | glGenTextures(1, &_colorTextureID); | ||
| 2084 | glBindTexture(GL_TEXTURE_2D, _colorTextureID); | ||
| 2085 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| 2086 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2087 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2088 | |||
| 2089 | glGenTextures(1, &_materialTextureID); | ||
| 2090 | glBindTexture(GL_TEXTURE_2D, _materialTextureID); | ||
| 2091 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 2092 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 2093 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2094 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2095 | |||
| 2096 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2097 | } | 2097 | } |
| 2098 | 2098 | ||
| 2099 | HeightfieldRenderer::~HeightfieldRenderer() { | 2099 | const int X_MAXIMUM_FLAG = 1; |
| 2100 | glDeleteTextures(1, &_heightTextureID); | 2100 | const int Y_MAXIMUM_FLAG = 2; |
| 2101 | glDeleteTextures(1, &_colorTextureID); | 2101 | |
| 2102 | glDeleteTextures(1, &_materialTextureID); | 2102 | static void renderNode(const HeightfieldNodePointer& node, Heightfield* heightfield, const MetavoxelLOD& lod, |
| 2103 | const glm::vec2& minimum, float size, bool contained, bool cursor) { | ||
| 2104 | const glm::quat& rotation = heightfield->getRotation(); | ||
| 2105 | glm::vec3 scale(heightfield->getScale() * size, heightfield->getScale() * heightfield->getAspectY(), | ||
| 2106 | heightfield->getScale() * heightfield->getAspectZ() * size); | ||
| 2107 | glm::vec3 translation = heightfield->getTranslation() + rotation * glm::vec3(minimum.x * heightfield->getScale(), | ||
| 2108 | 0.0f, minimum.y * heightfield->getScale() * heightfield->getAspectZ()); | ||
| 2109 | if (!contained) { | ||
| 2110 | Frustum::IntersectionType type = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType( | ||
| 2111 | glm::translate(translation) * glm::mat4_cast(rotation) * Box(glm::vec3(), scale)); | ||
| 2112 | if (type == Frustum::NO_INTERSECTION) { | ||
| 2113 | return; | ||
| 2114 | } | ||
| 2115 | if (type == Frustum::CONTAINS_INTERSECTION) { | ||
| 2116 | contained = true; | ||
| 2117 | } | ||
| 2118 | } | ||
| 2119 | if (!node->isLeaf() && lod.shouldSubdivide(minimum, size)) { | ||
| 2120 | float nextSize = size * 0.5f; | ||
| 2121 | for (int i = 0; i < HeightfieldNode::CHILD_COUNT; i++) { | ||
| 2122 | renderNode(node->getChild(i), heightfield, lod, minimum + glm::vec2(i & X_MAXIMUM_FLAG ? nextSize : 0.0f, | ||
| 2123 | i & Y_MAXIMUM_FLAG ? nextSize : 0.0f), nextSize, contained, cursor); | ||
| 2124 | } | ||
| 2125 | return; | ||
| 2126 | } | ||
| 2127 | HeightfieldNodeRenderer* renderer = static_cast<HeightfieldNodeRenderer*>(node->getRenderer()); | ||
| 2128 | if (!renderer) { | ||
| 2129 | node->setRenderer(renderer = new HeightfieldNodeRenderer()); | ||
| 2130 | } | ||
| 2131 | renderer->render(node, translation, rotation, scale, cursor); | ||
| 2103 | } | 2132 | } |
| 2104 | 2133 | ||
| 2105 | void HeightfieldRenderer::init(Spanner* spanner) { | 2134 | void HeightfieldRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) { |
| 2106 | SpannerRenderer::init(spanner); | 2135 | Heightfield* heightfield = static_cast<Heightfield*>(_spanner); |
| 2107 | 2136 | renderNode(heightfield->getRoot(), heightfield, heightfield->transformLOD(lod), glm::vec2(), 1.0f, contained, cursor); | |
| 2108 | Heightfield* heightfield = static_cast<Heightfield*>(spanner); | ||
| 2109 | applyHeight(heightfield->getHeight()); | ||
| 2110 | applyColor(heightfield->getColor()); | ||
| 2111 | applyMaterial(heightfield->getMaterial()); | ||
| 2112 | |||
| 2113 | connect(heightfield, &Heightfield::heightChanged, this, &HeightfieldRenderer::applyHeight); | ||
| 2114 | connect(heightfield, &Heightfield::colorChanged, this, &HeightfieldRenderer::applyColor); | ||
| 2115 | connect(heightfield, &Heightfield::materialChanged, this, &HeightfieldRenderer::applyMaterial); | ||
| 2116 | } | 2137 | } |
| 2117 | 2138 | ||
| 2118 | void HeightfieldRenderer::render(bool cursor) { | 2139 | HeightfieldNodeRenderer::HeightfieldNodeRenderer() : |
| 2119 | // create the buffer objects lazily | 2140 | _heightTextureID(0), |
| 2120 | Heightfield* heightfield = static_cast<Heightfield*>(_spanner); | 2141 | _colorTextureID(0), |
| 2121 | if (!heightfield->getHeight()) { | 2142 | _materialTextureID(0) { |
| 2143 | } | ||
| 2144 | |||
| 2145 | HeightfieldNodeRenderer::~HeightfieldNodeRenderer() { | ||
| 2146 | QMetaObject::invokeMethod(Application::getInstance()->getMetavoxels(), "deleteTextures", Q_ARG(int, _heightTextureID), | ||
| 2147 | Q_ARG(int, _colorTextureID), Q_ARG(int, _materialTextureID)); | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const glm::vec3& translation, | ||
| 2151 | const glm::quat& rotation, const glm::vec3& scale, bool cursor) { | ||
| 2152 | if (!node->getHeight()) { | ||
| 2122 | return; | 2153 | return; |
| 2123 | } | 2154 | } |
| 2124 | int width = heightfield->getHeight()->getWidth(); | 2155 | int width = node->getHeight()->getWidth(); |
| 2125 | int height = heightfield->getHeight()->getContents().size() / width; | 2156 | int height = node->getHeight()->getContents().size() / width; |
| 2126 | |||
| 2127 | int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER; | 2157 | int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER; |
| 2128 | int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER; | 2158 | int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER; |
| 2129 | int vertexCount = width * height; | 2159 | int vertexCount = width * height; |
| @@ -2180,17 +2210,71 @@ void HeightfieldRenderer::render(bool cursor) { · 50 unmodified lines | |||
| 2180 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); | 2210 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); |
| 2181 | bufferPair.second.release(); | 2211 | bufferPair.second.release(); |
| 2182 | } | 2212 | } |
| 2213 | if (_heightTextureID == 0) { | ||
| 2214 | glGenTextures(1, &_heightTextureID); | ||
| 2215 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); | ||
| 2216 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 2217 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 2218 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2219 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2220 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
| 2221 | const QVector<quint16>& heightContents = node->getHeight()->getContents(); | ||
| 2222 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width, height, 0, | ||
| 2223 | GL_RED, GL_UNSIGNED_SHORT, heightContents.constData()); | ||
| 2224 | |||
| 2225 | glGenTextures(1, &_colorTextureID); | ||
| 2226 | glBindTexture(GL_TEXTURE_2D, _colorTextureID); | ||
| 2227 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| 2228 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2229 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2230 | if (node->getColor()) { | ||
| 2231 | const QByteArray& contents = node->getColor()->getContents(); | ||
| 2232 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, node->getColor()->getWidth(), | ||
| 2233 | contents.size() / (node->getColor()->getWidth() * DataBlock::COLOR_BYTES), | ||
| 2234 | 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData()); | ||
| 2235 | |||
| 2236 | } else { | ||
| 2237 | const quint8 WHITE_COLOR[] = { 255, 255, 255 }; | ||
| 2238 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR); | ||
| 2239 | } | ||
| 2240 | |||
| 2241 | glGenTextures(1, &_materialTextureID); | ||
| 2242 | glBindTexture(GL_TEXTURE_2D, _materialTextureID); | ||
| 2243 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 2244 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 2245 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
| 2246 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
| 2247 | if (node->getMaterial()) { | ||
| 2248 | const QByteArray& contents = node->getMaterial()->getContents(); | ||
| 2249 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, node->getMaterial()->getWidth(), | ||
| 2250 | contents.size() / node->getMaterial()->getWidth(), | ||
| 2251 | 0, GL_RED, GL_UNSIGNED_BYTE, contents.constData()); | ||
| 2252 | |||
| 2253 | const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials(); | ||
| 2254 | _networkTextures.resize(materials.size()); | ||
| 2255 | for (int i = 0; i < materials.size(); i++) { | ||
| 2256 | const SharedObjectPointer& material = materials.at(i); | ||
| 2257 | if (material) { | ||
| 2258 | _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture( | ||
| 2259 | static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE); | ||
| 2260 | } | ||
| 2261 | } | ||
| 2262 | } else { | ||
| 2263 | const quint8 ZERO_VALUE = 0; | ||
| 2264 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE); | ||
| 2265 | } | ||
| 2266 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2267 | } | ||
| 2183 | 2268 | ||
| 2184 | float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ(); | ||
| 2185 | if (cursor) { | 2269 | if (cursor) { |
| 2186 | bufferPair.first.bind(); | 2270 | bufferPair.first.bind(); |
| 2187 | bufferPair.second.bind(); | 2271 | bufferPair.second.bind(); |
| 2188 | 2272 | ||
| 2189 | glPushMatrix(); | 2273 | glPushMatrix(); |
| 2190 | glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z); | 2274 | glTranslatef(translation.x, translation.y, translation.z); |
| 2191 | glm::vec3 axis = glm::axis(heightfield->getRotation()); | 2275 | glm::vec3 axis = glm::axis(rotation); |
| 2192 | glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z); | 2276 | glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); |
| 2193 | glScalef(xScale, xScale * heightfield->getAspectY(), zScale); | 2277 | glScalef(scale.x, scale.y, scale.z); |
| 2194 | 2278 | ||
| 2195 | HeightfieldPoint* point = 0; | 2279 | HeightfieldPoint* point = 0; |
| 2196 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | 2280 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); |
| @@ -2208,13 +2292,12 @@ void HeightfieldRenderer::render(bool cursor) { · 11 unmodified lines | |||
| 2208 | bufferPair.second.release(); | 2292 | bufferPair.second.release(); |
| 2209 | return; | 2293 | return; |
| 2210 | } | 2294 | } |
| 2211 | |||
| 2212 | HeightfieldBaseLayerBatch baseBatch; | 2295 | HeightfieldBaseLayerBatch baseBatch; |
| 2213 | baseBatch.vertexBuffer = &bufferPair.first; | 2296 | baseBatch.vertexBuffer = &bufferPair.first; |
| 2214 | baseBatch.indexBuffer = &bufferPair.second; | 2297 | baseBatch.indexBuffer = &bufferPair.second; |
| 2215 | baseBatch.translation = heightfield->getTranslation(); | 2298 | baseBatch.translation = translation; |
| 2216 | baseBatch.rotation = heightfield->getRotation(); | 2299 | baseBatch.rotation = rotation; |
| 2217 | baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); | 2300 | baseBatch.scale = scale; |
| 2218 | baseBatch.vertexCount = vertexCount; | 2301 | baseBatch.vertexCount = vertexCount; |
| 2219 | baseBatch.indexCount = indexCount; | 2302 | baseBatch.indexCount = indexCount; |
| 2220 | baseBatch.heightTextureID = _heightTextureID; | 2303 | baseBatch.heightTextureID = _heightTextureID; |
| @@ -2223,13 +2306,13 @@ void HeightfieldRenderer::render(bool cursor) { · 2 unmodified lines | |||
| 2223 | baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); | 2306 | baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); |
| 2224 | Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); | 2307 | Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); |
| 2225 | 2308 | ||
| 2226 | if (heightfield->getMaterial() && !_networkTextures.isEmpty()) { | 2309 | if (!_networkTextures.isEmpty()) { |
| 2227 | HeightfieldSplatBatch splatBatch; | 2310 | HeightfieldSplatBatch splatBatch; |
| 2228 | splatBatch.vertexBuffer = &bufferPair.first; | 2311 | splatBatch.vertexBuffer = &bufferPair.first; |
| 2229 | splatBatch.indexBuffer = &bufferPair.second; | 2312 | splatBatch.indexBuffer = &bufferPair.second; |
| 2230 | splatBatch.translation = heightfield->getTranslation(); | 2313 | splatBatch.translation = translation; |
| 2231 | splatBatch.rotation = heightfield->getRotation(); | 2314 | splatBatch.rotation = rotation; |
| 2232 | splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); | 2315 | splatBatch.scale = scale; |
| 2233 | splatBatch.vertexCount = vertexCount; | 2316 | splatBatch.vertexCount = vertexCount; |
| 2234 | splatBatch.indexCount = indexCount; | 2317 | splatBatch.indexCount = indexCount; |
| 2235 | splatBatch.heightTextureID = _heightTextureID; | 2318 | splatBatch.heightTextureID = _heightTextureID; |
| @@ -2237,10 +2320,10 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line | |||
| 2237 | splatBatch.materialTextureID = _materialTextureID; | 2320 | splatBatch.materialTextureID = _materialTextureID; |
| 2238 | splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); | 2321 | splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); |
| 2239 | splatBatch.splatTextureOffset = glm::vec2( | 2322 | splatBatch.splatTextureOffset = glm::vec2( |
| 2240 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale, | 2323 | glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x, |
| 2241 | glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale); | 2324 | glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z); |
| 2242 | 2325 | ||
| 2243 | const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials(); | 2326 | const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials(); |
| 2244 | for (int i = 0; i < materials.size(); i += SPLAT_COUNT) { | 2327 | for (int i = 0; i < materials.size(); i += SPLAT_COUNT) { |
| 2245 | for (int j = 0; j < SPLAT_COUNT; j++) { | 2328 | for (int j = 0; j < SPLAT_COUNT; j++) { |
| 2246 | int index = i + j; | 2329 | int index = i + j; |
| @@ -2248,8 +2331,8 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line | |||
| 2248 | const NetworkTexturePointer& texture = _networkTextures.at(index); | 2331 | const NetworkTexturePointer& texture = _networkTextures.at(index); |
| 2249 | if (texture) { | 2332 | if (texture) { |
| 2250 | MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data()); | 2333 | MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data()); |
| 2251 | splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS(); | 2334 | splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS(); |
| 2252 | splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT(); | 2335 | splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT(); |
| 2253 | splatBatch.splatTextureIDs[j] = texture->getID(); | 2336 | splatBatch.splatTextureIDs[j] = texture->getID(); |
| 2254 | 2337 | ||
| 2255 | } else { | 2338 | } else { |
| @@ -2265,62 +2348,5 @@ void HeightfieldRenderer::render(bool cursor) { · 9 unmodified lines | |||
| 2265 | } | 2348 | } |
| 2266 | } | 2349 | } |
| 2267 | 2350 | ||
| 2268 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { | 2351 | QHash<HeightfieldNodeRenderer::IntPair, HeightfieldNodeRenderer::BufferPair> HeightfieldNodeRenderer::_bufferPairs; |
| 2269 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
| 2270 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); | ||
| 2271 | if (height) { | ||
| 2272 | const QVector<quint16>& contents = height->getContents(); | ||
| 2273 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, height->getWidth(), contents.size() / height->getWidth(), 0, | ||
| 2274 | GL_RED, GL_UNSIGNED_SHORT, contents.constData()); | ||
| 2275 | |||
| 2276 | } else { | ||
| 2277 | const quint16 ZERO_VALUE = 0; | ||
| 2278 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, 1, 1, 0, GL_RED, GL_UNSIGNED_SHORT, &ZERO_VALUE); | ||
| 2279 | } | ||
| 2280 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | void HeightfieldRenderer::applyColor(const HeightfieldColorPointer& color) { | ||
| 2284 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
| 2285 | glBindTexture(GL_TEXTURE_2D, _colorTextureID); | ||
| 2286 | if (color) { | ||
| 2287 | const QByteArray& contents = color->getContents(); | ||
| 2288 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, color->getWidth(), | ||
| 2289 | contents.size() / (color->getWidth() * DataBlock::COLOR_BYTES), 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData()); | ||
| 2290 | |||
| 2291 | } else { | ||
| 2292 | const quint8 WHITE_COLOR[] = { 255, 255, 255 }; | ||
| 2293 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR); | ||
| 2294 | } | ||
| 2295 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2296 | } | ||
| 2297 | |||
| 2298 | void HeightfieldRenderer::applyMaterial(const HeightfieldMaterialPointer& material) { | ||
| 2299 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
| 2300 | glBindTexture(GL_TEXTURE_2D, _materialTextureID); | ||
| 2301 | if (material) { | ||
| 2302 | const QByteArray& contents = material->getContents(); | ||
| 2303 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, material->getWidth(), contents.size() / material->getWidth(), 0, | ||
| 2304 | GL_RED, GL_UNSIGNED_BYTE, contents.constData()); | ||
| 2305 | |||
| 2306 | const QVector<SharedObjectPointer>& materials = material->getMaterials(); | ||
| 2307 | _networkTextures.resize(materials.size()); | ||
| 2308 | for (int i = 0; i < materials.size(); i++) { | ||
| 2309 | const SharedObjectPointer& material = materials.at(i); | ||
| 2310 | if (material) { | ||
| 2311 | _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture( | ||
| 2312 | static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE); | ||
| 2313 | } else { | ||
| 2314 | _networkTextures[i].clear(); | ||
| 2315 | } | ||
| 2316 | } | ||
| 2317 | } else { | ||
| 2318 | const quint8 ZERO_VALUE = 0; | ||
| 2319 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE); | ||
| 2320 | _networkTextures.clear(); | ||
| 2321 | } | ||
| 2322 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs; | ||
| 2326 | 2352 | ||