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 {