我是第一次使用拾取技术,我已经按照 NEHE 教程在 opengl 中使用拾取技术,我实际上需要检测正方形上的细线。但是我不确定为什么它没有正确检测到它,即使我从它的背景中删除了正方形,它仍然会随机选择其他选择,而不是我做出的选择。大多数时候它从来没有检测到......所以我做了另一个测试exe,我只放了2行并删除了方形背景,但它仍然没有被选中......有时它会在屏幕的其他部分被选中......这些线条离屏幕有点远,所以我给了缩放自由以清楚地看到线条是如何存在的,所以我也通过缩放检查了它......但仍然没有用。它非常令人困惑。
下面是我的代码我如何创建行
我的初始化代码
void COpenGLControl::oglInitialize(void)
{
// Initial Setup:
//
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, // z-buffer depth
0, 0, 0, 0, 0, 0, 0,
};
// Get device context only once.
hdc = GetDC()->m_hDC;
// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
// Basic Setup:
//
// Set color to use when clearing the background.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
// Turn on backface culling
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
GLenum a = glGetError();
CCTrace::Trace(L"COpenGLControl::oglInitialize return",a);
OnDraw(NULL);
}
这是我在鼠标点击时调用的选择方法
void CRightOGL::Selection(int mouse_x,int mouse_y) // This Is Where Selection Is Done
{
GLuint buffer[512]={0};
GLint hits; // The Number Of Objects That We Selected
// The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>
GLint viewport[4];
// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(512, buffer); // Tell OpenGL To Use Our Array For Selection
(void) glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 30.0f, 30.0f, viewport);
gluPerspective(35.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.01f, 2000.0f);
glMatrixMode(GL_MODELVIEW);
DrawTargetLines();
//DrawJawImage();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Pop The Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
hits=glRenderMode(GL_RENDER); // Switch To Render Mode, Find Out How Many
// Objects Were Drawn Where The Mouse Was
GLenum s = glGetError();
if(s!=0) CCTrace::Trace(L"CRightOGL::oglDrawScene",s);
if (hits > 0) // If There Were More Than 0 Hits
{
int choose = buffer[3]; // Make Our Selection The First Object
int depth = buffer[1]; // Store How Far Away It Is
//SetTeethSlice(choose);
for (int loop = 1; loop < hits; loop++) // Loop Through All The Detected Hits
{
// If This Object Is Closer To Us Than The One We Have Selected
if (buffer[loop*4+1] < GLuint(depth))
{
choose = buffer[loop*4+3]; // Select The Closer Object
depth = buffer[loop*4+1]; // Store How Far Away It Is
}
}
((CTeethBiometricApp*)::AfxGetApp())->setDialogSlider(choose);
}
}
这是绘制线功能来绘制 52 条不同的线
void CRightOGL::DrawTargetLines()
{
glDisable(GL_TEXTURE_2D);
//original line when you need to adjust the line use this block
// glVertex3d(-0.5,-0.23f,1.0f);
// glVertex3d( -0.1,-0.35f,1.0f);
//-------------------------------------------------------------------
float y1 = 0.25f, y2 = 0.37f;
for(float loop=1;loop<51;loop++)
{
y1+=0.004f;
y2+=0.004f;
glLoadName(loop); // Assign Object A Name (ID)
glPushMatrix(); // Push The Modelview Matrix
glLineWidth(3.0f);
glBegin(GL_LINES); // Start Drawing Our Player Using Lines
if(this->m_CurrentSlice==loop)
glColor3f(1.0f,1.0f,0.0f);
else
glColor3f(1.0f,0.0f,0.0f);
glVertex3d(-0.5,y1,1.0f); // Top Left Of Player
glVertex3d( -0.1,y2,1.0f); // Bottom Right Of Player
// Pop The Modelview Matrix
glEnd();
glPopMatrix();
}
}
这是我的绘图功能
void CRightOGL::oglDrawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glLoadIdentity();
//glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
glRotated(90,0.0f, 0.0f, -1.0f);
GLenum s = glGetError();
DrawJawImage();
DrawTargetLines();
SwapBuffers(hdc);
glFlush();
}
我的测试前在这个保管箱上
http://dl.dropbox.com/u/104183650/Release.zip
请使用鼠标右键进行缩放并旋转鼠标左键