src/video/SDL_renderer_gles.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 24 Mar 2009 10:33:12 +0000
changeset 3099 82e60908fab1
parent 2964 0faae272a372
child 3122 6c98826d88b0
permissions -rw-r--r--
Date: Mon, 23 Mar 2009 09:17:24 +0200
From: "Mike Gorchak"
Subject: New QNX patches

Please apply patch qnx4.diff, which is attached. What has been done:
1)Added back OpenGL ES renderer for QNX target. Added few corrections to
OpenGL ES renderer to let it work under QNX. OpenGL ES renderer do not
support textures under QNX, so I think some additional work must be done.
2) Added GL_OES_query_matrix extension to SDL_opengles.h header file, which
required by OpenGL ES 1.1 specification.
3) Added attribute clearing at the entrance of function
SDL_GL_GetAttribure(). Added error checking into the function
SDL_GL_GetAttribure(), because some attributes can't be obtained in OpenGL
ES 1.0.
4) Porting testdyngles to OpenGL ES 1.0 (1.1 has glColor4ub() and
glColor4f() functions, but 1.0 has glColor4f() only).
5) Added error checking after obtaining attributes using
SDL_GL_GetAttribute() function to the testgl2 and testgles.
6) Small correction to testmultiaudio with printing errors.
7) Added software and accelerated OpenGL ES 1.0 support into the QNX GF
driver.

Please remove ./src/audio/nto directory - it will not be used anymore.
Please create ./src/audio/qsa directory and add content of the archive
qsa.tar.gz into this directory. I rewrote some sound code, added support for
multiple audio cards, enumeration, etc. Added initial support for capture.

As far as I can understand SDL 1.3 is not supporting audio capture right now
? Sam, Am I right ? Or audio capture must be supported through the
PlayDevice routine ?

And last, please put file SDL_gf_opengles.c to the ./src/video/qnxgf
directory. It is OpenGL ES 1.1 emulation layer for some functions, which are
not supported by OpenGL ES 1.0.
hfutrell@2739
     1
/*
hfutrell@2739
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 Sam Lantinga
hfutrell@2739
     4
hfutrell@2739
     5
    This library is free software; you can redistribute it and/or
hfutrell@2739
     6
    modify it under the terms of the GNU Lesser General Public
hfutrell@2739
     7
    License as published by the Free Software Foundation; either
hfutrell@2739
     8
    version 2.1 of the License, or (at your option) any later version.
hfutrell@2739
     9
hfutrell@2739
    10
    This library is distributed in the hope that it will be useful,
hfutrell@2739
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
hfutrell@2739
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
hfutrell@2739
    13
    Lesser General Public License for more details.
hfutrell@2739
    14
hfutrell@2739
    15
    You should have received a copy of the GNU Lesser General Public
hfutrell@2739
    16
    License along with this library; if not, write to the Free Software
hfutrell@2739
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
hfutrell@2739
    18
hfutrell@2739
    19
    Sam Lantinga
hfutrell@2739
    20
    slouken@libsdl.org
hfutrell@2739
    21
*/
hfutrell@2739
    22
#include "SDL_config.h"
hfutrell@2739
    23
hfutrell@2739
    24
#if SDL_VIDEO_RENDER_OGL_ES
hfutrell@2739
    25
hfutrell@2739
    26
#include "SDL_video.h"
hfutrell@2739
    27
#include "SDL_opengles.h"
hfutrell@2739
    28
#include "SDL_sysvideo.h"
hfutrell@2739
    29
#include "SDL_pixels_c.h"
hfutrell@2739
    30
#include "SDL_rect_c.h"
hfutrell@2739
    31
#include "SDL_yuv_sw_c.h"
hfutrell@2739
    32
slouken@3099
    33
#ifdef __QNXNTO__
slouken@3099
    34
slouken@3099
    35
/* Empty function stub to get OpenGL ES 1.0 support without  */
slouken@3099
    36
/* OpenGL ES extension GL_OES_draw_texture_supported         */
slouken@3099
    37
GL_API void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
slouken@3099
    38
{
slouken@3099
    39
   return;
slouken@3099
    40
}
slouken@3099
    41
slouken@3099
    42
#endif /* __QNXNTO__ */
slouken@3099
    43
hfutrell@2739
    44
/* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
hfutrell@2739
    45
hfutrell@2739
    46
static const float inv255f = 1.0f / 255.0f;
hfutrell@2739
    47
hfutrell@2739
    48
static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
hfutrell@2739
    49
static int GLES_ActivateRenderer(SDL_Renderer * renderer);
hfutrell@2739
    50
static int GLES_DisplayModeChanged(SDL_Renderer * renderer);
hfutrell@2739
    51
static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
hfutrell@2739
    52
static int GLES_QueryTexturePixels(SDL_Renderer * renderer,
slouken@2753
    53
                                   SDL_Texture * texture, void **pixels,
slouken@2753
    54
                                   int *pitch);
hfutrell@2739
    55
static int GLES_SetTexturePalette(SDL_Renderer * renderer,
slouken@2753
    56
                                  SDL_Texture * texture,
slouken@2753
    57
                                  const SDL_Color * colors, int firstcolor,
slouken@2753
    58
                                  int ncolors);
hfutrell@2739
    59
static int GLES_GetTexturePalette(SDL_Renderer * renderer,
slouken@2753
    60
                                  SDL_Texture * texture, SDL_Color * colors,
slouken@2753
    61
                                  int firstcolor, int ncolors);
hfutrell@2739
    62
static int GLES_SetTextureColorMod(SDL_Renderer * renderer,
slouken@2753
    63
                                   SDL_Texture * texture);
hfutrell@2739
    64
static int GLES_SetTextureAlphaMod(SDL_Renderer * renderer,
slouken@2753
    65
                                   SDL_Texture * texture);
hfutrell@2739
    66
static int GLES_SetTextureBlendMode(SDL_Renderer * renderer,
slouken@2753
    67
                                    SDL_Texture * texture);
hfutrell@2739
    68
static int GLES_SetTextureScaleMode(SDL_Renderer * renderer,
slouken@2753
    69
                                    SDL_Texture * texture);
hfutrell@2739
    70
static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
    71
                              const SDL_Rect * rect, const void *pixels,
slouken@2753
    72
                              int pitch);
hfutrell@2739
    73
static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
    74
                            const SDL_Rect * rect, int markDirty,
slouken@2753
    75
                            void **pixels, int *pitch);
slouken@2753
    76
static void GLES_UnlockTexture(SDL_Renderer * renderer,
slouken@2753
    77
                               SDL_Texture * texture);
hfutrell@2739
    78
static void GLES_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
    79
                              int numrects, const SDL_Rect * rects);
slouken@2936
    80
static int GLES_RenderPoint(SDL_Renderer * renderer, int x, int y);
slouken@2936
    81
static int GLES_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
slouken@2936
    82
                           int y2);
slouken@2936
    83
static int GLES_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
hfutrell@2739
    84
static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
    85
                           const SDL_Rect * srcrect,
slouken@2753
    86
                           const SDL_Rect * dstrect);
hfutrell@2739
    87
static void GLES_RenderPresent(SDL_Renderer * renderer);
slouken@2753
    88
static void GLES_DestroyTexture(SDL_Renderer * renderer,
slouken@2753
    89
                                SDL_Texture * texture);
hfutrell@2739
    90
static void GLES_DestroyRenderer(SDL_Renderer * renderer);
hfutrell@2739
    91
hfutrell@2739
    92
hfutrell@2739
    93
SDL_RenderDriver GL_ES_RenderDriver = {
hfutrell@2739
    94
    GLES_CreateRenderer,
hfutrell@2739
    95
    {
hfutrell@2739
    96
     "opengl_es",
hfutrell@2739
    97
     (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD |
hfutrell@2739
    98
      SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
hfutrell@2739
    99
     (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
hfutrell@2739
   100
      SDL_TEXTUREMODULATE_ALPHA),
slouken@2884
   101
     (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
slouken@2884
   102
      SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
hfutrell@2739
   103
     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
hfutrell@2739
   104
      SDL_TEXTURESCALEMODE_SLOW), 2,
slouken@2753
   105
     {
slouken@2753
   106
      SDL_PIXELFORMAT_RGB24,
slouken@2753
   107
      SDL_PIXELFORMAT_ABGR8888,
slouken@2753
   108
      },
slouken@2753
   109
     0,
hfutrell@2739
   110
     0}
hfutrell@2739
   111
};
hfutrell@2739
   112
hfutrell@2739
   113
typedef struct
hfutrell@2739
   114
{
hfutrell@2739
   115
    SDL_GLContext context;
hfutrell@2739
   116
    SDL_bool updateSize;
hfutrell@2739
   117
    int blendMode;
slouken@2753
   118
hfutrell@2739
   119
#ifndef APIENTRY
hfutrell@2739
   120
#define APIENTRY
hfutrell@2739
   121
#endif
slouken@2753
   122
slouken@2753
   123
    SDL_bool useDrawTexture;
slouken@2753
   124
    SDL_bool GL_OES_draw_texture_supported;
slouken@2753
   125
slouken@2753
   126
    /* OpenGL ES functions */
slouken@2753
   127
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
slouken@2753
   128
#include "SDL_glesfuncs.h"
slouken@2753
   129
#undef SDL_PROC
hfutrell@2739
   130
hfutrell@2739
   131
} GLES_RenderData;
hfutrell@2739
   132
hfutrell@2739
   133
typedef struct
hfutrell@2739
   134
{
hfutrell@2739
   135
    GLuint texture;
hfutrell@2739
   136
    GLenum type;
hfutrell@2739
   137
    GLfloat texw;
hfutrell@2739
   138
    GLfloat texh;
hfutrell@2739
   139
    GLenum format;
hfutrell@2739
   140
    GLenum formattype;
hfutrell@2739
   141
    void *pixels;
hfutrell@2739
   142
    int pitch;
hfutrell@2739
   143
    SDL_DirtyRectList dirty;
hfutrell@2739
   144
} GLES_TextureData;
hfutrell@2739
   145
hfutrell@2739
   146
static void
hfutrell@2739
   147
GLES_SetError(const char *prefix, GLenum result)
hfutrell@2739
   148
{
hfutrell@2739
   149
    const char *error;
hfutrell@2739
   150
hfutrell@2739
   151
    switch (result) {
hfutrell@2739
   152
    case GL_NO_ERROR:
hfutrell@2739
   153
        error = "GL_NO_ERROR";
hfutrell@2739
   154
        break;
hfutrell@2739
   155
    case GL_INVALID_ENUM:
hfutrell@2739
   156
        error = "GL_INVALID_ENUM";
hfutrell@2739
   157
        break;
hfutrell@2739
   158
    case GL_INVALID_VALUE:
hfutrell@2739
   159
        error = "GL_INVALID_VALUE";
hfutrell@2739
   160
        break;
hfutrell@2739
   161
    case GL_INVALID_OPERATION:
hfutrell@2739
   162
        error = "GL_INVALID_OPERATION";
hfutrell@2739
   163
        break;
hfutrell@2739
   164
    case GL_STACK_OVERFLOW:
hfutrell@2739
   165
        error = "GL_STACK_OVERFLOW";
hfutrell@2739
   166
        break;
hfutrell@2739
   167
    case GL_STACK_UNDERFLOW:
hfutrell@2739
   168
        error = "GL_STACK_UNDERFLOW";
hfutrell@2739
   169
        break;
hfutrell@2739
   170
    case GL_OUT_OF_MEMORY:
hfutrell@2739
   171
        error = "GL_OUT_OF_MEMORY";
hfutrell@2739
   172
        break;
hfutrell@2739
   173
    default:
hfutrell@2739
   174
        error = "UNKNOWN";
hfutrell@2739
   175
        break;
hfutrell@2739
   176
    }
hfutrell@2739
   177
    SDL_SetError("%s: %s", prefix, error);
hfutrell@2739
   178
}
hfutrell@2739
   179
hfutrell@2739
   180
static int
hfutrell@2739
   181
GLES_LoadFunctions(GLES_RenderData * data)
hfutrell@2739
   182
{
slouken@2753
   183
slouken@2753
   184
#define SDL_PROC(ret,func,params) \
hfutrell@2739
   185
	data->func = func;
slouken@2753
   186
#include "SDL_glesfuncs.h"
slouken@2753
   187
#undef SDL_PROC
slouken@2753
   188
hfutrell@2739
   189
    return 0;
hfutrell@2739
   190
}
hfutrell@2739
   191
hfutrell@2739
   192
void
hfutrell@2739
   193
