fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / avmedia / source / opengl / oglwindow.cxx
blobfe637f882c461796c985aab057ec170f1b750054
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "oglwindow.hxx"
11 #include <cppuhelper/supportsservice.hxx>
13 using namespace com::sun::star;
14 using namespace libgltf;
16 namespace avmedia { namespace ogl {
18 OGLWindow::OGLWindow( glTFHandle& rHandle, const rtl::Reference<OpenGLContext> &rContext, vcl::Window& rEventHandlerParent )
19 : m_rHandle( rHandle )
20 , m_xContext( rContext )
21 , m_rEventHandler( rEventHandlerParent )
22 , m_bVisible ( false )
23 , m_aLastMousePos(Point(0,0))
24 , m_bIsOrbitMode( false )
28 OGLWindow::~OGLWindow()
30 dispose();
33 void SAL_CALL OGLWindow::update() throw (css::uno::RuntimeException, std::exception)
35 m_xContext->makeCurrent();
36 int nRet = gltf_prepare_renderer(&m_rHandle);
37 if( nRet != 0 )
39 SAL_WARN("avmedia.opengl", "Error occurred while preparing for rendering! Error code: " << nRet);
40 return;
42 gltf_renderer(&m_rHandle);
43 gltf_complete_renderer(&m_rHandle);
44 m_xContext->swapBuffers();
47 sal_Bool SAL_CALL OGLWindow::setZoomLevel( css::media::ZoomLevel /*eZoomLevel*/ ) throw (css::uno::RuntimeException, std::exception)
49 return false;
52 css::media::ZoomLevel SAL_CALL OGLWindow::getZoomLevel() throw (css::uno::RuntimeException, std::exception)
54 return media::ZoomLevel_ORIGINAL;
57 void SAL_CALL OGLWindow::setPointerType( sal_Int32 ) throw (css::uno::RuntimeException, std::exception)
61 OUString SAL_CALL OGLWindow::getImplementationName() throw (css::uno::RuntimeException, std::exception)
63 return OUString("com.sun.star.comp.avmedia.Window_OpenGL");
66 sal_Bool SAL_CALL OGLWindow::supportsService( const OUString& rServiceName ) throw (css::uno::RuntimeException, std::exception)
68 return cppu::supportsService(this, rServiceName);
71 uno::Sequence< OUString > SAL_CALL OGLWindow::getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception)
73 uno::Sequence< OUString > aRet(1);
74 aRet[0] = "com.sun.star.media.Window_OpenGL";
75 return aRet;
78 void SAL_CALL OGLWindow::dispose() throw (uno::RuntimeException, std::exception)
80 assert(m_rEventHandler.GetParent());
81 m_rEventHandler.GetParent()->RemoveEventListener( LINK(this, OGLWindow, FocusGrabber));
82 m_rEventHandler.RemoveEventListener( LINK(this, OGLWindow, CameraHandler));
85 void SAL_CALL OGLWindow::addEventListener( const uno::Reference< lang::XEventListener >& )
86 throw (uno::RuntimeException, std::exception)
90 void SAL_CALL OGLWindow::removeEventListener( const uno::Reference< lang::XEventListener >& )
91 throw (uno::RuntimeException, std::exception)
95 void SAL_CALL OGLWindow::setPosSize( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 /*nFlags*/ )
96 throw (uno::RuntimeException, std::exception)
98 if( m_rHandle.viewport.x != nX || m_rHandle.viewport.x != nY ||
99 m_rHandle.viewport.width != nWidth || m_rHandle.viewport.height != nHeight )
101 m_xContext->setWinSize(Size(nWidth,nHeight));
102 m_rHandle.viewport.x = nX;
103 m_rHandle.viewport.y = nY;
104 m_rHandle.viewport.width = nWidth;
105 m_rHandle.viewport.height = nHeight;
109 awt::Rectangle SAL_CALL OGLWindow::getPosSize()
110 throw (uno::RuntimeException, std::exception)
112 return awt::Rectangle(m_rHandle.viewport.x, m_rHandle.viewport.y,
113 m_rHandle.viewport.width, m_rHandle.viewport.height);
116 void SAL_CALL OGLWindow::setVisible( sal_Bool bSet )
117 throw (uno::RuntimeException, std::exception)
119 assert(m_rEventHandler.GetParent());
120 if( bSet && !m_bVisible )
122 m_rEventHandler.GetParent()->AddEventListener( LINK(this, OGLWindow, FocusGrabber));
123 m_rEventHandler.AddEventListener( LINK(this, OGLWindow, CameraHandler));
124 m_rEventHandler.GrabFocus();
126 else if( !bSet )
128 m_rEventHandler.GetParent()->RemoveEventListener( LINK(this, OGLWindow, FocusGrabber));
129 m_rEventHandler.RemoveEventListener( LINK(this, OGLWindow, CameraHandler));
131 m_bVisible = bSet;
134 void SAL_CALL OGLWindow::setEnable( sal_Bool )
135 throw (uno::RuntimeException, std::exception)
139 void SAL_CALL OGLWindow::setFocus()
140 throw (uno::RuntimeException, std::exception)
144 void SAL_CALL OGLWindow::addWindowListener( const uno::Reference< awt::XWindowListener >& )
145 throw (uno::RuntimeException, std::exception)
149 void SAL_CALL OGLWindow::removeWindowListener( const uno::Reference< awt::XWindowListener >& )
150 throw (uno::RuntimeException, std::exception)
154 void SAL_CALL OGLWindow::addFocusListener( const uno::Reference< awt::XFocusListener >& )
155 throw (uno::RuntimeException, std::exception)
159 void SAL_CALL OGLWindow::removeFocusListener( const uno::Reference< awt::XFocusListener >& )
160 throw (uno::RuntimeException, std::exception)
164 void SAL_CALL OGLWindow::addKeyListener( const uno::Reference< awt::XKeyListener >& )
165 throw (uno::RuntimeException, std::exception)
169 void SAL_CALL OGLWindow::removeKeyListener( const uno::Reference< awt::XKeyListener >& )
170 throw (uno::RuntimeException, std::exception)
174 void SAL_CALL OGLWindow::addMouseListener( const uno::Reference< awt::XMouseListener >& )
175 throw (uno::RuntimeException, std::exception)
179 void SAL_CALL OGLWindow::removeMouseListener( const uno::Reference< awt::XMouseListener >& )
180 throw (uno::RuntimeException, std::exception)
184 void SAL_CALL OGLWindow::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& )
185 throw (uno::RuntimeException, std::exception)
189 void SAL_CALL OGLWindow::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& )
190 throw (uno::RuntimeException, std::exception)
194 void SAL_CALL OGLWindow::addPaintListener( const uno::Reference< awt::XPaintListener >& )
195 throw (uno::RuntimeException, std::exception)
199 void SAL_CALL OGLWindow::removePaintListener( const uno::Reference< awt::XPaintListener >& )
200 throw (uno::RuntimeException, std::exception)
204 IMPL_LINK(OGLWindow, FocusGrabber, VclWindowEvent*, pEvent)
206 if( pEvent->GetId() == VCLEVENT_WINDOW_MOUSEMOVE )
208 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(pEvent->GetData());
209 if(pMouseEvt)
211 const Point& rMousePos = pMouseEvt->GetPosPixel();
212 const Rectangle aWinRect(m_rEventHandler.GetPosPixel(),m_rEventHandler.GetSizePixel());
213 // Grab focus to the OpenGL window when mouse pointer is over it
214 if( aWinRect.IsInside(rMousePos) )
216 if ( !m_rEventHandler.HasFocus() )
218 m_rEventHandler.GrabFocus();
221 // Move focus to the document when mouse is not over the OpenGL window
222 else if ( m_rEventHandler.HasFocus() )
224 m_rEventHandler.GrabFocusToDocument();
229 return 0;
232 IMPL_LINK(OGLWindow, CameraHandler, VclWindowEvent*, pEvent)
234 if( pEvent->GetId() == VCLEVENT_WINDOW_KEYINPUT )
236 KeyEvent* pKeyEvt = static_cast<KeyEvent*>(pEvent->GetData());
237 if(pKeyEvt)
239 const sal_uInt16 nCode = pKeyEvt->GetKeyCode().GetCode();
240 if (nCode == KEY_Q || nCode == KEY_E ||
241 nCode == KEY_A || nCode == KEY_D ||
242 nCode == KEY_W || nCode == KEY_S )
244 // Calculate movement
245 glm::vec3 vMoveBy;
247 glm::vec3 vEye;
248 glm::vec3 vView;
249 glm::vec3 vUp;
250 gltf_get_camera_pos(&m_rHandle, &vEye,&vView,&vUp);
251 float fModelSize =(float)gltf_get_model_size(&m_rHandle);
253 glm::vec3 vMove = vView-vEye;
254 vMove = glm::normalize(vMove);
255 vMove *= 25.0f;
256 glm::vec3 vStrafe = glm::cross(vMove, vUp);
257 vStrafe = glm::normalize(vStrafe);
258 vStrafe *= 25.0f;
259 glm::vec3 vMup = vUp * 25.0f;
261 if( !m_bIsOrbitMode )
263 if(nCode == KEY_E)vMoveBy += vMup*(0.0005f*fModelSize);
264 if(nCode == KEY_Q)vMoveBy -= vMup*(0.0005f*fModelSize);
265 if(nCode == KEY_W)vMoveBy += vMove*(0.0005f*fModelSize);
266 if(nCode == KEY_S)vMoveBy -= vMove*(0.0005f*fModelSize);
267 if(nCode == KEY_A)vMoveBy -= vStrafe*(0.0005f*fModelSize);
268 if(nCode == KEY_D)vMoveBy += vStrafe*(0.0005f*fModelSize);
270 else
272 bool bZoomIn = false;
273 bool bZoomOut = false;
274 if(nCode == KEY_E)
276 vMoveBy += vMove*(0.0005f*fModelSize);
277 bZoomIn = true;
279 if(nCode == KEY_Q)
281 vMoveBy -= vMove*(0.0005f*fModelSize);
282 bZoomOut = true;
285 // Limit zooming in orbit mode
286 float fCameraDistFromModelGlobe = glm::length(vEye + vMoveBy - vView) - fModelSize / 2.0f;
287 if ((fCameraDistFromModelGlobe < 0.5 * fModelSize && bZoomIn ) ||
288 (fCameraDistFromModelGlobe > 2 * fModelSize && bZoomOut ))
290 vMoveBy = glm::vec3(0.0);
294 gltf_renderer_move_camera(&m_rHandle, vMoveBy.x, vMoveBy.y, vMoveBy.z, 0.0001);
296 if( m_bIsOrbitMode )
298 long nDeltaX = 0;
299 long nDeltaY = 0;
300 if (nCode == KEY_W)
302 nDeltaY -= 1;
304 if (nCode == KEY_S)
306 nDeltaY += 1;
308 if (nCode == KEY_A)
310 nDeltaX -= 1;
312 if (nCode == KEY_D)
314 nDeltaX += 1;
316 float fSensitivity = 50.0;
317 gltf_renderer_rotate_model(&m_rHandle, nDeltaX*fSensitivity, nDeltaY*fSensitivity, 0.0);
320 else if(nCode == KEY_M)
322 if(m_bIsOrbitMode)
324 gltf_orbit_mode_stop(&m_rHandle);
325 m_bIsOrbitMode = false;
327 else
329 gltf_orbit_mode_start(&m_rHandle);
330 m_bIsOrbitMode = true;
333 else if(nCode == KEY_F)
335 gltf_render_FPS_enable(&m_rHandle);
339 else if( pEvent->GetId() == VCLEVENT_WINDOW_MOUSEBUTTONDOWN )
341 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(pEvent->GetData());
342 if(pMouseEvt && pMouseEvt->IsLeft() && pMouseEvt->GetClicks() == 1)
344 m_aLastMousePos = pMouseEvt->GetPosPixel();
347 else if( pEvent->GetId() == VCLEVENT_WINDOW_MOUSEMOVE )
349 if ( !m_rEventHandler.HasFocus() )
351 m_rEventHandler.GrabFocus();
353 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(pEvent->GetData());
354 if(pMouseEvt && pMouseEvt->IsLeft() && m_aLastMousePos != Point(0,0))
356 const Point& aCurPos = pMouseEvt->GetPosPixel();
357 float fSensitivity = std::min(m_rHandle.viewport.width, m_rHandle.viewport.height);
358 if (fSensitivity == 0.0)
359 fSensitivity = 1.0;
360 else
361 fSensitivity = 540.0 / fSensitivity;
364 long nDeltaX = m_aLastMousePos.X()-aCurPos.X();
365 long nDeltaY = m_aLastMousePos.Y()-aCurPos.Y();
366 if( m_bIsOrbitMode )
368 fSensitivity *= 5;
369 gltf_renderer_rotate_model(&m_rHandle, (float)nDeltaX*fSensitivity, (float)nDeltaY*fSensitivity, 0.0);
371 else
373 // Filter out too small deltas to avoid rewrite rotation parameter with 0
374 // before rotation is done
375 if( nDeltaX != 0 || nDeltaY != 0 )
376 gltf_renderer_rotate_camera(&m_rHandle, (float)nDeltaX*fSensitivity, (float)nDeltaY*fSensitivity, 0.0);
378 m_aLastMousePos = aCurPos;
381 else if( pEvent->GetId() == VCLEVENT_WINDOW_MOUSEBUTTONUP )
383 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(pEvent->GetData());
384 if(pMouseEvt && pMouseEvt->IsLeft() && pMouseEvt->GetClicks() == 1)
386 m_aLastMousePos = Point(0,0);
389 return 0;
392 } // namespace ogl
393 } // namespace avmedia
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */