Mercurial > mplayer.hg
comparison libvo/vo_gl2.c @ 2124:0bb00e528669
new version by Sven Goethel
author | arpi |
---|---|
date | Sun, 07 Oct 2001 21:35:59 +0000 |
parents | |
children | 724af64311c8 |
comparison
equal
deleted
inserted
replaced
2123:4a1c0f484497 | 2124:0bb00e528669 |
---|---|
1 #define DISP | |
2 | |
3 // this can be 3 or 4 (regarding 24bpp and 32bpp) | |
4 #define BYTES_PP 3 | |
5 | |
6 #define TEXTUREFORMAT_32BPP | |
7 | |
8 /* | |
9 * video_out_gl.c, X11/OpenGL interface | |
10 * based on video_out_x11 by Aaron Holtzman, | |
11 * and WS opengl window manager by Pontscho/Fresh! | |
12 */ | |
13 | |
14 #include <stdio.h> | |
15 #include <stdlib.h> | |
16 #include <string.h> | |
17 #include <math.h> | |
18 | |
19 #include "config.h" | |
20 #include "video_out.h" | |
21 #include "video_out_internal.h" | |
22 | |
23 | |
24 LIBVO_EXTERN(gl2) | |
25 | |
26 #include <X11/Xlib.h> | |
27 #include <X11/Xutil.h> | |
28 //#include <X11/keysym.h> | |
29 #include <GL/glx.h> | |
30 #include <errno.h> | |
31 #include "yuv2rgb.h" | |
32 | |
33 #include <GL/gl.h> | |
34 | |
35 #include "x11_common.h" | |
36 #include "aspect.h" | |
37 | |
38 #define NDEBUG | |
39 // #undef NDEBUG | |
40 | |
41 static vo_info_t vo_info = | |
42 { | |
43 "X11 (OpenGL)", | |
44 "gl2", | |
45 "Arpad Gereoffy <arpi@esp-team.scene.hu>", | |
46 "" | |
47 }; | |
48 | |
49 /* private prototypes */ | |
50 // static void Display_Image (unsigned char *ImageData); | |
51 | |
52 /* local data */ | |
53 static unsigned char *ImageData=NULL; | |
54 | |
55 /* X11 related variables */ | |
56 //static Display *mydisplay; | |
57 static Window mywindow; | |
58 //static GC mygc; | |
59 //static XImage *myximage; | |
60 //static int depth,mode; | |
61 //static XWindowAttributes attribs; | |
62 static int X_already_started = 0; | |
63 | |
64 //static int texture_id=1; | |
65 | |
66 static GLXContext wsGLXContext; | |
67 //XVisualInfo * wsVisualInfo; | |
68 static int wsGLXAttrib[] = { GLX_RGBA, | |
69 GLX_RED_SIZE,1, | |
70 GLX_GREEN_SIZE,1, | |
71 GLX_BLUE_SIZE,1, | |
72 // GLX_DEPTH_SIZE,16, | |
73 GLX_DOUBLEBUFFER, | |
74 None }; | |
75 | |
76 | |
77 static uint32_t image_width; | |
78 static uint32_t image_height; | |
79 static uint32_t image_format; | |
80 static uint32_t image_bpp; | |
81 static uint32_t image_bytes; | |
82 | |
83 static uint32_t texture_width; | |
84 static uint32_t texture_height; | |
85 static int texnumx, texnumy, memory_x_len, memory_x_start_offset, raw_line_len; | |
86 static GLfloat texpercx, texpercy; | |
87 static struct TexSquare * texgrid; | |
88 | |
89 /* The squares that are tiled to make up the game screen polygon */ | |
90 | |
91 struct TexSquare | |
92 { | |
93 GLubyte *texture; | |
94 GLuint texobj; | |
95 int isTexture; | |
96 GLfloat fx1, fy1, fx2, fy2, fx3, fy3, fx4, fy4; | |
97 GLfloat xcov, ycov; | |
98 }; | |
99 | |
100 static void CalcFlatPoint(int x,int y,GLfloat *px,GLfloat *py) | |
101 { | |
102 *px=(float)x*texpercx; | |
103 if(*px>1.0) *px=1.0; | |
104 *py=(float)y*texpercy; | |
105 if(*py>1.0) *py=1.0; | |
106 } | |
107 | |
108 static void initTextures() | |
109 { | |
110 unsigned char *line_1=0, *line_2=0, *mem_start=0; | |
111 struct TexSquare *tsq=0; | |
112 int e_x, e_y, s, i=0; | |
113 int x=0, y=0; | |
114 GLint format=0; | |
115 GLenum err; | |
116 | |
117 /* achieve the 2**e_x:=texture_width, 2**e_y:=texture_height */ | |
118 e_x=0; s=1; | |
119 while (s<texture_width) | |
120 { s*=2; e_x++; } | |
121 texture_width=s; | |
122 | |
123 e_y=0; s=1; | |
124 while (s<texture_height) | |
125 { s*=2; e_y++; } | |
126 texture_height=s; | |
127 | |
128 | |
129 /* Test the max texture size */ | |
130 do | |
131 { | |
132 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, | |
133 BYTES_PP, | |
134 texture_width, texture_height, | |
135 0, (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL); | |
136 | |
137 glGetTexLevelParameteriv | |
138 (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); | |
139 | |
140 if (format != BYTES_PP) | |
141 { | |
142 fprintf (stderr, "GLINFO: Needed texture [%dx%d] too big, trying ", | |
143 texture_height, texture_width); | |
144 | |
145 if (texture_width > texture_height) | |
146 { | |
147 e_x--; | |
148 texture_width = 1; | |
149 for (i = e_x; i > 0; i--) | |
150 texture_width *= 2; | |
151 } | |
152 else | |
153 { | |
154 e_y--; | |
155 texture_height = 1; | |
156 for (i = e_y; i > 0; i--) | |
157 texture_height *= 2; | |
158 } | |
159 | |
160 fprintf (stderr, "[%dx%d] !\n", texture_height, texture_width); | |
161 | |
162 if(texture_width < 64 || texture_height < 64) | |
163 { | |
164 fprintf (stderr, "GLERROR: Give up .. usable texture size not avaiable, or texture config error !\n"); | |
165 exit(1); | |
166 } | |
167 } | |
168 } | |
169 while (format != BYTES_PP && texture_width > 1 && texture_height > 1); | |
170 | |
171 texnumx = image_width / texture_width; | |
172 if ((image_width % texture_width) > 0) | |
173 texnumx++; | |
174 | |
175 texnumy = image_height / texture_height; | |
176 if ((image_height % texture_height) > 0) | |
177 texnumy++; | |
178 | |
179 /* Allocate the texture memory */ | |
180 | |
181 texpercx = (GLfloat) texture_width / (GLfloat) image_width; | |
182 if (texpercx > 1.0) | |
183 texpercx = 1.0; | |
184 | |
185 texpercy = (GLfloat) texture_height / (GLfloat) image_height; | |
186 if (texpercy > 1.0) | |
187 texpercy = 1.0; | |
188 | |
189 texgrid = (struct TexSquare *) | |
190 calloc (texnumx * texnumy, sizeof (struct TexSquare)); | |
191 | |
192 line_1 = (unsigned char *) ImageData; | |
193 line_2 = (unsigned char *) ImageData+(image_width*image_bytes); | |
194 | |
195 mem_start = (unsigned char *) ImageData; | |
196 | |
197 raw_line_len = line_2 - line_1; | |
198 | |
199 memory_x_len = raw_line_len / image_bytes; | |
200 | |
201 #ifndef NDEBUG | |
202 fprintf (stderr, "GLINFO: texture-usage %d*width=%d, %d*height=%d\n", | |
203 (int) texnumx, (int) texture_width, (int) texnumy, | |
204 (int) texture_height); | |
205 #endif | |
206 | |
207 for (y = 0; y < texnumy; y++) | |
208 { | |
209 for (x = 0; x < texnumx; x++) | |
210 { | |
211 tsq = texgrid + y * texnumx + x; | |
212 | |
213 if (x == texnumx - 1 && image_width % texture_width) | |
214 tsq->xcov = | |
215 (GLfloat) (image_width % texture_width) / (GLfloat) texture_width; | |
216 else | |
217 tsq->xcov = 1.0; | |
218 | |
219 if (y == texnumy - 1 && image_height % texture_height) | |
220 tsq->ycov = | |
221 (GLfloat) (image_height % texture_height) / (GLfloat) texture_height; | |
222 else | |
223 tsq->ycov = 1.0; | |
224 | |
225 CalcFlatPoint (x, y, &(tsq->fx1), &(tsq->fy1)); | |
226 CalcFlatPoint (x + 1, y, &(tsq->fx2), &(tsq->fy2)); | |
227 CalcFlatPoint (x + 1, y + 1, &(tsq->fx3), &(tsq->fy3)); | |
228 CalcFlatPoint (x, y + 1, &(tsq->fx4), &(tsq->fy4)); | |
229 | |
230 /* calculate the pixel store data, | |
231 to use the machine-bitmap for our texture | |
232 */ | |
233 memory_x_start_offset = 0 * image_bytes + | |
234 x * texture_width * image_bytes; | |
235 | |
236 tsq->texture = line_1 + | |
237 y * texture_height * raw_line_len + | |
238 memory_x_start_offset; | |
239 | |
240 tsq->isTexture=GL_FALSE; | |
241 tsq->texobj=0; | |
242 | |
243 glGenTextures (1, &(tsq->texobj)); | |
244 | |
245 glBindTexture (GL_TEXTURE_2D, tsq->texobj); | |
246 err = glGetError (); | |
247 if(err==GL_INVALID_ENUM) | |
248 { | |
249 fprintf (stderr, "GLERROR glBindTexture (glGenText) := GL_INVALID_ENUM, texnum x=%d, y=%d, texture=%d\n", x, y, tsq->texobj); | |
250 } | |
251 | |
252 if(glIsTexture(tsq->texobj) == GL_FALSE) | |
253 { | |
254 fprintf (stderr, "GLERROR ain't a texture (glGenText): texnum x=%d, y=%d, texture=%d\n", | |
255 x, y, tsq->texobj); | |
256 } else { | |
257 tsq->isTexture=GL_TRUE; | |
258 } | |
259 | |
260 glTexImage2D (GL_TEXTURE_2D, 0, | |
261 BYTES_PP, | |
262 texture_width, texture_height, | |
263 0, (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL); | |
264 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0); | |
265 | |
266 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
267 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
268 | |
269 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); | |
270 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); | |
271 | |
272 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
273 | |
274 } /* for all texnumx */ | |
275 } /* for all texnumy */ | |
276 } | |
277 | |
278 static void drawTextureDisplay () | |
279 { | |
280 struct TexSquare *square; | |
281 int x, y, xoff=0, yoff=0, wd, ht; | |
282 GLenum err; | |
283 | |
284 glColor3f(1.0,1.0,1.0); | |
285 | |
286 for (y = 0; y < texnumy; y++) | |
287 { | |
288 for (x = 0; x < texnumx; x++) | |
289 { | |
290 square = texgrid + y * texnumx + x; | |
291 | |
292 if(square->isTexture==GL_FALSE) | |
293 { | |
294 #ifndef NDEBUG | |
295 fprintf (stderr, "GLINFO ain't a texture(update): texnum x=%d, y=%d, texture=%d\n", | |
296 x, y, square->texobj); | |
297 #endif | |
298 continue; | |
299 } | |
300 | |
301 glBindTexture (GL_TEXTURE_2D, square->texobj); | |
302 err = glGetError (); | |
303 if(err==GL_INVALID_ENUM) | |
304 { | |
305 fprintf (stderr, "GLERROR glBindTexture := GL_INVALID_ENUM, texnum x=%d, y=%d, texture=%d\n", x, y, square->texobj); | |
306 } | |
307 #ifndef NDEBUG | |
308 else if(err==GL_INVALID_OPERATION) { | |
309 fprintf (stderr, "GLERROR glBindTexture := GL_INVALID_OPERATION, texnum x=%d, y=%d, texture=%d\n", x, y, square->texobj); | |
310 } | |
311 #endif | |
312 | |
313 if(glIsTexture(square->texobj) == GL_FALSE) | |
314 { | |
315 square->isTexture=GL_FALSE; | |
316 fprintf (stderr, "GLERROR ain't a texture(update): texnum x=%d, y=%d, texture=%d\n", | |
317 x, y, square->texobj); | |
318 } | |
319 | |
320 /* This is the quickest way I know of to update the texture */ | |
321 if (x < texnumx - 1) | |
322 wd = texture_width; | |
323 else | |
324 wd = image_width - texture_width * x; | |
325 | |
326 if (y < texnumy - 1) | |
327 ht = texture_height; | |
328 else | |
329 ht = image_height - texture_height * y; | |
330 | |
331 glTexSubImage2D (GL_TEXTURE_2D, 0, | |
332 xoff, yoff, | |
333 wd, ht, | |
334 (BYTES_PP==4)?GL_RGBA:GL_RGB, // format | |
335 GL_UNSIGNED_BYTE, // type | |
336 square->texture); | |
337 | |
338 #ifndef NDEBUG | |
339 fprintf (stdout, "GLINFO glTexSubImage2D texnum x=%d, y=%d, %d/%d - %d/%d\n", x, y, xoff, yoff, wd, ht); | |
340 #endif | |
341 | |
342 glBegin(GL_QUADS); | |
343 | |
344 glTexCoord2f (0, 0); | |
345 glVertex2f (square->fx1, square->fy1); | |
346 | |
347 glTexCoord2f (0, square->ycov); | |
348 glVertex2f (square->fx4, square->fy4); | |
349 | |
350 glTexCoord2f (square->xcov, square->ycov); | |
351 glVertex2f (square->fx3, square->fy3); | |
352 | |
353 glTexCoord2f (square->xcov, 0); | |
354 glVertex2f (square->fx2, square->fy2); | |
355 | |
356 #ifndef NDEBUG | |
357 fprintf (stdout, "GLINFO GL_QUADS texnum x=%d, y=%d, %f/%f %f/%f %f/%f %f/%f\n\n", x, y, square->fx1, square->fy1, square->fx4, square->fy4, | |
358 square->fx3, square->fy3, square->fx2, square->fy2); | |
359 #endif | |
360 | |
361 /* | |
362 glTexCoord2f(0,0);glVertex2i(0,0); | |
363 glTexCoord2f(0,1);glVertex2i(0,texture_height); | |
364 glTexCoord2f(1,1);glVertex2i(texture_width,texture_height); | |
365 glTexCoord2f(1,0);glVertex2i(texture_width,0); | |
366 */ | |
367 | |
368 glEnd(); | |
369 } /* for all texnumx */ | |
370 } /* for all texnumy */ | |
371 | |
372 /* YES - lets catch this error ... | |
373 */ | |
374 (void) glGetError (); | |
375 } | |
376 | |
377 | |
378 static void resize(int x,int y){ | |
379 printf("[gl] Resize: %dx%d\n",x,y); | |
380 glViewport( 0, 0, x, y ); | |
381 | |
382 glMatrixMode(GL_PROJECTION); | |
383 glLoadIdentity(); | |
384 //glOrtho(0, image_width, image_height, 0, -1,1); | |
385 glOrtho (0, 1, 1, 0, -1.0, 1.0); | |
386 | |
387 glMatrixMode(GL_MODELVIEW); | |
388 glLoadIdentity(); | |
389 } | |
390 | |
391 /* connect to server, create and map window, | |
392 * allocate colors and (shared) memory | |
393 */ | |
394 static uint32_t | |
395 init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) | |
396 { | |
397 // int screen; | |
398 int dwidth,dheight; | |
399 unsigned int fg, bg; | |
400 char *hello = (title == NULL) ? "OpenGL rulez" : title; | |
401 // char *name = ":0.0"; | |
402 XSizeHints hint; | |
403 XVisualInfo *vinfo; | |
404 XEvent xev; | |
405 | |
406 // XGCValues xgcv; | |
407 XSetWindowAttributes xswa; | |
408 unsigned long xswamask; | |
409 | |
410 image_height = height; | |
411 image_width = width; | |
412 image_format = format; | |
413 | |
414 if (X_already_started) return -1; | |
415 if(!vo_init()) return -1; | |
416 | |
417 X_already_started++; | |
418 | |
419 dwidth=d_width; dheight=d_height; | |
420 #ifdef X11_FULLSCREEN | |
421 if( flags&0x01 ){ // (-fs) | |
422 aspect(&d_width,&d_height,vo_screenwidth,vo_screenheight); | |
423 dwidth=d_width; dheight=d_height; | |
424 } | |
425 #endif | |
426 hint.x = 0; | |
427 hint.y = 0; | |
428 hint.width = d_width; | |
429 hint.height = d_height; | |
430 hint.flags = PPosition | PSize; | |
431 | |
432 /* Get some colors */ | |
433 | |
434 bg = WhitePixel(mDisplay, mScreen); | |
435 fg = BlackPixel(mDisplay, mScreen); | |
436 | |
437 /* Make the window */ | |
438 | |
439 // XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), &attribs); | |
440 | |
441 // XMatchVisualInfo(mDisplay, screen, depth, TrueColor, &vinfo); | |
442 vinfo=glXChooseVisual( mDisplay,mScreen,wsGLXAttrib ); | |
443 if (vinfo == NULL) | |
444 { | |
445 printf("[gl] no GLX support present\n"); | |
446 return -1; | |
447 } | |
448 | |
449 xswa.background_pixel = 0; | |
450 xswa.border_pixel = 1; | |
451 // xswa.colormap = XCreateColormap(mDisplay, mRootWin, vinfo.visual, AllocNone); | |
452 xswa.colormap = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone); | |
453 xswamask = CWBackPixel | CWBorderPixel | CWColormap; | |
454 // xswamask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect | CWSaveUnder | CWX | CWY | CWWidth | CWHeight; | |
455 | |
456 mywindow = XCreateWindow(mDisplay, RootWindow(mDisplay,mScreen), | |
457 hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa); | |
458 | |
459 vo_x11_classhint( mDisplay,mywindow,"gl" ); | |
460 vo_hidecursor(mDisplay,mywindow); | |
461 | |
462 wsGLXContext=glXCreateContext( mDisplay,vinfo,NULL,True ); | |
463 // XStoreName( wsDisplay,wsMyWin,wsSysName ); | |
464 | |
465 // printf("GLXcontext ok\n"); | |
466 | |
467 if ( flags&0x01 ) vo_x11_decoration( mDisplay,mywindow,0 ); | |
468 | |
469 XSelectInput(mDisplay, mywindow, StructureNotifyMask); | |
470 | |
471 /* Tell other applications about this window */ | |
472 | |
473 XSetStandardProperties(mDisplay, mywindow, hello, hello, None, NULL, 0, &hint); | |
474 | |
475 /* Map window. */ | |
476 | |
477 XMapWindow(mDisplay, mywindow); | |
478 | |
479 /* Wait for map. */ | |
480 do | |
481 { | |
482 XNextEvent(mDisplay, &xev); | |
483 } | |
484 while (xev.type != MapNotify || xev.xmap.event != mywindow); | |
485 | |
486 XSelectInput(mDisplay, mywindow, NoEventMask); | |
487 | |
488 glXMakeCurrent( mDisplay,mywindow,wsGLXContext ); | |
489 | |
490 XFlush(mDisplay); | |
491 XSync(mDisplay, False); | |
492 | |
493 // mygc = XCreateGC(mDisplay, mywindow, 0L, &xgcv); | |
494 | |
495 // myximage = XGetImage(mDisplay, mywindow, 0, 0, | |
496 // width, image_height, AllPlanes, ZPixmap); | |
497 // ImageData = myximage->data; | |
498 // bpp = myximage->bits_per_pixel; | |
499 | |
500 //XSelectInput(mDisplay, mywindow, StructureNotifyMask); // !!!! | |
501 XSelectInput(mDisplay, mywindow, StructureNotifyMask | KeyPressMask ); | |
502 | |
503 // printf("Window setup ok\n"); | |
504 | |
505 #if 0 | |
506 // If we have blue in the lowest bit then obviously RGB | |
507 mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_RGB : MODE_BGR; | |
508 #ifdef WORDS_BIGENDIAN | |
509 if (myximage->byte_order != MSBFirst) | |
510 #else | |
511 if (myximage->byte_order != LSBFirst) | |
512 #endif | |
513 { | |
514 printf("[gl] no support for non-native XImage byte order!\n"); | |
515 return -1; | |
516 } | |
517 | |
518 printf("DEPTH=%d BPP=%d\n",depth,bpp); | |
519 #endif | |
520 | |
521 /* | |
522 * If depth is 24 then it may either be a 3 or 4 byte per pixel | |
523 * format. We can't use bpp because then we would lose the | |
524 * distinction between 15/16bit depth (2 byte formate assumed). | |
525 * | |
526 * FIXME - change yuv2rgb_init to take both depth and bpp | |
527 * parameters | |
528 */ | |
529 | |
530 if(format==IMGFMT_YV12){ | |
531 yuv2rgb_init(8*BYTES_PP, MODE_BGR); | |
532 printf("[gl] YUV init OK!\n"); | |
533 image_bpp=8*BYTES_PP; | |
534 image_bytes=BYTES_PP; | |
535 } else { | |
536 image_bpp=format&0xFF; | |
537 image_bytes=(image_bpp+7)/8; | |
538 } | |
539 | |
540 ImageData=malloc(image_width*image_height*image_bytes); | |
541 memset(ImageData,128,image_width*image_height*image_bytes); | |
542 | |
543 texture_width=image_width; | |
544 texture_height=image_height; | |
545 initTextures(); | |
546 | |
547 printf("[gl] Creating %dx%d texture...\n",texture_width,texture_height); | |
548 | |
549 glDisable(GL_BLEND); | |
550 glDisable(GL_DEPTH_TEST); | |
551 glDepthMask(GL_FALSE); | |
552 glDisable(GL_CULL_FACE); | |
553 | |
554 glPixelStorei (GL_UNPACK_ROW_LENGTH, memory_x_len); | |
555 // glPixelStorei (GL_UNPACK_ALIGNMENT, 8); // causes non-12*n wide images to be broken | |
556 glEnable (GL_TEXTURE_2D); | |
557 | |
558 drawTextureDisplay (); | |
559 | |
560 printf("[gl] Creating %dx%d texture...\n",texture_width,texture_height); | |
561 | |
562 /* | |
563 #if 1 | |
564 // glBindTexture(GL_TEXTURE_2D, texture_id); | |
565 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
566 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
567 #ifdef TEXTUREFORMAT_32BPP | |
568 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture_width, texture_height, 0, | |
569 #else | |
570 glTexImage2D(GL_TEXTURE_2D, 0, BYTES_PP, texture_width, texture_height, 0, | |
571 #endif | |
572 (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL); | |
573 #endif | |
574 */ | |
575 | |
576 resize(d_width,d_height); | |
577 | |
578 glClearColor( 1.0f,0.0f,1.0f,0.0f ); | |
579 glClear( GL_COLOR_BUFFER_BIT ); | |
580 | |
581 // printf("OpenGL setup OK!\n"); | |
582 | |
583 saver_off(mDisplay); // turning off screen saver | |
584 | |
585 return 0; | |
586 } | |
587 | |
588 static const vo_info_t* | |
589 get_info(void) | |
590 { | |
591 return &vo_info; | |
592 } | |
593 | |
594 static void | |
595 Terminate_Display_Process(void) | |
596 { | |
597 getchar(); /* wait for enter to remove window */ | |
598 XDestroyWindow(mDisplay, mywindow); | |
599 XCloseDisplay(mDisplay); | |
600 X_already_started = 0; | |
601 } | |
602 | |
603 | |
604 static void check_events(void) | |
605 { | |
606 int e=vo_x11_check_events(mDisplay); | |
607 if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight); | |
608 } | |
609 | |
610 static void draw_osd(void) | |
611 { | |
612 } | |
613 | |
614 static void | |
615 flip_page(void) | |
616 { | |
617 | |
618 drawTextureDisplay(); | |
619 | |
620 // glFlush(); | |
621 glFinish(); | |
622 glXSwapBuffers( mDisplay,mywindow ); | |
623 | |
624 } | |
625 | |
626 //static inline uint32_t draw_slice_x11(uint8_t *src[], uint32_t slice_num) | |
627 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) | |
628 { | |
629 int i; | |
630 int dstride=w*BYTES_PP; | |
631 | |
632 // dstride=(dstride+15)&(~15); | |
633 | |
634 yuv2rgb(ImageData+y*raw_line_len, src[0], src[1], src[2], | |
635 w,h, dstride, stride[0],stride[1]); | |
636 | |
637 // emms (); | |
638 | |
639 #ifndef NDEBUG | |
640 printf("slice: %d/%d -> %d/%d (%dx%d)\n", | |
641 x, y, x+w-1, y+h-1, w, h); | |
642 #endif | |
643 | |
644 return 0; | |
645 } | |
646 | |
647 static inline uint32_t | |
648 draw_frame_x11_bgr(uint8_t *src[]) | |
649 { | |
650 uint8_t *s=src[0]; | |
651 uint8_t *d=ImageData; | |
652 uint8_t *de=d+3*image_width*image_height; | |
653 int i; | |
654 | |
655 // RGB->BGR | |
656 while(d<de){ | |
657 #if 1 | |
658 d[0]=s[2]; | |
659 d[1]=s[1]; | |
660 d[2]=s[0]; | |
661 s+=3;d+=3; | |
662 #else | |
663 // R1 G1 B1 R2 G2 B2 | |
664 // B1 G1 R1 B2 G2 R2 | |
665 | |
666 unsigned int a=*((unsigned int*)s); | |
667 unsigned short b=*((unsigned short*)(s+4)); | |
668 *((unsigned int*)d)=((a>>16)&0xFF)|(a&0xFF00)|((a&0xFF)<<16)|((b>>8)<<24); | |
669 *((unsigned short*)(d+4))=(b&0xFF)|((a>>24)<<8); | |
670 s+=6;d+=6; | |
671 #endif | |
672 } | |
673 | |
674 for(i=0;i<image_height;i++) ImageData[image_width*BYTES_PP*i+20]=128; | |
675 | |
676 // printf("draw_frame_x11_bgr\n"); | |
677 // drawTextureDisplay (); | |
678 | |
679 // Display_Image(ImageData); | |
680 return 0; | |
681 } | |
682 | |
683 static inline uint32_t | |
684 draw_frame_x11_rgb(uint8_t *src[]) | |
685 { | |
686 int i; | |
687 uint8_t *ImageData=src[0]; | |
688 | |
689 printf("draw_frame_x11_rgb not implemented\n"); | |
690 // drawTextureDisplay (); | |
691 | |
692 // Display_Image(ImageData); | |
693 return 0; | |
694 } | |
695 | |
696 | |
697 static uint32_t | |
698 draw_frame(uint8_t *src[]) | |
699 { | |
700 uint32_t res = 0; | |
701 | |
702 if((image_format&IMGFMT_RGB_MASK)==IMGFMT_RGB) | |
703 res = draw_frame_x11_rgb(src); | |
704 else | |
705 res = draw_frame_x11_bgr(src); | |
706 | |
707 //flip_page(); | |
708 return res; | |
709 } | |
710 | |
711 static uint32_t | |
712 query_format(uint32_t format) | |
713 { | |
714 switch(format){ | |
715 case IMGFMT_YV12: | |
716 case IMGFMT_RGB|24: | |
717 case IMGFMT_BGR|24: | |
718 return 1; | |
719 } | |
720 return 0; | |
721 } | |
722 | |
723 | |
724 static void | |
725 uninit(void) | |
726 { | |
727 saver_on(mDisplay); // screen saver back on | |
728 XDestroyWindow( mDisplay,mywindow ); | |
729 } |