| 8341 | } |
| 8342 | |
| 8343 | void SpectrumWidget::initialize(QRhiCommandBuffer* cb) |
| 8344 | { |
| 8345 | if (m_rhiInitialized) return; |
| 8346 | |
| 8347 | QRhi* r = rhi(); |
| 8348 | if (!r) { |
| 8349 | qWarning() << "SpectrumWidget: QRhi initialization failed — no GPU backend"; |
| 8350 | return; |
| 8351 | } |
| 8352 | |
| 8353 | qDebug() << "SpectrumWidget: QRhi initialized, backend:" << r->backendName(); |
| 8354 | |
| 8355 | // Upload quad vertex data for both pipelines |
| 8356 | auto* batch = r->nextResourceUpdateBatch(); |
| 8357 | |
| 8358 | initWaterfallPipeline(); |
| 8359 | initOverlayPipeline(); |
| 8360 | initSpectrumPipeline(); |
| 8361 | initDssMeshPipeline(); |
| 8362 | |
| 8363 | // Upload VBO data |
| 8364 | batch->uploadStaticBuffer(m_wfVbo, kQuadData); |
| 8365 | batch->uploadStaticBuffer(m_ovVbo, kQuadData); |
| 8366 | |
| 8367 | // 3DSS mesh: build the static perspective grid once (geometry never changes — |
| 8368 | // height comes from the ring-buffered texture sampled per-vertex). |
| 8369 | if (m_dssMeshReady) { |
| 8370 | const int cols = m_dss.cols(); |
| 8371 | const int rows = m_dss.rows(); |
| 8372 | QVector<float> fill; |
| 8373 | QVector<float> line; |
| 8374 | fill.reserve(rows * dssFillVerticesPerRow() * 3); |
| 8375 | line.reserve(rows * dssLineVerticesPerRow() * 3); |
| 8376 | for (int rr = rows - 1; rr >= 0; --rr) { |
| 8377 | const float v = static_cast<float>(rr) / rows; // 0 front .. ~1 back |
| 8378 | for (int cc = 0; cc + 1 < cols; ++cc) { |
| 8379 | const float u0 = static_cast<float>(cc) / (cols - 1); |
| 8380 | const float u1 = static_cast<float>(cc + 1) / (cols - 1); |
| 8381 | appendDssVertex(fill, u0, v, 0.0f); // ridge |
| 8382 | appendDssVertex(fill, u0, v, 1.0f); // floor |
| 8383 | appendDssVertex(fill, u1, v, 0.0f); // next ridge |
| 8384 | appendDssVertex(fill, u1, v, 0.0f); |
| 8385 | appendDssVertex(fill, u0, v, 1.0f); |
| 8386 | appendDssVertex(fill, u1, v, 1.0f); // next floor |
| 8387 | appendDssVertex(line, u0, v, -1.0f); |
| 8388 | appendDssVertex(line, u1, v, -1.0f); |
| 8389 | } |
| 8390 | } |
| 8391 | batch->uploadStaticBuffer(m_dssMeshVbo, fill.constData()); |
| 8392 | batch->uploadStaticBuffer(m_dssMeshLineVbo, line.constData()); |
| 8393 | // The palette LUT is baked from the live floor/range on the first 3D |
| 8394 | // frame (renderGpuFrame) before the surface is drawn — no init upload. |
| 8395 | } |
| 8396 | |
| 8397 | // Initial full waterfall texture upload (convert RGB32→RGBA8) |
| 8398 | if (!m_waterfall.isNull()) { |
| 8399 | QImage rgba = m_waterfall.convertToFormat(QImage::Format_RGBA8888); |
| 8400 | QRhiTextureSubresourceUploadDescription desc(rgba); |
nothing calls this directly
no test coverage detected