comparison src/video/SDL_video.c @ 2266:e61ad15a205f

More work in progress integrating SDL_Surface and the new SDL_Texture API
author Sam Lantinga <slouken@libsdl.org>
date Sat, 18 Aug 2007 01:44:21 +0000
parents 340942cfda48
children c785543d1843
comparison
equal deleted inserted replaced
2265:265bb136af92 2266:e61ad15a205f
1533 1533
1534 SDL_TextureID 1534 SDL_TextureID
1535 SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) 1535 SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
1536 { 1536 {
1537 SDL_TextureID textureID; 1537 SDL_TextureID textureID;
1538 Uint32 surface_flags = surface->flags; 1538 SDL_PixelFormat *fmt;
1539 SDL_PixelFormat *fmt = surface->format;
1540 int bpp; 1539 int bpp;
1541 Uint32 Rmask, Gmask, Bmask, Amask; 1540 Uint32 Rmask, Gmask, Bmask, Amask;
1542 1541
1543 if (!surface) { 1542 if (!surface) {
1544 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); 1543 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
1545 return 0; 1544 return 0;
1546 } 1545 }
1546 fmt = surface->format;
1547 1547
1548 if (format) { 1548 if (format) {
1549 if (!SDL_PixelFormatEnumToMasks 1549 if (!SDL_PixelFormatEnumToMasks
1550 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { 1550 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
1551 SDL_SetError("Unknown pixel format"); 1551 SDL_SetError("Unknown pixel format");
1552 return 0; 1552 return 0;
1553 } 1553 }
1554 } else { 1554 } else {
1555 if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) { 1555 if (surface->format->Amask || !(flags & (SDL_COPY_COLORKEY|SDL_COPY_MASK|SDL_COPY_BLEND))) {
1556 bpp = fmt->BitsPerPixel; 1556 bpp = fmt->BitsPerPixel;
1557 Rmask = fmt->Rmask; 1557 Rmask = fmt->Rmask;
1558 Gmask = fmt->Gmask; 1558 Gmask = fmt->Gmask;
1559 Bmask = fmt->Bmask; 1559 Bmask = fmt->Bmask;
1560 Amask = fmt->Amask; 1560 Amask = fmt->Amask;
1593 } else { 1593 } else {
1594 SDL_UpdateTexture(textureID, NULL, surface->pixels, 1594 SDL_UpdateTexture(textureID, NULL, surface->pixels,
1595 surface->pitch); 1595 surface->pitch);
1596 } 1596 }
1597 } else { 1597 } else {
1598 Uint32 cmod; 1598 SDL_PixelFormat *dst_fmt;
1599 SDL_Rect bounds; 1599 SDL_Surface *dst = NULL;
1600 SDL_Surface dst;
1601 1600
1602 /* Set up a destination surface for the texture update */ 1601 /* Set up a destination surface for the texture update */
1603 SDL_zero(dst); 1602 dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
1604 dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); 1603 if (dst_fmt) {
1605 if (!dst.format) { 1604 if (SDL_ISPIXELFORMAT_INDEXED(format)) {
1606 SDL_DestroyTexture(textureID); 1605 dst_fmt->palette = SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
1607 return 0; 1606 if (dst_fmt->palette) {
1608 } 1607 if (fmt->palette) {
1609 dst.w = surface->w; 1608 fixme
1610 dst.h = surface->h; 1609 } else {
1611 dst.pitch = SDL_CalculatePitch(&dst); 1610 SDL_DitherColors(dst_fmt->palette->colors, SDL_BITSPERPIXEL(format));
1612 dst.pixels = SDL_malloc(dst.h * dst.pitch); 1611 }
1613 if (!dst.pixels) {
1614 SDL_DestroyTexture(textureID);
1615 SDL_FreeFormat(dst.format);
1616 SDL_OutOfMemory();
1617 return 0;
1618 }
1619
1620 /* Copy the palette if any */
1621 if (SDL_ISPIXELFORMAT_INDEXED(format)) {
1622 if (fmt->palette) {
1623 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
1624 fmt->palette->ncolors);
1625 SDL_SetSurfacePalette(&dst, fmt->palette);
1626 } else {
1627 dst.format->palette =
1628 SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
1629 if (!dst.format->palette) {
1630 SDL_DestroyTexture(textureID);
1631 SDL_FreeFormat(dst.format);
1632 return 0;
1633 } 1612 }
1634 SDL_DitherColors(dst.format->palette->colors, 1613 if (fmt->palette) {
1635 SDL_BITSPERPIXEL(format)); 1614 dst_fmt->palette = fmt->palette;
1615 } else {
1616 }
1636 } 1617 }
1637 } 1618
1638 1619 cvt = SDL_ConvertSurface(surface, fmt, 0);
1639 /* Make the texture transparent if the surface has colorkey */ 1620 if (cvt) {
1640 if (surface_flags & SDL_SRCCOLORKEY) { 1621 SDL_UpdateTexture(textureID, NULL, cvt->pixels, cvt->pitch);
1641 int row; 1622 SDL_FreeSurface(cvt);
1642 int length = dst.w * dst.format->BytesPerPixel;
1643 Uint8 *p = (Uint8 *) dst.pixels;
1644 for (row = 0; row < dst.h; ++row) {
1645 SDL_memset(p, 0, length);
1646 p += dst.pitch;
1647 } 1623 }
1648 } 1624 SDL_FreeFormat(fmt);
1649 1625 }
1650 /* Copy over the alpha channel */ 1626 }
1651 cmod = surface->map->cmod; 1627
1652 if (surface_flags & SDL_SRCALPHA) { 1628 if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) {
1653 if (fmt->Amask) { 1629 SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, fmt->palette->ncolors);
1654 surface->flags &= ~SDL_SRCALPHA;
1655 } else {
1656 /* FIXME: Need to make sure the texture has an alpha channel
1657 * and copy 'alpha' into the texture alpha channel.
1658 */
1659 SDL_SetAlpha(surface, 0, 0);
1660 }
1661 }
1662
1663 /* Copy over the image data */
1664 bounds.x = 0;
1665 bounds.y = 0;
1666 bounds.w = surface->w;
1667 bounds.h = surface->h;
1668 SDL_LowerBlit(surface, &bounds, &dst, &bounds);
1669
1670 /* Clean up the original surface */
1671 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
1672 Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
1673 if (fmt->Amask) {
1674 surface->flags |= SDL_SRCALPHA;
1675 } else {
1676 SDL_SetAlpha(surface, aflags, (cmod >> 24));
1677 }
1678 }
1679
1680 /* Update the texture */
1681 SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
1682 SDL_free(dst.pixels);
1683 SDL_FreeFormat(dst.format);
1684 } 1630 }
1685 1631
1686 return textureID; 1632 return textureID;
1687 } 1633 }
1688 1634