test/testshader.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 25 Apr 2013 00:26:17 -0700
changeset 7110 2a98852fd58d
parent 6256 1d905b13b102
child 7191 75360622e65f
permissions -rw-r--r--
Fixed bug 1582 - Allow disabling SDL_VIDEO_DRIVER_WINDOWS

Marcus von Appen

Trying to build SDL 2.x (HG) on Win32 platforms with either VS.NET or MinGW requires one to have the video subsystem and SDL_VIDEO_DRIVER_WINDOWS flag enabled due to the helper window creation routines.

The attached patch changes the helper window creation behaviour, so that one can build SDL2 without the video subsystem or Windows video drivers on Win32 platforms.
slouken@5535
     1
/*
slouken@5535
     2
  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@5232
    12
/* This is a simple example of using GLSL shaders with SDL */
slouken@5232
    13
slouken@6256
    14
#if 1 /* FIXME: Rework this using the 2.0 API */
slouken@6256
    15
#include <stdio.h>
slouken@6256
    16
slouken@6256
    17
int main(int argc, char *argv[])
slouken@6256
    18
{
slouken@6256
    19
    printf("FIXME\n");
slouken@6256
    20
    return 0;
slouken@6256
    21
}
slouken@6256
    22
#else
slouken@5232
    23
#include "SDL.h"
slouken@5232
    24
slouken@5232
    25
#ifdef HAVE_OPENGL
slouken@5232
    26
slouken@5232
    27
#include "SDL_opengl.h"
slouken@5232
    28
slouken@5232
    29
slouken@5232
    30
static SDL_bool shaders_supported;
slouken@5232
    31
static int      current_shader = 0;
slouken@5232
    32
slouken@5232
    33
enum {
slouken@5232
    34
    SHADER_COLOR,
slouken@5232
    35
    SHADER_TEXTURE,
slouken@5232
    36
    SHADER_TEXCOORDS,
slouken@5232
    37
    NUM_SHADERS
slouken@5232
    38
};
slouken@5232
    39
slouken@5232
    40
typedef struct {
icculus@5641
    41
    GLhandleARB program;
icculus@5641
    42
    GLhandleARB vert_shader;
icculus@5641
    43
    GLhandleARB frag_shader;
slouken@5232
    44
    const char *vert_source;
slouken@5232
    45
    const char *frag_source;
slouken@5232
    46
} ShaderData;
slouken@5232
    47
slouken@5232
    48