GLES_AddRenderDriver(_THIS)
hfutrell@2739
   194
{
hfutrell@2739
   195
    if (_this->GL_CreateContext) {
hfutrell@2739
   196
        SDL_AddRenderDriver(0, &GL_ES_RenderDriver);
hfutrell@2739
   197
    }
hfutrell@2739
   198
}
hfutrell@2739
   199
hfutrell@2739
   200
SDL_Renderer *
hfutrell@2739
   201
GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
hfutrell@2739
   202
{
slouken@2753
   203
hfutrell@2739
   204
    SDL_Renderer *renderer;
hfutrell@2739
   205
    GLES_RenderData *data;
hfutrell@2739
   206
    GLint value;
hfutrell@2739
   207
    int doublebuffer;
hfutrell@2739
   208
hfutrell@2739
   209
    if (!(window->flags & SDL_WINDOW_OPENGL)) {
hfutrell@2739
   210
        if (SDL_RecreateWindow(window, window->flags | SDL_WINDOW_OPENGL) < 0) {
hfutrell@2739
   211
            return NULL;
hfutrell@2739
   212
        }
hfutrell@2739
   213
    }
hfutrell@2739
   214
hfutrell@2739
   215
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
hfutrell@2739
   216
    if (!renderer) {
hfutrell@2739
   217
        SDL_OutOfMemory();
hfutrell@2739
   218
        return NULL;
hfutrell@2739
   219
    }
hfutrell@2739
   220
hfutrell@2739
   221
    data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
hfutrell@2739
   222
    if (!data) {
hfutrell@2739
   223
        GLES_DestroyRenderer(renderer);
hfutrell@2739
   224
        SDL_OutOfMemory();
hfutrell@2739
   225
        return NULL;
hfutrell@2739
   226
    }
hfutrell@2739
   227
hfutrell@2739
   228
    renderer->ActivateRenderer = GLES_ActivateRenderer;
hfutrell@2739
   229
    renderer->DisplayModeChanged = GLES_DisplayModeChanged;
hfutrell@2739
   230
    renderer->CreateTexture = GLES_CreateTexture;
hfutrell@2739
   231
    renderer->QueryTexturePixels = GLES_QueryTexturePixels;
hfutrell@2739
   232
    renderer->SetTexturePalette = GLES_SetTexturePalette;
hfutrell@2739
   233
    renderer->GetTexturePalette = GLES_GetTexturePalette;
hfutrell@2739
   234
    renderer->SetTextureColorMod = GLES_SetTextureColorMod;
hfutrell@2739
   235
    renderer->SetTextureAlphaMod = GLES_SetTextureAlphaMod;
hfutrell@2739
   236
    renderer->SetTextureBlendMode = GLES_SetTextureBlendMode;
hfutrell@2739
   237
    renderer->SetTextureScaleMode = GLES_SetTextureScaleMode;
hfutrell@2739
   238
    renderer->UpdateTexture = GLES_UpdateTexture;
hfutrell@2739
   239
    renderer->LockTexture = GLES_LockTexture;
hfutrell@2739
   240
    renderer->UnlockTexture = GLES_UnlockTexture;
hfutrell@2739
   241
    renderer->DirtyTexture = GLES_DirtyTexture;
slouken@2936
   242
    renderer->RenderPoint = GLES_RenderPoint;
slouken@2936
   243
    renderer->RenderLine = GLES_RenderLine;
hfutrell@2739
   244
    renderer->RenderFill = GLES_RenderFill;
hfutrell@2739
   245
    renderer->RenderCopy = GLES_RenderCopy;
hfutrell@2739
   246
    renderer->RenderPresent = GLES_RenderPresent;
hfutrell@2739
   247
    renderer->DestroyTexture = GLES_DestroyTexture;
hfutrell@2739
   248
    renderer->DestroyRenderer = GLES_DestroyRenderer;
hfutrell@2739
   249
    renderer->info = GL_ES_RenderDriver.info;
hfutrell@2739
   250
    renderer->window = window->id;
hfutrell@2739
   251
    renderer->driverdata = data;
slouken@2753
   252
slouken@2753
   253
slouken@2753
   254
    renderer->info.flags =
slouken@2753
   255
        (SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED);
hfutrell@2739
   256
hfutrell@2739
   257
    if (GLES_LoadFunctions(data) < 0) {
hfutrell@2739
   258
        GLES_DestroyRenderer(renderer);
hfutrell@2739
   259
        return NULL;
hfutrell@2739
   260
    }
hfutrell@2739
   261
hfutrell@2739
   262
    data->context = SDL_GL_CreateContext(window->id);
hfutrell@2739
   263
    if (!data->context) {
hfutrell@2739
   264
        GLES_DestroyRenderer(renderer);
hfutrell@2739
   265
        return NULL;
hfutrell@2739
   266
    }
hfutrell@2739
   267
    if (SDL_GL_MakeCurrent(window->id, data->context) < 0) {
hfutrell@2739
   268
        GLES_DestroyRenderer(renderer);
hfutrell@2739
   269
        return NULL;
hfutrell@2739
   270
    }
hfutrell@2739
   271
hfutrell@2739
   272
    if (flags & SDL_RENDERER_PRESENTVSYNC) {
hfutrell@2739
   273
        SDL_GL_SetSwapInterval(1);
hfutrell@2739
   274
    } else {
hfutrell@2739
   275
        SDL_GL_SetSwapInterval(0);
hfutrell@2739
   276
    }
hfutrell@2739
   277
    if (SDL_GL_GetSwapInterval() > 0) {
hfutrell@2739
   278
        renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
hfutrell@2739
   279
    }
hfutrell@2739
   280
hfutrell@2739
   281
    if (SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuffer) == 0) {
hfutrell@2739
   282
        if (!doublebuffer) {
hfutrell@2739
   283
            renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
hfutrell@2739
   284
        }
hfutrell@2739
   285
    }
slouken@2753
   286
slouken@2753
   287
    if (SDL_GL_ExtensionSupported("GL_OES_draw_texture")) {
slouken@2753
   288
        data->GL_OES_draw_texture_supported = SDL_TRUE;
slouken@2753
   289
        data->useDrawTexture = SDL_TRUE;
slouken@2753
   290
    } else {
slouken@2753
   291
        data->GL_OES_draw_texture_supported = SDL_FALSE;
slouken@2753
   292
        data->useDrawTexture = SDL_FALSE;
slouken@2753
   293
    }
