comparison src/video/SDL_renderer_sw.c @ 3536:0267b8b1595c

Added interfaces for batch drawing of points, lines and rects: SDL_DrawPoints() SDL_BlendPoints() SDL_BlendLines() SDL_DrawLines() SDL_FillRects() SDL_BlendRects() SDL_RenderPoints() SDL_RenderLines() SDL_RenderRects() Renamed SDL_RenderFill() to SDL_RenderRect()
author Sam Lantinga <slouken@libsdl.org>
date Wed, 09 Dec 2009 15:56:56 +0000
parents 9f62f47d989b
children f638ded38b8a
comparison
equal deleted inserted replaced
3535:b403f790df65 3536:0267b8b1595c
57 int pitch); 57 int pitch);
58 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 58 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
59 const SDL_Rect * rect, int markDirty, void **pixels, 59 const SDL_Rect * rect, int markDirty, void **pixels,
60 int *pitch); 60 int *pitch);
61 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 61 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
62 static int SW_RenderPoint(SDL_Renderer * renderer, int x, int y); 62 static int SW_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
63 static int SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, 63 int count);
64 int y2); 64 static int SW_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
65 static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); 65 int count);
66 static int SW_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
67 int count);
66 static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 68 static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
67 const SDL_Rect * srcrect, const SDL_Rect * dstrect); 69 const SDL_Rect * srcrect, const SDL_Rect * dstrect);
68 static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 70 static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
69 Uint32 format, void * pixels, int pitch); 71 Uint32 format, void * pixels, int pitch);
70 static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, 72 static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
226 return NULL; 228 return NULL;
227 } 229 }
228 renderer->ActivateRenderer = SW_ActivateRenderer; 230 renderer->ActivateRenderer = SW_ActivateRenderer;
229 renderer->DisplayModeChanged = SW_DisplayModeChanged; 231 renderer->DisplayModeChanged = SW_DisplayModeChanged;
230 232
231 renderer->RenderPoint = SW_RenderPoint; 233 renderer->RenderPoints = SW_RenderPoints;
232 renderer->RenderLine = SW_RenderLine; 234 renderer->RenderLines = SW_RenderLines;
233 renderer->RenderFill = SW_RenderFill; 235 renderer->RenderRects = SW_RenderRects;
234 renderer->RenderCopy = SW_RenderCopy; 236 renderer->RenderCopy = SW_RenderCopy;
235 renderer->RenderReadPixels = SW_RenderReadPixels; 237 renderer->RenderReadPixels = SW_RenderReadPixels;
236 renderer->RenderWritePixels = SW_RenderWritePixels; 238 renderer->RenderWritePixels = SW_RenderWritePixels;
237 renderer->RenderPresent = SW_RenderPresent; 239 renderer->RenderPresent = SW_RenderPresent;
238 renderer->DestroyRenderer = SW_DestroyRenderer; 240 renderer->DestroyRenderer = SW_DestroyRenderer;
535 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata); 537 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
536 } 538 }
537 } 539 }
538 540
539 static int 541 static int
540 SW_RenderPoint(SDL_Renderer * renderer, int x, int y) 542 SW_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
541 { 543 {
542 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; 544 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
545 SDL_Texture *texture = data->texture[data->current_texture];
543 SDL_Rect rect; 546 SDL_Rect rect;
544 int status; 547 int i;
545 548 int x, y;
546 rect.x = x; 549 int status = 0;
547 rect.y = y; 550
548 rect.w = 1; 551 /* Get the smallest rectangle that contains everything */
549 rect.h = 1; 552 rect.x = 0;
553 rect.y = 0;
554 rect.w = texture->w;
555 rect.h = texture->h;
556 if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
557 /* Nothing to draw */
558 return 0;
559 }
550 560
551 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { 561 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
552 SDL_AddDirtyRect(&data->dirty, &rect); 562 SDL_AddDirtyRect(&data->dirty, &rect);
553 } 563 }
554 564
555 if (data->renderer->LockTexture(data->renderer, 565 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
556 data->texture[data->current_texture],
557 &rect, 1,
558 &data->surface.pixels, 566 &data->surface.pixels,
559 &data->surface.pitch) < 0) { 567 &data->surface.pitch) < 0) {
560 return -1; 568 return -1;
561 } 569 }
562 570
563 data->surface.w = 1; 571 data->surface.clip_rect.w = data->surface.w = rect.w;
564 data->surface.h = 1; 572 data->surface.clip_rect.h = data->surface.h = rect.h;
565 data->surface.clip_rect.w = 1; 573
566 data->surface.clip_rect.h = 1; 574 /* Draw the points! */
567
568 if (renderer->blendMode == SDL_BLENDMODE_NONE || 575 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
569 renderer->blendMode == SDL_BLENDMODE_MASK) { 576 renderer->blendMode == SDL_BLENDMODE_MASK) {
570 Uint32 color = 577 Uint32 color = SDL_MapRGBA(data->surface.format,
571 SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, 578 renderer->r, renderer->g, renderer->b,
572 renderer->b, renderer->a); 579 renderer->a);
573 580
574 status = SDL_DrawPoint(&data->surface, 0, 0, color); 581 for (i = 0; i < count; ++i) {
575 } else { 582 x = points[i].x - rect.x;
576 status = 583 y = points[i].y - rect.y;
577 SDL_BlendPoint(&data->surface, 0, 0, renderer->blendMode, 584
578 renderer->r, renderer->g, renderer->b, 585 status = SDL_DrawPoint(&data->surface, x, y, color);
579 renderer->a); 586 }
580 } 587 } else {
581 588 for (i = 0; i < count; ++i) {
582 data->renderer->UnlockTexture(data->renderer, 589 x = points[i].x - rect.x;
583 data->texture[data->current_texture]); 590 y = points[i].y - rect.y;
591
592 status = SDL_BlendPoint(&data->surface, x, y,
593 renderer->blendMode,
594 renderer->r, renderer->g, renderer->b,
595 renderer->a);
596 }
597 }
598
599 data->renderer->UnlockTexture(data->renderer, texture);
600
584 return status; 601 return status;
585 } 602 }
586 603
587 static int 604 static int
588 SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) 605 SW_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
589 { 606 {
590 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; 607 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
591 SDL_Rect rect; 608 SDL_Texture *texture = data->texture[data->current_texture];
592 int status; 609 SDL_Rect clip, rect;
593 610 int i;
594 if (x1 < x2) { 611 int x1, y1, x2, y2;
595 rect.x = x1; 612 int status = 0;
596 rect.w = (x2 - x1) + 1; 613
597 x2 -= x1; 614 /* Get the smallest rectangle that contains everything */
598 x1 = 0; 615 clip.x = 0;
599 } else { 616 clip.y = 0;
600 rect.x = x2; 617 clip.w = texture->w;
601 rect.w = (x1 - x2) + 1; 618 clip.h = texture->h;
602 x1 -= x2; 619 SDL_EnclosePoints(points, count, NULL, &rect);
603 x2 = 0; 620 if (!SDL_IntersectRect(&rect, &clip, &rect)) {
604 } 621 /* Nothing to draw */
605 if (y1 < y2) { 622 return 0;
606 rect.y = y1;
607 rect.h = (y2 - y1) + 1;
608 y2 -= y1;
609 y1 = 0;
610 } else {
611 rect.y = y2;
612 rect.h = (y1 - y2) + 1;
613 y1 -= y2;
614 y2 = 0;
615 } 623 }
616 624
617 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { 625 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
618 SDL_AddDirtyRect(&data->dirty, &rect); 626 SDL_AddDirtyRect(&data->dirty, &rect);
619 } 627 }
620 628
621 if (data->renderer->LockTexture(data->renderer, 629 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
622 data->texture[data->current_texture],
623 &rect, 1,
624 &data->surface.pixels, 630 &data->surface.pixels,
625 &data->surface.pitch) < 0) { 631 &data->surface.pitch) < 0) {
626 return -1; 632 return -1;
627 } 633 }
628 634
629 data->surface.w = rect.w; 635 data->surface.clip_rect.w = data->surface.w = rect.w;
630 data->surface.h = rect.h; 636 data->surface.clip_rect.h = data->surface.h = rect.h;
631 data->surface.clip_rect.w = rect.w; 637
632 data->surface.clip_rect.h = rect.h; 638 /* Draw the points! */
633
634 if (renderer->blendMode == SDL_BLENDMODE_NONE || 639 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
635 renderer->blendMode == SDL_BLENDMODE_MASK) { 640 renderer->blendMode == SDL_BLENDMODE_MASK) {
636 Uint32 color = 641 Uint32 color = SDL_MapRGBA(data->surface.format,
637 SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, 642 renderer->r, renderer->g, renderer->b,
638 renderer->b, renderer->a); 643 renderer->a);
639 644
640 status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color); 645 for (i = 1; i < count; ++i) {
641 } else { 646 x1 = points[i-1].x - rect.x;
642 status = 647 y1 = points[i-1].y - rect.y;
643 SDL_BlendLine(&data->surface, x1, y1, x2, y2, renderer->blendMode, 648 x2 = points[i].x - rect.x;
644 renderer->r, renderer->g, renderer->b, renderer->a); 649 y2 = points[i].y - rect.y;
645 } 650
646 651 status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color);
647 data->renderer->UnlockTexture(data->renderer, 652 }
648 data->texture[data->current_texture]); 653 } else {
654 for (i = 1; i < count; ++i) {
655 x1 = points[i-1].x - rect.x;
656 y1 = points[i-1].y - rect.y;
657 x2 = points[i].x - rect.x;
658 y2 = points[i].y - rect.y;
659
660 status = SDL_BlendLine(&data->surface, x1, y1, x2, y2,
661 renderer->blendMode,
662 renderer->r, renderer->g, renderer->b,
663 renderer->a);
664 }
665 }
666
667 data->renderer->UnlockTexture(data->renderer, texture);
668
649 return status; 669 return status;
650 } 670 }
651 671
652 static int 672 static int
653 SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) 673 SW_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
654 { 674 {
655 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; 675 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
656 SDL_Rect real_rect; 676 SDL_Texture *texture = data->texture[data->current_texture];
657 int status; 677 SDL_Rect clip, rect;
658 678 Uint32 color = 0;
659 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { 679 int i;
660 SDL_AddDirtyRect(&data->dirty, rect); 680 int status = 0;
661 } 681
662 682 clip.x = 0;
663 if (data->renderer->LockTexture(data->renderer, 683 clip.y = 0;
664 data->texture[data->current_texture], 684 clip.w = texture->w;
665 rect, 1, &data->surface.pixels, 685 clip.h = texture->h;
666 &data->surface.pitch) < 0) { 686
667 return -1; 687 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
668 } 688 renderer->blendMode == SDL_BLENDMODE_MASK) {
669 689 color = SDL_MapRGBA(data->surface.format,
670 data->surface.w = rect->w; 690 renderer->r, renderer->g, renderer->b,
671 data->surface.h = rect->h; 691 renderer->a);
672 data->surface.clip_rect.w = rect->w; 692 }
673 data->surface.clip_rect.h = rect->h; 693
674 real_rect = data->surface.clip_rect; 694 for (i = 0; i < count; ++i) {
675 695 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
676 if (renderer->blendMode == SDL_BLENDMODE_NONE) { 696 /* Nothing to draw */
677 Uint32 color = 697 continue;
678 SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, 698 }
679 renderer->b, renderer->a); 699
680 700 if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
681 status = SDL_FillRect(&data->surface, &real_rect, color); 701 SDL_AddDirtyRect(&data->dirty, &rect);
682 } else { 702 }
683 status = 703
684 SDL_BlendRect(&data->surface, &real_rect, renderer->blendMode, 704 if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
685 renderer->r, renderer->g, renderer->b, renderer->a); 705 &data->surface.pixels,
686 } 706 &data->surface.pitch) < 0) {
687 707 return -1;
688 data->renderer->UnlockTexture(data->renderer, 708 }
689 data->texture[data->current_texture]); 709
710 data->surface.clip_rect.w = data->surface.w = rect.w;
711 data->surface.clip_rect.h = data->surface.h = rect.h;
712
713 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
714 renderer->blendMode == SDL_BLENDMODE_MASK) {
715 status = SDL_FillRect(&data->surface, NULL, color);
716 } else {
717 status = SDL_BlendRect(&data->surface, NULL,
718 renderer->blendMode,
719 renderer->r, renderer->g, renderer->b,
720 renderer->a);
721 }
722
723 data->renderer->UnlockTexture(data->renderer, texture);
724 }
690 return status; 725 return status;
691 } 726 }
692 727
693 static int 728 static int
694 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 729 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,