static ShaderData shaders[NUM_SHADERS] = {
slouken@5232
    49
slouken@5232
    50
    /* SHADER_COLOR */
slouken@5232
    51
    { 0, 0, 0,
slouken@5232
    52
        /* vertex shader */
slouken@5232
    53
"varying vec4 v_color;\n"
slouken@5232
    54
"\n"
slouken@5232
    55
"void main()\n"
slouken@5232
    56
"{\n"
slouken@5232
    57
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5232
    58
"    v_color = gl_Color;\n"
slouken@5232
    59
"}",
slouken@5232
    60
        /* fragment shader */
slouken@5232
    61
"varying vec4 v_color;\n"
slouken@5232
    62
"\n"
slouken@5232
    63
"void main()\n"
slouken@5232
    64
"{\n"
slouken@5232
    65
"    gl_FragColor = v_color;\n"
slouken@5232
    66
"}"
slouken@5232
    67
    },
slouken@5232
    68
slouken@5232
    69
    /* SHADER_TEXTURE */
slouken@5232
    70
    { 0, 0, 0,
slouken@5232
    71
        /* vertex shader */
slouken@5232
    72
"varying vec4 v_color;\n"
slouken@5232
    73
"varying vec2 v_texCoord;\n"
slouken@5232
    74
"\n"
slouken@5232
    75
"void main()\n"
slouken@5232
    76
"{\n"
slouken@5232
    77
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5232
    78
"    v_color = gl_Color;\n"
slouken@5232
    79
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@5232
    80
"}",
slouken@5232
    81
        /* fragment shader */
slouken@5232
    82
"varying vec4 v_color;\n"
slouken@5232
    83
"varying vec2 v_texCoord;\n"
slouken@5232
    84
"uniform sampler2D tex0;\n"
slouken@5232
    85
"\n"
slouken@5232
    86
"void main()\n"
slouken@5232
    87
"{\n"
slouken@5232
    88
"    gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
slouken@5232
    89
"}"
slouken@5232
    90
    },
slouken@5232
    91
slouken@5232
    92
    /* SHADER_TEXCOORDS */
slouken@5232
    93
    { 0, 0, 0,
slouken@5232
    94
        /* vertex shader */
slouken@5232
    95
"varying vec2 v_texCoord;\n"
slouken@5232
    96
"\n"
slouken@5232
    97
"void main()\n"
slouken@5232
    98
"{\n"
slouken@5232
    99
"    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
slouken@5232
   100
"    v_texCoord = vec2(gl_MultiTexCoord0);\n"
slouken@5232
   101
"}",
slouken@5232
   102
        /* fragment shader */
slouken@5232
   103
"varying vec2 v_texCoord;\n"
slouken@5232
   104
"\n"
slouken@5232
   105
"void main()\n"
slouken@5232
   106
"{\n"
slouken@5232
   107
"    vec4 color;\n"
slouken@5232
   108
"    vec2 delta;\n"
slouken@5232
   109
"    float dist;\n"
slouken@5232
   110
"\n"
slouken@5232
   111
"    delta = vec2(0.5, 0.5) - v_texCoord;\n"
slouken@5232
   112
"    dist = dot(delta, delta);\n"
slouken@5232
   113
"\n"
slouken@5232
   114
"    color.r = v_texCoord.x;\n"
slouken@5232
   115
"    color.g = v_texCoord.x * v_texCoord.y;\n"
slouken@5232
   116
"    color.b = v_texCoord.y;\n"
slouken@5232
   117
"    color.a = 1.0 - (dist * 4.0);\n"
slouken@5232
   118
"    gl_FragColor = color;\n"
slouken@5232
   119
"}"
slouken@5232
   120
    },
slouken@5232
   121
};
slouken@5232
   122
    
slouken@5232
   123
static PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
slouken@5232
   124
static PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
slouken@5232
   125
static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
slouken@5232
   126
static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
slouken@5232
   127
static PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
slouken@5232
   128
static PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
slouken@5232
   129
static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
slouken@5232
   130
static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
slouken@5232
   131
static PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
slouken@5232
   132
static PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
slouken@5232
   133
static PFNGLUNIFORM1IARBPROC glUniform1iARB;
slouken@5232
   134
static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
slouken@5232
   135
icculus@5641
   136
static SDL_bool CompileShader(GLhandleARB shader, const char *source)
slouken@5232
   137
{
slouken@5232
   138
    GLint status;
slouken@5232
   139
slouken@5232
   140
    glShaderSourceARB(shader, 1, &source, NULL);
slouken@5232
   141
    glCompileShaderARB(shader);
slouken@5232
   142
    glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
slouken@5232
   143
    if (status == 0) {
slouken@5232
   144
        GLint length;
slouken@5232
   145
        char *info;
slouken@5232
   146
slouken@5232
   147
        glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
slouken@5232
   148
        info = SDL_stack_alloc(char, length+1);
slouken@5232
   149
        glGetInfoLogARB(shader, length, NULL, info);
slouken@5232
   150
        fprintf(stderr, "Failed to compile shader:\n%s\n%s", source, info);
slouken@5232
   151
        SDL_stack_free(info);
slouken@5232
   152
slouken@5232
   153
        return SDL_FALSE;
slouken@5232
   154
    } else {
slouken@5232
   155
        return SDL_TRUE;
slouken@5232
   156
    }
slouken@5232
   157
}
slouken@5232
   158
