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 | 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 | 492 | // give external parties a chance to join in |
| 465 | 493 | emit rendering(); |
| 466 | 494 | } |
| @@ -550,10 +578,53 @@ void MetavoxelSystem::setVoxelMaterial(const SharedObjectPointer& spanner, const · 83 unmodified lines | ||
| 550 | 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 | 625 | public: |
| 555 | 626 | |
| 556 | − SpannerCursorRenderVisitor(const Box& bounds); | |
| 627 | + SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds); | |
| 557 | 628 | |
| 558 | 629 | virtual bool visit(Spanner* spanner); |
| 559 | 630 | |
| @@ -564,20 +635,20 @@ private: · 4 unmodified lines | ||
| 564 | 635 | Box _bounds; |
| 565 | 636 | }; |
| 566 | 637 | |
| 567 | −SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const Box& bounds) : | |
| 568 | − SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute()), | |
| 638 | +SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) : | |
| 639 | + SpannerRenderVisitor(lod), | |
| 569 | 640 | _bounds(bounds) { |
| 570 | 641 | } |
| 571 | 642 | |
| 572 | 643 | bool SpannerCursorRenderVisitor::visit(Spanner* spanner) { |
| 573 | 644 | if (spanner->isHeightfield()) { |
| 574 | − spanner->getRenderer()->render(true); | |
| 645 | + spanner->getRenderer()->render(_lod, _containmentDepth <= _depth, true); | |
| 575 | 646 | } |
| 576 | 647 | return true; |
| 577 | 648 | } |
| 578 | 649 | |
| 579 | 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 | 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 | 675 | glActiveTexture(GL_TEXTURE0); |
| 605 | 676 | |
| 606 | 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 | 679 | guide(visitor); |
| 609 | 680 | |
| 610 | 681 | _heightfieldCursorProgram.release(); |
| @@ -678,7 +749,7 @@ void MetavoxelSystem::renderVoxelCursor(const glm::vec3& position, float radius) · 67 unmodified lines | ||
| 678 | 749 | |
| 679 | 750 | _heightfieldCursorProgram.bind(); |
| 680 | 751 | |
| 681 | − SpannerCursorRenderVisitor spannerVisitor(bounds); | |
| 752 | + SpannerCursorRenderVisitor spannerVisitor(getLOD(), bounds); | |
| 682 | 753 | guide(spannerVisitor); |
| 683 | 754 | |
| 684 | 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 | 1267 | if (!_hermiteBuffer.isCreated()) { |
| 1197 | 1268 | _hermiteBuffer.create(); |
| 1198 | 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 | 1272 | _hermite.clear(); |
| 1201 | − | |
| 1202 | − } else { | |
| 1203 | − _hermiteBuffer.bind(); | |
| 1204 | 1273 | } |
| 1205 | − | |
| 1206 | − glVertexPointer(3, GL_FLOAT, 0, 0); | |
| 1207 | − | |
| 1208 | − Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); | |
| 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(); | |
| 1274 | + HermiteBatch hermiteBatch; | |
| 1275 | + hermiteBatch.vertexBuffer = &_hermiteBuffer; | |
| 1276 | + hermiteBatch.vertexCount = _hermiteCount; | |
| 1277 | + Application::getInstance()->getMetavoxels()->addHermiteBatch(hermiteBatch); | |
| 1220 | 1278 | } |
| 1221 | 1279 | } |
| 1222 | 1280 | |
| @@ -1880,43 +1938,6 @@ void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float · 657 unmodified lines | ||
| 1880 | 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 | 1941 | class BufferRenderVisitor : public MetavoxelVisitor { |
| 1921 | 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 | 1995 | Sphere* sphere = static_cast<Sphere*>(_spanner); |
| 1975 | 1996 | const QColor& color = sphere->getColor(); |
| 1976 | 1997 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); |
| @@ -1990,7 +2011,7 @@ void SphereRenderer::render(bool cursor) { · 13 unmodified lines | ||
| 1990 | 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 | 2015 | Cuboid* cuboid = static_cast<Cuboid*>(_spanner); |
| 1995 | 2016 | const QColor& color = cuboid->getColor(); |
| 1996 | 2017 | glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); |
| @@ -2041,7 +2062,7 @@ void StaticModelRenderer::simulate(float deltaTime) { · 44 unmodified lines | ||
| 2041 | 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 | 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 | 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() { | |
| 2100 | − glDeleteTextures(1, &_heightTextureID); | |
| 2101 | − glDeleteTextures(1, &_colorTextureID); | |
| 2102 | − glDeleteTextures(1, &_materialTextureID); | |
| 2099 | +const int X_MAXIMUM_FLAG = 1; | |
| 2100 | +const int Y_MAXIMUM_FLAG = 2; | |
| 2101 | + | |
| 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) { | |
| 2106 | − SpannerRenderer::init(spanner); | |
| 2107 | − | |
| 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); | |
| 2134 | +void HeightfieldRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) { | |
| 2135 | + Heightfield* heightfield = static_cast<Heightfield*>(_spanner); | |
| 2136 | + renderNode(heightfield->getRoot(), heightfield, heightfield->transformLOD(lod), glm::vec2(), 1.0f, contained, cursor); | |
| 2116 | 2137 | } |
| 2117 | 2138 | |
| 2118 | −void HeightfieldRenderer::render(bool cursor) { | |
| 2119 | − // create the buffer objects lazily | |
| 2120 | − Heightfield* heightfield = static_cast<Heightfield*>(_spanner); | |
| 2121 | − if (!heightfield->getHeight()) { | |
| 2139 | +HeightfieldNodeRenderer::HeightfieldNodeRenderer() : | |
| 2140 | + _heightTextureID(0), | |
| 2141 | + _colorTextureID(0), | |
| 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 | 2153 | return; |
| 2123 | 2154 | } |
| 2124 | − int width = heightfield->getHeight()->getWidth(); | |
| 2125 | − int height = heightfield->getHeight()->getContents().size() / width; | |
| 2126 | − | |
| 2155 | + int width = node->getHeight()->getWidth(); | |
| 2156 | + int height = node->getHeight()->getContents().size() / width; | |
| 2127 | 2157 | int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER; |
| 2128 | 2158 | int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER; |
| 2129 | 2159 | int vertexCount = width * height; |
| @@ -2180,17 +2210,71 @@ void HeightfieldRenderer::render(bool cursor) { · 50 unmodified lines | ||
| 2180 | 2210 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); |
| 2181 | 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 | 2269 | if (cursor) { |
| 2186 | 2270 | bufferPair.first.bind(); |
| 2187 | 2271 | bufferPair.second.bind(); |
| 2188 | 2272 | |
| 2189 | 2273 | glPushMatrix(); |
| 2190 | − glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z); | |
| 2191 | − glm::vec3 axis = glm::axis(heightfield->getRotation()); | |
| 2192 | − glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z); | |
| 2193 | − glScalef(xScale, xScale * heightfield->getAspectY(), zScale); | |
| 2274 | + glTranslatef(translation.x, translation.y, translation.z); | |
| 2275 | + glm::vec3 axis = glm::axis(rotation); | |
| 2276 | + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); | |
| 2277 | + glScalef(scale.x, scale.y, scale.z); | |
| 2194 | 2278 | |
| 2195 | 2279 | HeightfieldPoint* point = 0; |
| 2196 | 2280 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); |
| @@ -2208,13 +2292,12 @@ void HeightfieldRenderer::render(bool cursor) { · 11 unmodified lines | ||
| 2208 | 2292 | bufferPair.second.release(); |
| 2209 | 2293 | return; |
| 2210 | 2294 | } |
| 2211 | − | |
| 2212 | 2295 | HeightfieldBaseLayerBatch baseBatch; |
| 2213 | 2296 | baseBatch.vertexBuffer = &bufferPair.first; |
| 2214 | 2297 | baseBatch.indexBuffer = &bufferPair.second; |
| 2215 | − baseBatch.translation = heightfield->getTranslation(); | |
| 2216 | − baseBatch.rotation = heightfield->getRotation(); | |
| 2217 | − baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); | |
| 2298 | + baseBatch.translation = translation; | |
| 2299 | + baseBatch.rotation = rotation; | |
| 2300 | + baseBatch.scale = scale; | |
| 2218 | 2301 | baseBatch.vertexCount = vertexCount; |
| 2219 | 2302 | baseBatch.indexCount = indexCount; |
| 2220 | 2303 | baseBatch.heightTextureID = _heightTextureID; |
| @@ -2223,13 +2306,13 @@ void HeightfieldRenderer::render(bool cursor) { · 2 unmodified lines | ||
| 2223 | 2306 | baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); |
| 2224 | 2307 | Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); |
| 2225 | 2308 | |
| 2226 | − if (heightfield->getMaterial() && !_networkTextures.isEmpty()) { | |
| 2309 | + if (!_networkTextures.isEmpty()) { | |
| 2227 | 2310 | HeightfieldSplatBatch splatBatch; |
| 2228 | 2311 | splatBatch.vertexBuffer = &bufferPair.first; |
| 2229 | 2312 | splatBatch.indexBuffer = &bufferPair.second; |
| 2230 | − splatBatch.translation = heightfield->getTranslation(); | |
| 2231 | − splatBatch.rotation = heightfield->getRotation(); | |
| 2232 | − splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale); | |
| 2313 | + splatBatch.translation = translation; | |
| 2314 | + splatBatch.rotation = rotation; | |
| 2315 | + splatBatch.scale = scale; | |
| 2233 | 2316 | splatBatch.vertexCount = vertexCount; |
| 2234 | 2317 | splatBatch.indexCount = indexCount; |
| 2235 | 2318 | splatBatch.heightTextureID = _heightTextureID; |
| @@ -2237,10 +2320,10 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line | ||
| 2237 | 2320 | splatBatch.materialTextureID = _materialTextureID; |
| 2238 | 2321 | splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); |
| 2239 | 2322 | splatBatch.splatTextureOffset = glm::vec2( |
| 2240 | − glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale, | |
| 2241 | − glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale); | |
| 2323 | + glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x, | |
| 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 | 2327 | for (int i = 0; i < materials.size(); i += SPLAT_COUNT) { |
| 2245 | 2328 | for (int j = 0; j < SPLAT_COUNT; j++) { |
| 2246 | 2329 | int index = i + j; |
| @@ -2248,8 +2331,8 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line | ||
| 2248 | 2331 | const NetworkTexturePointer& texture = _networkTextures.at(index); |
| 2249 | 2332 | if (texture) { |
| 2250 | 2333 | MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data()); |
| 2251 | − splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS(); | |
| 2252 | − splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT(); | |
| 2334 | + splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS(); | |
| 2335 | + splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT(); | |
| 2253 | 2336 | splatBatch.splatTextureIDs[j] = texture->getID(); |
| 2254 | 2337 | |
| 2255 | 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) { | |
| 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; | |
| 2351 | +QHash<HeightfieldNodeRenderer::IntPair, HeightfieldNodeRenderer::BufferPair> HeightfieldNodeRenderer::_bufferPairs; | |
| 2326 | 2352 | |