Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 6 files). Show all
Unified · Split
| @@ -31,6 +31,10 @@ REGISTER_META_OBJECT(StaticModelRenderer) · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>(); |
| 33 | 33 | |
| 34 | +MetavoxelSystem::MetavoxelSystem() : | |
| 35 | + _cursorTexture(QOpenGLTexture::Target2D) { | |
| 36 | +} | |
| 37 | + | |
| 34 | 38 | void MetavoxelSystem::init() { |
| 35 | 39 | MetavoxelClientManager::init(); |
| 36 | 40 | DefaultMetavoxelRendererImplementation::init(); |
| @@ -118,6 +122,105 @@ void MetavoxelSystem::render() { · 81 unmodified lines | ||
| 118 | 122 | guideToAugmented(renderVisitor); |
| 119 | 123 | } |
| 120 | 124 | |
| 125 | +class HeightfieldCursorRenderVisitor : public MetavoxelVisitor { | |
| 126 | +public: | |
| 127 | + | |
| 128 | + HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds); | |
| 129 | + | |
| 130 | + virtual int visit(MetavoxelInfo& info); | |
| 131 | + | |
| 132 | +private: | |
| 133 | + | |
| 134 | + Box _bounds; | |
| 135 | +}; | |
| 136 | + | |
| 137 | +HeightfieldCursorRenderVisitor::HeightfieldCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) : | |
| 138 | + MetavoxelVisitor(QVector<AttributePointer>() << | |
| 139 | + Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), QVector<AttributePointer>(), lod), | |
| 140 | + _bounds(bounds) { | |
| 141 | +} | |
| 142 | + | |
| 143 | +int HeightfieldCursorRenderVisitor::visit(MetavoxelInfo& info) { | |
| 144 | + if (!info.getBounds().intersects(_bounds)) { | |
| 145 | + return STOP_RECURSION; | |
| 146 | + } | |
| 147 | + if (!info.isLeaf) { | |
| 148 | + return DEFAULT_ORDER; | |
| 149 | + } | |
| 150 | + BufferDataPointer buffer = info.inputValues.at(0).getInlineValue<BufferDataPointer>(); | |
| 151 | + if (buffer) { | |
| 152 | + buffer->render(true); | |
| 153 | + } | |
| 154 | + return STOP_RECURSION; | |
| 155 | +} | |
| 156 | + | |
| 157 | +void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float radius) { | |
| 158 | + // create the cursor texture lazily | |
| 159 | + if (!_cursorTexture.isCreated()) { | |
| 160 | + const int CURSOR_TEXTURE_SIZE = 512; | |
| 161 | + QImage cursorImage(CURSOR_TEXTURE_SIZE, CURSOR_TEXTURE_SIZE, QImage::Format_ARGB32_Premultiplied); | |
| 162 | + cursorImage.fill(0x0); | |
| 163 | + { | |
| 164 | + QPainter painter(&cursorImage); | |
| 165 | + const int ELLIPSE_EDGE = 10; | |
| 166 | + const int OUTER_WIDTH = 10; | |
| 167 | + QPen outerPen; | |
| 168 | + outerPen.setWidth(OUTER_WIDTH); | |
| 169 | + painter.setPen(outerPen); | |
| 170 | + const int HALF_TEXTURE_SIZE = CURSOR_TEXTURE_SIZE / 2; | |
| 171 | + painter.drawEllipse(QPoint(HALF_TEXTURE_SIZE, HALF_TEXTURE_SIZE), HALF_TEXTURE_SIZE - ELLIPSE_EDGE, | |
| 172 | + HALF_TEXTURE_SIZE - ELLIPSE_EDGE); | |
| 173 | + QPen innerPen(Qt::white); | |
| 174 | + const int INNER_WIDTH = 6; | |
| 175 | + innerPen.setWidth(INNER_WIDTH); | |
| 176 | + painter.setPen(innerPen); | |
| 177 | + painter.drawEllipse(QPoint(HALF_TEXTURE_SIZE, HALF_TEXTURE_SIZE), HALF_TEXTURE_SIZE - ELLIPSE_EDGE, | |
| 178 | + HALF_TEXTURE_SIZE - ELLIPSE_EDGE); | |
| 179 | + } | |
| 180 | + _cursorTexture.setData(cursorImage, QOpenGLTexture::DontGenerateMipMaps); | |
| 181 | + _cursorTexture.setWrapMode(QOpenGLTexture::ClampToEdge); | |
| 182 | + _cursorTexture.setMinificationFilter(QOpenGLTexture::Linear); | |
| 183 | + } | |
| 184 | + | |
| 185 | + glDepthFunc(GL_LEQUAL); | |
| 186 | + glEnable(GL_CULL_FACE); | |
| 187 | + glEnable(GL_POLYGON_OFFSET_FILL); | |
| 188 | + glPolygonOffset(-1.0f, -1.0f); | |
| 189 | + | |
| 190 | + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |
| 191 | + | |
| 192 | + glEnableClientState(GL_VERTEX_ARRAY); | |
| 193 | + glEnableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 194 | + | |
| 195 | + DefaultMetavoxelRendererImplementation::getHeightfieldCursorProgram().bind(); | |
| 196 | + | |
| 197 | + glActiveTexture(GL_TEXTURE4); | |
| 198 | + float scale = 1.0f / radius; | |
| 199 | + glm::vec4 sCoefficients(scale, 0.0f, 0.0f, 0.5f - scale * position.x); | |
| 200 | + glm::vec4 tCoefficients(0.0f, 0.0f, scale, 0.5f - scale * position.z); | |
| 201 | + glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&sCoefficients); | |
| 202 | + glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&tCoefficients); | |
| 203 | + | |
| 204 | + _cursorTexture.bind(1); | |
| 205 | + glActiveTexture(GL_TEXTURE0); | |
| 206 | + | |
| 207 | + glm::vec3 extents(radius, radius, radius); | |
| 208 | + HeightfieldCursorRenderVisitor visitor(getLOD(), Box(position - extents, position + extents)); | |
| 209 | + guideToAugmented(visitor); | |
| 210 | + | |
| 211 | + _cursorTexture.release(1); | |
| 212 | + glActiveTexture(GL_TEXTURE0); | |
| 213 | + | |
| 214 | + DefaultMetavoxelRendererImplementation::getHeightfieldCursorProgram().release(); | |
| 215 | + | |
| 216 | + glDisableClientState(GL_TEXTURE_COORD_ARRAY); | |
| 217 | + glDisableClientState(GL_VERTEX_ARRAY); | |
| 218 | + | |
| 219 | + glDisable(GL_POLYGON_OFFSET_FILL); | |
| 220 | + glDisable(GL_CULL_FACE); | |
| 221 | + glDepthFunc(GL_LESS); | |
| 222 | +} | |
| 223 | + | |
| 121 | 224 | void MetavoxelSystem::deleteTextures(int heightID, int colorID) { |
| 122 | 225 | glDeleteTextures(1, (GLuint*)&heightID); |
| 123 | 226 | glDeleteTextures(1, (GLuint*)&colorID); |
| @@ -239,7 +342,7 @@ PointBuffer::PointBuffer(const BufferPointVector& points) : · 115 unmodified lines | ||
| 239 | 342 | _points(points) { |
| 240 | 343 | } |
| 241 | 344 | |
| 242 | −void PointBuffer::render() { | |
| 345 | +void PointBuffer::render(bool cursor) { | |
| 243 | 346 | // initialize buffer, etc. on first render |
| 244 | 347 | if (!_buffer.isCreated()) { |
| 245 | 348 | _buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
| @@ -294,7 +397,7 @@ public: · 48 unmodified lines | ||
| 294 | 397 | glm::vec3 vertex; |
| 295 | 398 | }; |
| 296 | 399 | |
| 297 | −void HeightfieldBuffer::render() { | |
| 400 | +void HeightfieldBuffer::render(bool cursor) { | |
| 298 | 401 | // initialize textures, etc. on first render |
| 299 | 402 | if (_heightTextureID == 0) { |
| 300 | 403 | glGenTextures(1, &_heightTextureID); |
| @@ -385,17 +488,24 @@ void HeightfieldBuffer::render() { · 84 unmodified lines | ||
| 385 | 488 | |
| 386 | 489 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); |
| 387 | 490 | |
| 388 | − glActiveTexture(GL_TEXTURE1); | |
| 389 | − glBindTexture(GL_TEXTURE_2D, _colorTextureID); | |
| 491 | + int heightScaleLocation; | |
| 492 | + if (cursor) { | |
| 493 | + heightScaleLocation = DefaultMetavoxelRendererImplementation::getCursorHeightScaleLocation(); | |
| 494 | + } else { | |
| 495 | + heightScaleLocation = DefaultMetavoxelRendererImplementation::getHeightScaleLocation(); | |
| 496 | + glActiveTexture(GL_TEXTURE1); | |
| 497 | + glBindTexture(GL_TEXTURE_2D, _colorTextureID); | |
| 498 | + } | |
| 390 | 499 | |
| 391 | − DefaultMetavoxelRendererImplementation::getHeightfieldProgram().setUniformValue( | |
| 392 | − DefaultMetavoxelRendererImplementation::getHeightScaleLocation(), 1.0f / _heightSize); | |
| 500 | + DefaultMetavoxelRendererImplementation::getHeightfieldProgram().setUniformValue(heightScaleLocation, 1.0f / _heightSize); | |
| 393 | 501 | |
| 394 | 502 | glDrawRangeElements(GL_QUADS, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); |
| 395 | 503 | |
| 396 | − glBindTexture(GL_TEXTURE_2D, 0); | |
| 504 | + if (!cursor) { | |
| 505 | + glBindTexture(GL_TEXTURE_2D, 0); | |
| 506 | + glActiveTexture(GL_TEXTURE0); | |
| 507 | + } | |
| 397 | 508 | |
| 398 | − glActiveTexture(GL_TEXTURE0); | |
| 399 | 509 | glBindTexture(GL_TEXTURE_2D, 0); |
| 400 | 510 | |
| 401 | 511 | glPopMatrix(); |
| @@ -475,6 +585,18 @@ void DefaultMetavoxelRendererImplementation::init() { · 73 unmodified lines | ||
| 475 | 585 | _heightfieldProgram.setUniformValue("diffuseMap", 1); |
| 476 | 586 | _heightScaleLocation = _heightfieldProgram.uniformLocation("heightScale"); |
| 477 | 587 | _heightfieldProgram.release(); |
| 588 | + | |
| 589 | + _heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + | |
| 590 | + "shaders/metavoxel_heightfield_cursor.vert"); | |
| 591 | + _heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + | |
| 592 | + "shaders/metavoxel_heightfield_cursor.frag"); | |
| 593 | + _heightfieldCursorProgram.link(); | |
| 594 | + | |
| 595 | + _heightfieldCursorProgram.bind(); | |
| 596 | + _heightfieldCursorProgram.setUniformValue("heightMap", 0); | |
| 597 | + _heightfieldCursorProgram.setUniformValue("cursorMap", 1); | |
| 598 | + _cursorHeightScaleLocation = _heightfieldCursorProgram.uniformLocation("heightScale"); | |
| 599 | + _heightfieldCursorProgram.release(); | |
| 478 | 600 | } |
| 479 | 601 | } |
| 480 | 602 | |
| @@ -771,6 +893,8 @@ ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram; · 290 unmodified lines | ||
| 771 | 893 | int DefaultMetavoxelRendererImplementation::_pointScaleLocation; |
| 772 | 894 | ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram; |
| 773 | 895 | int DefaultMetavoxelRendererImplementation::_heightScaleLocation; |
| 896 | +ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldCursorProgram; | |
| 897 | +int DefaultMetavoxelRendererImplementation::_cursorHeightScaleLocation; | |
| 774 | 898 | |
| 775 | 899 | static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { |
| 776 | 900 | GLdouble coefficients[] = { x, y, z, w }; |