slouken@5232
   159
static SDL_bool CompileShaderProgram(ShaderData *data)
slouken@5232
   160
{
slouken@5232
   161
    const int num_tmus_bound = 4;
slouken@5232
   162
    int i;
slouken@5232
   163
    GLint location;
slouken@5232
   164
slouken@5232
   165
    glGetError();
slouken@5232
   166
slouken@5232
   167
    /* Create one program object to rule them all */
slouken@5232
   168
    data->program = glCreateProgramObjectARB();
slouken@5232
   169
slouken@5232
   170
    /* Create the vertex shader */
slouken@5232
   171
    data->vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
slouken@5232
   172
    if (!CompileShader(data->vert_shader, data->vert_source)) {
slouken@5232
   173
        return SDL_FALSE;
slouken@5232
   174
    }
slouken@5232
   175
slouken@5232
   176
    /* Create the fragment shader */
slouken@5232
   177
    data->frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
slouken@5232
   178
    if (!CompileShader(data->frag_shader, data->frag_source)) {
slouken@5232
   179
        return SDL_FALSE;
slouken@5232
   180
    }
slouken@5232
   181
slouken@5232
   182
    /* ... and in the darkness bind them */
slouken@5232
   183
    glAttachObjectARB(data->program, data->vert_shader);
slouken@5232
   184
    glAttachObjectARB(data->program, data->frag_shader);
slouken@5232
   185
    glLinkProgramARB(data->program);
slouken@5232
   186
slouken@5232
   187
    /* Set up some uniform variables */
slouken@5232
   188
    glUseProgramObjectARB(data->program);
slouken@5232
   189
    for (i = 0; i < num_tmus_bound; ++i) {
slouken@5232
   190
        char tex_name[5];
slouken@5232
   191
        SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i);
slouken@5232
   192
        location = glGetUniformLocationARB(data->program, tex_name);
slouken@5232
   193
        if (location >= 0) {
slouken@5232
   194
            glUniform1iARB(location, i);
slouken@5232
   195
        }
slouken@5232
   196
    }
slouken@5232
   197
    glUseProgramObjectARB(0);
slouken@5232
   198
 
slouken@5232
   199
    return (glGetError() == GL_NO_ERROR);
slouken@5232
   200
}
slouken@5232
   201
slouken@5232
   202
static void DestroyShaderProgram(ShaderData *data)
slouken@5232
   203
{
slouken@5236
   204
    if (shaders_supported) {
slouken@5236
   205
        glDeleteObjectARB(data->vert_shader);
slouken@5236
   206
        glDeleteObjectARB(data->frag_shader);
slouken@5236
   207
        glDeleteObjectARB(data->program);
slouken@5236
   208
    }
slouken@5232
   209
}
slouken@5232
   210
slouken@5232
   211