hfutrell@2739
   294
hfutrell@2739
   295
    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
hfutrell@2739
   296
    renderer->info.max_texture_width = value;
hfutrell@2739
   297
    data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
hfutrell@2739
   298
    renderer->info.max_texture_height = value;
hfutrell@2739
   299
hfutrell@2739
   300
    /* Set up parameters for rendering */
hfutrell@2739
   301
    data->blendMode = -1;
hfutrell@2739
   302
    data->glDisable(GL_DEPTH_TEST);
hfutrell@2739
   303
    data->glDisable(GL_CULL_FACE);
slouken@2753
   304
    data->glEnable(GL_TEXTURE_2D);
hfutrell@2739
   305
    data->updateSize = SDL_TRUE;
hfutrell@2739
   306
hfutrell@2739
   307
    return renderer;
hfutrell@2739
   308
}
hfutrell@2739
   309
slouken@2753
   310
static int
slouken@2753
   311
GLES_ActivateRenderer(SDL_Renderer * renderer)
hfutrell@2739
   312
{
slouken@2753
   313
slouken@2753
   314
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   315
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
slouken@2753
   316
hfutrell@2739
   317
    if (SDL_GL_MakeCurrent(window->id, data->context) < 0) {
hfutrell@2739
   318
        return -1;
hfutrell@2739
   319
    }
hfutrell@2739
   320
    if (data->updateSize) {
hfutrell@2739
   321
        data->glMatrixMode(GL_PROJECTION);
hfutrell@2739
   322
        data->glLoadIdentity();
hfutrell@2739
   323
        data->glMatrixMode(GL_MODELVIEW);
hfutrell@2739
   324
        data->glLoadIdentity();
hfutrell@2739
   325
        data->glViewport(0, 0, window->w, window->h);
slouken@2753
   326
        data->glOrthof(0.0, (GLfloat) window->w, (GLfloat) window->h, 0.0,
slouken@2753
   327
                       0.0, 1.0);
hfutrell@2739
   328
        data->updateSize = SDL_FALSE;
hfutrell@2739
   329
    }
hfutrell@2739
   330
    return 0;
hfutrell@2739
   331
}
hfutrell@2739
   332
hfutrell@2739
   333
static int
hfutrell@2739
   334
GLES_DisplayModeChanged(SDL_Renderer * renderer)
hfutrell@2739
   335
{
hfutrell@2739
   336
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   337
hfutrell@2739
   338
    data->updateSize = SDL_TRUE;
hfutrell@2739
   339
    return 0;
hfutrell@2739
   340
}
hfutrell@2739
   341
hfutrell@2739
   342
static __inline__ int
hfutrell@2739
   343
power_of_2(int input)
hfutrell@2739
   344
{
hfutrell@2739
   345
    int value = 1;
hfutrell@2739
   346
hfutrell@2739
   347
    while (value < input) {
hfutrell@2739
   348
        value <<= 1;
hfutrell@2739
   349
    }
hfutrell@2739
   350
    return value;
hfutrell@2739
   351
}
hfutrell@2739
   352
hfutrell@2739
   353
static int
hfutrell@2739
   354
GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   355
{
hfutrell@2739
   356
    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   357
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
hfutrell@2739
   358
    GLES_TextureData *data;
hfutrell@2739
   359
    GLint internalFormat;
hfutrell@2739
   360
    GLenum format, type;
hfutrell@2739
   361
    int texture_w, texture_h;
hfutrell@2739
   362
    GLenum result;
slouken@3099
   363
slouken@2753
   364
    switch (texture->format) {
slouken@2753
   365
    case SDL_PIXELFORMAT_INDEX1LSB:
slouken@2753
   366
    case SDL_PIXELFORMAT_INDEX1MSB:
slouken@2753
   367
    case SDL_PIXELFORMAT_INDEX8:
slouken@2753
   368
    case SDL_PIXELFORMAT_RGB332:
slouken@2753
   369
    case SDL_PIXELFORMAT_RGB444:
slouken@2753
   370
    case SDL_PIXELFORMAT_RGB555:
slouken@2753
   371
    case SDL_PIXELFORMAT_ARGB4444:
slouken@2753
   372
    case SDL_PIXELFORMAT_ARGB1555:
slouken@2753
   373
    case SDL_PIXELFORMAT_BGR24:
slouken@2753
   374
    case SDL_PIXELFORMAT_BGR888:
slouken@2753
   375
    case SDL_PIXELFORMAT_RGB888:
slouken@2753
   376
    case SDL_PIXELFORMAT_RGBA8888:
slouken@2753
   377
    case SDL_PIXELFORMAT_ARGB2101010:
slouken@2753
   378
    case SDL_PIXELFORMAT_ARGB8888:
slouken@2753
   379
    case SDL_PIXELFORMAT_RGB24:
slouken@2753
   380
        internalFormat = GL_RGB;
slouken@2753
   381
        format = GL_RGB;
slouken@2753
   382
        type = GL_UNSIGNED_BYTE;
slouken@2753
   383
        break;
slouken@2753
   384
    case SDL_PIXELFORMAT_ABGR8888:
slouken@2753
   385
        internalFormat = GL_RGBA;
slouken@2753
   386
        format = GL_RGBA;
slouken@2753
   387
        type = GL_UNSIGNED_BYTE;
slouken@2753
   388
        break;
slouken@2753
   389
        /*
slouken@2753
   390
           These formats would be supported if SDL had the necessary pixel formats
slouken@2753
   391
           case SDL_PIXELFORMAT_BGR565:
slouken@2753
   392
           internalFormat = GL_RGB;
slouken@2753
   393
           format = GL_RGB;
slouken@2753
   394
           type = GL_UNSIGNED_SHORT_5_6_5;
slouken@2753
   395
           break;                       
slouken@2753
   396
           case SDL_PIXELFORMAT_ABGR5551:
slouken@2753
   397
           internalFormat = GL_RGBA;
slouken@2753
   398
           format = GL_RGBA;
slouken@2753
   399
           type = GL_UNSIGNED_SHORT_5_5_5_1;
slouken@2753
   400
           break;
slouken@2753
   401
           case SDL_PIXELFORMAT_ABGR4444:
slouken@2753
   402
           internalFormat = GL_RGBA;
slouken@2753
   403
           format = GL_RGBA;
slouken@2753
   404
           type = GL_UNSIGNED_SHORT_4_4_4_4;
slouken@2753
   405
           break;
slouken@2753
   406
         */
slouken@2753
   407
    default:
slouken@2753
   408
        SDL_SetError("Unsupported texture format");
slouken@2753
   409
        return -1;
hfutrell@2739
   410
    }
slouken@2753
   411
slouken@2753
   412
    data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
hfutrell@2739
   413
    if (!data) {
hfutrell@2739
   414
        SDL_OutOfMemory();
hfutrell@2739
   415
        return -1;
hfutrell@2739
   416
    }
hfutrell@2739
   417
hfutrell@2739
   418
    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
hfutrell@2739
   419
        data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
hfutrell@2739
   420
        data->pixels = SDL_malloc(texture->h * data->pitch);
hfutrell@2739
   421
        if (!data->pixels) {
hfutrell@2739
   422
            SDL_OutOfMemory();
hfutrell@2739
   423
            SDL_free(data);
hfutrell@2739
   424
            return -1;
hfutrell@2739
   425
        }
hfutrell@2739
   426
    }
