Document lmin and lmax lavcopts; mpeg vrc_buf_size values
[mplayer/greg.git] / libvo / vo_gl.c
blob8fd08bdf0efa95d68890e4961c13ec2b121e13a1
1 #define TEXTUREFORMAT_32BPP
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <math.h>
7 #include <errno.h>
9 #include "config.h"
10 #include "video_out.h"
11 #include "video_out_internal.h"
13 #include <X11/Xlib.h>
14 #include <X11/Xutil.h>
15 //#include <X11/keysym.h>
16 #include <GL/glx.h>
17 #include <errno.h>
19 #include <GL/gl.h>
21 #include "x11_common.h"
22 #include "aspect.h"
24 static vo_info_t info =
26 "X11 (OpenGL)",
27 "gl",
28 "Arpad Gereoffy <arpi@esp-team.scene.hu>",
32 LIBVO_EXTERN(gl)
34 /* local data */
35 static unsigned char *ImageData=NULL;
37 static GLXContext wsGLXContext;
38 static int wsGLXAttrib[] = { GLX_RGBA,
39 GLX_RED_SIZE,1,
40 GLX_GREEN_SIZE,1,
41 GLX_BLUE_SIZE,1,
42 GLX_DOUBLEBUFFER,
43 None };
46 static uint32_t image_width;
47 static uint32_t image_height;
48 static uint32_t image_bytes;
50 static int int_pause;
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);
62 glLoadIdentity();
63 glOrtho(0, image_width, image_height, 0, -1,1);
65 glMatrixMode(GL_MODELVIEW);
66 glLoadIdentity();
69 /* connect to server, create and map window,
70 * allocate colors and (shared) memory
72 static uint32_t
73 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
75 // int screen;
76 unsigned int fg, bg;
77 XSizeHints hint;
78 XVisualInfo *vinfo;
79 XEvent xev;
81 // XGCValues xgcv;
83 image_height = height;
84 image_width = width;
85 vo_dwidth = d_width;
86 vo_dheight = d_height;
88 int_pause = 0;
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);
95 #ifdef X11_FULLSCREEN
96 // if( flags&0x01 ){ // (-fs)
97 // aspect(&d_width,&d_height,A_ZOOM);
98 // }
99 #endif
100 hint.x = 0;
101 hint.y = 0;
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 );
114 if (vinfo == NULL)
116 printf("[gl] no GLX support present\n");
117 return -1;
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);
134 /* Map window. */
135 XMapWindow(mDisplay, vo_window);
136 if ( flags&1 ) vo_x11_fullscreen();
137 #ifdef HAVE_XINERAMA
138 vo_x11_xinerama_move(mDisplay,vo_window);
139 #endif
141 /* Wait for map. */
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 );
155 XFlush(mDisplay);
156 XSync(mDisplay, False);
158 vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PointerMotionMask
159 | ButtonPressMask | ButtonReleaseMask | ExposureMask
162 texture_width=32;
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);
172 glDisable(GL_BLEND);
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);
181 #if 1
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,
195 #else
196 glTexImage2D(GL_TEXTURE_2D, 0, image_bytes, texture_width, texture_height, 0,
197 #endif
198 (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, ImageData);
199 #endif
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
210 return 0;
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)
224 static void
225 flip_page(void)
228 // glEnable(GL_TEXTURE_2D);
229 // glBindTexture(GL_TEXTURE_2D, texture_id);
231 glColor3f(1,1,1);
232 glBegin(GL_QUADS);
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);
237 glEnd();
239 // glFlush();
240 glFinish();
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)
248 return 0;
252 static uint32_t
253 draw_frame(uint8_t *src[])
255 int i;
256 uint8_t *ImageData=src[0];
258 for(i=0;i<image_height;i+=slice_height){
259 glTexSubImage2D( GL_TEXTURE_2D, // target
260 0, // level
261 0, // x offset
262 // image_height-1-i, // y offset
263 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
271 return 0;
274 static uint32_t
275 query_format(uint32_t format)
277 if ((format == IMGFMT_RGB24) || (format == IMGFMT_RGB32))
278 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
279 return 0;
283 static void
284 uninit(void)
286 if ( !vo_config_count ) return;
287 saver_on(mDisplay); // screen saver back on
288 vo_x11_uninit();
291 static uint32_t preinit(const char *arg)
293 if(arg)
295 slice_height = atoi(arg);
296 if (slice_height <= 0)
297 slice_height = 65536;
299 else
301 slice_height = 4;
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
307 return 0;
310 static uint32_t control(uint32_t request, void *data, ...)
312 switch (request) {
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:
318 vo_x11_fullscreen();
319 return VO_TRUE;
321 return VO_NOTIMPL;