void guiRenderer2D::drawMatrices(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height, bool screenshot) { cr->scale(m_scaleFactor, m_scaleFactor); // Scale sensor to fit the active window cr->translate(m_offsetX, m_offsetY); // Center figure on drawable/surface cr->set_line_width(0.25); for(uint m = 0; m < m_frameManager->getNumMatrices(); m++) { matrixInfo &matrix = m_frameManager->getMatrixInfo(m); // TSFrame* tsFrame = m_frameManager->getCurrentFrame(); TSFrame* tsFrame = m_frameManager->getCurrentFilteredFrame(); for(uint y = 0; y < matrix.cells_y; y++) { for(uint x = 0; x < matrix.cells_x; x++) { bool maskedStatic = m_frameManager->getStaticMask(m, x, y); bool maskedDynamic = m_frameManager->getDynamicMask(m, x, y); uint cellID = matrix.texel_offset + y * matrix.cells_x + x; float value = tsFrame->cells[cellID]; if(maskedStatic) { RGB color = determineColor(value); // Draw sensor cell rectangle cr->rectangle(m_rectangleTopLeftX[cellID], m_rectangleTopLeftY[cellID], m_rectangleWidth[cellID], m_rectangleHeight[cellID]); cr->set_source_rgb(0.0, 0.0, 0.0); cr->stroke_preserve(); // Cell outline if(maskedDynamic) { if(value > 0.0) { cr->set_source_rgb(color.r, color.g, color.b); // Active cells } else { cr->set_source_rgb(1.0, 1.0, 1.0); // Inactive cells } } else { cr->set_source_rgb(0.8, 0.8, 0.8); // Disabled cells } cr->fill(); } // Highlight selected cells if(m_frameManager->isSelected(cellID)) { cr->rectangle(m_rectangleTopLeftX[cellID], m_rectangleTopLeftY[cellID], m_rectangleWidth[cellID], m_rectangleHeight[cellID]); cr->set_source_rgba(0.0, 1.0, 0.0, 0.5); // Fill active cells cr->fill(); } if(screenshot) { if(maskedStatic) { // Print values Cairo::RefPtr<Cairo::ToyFontFace> font = Cairo::ToyFontFace::create("LMSans10", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_face(font); cr->set_font_size(matrix.texel_width/3); std::ostringstream ss; ss << value; std::string valueStr = ss.str(); Cairo::TextExtents te; cr->get_text_extents(valueStr, te); cr->move_to(m_matrixCellCenterX[cellID]-te.width/2, m_matrixCellCenterY[cellID]+te.height/2); cr->set_source_rgb(0.0, 0.0, 0.0); cr->show_text(valueStr); } } } } if(!screenshot) { { // Print Matrix IDs Cairo::RefPtr<Cairo::ToyFontFace> font = Cairo::ToyFontFace::create("LMSans10", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_face(font); cr->set_font_size(matrix.cells_x*matrix.texel_width); std::ostringstream ss; ss << m; std::string idString = ss.str(); Cairo::TextExtents te; cr->get_text_extents(idString, te); cr->move_to(m_newCenterX[m]-te.width/2, m_newCenterY[m]+te.height/2); cr->set_source_rgba(0.3, 0.3, 0.3, 0.3); cr->show_text(idString); } } } }
void Viewport::drawBins(QPainter &painter, QTimer &renderTimer, unsigned int &renderedLines, unsigned int renderStep, bool highlight) { SharedDataLock ctxlock(ctx->mutex); // TODO: this also locks shuffleIdx implicitely, better do it explicitely? SharedDataLock setslock(sets->mutex); // Stopwatch watch("drawBins"); /* initialize painting in GL, vertex buffer */ target->makeCurrent(); painter.beginNativePainting(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); bool success = vb.bind(); if (!success) { GerbilApplication::internalError( "Vertex buffer could not be bound in viewport drawBins().", false); painter.endNativePainting(); return; } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, 0); size_t iD = renderedLines * (*ctx)->dimensionality; /* determine drawing range. could be expanded to only draw spec. labels */ // make sure that viewport draws "unlabeled" data in ignore-label case int start = ((showUnlabeled || (*ctx)->ignoreLabels == 1) ? 0 : 1); int end = (showLabeled ? (int)(*sets)->size() : 1); size_t total = shuffleIdx.size(); size_t first = renderedLines; size_t last = std::min((size_t)(renderedLines + renderStep), total); // loop over all elements in vertex index, update element and vector indices for (size_t i = first; i < last; ++i, iD += (*ctx)->dimensionality) { std::pair<int, BinSet::HashKey> &idx = shuffleIdx[i]; // filter out according to label bool filter = ((idx.first < start || idx.first >= end)); // do not filter out highlighted label(s) if (!(*ctx)->ignoreLabels) { filter = filter && !highlightLabels.contains(idx.first); } if (filter) { // increase loop count to achieve renderStep if (last < total) ++last; continue; } BinSet::HashKey &K = idx.second; // highlight mode (foreground buffer) if (highlight) { //test if we are part of the highlight bool highlighted = false; if (limiterMode) { highlighted = true; for (size_t i = 0; i < (*ctx)->dimensionality; ++i) { unsigned char k = K[i]; if (k < limiters[i].first || k > limiters[i].second) highlighted = false; } } else if ((unsigned char)K[selection] == hover) { highlighted = true; } // filter out if (!highlighted) { // increase loop count to achieve renderStep if (last < total) ++last; continue; } } // grab binset and bin according to key BinSet &s = (**sets)[idx.first]; std::pair<BinSet::HashMap::const_iterator, BinSet::HashMap::const_iterator> binitp = s.bins.equal_range(K); if (s.bins.end() == binitp.first) { // FIXME this is an error and should be treated accordingly GGDBGM("no bin"<< endl); return; } Bin const &b = s.bins.equal_range(K).first->second; // set color QColor color = determineColor((drawRGB->isChecked() ? b.rgb : s.label), b.weight, s.totalweight, highlight, highlightLabels.contains(idx.first)); target->qglColor(color); // draw polyline glDrawArrays(GL_LINE_STRIP, (GLsizei)iD, (GLint)(*ctx)->dimensionality); } vb.release(); painter.endNativePainting(); // setup succeeding incremental drawing renderedLines += (unsigned int)(last - first); if (renderedLines < total) { if (renderedLines <= renderStep) { renderTimer.start(150); } else { renderTimer.start(0); } } }