1 /*****************************************************************************
2 * glwin32.c: Windows OpenGL provider
3 *****************************************************************************
4 * Copyright (C) 2001-2009 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
28 #include <vlc_common.h>
29 #include <vlc_plugin.h>
30 #include <vlc_vout_display.h>
31 #include <vlc_opengl.h>
34 #include <versionhelpers.h>
37 #include "../opengl/filter_draw.h"
38 #include "../opengl/renderer.h"
39 #include "../opengl/vout_helper.h"
43 /*****************************************************************************
45 *****************************************************************************/
46 static int Open (vout_display_t
*, const vout_display_cfg_t
*,
47 video_format_t
*, vlc_video_context
*);
48 static void Close(vout_display_t
*);
51 set_category(CAT_VIDEO
)
52 set_subcategory(SUBCAT_VIDEO_VOUT
)
53 set_shortname("OpenGL")
54 set_description(N_("OpenGL video output for Windows"))
55 add_shortcut("glwin32", "opengl")
56 set_callback_display(Open
, 275)
59 add_opengl_submodule_renderer()
60 add_opengl_submodule_draw()
63 /*****************************************************************************
65 *****************************************************************************/
66 struct vout_display_sys_t
68 vout_display_sys_win32_t sys
;
69 display_win32_area_t area
;
72 vout_display_opengl_t
*vgl
;
78 static void Prepare(vout_display_t
*, picture_t
*, subpicture_t
*, vlc_tick_t
);
79 static void Display(vout_display_t
*, picture_t
*);
81 static int SetViewpoint(vout_display_t
*vd
, const vlc_viewpoint_t
*vp
)
83 vout_display_sys_t
*sys
= vd
->sys
;
84 return vout_display_opengl_SetViewpoint(sys
->vgl
, vp
);
87 static int Control(vout_display_t
*vd
, int query
)
89 vout_display_sys_t
*sys
= vd
->sys
;
90 return CommonControl(vd
, &sys
->area
, &sys
->sys
, query
);
93 static const struct vout_window_operations embedVideoWindow_Ops
=
97 static vout_window_t
*EmbedVideoWindow_Create(vout_display_t
*vd
)
99 vout_display_sys_t
*sys
= vd
->sys
;
101 vout_window_t
*wnd
= vlc_object_create(vd
, sizeof(vout_window_t
));
105 wnd
->type
= VOUT_WINDOW_TYPE_HWND
;
106 wnd
->handle
.hwnd
= sys
->sys
.hvideownd
;
107 wnd
->ops
= &embedVideoWindow_Ops
;
111 static const struct vlc_display_operations ops
= {
112 Close
, Prepare
, Display
, Control
, NULL
, SetViewpoint
,
116 * It creates an OpenGL vout display.
118 static int Open(vout_display_t
*vd
, const vout_display_cfg_t
*cfg
,
119 video_format_t
*fmtp
, vlc_video_context
*context
)
121 vout_display_sys_t
*sys
;
123 /* do not use OpenGL on XP unless forced */
124 if(!vd
->obj
.force
&& !IsWindowsVistaOrGreater())
127 /* Allocate structure */
128 vd
->sys
= sys
= calloc(1, sizeof(*sys
));
133 CommonInit(&sys
->area
);
134 if (CommonWindowInit(vd
, &sys
->area
, &sys
->sys
,
135 vd
->source
->projection_mode
!= PROJECTION_MODE_RECTANGULAR
))
138 if (vd
->source
->projection_mode
!= PROJECTION_MODE_RECTANGULAR
)
139 sys
->p_sensors
= HookWindowsSensors(vd
, sys
->sys
.hvideownd
);
141 vout_window_SetTitle(cfg
->window
, VOUT_TITLE
" (OpenGL output)");
143 vout_display_cfg_t embed_cfg
= *cfg
;
144 embed_cfg
.window
= EmbedVideoWindow_Create(vd
);
145 if (!embed_cfg
.window
)
148 char *modlist
= var_InheritString(embed_cfg
.window
, "gl");
149 sys
->gl
= vlc_gl_Create(&embed_cfg
, VLC_OPENGL
, modlist
);
153 vlc_object_delete(embed_cfg
.window
);
157 vlc_gl_Resize (sys
->gl
, cfg
->display
.width
, cfg
->display
.height
);
159 const vlc_fourcc_t
*subpicture_chromas
;
160 if (vlc_gl_MakeCurrent (sys
->gl
))
162 sys
->vgl
= vout_display_opengl_New(fmtp
, &subpicture_chromas
, sys
->gl
,
163 &cfg
->viewpoint
, context
);
164 vlc_gl_ReleaseCurrent (sys
->gl
);
168 /* Setup vout_display now that everything is fine */
169 vd
->info
.subpicture_chromas
= subpicture_chromas
;
181 * It destroys an OpenGL vout display.
183 static void Close(vout_display_t
*vd
)
185 vout_display_sys_t
*sys
= vd
->sys
;
186 vlc_gl_t
*gl
= sys
->gl
;
190 vout_window_t
*surface
= gl
->surface
;
193 vlc_gl_MakeCurrent (gl
);
194 vout_display_opengl_Delete(sys
->vgl
);
195 vlc_gl_ReleaseCurrent (gl
);
198 vlc_object_delete(surface
);
201 UnhookWindowsSensors(sys
->p_sensors
);
202 CommonWindowClean(&sys
->sys
);
208 static void Prepare(vout_display_t
*vd
, picture_t
*picture
, subpicture_t
*subpicture
,
212 vout_display_sys_t
*sys
= vd
->sys
;
214 if (vlc_gl_MakeCurrent (sys
->gl
) != VLC_SUCCESS
)
216 if (sys
->area
.place_changed
)
218 vout_display_cfg_t place_cfg
= *vd
->cfg
;
219 vout_display_place_t place
;
221 /* Reverse vertical alignment as the GL tex are Y inverted */
222 if (place_cfg
.align
.vertical
== VLC_VIDEO_ALIGN_TOP
)
223 place_cfg
.align
.vertical
= VLC_VIDEO_ALIGN_BOTTOM
;
224 else if (place_cfg
.align
.vertical
== VLC_VIDEO_ALIGN_BOTTOM
)
225 place_cfg
.align
.vertical
= VLC_VIDEO_ALIGN_TOP
;
227 vout_display_PlacePicture(&place
, vd
->source
, &place_cfg
);
229 const int width
= place
.width
;
230 const int height
= place
.height
;
231 vlc_gl_Resize (sys
->gl
, width
, height
);
232 vout_display_opengl_SetWindowAspectRatio(sys
->vgl
, (float)width
/ height
);
233 vout_display_opengl_Viewport(sys
->vgl
, place
.x
, place
.y
, width
, height
);
234 sys
->area
.place_changed
= false;
236 vout_display_opengl_Prepare (sys
->vgl
, picture
, subpicture
);
237 vlc_gl_ReleaseCurrent (sys
->gl
);
240 static void Display(vout_display_t
*vd
, picture_t
*picture
)
242 vout_display_sys_t
*sys
= vd
->sys
;
245 if (vlc_gl_MakeCurrent (sys
->gl
) == VLC_SUCCESS
)
247 vout_display_opengl_Display(sys
->vgl
);
248 vlc_gl_ReleaseCurrent (sys
->gl
);