static SDL_bool InitShaders()
slouken@5232
   212
{
slouken@5232
   213
    int i;
slouken@5232
   214
slouken@5232
   215
    /* Check for shader support */
slouken@5232
   216
    shaders_supported = SDL_FALSE;
slouken@5232
   217
    if (SDL_GL_ExtensionSupported("GL_ARB_shader_objects") &&
slouken@5232
   218
        SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") &&
slouken@5232
   219
        SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") &&
slouken@5232
   220
        SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) {
slouken@5232
   221
        glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
slouken@5232
   222
        glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
slouken@5232
   223
        glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
slouken@5232
   224
        glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
slouken@5232
   225
        glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
slouken@5232
   226
        glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
slouken@5232
   227
        glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
slouken@5232
   228
        glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
slouken@5232
   229
        glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
slouken@5232
   230
        glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
slouken@5232
   231
        glUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
slouken@5232
   232
        glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
slouken@5232
   233
        if (glAttachObjectARB &&
slouken@5232
   234
            glCompileShaderARB &&
slouken@5232
   235
            glCreateProgramObjectARB &&
slouken@5232
   236
            glCreateShaderObjectARB &&
slouken@5232
   237
            glDeleteObjectARB &&
slouken@5232
   238
            glGetInfoLogARB &&
slouken@5232
   239
            glGetObjectParameterivARB &&
slouken@5232
   240
            glGetUniformLocationARB &&
slouken@5232
   241
            glLinkProgramARB &&
slouken@5232
   242
            glShaderSourceARB &&
slouken@5232
   243
            glUniform1iARB &&
slouken@5232
   244
            glUseProgramObjectARB) {
slouken@5232
   245
            shaders_supported = SDL_TRUE;
slouken@5232
   246
        }
slouken@5232
   247
    }
slouken@5232
   248
slouken@5232
   249
    if (!shaders_supported) {
slouken@5232
   250
        return SDL_FALSE;
slouken@5232
   251
    }
slouken@5232
   252
slouken@5232
   253
    /* Compile all the shaders */
slouken@5232
   254
    for (i = 0; i < NUM_SHADERS; ++i) {
slouken@5232
   255
        if (!CompileShaderProgram(&shaders[i])) {
slouken@5232
   256
            fprintf(stderr, "Unable to compile shader!\n");
slouken@5232
   257
            return SDL_FALSE;
slouken@5232
   258
        }
slouken@5232
   259
    }
slouken@5232
   260
slouken@5232
   261
    /* We're done! */
slouken@5232
   262
    return SDL_TRUE;
slouken@5232
   263
}
slouken@5232
   264
slouken@5232
   265
static void QuitShaders()
slouken@5232
   266
{
slouken@5232
   267
    int i;
slouken@5232
   268
slouken@5232
   269
    for (i = 0; i < NUM_SHADERS; ++i) {
slouken@5232
   270
        DestroyShaderProgram(&shaders[i]);
slouken@5232
   271
    }
slouken@5232
   272
}
slouken@5232
   273
slouken@5232
   274
/* Quick utility function for texture creation */
slouken@5232
   275
static int
slouken@5232
   276
power_of_two(int input)
slouken@5232
   277
{
slouken@5232
   278
    int value = 1;
slouken@5232
   279
slouken@5232
   280
    while (value < input) {
slouken@5232
   281
        value <<= 1;
slouken@5232
   282
    }
slouken@5232
   283
    return value;
slouken@5232
   284
}
slouken@5232
   285
slouken@5232
   286
GLuint
slouken@5232
   287
SDL_GL_LoadTexture(SDL_Surface * surface, GLfloat * texcoord)
slouken@5232
   288
{
slouken@5232
   289
    GLuint texture;
slouken@5232
   290
    int w, h;
slouken@5232
   291
    SDL_Surface *image;
slouken@5232
   292
    SDL_Rect area;
slouken@5232
   293
    Uint32 saved_flags;
slouken@5232
   294
    Uint8 saved_alpha;
slouken@5232
   295
slouken@5232
   296
    /* Use the surface width and height expanded to powers of 2 */
slouken@5232
   297
    w = power_of_two(surface->w);
slouken@5232
   298
    h = power_of_two(surface->h);
slouken@5232
   299
    texcoord[0] = 0.0f;         /* Min X */
slouken@5232
   300
    texcoord[1] = 0.0f;         /* Min Y */
slouken@5232
   301
    texcoord[2] = (GLfloat) surface->w / w;     /* Max X */
slouken@5232
   302
    texcoord[3] = (GLfloat) surface->h / h;     /* Max Y */
slouken@5232
   303
slouken@5232
   304
    image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
slouken@5232
   305
#if SDL_BYTEORDER == SDL_LIL_ENDIAN     /* OpenGL RGBA masks */
slouken@5232
   306
                                 0x000000FF,
slouken@5232
   307
                                 0x0000FF00, 0x00FF0000, 0xFF000000
slouken@5232
   308
#else
slouken@5232
   309
                                 0xFF000000,
slouken@5232
   310
                                 0x00FF0000, 0x0000FF00, 0x000000FF
slouken@5232
   311
#endif
slouken@5232
   312
        );
