If the OpenGL renderer is selected for a non-OpenGL window, recreate the window with OpenGL enabled.
authorSam Lantinga <slouken@libsdl.org>
Sat, 22 Jul 2006 21:02:57 +0000
changeset 192469217fdd2c0a
parent 1923 d4572b97b08f
child 1925 411bfb37082b
If the OpenGL renderer is selected for a non-OpenGL window, recreate the window with OpenGL enabled.
Added OpenGL renderer error checking.
Use fast-path texture formats in the OpenGL renderer.
src/SDL_compat.c
src/video/SDL_renderer_gl.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/win32/SDL_d3drender.c
src/video/win32/SDL_gdirender.c
test/common.c
     1.1 --- a/src/SDL_compat.c	Sat Jul 22 19:51:48 2006 +0000
     1.2 +++ b/src/SDL_compat.c	Sat Jul 22 21:02:57 2006 +0000
     1.3 @@ -469,7 +469,8 @@
     1.4                            height);
     1.5      if (!SDL_VideoTexture) {
     1.6          SDL_VideoTexture =
     1.7 -            SDL_CreateTexture(0, SDL_TextureAccess_Local, width, height);
     1.8 +            SDL_CreateTexture(SDL_PixelFormat_RGB888, SDL_TextureAccess_Local,
     1.9 +                              width, height);
    1.10      }
    1.11      if (!SDL_VideoTexture) {
    1.12          return NULL;
     2.1 --- a/src/video/SDL_renderer_gl.c	Sat Jul 22 19:51:48 2006 +0000
     2.2 +++ b/src/video/SDL_renderer_gl.c	Sat Jul 22 21:02:57 2006 +0000
     2.3 @@ -72,7 +72,7 @@
     2.4        SDL_TextureBlendMode_Mod),
     2.5       (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast |
     2.6        SDL_TextureScaleMode_Slow),
     2.7 -     18,
     2.8 +     16,
     2.9       {
    2.10        SDL_PixelFormat_Index1LSB,
    2.11        SDL_PixelFormat_Index1MSB,
    2.12 @@ -88,10 +88,8 @@
    2.13        SDL_PixelFormat_RGB888,
    2.14        SDL_PixelFormat_BGR888,
    2.15        SDL_PixelFormat_ARGB8888,
    2.16 -      SDL_PixelFormat_RGBA8888,
    2.17        SDL_PixelFormat_ABGR8888,
    2.18 -      SDL_PixelFormat_BGRA8888,
    2.19 -      SDL_PixelFormat_ARGB2101010},     /* FIXME: YUV texture support */
    2.20 +      SDL_PixelFormat_ARGB2101010},
    2.21       0,
    2.22       0}
    2.23  };
    2.24 @@ -115,6 +113,43 @@
    2.25  } GL_TextureData;
    2.26  
    2.27  
    2.28 +static void
    2.29 +GL_SetError(const char *prefix, GLenum result)
    2.30 +{
    2.31 +    const char *error;
    2.32 +
    2.33 +    switch (result) {
    2.34 +    case GL_NO_ERROR:
    2.35 +        error = "GL_NO_ERROR";
    2.36 +        break;
    2.37 +    case GL_INVALID_ENUM:
    2.38 +        error = "GL_INVALID_ENUM";
    2.39 +        break;
    2.40 +    case GL_INVALID_VALUE:
    2.41 +        error = "GL_INVALID_VALUE";
    2.42 +        break;
    2.43 +    case GL_INVALID_OPERATION:
    2.44 +        error = "GL_INVALID_OPERATION";
    2.45 +        break;
    2.46 +    case GL_STACK_OVERFLOW:
    2.47 +        error = "GL_STACK_OVERFLOW";
    2.48 +        break;
    2.49 +    case GL_STACK_UNDERFLOW:
    2.50 +        error = "GL_STACK_UNDERFLOW";
    2.51 +        break;
    2.52 +    case GL_OUT_OF_MEMORY:
    2.53 +        error = "GL_OUT_OF_MEMORY";
    2.54 +        break;
    2.55 +    case GL_TABLE_TOO_LARGE:
    2.56 +        error = "GL_TABLE_TOO_LARGE";
    2.57 +        break;
    2.58 +    default:
    2.59 +        error = "UNKNOWN";
    2.60 +        break;
    2.61 +    }
    2.62 +    SDL_SetError("%s: %s", prefix, error);
    2.63 +}
    2.64 +
    2.65  void
    2.66  GL_AddRenderDriver(_THIS)
    2.67  {
    2.68 @@ -130,9 +165,10 @@
    2.69      GL_RenderData *data;
    2.70  
    2.71      if (!(window->flags & SDL_WINDOW_OPENGL)) {
    2.72 -        SDL_SetError
    2.73 -            ("The OpenGL renderer can only be used on OpenGL windows");
    2.74 -        return NULL;
    2.75 +        window->flags |= SDL_WINDOW_OPENGL;
    2.76 +        if (SDL_RecreateWindow(window) < 0) {
    2.77 +            return NULL;
    2.78 +        }
    2.79      }
    2.80  
    2.81      renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
    2.82 @@ -239,6 +275,7 @@
    2.83      GLint internalFormat;
    2.84      GLenum format, type;
    2.85      int texture_w, texture_h;
    2.86 +    GLenum result;
    2.87  
    2.88      switch (texture->format) {
    2.89      case SDL_PixelFormat_Index1LSB:
    2.90 @@ -289,8 +326,8 @@
    2.91          break;
    2.92      case SDL_PixelFormat_RGB888:
    2.93          internalFormat = GL_RGB8;
    2.94 -        format = GL_RGB;
    2.95 -        type = GL_UNSIGNED_INT_8_8_8_8;
    2.96 +        format = GL_BGRA;
    2.97 +        type = GL_UNSIGNED_BYTE;
    2.98          break;
    2.99      case SDL_PixelFormat_BGR24:
   2.100          internalFormat = GL_RGB8;
   2.101 @@ -299,28 +336,18 @@
   2.102          break;
   2.103      case SDL_PixelFormat_BGR888:
   2.104          internalFormat = GL_RGB8;
   2.105 -        format = GL_BGR;
   2.106 -        type = GL_UNSIGNED_INT_8_8_8_8;
   2.107 +        format = GL_RGBA;
   2.108 +        type = GL_UNSIGNED_BYTE;
   2.109          break;
   2.110      case SDL_PixelFormat_ARGB8888:
   2.111          internalFormat = GL_RGBA8;
   2.112          format = GL_BGRA;
   2.113 -        type = GL_UNSIGNED_INT_8_8_8_8_REV;
   2.114 -        break;
   2.115 -    case SDL_PixelFormat_RGBA8888:
   2.116 -        internalFormat = GL_RGBA8;
   2.117 -        format = GL_RGBA;
   2.118 -        type = GL_UNSIGNED_INT_8_8_8_8;
   2.119 +        type = GL_UNSIGNED_BYTE;
   2.120          break;
   2.121      case SDL_PixelFormat_ABGR8888:
   2.122          internalFormat = GL_RGBA8;
   2.123          format = GL_RGBA;
   2.124 -        type = GL_UNSIGNED_INT_8_8_8_8_REV;
   2.125 -        break;
   2.126 -    case SDL_PixelFormat_BGRA8888:
   2.127 -        internalFormat = GL_RGBA8;
   2.128 -        format = GL_BGRA;
   2.129 -        type = GL_UNSIGNED_INT_8_8_8_8;
   2.130 +        type = GL_UNSIGNED_BYTE;
   2.131          break;
   2.132      case SDL_PixelFormat_ARGB2101010:
   2.133          internalFormat = GL_RGB10_A2;
   2.134 @@ -340,7 +367,7 @@
   2.135  
   2.136      texture->driverdata = data;
   2.137  
   2.138 -    /* FIXME: Check for GL_ARB_texture_rectangle and GL_EXT_texture_rectangle */
   2.139 +    glGetError();
   2.140      glGenTextures(1, &data->texture);
   2.141  #ifdef USE_GL_TEXTURE_RECTANGLE
   2.142      data->type = GL_TEXTURE_RECTANGLE_ARB;
   2.143 @@ -360,7 +387,11 @@
   2.144      glBindTexture(data->type, data->texture);
   2.145      glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0,
   2.146                   format, type, NULL);
   2.147 -
   2.148 +    result = glGetError();
   2.149 +    if (result != GL_NO_ERROR) {
   2.150 +        GL_SetError("glTexImage2D()", result);
   2.151 +        return -1;
   2.152 +    }
   2.153      return 0;
   2.154  }
   2.155  
   2.156 @@ -383,19 +414,36 @@
   2.157      return 0;
   2.158  }
   2.159  
   2.160 +static void
   2.161 +SetupTextureUpdate(SDL_Texture * texture, int pitch)
   2.162 +{
   2.163 +    if (texture->format == SDL_PixelFormat_Index1LSB) {
   2.164 +        glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
   2.165 +    } else if (texture->format == SDL_PixelFormat_Index1MSB) {
   2.166 +        glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
   2.167 +    }
   2.168 +    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2.169 +    glPixelStorei(GL_UNPACK_ROW_LENGTH,
   2.170 +                  pitch / SDL_BYTESPERPIXEL(texture->format));
   2.171 +}
   2.172 +
   2.173  static int
   2.174  GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   2.175                   const SDL_Rect * rect, const void *pixels, int pitch)
   2.176  {
   2.177      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   2.178 +    GLenum result;
   2.179  
   2.180 -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);      /* FIXME, what to use for RGB 4 byte formats? */
   2.181 -    glPixelStorei(GL_UNPACK_ROW_LENGTH,
   2.182 -                  pitch / SDL_BYTESPERPIXEL(texture->format));
   2.183 +    glGetError();
   2.184 +    SetupTextureUpdate(texture, pitch);
   2.185      glBindTexture(data->type, data->texture);
   2.186      glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h,
   2.187                      data->format, data->formattype, pixels);
   2.188 -    /* FIXME: check for errors */
   2.189 +    result = glGetError();
   2.190 +    if (result != GL_NO_ERROR) {
   2.191 +        GL_SetError("glTexSubImage2D()", result);
   2.192 +        return -1;
   2.193 +    }
   2.194      return 0;
   2.195  }
   2.196  
   2.197 @@ -478,9 +526,7 @@
   2.198          int bpp = SDL_BYTESPERPIXEL(texture->format);
   2.199          int pitch = texturedata->pitch;
   2.200  
   2.201 -        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  /* FIXME, what to use for RGB 4 byte formats? */
   2.202 -        glPixelStorei(GL_UNPACK_ROW_LENGTH,
   2.203 -                      pitch / SDL_BYTESPERPIXEL(texture->format));
   2.204 +        SetupTextureUpdate(texture, pitch);
   2.205          glBindTexture(texturedata->type, texturedata->texture);
   2.206          for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
   2.207              SDL_Rect *rect = &dirty->rect;
     3.1 --- a/src/video/SDL_sysvideo.h	Sat Jul 22 19:51:48 2006 +0000
     3.2 +++ b/src/video/SDL_sysvideo.h	Sat Jul 22 21:02:57 2006 +0000
     3.3 @@ -397,6 +397,7 @@
     3.4  extern void SDL_AddRenderDriver(int displayIndex,
     3.5                                  const SDL_RenderDriver * driver);
     3.6  
     3.7 +extern int SDL_RecreateWindow(SDL_Window * window);
     3.8  extern SDL_Window *SDL_GetWindowFromID(SDL_WindowID windowID);
     3.9  extern SDL_VideoDisplay *SDL_GetDisplayFromWindow(SDL_Window * window);
    3.10  
     4.1 --- a/src/video/SDL_video.c	Sat Jul 22 19:51:48 2006 +0000
     4.2 +++ b/src/video/SDL_video.c	Sat Jul 22 21:02:57 2006 +0000
     4.3 @@ -833,6 +833,20 @@
     4.4      return window.id;
     4.5  }
     4.6  
     4.7 +int
     4.8 +SDL_RecreateWindow(SDL_Window * window)
     4.9 +{
    4.10 +    if ((window->flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
    4.11 +        window->flags &= ~SDL_WINDOW_OPENGL;
    4.12 +        SDL_SetError("No OpenGL support in video driver");
    4.13 +        return -1;
    4.14 +    }
    4.15 +    if (_this->DestroyWindow) {
    4.16 +        _this->DestroyWindow(_this, window);
    4.17 +    }
    4.18 +    return _this->CreateWindow(_this, window);
    4.19 +}
    4.20 +
    4.21  SDL_Window *
    4.22  SDL_GetWindowFromID(SDL_WindowID windowID)
    4.23  {
    4.24 @@ -1259,6 +1273,7 @@
    4.25              if (window->title) {
    4.26                  SDL_free(window->title);
    4.27              }
    4.28 +            SDL_free(window);
    4.29              if (j != display->num_windows - 1) {
    4.30                  SDL_memcpy(&display->windows[i],
    4.31                             &display->windows[i + 1],
    4.32 @@ -1421,6 +1436,9 @@
    4.33      texture->renderer = renderer;
    4.34  
    4.35      if (renderer->CreateTexture(renderer, texture) < 0) {
    4.36 +        if (renderer->DestroyTexture) {
    4.37 +            renderer->DestroyTexture(renderer, texture);
    4.38 +        }
    4.39          SDL_free(texture);
    4.40          return 0;
    4.41      }
     5.1 --- a/src/video/win32/SDL_d3drender.c	Sat Jul 22 19:51:48 2006 +0000
     5.2 +++ b/src/video/win32/SDL_d3drender.c	Sat Jul 22 21:02:57 2006 +0000
     5.3 @@ -396,7 +396,6 @@
     5.4                                         PixelFormatToD3DFMT(texture->format),
     5.5                                         pool, &data->texture, NULL);
     5.6      if (FAILED(result)) {
     5.7 -        SDL_free(data);
     5.8          D3D_SetError("CreateTexture()", result);
     5.9          return -1;
    5.10      }
     6.1 --- a/src/video/win32/SDL_gdirender.c	Sat Jul 22 19:51:48 2006 +0000
     6.2 +++ b/src/video/win32/SDL_gdirender.c	Sat Jul 22 21:02:57 2006 +0000
     6.3 @@ -249,7 +249,6 @@
     6.4      if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
     6.5          data->yuv = SDL_SW_CreateYUVTexture(texture);
     6.6          if (!data->yuv) {
     6.7 -            GDI_DestroyTexture(renderer, texture);
     6.8              return -1;
     6.9          }
    6.10          data->format = display->current_mode.format;
    6.11 @@ -266,7 +265,6 @@
    6.12          bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
    6.13          bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size);
    6.14          if (!bmi) {
    6.15 -            GDI_DestroyTexture(renderer, texture);
    6.16              SDL_OutOfMemory();
    6.17              return -1;
    6.18          }
    6.19 @@ -291,7 +289,6 @@
    6.20                                            ncolors * sizeof(PALETTEENTRY));
    6.21              if (!palette) {
    6.22                  SDL_free(bmi);
    6.23 -                GDI_DestroyTexture(renderer, texture);
    6.24                  SDL_OutOfMemory();
    6.25                  return -1;
    6.26              }
    6.27 @@ -327,7 +324,6 @@
    6.28          data->pixels = NULL;
    6.29      }
    6.30      if (!data->hbm) {
    6.31 -        GDI_DestroyTexture(renderer, texture);
    6.32          WIN_SetError("Couldn't create bitmap");
    6.33          return -1;
    6.34      }
     7.1 --- a/test/common.c	Sat Jul 22 19:51:48 2006 +0000
     7.2 +++ b/test/common.c	Sat Jul 22 21:02:57 2006 +0000
     7.3 @@ -55,9 +55,6 @@
     7.4          if (!argv[index]) {
     7.5              return -1;
     7.6          }
     7.7 -        if (SDL_strcasecmp(argv[index], "opengl") == 0) {
     7.8 -            state->window_flags |= SDL_WINDOW_OPENGL;
     7.9 -        }
    7.10          state->renderdriver = argv[index];
    7.11          return 2;
    7.12      }