hfutrell@2739
   427
hfutrell@2739
   428
    texture->driverdata = data;
hfutrell@2739
   429
hfutrell@2739
   430
    renderdata->glGetError();
hfutrell@2739
   431
    renderdata->glGenTextures(1, &data->texture);
slouken@2753
   432
slouken@2753
   433
    data->type = GL_TEXTURE_2D;
slouken@2753
   434
    /* no NPOV textures allowed in OpenGL ES (yet) */
slouken@2753
   435
    texture_w = power_of_2(texture->w);
slouken@2753
   436
    texture_h = power_of_2(texture->h);
slouken@2753
   437
    data->texw = (GLfloat) texture->w / texture_w;
slouken@2753
   438
    data->texh = (GLfloat) texture->h / texture_h;
slouken@2753
   439
hfutrell@2739
   440
    data->format = format;
hfutrell@2739
   441
    data->formattype = type;
hfutrell@2739
   442
    renderdata->glBindTexture(data->type, data->texture);
hfutrell@2739
   443
    renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
hfutrell@2739
   444
                                GL_NEAREST);
hfutrell@2739
   445
    renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
hfutrell@2739
   446
                                GL_NEAREST);
hfutrell@2739
   447
    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
hfutrell@2739
   448
                                GL_CLAMP_TO_EDGE);
hfutrell@2739
   449
    renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
hfutrell@2739
   450
                                GL_CLAMP_TO_EDGE);
slouken@2753
   451
slouken@2753
   452
    renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
slouken@2753
   453
                             texture_h, 0, format, type, NULL);
hfutrell@2739
   454
hfutrell@2739
   455
    result = renderdata->glGetError();
hfutrell@2739
   456
    if (result != GL_NO_ERROR) {
hfutrell@2739
   457
        GLES_SetError("glTexImage2D()", result);
hfutrell@2739
   458
        return -1;
hfutrell@2739
   459
    }
hfutrell@2739
   460
    return 0;
hfutrell@2739
   461
}
hfutrell@2739
   462
hfutrell@2739
   463
static int
hfutrell@2739
   464
GLES_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   465
                        void **pixels, int *pitch)
hfutrell@2739
   466
{
hfutrell@2739
   467
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   468
hfutrell@2739
   469
    *pixels = data->pixels;
hfutrell@2739
   470
    *pitch = data->pitch;
hfutrell@2739
   471
    return 0;
hfutrell@2739
   472
}
hfutrell@2739
   473
hfutrell@2739
   474
static int
hfutrell@2739
   475
GLES_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   476
                       const SDL_Color * colors, int firstcolor, int ncolors)
hfutrell@2739
   477
{
slouken@2753
   478
    SDL_SetError("OpenGL ES does not support paletted textures");
hfutrell@2739
   479
    return -1;
hfutrell@2739
   480
}
hfutrell@2739
   481
hfutrell@2739
   482
static int
hfutrell@2739
   483
GLES_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   484
                       SDL_Color * colors, int firstcolor, int ncolors)
hfutrell@2739
   485
{
slouken@2753
   486
    SDL_SetError("OpenGL ES does not support paletted textures");
hfutrell@2739
   487
    return -1;
hfutrell@2739
   488
}
hfutrell@2739
   489
hfutrell@2739
   490
static void
hfutrell@2739
   491
SetupTextureUpdate(GLES_RenderData * renderdata, SDL_Texture * texture,
hfutrell@2739
   492
                   int pitch)
hfutrell@2739
   493
{
slouken@2753
   494
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
slouken@2753
   495
    renderdata->glBindTexture(data->type, data->texture);
hfutrell@2739
   496
    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
hfutrell@2739
   497
}
hfutrell@2739
   498
hfutrell@2739
   499
static int
hfutrell@2739
   500
GLES_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   501
{
hfutrell@2739
   502
    return 0;
hfutrell@2739
   503
}
hfutrell@2739
   504
hfutrell@2739
   505
static int
hfutrell@2739
   506
GLES_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   507
{
hfutrell@2739
   508
    return 0;
hfutrell@2739
   509
}
hfutrell@2739
   510
hfutrell@2739
   511
static int
hfutrell@2739
   512
GLES_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   513
{
hfutrell@2739
   514
    switch (texture->blendMode) {
slouken@2884
   515
    case SDL_BLENDMODE_NONE:
slouken@2884
   516
    case SDL_BLENDMODE_MASK:
slouken@2884
   517
    case SDL_BLENDMODE_BLEND:
slouken@2884
   518
    case SDL_BLENDMODE_ADD:
slouken@2884
   519
    case SDL_BLENDMODE_MOD:
hfutrell@2739
   520
        return 0;
hfutrell@2739
   521
    default:
hfutrell@2739
   522
        SDL_Unsupported();
slouken@2884
   523
        texture->blendMode = SDL_BLENDMODE_NONE;
hfutrell@2739
   524
        return -1;
hfutrell@2739
   525
    }
hfutrell@2739
   526
}
hfutrell@2739
   527
hfutrell@2739
   528
static int
hfutrell@2739
   529
