src/glrenderer.cpp

changeset 1278
6e1ea24e5a5e
parent 1251
e75cc5bff076
child 1306
be85306198a2
equal deleted inserted replaced
1277:821c30615069 1278:6e1ea24e5a5e
699 m_config->setCamera(static_cast<int>(camera)); 699 m_config->setCamera(static_cast<int>(camera));
700 } 700 }
701 } 701 }
702 702
703 /* 703 /*
704 * Resolves a pixel pointer to an RGB color.
705 * pixel[0..2] must be valid.
706 */
707 static QRgb colorFromPixel(uint8_t* pixel)
708 {
709 return pixel[0] << 16 | pixel[1] << 8 | pixel[2] | 0xff000000;
710 }
711
712 /*
704 * Returns the set of objects found in the specified pixel area. 713 * Returns the set of objects found in the specified pixel area.
705 */ 714 */
706 QItemSelection GLRenderer::pick(const QRect& range) 715 QItemSelection GLRenderer::pick(const QRect& range)
707 { 716 {
708 makeCurrent(); 717 makeCurrent();
731 pixelData.resize(4 * numpixels); 740 pixelData.resize(4 * numpixels);
732 741
733 // Read pixels from the color buffer. 742 // Read pixels from the color buffer.
734 glReadPixels(x0, height() - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data()); 743 glReadPixels(x0, height() - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
735 744
736 QSet<qint32> ids; 745 QSet<QRgb> pixelColors;
737 746
738 // Go through each pixel read and add them to the selection. 747 // Go through each pixel read and add them to the selection.
739 // Each pixel maps to an LDObject index injectively. 748 // Each pixel maps to an LDObject injectively.
740 // Note: black is background, those indices are skipped. 749 // Note: black is background, those indices are skipped.
741 for (unsigned char *pixelCursor = pixelData.begin(); pixelCursor < pixelData.end(); pixelCursor += 4) 750 for (int i : ::range(0, 4, pixelData.size() - 4))
742 { 751 {
743 qint32 id = pixelCursor[0] * 0x10000 + pixelCursor[1] * 0x100 + pixelCursor[2] * 0x1; 752 QRgb color = colorFromPixel(&pixelData[i]);
744 if (id != 0) 753
745 ids.insert(id); 754 if (color != BlackRgb)
755 pixelColors.insert(color);
746 } 756 }
747 757
748 // For each index read, resolve the LDObject behind it and add it to the selection. 758 // For each index read, resolve the LDObject behind it and add it to the selection.
749 for (qint32 id : ids) 759 for (QRgb color : pixelColors)
750 { 760 {
751 QModelIndex index = m_model->indexFromId(id); 761 QModelIndex index = m_model->objectByPickingColor(color);
752 762
753 if (index.isValid()) 763 if (index.isValid())
754 result.select(index, index); 764 result.select(index, index);
755 } 765 }
756 766
767 makeCurrent(); 777 makeCurrent();
768 setPicking(true); 778 setPicking(true);
769 drawGLScene(); 779 drawGLScene();
770 unsigned char pixel[4]; 780 unsigned char pixel[4];
771 glReadPixels(mouseX, height() - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); 781 glReadPixels(mouseX, height() - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
772 QModelIndex result = m_model->indexFromId(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]); 782 QModelIndex result = m_model->objectByPickingColor(colorFromPixel(pixel));
773 setPicking(false); 783 setPicking(false);
774 repaint(); 784 repaint();
775 return result; 785 return result;
776 } 786 }
777 787
836 void GLRenderer::zoomToFit() 846 void GLRenderer::zoomToFit()
837 { 847 {
838 currentCamera().setZoom(30.0f); 848 currentCamera().setZoom(30.0f);
839 bool lastfilled = false; 849 bool lastfilled = false;
840 bool firstrun = true; 850 bool firstrun = true;
841 enum { black = 0xFF000000 };
842 bool inward = true; 851 bool inward = true;
843 int runaway = 50; 852 int runaway = 50;
844 853
845 // Use the pick list while drawing the scene, this way we can tell whether borders 854 // Use the pick list while drawing the scene, this way we can tell whether borders
846 // are background or not. 855 // are background or not.
863 bool filled = false; 872 bool filled = false;
864 873
865 // Check the top and bottom rows 874 // Check the top and bottom rows
866 for (int i = 0; i < image.width(); ++i) 875 for (int i = 0; i < image.width(); ++i)
867 { 876 {
868 if (image.pixel (i, 0) != black or image.pixel (i, height() - 1) != black) 877 if (image.pixel (i, 0) != BlackRgb or image.pixel (i, height() - 1) != BlackRgb)
869 { 878 {
870 filled = true; 879 filled = true;
871 break; 880 break;
872 } 881 }
873 } 882 }
875 // Left and right edges 884 // Left and right edges
876 if (filled == false) 885 if (filled == false)
877 { 886 {
878 for (int i = 0; i < image.height(); ++i) 887 for (int i = 0; i < image.height(); ++i)
879 { 888 {
880 if (image.pixel (0, i) != black or image.pixel (width() - 1, i) != black) 889 if (image.pixel (0, i) != BlackRgb or image.pixel (width() - 1, i) != BlackRgb)
881 { 890 {
882 filled = true; 891 filled = true;
883 break; 892 break;
884 } 893 }
885 } 894 }
937 if (not m_isCameraMoving and m_config->highlightObjectBelowCursor()) 946 if (not m_isCameraMoving and m_config->highlightObjectBelowCursor())
938 { 947 {
939 setPicking (true); 948 setPicking (true);
940 drawGLScene(); 949 drawGLScene();
941 setPicking (false); 950 setPicking (false);
942
943 unsigned char pixel[4]; 951 unsigned char pixel[4];
944 glReadPixels (m_mousePosition.x(), height() - m_mousePosition.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel[0]); 952 glReadPixels(
945 qint32 id = pixel[0] * 0x10000 | pixel[1] * 0x100 | pixel[2]; 953 m_mousePosition.x(),
946 954 height() - m_mousePosition.y(),
947 if (id != 0) 955 1,
948 newIndex = model()->indexFromId(id); 956 1,
957 GL_RGBA,
958 GL_UNSIGNED_BYTE,
959 &pixel[0]
960 );
961 newIndex = model()->objectByPickingColor(colorFromPixel(pixel));
949 } 962 }
950 963
951 if (newIndex != oldIndex) 964 if (newIndex != oldIndex)
952 { 965 {
953 m_objectAtCursor = newIndex; 966 m_objectAtCursor = newIndex;

mercurial