1 #define TEXTUREFORMAT_32BPP
10 #include "video_out.h"
11 #include "video_out_internal.h"
14 #include <X11/Xutil.h>
15 //#include <X11/keysym.h>
21 #include "x11_common.h"
24 static vo_info_t info
=
28 "Arpad Gereoffy <arpi@esp-team.scene.hu>",
35 static unsigned char *ImageData
=NULL
;
37 static GLXContext wsGLXContext
;
38 static int wsGLXAttrib
[] = { GLX_RGBA
,
46 static uint32_t image_width
;
47 static uint32_t image_height
;
48 static uint32_t image_bytes
;
52 static uint32_t texture_width
;
53 static uint32_t texture_height
;
55 static int slice_height
=1;
57 static void resize(int x
,int y
){
58 printf("[gl] Resize: %dx%d\n",x
,y
);
59 glViewport( 0, 0, x
, y
);
61 glMatrixMode(GL_PROJECTION
);
63 glOrtho(0, image_width
, image_height
, 0, -1,1);
65 glMatrixMode(GL_MODELVIEW
);
69 /* connect to server, create and map window,
70 * allocate colors and (shared) memory
73 config(uint32_t width
, uint32_t height
, uint32_t d_width
, uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
83 image_height
= height
;
86 vo_dheight
= d_height
;
90 aspect_save_orig(width
,height
);
91 aspect_save_prescale(d_width
,d_height
);
92 aspect_save_screenres(vo_screenwidth
,vo_screenheight
);
94 aspect(&d_width
,&d_height
,A_NOZOOM
);
96 // if( flags&0x01 ){ // (-fs)
97 // aspect(&d_width,&d_height,A_ZOOM);
102 hint
.width
= d_width
;
103 hint
.height
= d_height
;
104 hint
.flags
= PPosition
| PSize
;
106 /* Get some colors */
108 bg
= WhitePixel(mDisplay
, mScreen
);
109 fg
= BlackPixel(mDisplay
, mScreen
);
111 /* Make the window */
113 vinfo
=glXChooseVisual( mDisplay
,mScreen
,wsGLXAttrib
);
116 printf("[gl] no GLX support present\n");
122 if ( vo_window
== None
)
124 vo_window
= vo_x11_create_smooth_window(mDisplay
, mRootWin
, vinfo
->visual
, hint
.x
, hint
.y
, hint
.width
, hint
.height
,
125 vinfo
->depth
, XCreateColormap(mDisplay
, mRootWin
, vinfo
->visual
, AllocNone
));
127 vo_x11_classhint( mDisplay
,vo_window
,"gl" );
128 vo_hidecursor(mDisplay
,vo_window
);
130 // if ( flags&0x01 ) vo_x11_decoration( mDisplay,vo_window,0 );
131 XSelectInput(mDisplay
, vo_window
, StructureNotifyMask
);
132 /* Tell other applications about this window */
133 XSetStandardProperties(mDisplay
, vo_window
, title
, title
, None
, NULL
, 0, &hint
);
135 XMapWindow(mDisplay
, vo_window
);
136 if ( flags
&1 ) vo_x11_fullscreen();
138 vo_x11_xinerama_move(mDisplay
,vo_window
);
144 XNextEvent(mDisplay
, &xev
);
146 while (xev
.type
!= MapNotify
|| xev
.xmap
.event
!= vo_window
);
148 XSelectInput(mDisplay
, vo_window
, NoEventMask
);
151 if ( vo_config_count
) glXDestroyContext( mDisplay
,wsGLXContext
);
152 wsGLXContext
=glXCreateContext( mDisplay
,vinfo
,NULL
,True
);
153 glXMakeCurrent( mDisplay
,vo_window
,wsGLXContext
);
156 XSync(mDisplay
, False
);
158 vo_x11_selectinput_witherr(mDisplay
, vo_window
, StructureNotifyMask
| KeyPressMask
| PointerMotionMask
159 | ButtonPressMask
| ButtonReleaseMask
| ExposureMask
163 while(texture_width
<image_width
|| texture_width
<image_height
) texture_width
*=2;
164 texture_height
=texture_width
;
166 image_bytes
=(IMGFMT_RGB_DEPTH(format
)+7)/8;
168 if ( ImageData
) free( ImageData
);
169 ImageData
=malloc(texture_width
*texture_height
*image_bytes
);
170 memset(ImageData
,128,texture_width
*texture_height
*image_bytes
);
173 glDisable(GL_DEPTH_TEST
);
174 glDepthMask(GL_FALSE
);
175 glDisable(GL_CULL_FACE
);
177 glEnable(GL_TEXTURE_2D
);
179 printf("[gl] Creating %dx%d texture...\n",texture_width
,texture_height
);
182 // glBindTexture(GL_TEXTURE_2D, texture_id);
183 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
184 glTexParameterf(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
185 /* Old OpenGL 1.0 used the third parameter (known as internalFormat) as an
186 integer, which indicated the bytes per pixel (bpp). Later in OpenGL 1.1
187 they switched to constants, like GL_RGB8. GL_RGB8 means 8 bits for each
188 channel (R,G,B), so it's equal to RGB24. It should be safe to pass the
189 image_bytes to internalFormat with newer OpenGL versions.
190 Anyway, I'm leaving this so as it was, it doesn't hurt, as OpenGL 1.1 is
191 about 10 years old too. -- alex
193 #ifdef TEXTUREFORMAT_32BPP
194 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB8
, texture_width
, texture_height
, 0,
196 glTexImage2D(GL_TEXTURE_2D
, 0, image_bytes
, texture_width
, texture_height
, 0,
198 (image_bytes
==4)?GL_RGBA
:GL_BGR
, GL_UNSIGNED_BYTE
, ImageData
);
201 resize(d_width
,d_height
);
203 glClearColor( 1.0f
,0.0f
,1.0f
,0.0f
);
204 glClear( GL_COLOR_BUFFER_BIT
);
206 // printf("OpenGL setup OK!\n");
208 saver_off(mDisplay
); // turning off screen saver
213 static void check_events(void)
215 int e
=vo_x11_check_events(mDisplay
);
216 if(e
&VO_EVENT_RESIZE
) resize(vo_dwidth
,vo_dheight
);
217 if(e
&VO_EVENT_EXPOSE
&& int_pause
) flip_page();
220 static void draw_osd(void)
228 // glEnable(GL_TEXTURE_2D);
229 // glBindTexture(GL_TEXTURE_2D, texture_id);
233 glTexCoord2f(0,0);glVertex2i(0,0);
234 glTexCoord2f(0,1);glVertex2i(0,texture_height
);
235 glTexCoord2f(1,1);glVertex2i(texture_width
,texture_height
);
236 glTexCoord2f(1,0);glVertex2i(texture_width
,0);
241 glXSwapBuffers( mDisplay
,vo_window
);
245 //static inline uint32_t draw_slice_x11(uint8_t *src[], uint32_t slice_num)
246 static uint32_t draw_slice(uint8_t *src
[], int stride
[], int w
,int h
,int x
,int y
)
253 draw_frame(uint8_t *src
[])
256 uint8_t *ImageData
=src
[0];
258 for(i
=0;i
<image_height
;i
+=slice_height
){
259 glTexSubImage2D( GL_TEXTURE_2D
, // target
262 // image_height-1-i, // y offset
264 image_width
, // width
265 (i
+slice_height
<=image_height
)?slice_height
:image_height
-i
, // height
266 (image_bytes
==4)?GL_RGBA
:GL_RGB
, // format
267 GL_UNSIGNED_BYTE
, // type
268 ImageData
+i
*image_bytes
*image_width
); // *pixels
275 query_format(uint32_t format
)
277 if ((format
== IMGFMT_RGB24
) || (format
== IMGFMT_RGB32
))
278 return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
286 if ( !vo_config_count
) return;
287 saver_on(mDisplay
); // screen saver back on
291 static uint32_t preinit(const char *arg
)
295 slice_height
= atoi(arg
);
296 if (slice_height
<= 0)
297 slice_height
= 65536;
303 printf("[vo_gl] Using %d as slice_height (0 means image_height).\n", slice_height
);
305 if( !vo_init() ) return -1; // Can't open X11
310 static uint32_t control(uint32_t request
, void *data
, ...)
313 case VOCTRL_PAUSE
: return (int_pause
=1);
314 case VOCTRL_RESUME
: return (int_pause
=0);
315 case VOCTRL_QUERY_FORMAT
:
316 return query_format(*((uint32_t*)data
));
317 case VOCTRL_FULLSCREEN
: