src/render/opengl/SDL_shaders_gl.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Wed, 16 Nov 2016 22:08:51 +0100
changeset 10617 346c02ff71b6
parent 9998 f67cf37e9cd4
child 10737 3406a0f8b041
permissions -rw-r--r--
Fixed empty parameter list in signatures of internal functions.
slouken@5228
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
slouken@5228
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@5228
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@5228
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@5228
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@5228
    22
slouken@5228
    23
#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
slouken@5228
    24
slouken@5228
    25
#include "SDL_stdinc.h"
slouken@5228
    26
#include "SDL_log.h"
slouken@5228
    27
#include "SDL_opengl.h"
slouken@5228
    28
#include "SDL_video.h"
slouken@5228
    29
#include "SDL_shaders_gl.h"
slouken@5228
    30
slouken@5228
    31
/* OpenGL shader implementation */
slouken@5228
    32
gabomdq@7678
    33
/* #define DEBUG_SHADERS */
slouken@5231
    34
slouken@5228
    35
typedef struct
slouken@5228
    36
{
icculus@5641
    37
    GLhandleARB program;
icculus@5641
    38
    GLhandleARB vert_shader;
icculus@5641
    39
    GLhandleARB frag_shader;
slouken@5228
    40
} GL_ShaderData;
slouken@5228
    41
slouken@5228
    42
struct GL_ShaderContext
slouken@5228
    43
{
slouken@5228
    44
    GLenum (*glGetError)(void);
slouken@5228
    45
slouken@5228
    46
    PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
slouken@5228
    47
    PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
slouken@5228
    48
    PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
slouken@5228
    49
    PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
slouken@5228
    50
    PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
slouken@5228
    51
    PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
slouken@5228
    52
    PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
slouken@5228
    53
    PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
slouken@5228
    54
    PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
slouken@5228
    55
    PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
slouken@5228
    56
    PFNGLUNIFORM1IARBPROC glUniform1iARB;
slouken@5228
    57
    PFNGLUNIFORM1FARBPROC glUniform1fARB;
slouken@5228
    58
    PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
slouken@5228
    59
slouken@5230
    60
    SDL_bool GL_ARB_texture_rectangle_supported;
slouken@5230
    61
slouken@5228
    62
    GL_ShaderData shaders[NUM_SHADERS];
slouken@5228
    63
};
slouken@5228
    64
slouken@5230
    65
/*
slouken@5230
    66
 * NOTE: Always use sampler2D, etc here. We'll #define them to the
slouken@5230
    67
 *  texture_rectangle versions if we choose to use that extension.
slouken@5230
    68
 */
slouken@5228
    69
static const char *shader_source[NUM_SHADERS][2] =
slouken@5228
    70
{
slouken@5228
    71
    /* SHADER_NONE */
slouken@5228
    72
    { NULL, NULL },
slouken@5228
    73
slouken@5228
    74
    /* SHADER_SOLID */
slouken@5228
    75
    {
slouken@5228
    76
        /* vertex shader */
slouken@5231
    77
"varying vec4 v_color;\n"
slouken@5231
    78
"\n"
slouken@5231
    79
"void main()\n"
slouken@5231
    80
"{\n"
slouken@5231
    81
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5231
    82
"    v_color = gl_Color;\n"
slouken@5231
    83
"}",
slouken@5228
    84
        /* fragment shader */
slouken@5231
    85
"varying vec4 v_color;\n"
slouken@5231
    86
"\n"
slouken@5231
    87
"void main()\n"
slouken@5231
    88
"{\n"
slouken@5231
    89
"    gl_FragColor = v_color;\n"
slouken@5231
    90
"}"
slouken@5228
    91
    },
slouken@5228
    92
slouken@5228
    93
    /* SHADER_RGB */
slouken@5228
    94
    {
slouken@5228
    95
        /* vertex shader */
slouken@5231
    96
"varying vec4 v_color;\n"
slouken@5231
    97
"varying vec2 v_texCoord;\n"
slouken@5231
    98
"\n"
slouken@5231
    99
"void main()\n"
slouken@5231
   100
"{\n"
slouken@5231
   101
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5231
   102
"    v_color = gl_Color;\n"
slouken@5231
   103
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@5231
   104
"}",
slouken@5228
   105
        /* fragment shader */
slouken@5231
   106
"varying vec4 v_color;\n"
slouken@5231
   107
"varying vec2 v_texCoord;\n"
slouken@5231
   108
"uniform sampler2D tex0;\n"
slouken@5231
   109
"\n"
slouken@5231
   110
"void main()\n"
slouken@5231
   111
"{\n"
slouken@5231
   112
"    gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
slouken@5231
   113
"}"
slouken@5228
   114
    },
slouken@5238
   115
slouken@9046
   116
    /* SHADER_YUV */
slouken@5238
   117
    {
slouken@5238
   118
        /* vertex shader */
slouken@5238
   119
"varying vec4 v_color;\n"
slouken@5238
   120
"varying vec2 v_texCoord;\n"
slouken@5238
   121
"\n"
slouken@5238
   122
"void main()\n"
slouken@5238
   123
"{\n"
slouken@5238
   124
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5238
   125
"    v_color = gl_Color;\n"
slouken@5238
   126
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@5238
   127
"}",
slouken@5238
   128
        /* fragment shader */
slouken@5238
   129
"varying vec4 v_color;\n"
slouken@5238
   130
"varying vec2 v_texCoord;\n"
slouken@5238
   131
"uniform sampler2D tex0; // Y \n"
slouken@5238
   132
"uniform sampler2D tex1; // U \n"
slouken@5238
   133
"uniform sampler2D tex2; // V \n"
slouken@5238
   134
"\n"
slouken@5238
   135
"// YUV offset \n"
alfred@8969
   136
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n"
slouken@5238
   137
"\n"
slouken@5238
   138
"// RGB coefficients \n"
slouken@5238
   139
"const vec3 Rcoeff = vec3(1.164,  0.000,  1.596);\n"
slouken@5238
   140
"const vec3 Gcoeff = vec3(1.164, -0.391, -0.813);\n"
slouken@5238
   141
"const vec3 Bcoeff = vec3(1.164,  2.018,  0.000);\n"
slouken@5238
   142
"\n"
slouken@5238
   143
"void main()\n"
slouken@5238
   144
"{\n"
slouken@5238
   145
"    vec2 tcoord;\n"
slouken@5238
   146
"    vec3 yuv, rgb;\n"
slouken@5238
   147
"\n"
slouken@5238
   148
"    // Get the Y value \n"
slouken@5238
   149
"    tcoord = v_texCoord;\n"
slouken@5238
   150
"    yuv.x = texture2D(tex0, tcoord).r;\n"
slouken@5238
   151
"\n"
slouken@5238
   152
"    // Get the U and V values \n"
slouken@9089
   153
"    tcoord *= UVCoordScale;\n"
slouken@5238
   154
"    yuv.y = texture2D(tex1, tcoord).r;\n"
slouken@5238
   155
"    yuv.z = texture2D(tex2, tcoord).r;\n"
slouken@5238
   156
"\n"
slouken@5238
   157
"    // Do the color transform \n"
slouken@5238
   158
"    yuv += offset;\n"
slouken@5238
   159
"    rgb.r = dot(yuv, Rcoeff);\n"
slouken@5238
   160
"    rgb.g = dot(yuv, Gcoeff);\n"
slouken@5238
   161
"    rgb.b = dot(yuv, Bcoeff);\n"
slouken@5238
   162
"\n"
slouken@5238
   163
"    // That was easy. :) \n"
slouken@5238
   164
"    gl_FragColor = vec4(rgb, 1.0) * v_color;\n"
slouken@5238
   165
"}"
slouken@5238
   166
    },
slouken@9046
   167
slouken@9046
   168
    /* SHADER_NV12 */
slouken@9046
   169
    {
slouken@9046
   170
        /* vertex shader */
slouken@9046
   171
"varying vec4 v_color;\n"
slouken@9046
   172
"varying vec2 v_texCoord;\n"
slouken@9046
   173
"\n"
slouken@9046
   174
"void main()\n"
slouken@9046
   175
"{\n"
slouken@9046
   176
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@9046
   177
"    v_color = gl_Color;\n"
slouken@9046
   178
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@9046
   179
"}",
slouken@9046
   180
        /* fragment shader */
slouken@9046
   181
"varying vec4 v_color;\n"
slouken@9046
   182
"varying vec2 v_texCoord;\n"
slouken@9046
   183
"uniform sampler2D tex0; // Y \n"
slouken@9046
   184
"uniform sampler2D tex1; // U/V \n"
slouken@9046
   185
"\n"
slouken@9046
   186
"// YUV offset \n"
slouken@9046
   187
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n"
slouken@9046
   188
"\n"
slouken@9046
   189
"// RGB coefficients \n"
slouken@9046
   190
"const vec3 Rcoeff = vec3(1.164,  0.000,  1.596);\n"
slouken@9046
   191
"const vec3 Gcoeff = vec3(1.164, -0.391, -0.813);\n"
slouken@9046
   192
"const vec3 Bcoeff = vec3(1.164,  2.018,  0.000);\n"
slouken@9046
   193
"\n"
slouken@9046
   194
"void main()\n"
slouken@9046
   195
"{\n"
slouken@9046
   196
"    vec2 tcoord;\n"
slouken@9046
   197
"    vec3 yuv, rgb;\n"
slouken@9046
   198
"\n"
slouken@9046
   199
"    // Get the Y value \n"
slouken@9046
   200
"    tcoord = v_texCoord;\n"
slouken@9046
   201
"    yuv.x = texture2D(tex0, tcoord).r;\n"
slouken@9046
   202
"\n"
slouken@9046
   203
"    // Get the U and V values \n"
slouken@9089
   204
"    tcoord *= UVCoordScale;\n"
slouken@9046
   205
"    yuv.yz = texture2D(tex1, tcoord).ra;\n"
slouken@9046
   206
"\n"
slouken@9046
   207
"    // Do the color transform \n"
slouken@9046
   208
"    yuv += offset;\n"
slouken@9046
   209
"    rgb.r = dot(yuv, Rcoeff);\n"
slouken@9046
   210
"    rgb.g = dot(yuv, Gcoeff);\n"
slouken@9046
   211
"    rgb.b = dot(yuv, Bcoeff);\n"
slouken@9046
   212
"\n"
slouken@9046
   213
"    // That was easy. :) \n"
slouken@9046
   214
"    gl_FragColor = vec4(rgb, 1.0) * v_color;\n"
slouken@9046
   215
"}"
slouken@9046
   216
    },
slouken@9046
   217
slouken@9046
   218
    /* SHADER_NV21 */
slouken@9046
   219
    {
slouken@9046
   220
        /* vertex shader */
slouken@9046
   221
"varying vec4 v_color;\n"
slouken@9046
   222
"varying vec2 v_texCoord;\n"
slouken@9046
   223
"\n"
slouken@9046
   224
"void main()\n"
slouken@9046
   225
"{\n"
slouken@9046
   226
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@9046
   227
"    v_color = gl_Color;\n"
slouken@9046
   228
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@9046
   229
"}",
slouken@9046
   230
        /* fragment shader */
slouken@9046
   231
"varying vec4 v_color;\n"
slouken@9046
   232
"varying vec2 v_texCoord;\n"
slouken@9046
   233
"uniform sampler2D tex0; // Y \n"
slouken@9046
   234
"uniform sampler2D tex1; // U/V \n"
slouken@9046
   235
"\n"
slouken@9046
   236
"// YUV offset \n"
slouken@9046
   237
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n"
slouken@9046
   238
"\n"
slouken@9046
   239
"// RGB coefficients \n"
slouken@9046
   240
"const vec3 Rcoeff = vec3(1.164,  0.000,  1.596);\n"
slouken@9046
   241
"const vec3 Gcoeff = vec3(1.164, -0.391, -0.813);\n"
slouken@9046
   242
"const vec3 Bcoeff = vec3(1.164,  2.018,  0.000);\n"
slouken@9046
   243
"\n"
slouken@9046
   244
"void main()\n"
slouken@9046
   245
"{\n"
slouken@9046
   246
"    vec2 tcoord;\n"
slouken@9046
   247
"    vec3 yuv, rgb;\n"
slouken@9046
   248
"\n"
slouken@9046
   249
"    // Get the Y value \n"
slouken@9046
   250
"    tcoord = v_texCoord;\n"
slouken@9046
   251
"    yuv.x = texture2D(tex0, tcoord).r;\n"
slouken@9046
   252
"\n"
slouken@9046
   253
"    // Get the U and V values \n"
slouken@9089
   254
"    tcoord *= UVCoordScale;\n"
slouken@9046
   255
"    yuv.yz = texture2D(tex1, tcoord).ar;\n"
slouken@9046
   256
"\n"
slouken@9046
   257
"    // Do the color transform \n"
slouken@9046
   258
"    yuv += offset;\n"
slouken@9046
   259
"    rgb.r = dot(yuv, Rcoeff);\n"
slouken@9046
   260
"    rgb.g = dot(yuv, Gcoeff);\n"
slouken@9046
   261
"    rgb.b = dot(yuv, Bcoeff);\n"
slouken@9046
   262
"\n"
slouken@9046
   263
"    // That was easy. :) \n"
slouken@9046
   264
"    gl_FragColor = vec4(rgb, 1.0) * v_color;\n"
slouken@9046
   265
"}"
slouken@9046
   266
    },
slouken@5228
   267
};
slouken@5228
   268
slouken@5228
   269
static SDL_bool
icculus@5641
   270
CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, const char *source)
slouken@5228
   271
{
slouken@5228
   272
    GLint status;
slouken@5230
   273
    const char *sources[2];
slouken@5228
   274
slouken@5230
   275
    sources[0] = defines;
slouken@5230
   276
    sources[1] = source;
slouken@5230
   277
slouken@5230
   278
    ctx->glShaderSourceARB(shader, SDL_arraysize(sources), sources, NULL);
slouken@5228
   279
    ctx->glCompileShaderARB(shader);
slouken@5228
   280
    ctx->glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
slouken@5228
   281
    if (status == 0) {
slouken@5228
   282
        GLint length;
slouken@5228
   283
        char *info;
slouken@5228
   284
slouken@5228
   285
        ctx->glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
slouken@5228
   286
        info = SDL_stack_alloc(char, length+1);
slouken@5228
   287
        ctx->glGetInfoLogARB(shader, length, NULL, info);
slouken@5228
   288
        SDL_LogError(SDL_LOG_CATEGORY_RENDER,
slouken@5231
   289
            "Failed to compile shader:\n%s%s\n%s", defines, source, info);
slouken@5231
   290
#ifdef DEBUG_SHADERS
slouken@5231
   291
        fprintf(stderr,
slouken@5231
   292
            "Failed to compile shader:\n%s%s\n%s", defines, source, info);
slouken@5231
   293
#endif
slouken@5228
   294
        SDL_stack_free(info);
slouken@5228
   295
slouken@5228
   296
        return SDL_FALSE;
slouken@5228
   297
    } else {
slouken@5228
   298
        return SDL_TRUE;
slouken@5228
   299
    }
slouken@5228
   300
}
slouken@5228
   301
slouken@5228
   302
static SDL_bool
slouken@5228
   303
CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data)
slouken@5228
   304
{
slouken@5228
   305
    const int num_tmus_bound = 4;
slouken@5230
   306
    const char *vert_defines = "";
slouken@5230
   307
    const char *frag_defines = "";
slouken@5228
   308
    int i;
slouken@5228
   309
    GLint location;
slouken@5228
   310
slouken@5228
   311
    if (index == SHADER_NONE) {
slouken@5228
   312
        return SDL_TRUE;
slouken@5228
   313
    }
slouken@5228
   314
slouken@5228
   315
    ctx->glGetError();
slouken@5228
   316
slouken@5230
   317
    /* Make sure we use the correct sampler type for our texture type */
slouken@5230
   318
    if (ctx->GL_ARB_texture_rectangle_supported) {
slouken@7191
   319
        frag_defines =
slouken@5230
   320
"#define sampler2D sampler2DRect\n"
slouken@9089
   321
"#define texture2D texture2DRect\n"
slouken@9089
   322
"#define UVCoordScale 0.5\n";
slouken@9089
   323
    } else {
slouken@9089
   324
        frag_defines = 
slouken@9089
   325
"#define UVCoordScale 1.0\n";
slouken@5230
   326
    }
slouken@5230
   327
slouken@5228
   328
    /* Create one program object to rule them all */
slouken@5228
   329
    data->program = ctx->glCreateProgramObjectARB();
slouken@5228
   330
slouken@5228
   331
    /* Create the vertex shader */
slouken@5228
   332
    data->vert_shader = ctx->glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
slouken@5230
   333
    if (!CompileShader(ctx, data->vert_shader, vert_defines, shader_source[index][0])) {
slouken@5228
   334
        return SDL_FALSE;
slouken@5228
   335
    }
slouken@5228
   336
slouken@5228
   337
    /* Create the fragment shader */
slouken@5228
   338
    data->frag_shader = ctx->glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
slouken@5230
   339
    if (!CompileShader(ctx, data->frag_shader, frag_defines, shader_source[index][1])) {
slouken@5228
   340
        return SDL_FALSE;
slouken@5228
   341
    }
slouken@5228
   342
slouken@5228
   343
    /* ... and in the darkness bind them */
slouken@5228
   344
    ctx->glAttachObjectARB(data->program, data->vert_shader);
slouken@5228
   345
    ctx->glAttachObjectARB(data->program, data->frag_shader);
slouken@5228
   346
    ctx->glLinkProgramARB(data->program);
slouken@5228
   347
slouken@5228
   348
    /* Set up some uniform variables */
slouken@5228
   349
    ctx->glUseProgramObjectARB(data->program);
slouken@5228
   350
    for (i = 0; i < num_tmus_bound; ++i) {
slouken@6903
   351
        char tex_name[10];
slouken@5228
   352
        SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i);
slouken@5228
   353
        location = ctx->glGetUniformLocationARB(data->program, tex_name);
slouken@5228
   354
        if (location >= 0) {
slouken@5229
   355
            ctx->glUniform1iARB(location, i);
slouken@5228
   356
        }
slouken@5228
   357
    }
