[OpenGL/C+/CLI] wspolrzedne myszy gluUnProject

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?

0

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

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

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