slouken@5232
   313
    if (image == NULL) {
slouken@5232
   314
        return 0;
slouken@5232
   315
    }
slouken@5232
   316
slouken@5232
   317
    /* Save the alpha blending attributes */
slouken@5232
   318
    saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
slouken@5232
   319
    SDL_GetSurfaceAlphaMod(surface, &saved_alpha);
slouken@5232
   320
    if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
slouken@5232
   321
        SDL_SetAlpha(surface, 0, 0);
slouken@5232
   322
    }
slouken@5232
   323
slouken@5232
   324
    /* Copy the surface into the GL texture image */
slouken@5232
   325
    area.x = 0;
slouken@5232
   326
    area.y = 0;
slouken@5232
   327
    area.w = surface->w;
slouken@5232
   328
    area.h = surface->h;
slouken@5232
   329
    SDL_BlitSurface(surface, &area, image, &area);
slouken@5232
   330
slouken@5232
   331
    /* Restore the alpha blending attributes */
slouken@5232
   332
    if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
slouken@5232
   333
        SDL_SetAlpha(surface, saved_flags, saved_alpha);
slouken@5232
   334
    }
slouken@5232
   335
slouken@5232
   336
    /* Create an OpenGL texture for the image */
slouken@5232
   337
    glGenTextures(1, &texture);
slouken@5232
   338
    glBindTexture(GL_TEXTURE_2D, texture);
slouken@5232
   339
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
slouken@5232
   340
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
slouken@5232
   341
    glTexImage2D(GL_TEXTURE_2D,
slouken@5232
   342
                 0,
slouken@5232
   343
                 GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
slouken@5232
   344
    SDL_FreeSurface(image);     /* No longer needed */
slouken@5232
   345
slouken@5232
   346
    return texture;
slouken@5232
   347
}
slouken@5232
   348
slouken@5232
   349
/* A general OpenGL initialization function.    Sets all of the initial parameters. */
slouken@5232
   350
void InitGL(int Width, int Height)                    // We call this right after our OpenGL window is created.
slouken@5232
   351
{
slouken@5232
   352
    GLdouble aspect;
slouken@5232
   353
slouken@5232
   354
    glViewport(0, 0, Width, Height);
slouken@5232
   355
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);        // This Will Clear The Background Color To Black
slouken@5232
   356
    glClearDepth(1.0);                // Enables Clearing Of The Depth Buffer
slouken@5232
   357
    glDepthFunc(GL_LESS);                // The Type Of Depth Test To Do
slouken@5232
   358
    glEnable(GL_DEPTH_TEST);            // Enables Depth Testing
slouken@5232
   359
    glShadeModel(GL_SMOOTH);            // Enables Smooth Color Shading
slouken@5232
   360
slouken@5232
   361
    glMatrixMode(GL_PROJECTION);
slouken@5232
   362
    glLoadIdentity();                // Reset The Projection Matrix
slouken@5232
   363
slouken@5232
   364
    aspect = (GLdouble)Width / Height;
slouken@5232
   365
    glOrtho(-3.0, 3.0, -3.0 / aspect, 3.0 / aspect, 0.0, 1.0);
slouken@5232
   366
slouken@5232
   367
    glMatrixMode(GL_MODELVIEW);
slouken@5232
   368
}
slouken@5232
   369
slouken@5232
   370
/* The main drawing function. */
slouken@5232
   371