slouken@5228
   358
    ctx->glUseProgramObjectARB(0);
slouken@7191
   359
slouken@5228
   360
    return (ctx->glGetError() == GL_NO_ERROR);
slouken@5228
   361
}
slouken@5228
   362
slouken@5228
   363
static void
slouken@5228
   364
DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data)
slouken@5228
   365
{
slouken@5228
   366
    ctx->glDeleteObjectARB(data->vert_shader);
slouken@5228
   367
    ctx->glDeleteObjectARB(data->frag_shader);
slouken@5228
   368
    ctx->glDeleteObjectARB(data->program);
slouken@5228
   369
}
slouken@5228
   370
slouken@5228
   371
GL_ShaderContext *
philipp@10617
   372
GL_CreateShaderContext(void)
slouken@5228
   373
{
slouken@5228
   374
    GL_ShaderContext *ctx;
slouken@5228
   375
    SDL_bool shaders_supported;
slouken@5228
   376
    int i;
slouken@5228
   377
slouken@5228
   378
    ctx = (GL_ShaderContext *)SDL_calloc(1, sizeof(*ctx));
slouken@5228
   379
    if (!ctx) {
slouken@5228
   380
        return NULL;
slouken@5228
   381
    }
slouken@5228
   382
slouken@9063
   383
    if (!SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two") &&
slouken@9063
   384
        (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
slouken@9063
   385
         SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle"))) {
slouken@5230
   386
        ctx->GL_ARB_texture_rectangle_supported = SDL_TRUE;
slouken@5230
   387
    }
slouken@5230
   388
slouken@5228
   389
    /* Check for shader support */
slouken@5228
   390
    shaders_supported = SDL_FALSE;
slouken@5228
   391
    if (SDL_GL_ExtensionSupported("GL_ARB_shader_objects") &&
slouken@5228
   392
        SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") &&
slouken@5228
   393
        SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") &&
slouken@5228
   394
        SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) {
slouken@5228
   395
        ctx->glGetError = (GLenum (*)(void)) SDL_GL_GetProcAddress("glGetError");
slouken@5228
   396
        ctx->glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
slouken@5228
   397
        ctx->glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
slouken@5228
   398
        ctx->glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
slouken@5228
   399
        ctx->glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
slouken@5228
   400
        ctx->glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
slouken@5228
   401
        ctx->glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
slouken@5228
   402
        ctx->glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
slouken@5228
   403
        ctx->glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
slouken@5228
   404
        ctx->glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
slouken@5228
   405
        ctx->glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
slouken@5228
   406
        ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
slouken@5228
   407
        ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB");
slouken@5228
   408
        ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
slouken@5228
   409
        if (ctx->glGetError &&
slouken@5228
   410
            ctx->glAttachObjectARB &&
slouken@5228
   411
            ctx->glCompileShaderARB &&
slouken@5228
   412
            ctx->glCreateProgramObjectARB &&
slouken@5228
   413
            ctx->glCreateShaderObjectARB &&
slouken@5228
   414
            ctx->glDeleteObjectARB &&
slouken@5228
   415
            ctx->glGetInfoLogARB &&
slouken@5228
   416
            ctx->glGetObjectParameterivARB &&
slouken@5228
   417
            ctx->glGetUniformLocationARB &&
slouken@5228
   418
            ctx->glLinkProgramARB &&
slouken@5228
   419
            ctx->glShaderSourceARB &&
slouken@5228
   420
            ctx->glUniform1iARB &&
slouken@5228
   421
            ctx->glUniform1fARB &&
slouken@5228
   422
            ctx->glUseProgramObjectARB) {
slouken@5228
   423
            shaders_supported = SDL_TRUE;
slouken@5228
   424
        }
slouken@5228
   425
    }
slouken@5228
   426
slouken@5228
   427
    if (!shaders_supported) {
slouken@5237
   428
        SDL_free(ctx);
slouken@5228
   429
        return NULL;
slouken@5228
   430
    }
slouken@5228
   431
slouken@5228
   432
    /* Compile all the shaders */
slouken@5228
   433
    for (i = 0; i < NUM_SHADERS; ++i) {
slouken@5228
   434
        if (!CompileShaderProgram(ctx, i, &ctx->shaders[i])) {
slouken@5228
   435
            GL_DestroyShaderContext(ctx);
slouken@5228
   436
            return NULL;
slouken@5228
   437
        }
slouken@5228
   438
    }
slouken@5228
   439
slouken@5228
   440
    /* We're done! */
slouken@5228
   441
    return ctx;
slouken@5228
   442
}
slouken@5228
   443
slouken@5228
   444
void
slouken@5228
   445
GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
slouken@5228
   446
{
slouken@5228
   447
    ctx->glUseProgramObjectARB(ctx->shaders[shader].program);
slouken@5228
   448
}
slouken@5228
   449
slouken@5228
   450
void
slouken@5228
   451
GL_DestroyShaderContext(GL_ShaderContext *ctx)
slouken@5228
   452
{
slouken@5228
   453
    int i;
slouken@5228
   454
slouken@5228
   455
    for (i = 0; i < NUM_SHADERS; ++i) {
slouken@5228
   456
        DestroyShaderProgram(ctx, &ctx->shaders[i]);
slouken@5228
   457
    }
slouken@5228
   458
    SDL_free(ctx);
slouken@5228
   459
}
slouken@5228
   460
slouken@5228
   461
#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
slouken@5228
   462
slouken@5228
   463
/* vi: set ts=4 sw=4 expandtab: */