gldraw.cpp

changeset 134
7fd0784471df
parent 133
5a8073d713a3
child 135
c243df39913e
equal deleted inserted replaced
133:5a8073d713a3 134:7fd0784471df
556 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 556 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
557 // ========================================================================= // 557 // ========================================================================= //
558 void GLRenderer::pick (uint mx, uint my, bool add) { 558 void GLRenderer::pick (uint mx, uint my, bool add) {
559 GLint viewport[4]; 559 GLint viewport[4];
560 560
561 // Clear the selection if we do not wish to add to it.
561 if (add == false) { 562 if (add == false) {
562 // Clear the selection if we don't wish to add to it.
563 std::vector<LDObject*> paOldSelection = g_ForgeWindow->paSelection; 563 std::vector<LDObject*> paOldSelection = g_ForgeWindow->paSelection;
564 g_ForgeWindow->paSelection.clear (); 564 g_ForgeWindow->paSelection.clear ();
565 565
566 // Recompile the prior selection to remove the highlight color 566 // Recompile the prior selection to remove the highlight color
567 for (LDObject* obj : paOldSelection) 567 for (LDObject* obj : paOldSelection)
579 579
580 short x0 = mx, 580 short x0 = mx,
581 y0 = my; 581 y0 = my;
582 short x1, y1; 582 short x1, y1;
583 583
584 // Determine how big an area to read - with range picking, we pick by
585 // the area given, with single pixel picking, we use an 1 x 1 area.
584 if (rangepick) { 586 if (rangepick) {
585 x1 = rangeStart.x (); 587 x1 = rangeStart.x ();
586 y1 = rangeStart.y (); 588 y1 = rangeStart.y ();
587 } else { 589 } else {
588 x1 = x0 + 1; 590 x1 = x0 + 1;
589 y1 = y0 + 1; 591 y1 = y0 + 1;
590 } 592 }
591 593
594 // x0 and y0 must be less than x1 and y1, respectively.
592 if (x0 > x1) 595 if (x0 > x1)
593 dataswap (x0, x1); 596 dataswap (x0, x1);
594 597
595 if (y0 > y1) 598 if (y0 > y1)
596 dataswap (y0, y1); 599 dataswap (y0, y1);
599 x0 = max<short> (0, x0); 602 x0 = max<short> (0, x0);
600 y0 = max<short> (0, y0); 603 y0 = max<short> (0, y0);
601 x1 = min<short> (x1, width); 604 x1 = min<short> (x1, width);
602 y1 = min<short> (y1, height); 605 y1 = min<short> (y1, height);
603 606
604 short areawidth = (x1 - x0); 607 const short areawidth = (x1 - x0);
605 short areaheight = (y1 - y0); 608 const short areaheight = (y1 - y0);
606
607 const long numpixels = areawidth * areaheight; 609 const long numpixels = areawidth * areaheight;
610
611 // Allocate space for the pixel data.
608 uchar* const pixeldata = new uchar[4 * numpixels]; 612 uchar* const pixeldata = new uchar[4 * numpixels];
609 uchar* pixelptr = &pixeldata[0]; 613 uchar* pixelptr = &pixeldata[0];
610 614
611 assert (viewport[3] == height); 615 assert (viewport[3] == height);
612 616
617 // Read pixels from the color buffer.
613 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata); 618 glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata);
614 619
620 // Go through each pixel read and add them to the selection.
615 for (long i = 0; i < numpixels; ++i) { 621 for (long i = 0; i < numpixels; ++i) {
616 uint32 idx = 622 uint32 idx =
617 (*(pixelptr) * 0x10000) + 623 (*(pixelptr) * 0x10000) +
618 (*(pixelptr + 1) * 0x00100) + 624 (*(pixelptr + 1) * 0x00100) +
619 (*(pixelptr + 2) * 0x00001); 625 (*(pixelptr + 2) * 0x00001);
626 g_ForgeWindow->paSelection.push_back (obj); 632 g_ForgeWindow->paSelection.push_back (obj);
627 } 633 }
628 634
629 delete[] pixeldata; 635 delete[] pixeldata;
630 636
637 // Remove duplicate entries. For this to be effective, the vector must be
638 // sorted first.
631 std::vector<LDObject*>& sel = g_ForgeWindow->paSelection; 639 std::vector<LDObject*>& sel = g_ForgeWindow->paSelection;
632 std::sort (sel.begin(), sel.end ()); 640 std::sort (sel.begin(), sel.end ());
633 std::vector<LDObject*>::iterator pos = std::unique (sel.begin (), sel.end ()); 641 std::vector<LDObject*>::iterator pos = std::unique (sel.begin (), sel.end ());
634 sel.resize (std::distance (sel.begin (), pos)); 642 sel.resize (std::distance (sel.begin (), pos));
635 643
644 // Update everything now.
636 g_ForgeWindow->buildObjList (); 645 g_ForgeWindow->buildObjList ();
637 646
638 picking = false; 647 picking = false;
639 rangepick = false; 648 rangepick = false;
640 glEnable (GL_DITHER); 649 glEnable (GL_DITHER);

mercurial