void DrawGLScene(GLuint texture, GLfloat * texcoord)
slouken@5232
   372
{
slouken@5232
   373
    /* Texture coordinate lookup, to make it simple */
slouken@5232
   374
    enum {
slouken@5232
   375
        MINX,
slouken@5232
   376
        MINY,
slouken@5232
   377
        MAXX,
slouken@5232
   378
        MAXY
slouken@5232
   379
    };
slouken@5232
   380
slouken@5232
   381
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        // Clear The Screen And The Depth Buffer
slouken@5232
   382
    glLoadIdentity();                // Reset The View
slouken@5232
   383
slouken@5232
   384
    glTranslatef(-1.5f,0.0f,0.0f);        // Move Left 1.5 Units
slouken@5232
   385
    
slouken@5232
   386
    // draw a triangle (in smooth coloring mode)
slouken@5232
   387
    glBegin(GL_POLYGON);                // start drawing a polygon
slouken@5232
   388
    glColor3f(1.0f,0.0f,0.0f);            // Set The Color To Red
slouken@5232
   389
    glVertex3f( 0.0f, 1.0f, 0.0f);        // Top
slouken@5232
   390
    glColor3f(0.0f,1.0f,0.0f);            // Set The Color To Green
slouken@5232
   391
    glVertex3f( 1.0f,-1.0f, 0.0f);        // Bottom Right
slouken@5232
   392
    glColor3f(0.0f,0.0f,1.0f);            // Set The Color To Blue
slouken@5232
   393
    glVertex3f(-1.0f,-1.0f, 0.0f);        // Bottom Left    
slouken@5232
   394
    glEnd();                    // we're done with the polygon (smooth color interpolation)    
slouken@5232
   395
slouken@5232
   396
    glTranslatef(3.0f,0.0f,0.0f);         // Move Right 3 Units
slouken@5232
   397
slouken@5232
   398
    // Enable blending
slouken@5232
   399
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
slouken@5232
   400
    glEnable(GL_BLEND);
slouken@5232
   401
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
slouken@5232
   402
slouken@5232
   403
    // draw a textured square (quadrilateral)
slouken@5232
   404
    glEnable(GL_TEXTURE_2D);
slouken@5232
   405
    glBindTexture(GL_TEXTURE_2D, texture);
slouken@5232
   406
    glColor3f(1.0f,1.0f,1.0f);
slouken@5232
   407
    if (shaders_supported) {
slouken@5232
   408
        glUseProgramObjectARB(shaders[current_shader].program);
slouken@5232
   409
    }
slouken@5232
   410
slouken@5232
   411
    glBegin(GL_QUADS);                // start drawing a polygon (4 sided)
slouken@5232
   412
    glTexCoord2f(texcoord[MINX], texcoord[MINY]);
slouken@5232
   413
    glVertex3f(-1.0f, 1.0f, 0.0f);        // Top Left
slouken@5232
   414
    glTexCoord2f(texcoord[MAXX], texcoord[MINY]);
slouken@5232
   415
    glVertex3f( 1.0f, 1.0f, 0.0f);        // Top Right
slouken@5232
   416
    glTexCoord2f(texcoord[MAXX], texcoord[MAXY]);
slouken@5232
   417
    glVertex3f( 1.0f,-1.0f, 0.0f);        // Bottom Right
slouken@5232
   418
    glTexCoord2f(texcoord[MINX], texcoord[MAXY]);
slouken@5232
   419
    glVertex3f(-1.0f,-1.0f, 0.0f);        // Bottom Left    
slouken@5232
   420
    glEnd();                    // done with the polygon
slouken@5232
   421
slouken@5232
   422
    if (shaders_supported) {
slouken@5232
   423
        glUseProgramObjectARB(0);
slouken@5232
   424
    }
slouken@5232
   425
    glDisable(GL_TEXTURE_2D);
slouken@5232
   426
slouken@5232
   427
    // swap buffers to display, since we're double buffered.
slouken@5232
   428
    SDL_GL_SwapBuffers();
slouken@5232
   429
}
slouken@5232
   430
slouken@5232
   431
