2011-05-26 76 views
0

你好
这是我的功能,将检测命中。gluLookAt选择问题

private int[] GetSelected(int x, int y) 
{ 
    const int max = 512; 
    var Hit_Buffer = new int[max]; 
    var viewport = new int[4]; 

    Gl.glSelectBuffer(max, Hit_Buffer); 
    Gl.glRenderMode(Gl.GL_SELECT); 

    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPushMatrix(); 
    Gl.glLoadIdentity(); 

    Glu.gluLookAt(Distance * Math.Cos(beta) * Math.Cos(alpha) 
     , Distance * Math.Cos(beta) * Math.Sin(alpha) 
     , Distance * Math.Sin(beta) 
     , 0, 0, 0 
     , -Math.Sin(beta) * Math.Cos(alpha) 
     , -Math.Sin(beta) * Math.Sin(alpha) 
     , Math.Cos(beta)); 

    Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport); 
    Glu.gluPickMatrix(x, viewport[3] - y, 1, 1, viewport); 

    Glu.gluPerspective(fovY, ogl1.Width/(double)(ogl1.Height != 0 ? ogl1.Height : 1), 0.1, 100.0); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 

    Gl.glInitNames(); 
    // render scene: a TRIANGLE 
    Gl.glPushName(1); 
    Gl.glBegin(Gl.GL_TRIANGLES); 
    Gl.glVertex3d(0, 0, 0); 
    Gl.glVertex3d(0, 1, 0); 
    Gl.glVertex3d(1, 0, 0); 
    Gl.glEnd(); 
    Gl.glPopName(); 
    // 

    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPopMatrix(); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 
    Gl.glFlush(); 

    var hits = Gl.glRenderMode(Gl.GL_RENDER); 
    Array.Resize(ref Hit_Buffer, hits); 

    return Hit_Buffer; 
} 

我在xy平面上绘制一个三角形。
在gluLookAt中,beta是来自xy平面的摄像机角度,alpha是关于z的摄像机角度。
但它只是工程,如果测试版很小(-15 <测试版< 15度)!
这里有什么问题?

+0

α和β是真正的弧度,对不对? – vines 2011-05-26 11:43:42

+0

@vines:是的,他们是。 – mrbm 2011-05-26 11:58:46

回答

0

你好再次
我终于找到我自己的答案了! (由谷歌搜索)
这是我纠正代码

private int[] GetSelected(int x, int y, bool debug) 
{ 
    var hits = 0; // number of hits 

    // Define select buffer 
    const int max = 512; 
    var Hit_buffer = new int[max]; 
    Gl.glSelectBuffer(max, Hit_buffer); 

    var viewport = new int[4]; 
    Gl.glViewport(0, 0, Width, (Height != 0 ? Height : 1)); 
    Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport); 

    if (debug)// show real scene in debug mode 
     GlDraw(); 

    if(!debug) 
     Gl.glRenderMode(Gl.GL_SELECT); 

    int s = debug ? 60 : 3; // test region size 

    Gl.glLoadIdentity(); 
    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPushMatrix(); 
    Gl.glLoadIdentity(); 

    Glu.gluPickMatrix(x, viewport[3] - y, s, s, viewport); 

    Glu.gluPerspective(fovY, Width/(double)(Height != 0 ? Height : 1), 0.1, 1000.0); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 

    if (debug) // test region will be shown in left-bottom corner 
     Gl.glViewport(0, 0, s, s); 

    #region camera 
    Gl.glTranslated(Dx, Dy, 0); 
    var Distance = this.Distance;// *ogl1.Height/60.0; 
    var CenterView = this.CenterView.Duplicate(); 
    Glu.gluLookAt(Distance * Math.Cos(beta) * Math.Cos(alpha) + CenterView.x 
     , Distance * Math.Cos(beta) * Math.Sin(alpha) + CenterView.y 
     , Distance * Math.Sin(beta) + CenterView.z 
     , CenterView.x 
     , CenterView.y 
     , CenterView.z 
     , -Math.Sin(beta) * Math.Cos(alpha) 
     , -Math.Sin(beta) * Math.Sin(alpha) 
     , Math.Cos(beta)); 
    #endregion 

    if (debug) // draw a bacground in left-bottom corner 
    { 
     ChangeColor(Color.Blue); 
     Glu.gluSphere(Glu.gluNewQuadric(), 50, 50, 50); 
     Gl.glBegin(Gl.GL_QUADS); 
     Gl.glVertex3d(-10, -10, -10); 
     Gl.glVertex3d(-10, 10, -10); 
     Gl.glVertex3d(10, 10, -10); 
     Gl.glVertex3d(10, -10, -10); 
     Gl.glEnd(); 
    } 

    Gl.glInitNames(); 

    // render scene 
    foreach (var b in Bodies) 
    { 
     Gl.glPushName(b.id); 
     var bb = b.Duplicate(); 
     bb.color = Color.Red; 
     bb.Draw(); 
     Gl.glPopName(); 
    } 
    // 

    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPopMatrix(); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 
    Gl.glFlush(); 

    if (!debug) 
     hits = Gl.glRenderMode(Gl.GL_RENDER); 

    // process hits 
    int[] Res = { }; 
    int startRecord = 0; 
    for (int i = 0; i < hits; i++) 
    { 
     for (int j = 0; j < Hit_buffer[startRecord]; j++) 
     { 
      Array.Resize(ref Res, Res.Length + 1); 
      Res[Res.Length - 1] = Hit_buffer[startRecord + 3 + j]; 
     } 
     startRecord += 3 + Hit_buffer[startRecord]; 
    } 

    return Res; 
} 

如果将调试参数=属实,这将在左下角绘制选择区域。
代码可能是无聊,所以我要去写的主要部分在这里

// Define select buffer 
    const int max = 512; 
    var Hit_buffer = new int[max]; 
    Gl.glSelectBuffer(max, Hit_buffer); 

    var viewport = new int[4]; 
    Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport); 

    Gl.glRenderMode(Gl.GL_SELECT); 

    Gl.glLoadIdentity(); 
    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPushMatrix(); 
    Gl.glLoadIdentity(); 

    Glu.gluPickMatrix(x, viewport[3] - y, 3, 3, viewport); 

    Glu.gluPerspective(fovY, Width/(double)(Height != 0 ? Height : 1), 0.1, 1000.0); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 

    Gl.glInitNames(); 

    // set camera (gluLookAt, ...) & draw scene 

    Gl.glMatrixMode(Gl.GL_PROJECTION); 
    Gl.glPopMatrix(); 
    Gl.glMatrixMode(Gl.GL_MODELVIEW); 
    Gl.glFlush(); 

    var hits = Gl.glRenderMode(Gl.GL_RENDER); 

    // process hits 
0

在OpenGL中,Y是高达

对于第3个参数,我宁愿说:

 Distance * Math.Cos(beta) * Math.Cos(alpha) 
    , Distance * Math.Sin(beta) 
    , Distance * Math.Cos(beta) * Math.Sin(alpha) 

而对于3分最后的,尝试用(0,1,0)第一。

+0

这不是我的问题!我的代码运行良好。我有选择问题。 – mrbm 2011-05-26 16:22:04

0

您是否有意在gluPickMatrix之前调用gluLookAt。你想把翻译应用到你的选择矩阵吗?如果不是,你可以在glLoadIdentity后立即移动gluPickMatrix,并尝试解决问题吗?

+0

谢谢你的回答。是的,在gluPickMatrix错误之前调用gluLookAt! – mrbm 2011-05-27 07:45:11