Commit 6154bbb5 authored by Jan Möbius's avatar Jan Möbius
Browse files

Dennis:

Add alpha to colorpicking ( Up to 4.294.967.295 Elements )



git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@5910 383ad7c9-94d9-4d36-a494-682f7c89f535
parent b102d0da
......@@ -111,6 +111,22 @@ void ColorStack::setIndex (unsigned int _idx)
//----------------------------------------------------------------------------
Vec4uc ColorStack::getIndexColor (unsigned int _idx)
{
if (initialized_)
{
Vec4uc rv;
if (!currentNode_->getIndexColor (_idx, rv))
error_ = true;
else
return rv;
}
return Vec4uc (0, 0, 0, 0);
}
//----------------------------------------------------------------------------
void ColorStack::pushIndex (unsigned int _idx)
{
if (initialized_)
......@@ -127,12 +143,12 @@ void ColorStack::popIndex ()
//----------------------------------------------------------------------------
std::vector<unsigned int> ColorStack::colorToStack (Vec3uc _rgb) const
std::vector<unsigned int> ColorStack::colorToStack (Vec4uc _rgba) const
{
std::vector<unsigned int> rv(0);
if (initialized_ && !error_)
{
unsigned int idx = translator_.color2index (_rgb);
unsigned int idx = translator_.color2index (_rgba);
if (idx >= root_->startIndex () && idx < root_->endIndex ())
root_->colorToStack (rv, idx);
}
......@@ -216,6 +232,18 @@ bool ColorStack::Node::setIndex (unsigned int _idx) const
//----------------------------------------------------------------------------
bool ColorStack::Node::getIndexColor (unsigned int _idx, Vec4uc &_rgba) const
{
if (colorStartIdx_ && colorStartIdx_ + _idx < colorEndIdx_)
{
_rgba = translator_->index2color(colorStartIdx_ + _idx);
return true;
}
return false;
}
//----------------------------------------------------------------------------
ColorStack::Node * ColorStack::Node::pushIndex (unsigned int _idx)
{
ColorStack::Node *n = new ColorStack::Node (_idx, this, translator_);
......
......@@ -83,6 +83,9 @@ public:
/// sets the current color the given index (like glLoadName)
void setIndex (unsigned int _idx);
/// gets the color instead of setting it directly
Vec4uc getIndexColor (unsigned int _idx);
/// creates a new node the stack (like glPushName)
void pushIndex (unsigned int _idx);
......@@ -90,7 +93,7 @@ public:
void popIndex ();
/// converts the given color to index values on the stack
std::vector<unsigned int> colorToStack (Vec3uc _rgb) const;
std::vector<unsigned int> colorToStack (Vec4uc _rgba) const;
/// returns maximal available index count
unsigned int freeIndicies () const;
......@@ -116,6 +119,9 @@ private:
/// sets the current color the given index (like glLoadName)
bool setIndex (unsigned int _idx) const;
/// gets the color instead of setting it directly
bool getIndexColor (unsigned int _idx, Vec4uc &_rgba) const;
/// creates a new node the stack (like glPushName)
Node * pushIndex (unsigned int _idx);
......
......@@ -62,22 +62,27 @@ initialize()
glGetIntegerv( GL_RED_BITS, &red_bits_ );
glGetIntegerv( GL_GREEN_BITS, &green_bits_ );
glGetIntegerv( GL_BLUE_BITS, &blue_bits_ );
glGetIntegerv( GL_ALPHA_BITS, &alpha_bits_ );
if (red_bits_ > 8) red_bits_ = 8;
if (green_bits_ > 8) green_bits_ = 8;
if (blue_bits_ > 8) blue_bits_ = 8;
if (alpha_bits_ > 8) alpha_bits_ = 8;
red_mask_ = ((1 << red_bits_) - 1);
green_mask_ = ((1 << green_bits_) - 1);
blue_mask_ = ((1 << blue_bits_) - 1);
blue_mask_ = ((1 << blue_bits_) - 1);
alpha_mask_ = ((1 << alpha_bits_) - 1);
red_shift_ = 8 - red_bits_;
green_shift_ = 8 - green_bits_;
blue_shift_ = 8 - blue_bits_;
blue_shift_ = 8 - blue_bits_;
alpha_shift_ = 8 - alpha_bits_;
red_round_ = 1 << (red_shift_ - 1);
green_round_ = 1 << (green_shift_ - 1);
blue_round_ = 1 << (blue_shift_ - 1);
alpha_round_ = 1 << (alpha_shift_ - 1);
initialized_ = true;
}
......@@ -86,12 +91,12 @@ initialize()
//-----------------------------------------------------------------------------
Vec3uc
Vec4uc
ColorTranslator::
index2color(unsigned int _idx) const
{
assert(initialized());
unsigned char r, g, b;
unsigned char r, g, b, a;
unsigned int idx(_idx+1);
b = ((idx & blue_mask_) << blue_shift_) | blue_round_;
......@@ -100,14 +105,16 @@ index2color(unsigned int _idx) const
idx >>= green_bits_;
r = ((idx & red_mask_) << red_shift_) | red_round_;
idx >>= red_bits_;
a = ((idx & alpha_mask_) << alpha_shift_) | alpha_round_;
idx >>= alpha_bits_;
if (!idx)
return Vec3uc(r, g, b);
return Vec4uc(r, g, b, a);
else
{
std::cerr << "Can't convert index " << _idx << " to RGB\n";
return Vec3uc(0, 0, 0);
std::cerr << "Can't convert index " << _idx << " to RGBA\n";
return Vec4uc(0, 0, 0, 0);
}
}
......@@ -117,16 +124,18 @@ index2color(unsigned int _idx) const
int
ColorTranslator::
color2index(Vec3uc _rgb) const
color2index(Vec4uc _rgba) const
{
assert(initialized());
unsigned int result;
result = _rgb[0] >> red_shift_;
result = _rgba[3] >> alpha_shift_;
result <<= red_bits_;
result = _rgba[0] >> red_shift_;
result <<= green_bits_;
result |= _rgb[1] >> green_shift_;
result |= _rgba[1] >> green_shift_;
result <<= blue_bits_;
result |= _rgb[2] >> blue_shift_;
result |= _rgba[2] >> blue_shift_;
return (result-1);
}
......@@ -139,7 +148,10 @@ unsigned int
ColorTranslator::max_index() const
{
assert(initialized());
return (1 << (red_bits_+green_bits_+blue_bits_))-1;
if (red_bits_+green_bits_+blue_bits_+alpha_bits_ == 32)
return 0xffffffff;
else
return (1 << (red_bits_+green_bits_+blue_bits_+alpha_bits_))-1;
}
......
......@@ -79,9 +79,9 @@ public:
/// index -> color (one buffer)
Vec3uc index2color(unsigned int _idx) const;
Vec4uc index2color(unsigned int _idx) const;
/// color -> index (one buffer)
int color2index(Vec3uc _rgb) const;
int color2index(Vec4uc _rgba) const;
/// returns maximal convertable index
......@@ -91,10 +91,10 @@ public:
private:
bool initialized_;
GLint red_bits_, green_bits_, blue_bits_;
GLuint red_mask_, green_mask_, blue_mask_;
GLuint red_shift_, green_shift_, blue_shift_;
GLuint red_round_, green_round_, blue_round_;
GLint red_bits_, green_bits_, blue_bits_, alpha_bits_;
GLuint red_mask_, green_mask_, blue_mask_, alpha_mask_;
GLuint red_shift_, green_shift_, blue_shift_, alpha_shift_;
GLuint red_round_, green_round_, blue_round_, alpha_round_;
};
......
......@@ -880,10 +880,10 @@ void GLState::pick_pop_name ()
//-----------------------------------------------------------------------------
std::vector<unsigned int> GLState::pick_color_to_stack (Vec3uc _rgb) const
std::vector<unsigned int> GLState::pick_color_to_stack (Vec4uc _rgba) const
{
if (colorPicking_ && colorStack_.initialized ())
return colorStack_.colorToStack (_rgb);
return colorStack_.colorToStack (_rgba);
return std::vector<unsigned int> ();
}
......@@ -909,7 +909,17 @@ bool GLState::pick_error () const
unsigned int GLState::pick_current_index () const
{
return colorStack_.currentIndex ();
if (colorPicking_)
return colorStack_.currentIndex ();
else
return 0;
}
//-----------------------------------------------------------------------------
bool GLState::color_picking () const
{
return colorPicking_;
}
//=============================================================================
......
......@@ -389,7 +389,7 @@ public:
void pick_pop_name ();
/// converts the given color to index values on the stack (only used in color picking)
std::vector<unsigned int> pick_color_to_stack (Vec3uc _rgb) const;
std::vector<unsigned int> pick_color_to_stack (Vec4uc _rgba) const;
/// returns maximal available index count (only used in color picking)
unsigned int pick_free_indicies () const;
......@@ -400,6 +400,9 @@ public:
/// returns the current color picking index (can be used for caching)
unsigned int pick_current_index () const;
/// Is color picking active?
bool color_picking () const;
private: //--------------------------------------------------------------------
......
......@@ -511,6 +511,7 @@ void glViewer::drawScene_mono()
makeCurrent();
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glClear(GL_DEPTH_BUFFER_BIT);
glInitNames();
glPushName((GLuint) 0);
......@@ -521,6 +522,7 @@ void glViewer::drawScene_mono()
ACG::SceneGraph::traverse(sceneGraphRoot_, action);
glEnable(GL_LIGHTING);
glEnable(GL_BLEND);
}
}
......
......@@ -99,7 +99,7 @@ int glViewer::pickColor( ACG::SceneGraph::PickTarget _pickTarget,
b = scene()->height () - scenePos().y() - h,
x = _mousePos.x(),
y = scene()->height () - _mousePos.y();
GLubyte pixels[9][3];
GLubyte pixels[9][4];
GLfloat depths[9];
int hit = -1;
unsigned char order[9] = { 4, 7, 1, 3, 5, 0, 2, 6, 8 };
......@@ -144,12 +144,12 @@ int glViewer::pickColor( ACG::SceneGraph::PickTarget _pickTarget,
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels (x - 1, y - 1, 3, 3, GL_RGB, GL_UNSIGNED_BYTE, pixels);
glReadPixels (x - 1, y - 1, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glReadPixels (x - 1, y - 1, 3, 3, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
for (int i = 0; i < 9; i++)
{
if (hit < 0 && (pixels[order[i]][2] != 0 || pixels[order[i]][1] != 0 || pixels[order[i]][0] != 0))
if (hit < 0 && (pixels[order[i]][2] != 0 || pixels[order[i]][1] != 0 || pixels[order[i]][0] != 0 || pixels[order[i]][3] != 0))
{
hit = order[i];
break;
......@@ -160,12 +160,13 @@ int glViewer::pickColor( ACG::SceneGraph::PickTarget _pickTarget,
return 0;
ACG::Vec3uc rgb;
rgb[0] = pixels[hit][0];
rgb[1] = pixels[hit][1];
rgb[2] = pixels[hit][2];
ACG::Vec4uc rgba;
rgba[0] = pixels[hit][0];
rgba[1] = pixels[hit][1];
rgba[2] = pixels[hit][2];
rgba[3] = pixels[hit][3];
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgb);
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
// something wrong with the color stack ?
if (rv.size () < 2)
......@@ -215,6 +216,7 @@ bool glViewer::pickGL( ACG::SceneGraph::PickTarget _pickTarget,
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelview.get_raw_data());
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glClear(GL_DEPTH_BUFFER_BIT);
properties_.glState().pick_init (false);
......@@ -229,6 +231,7 @@ bool glViewer::pickGL( ACG::SceneGraph::PickTarget _pickTarget,
glMatrixMode( GL_MODELVIEW );
glLoadMatrixd(modelview.get_raw_data());
glEnable(GL_LIGHTING);
glEnable(GL_BLEND);
// process hit record
if ( hits > 0 )
......@@ -309,6 +312,7 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelview.get_raw_data());
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
properties_.glState().pick_init (true);
......@@ -323,19 +327,20 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
glMatrixMode( GL_MODELVIEW );
glLoadMatrixd(modelview.get_raw_data());
glEnable(GL_LIGHTING);
glEnable(GL_BLEND);
properties_.glState().set_clear_color (clear_color);
if (properties_.glState().pick_error ())
return false;
buffer = new GLubyte[3 * rect.width() * rect.height()];
buffer = new GLubyte[4 * rect.width() * rect.height()];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels (rect.x(), scene()->height () - rect.bottom() , rect.width(),
rect.height(), GL_RGB, GL_UNSIGNED_BYTE, buffer);
rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
QSet<QPair<unsigned int, unsigned int> > found;
......@@ -344,15 +349,16 @@ bool glViewer::pick_region( ACG::SceneGraph::PickTarget _pickTarg
{
if (_region.contains (QPoint (rect.x() + x, rect.y() + y)))
{
int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 3;
if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0)
int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 4;
if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0 || buffer[bPos + 3] != 0)
{
ACG::Vec3uc rgb;
rgb[0] = buffer[bPos];
rgb[1] = buffer[bPos + 1];
rgb[2] = buffer[bPos + 2];
ACG::Vec4uc rgba;
rgba[0] = buffer[bPos];
rgba[1] = buffer[bPos + 1];
rgba[2] = buffer[bPos + 2];
rgba[3] = buffer[bPos + 3];
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgb);
std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
if (rv.size () < 2)
continue;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment