[OpenGL/C+/CLI] wspolrzedne myszy gluUnProject

Odpowiedz Nowy wątek
2009-05-04 15:45
1

co chce zrobic:
po kliknieciu na scene maja zostac pobrane wspolrzedne myszy i ma zostac narysowany obiekt

jak to robie:
calosc pisana jest na Windows Forms z wykorzystaniem OpenGL
informacje o wspolrzednych myszy pobieram z procedury okna OpenGL

virtual void WndProc( Message% m ) override
                 {

                     IntPtr lpar = m.LParam;
                     DWORD_PTR temp ;
                     if(m.Msg==0x201)
                     {
                         temp=(DWORD_PTR)lpar.ToPointer();
                         mPosX=LOWORD(temp);
                         mPosY=HIWORD(temp);
                         MouseConvert(mPosX, mPosY);
                     }                   
                     DefWndProc(m);

                 }

I to wg mnie dziala, wspolrzedne okna czyli mPosX i mPosY sa zawsze poprawne
dalej obliczam wspolrzedne na scenie:

void MouseConvert(int x, int y)
        {           
            GLdouble model[16];
            GLdouble proj[16];
            GLint view[4];
            GLfloat win[3];
            GLdouble pos[3];

            glGetDoublev(GL_MODELVIEW_MATRIX, model);
            glGetDoublev(GL_PROJECTION_MATRIX, proj);
            glGetIntegerv(GL_VIEWPORT, view);

            win[0] = (float)x;                  //winX
            win[1] = (float)view[3] - (float)y;     //winY

            glReadPixels( x, int(win[1]), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, win+2 );

            gluUnProject(win[0], win[1], win[2], model, proj, view, pos+0, pos+1, pos+2);

            mRoomX=pos[0];
            mRoomY=pos[1];
            mRoomZ=pos[2];
        }

w czym jest problem:
Po pierwszym kliknięciu na scenę dzieje się dokładnie to co chce, jednak każde kolejne kliknięcie niesie za sobą złe wartości współrzędnych na scenie (współrzędne na oknie są cały czas poprawne).
Zakładam, że błąd leży gdzieś po stronie obliczeń OpenGL tylko nie mam już pomysłu gdzie?

Pozostało 580 znaków

2009-07-03 11:53
Problem
0

Mam prawdopodobnie ten sam problem co Ty, rozwiazales go moze? Jak tak to chetnie dowiedzialbym sie jak :)

Pozostało 580 znaków

2009-07-04 08:45
0

Stasiuuuuu gl_DEPTH_COMPONENT jest nieposrotwany, natomiast GL_COLOR_BUFFER_BIT.

ja bym ci stasiu proponowal ustawic sobie gdzies w przestrzeni przed kamera kwadraciki o roznyvch kolorach i bym na podstawie na ktorym kwadracie jest kursor wstawil tam punkt

bool TFCOpenGL::mouse_tick( int button, int state, int x, int y, t3dpoint & obj )
{
glPushMatrix();
double *objx=new double;
double *objy=new double;
double *objz=new double;
int*viewport = new int[4];
double* projection = new double[16];
double* modelview = new double[16];
    float z;
    //get the projection matrix
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    //get the modelview matrix
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    //get the viewport
          glViewport(0, 0, FCOpenGL->Width, FCOpenGL->Height);
    glGetIntegerv( GL_VIEWPORT, viewport );

    //Read the window z co-ordinate
    //(the z value on that point in unit cube)
//  unsigned char* pdata = new unsigned char[1];
//  glReadPixels( x, FCOpenGL->Height-y, 1, 1,
//       GL_DEPTH_COMPONENT, GL_FLOAT, &z);
//                    z = pdata[0];
    //Unproject the window co-ordinates to
    //find the world co-ordinates.
//  ShowMessage(FloatToStr(z));
    gluUnProject( x, FCOpenGL->Height-y-1, 0.0, modelview,
        projection, viewport, objx, objy, objz );

         Gef1.x = (*objx);
         Gef1.y = (*objy);
         Gef1.z = (*objz);

    gluUnProject( x, FCOpenGL->Height-y-1, 0.986, modelview,
        projection, viewport, objx, objy, objz );

         Gef2.x = (*objx);
         Gef2.y = (*objy);
         Gef2.z = (*objz);
glPopMatrix();

     ballpos = vectors_add(Gef1,vector_multiple(Normalize(vectorAB(Gef1,Gef2)),1000.0f));

//       PGLVEC3 ps;
//ps=                 GetOpenGLPos(x,y);
//ballpos.x = ps.x;
//ballpos.y = ps.y;
//ballpos.z = ps.z;
//       obj = Normalize(obj);
//
//obj = vectors_add(old,vector_multiple(obj,1000.0f));

       /*
SCENE_MODELS[0]->CreateCollArrays();
ShowMessage(IntToStr(SCENE_MODELS[0]->VBO_BE.Length));

  double mvmatrix[16];
   double projmatrix[16];
   int viewport[4];
   double dX, dY, dZ, dClickY; // glUnProject uses doubles, but I'm using floats for these 3D vectors

   glGetIntegerv(GL_VIEWPORT, viewport);    
   glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
   glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
   dClickY = double (FCOpenGL->Height - y); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top

   gluUnProject ((double) x, dClickY, 0.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
t3dpoint   ClickRayP1 = triplesingletoT3DPOINT ( (float) dX, (float) dY, (float) dZ );
gluUnProject ((double) x, dClickY, 1.0, mvmatrix, projmatrix, viewport, &dX, &dY, &dZ);
t3dpoint   ClickRayP2 = triplesingletoT3DPOINT ( (float) dX, (float) dY, (float) dZ );
Gef1 = ClickRayP1;
Gef2 = ClickRayP2;

t3dpoint normal;
float distance;
//normal = Normalize(vectorAB(old,Gef2));
normal = Normalize(vectors_frontadd(FCOpenGL->old,FCOpenGL->SUPERPOINT));
distance = getplaneD(normal, old);
//SCENE_MODEL RayIntersectModel2
if (classifyapointagainstaplane(Gef2,normal,distance) == isBack) {
normal = Normalize(vectorAB(Gef1,Gef2));
normal.x = -normal.x;
normal.y = -normal.y;
normal.z = -normal.z;
distance = n3ddistance(Gef1,Gef2);
Gef2 = vectors_add(Gef1,vector_multiple(normal,distance));
}

t3dpoint line[2];
line[0] = Gef1;line[1] = Gef2;
if(SCENE_MODELS[0]->RayIntersectModel2(old,line)==true) ShowMessage("INTERSECTION");
          */
}

Tak na boku ten kod zawsze mi zwraca punkt troche za wysoko ale os X jest poprawna :S

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0