Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 1654:0a53c90a37f9 SDL-1.3
Updated to 1.3.0, SDL_OPENGLBLIT is no longer supported
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 27 Apr 2006 05:30:05 +0000 |
parents | 8d9bb0cf2c2a |
children | 59227394023d |
comparison
equal
deleted
inserted
replaced
1653:939d938d62df | 1654:0a53c90a37f9 |
---|---|
129 SDL_VideoDevice *current_video = NULL; | 129 SDL_VideoDevice *current_video = NULL; |
130 | 130 |
131 /* Various local functions */ | 131 /* Various local functions */ |
132 int SDL_VideoInit(const char *driver_name, Uint32 flags); | 132 int SDL_VideoInit(const char *driver_name, Uint32 flags); |
133 void SDL_VideoQuit(void); | 133 void SDL_VideoQuit(void); |
134 void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects); | |
135 | 134 |
136 static SDL_GrabMode SDL_WM_GrabInputOff(void); | 135 static SDL_GrabMode SDL_WM_GrabInputOff(void); |
137 #if SDL_VIDEO_OPENGL | |
138 static int lock_count = 0; | |
139 #endif | |
140 | 136 |
141 | 137 |
142 /* | 138 /* |
143 * Initialize the video and event subsystems -- determine native pixel format | 139 * Initialize the video and event subsystems -- determine native pixel format |
144 */ | 140 */ |
575 int video_h; | 571 int video_h; |
576 int video_bpp; | 572 int video_bpp; |
577 int is_opengl; | 573 int is_opengl; |
578 SDL_GrabMode saved_grab; | 574 SDL_GrabMode saved_grab; |
579 | 575 |
576 /* Handle obsolete flags */ | |
577 if ( (flags & SDL_OPENGLBLIT_OBSOLETE) == SDL_OPENGLBLIT_OBSOLETE ) { | |
578 SDL_SetError("SDL_OPENGLBLIT is no longer supported"); | |
579 return(NULL); | |
580 } | |
581 | |
580 /* Start up the video driver, if necessary.. | 582 /* Start up the video driver, if necessary.. |
581 WARNING: This is the only function protected this way! | 583 WARNING: This is the only function protected this way! |
582 */ | 584 */ |
583 if ( ! current_video ) { | 585 if ( ! current_video ) { |
584 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { | 586 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { |
746 SDL_WM_GrabInput(saved_grab); | 748 SDL_WM_GrabInput(saved_grab); |
747 SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ | 749 SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ |
748 | 750 |
749 #if SDL_VIDEO_OPENGL | 751 #if SDL_VIDEO_OPENGL |
750 /* Load GL symbols (before MakeCurrent, where we need glGetString). */ | 752 /* Load GL symbols (before MakeCurrent, where we need glGetString). */ |
751 if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) { | 753 if ( flags & SDL_OPENGL ) { |
752 | 754 |
753 #if defined(__QNXNTO__) && (_NTO_VERSION < 630) | 755 #if defined(__QNXNTO__) && (_NTO_VERSION < 630) |
754 #define __SDL_NOGETPROCADDR__ | 756 #define __SDL_NOGETPROCADDR__ |
755 #elif defined(__MINT__) | 757 #elif defined(__MINT__) |
756 #define __SDL_NOGETPROCADDR__ | 758 #define __SDL_NOGETPROCADDR__ |
778 if ( (video->screen->flags & SDL_OPENGL) && | 780 if ( (video->screen->flags & SDL_OPENGL) && |
779 video->GL_MakeCurrent ) { | 781 video->GL_MakeCurrent ) { |
780 if ( video->GL_MakeCurrent(this) < 0 ) { | 782 if ( video->GL_MakeCurrent(this) < 0 ) { |
781 return(NULL); | 783 return(NULL); |
782 } | 784 } |
783 } | |
784 | |
785 /* Set up a fake SDL surface for OpenGL "blitting" */ | |
786 if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) { | |
787 /* Load GL functions for performing the texture updates */ | |
788 #if SDL_VIDEO_OPENGL | |
789 | |
790 /* Create a software surface for blitting */ | |
791 #ifdef GL_VERSION_1_2 | |
792 /* If the implementation either supports the packed pixels | |
793 extension, or implements the core OpenGL 1.2 API, it will | |
794 support the GL_UNSIGNED_SHORT_5_6_5 texture format. | |
795 */ | |
796 if ( (bpp == 16) && | |
797 (SDL_strstr((const char *)video->glGetString(GL_EXTENSIONS), "GL_EXT_packed_pixels") || | |
798 (SDL_atof((const char *)video->glGetString(GL_VERSION)) >= 1.2f)) | |
799 ) { | |
800 video->is_32bit = 0; | |
801 SDL_VideoSurface = SDL_CreateRGBSurface( | |
802 flags, | |
803 width, | |
804 height, | |
805 16, | |
806 31 << 11, | |
807 63 << 5, | |
808 31, | |
809 0 | |
810 ); | |
811 } | |
812 else | |
813 #endif /* OpenGL 1.2 */ | |
814 { | |
815 video->is_32bit = 1; | |
816 SDL_VideoSurface = SDL_CreateRGBSurface( | |
817 flags, | |
818 width, | |
819 height, | |
820 32, | |
821 #if SDL_BYTEORDER == SDL_LIL_ENDIAN | |
822 0x000000FF, | |
823 0x0000FF00, | |
824 0x00FF0000, | |
825 0xFF000000 | |
826 #else | |
827 0xFF000000, | |
828 0x00FF0000, | |
829 0x0000FF00, | |
830 0x000000FF | |
831 #endif | |
832 ); | |
833 } | |
834 if ( ! SDL_VideoSurface ) { | |
835 return(NULL); | |
836 } | |
837 SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT; | |
838 | |
839 /* Free the original video mode surface (is this safe?) */ | |
840 SDL_FreeSurface(mode); | |
841 | |
842 /* Set the surface completely opaque & white by default */ | |
843 SDL_memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch ); | |
844 video->glGenTextures( 1, &video->texture ); | |
845 video->glBindTexture( GL_TEXTURE_2D, video->texture ); | |
846 video->glTexImage2D( | |
847 GL_TEXTURE_2D, | |
848 0, | |
849 video->is_32bit ? GL_RGBA : GL_RGB, | |
850 256, | |
851 256, | |
852 0, | |
853 video->is_32bit ? GL_RGBA : GL_RGB, | |
854 #ifdef GL_VERSION_1_2 | |
855 video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, | |
856 #else | |
857 GL_UNSIGNED_BYTE, | |
858 #endif | |
859 NULL); | |
860 | |
861 video->UpdateRects = SDL_GL_UpdateRectsLock; | |
862 #else | |
863 SDL_SetError("Somebody forgot to #define SDL_VIDEO_OPENGL"); | |
864 return(NULL); | |
865 #endif | |
866 } | 785 } |
867 | 786 |
868 /* Create a shadow surface if necessary */ | 787 /* Create a shadow surface if necessary */ |
869 /* There are three conditions under which we create a shadow surface: | 788 /* There are three conditions under which we create a shadow surface: |
870 1. We need a particular bits-per-pixel that we didn't get. | 789 1. We need a particular bits-per-pixel that we didn't get. |
1509 } else { | 1428 } else { |
1510 SDL_SetError("OpenGL video mode has not been set"); | 1429 SDL_SetError("OpenGL video mode has not been set"); |
1511 } | 1430 } |
1512 } | 1431 } |
1513 | 1432 |
1514 /* Update rects with locking */ | |
1515 void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects) | |
1516 { | |
1517 SDL_GL_Lock(); | |
1518 SDL_GL_UpdateRects(numrects, rects); | |
1519 SDL_GL_Unlock(); | |
1520 } | |
1521 | |
1522 /* Update rects without state setting and changing (the caller is responsible for it) */ | |
1523 void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects) | |
1524 { | |
1525 #if SDL_VIDEO_OPENGL | |
1526 SDL_VideoDevice *this = current_video; | |
1527 SDL_Rect update, tmp; | |
1528 int x, y, i; | |
1529 | |
1530 for ( i = 0; i < numrects; i++ ) | |
1531 { | |
1532 tmp.y = rects[i].y; | |
1533 tmp.h = rects[i].h; | |
1534 for ( y = 0; y <= rects[i].h / 256; y++ ) | |
1535 { | |
1536 tmp.x = rects[i].x; | |
1537 tmp.w = rects[i].w; | |
1538 for ( x = 0; x <= rects[i].w / 256; x++ ) | |
1539 { | |
1540 update.x = tmp.x; | |
1541 update.y = tmp.y; | |
1542 update.w = tmp.w; | |
1543 update.h = tmp.h; | |
1544 | |
1545 if ( update.w > 256 ) | |
1546 update.w = 256; | |
1547 | |
1548 if ( update.h > 256 ) | |
1549 update.h = 256; | |
1550 | |
1551 this->glFlush(); | |
1552 this->glTexSubImage2D( | |
1553 GL_TEXTURE_2D, | |
1554 0, | |
1555 0, | |
1556 0, | |
1557 update.w, | |
1558 update.h, | |
1559 this->is_32bit? GL_RGBA : GL_RGB, | |
1560 #ifdef GL_VERSION_1_2 | |
1561 this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, | |
1562 #else | |
1563 GL_UNSIGNED_BYTE, | |
1564 #endif | |
1565 (Uint8 *)this->screen->pixels + | |
1566 this->screen->format->BytesPerPixel * update.x + | |
1567 update.y * this->screen->pitch ); | |
1568 | |
1569 this->glFlush(); | |
1570 /* | |
1571 * Note the parens around the function name: | |
1572 * This is because some OpenGL implementations define glTexCoord etc | |
1573 * as macros, and we don't want them expanded here. | |
1574 */ | |
1575 this->glBegin(GL_TRIANGLE_STRIP); | |
1576 (this->glTexCoord2f)( 0.0, 0.0 ); | |
1577 (this->glVertex2i)( update.x, update.y ); | |
1578 (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 ); | |
1579 (this->glVertex2i)( update.x + update.w, update.y ); | |
1580 (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) ); | |
1581 (this->glVertex2i)( update.x, update.y + update.h ); | |
1582 (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) ); | |
1583 (this->glVertex2i)( update.x + update.w , update.y + update.h ); | |
1584 this->glEnd(); | |
1585 | |
1586 tmp.x += 256; | |
1587 tmp.w -= 256; | |
1588 } | |
1589 tmp.y += 256; | |
1590 tmp.h -= 256; | |
1591 } | |
1592 } | |
1593 #endif | |
1594 } | |
1595 | |
1596 /* Lock == save current state */ | |
1597 void SDL_GL_Lock() | |
1598 { | |
1599 #if SDL_VIDEO_OPENGL | |
1600 lock_count--; | |
1601 if (lock_count==-1) | |
1602 { | |
1603 SDL_VideoDevice *this = current_video; | |
1604 | |
1605 this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */ | |
1606 #ifdef GL_CLIENT_PIXEL_STORE_BIT | |
1607 this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); | |
1608 #endif | |
1609 | |
1610 this->glEnable(GL_TEXTURE_2D); | |
1611 this->glEnable(GL_BLEND); | |
1612 this->glDisable(GL_FOG); | |
1613 this->glDisable(GL_ALPHA_TEST); | |
1614 this->glDisable(GL_DEPTH_TEST); | |
1615 this->glDisable(GL_SCISSOR_TEST); | |
1616 this->glDisable(GL_STENCIL_TEST); | |
1617 this->glDisable(GL_CULL_FACE); | |
1618 | |
1619 this->glBindTexture( GL_TEXTURE_2D, this->texture ); | |
1620 this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); | |
1621 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); | |
1622 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); | |
1623 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); | |
1624 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); | |
1625 | |
1626 this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel ); | |
1627 this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
1628 (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */ | |
1629 | |
1630 this->glViewport(0, 0, this->screen->w, this->screen->h); | |
1631 this->glMatrixMode(GL_PROJECTION); | |
1632 this->glPushMatrix(); | |
1633 this->glLoadIdentity(); | |
1634 | |
1635 this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0); | |
1636 | |
1637 this->glMatrixMode(GL_MODELVIEW); | |
1638 this->glPushMatrix(); | |
1639 this->glLoadIdentity(); | |
1640 } | |
1641 #endif | |
1642 } | |
1643 | |
1644 /* Unlock == restore saved state */ | |
1645 void SDL_GL_Unlock() | |
1646 { | |
1647 #if SDL_VIDEO_OPENGL | |
1648 lock_count++; | |
1649 if (lock_count==0) | |
1650 { | |
1651 SDL_VideoDevice *this = current_video; | |
1652 | |
1653 this->glPopMatrix(); | |
1654 this->glMatrixMode(GL_PROJECTION); | |
1655 this->glPopMatrix(); | |
1656 | |
1657 this->glPopClientAttrib(); | |
1658 this->glPopAttrib(); | |
1659 } | |
1660 #endif | |
1661 } | |
1662 | |
1663 /* | 1433 /* |
1664 * Sets/Gets the title and icon text of the display window, if any. | 1434 * Sets/Gets the title and icon text of the display window, if any. |
1665 */ | 1435 */ |
1666 void SDL_WM_SetCaption (const char *title, const char *icon) | 1436 void SDL_WM_SetCaption (const char *title, const char *icon) |
1667 { | 1437 { |