Move the sources to trunk
[opencv] / apps / StereoGR / OpenGLView.cpp
1 // OpenGLView.cpp : implementation of the COpenGLView class\r
2 //\r
3 \r
4 #include "stdafx.h"\r
5 #include "OpenGLView.h"\r
6 #include <math.h>\r
7 \r
8 typedef struct _Point3d\r
9 {\r
10   double x, y, z;\r
11 } Point3d;\r
12 \r
13 #ifdef _DEBUG\r
14 #define new DEBUG_NEW\r
15 #undef THIS_FILE\r
16 static char THIS_FILE[] = __FILE__;\r
17 #endif\r
18 \r
19 #define vector_length(a)    sqrt(a.x*a.x+a.y*a.y+a.z*a.z)\r
20 #define scalar_product(a,b)    (a.x*b.x+a.y*b.y+a.z*b.z)\r
21 #define vector_angle(a,b)    (acos(scalar_product(a,b))*180./3.1415926535)\r
22 #define vector_product_x(a,b)  (a.y*b.z-a.z*b.y)\r
23 #define vector_product_y(a,b)  (a.z*b.x-a.x*b.z)\r
24 #define vector_product_z(a,b)  (a.x*b.y-a.y*b.x)\r
25 #define vector_product(a,b,c)  c.x=vector_product_x(a,b);c.y=vector_product_y(a,b);c.z=vector_product_z(a,b)\r
26 #define sub_vector(a,b,c)    c.x=a.x-b.x;c.y=a.y-b.y;c.z=a.z-b.z\r
27 #define add_vector(a,b,c)    c.x=a.x+b.x;c.y=a.y+b.y;c.z=a.z+b.z\r
28 \r
29 #define normalize_vector(a)    {float len;len=(float)vector_length(a);if(len>0){a.x /= len;a.y /= len;a.z /= len;}}\r
30 \r
31 #define vector_lengthV(a)    sqrt(a->x*a->x+a->y*a->y+a->z*a->z)\r
32 #define normalize_vectorV(a)  {float len;len=(float)vector_lengthV(a);if(len>0){a->x /= len;a->y /= len;a->z /= len;}}\r
33 \r
34 /////////////////////////////////////////////////////////////////////////////\r
35 // COpenGLView\r
36 \r
37 IMPLEMENT_DYNCREATE(COpenGLView, CView)\r
38 \r
39 BEGIN_MESSAGE_MAP(COpenGLView, CView)\r
40   //{{AFX_MSG_MAP(COpenGLView)\r
41   ON_WM_DESTROY()\r
42   ON_WM_SIZE()\r
43   ON_WM_MOUSEMOVE()\r
44   ON_WM_LBUTTONDOWN()\r
45   ON_WM_CREATE()\r
46   //}}AFX_MSG_MAP\r
47   // Standard printing commands\r
48   ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)\r
49   ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)\r
50   ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)\r
51 END_MESSAGE_MAP()\r
52 \r
53 /////////////////////////////////////////////////////////////////////////////\r
54 // COpenGLView construction/destruction\r
55 \r
56 COpenGLView::COpenGLView() : m_pDC(0)\r
57 {\r
58   InitCameraPosition();\r
59 }\r
60 \r
61 COpenGLView::~COpenGLView()\r
62 {\r
63 //  delete m_pDC;\r
64 }\r
65 \r
66 BOOL COpenGLView::PreCreateWindow(CREATESTRUCT& cs)\r
67 {\r
68   // OpenGL òðåáóåò íàëè÷èÿ ñòèëåé WS_CLIPCHILDREN è WS_CLIPSIBLINGS\r
69   cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);\r
70 \r
71   return CView::PreCreateWindow(cs);\r
72 }\r
73 \r
74 /////////////////////////////////////////////////////////////////////////////\r
75 // COpenGLView printing\r
76 \r
77 BOOL COpenGLView::OnPreparePrinting(CPrintInfo* pInfo)\r
78 {\r
79   // default preparation\r
80   return DoPreparePrinting(pInfo);\r
81 }\r
82 \r
83 void COpenGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)\r
84 {\r
85 }\r
86 \r
87 void COpenGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)\r
88 {\r
89 }\r
90 \r
91 /////////////////////////////////////////////////////////////////////////////\r
92 // COpenGLView diagnostics\r
93 \r
94 #ifdef _DEBUG\r
95 void COpenGLView::AssertValid() const\r
96 {\r
97   CView::AssertValid();\r
98 }\r
99 \r
100 void COpenGLView::Dump(CDumpContext& dc) const\r
101 {\r
102   CView::Dump(dc);\r
103 }\r
104 \r
105 CDocument* COpenGLView::GetDocument() // non-debug version is inline\r
106 {\r
107   ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDocument)));\r
108   return (CDocument*)m_pDocument;\r
109 }\r
110 #endif //_DEBUG\r
111 \r
112 /////////////////////////////////////////////////////////////////////////////\r
113 // COpenGLView message handlers\r
114 \r
115 int COpenGLView::InitOpenGL()\r
116 {\r
117 // Ôîðìèðóåì êîíòåêñò ðàáî÷åé îáëàñòè\r
118   m_pDC = new CClientDC(this);\r
119   ASSERT(m_pDC != NULL);\r
120 \r
121 // Ïîëó÷àåì äåñêðèïòîð êîíòåêñòà óñòðîéñòâà\r
122   HDC hdc = m_pDC->GetSafeHdc();\r
123 \r
124 // Óñòàíàâëèâàåì ôîðìàò ïèêñåëåé\r
125   if (SetPixelFormat(hdc)==FALSE)\r
126     return -1;\r
127 \r
128 // Ñîçäàåì è äåëàåì òåêóùèì êîíòåêñò âîñïðîèçâåäåíèÿ\r
129   if (CreateGLContext(hdc)==FALSE)\r
130     return -1;\r
131 \r
132   return 0;\r
133 }\r
134 \r
135 void COpenGLView::OnDestroy()\r
136 {\r
137   // Ïîëó÷àåì òåêóùèé êîíòåêñò âîñïðîèçâåäåíèÿ\r
138   HGLRC  hrc = ::wglGetCurrentContext();\r
139 \r
140 // Ïåðåä óäàëåíèåì îí íå äîëæåí áûòü òåêóùèì\r
141   ::wglMakeCurrent(NULL,  NULL);\r
142 \r
143 // Óäàëÿåì êîíòåêñò âîñïðîèçâåäåíèÿ\r
144   if (hrc)\r
145     ::wglDeleteContext(hrc);\r
146 \r
147 // Óäàëÿåì êîíòåêñò ðàáî÷åé îáëàñòè\r
148   if (m_pDC)\r
149     delete m_pDC;\r
150 \r
151   CView::OnDestroy();\r
152 }\r
153 \r
154 BOOL COpenGLView::SetPixelFormat(HDC hdc)\r
155 {\r
156  // Çàïîëíÿåì ïîëÿ ñòðóêòóðû\r
157   static PIXELFORMATDESCRIPTOR pfd =   {\r
158     sizeof(PIXELFORMATDESCRIPTOR),  // ðàçìåð ñòðóêòóðû\r
159     1,                              // íîìåð âåðñèè\r
160     PFD_DRAW_TO_WINDOW   |          // ïîääåðæêà âûâîäà â îêíî\r
161     PFD_SUPPORT_OPENGL   |          // ïîääåðæêà OpenGL\r
162     PFD_DOUBLEBUFFER,               // äâîéíàÿ áóôåðèçàöèÿ\r
163     PFD_TYPE_RGBA,         // öâåòà â ðåæèìå RGBA\r
164     24,                    // 24-ðàçðÿäà íà öâåò\r
165     0, 0, 0, 0, 0, 0,      // áèòû öâåòà èãíîðèðóþòñÿ\r
166     0,                     // íå èñïîëüçóåòñÿ àëüôà ïàðàìåòð\r
167     0,                     // ñìåùåíèå öâåòîâ èãíîðèðóþòñÿ\r
168     0,                     // áóôåð àêêóìóëÿòîðà íå èñïîëüçóåòñÿ\r
169     0, 0, 0, 0,            // áèòû àêêóìóëÿòîðà èãíîðèðóþòñÿ\r
170     32,                    // 32-ðàçðÿäíûé áóôåð ãëóáèíû\r
171     0,                     // áóôåð òðàôàðåòà íå èñïîëüçóåòñÿ\r
172     0,                     // âñïîìîãàòåëüíûé áóôåð íå èñïîëüçóåòñÿ\r
173     PFD_MAIN_PLANE,        // îñíîâíîé ñëîé\r
174     0,                     // çàðåçåðâèðîâàí\r
175     0, 0, 0                // ìàñêè ñëîÿ èãíîðèðóþòñÿ\r
176   };\r
177 \r
178   int pixelFormat;\r
179 \r
180 // Ïîääåðæèâàåò ëè ñèñòåìà íåîáõîäèìûé ôîðìàò ïèêñåëåé?\r
181   if((pixelFormat = ::ChoosePixelFormat(hdc, &pfd)) == 0){\r
182     MessageBox("Ñ çàäàííûì ôîðìàòîì ïèêñåëåé ðàáîòàòü íåëüçÿ");\r
183     return FALSE;\r
184   }\r
185 \r
186   if (::SetPixelFormat(hdc, pixelFormat, &pfd) == FALSE)\r
187     {\r
188       MessageBox("Îøèáêà ïðè âûïîëíåíèè SetPixelFormat");\r
189       return FALSE;\r
190     }\r
191 \r
192   return TRUE;\r
193 }\r
194 \r
195 BOOL COpenGLView::CreateGLContext(HDC hdc)\r
196 {\r
197 \r
198 // Ñîçäàåì êîíòåêñò âîñïðîèçâåäåíèÿ\r
199   if((m_hrc = ::wglCreateContext(hdc)) == NULL)\r
200     return FALSE;\r
201 \r
202 // Äåëàåì êîíòåêñò âîñïðîèçâåäåíèÿ òåêóùèì\r
203   if(::wglMakeCurrent(hdc, m_hrc) == FALSE)\r
204     return FALSE;\r
205 \r
206   return TRUE;\r
207 }\r
208 \r
209 void COpenGLView::OnSize(UINT nType, int cx, int cy)\r
210 {\r
211   CView::OnSize(nType, cx, cy);\r
212 \r
213   m_width = cx;\r
214   m_height = cy;\r
215   SetOwnContext();\r
216   glViewport(0, 0, cx, cy);\r
217 }\r
218 \r
219 /////////////////////////////////////////////////////////////////////////////\r
220 // COpenGLView drawing\r
221 \r
222 void COpenGLView::OnDraw(CDC* pDC)\r
223 {\r
224   CDocument* pDoc = GetDocument();\r
225   ASSERT_VALID(pDoc);\r
226 }\r
227 \r
228 void COpenGLView::BeginScene()\r
229 {\r
230   SetOwnContext();\r
231   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);\r
232 }\r
233 \r
234 void COpenGLView::EndScene()\r
235 {\r
236   Swap();\r
237 }\r
238 \r
239 void COpenGLView::Swap()\r
240 {\r
241    if (m_pDC)\r
242     SwapBuffers(m_pDC->m_hDC);\r
243 }\r
244 \r
245 void COpenGLView::TrackBall(CPoint last, CPoint init, double& angle, double& x, double& y, double& z)\r
246 {\r
247   Point3d  end, start, out;\r
248   double    sum, len, norm;\r
249   double pi = 3.1415926535;\r
250 \r
251   norm = (double)__min(m_width, m_height);\r
252 \r
253   start.x = (2*init.x-m_width)/norm;\r
254   start.y = (m_height-2.*init.y)/norm;\r
255   sum = start.x*start.x + start.y*start.y;\r
256   if (sum < 1.)  start.z = sqrt(1 - sum);\r
257   else      start.z = 0.;\r
258 \r
259   end.x = (2.*last.x-m_width)/norm;\r
260   end.y = (m_height-2.*last.y)/norm;\r
261   sum = end.x*end.x + end.y*end.y;\r
262   if (sum < 1.)  end.z = sqrt(1 - sum);\r
263   else      end.z = 0.;\r
264 \r
265     ASSERT(vector_length(start)*vector_length(end)>1.0e-30);\r
266   angle = scalar_product(start,end)/(vector_length(start)*vector_length(end));\r
267 \r
268     if (angle<=-1) angle = -0.99999;\r
269     if (angle>=1) angle = 0.99999;\r
270 \r
271     angle = acos(angle)*180./pi;\r
272   out.x = vector_product_x(start,end);\r
273   out.y = vector_product_y(start,end);\r
274   out.z = vector_product_z(start,end);\r
275 \r
276   len = vector_length(out);\r
277   if (len != 0.) {\r
278     out.x /= len;\r
279     out.y /= len;\r
280     out.z /= len;\r
281   }\r
282 \r
283   x = out.x;\r
284   y = out.y;\r
285   z = out.z;\r
286 }\r
287 \r
288 void COpenGLView::SetOwnContext()\r
289 {\r
290   if (!m_hrc)\r
291     return;\r
292 \r
293   if (m_pDC) {\r
294     delete m_pDC;\r
295     m_pDC = NULL;\r
296   }\r
297 \r
298   m_pDC = new CClientDC(this);\r
299 \r
300   if (wglMakeCurrent(m_pDC->m_hDC, m_hrc))\r
301     return;\r
302 \r
303 //error handler\r
304 \r
305   return;\r
306 }\r
307 \r
308 void COpenGLView::OnMouseMove(UINT nFlags, CPoint point)\r
309 {\r
310     SetOwnContext();\r
311     if(nFlags & MK_LBUTTON)\r
312     {\r
313     if(nFlags & MK_SHIFT)\r
314     {\r
315       /* Track translation */\r
316       double x = point.x - m_mousePosition.x;\r
317       double y = point.y - m_mousePosition.y;\r
318       x /= m_width/2;\r
319       y /= m_height/2;\r
320       m_translate[0] += x;\r
321       m_translate[1] += y;\r
322 \r
323       m_mousePosition = point;\r
324     }\r
325     else\r
326     {\r
327       /* Track rotation */\r
328           double x, y, z, angle;\r
329 \r
330           TrackBall(point, m_mousePosition, angle, x, y, z);\r
331           m_mousePosition = point;\r
332 \r
333           glMatrixMode(GL_MODELVIEW);\r
334           glPushMatrix();\r
335           glLoadIdentity();\r
336           glRotated(angle, x, y, z);\r
337           glMultMatrixd(m_rotate);\r
338           glGetDoublev(GL_MODELVIEW_MATRIX, m_rotate);\r
339           glPopMatrix();\r
340     }\r
341     }\r
342 \r
343   DrawScene();\r
344 \r
345   CView::OnMouseMove(nFlags, point);\r
346 }\r
347 \r
348 void COpenGLView::OnLButtonDown(UINT nFlags, CPoint point)\r
349 {\r
350   m_mousePosition = point;\r
351   CView::OnLButtonDown(nFlags, point);\r
352 }\r
353 \r
354 void COpenGLView::InitCameraPosition()\r
355 {\r
356   for(int i = 0; i < 16; i++)\r
357     m_rotate[i] = GLdouble(i/4 == i%4);\r
358   for(i = 0; i < 3; i++)\r
359     m_translate[i] = 0;\r
360 }\r
361 \r
362 void COpenGLView::DrawScene(CDC* pDC)\r
363 {\r
364 }