OpenGL renderer is feature complete!
authorSam Lantinga <slouken@libsdl.org>
Sat, 22 Jul 2006 23:04:41 +0000
changeset 1927aeb8263d377a
parent 1926 307355678142
child 1928 861bc36f0ab3
OpenGL renderer is feature complete!
Dynamically load GL functions in the OpenGL renderer.
src/video/SDL_glfuncs.h
src/video/SDL_renderer_gl.c
     1.1 --- a/src/video/SDL_glfuncs.h	Sat Jul 22 21:58:17 2006 +0000
     1.2 +++ b/src/video/SDL_glfuncs.h	Sat Jul 22 23:04:41 2006 +0000
     1.3 @@ -16,9 +16,9 @@
     1.4  SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
     1.5  SDL_PROC_UNUSED(void, glCallList, (GLuint))
     1.6  SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *))
     1.7 -SDL_PROC_UNUSED(void, glClear, (GLbitfield))
     1.8 +SDL_PROC(void, glClear, (GLbitfield))
     1.9  SDL_PROC_UNUSED(void, glClearAccum, (GLfloat, GLfloat, GLfloat, GLfloat))
    1.10 -SDL_PROC_UNUSED(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
    1.11 +SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
    1.12  SDL_PROC_UNUSED(void, glClearDepth, (GLclampd))
    1.13  SDL_PROC_UNUSED(void, glClearIndex, (GLfloat))
    1.14  SDL_PROC_UNUSED(void, glClearStencil, (GLint))
    1.15 @@ -33,7 +33,7 @@
    1.16  SDL_PROC_UNUSED(void, glColor3iv, (const GLint *))
    1.17  SDL_PROC_UNUSED(void, glColor3s, (GLshort, GLshort, GLshort))
    1.18  SDL_PROC_UNUSED(void, glColor3sv, (const GLshort *))
    1.19 -SDL_PROC(void, glColor3ub, (GLubyte, GLubyte, GLubyte))
    1.20 +SDL_PROC_UNUSED(void, glColor3ub, (GLubyte, GLubyte, GLubyte))
    1.21  SDL_PROC_UNUSED(void, glColor3ubv, (const GLubyte *))
    1.22  SDL_PROC_UNUSED(void, glColor3ui, (GLuint, GLuint, GLuint))
    1.23  SDL_PROC_UNUSED(void, glColor3uiv, (const GLuint *))
    1.24 @@ -43,14 +43,14 @@
    1.25  SDL_PROC_UNUSED(void, glColor4bv, (const GLbyte *))
    1.26  SDL_PROC_UNUSED(void, glColor4d, (GLdouble, GLdouble, GLdouble, GLdouble))
    1.27  SDL_PROC_UNUSED(void, glColor4dv, (const GLdouble *))
    1.28 -SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
    1.29 +SDL_PROC_UNUSED(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
    1.30  SDL_PROC_UNUSED(void, glColor4fv, (const GLfloat *))
    1.31  SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint))
    1.32  SDL_PROC_UNUSED(void, glColor4iv, (const GLint *))
    1.33  SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort))
    1.34  SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *))
    1.35 -SDL_PROC(void, glColor4ub,
    1.36 -         (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
    1.37 +SDL_PROC_UNUSED(void, glColor4ub,
    1.38 +                (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
    1.39  SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte * v))
    1.40  SDL_PROC_UNUSED(void, glColor4ui,
    1.41                  (GLuint red, GLuint green, GLuint blue, GLuint alpha))
    1.42 @@ -89,7 +89,7 @@
    1.43  SDL_PROC(void, glDisable, (GLenum cap))
    1.44  SDL_PROC_UNUSED(void, glDisableClientState, (GLenum array))
    1.45  SDL_PROC_UNUSED(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
    1.46 -SDL_PROC(void, glDrawBuffer, (GLenum mode))
    1.47 +SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode))
    1.48  SDL_PROC_UNUSED(void, glDrawElements,
    1.49                  (GLenum mode, GLsizei count, GLenum type,
    1.50                   const GLvoid * indices))
    1.51 @@ -119,8 +119,8 @@
    1.52  SDL_PROC_UNUSED(void, glEvalPoint2, (GLint i, GLint j))
    1.53  SDL_PROC_UNUSED(void, glFeedbackBuffer,
    1.54                  (GLsizei size, GLenum type, GLfloat * buffer))
    1.55 -SDL_PROC(void, glFinish, (void))
    1.56 -SDL_PROC(void, glFlush, (void))
    1.57 +SDL_PROC_UNUSED(void, glFinish, (void))
    1.58 +SDL_PROC_UNUSED(void, glFlush, (void))
    1.59  SDL_PROC_UNUSED(void, glFogf, (GLenum pname, GLfloat param))
    1.60  SDL_PROC_UNUSED(void, glFogfv, (GLenum pname, const GLfloat * params))
    1.61  SDL_PROC_UNUSED(void, glFogi, (GLenum pname, GLint param))
    1.62 @@ -153,7 +153,7 @@
    1.63  SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort * values))
    1.64  SDL_PROC_UNUSED(void, glGetPointerv, (GLenum pname, GLvoid * *params))
    1.65  SDL_PROC_UNUSED(void, glGetPolygonStipple, (GLubyte * mask))
    1.66 -SDL_PROC(const GLubyte *, glGetString, (GLenum name))
    1.67 +SDL_PROC_UNUSED(const GLubyte *, glGetString, (GLenum name))
    1.68  SDL_PROC_UNUSED(void, glGetTexEnvfv,
    1.69                  (GLenum target, GLenum pname, GLfloat * params))
    1.70  SDL_PROC_UNUSED(void, glGetTexEnviv,
    1.71 @@ -276,16 +276,16 @@
    1.72  SDL_PROC_UNUSED(void, glPolygonMode, (GLenum face, GLenum mode))
    1.73  SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units))
    1.74  SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte * mask))
    1.75 -SDL_PROC(void, glPopAttrib, (void))
    1.76 -SDL_PROC(void, glPopClientAttrib, (void))
    1.77 -SDL_PROC(void, glPopMatrix, (void))
    1.78 +SDL_PROC_UNUSED(void, glPopAttrib, (void))
    1.79 +SDL_PROC_UNUSED(void, glPopClientAttrib, (void))
    1.80 +SDL_PROC_UNUSED(void, glPopMatrix, (void))
    1.81  SDL_PROC_UNUSED(void, glPopName, (void))
    1.82  SDL_PROC_UNUSED(void, glPrioritizeTextures,
    1.83                  (GLsizei n, const GLuint * textures,
    1.84                   const GLclampf * priorities))
    1.85 -SDL_PROC(void, glPushAttrib, (GLbitfield mask))
    1.86 -SDL_PROC(void, glPushClientAttrib, (GLbitfield mask))
    1.87 -SDL_PROC(void, glPushMatrix, (void))
    1.88 +SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask))
    1.89 +SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask))
    1.90 +SDL_PROC_UNUSED(void, glPushMatrix, (void))
    1.91  SDL_PROC_UNUSED(void, glPushName, (GLuint name))
    1.92  SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y))
    1.93  SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble * v))
    1.94 @@ -315,9 +315,9 @@
    1.95                  (GLshort x, GLshort y, GLshort z, GLshort w))
    1.96  SDL_PROC_UNUSED(void, glRasterPos4sv, (const GLshort * v))
    1.97  SDL_PROC_UNUSED(void, glReadBuffer, (GLenum mode))
    1.98 -SDL_PROC(void, glReadPixels,
    1.99 -         (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
   1.100 -          GLenum type, GLvoid * pixels))
   1.101 +SDL_PROC_UNUSED(void, glReadPixels,
   1.102 +                (GLint x, GLint y, GLsizei width, GLsizei height,
   1.103 +                 GLenum format, GLenum type, GLvoid * pixels))
   1.104  SDL_PROC_UNUSED(void, glRectd,
   1.105                  (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2))
   1.106  SDL_PROC_UNUSED(void, glRectdv, (const GLdouble * v1, const GLdouble * v2))
   1.107 @@ -418,7 +418,7 @@
   1.108           (GLenum target, GLint level, GLint xoffset, GLint yoffset,
   1.109            GLsizei width, GLsizei height, GLenum format, GLenum type,
   1.110            const GLvoid * pixels))
   1.111 -SDL_PROC(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z))
   1.112 +SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z))
   1.113  SDL_PROC_UNUSED(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z))
   1.114  SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y))
   1.115  SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble * v))
   1.116 @@ -451,4 +451,5 @@
   1.117                  (GLint size, GLenum type, GLsizei stride,
   1.118                   const GLvoid * pointer))
   1.119  SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height))
   1.120 +
   1.121  /* vi: set ts=4 sw=4 expandtab: */
     2.1 --- a/src/video/SDL_renderer_gl.c	Sat Jul 22 21:58:17 2006 +0000
     2.2 +++ b/src/video/SDL_renderer_gl.c	Sat Jul 22 23:04:41 2006 +0000
     2.3 @@ -98,6 +98,13 @@
     2.4  {
     2.5      SDL_GLContext context;
     2.6      SDL_bool GL_ARB_texture_rectangle_supported;
     2.7 +    int blendMode;
     2.8 +    int scaleMode;
     2.9 +
    2.10 +    /* OpenGL functions */
    2.11 +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
    2.12 +#include "SDL_glfuncs.h"
    2.13 +#undef SDL_PROC
    2.14  } GL_RenderData;
    2.15  
    2.16  typedef struct
    2.17 @@ -151,6 +158,32 @@
    2.18      SDL_SetError("%s: %s", prefix, error);
    2.19  }
    2.20  
    2.21 +static int
    2.22 +GL_LoadFunctions(GL_RenderData * data)
    2.23 +{
    2.24 +#if defined(__QNXNTO__) && (_NTO_VERSION < 630)
    2.25 +#define __SDL_NOGETPROCADDR__
    2.26 +#elif defined(__MINT__)
    2.27 +#define __SDL_NOGETPROCADDR__
    2.28 +#endif
    2.29 +#ifdef __SDL_NOGETPROCADDR__
    2.30 +#define SDL_PROC(ret,func,params) data->func=func;
    2.31 +#else
    2.32 +#define SDL_PROC(ret,func,params) \
    2.33 +    do { \
    2.34 +        data->func = SDL_GL_GetProcAddress(#func); \
    2.35 +        if ( ! data->func ) { \
    2.36 +            SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
    2.37 +            return -1; \
    2.38 +        } \
    2.39 +    } while ( 0 );
    2.40 +#endif /* __SDL_NOGETPROCADDR__ */
    2.41 +
    2.42 +#include "SDL_glfuncs.h"
    2.43 +#undef SDL_PROC
    2.44 +    return 0;
    2.45 +}
    2.46 +
    2.47  void
    2.48  GL_AddRenderDriver(_THIS)
    2.49  {
    2.50 @@ -205,6 +238,11 @@
    2.51      renderer->info.flags =
    2.52          (SDL_Renderer_PresentDiscard | SDL_Renderer_Accelerated);
    2.53  
    2.54 +    if (GL_LoadFunctions(data) < 0) {
    2.55 +        GL_DestroyRenderer(renderer);
    2.56 +        return NULL;
    2.57 +    }
    2.58 +
    2.59      data->context = SDL_GL_CreateContext(window->id);
    2.60      if (!data->context) {
    2.61          GL_DestroyRenderer(renderer);
    2.62 @@ -224,8 +262,10 @@
    2.63          renderer->info.flags |= SDL_Renderer_PresentVSync;
    2.64      }
    2.65  
    2.66 -    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer->info.max_texture_width);
    2.67 -    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer->info.max_texture_height);
    2.68 +    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE,
    2.69 +                        &renderer->info.max_texture_width);
    2.70 +    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE,
    2.71 +                        &renderer->info.max_texture_height);
    2.72  
    2.73      if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
    2.74          || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
    2.75 @@ -233,19 +273,22 @@
    2.76      }
    2.77  
    2.78      /* Set up parameters for rendering */
    2.79 -    glDisable(GL_DEPTH_TEST);
    2.80 -    glDisable(GL_CULL_FACE);
    2.81 +    data->blendMode = -1;
    2.82 +    data->scaleMode = -1;
    2.83 +    data->glDisable(GL_DEPTH_TEST);
    2.84 +    data->glDisable(GL_CULL_FACE);
    2.85      if (data->GL_ARB_texture_rectangle_supported) {
    2.86 -        glEnable(GL_TEXTURE_RECTANGLE_ARB);
    2.87 +        data->glEnable(GL_TEXTURE_RECTANGLE_ARB);
    2.88      } else {
    2.89 -        glEnable(GL_TEXTURE_2D);
    2.90 +        data->glEnable(GL_TEXTURE_2D);
    2.91      }
    2.92 -    glMatrixMode(GL_PROJECTION);
    2.93 -    glLoadIdentity();
    2.94 -    glMatrixMode(GL_MODELVIEW);
    2.95 -    glLoadIdentity();
    2.96 -    glViewport(0, 0, window->w, window->h);
    2.97 -    glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0, 1.0);
    2.98 +    data->glMatrixMode(GL_PROJECTION);
    2.99 +    data->glLoadIdentity();
   2.100 +    data->glMatrixMode(GL_MODELVIEW);
   2.101 +    data->glLoadIdentity();
   2.102 +    data->glViewport(0, 0, window->w, window->h);
   2.103 +    data->glOrtho(0.0, (GLdouble) window->w, (GLdouble) window->h, 0.0, 0.0,
   2.104 +                  1.0);
   2.105  
   2.106      return renderer;
   2.107  }
   2.108 @@ -371,8 +414,8 @@
   2.109  
   2.110      texture->driverdata = data;
   2.111  
   2.112 -    glGetError();
   2.113 -    glGenTextures(1, &data->texture);
   2.114 +    renderdata->glGetError();
   2.115 +    renderdata->glGenTextures(1, &data->texture);
   2.116      if (renderdata->GL_ARB_texture_rectangle_supported) {
   2.117          data->type = GL_TEXTURE_RECTANGLE_ARB;
   2.118          texture_w = texture->w;
   2.119 @@ -388,10 +431,10 @@
   2.120      }
   2.121      data->format = format;
   2.122      data->formattype = type;
   2.123 -    glBindTexture(data->type, data->texture);
   2.124 -    glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0,
   2.125 -                 format, type, NULL);
   2.126 -    result = glGetError();
   2.127 +    renderdata->glBindTexture(data->type, data->texture);
   2.128 +    renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
   2.129 +                             texture_h, 0, format, type, NULL);
   2.130 +    result = renderdata->glGetError();
   2.131      if (result != GL_NO_ERROR) {
   2.132          GL_SetError("glTexImage2D()", result);
   2.133          return -1;
   2.134 @@ -419,31 +462,34 @@
   2.135  }
   2.136  
   2.137  static void
   2.138 -SetupTextureUpdate(SDL_Texture * texture, int pitch)
   2.139 +SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
   2.140 +                   int pitch)
   2.141  {
   2.142      if (texture->format == SDL_PixelFormat_Index1LSB) {
   2.143 -        glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
   2.144 +        renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
   2.145      } else if (texture->format == SDL_PixelFormat_Index1MSB) {
   2.146 -        glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
   2.147 +        renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
   2.148      }
   2.149 -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2.150 -    glPixelStorei(GL_UNPACK_ROW_LENGTH,
   2.151 -                  pitch / SDL_BYTESPERPIXEL(texture->format));
   2.152 +    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2.153 +    renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
   2.154 +                              pitch / SDL_BYTESPERPIXEL(texture->format));
   2.155  }
   2.156  
   2.157  static int
   2.158  GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   2.159                   const SDL_Rect * rect, const void *pixels, int pitch)
   2.160  {
   2.161 +    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   2.162      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   2.163      GLenum result;
   2.164  
   2.165 -    glGetError();
   2.166 -    SetupTextureUpdate(texture, pitch);
   2.167 -    glBindTexture(data->type, data->texture);
   2.168 -    glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, rect->h,
   2.169 -                    data->format, data->formattype, pixels);
   2.170 -    result = glGetError();
   2.171 +    renderdata->glGetError();
   2.172 +    SetupTextureUpdate(renderdata, texture, pitch);
   2.173 +    renderdata->glBindTexture(data->type, data->texture);
   2.174 +    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
   2.175 +                                rect->h, data->format, data->formattype,
   2.176 +                                pixels);
   2.177 +    result = renderdata->glGetError();
   2.178      if (result != GL_NO_ERROR) {
   2.179          GL_SetError("glTexSubImage2D()", result);
   2.180          return -1;
   2.181 @@ -507,10 +553,10 @@
   2.182      g = ((GLclampf) ((color >> 8) & 0xFF)) / 255.0f;
   2.183      b = ((GLclampf) (color & 0xFF)) / 255.0f;
   2.184  
   2.185 -    glClearColor(r, g, b, a);
   2.186 -    glViewport(rect->x, window->h - rect->y, rect->w, rect->h);
   2.187 -    glClear(GL_COLOR_BUFFER_BIT);
   2.188 -    glViewport(0, 0, window->w, window->h);
   2.189 +    data->glClearColor(r, g, b, a);
   2.190 +    data->glViewport(rect->x, window->h - rect->y, rect->w, rect->h);
   2.191 +    data->glClear(GL_COLOR_BUFFER_BIT);
   2.192 +    data->glViewport(0, 0, window->w, window->h);
   2.193      return 0;
   2.194  }
   2.195  
   2.196 @@ -530,16 +576,16 @@
   2.197          int bpp = SDL_BYTESPERPIXEL(texture->format);
   2.198          int pitch = texturedata->pitch;
   2.199  
   2.200 -        SetupTextureUpdate(texture, pitch);
   2.201 -        glBindTexture(texturedata->type, texturedata->texture);
   2.202 +        SetupTextureUpdate(data, texture, pitch);
   2.203 +        data->glBindTexture(texturedata->type, texturedata->texture);
   2.204          for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
   2.205              SDL_Rect *rect = &dirty->rect;
   2.206              pixels =
   2.207                  (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
   2.208                            rect->x * bpp);
   2.209 -            glTexSubImage2D(texturedata->type, 0, rect->x, rect->y, rect->w,
   2.210 -                            rect->h, texturedata->format,
   2.211 -                            texturedata->formattype, pixels);
   2.212 +            data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y,
   2.213 +                                  rect->w, rect->h, texturedata->format,
   2.214 +                                  texturedata->formattype, pixels);
   2.215          }
   2.216          SDL_ClearDirtyRects(&texturedata->dirty);
   2.217      }
   2.218 @@ -558,54 +604,64 @@
   2.219      maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
   2.220      maxv *= texturedata->texh;
   2.221  
   2.222 -    glBindTexture(texturedata->type, texturedata->texture);
   2.223 +    data->glBindTexture(texturedata->type, texturedata->texture);
   2.224  
   2.225 -    switch (blendMode) {
   2.226 -    case SDL_TextureBlendMode_None:
   2.227 -        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
   2.228 -        glDisable(GL_BLEND);
   2.229 -        break;
   2.230 -    case SDL_TextureBlendMode_Mask:
   2.231 -    case SDL_TextureBlendMode_Blend:
   2.232 -        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.233 -        glEnable(GL_BLEND);
   2.234 -        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   2.235 -        break;
   2.236 -    case SDL_TextureBlendMode_Add:
   2.237 -        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.238 -        glEnable(GL_BLEND);
   2.239 -        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   2.240 -        break;
   2.241 -    case SDL_TextureBlendMode_Mod:
   2.242 -        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.243 -        glEnable(GL_BLEND);
   2.244 -        glBlendFunc(GL_ZERO, GL_SRC_COLOR);
   2.245 -        break;
   2.246 +    if (blendMode != data->blendMode) {
   2.247 +        switch (blendMode) {
   2.248 +        case SDL_TextureBlendMode_None:
   2.249 +            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
   2.250 +            data->glDisable(GL_BLEND);
   2.251 +            break;
   2.252 +        case SDL_TextureBlendMode_Mask:
   2.253 +        case SDL_TextureBlendMode_Blend:
   2.254 +            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.255 +            data->glEnable(GL_BLEND);
   2.256 +            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   2.257 +            break;
   2.258 +        case SDL_TextureBlendMode_Add:
   2.259 +            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.260 +            data->glEnable(GL_BLEND);
   2.261 +            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   2.262 +            break;
   2.263 +        case SDL_TextureBlendMode_Mod:
   2.264 +            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   2.265 +            data->glEnable(GL_BLEND);
   2.266 +            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
   2.267 +            break;
   2.268 +        }
   2.269 +        data->blendMode = blendMode;
   2.270      }
   2.271  
   2.272 -    switch (scaleMode) {
   2.273 -    case SDL_TextureScaleMode_None:
   2.274 -    case SDL_TextureScaleMode_Fast:
   2.275 -        glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2.276 -        glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2.277 -        break;
   2.278 -    case SDL_TextureScaleMode_Slow:
   2.279 -    case SDL_TextureScaleMode_Best:
   2.280 -        glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   2.281 -        glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   2.282 -        break;
   2.283 +    if (scaleMode != data->scaleMode) {
   2.284 +        switch (scaleMode) {
   2.285 +        case SDL_TextureScaleMode_None:
   2.286 +        case SDL_TextureScaleMode_Fast:
   2.287 +            data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
   2.288 +                                  GL_NEAREST);
   2.289 +            data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
   2.290 +                                  GL_NEAREST);
   2.291 +            break;
   2.292 +        case SDL_TextureScaleMode_Slow:
   2.293 +        case SDL_TextureScaleMode_Best:
   2.294 +            data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
   2.295 +                                  GL_LINEAR);
   2.296 +            data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
   2.297 +                                  GL_LINEAR);
   2.298 +            break;
   2.299 +        }
   2.300 +        data->scaleMode = scaleMode;
   2.301      }
   2.302  
   2.303 -    glBegin(GL_TRIANGLE_STRIP);
   2.304 -    glTexCoord2f(minu, minv);
   2.305 -    glVertex2i(minx, miny);
   2.306 -    glTexCoord2f(maxu, minv);
   2.307 -    glVertex2i(maxx, miny);
   2.308 -    glTexCoord2f(minu, maxv);
   2.309 -    glVertex2i(minx, maxy);
   2.310 -    glTexCoord2f(maxu, maxv);
   2.311 -    glVertex2i(maxx, maxy);
   2.312 -    glEnd();
   2.313 +    data->glBegin(GL_TRIANGLE_STRIP);
   2.314 +    data->glTexCoord2f(minu, minv);
   2.315 +    data->glVertex2i(minx, miny);
   2.316 +    data->glTexCoord2f(maxu, minv);
   2.317 +    data->glVertex2i(maxx, miny);
   2.318 +    data->glTexCoord2f(minu, maxv);
   2.319 +    data->glVertex2i(minx, maxy);
   2.320 +    data->glTexCoord2f(maxu, maxv);
   2.321 +    data->glVertex2i(maxx, maxy);
   2.322 +    data->glEnd();
   2.323  
   2.324      return 0;
   2.325  }
   2.326 @@ -619,13 +675,14 @@
   2.327  static void
   2.328  GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   2.329  {
   2.330 +    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   2.331      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   2.332  
   2.333      if (!data) {
   2.334          return;
   2.335      }
   2.336      if (data->texture) {
   2.337 -        glDeleteTextures(1, &data->texture);
   2.338 +        renderdata->glDeleteTextures(1, &data->texture);
   2.339      }
   2.340      if (data->pixels) {
   2.341          SDL_free(data->pixels);