GLES_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   530
{
hfutrell@2739
   531
    switch (texture->scaleMode) {
hfutrell@2739
   532
    case SDL_TEXTURESCALEMODE_NONE:
hfutrell@2739
   533
    case SDL_TEXTURESCALEMODE_FAST:
hfutrell@2739
   534
    case SDL_TEXTURESCALEMODE_SLOW:
hfutrell@2739
   535
        return 0;
hfutrell@2739
   536
    case SDL_TEXTURESCALEMODE_BEST:
hfutrell@2739
   537
        SDL_Unsupported();
slouken@2753
   538
        texture->scaleMode = SDL_TEXTURESCALEMODE_SLOW;
hfutrell@2739
   539
        return -1;
hfutrell@2739
   540
    default:
hfutrell@2739
   541
        SDL_Unsupported();
hfutrell@2739
   542
        texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
hfutrell@2739
   543
        return -1;
hfutrell@2739
   544
    }
hfutrell@2739
   545
}
hfutrell@2739
   546
hfutrell@2739
   547
static int
hfutrell@2739
   548
GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   549
                   const SDL_Rect * rect, const void *pixels, int pitch)
hfutrell@2739
   550
{
hfutrell@2739
   551
    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   552
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   553
    GLenum result;
hfutrell@2739
   554
hfutrell@2739
   555
    SetupTextureUpdate(renderdata, texture, pitch);
slouken@2753
   556
    renderdata->glGetError();
slouken@2753
   557
    renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
hfutrell@2739
   558
                                rect->h, data->format, data->formattype,
hfutrell@2739
   559
                                pixels);
hfutrell@2739
   560
    result = renderdata->glGetError();
hfutrell@2739
   561
    if (result != GL_NO_ERROR) {
hfutrell@2739
   562
        GLES_SetError("glTexSubImage2D()", result);
hfutrell@2739
   563
        return -1;
hfutrell@2739
   564
    }
hfutrell@2739
   565
    return 0;
hfutrell@2739
   566
}
hfutrell@2739
   567
hfutrell@2739
   568
static int
hfutrell@2739
   569
GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   570
                 const SDL_Rect * rect, int markDirty, void **pixels,
slouken@2753
   571
                 int *pitch)
hfutrell@2739
   572
{
hfutrell@2739
   573
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   574
hfutrell@2739
   575
    if (markDirty) {
hfutrell@2739
   576
        SDL_AddDirtyRect(&data->dirty, rect);
hfutrell@2739
   577
    }
hfutrell@2739
   578
hfutrell@2739
   579
    *pixels =
hfutrell@2739
   580
        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
hfutrell@2739
   581
                  rect->x * SDL_BYTESPERPIXEL(texture->format));
hfutrell@2739
   582
    *pitch = data->pitch;
hfutrell@2739
   583
    return 0;
hfutrell@2739
   584
}
hfutrell@2739
   585
hfutrell@2739
   586
static void
hfutrell@2739
   587
GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   588
{
hfutrell@2739
   589
}
hfutrell@2739
   590
hfutrell@2739
   591
static void
slouken@2753
   592
GLES_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   593
                  int numrects, const SDL_Rect * rects)
hfutrell@2739
   594
{
hfutrell@2739
   595
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   596
    int i;
hfutrell@2739
   597
hfutrell@2739
   598
    for (i = 0; i < numrects; ++i) {
hfutrell@2739
   599
        SDL_AddDirtyRect(&data->dirty, &rects[i]);
hfutrell@2739
   600
    }
hfutrell@2739
   601
}
hfutrell@2739
   602
slouken@2936
   603
static void
slouken@2936
   604
GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
slouken@2936
   605
{
slouken@2936
   606
    if (blendMode != data->blendMode) {
slouken@2936
   607
        switch (blendMode) {
slouken@2936
   608
        case SDL_BLENDMODE_NONE:
slouken@2936
   609
            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
slouken@2936
   610
            data->glDisable(GL_BLEND);
slouken@2936
   611
            break;
slouken@2936
   612
        case SDL_BLENDMODE_MASK:
slouken@2936
   613
        case SDL_BLENDMODE_BLEND:
slouken@2936
   614
            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
slouken@2936
   615
            data->glEnable(GL_BLEND);
slouken@2936
   616
            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
slouken@2936
   617
            break;
slouken@2936
   618
        case SDL_BLENDMODE_ADD:
slouken@2936
   619
            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
slouken@2936
   620
            data->glEnable(GL_BLEND);
slouken@2936
   621
            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
slouken@2936
   622
            break;
slouken@2936
   623
        case SDL_BLENDMODE_MOD:
slouken@2936
   624
            data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
slouken@2936
   625
            data->glEnable(GL_BLEND);
slouken@2936
   626
            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
slouken@2936
   627
            break;
slouken@2936
   628
        }
slouken@2936
   629
        data->blendMode = blendMode;
slouken@2936
   630
    }
slouken@2936
   631
}
slouken@2936
   632
hfutrell@2739
   633
static int
slouken@2936
   634
GLES_RenderPoint(SDL_Renderer * renderer, int x, int y)
hfutrell@2739
   635
{
slouken@2936
   636
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
slouken@2753
   637
slouken@2936
   638
    GLES_SetBlendMode(data, renderer->blendMode);
slouken@2936
   639
slouken@2936
   640
    data->glColor4f((GLfloat) renderer->r * inv255f,
slouken@2936
   641
                    (GLfloat) renderer->g * inv255f,
slouken@2936
   642
                    (GLfloat) renderer->b * inv255f,
slouken@2936
   643
                    (GLfloat) renderer->a * inv255f);
slouken@2936
   644
slouken@2964
   645
    GLshort vertices[2];
slouken@2964
   646
    vertices[0] = x;
slouken@2964
   647
    vertices[1] = y;
slouken@2964
   648
slouken@2964
   649
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
slouken@2964
   650
    data->glEnableClientState(GL_VERTEX_ARRAY);
slouken@2964
   651
    data->glDrawArrays(GL_POINTS, 0, 1);
slouken@2964
   652
    data->glDisableClientState(GL_VERTEX_ARRAY);
slouken@2964
   653
slouken@2936
   654
    return 0;
slouken@2936
   655
}
slouken@2936
   656
slouken@2936
   657
static int
slouken@2936
   658
