Posted on 2007-09-04 15:25
劒蚩 阅读(454)
评论(0) 编辑 收藏 引用 所属分类:
Opengl
这是我在国外的一个网站上看到的一篇文章,觉得很不错,以前我所知道的在Opengl中选择物体的方式有2种,一种是用Opengl自带的Select模式,一种是用包围盒来选择物体.这篇文章的方式是用一个唯一的Color ID来代表一个物体,然后根据这个Color来选择物体.DX也同样可以使用这样的方式.
实现的步骤:
- 关闭Opengl中的纹理,灯光和雾
- 使用物体定义的唯一Color来渲染这个物体
- 从后备缓冲数据中读出当前鼠标所在位置的颜色值
- 找出与读出的颜色值相匹配的物体
这种方法有个问题,在32Bit模式下是完全正确的,在16Bit下会因为颜色丢失的问题而选不中物体,解决方案在这篇文章里:http://www.3dkingdoms.com/selection.html
源代码:
class BaseObject
{
private:
unsignedchar m_colorID[3];
staticunsignedchar gColorID[3];
public:
BaseObject()
{
m_colorID[0] = gColorID[0];
m_colorID[1] = gColorID[1];
m_colorID[2] = gColorID[2];
gColorID[0]++;
if(gColorID[0] > 255)
{
gColorID[0] = 0;
gColorID[1]++;
if(gColorID[1] > 255)
{
gColorID[1] = 0;
gColorID[2]++;
}
}
}
~BaseObject(){};
};
unsignedchar BaseObject::gColorID[3] = {0, 0, 0};
class SceneObject : public BaseObject
{
private:
float m_position[3];
string m_name;
public:
SceneObject();
~SceneObject();
void Render();
void Picking()
{ // set mesh position
glPushMatrix();
glTranslatef(m_position[0], m_position[1], m_position[2]);
glColor3f(m_colorID[0]/255.0f, m_colorID[1]/255.0f, m_colorID[2]/255.0f);
// render object's vertices here
glPopMatrix();
}
};
void MouseDownEvent(int x, int y)
{
// turn off texturing, lighting and fog
glDisable(GL_TEXTURE_2D);
glDisable(GL_FOG);
glDisable(GL_LIGHTING);
// render every object in our scene// suppose every object is stored in a list container called SceneObjects
list<SceneObject *>::iterator itr = SceneObjects.begin();
while(itr != SceneObjects.end())
{
(*itr)->Picking();
itr++;
}
// get color information from framebuffer
unsignedchar pixel[3];
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glReadPixels(x, viewport[3] - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
// now our picked screen pixel color is stored in pixel[3]// so we search through our object list looking for the object that was selected
itr = SceneObjects.begin();
while(itr != SceneObjects.end())
{
if((*itr)->m_colorID[0] == pixel[0] && (*itr)->m_colorID[1] == pixel[1] && (*itr)->m_colorID[2] == pixel[2])
{
// flag object as selected
SetSelected((*itr);
break;
}
itr++;
}
}
原文地址:http://gpwiki.org/index.php/OpenGL_Selection_Using_Unique_Color_IDs