Mercurial > sdl-ios-xcode
comparison test/testoverlay2.c @ 5221:16d5e8e90e01
Updated testoverlay2 to use the SDL 2D rendering API
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 07 Feb 2011 00:46:43 -0800 |
parents | 27ab20a36eba |
children | ec30f9d4c2a8 |
comparison
equal
deleted
inserted
replaced
5220:42e0e2f91c55 | 5221:16d5e8e90e01 |
---|---|
170 yuv[0] = 255; | 170 yuv[0] = 255; |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
174 void | 174 void |
175 ConvertRGBtoYV12(SDL_Surface * s, SDL_Overlay * o, int monochrome, | 175 ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h, |
176 int luminance) | 176 int monochrome, int luminance) |
177 { | 177 { |
178 int x, y; | 178 int x, y; |
179 int yuv[3]; | 179 int yuv[3]; |
180 Uint8 *p, *op[3]; | 180 Uint8 *op[3]; |
181 | 181 |
182 SDL_LockSurface(s); | 182 op[0] = out; |
183 SDL_LockYUVOverlay(o); | 183 op[1] = op[0] + w*h; |
184 | 184 op[2] = op[1] + w*h/4; |
185 /* Convert */ | 185 for (y = 0; y < h; ++y) { |
186 for (y = 0; y < s->h && y < o->h; y++) { | 186 for (x = 0; x < w; ++x) { |
187 p = ((Uint8 *) s->pixels) + s->pitch * y; | 187 RGBtoYUV(rgb, yuv, monochrome, luminance); |
188 op[0] = o->pixels[0] + o->pitches[0] * y; | |
189 op[1] = o->pixels[1] + o->pitches[1] * (y / 2); | |
190 op[2] = o->pixels[2] + o->pitches[2] * (y / 2); | |
191 for (x = 0; x < s->w && x < o->w; x++) { | |
192 RGBtoYUV(p, yuv, monochrome, luminance); | |
193 *(op[0]++) = yuv[0]; | 188 *(op[0]++) = yuv[0]; |
194 if (x % 2 == 0 && y % 2 == 0) { | 189 if (x % 2 == 0 && y % 2 == 0) { |
195 *(op[1]++) = yuv[2]; | 190 *(op[1]++) = yuv[2]; |
196 *(op[2]++) = yuv[1]; | 191 *(op[2]++) = yuv[1]; |
197 } | 192 } |
198 p += s->format->BytesPerPixel; | 193 rgb += 3; |
199 } | 194 } |
200 } | 195 } |
201 | |
202 SDL_UnlockYUVOverlay(o); | |
203 SDL_UnlockSurface(s); | |
204 } | 196 } |
205 | 197 |
206 void | 198 void |
207 ConvertRGBtoIYUV(SDL_Surface * s, SDL_Overlay * o, int monochrome, | 199 ConvertRGBtoIYUV(SDL_Surface * s, SDL_Overlay * o, int monochrome, |
208 int luminance) | 200 int luminance) |
337 { | 329 { |
338 fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0); | 330 fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0); |
339 fprintf(stderr, "\n"); | 331 fprintf(stderr, "\n"); |
340 fprintf(stderr, "Where 'arg' is any of the following options:\n"); | 332 fprintf(stderr, "Where 'arg' is any of the following options:\n"); |
341 fprintf(stderr, "\n"); | 333 fprintf(stderr, "\n"); |
342 fprintf(stderr, " -fps <frames per second>\n"); | 334 fprintf(stderr, " -fps <frames per second>\n"); |
343 fprintf(stderr, | 335 fprintf(stderr, " -nodelay\n"); |
344 " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); | 336 fprintf(stderr, " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); |
345 fprintf(stderr, | 337 fprintf(stderr, " -scale <scale factor> (initial scale of the overlay)\n"); |
346 " -scale <scale factor> (initial scale of the overlay)\n"); | 338 fprintf(stderr, " -help (shows this help)\n"); |
347 fprintf(stderr, " -help (shows this help)\n"); | |
348 fprintf(stderr, "\n"); | 339 fprintf(stderr, "\n"); |
349 fprintf(stderr, | 340 fprintf(stderr, |
350 "Press ESC to exit, or SPACE to freeze the movie while application running.\n"); | 341 "Press ESC to exit, or SPACE to freeze the movie while application running.\n"); |
351 fprintf(stderr, "\n"); | 342 fprintf(stderr, "\n"); |
352 } | 343 } |
354 int | 345 int |
355 main(int argc, char **argv) | 346 main(int argc, char **argv) |
356 { | 347 { |
357 Uint8 *RawMooseData; | 348 Uint8 *RawMooseData; |
358 SDL_RWops *handle; | 349 SDL_RWops *handle; |
359 SDL_Surface *screen; | 350 int window_w; |
360 SDL_Surface *MooseFrame[MOOSEFRAMES_COUNT]; | 351 int window_h; |
361 SDL_Overlay *overlay; | 352 SDL_Window *window; |
362 SDL_Rect overlayrect; | 353 SDL_Renderer *renderer; |
354 Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2]; | |
355 SDL_Texture *MooseTexture; | |
356 SDL_Rect displayrect; | |
363 SDL_Event event; | 357 SDL_Event event; |
364 Uint32 lastftick; | |
365 int paused = 0; | 358 int paused = 0; |
366 int resized = 0; | 359 int i, j; |
367 int i; | |
368 int fps = 12; | 360 int fps = 12; |
369 int fpsdelay; | 361 int fpsdelay; |
362 int nodelay = 0; | |
370 int overlay_format = SDL_YUY2_OVERLAY; | 363 int overlay_format = SDL_YUY2_OVERLAY; |
371 int scale = 5; | 364 int scale = 5; |
365 SDL_bool done = SDL_FALSE; | |
372 | 366 |
373 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { | 367 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { |
374 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); | 368 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); |
375 return 3; | 369 return 3; |
376 } | 370 } |
394 } else { | 388 } else { |
395 fprintf(stderr, | 389 fprintf(stderr, |
396 "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); | 390 "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); |
397 quit(10); | 391 quit(10); |
398 } | 392 } |
393 } else if (strcmp(argv[1], "-nodelay") == 0) { | |
394 nodelay = 1; | |
395 argv += 1; | |
396 argc -= 1; | |
399 } else if (strcmp(argv[1], "-format") == 0) { | 397 } else if (strcmp(argv[1], "-format") == 0) { |
400 if (argv[2]) { | 398 if (argv[2]) { |
401 if (!strcmp(argv[2], "YV12")) | 399 if (!strcmp(argv[2], "YV12")) |
402 overlay_format = SDL_YV12_OVERLAY; | 400 overlay_format = SDL_YV12_OVERLAY; |
403 else if (!strcmp(argv[2], "IYUV")) | 401 else if (!strcmp(argv[2], "IYUV")) |
469 | 467 |
470 SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); | 468 SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); |
471 | 469 |
472 SDL_RWclose(handle); | 470 SDL_RWclose(handle); |
473 | 471 |
474 /* Set video mode */ | 472 /* Create the window and renderer */ |
475 if ((screen = | 473 window_w = MOOSEPIC_W * scale; |
476 SDL_SetVideoMode(MOOSEPIC_W * scale, MOOSEPIC_H * scale, 0, | 474 window_h = MOOSEPIC_H * scale; |
477 SDL_RESIZABLE | SDL_SWSURFACE)) == NULL) { | 475 window = SDL_CreateWindow("Happy Moose", |
478 fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); | 476 SDL_WINDOWPOS_UNDEFINED, |
477 SDL_WINDOWPOS_UNDEFINED, | |
478 window_w, window_h, | |
479 SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE); | |
480 if (!window) { | |
481 fprintf(stderr, "Couldn't set create window: %s\n", SDL_GetError()); | |
479 free(RawMooseData); | 482 free(RawMooseData); |
480 quit(4); | 483 quit(4); |
481 } | 484 } |
482 | 485 |
483 /* Set the window manager title bar */ | 486 renderer = SDL_CreateRenderer(window, -1, 0); |
484 SDL_WM_SetCaption("SDL test overlay: running moose", "testoverlay2"); | 487 if (!renderer) { |
488 fprintf(stderr, "Couldn't set create renderer: %s\n", SDL_GetError()); | |
489 free(RawMooseData); | |
490 quit(4); | |
491 } | |
492 | |
493 MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H); | |
494 if (!renderer) { | |
495 fprintf(stderr, "Couldn't set create texture: %s\n", SDL_GetError()); | |
496 free(RawMooseData); | |
497 quit(5); | |
498 } | |
485 | 499 |
486 for (i = 0; i < MOOSEFRAMES_COUNT; i++) { | 500 for (i = 0; i < MOOSEFRAMES_COUNT; i++) { |
487 MooseFrame[i] = | 501 Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3]; |
488 SDL_CreateRGBSurfaceFrom(RawMooseData + i * MOOSEFRAME_SIZE, | 502 Uint8 *rgb; |
489 MOOSEPIC_W, MOOSEPIC_H, 8, MOOSEPIC_W, | 503 Uint8 *frame; |
490 0, 0, 0, 0); | 504 |
491 if (MooseFrame[i] == NULL) { | 505 rgb = MooseFrameRGB; |
492 fprintf(stderr, "Couldn't create SDL_Surfaces:%s\n", | 506 frame = RawMooseData + i * MOOSEFRAME_SIZE; |
493 SDL_GetError()); | 507 for (j = 0; j < MOOSEFRAME_SIZE; ++j) { |
494 free(RawMooseData); | 508 rgb[0] = MooseColors[frame[j]].r; |
495 quit(5); | 509 rgb[1] = MooseColors[frame[j]].g; |
496 } | 510 rgb[2] = MooseColors[frame[j]].b; |
497 SDL_SetColors(MooseFrame[i], MooseColors, 0, 84); | 511 rgb += 3; |
498 | 512 } |
499 { | 513 ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100); |
500 SDL_Surface *newsurf; | |
501 SDL_PixelFormat format; | |
502 | |
503 format.palette = NULL; | |
504 format.BitsPerPixel = 32; | |
505 format.BytesPerPixel = 4; | |
506 #if SDL_BYTEORDER == SDL_LIL_ENDIAN | |
507 format.Rshift = 0; | |
508 format.Gshift = 8; | |
509 format.Bshift = 16; | |
510 #else | |
511 format.Rshift = 24; | |
512 format.Gshift = 16; | |
513 format.Bshift = 8; | |
514 #endif | |
515 format.Ashift = 0; | |
516 format.Rmask = 0xff << format.Rshift; | |
517 format.Gmask = 0xff << format.Gshift; | |
518 format.Bmask = 0xff << format.Bshift; | |
519 format.Amask = 0; | |
520 format.Rloss = 0; | |
521 format.Gloss = 0; | |
522 format.Bloss = 0; | |
523 format.Aloss = 8; | |
524 | |
525 newsurf = | |
526 SDL_ConvertSurface(MooseFrame[i], &format, SDL_SWSURFACE); | |
527 if (!newsurf) { | |
528 fprintf(stderr, | |
529 "Couldn't convert picture to 32bits RGB: %s\n", | |
530 SDL_GetError()); | |
531 quit(6); | |
532 } | |
533 SDL_FreeSurface(MooseFrame[i]); | |
534 MooseFrame[i] = newsurf; | |
535 } | |
536 } | 514 } |
537 | 515 |
538 free(RawMooseData); | 516 free(RawMooseData); |
539 | |
540 overlay = | |
541 SDL_CreateYUVOverlay(MOOSEPIC_W, MOOSEPIC_H, overlay_format, screen); | |
542 if (!overlay) { | |
543 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); | |
544 quit(7); | |
545 } | |
546 | |
547 printf("Created %dx%dx%d %s %s overlay\n", overlay->w, overlay->h, | |
548 overlay->planes, overlay->hw_overlay ? "hardware" : "software", | |
549 overlay->format == SDL_YV12_OVERLAY ? "YV12" : overlay->format == | |
550 SDL_IYUV_OVERLAY ? "IYUV" : overlay->format == | |
551 SDL_YUY2_OVERLAY ? "YUY2" : overlay->format == | |
552 SDL_UYVY_OVERLAY ? "UYVY" : overlay->format == | |
553 SDL_YVYU_OVERLAY ? "YVYU" : "Unknown"); | |
554 | |
555 for (i = 0; i < overlay->planes; i++) { | |
556 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]); | |
557 } | |
558 | |
559 overlayrect.x = 0; | |
560 overlayrect.y = 0; | |
561 overlayrect.w = MOOSEPIC_W * scale; | |
562 overlayrect.h = MOOSEPIC_H * scale; | |
563 | 517 |
564 /* set the start frame */ | 518 /* set the start frame */ |
565 i = 0; | 519 i = 0; |
566 fpsdelay = 1000 / fps; | 520 if (nodelay) { |
521 fpsdelay = 0; | |
522 } else { | |
523 fpsdelay = 1000 / fps; | |
524 } | |
525 | |
526 displayrect.x = 0; | |
527 displayrect.y = 0; | |
528 displayrect.w = window_w; | |
529 displayrect.h = window_h; | |
567 | 530 |
568 /* Ignore key up events, they don't even get filtered */ | 531 /* Ignore key up events, they don't even get filtered */ |
569 SDL_EventState(SDL_KEYUP, SDL_IGNORE); | 532 SDL_EventState(SDL_KEYUP, SDL_IGNORE); |
570 | 533 |
571 lastftick = SDL_GetTicks(); | |
572 | |
573 /* Loop, waiting for QUIT or RESIZE */ | 534 /* Loop, waiting for QUIT or RESIZE */ |
574 while (1) { | 535 while (!done) { |
575 if (SDL_PollEvent(&event)) { | 536 while (SDL_PollEvent(&event)) { |
576 switch (event.type) { | 537 switch (event.type) { |
577 case SDL_VIDEORESIZE: | 538 case SDL_WINDOWEVENT: |
578 screen = | 539 if (event.window.event == SDL_WINDOWEVENT_RESIZED) { |
579 SDL_SetVideoMode(event.resize.w, event.resize.h, 0, | 540 displayrect.w = window_w = event.window.data1; |
580 SDL_RESIZABLE | SDL_SWSURFACE); | 541 displayrect.w = window_h = event.window.data2; |
581 overlayrect.w = event.resize.w; | |
582 overlayrect.h = event.resize.h; | |
583 if (paused) { | |
584 resized = 1; | |
585 } | 542 } |
586 break; | 543 break; |
587 case SDL_MOUSEBUTTONDOWN: | 544 case SDL_MOUSEBUTTONDOWN: |
588 overlayrect.x = event.button.x - overlayrect.w / 2; | 545 displayrect.x = event.button.x - window_w / 2; |
589 overlayrect.y = event.button.y - overlayrect.h / 2; | 546 displayrect.y = event.button.y - window_h / 2; |
547 break; | |
548 case SDL_MOUSEMOTION: | |
549 if (event.motion.state) { | |
550 displayrect.x = event.motion.x - window_w / 2; | |
551 displayrect.y = event.motion.y - window_h / 2; | |
552 } | |
590 break; | 553 break; |
591 case SDL_KEYDOWN: | 554 case SDL_KEYDOWN: |
592 if (event.key.keysym.sym == SDLK_SPACE) { | 555 if (event.key.keysym.sym == SDLK_SPACE) { |
593 paused = !paused; | 556 paused = !paused; |
594 break; | 557 break; |
595 } | 558 } |
596 if (event.key.keysym.sym != SDLK_ESCAPE) { | 559 if (event.key.keysym.sym != SDLK_ESCAPE) { |
597 break; | 560 break; |
598 } | 561 } |
599 case SDL_QUIT: | 562 case SDL_QUIT: |
600 SDL_FreeYUVOverlay(overlay); | 563 done = SDL_TRUE; |
601 for (i = 0; i < MOOSEFRAMES_COUNT; i++) { | 564 break; |
602 SDL_FreeSurface(MooseFrame[i]); | 565 } |
603 } | 566 } |
604 quit(0); | 567 SDL_Delay(fpsdelay); |
605 } | 568 |
606 } | 569 if (!paused) { |
607 | 570 i = (i + 1) % MOOSEFRAMES_COUNT; |
608 if ((!paused) || (resized)) { | 571 |
609 if (((SDL_GetTicks() - lastftick) > (Uint32)fpsdelay) || (resized)) { | 572 SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*2); |
610 lastftick = SDL_GetTicks(); | 573 } |
611 | 574 SDL_RenderClear(renderer); |
612 switch (overlay_format) { | 575 SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect); |
613 case SDL_YUY2_OVERLAY: | 576 SDL_RenderPresent(renderer); |
614 ConvertRGBtoYUY2(MooseFrame[i], overlay, 0, 100); | 577 } |
615 break; | 578 SDL_DestroyRenderer(renderer); |
616 case SDL_YV12_OVERLAY: | 579 quit(0); |
617 ConvertRGBtoYV12(MooseFrame[i], overlay, 0, 100); | |
618 break; | |
619 case SDL_UYVY_OVERLAY: | |
620 ConvertRGBtoUYVY(MooseFrame[i], overlay, 0, 100); | |
621 break; | |
622 case SDL_YVYU_OVERLAY: | |
623 ConvertRGBtoYVYU(MooseFrame[i], overlay, 0, 100); | |
624 break; | |
625 case SDL_IYUV_OVERLAY: | |
626 ConvertRGBtoIYUV(MooseFrame[i], overlay, 0, 100); | |
627 break; | |
628 } | |
629 | |
630 SDL_DisplayYUVOverlay(overlay, &overlayrect); | |
631 if (!resized) { | |
632 i++; | |
633 if (i == 10) { | |
634 i = 0; | |
635 } | |
636 } else { | |
637 resized = 0; | |
638 } | |
639 } | |
640 } | |
641 /* kind of timeslice to OS */ | |
642 SDL_Delay(1); | |
643 } | |
644 | |
645 SDL_Quit(); | |
646 return 0; | 580 return 0; |
647 } | 581 } |
582 | |
583 /* vi: set ts=4 sw=4 expandtab: */ |