GLES_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
slouken@2936
   659
{
slouken@2936
   660
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
slouken@2936
   661
slouken@2936
   662
    GLES_SetBlendMode(data, renderer->blendMode);
slouken@2936
   663
slouken@2936
   664
    data->glColor4f((GLfloat) renderer->r * inv255f,
slouken@2936
   665
                    (GLfloat) renderer->g * inv255f,
slouken@2936
   666
                    (GLfloat) renderer->b * inv255f,
slouken@2936
   667
                    (GLfloat) renderer->a * inv255f);
slouken@2936
   668
slouken@2964
   669
    GLshort vertices[4];
slouken@2964
   670
    vertices[0] = x1;
slouken@2964
   671
    vertices[1] = y1;
slouken@2964
   672
    vertices[2] = x2;
slouken@2964
   673
    vertices[3] = y2;
hfutrell@2949
   674
slouken@2964
   675
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
slouken@2964
   676
    data->glEnableClientState(GL_VERTEX_ARRAY);
slouken@2964
   677
    data->glDrawArrays(GL_LINES, 0, 2);
slouken@2964
   678
    data->glDisableClientState(GL_VERTEX_ARRAY);
hfutrell@2949
   679
slouken@2936
   680
    return 0;
slouken@2936
   681
}
slouken@2936
   682
slouken@2936
   683
static int
slouken@2936
   684
GLES_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
slouken@2936
   685
{
slouken@2753
   686
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
slouken@2753
   687
slouken@2936
   688
    GLES_SetBlendMode(data, renderer->blendMode);
slouken@2753
   689
slouken@2936
   690
    data->glColor4f((GLfloat) renderer->r * inv255f,
slouken@2936
   691
                    (GLfloat) renderer->g * inv255f,
slouken@2936
   692
                    (GLfloat) renderer->b * inv255f,
slouken@2936
   693
                    (GLfloat) renderer->a * inv255f);
slouken@2753
   694
slouken@2964
   695
    GLshort minx = rect->x;
slouken@2964
   696
    GLshort maxx = rect->x + rect->w;
slouken@2964
   697
    GLshort miny = rect->y;
slouken@2964
   698
    GLshort maxy = rect->y + rect->h;
slouken@2964
   699
slouken@2964
   700
    GLshort vertices[8];
slouken@2964
   701
    vertices[0] = minx;
slouken@2964
   702
    vertices[1] = miny;
slouken@2964
   703
    vertices[2] = maxx;
slouken@2964
   704
    vertices[3] = miny;
slouken@2964
   705
    vertices[4] = minx;
slouken@2964
   706
    vertices[5] = maxy;
slouken@2964
   707
    vertices[6] = maxx;
slouken@2964
   708
    vertices[7] = maxy;
slouken@2964
   709
slouken@2964
   710
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
slouken@2964
   711
    data->glEnableClientState(GL_VERTEX_ARRAY);
slouken@2964
   712
    data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
slouken@2964
   713
    data->glDisableClientState(GL_VERTEX_ARRAY);
hfutrell@2949
   714
slouken@2753
   715
    return 0;
hfutrell@2739
   716
}
hfutrell@2739
   717
hfutrell@2739
   718
static int
hfutrell@2739
   719
GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2753
   720
                const SDL_Rect * srcrect, const SDL_Rect * dstrect)
hfutrell@2739
   721
{
slouken@2753
   722
hfutrell@2739
   723
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   724
    GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   725
    int minx, miny, maxx, maxy;
hfutrell@2739
   726
    GLfloat minu, maxu, minv, maxv;
slouken@2753
   727
    int i;
slouken@2753
   728
    void *temp_buffer;          /* used for reformatting dirty rect pixels */
slouken@2753
   729
    void *temp_ptr;
slouken@2753
   730
hfutrell@2739
   731
    if (texturedata->dirty.list) {
hfutrell@2739
   732
        SDL_DirtyRect *dirty;
hfutrell@2739
   733
        void *pixels;
hfutrell@2739
   734
        int bpp = SDL_BYTESPERPIXEL(texture->format);
hfutrell@2739
   735
        int pitch = texturedata->pitch;
hfutrell@2739
   736
hfutrell@2739
   737
        SetupTextureUpdate(data, texture, pitch);
slouken@2753
   738
hfutrell@2739
   739
        data->glBindTexture(texturedata->type, texturedata->texture);
hfutrell@2739
   740
        for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
hfutrell@2739
   741
            SDL_Rect *rect = &dirty->rect;
slouken@2753
   742
            pixels =
slouken@2753
   743
                (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
slouken@2753
   744
                          rect->x * bpp);
slouken@2753
   745
            /*      There is no GL_UNPACK_ROW_LENGTH in OpenGLES 
slouken@2753
   746
               we must do this reformatting ourselves(!)
slouken@2753
   747
slouken@2753
   748
               maybe it'd be a good idea to keep a temp buffer around
slouken@2753
   749
               for this purpose rather than allocating it each time
slouken@2753
   750
             */
slouken@2753
   751
            temp_buffer = SDL_malloc(rect->w * rect->h * bpp);
slouken@2753
   752
            temp_ptr = temp_buffer;
slouken@2753
   753
            for (i = 0; i < rect->h; i++) {
slouken@2753
   754
                SDL_memcpy(temp_ptr, pixels, rect->w * bpp);
slouken@2753
   755
                temp_ptr += rect->w * bpp;
slouken@2753
   756
                pixels += pitch;
slouken@2753
   757
            }
slouken@2753
   758
hfutrell@2739
   759
            data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y,
hfutrell@2739
   760
                                  rect->w, rect->h, texturedata->format,
hfutrell@2739
   761
                                  texturedata->formattype, temp_buffer);
slouken@2753
   762
slouken@2753
   763
            SDL_free(temp_buffer);
slouken@2753
   764
hfutrell@2739
   765
        }
hfutrell@2739
   766
        SDL_ClearDirtyRects(&texturedata->dirty);
hfutrell@2739
   767
    }
slouken@2753
   768
hfutrell@2739
   769
    data->glBindTexture(texturedata->type, texturedata->texture);
slouken@2753
   770
    data->glEnable(GL_TEXTURE_2D);
slouken@2753
   771
hfutrell@2739
   772
    if (texture->modMode) {
hfutrell@2739
   773
        data->glColor4f((GLfloat) texture->r * inv255f,
hfutrell@2739
   774
                        (GLfloat) texture->g * inv255f,
hfutrell@2739
   775
                        (GLfloat) texture->b * inv255f,
hfutrell@2739
   776
                        (GLfloat) texture->a * inv255f);
hfutrell@2739
   777
    } else {
hfutrell@2739
   778
        data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
hfutrell@2739
   779
    }
hfutrell@2739
   780
slouken@2936
   781
    GLES_SetBlendMode(data, texture->blendMode);