int main(int argc, char **argv) 
slouken@5232
   432
{    
slouken@5232
   433
    int done;
slouken@5232
   434
    SDL_Surface *surface;
slouken@5232
   435
    GLuint texture;
slouken@5232
   436
    GLfloat texcoords[4];
slouken@5232
   437
slouken@5232
   438
    /* Initialize SDL for video output */
slouken@5232
   439
    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
slouken@5232
   440
        fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
slouken@5232
   441
        exit(1);
slouken@5232
   442
    }
slouken@5232
   443
slouken@5232
   444
    /* Create a 640x480 OpenGL screen */
slouken@5232
   445
    if ( SDL_SetVideoMode(640, 480, 0, SDL_OPENGL) == NULL ) {
slouken@5232
   446
        fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
slouken@5232
   447
        SDL_Quit();
slouken@5232
   448
        exit(2);
slouken@5232
   449
    }
slouken@5232
   450
slouken@5232
   451
    /* Set the title bar in environments that support it */
slouken@5232
   452
    SDL_WM_SetCaption("Shader Demo", NULL);
slouken@5232
   453
slouken@5232
   454
    surface = SDL_LoadBMP("icon.bmp");
slouken@5232
   455
    if ( ! surface ) {
slouken@5232
   456
        fprintf(stderr, "Unable to load icon.bmp: %s\n", SDL_GetError());
slouken@5232
   457
        SDL_Quit();
slouken@5232
   458
        exit(3);
slouken@5232
   459
    }
slouken@5232
   460
    texture = SDL_GL_LoadTexture(surface, texcoords);
slouken@5232
   461
    SDL_FreeSurface(surface);
slouken@5232
   462
slouken@5232
   463
    /* Loop, drawing and checking events */
slouken@5232
   464
    InitGL(640, 480);
slouken@5232
   465
    if (InitShaders()) {
slouken@5232
   466
        printf("Shaders supported, press SPACE to cycle them.\n");
slouken@5232
   467
    } else {
slouken@5232
   468
        printf("Shaders not supported!\n");
slouken@5232
   469
    }
slouken@5232
   470
    done = 0;
slouken@5232
   471
    while ( ! done ) {
slouken@5232
   472
        DrawGLScene(texture, texcoords);
slouken@5232
   473
slouken@5232
   474
        /* This could go in a separate function */
slouken@5232
   475
        { SDL_Event event;
slouken@5232
   476
            while ( SDL_PollEvent(&event) ) {
slouken@5232
   477
                if ( event.type == SDL_QUIT ) {
slouken@5232
   478
                    done = 1;
slouken@5232
   479
                }
slouken@5232
   480
                if ( event.type == SDL_KEYDOWN ) {
slouken@5232
   481
                    if ( event.key.keysym.sym == SDLK_SPACE ) {
slouken@5232
   482
                        current_shader = (current_shader + 1) % NUM_SHADERS;
slouken@5232
   483
                    }
slouken@5232
   484
                    if ( event.key.keysym.sym == SDLK_ESCAPE ) {
slouken@5232
   485
                        done = 1;
slouken@5232
   486
                    }
slouken@5232
   487
                }
slouken@5232
   488
            }
slouken@5232
   489
        }
slouken@5232
   490
    }
slouken@5232
   491
    QuitShaders();
slouken@5232
   492
    SDL_Quit();
slouken@5232
   493
    return 1;
slouken@5232
   494
}
slouken@5232
   495
slouken@5232
   496
#else /* HAVE_OPENGL */
slouken@5232
   497
slouken@5232
   498
int
slouken@5232
   499
main(int argc, char *argv[])
slouken@5232
   500
{
slouken@5232
   501
    printf("No OpenGL support on this system\n");
slouken@5232
   502
    return 1;
slouken@5232
   503
}
slouken@5232
   504
slouken@5232
   505
#endif /* HAVE_OPENGL */
slouken@6256
   506
#endif
slouken@5236
   507
slouken@5236
   508
/* vi: set ts=4 sw=4 expandtab: */