hfutrell@2739
   782
slouken@2753
   783
    switch (texture->scaleMode) {
slouken@2753
   784
    case SDL_TEXTURESCALEMODE_NONE:
slouken@2753
   785
    case SDL_TEXTURESCALEMODE_FAST:
slouken@2753
   786
        data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
slouken@2753
   787
                              GL_NEAREST);
slouken@2753
   788
        data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
slouken@2753
   789
                              GL_NEAREST);
slouken@2753
   790
        break;
slouken@2753
   791
    case SDL_TEXTURESCALEMODE_SLOW:
slouken@2753
   792
    case SDL_TEXTURESCALEMODE_BEST:
slouken@2753
   793
        data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER,
slouken@2753
   794
                              GL_LINEAR);
slouken@2753
   795
        data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER,
slouken@2753
   796
                              GL_LINEAR);
slouken@2753
   797
        break;
slouken@2753
   798
    }
hfutrell@2739
   799
slouken@2753
   800
    if (data->GL_OES_draw_texture_supported && data->useDrawTexture) {
slouken@2753
   801
        /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */
slouken@2753
   802
        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
slouken@2753
   803
        GLint cropRect[4];
slouken@2753
   804
        cropRect[0] = srcrect->x;
slouken@2753
   805
        cropRect[1] = srcrect->y + srcrect->h;
slouken@2753
   806
        cropRect[2] = srcrect->w;
slouken@2753
   807
        cropRect[3] = -srcrect->h;
slouken@2753
   808
        data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES,
slouken@2753
   809
                               cropRect);
slouken@2753
   810
        data->glDrawTexiOES(dstrect->x, window->h - dstrect->y - dstrect->h,
slouken@2753
   811
                            0, dstrect->w, dstrect->h);
slouken@2753
   812
    } else {
slouken@2753
   813
slouken@2753
   814
        minx = dstrect->x;
slouken@2753
   815
        miny = dstrect->y;
slouken@2753
   816
        maxx = dstrect->x + dstrect->w;
slouken@2753
   817
        maxy = dstrect->y + dstrect->h;
slouken@2753
   818
slouken@2753
   819
        minu = (GLfloat) srcrect->x / texture->w;
slouken@2753
   820
        minu *= texturedata->texw;
slouken@2753
   821
        maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
slouken@2753
   822
        maxu *= texturedata->texw;
slouken@2753
   823
        minv = (GLfloat) srcrect->y / texture->h;
slouken@2753
   824
        minv *= texturedata->texh;
slouken@2753
   825
        maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
slouken@2753
   826
        maxv *= texturedata->texh;
slouken@2753
   827
slouken@2753
   828
        GLshort vertices[8];
slouken@2753
   829
        GLfloat texCoords[8];
slouken@2753
   830
slouken@2753
   831
        vertices[0] = minx;
slouken@2753
   832
        vertices[1] = miny;
slouken@2753
   833
        vertices[2] = maxx;
slouken@2753
   834
        vertices[3] = miny;
slouken@2753
   835
        vertices[4] = minx;
slouken@2753
   836
        vertices[5] = maxy;
slouken@2753
   837
        vertices[6] = maxx;
slouken@2753
   838
        vertices[7] = maxy;
slouken@2753
   839
slouken@2753
   840
        texCoords[0] = minu;
slouken@2753
   841
        texCoords[1] = minv;
slouken@2753
   842
        texCoords[2] = maxu;
slouken@2753
   843
        texCoords[3] = minv;
slouken@2753
   844
        texCoords[4] = minu;
slouken@2753
   845
        texCoords[5] = maxv;
slouken@2753
   846
        texCoords[6] = maxu;
slouken@2753
   847
        texCoords[7] = maxv;
slouken@2753
   848
slouken@2753
   849
        data->glVertexPointer(2, GL_SHORT, 0, vertices);
slouken@2753
   850
        data->glEnableClientState(GL_VERTEX_ARRAY);
slouken@2753
   851
        data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
slouken@2753
   852
        data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
slouken@2753
   853
        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
slouken@2753
   854
slouken@2753
   855
    }
slouken@2753
   856
hfutrell@2739
   857
    return 0;
hfutrell@2739
   858
}
hfutrell@2739
   859
hfutrell@2739
   860
static void
hfutrell@2739
   861
GLES_RenderPresent(SDL_Renderer * renderer)
hfutrell@2739
   862
{
hfutrell@2739
   863
    SDL_GL_SwapWindow(renderer->window);
hfutrell@2739
   864
}
hfutrell@2739
   865
hfutrell@2739
   866
static void
hfutrell@2739
   867
GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
hfutrell@2739
   868
{
hfutrell@2739
   869
    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   870
    GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
hfutrell@2739
   871
hfutrell@2739
   872
    if (!data) {
hfutrell@2739
   873
        return;
hfutrell@2739
   874
    }
hfutrell@2739
   875
    if (data->texture) {
slouken@2753
   876
        glDeleteTextures(1, &data->texture);
hfutrell@2739
   877
    }
hfutrell@2739
   878
    if (data->pixels) {
hfutrell@2739
   879
        SDL_free(data->pixels);
hfutrell@2739
   880
    }
hfutrell@2739
   881
    SDL_FreeDirtyRects(&data->dirty);
hfutrell@2739
   882
    SDL_free(data);
hfutrell@2739
   883
    texture->driverdata = NULL;
hfutrell@2739
   884
}
hfutrell@2739
   885
hfutrell@2739
   886
static void
hfutrell@2739
   887
GLES_DestroyRenderer(SDL_Renderer * renderer)
hfutrell@2739
   888
{
hfutrell@2739
   889
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
hfutrell@2739
   890
hfutrell@2739
   891
    if (data) {
hfutrell@2739
   892
        if (data->context) {
hfutrell@2739
   893
            /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
hfutrell@2739
   894
            SDL_GL_DeleteContext(data->context);
hfutrell@2739
   895
        }
hfutrell@2739
   896
        SDL_free(data);
hfutrell@2739
   897
    }
hfutrell@2739
   898
    SDL_free(renderer);
hfutrell@2739
   899
}
hfutrell@2739
   900
slouken@3099
   901
#endif /* SDL_VIDEO_RENDER_OGL_ES */
hfutrell@2739
   902
hfutrell@2739
   903
/* vi: set ts=4 sw=4 expandtab: */