test/testgles2.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:47 -0800
changeset 11731 30f337dc8c74
parent 10945 1300a3135d61
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Added iOS and OSX versions of the Metal shaders
gabomdq@8021
     1
/*
philipp@10825
     2
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
gabomdq@8021
     3
gabomdq@8021
     4
  This software is provided 'as-is', without any express or implied
gabomdq@8021
     5
  warranty.  In no event will the authors be held liable for any damages
gabomdq@8021
     6
  arising from the use of this software.
gabomdq@8021
     7
gabomdq@8021
     8
  Permission is granted to anyone to use this software for any purpose,
gabomdq@8021
     9
  including commercial applications, and to alter it and redistribute it
gabomdq@8021
    10
  freely.
gabomdq@8021
    11
*/
gabomdq@8021
    12
#include <stdlib.h>
gabomdq@8021
    13
#include <stdio.h>
gabomdq@8021
    14
#include <string.h>
gabomdq@8021
    15
#include <math.h>
gabomdq@8021
    16
icculus@9278
    17
#ifdef __EMSCRIPTEN__
icculus@9278
    18
#include <emscripten/emscripten.h>
icculus@9278
    19
#endif
icculus@9278
    20
gabomdq@8021
    21
#include "SDL_test_common.h"
gabomdq@8021
    22
slouken@10806
    23
#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \
slouken@10806
    24
    || defined(__WINDOWS__) || defined(__LINUX__)
gabomdq@8021
    25
#define HAVE_OPENGLES2
gabomdq@8021
    26
#endif
gabomdq@8021
    27
gabomdq@8021
    28
#ifdef HAVE_OPENGLES2
gabomdq@8021
    29
gabomdq@8021
    30
#include "SDL_opengles2.h"
gabomdq@8021
    31
gabomdq@8021
    32
typedef struct GLES2_Context
gabomdq@8021
    33
{
gabomdq@8021
    34
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
gabomdq@8021
    35
#include "../src/render/opengles2/SDL_gles2funcs.h"
gabomdq@8021
    36
#undef SDL_PROC
gabomdq@8021
    37
} GLES2_Context;
gabomdq@8021
    38
gabomdq@8021
    39
gabomdq@8021
    40
static SDLTest_CommonState *state;
gabomdq@8021
    41
static SDL_GLContext *context = NULL;
gabomdq@8021
    42
static int depth = 16;
gabomdq@8021
    43
static GLES2_Context ctx;
gabomdq@8021
    44
gabomdq@8021
    45
static int LoadContext(GLES2_Context * data)
gabomdq@8021
    46
{
gabomdq@8021
    47
#if SDL_VIDEO_DRIVER_UIKIT
gabomdq@8021
    48
#define __SDL_NOGETPROCADDR__
gabomdq@8021
    49
#elif SDL_VIDEO_DRIVER_ANDROID
gabomdq@8021
    50
#define __SDL_NOGETPROCADDR__
gabomdq@8021
    51
#elif SDL_VIDEO_DRIVER_PANDORA
gabomdq@8021
    52
#define __SDL_NOGETPROCADDR__
gabomdq@8021
    53
#endif
gabomdq@8021
    54
gabomdq@8021
    55
#if defined __SDL_NOGETPROCADDR__
gabomdq@8021
    56
#define SDL_PROC(ret,func,params) data->func=func;
gabomdq@8021
    57
#else
gabomdq@8021
    58
#define SDL_PROC(ret,func,params) \
gabomdq@8021
    59
    do { \
gabomdq@8021
    60
        data->func = SDL_GL_GetProcAddress(#func); \
gabomdq@8021
    61
        if ( ! data->func ) { \
philipp@10945
    62
            return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \
gabomdq@8021
    63
        } \
gabomdq@8021
    64
    } while ( 0 );
philipp@9966
    65
#endif /* __SDL_NOGETPROCADDR__ */
gabomdq@8021
    66
gabomdq@8021
    67
#include "../src/render/opengles2/SDL_gles2funcs.h"
gabomdq@8021
    68
#undef SDL_PROC
gabomdq@8021
    69
    return 0;
gabomdq@8021
    70
}
gabomdq@8021
    71
gabomdq@8021
    72
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
gabomdq@8021
    73
static void
gabomdq@8021
    74
quit(int rc)
gabomdq@8021
    75
{
gabomdq@8021
    76
    int i;
gabomdq@8021
    77
gabomdq@8021
    78
    if (context != NULL) {
gabomdq@8021
    79
        for (i = 0; i < state->num_windows; i++) {
gabomdq@8021
    80
            if (context[i]) {
gabomdq@8021
    81
                SDL_GL_DeleteContext(context[i]);
gabomdq@8021
    82
            }
gabomdq@8021
    83
        }
gabomdq@8021
    84
gabomdq@8021
    85
        SDL_free(context);
gabomdq@8021
    86
    }
gabomdq@8021
    87
gabomdq@8021
    88
    SDLTest_CommonQuit(state);
gabomdq@8021
    89
    exit(rc);
gabomdq@8021
    90
}
gabomdq@8021
    91
gabomdq@8021
    92
#define GL_CHECK(x) \
gabomdq@8021
    93
        x; \
gabomdq@8021
    94
        { \
gabomdq@8021
    95
          GLenum glError = ctx.glGetError(); \
gabomdq@8021
    96
          if(glError != GL_NO_ERROR) { \
gabomdq@8021
    97
            SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \
gabomdq@8021
    98
            quit(1); \
gabomdq@8021
    99
          } \
gabomdq@8021
   100
        }
gabomdq@8021
   101
gabomdq@8021
   102
/* 
gabomdq@8021
   103
 * Simulates desktop's glRotatef. The matrix is returned in column-major 
gabomdq@8021
   104
 * order. 
gabomdq@8021
   105
 */
gabomdq@8021
   106
static void
slouken@8841
   107
rotate_matrix(float angle, float x, float y, float z, float *r)
gabomdq@8021
   108
{
slouken@8841
   109
    float radians, c, s, c1, u[3], length;
gabomdq@8021
   110
    int i, j;
gabomdq@8021
   111
slouken@8841
   112
    radians = (float)(angle * M_PI) / 180.0f;
gabomdq@8021
   113
slouken@8841
   114
    c = SDL_cosf(radians);
slouken@8841
   115
    s = SDL_sinf(radians);
gabomdq@8021
   116
slouken@8841
   117
    c1 = 1.0f - SDL_cosf(radians);
gabomdq@8021
   118
slouken@8841
   119
    length = (float)SDL_sqrt(x * x + y * y + z * z);
gabomdq@8021
   120
gabomdq@8021
   121
    u[0] = x / length;
gabomdq@8021
   122
    u[1] = y / length;
gabomdq@8021
   123
    u[2] = z / length;
gabomdq@8021
   124
gabomdq@8021
   125
    for (i = 0; i < 16; i++) {
gabomdq@8021
   126
        r[i] = 0.0;
gabomdq@8021
   127
    }
gabomdq@8021
   128
gabomdq@8021
   129
    r[15] = 1.0;
gabomdq@8021
   130
gabomdq@8021
   131
    for (i = 0; i < 3; i++) {
gabomdq@8021
   132
        r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s;
gabomdq@8021
   133
        r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s;
gabomdq@8021
   134
    }
gabomdq@8021
   135
gabomdq@8021
   136
    for (i = 0; i < 3; i++) {
gabomdq@8021
   137
        for (j = 0; j < 3; j++) {
slouken@8841
   138
            r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0f);
gabomdq@8021
   139
        }
gabomdq@8021
   140
    }
gabomdq@8021
   141
}
gabomdq@8021
   142
gabomdq@8021
   143
/* 
gabomdq@8021
   144
 * Simulates gluPerspectiveMatrix 
gabomdq@8021
   145
 */
gabomdq@8021
   146
static void 
slouken@8841
   147
perspective_matrix(float fovy, float aspect, float znear, float zfar, float *r)
gabomdq@8021
   148
{
gabomdq@8021
   149
    int i;
slouken@8841
   150
    float f;
gabomdq@8021
   151
slouken@8841
   152
    f = 1.0f/SDL_tanf(fovy * 0.5f);
gabomdq@8021
   153
gabomdq@8021
   154
    for (i = 0; i < 16; i++) {
gabomdq@8021
   155
        r[i] = 0.0;
gabomdq@8021
   156
    }
gabomdq@8021
   157
gabomdq@8021
   158
    r[0] = f / aspect;
gabomdq@8021
   159
    r[5] = f;
gabomdq@8021
   160
    r[10] = (znear + zfar) / (znear - zfar);
slouken@8841
   161
    r[11] = -1.0f;
slouken@8841
   162
    r[14] = (2.0f * znear * zfar) / (znear - zfar);
slouken@8841
   163
    r[15] = 0.0f;
gabomdq@8021
   164
}
gabomdq@8021
   165
gabomdq@8021
   166
/* 
gabomdq@8021
   167
 * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column
gabomdq@8021
   168
 * major. In-place multiplication is supported.
gabomdq@8021
   169
 */
gabomdq@8021
   170
static void
gabomdq@8021
   171
multiply_matrix(float *lhs, float *rhs, float *r)
gabomdq@8021
   172
{
philipp@9922
   173
    int i, j, k;
gabomdq@8021
   174
    float tmp[16];
gabomdq@8021
   175
gabomdq@8021
   176
    for (i = 0; i < 4; i++) {
gabomdq@8021
   177
        for (j = 0; j < 4; j++) {
gabomdq@8021
   178
            tmp[j * 4 + i] = 0.0;
gabomdq@8021
   179
gabomdq@8021
   180
            for (k = 0; k < 4; k++) {
gabomdq@8021
   181
                tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k];
gabomdq@8021
   182
            }
gabomdq@8021
   183
        }
gabomdq@8021
   184
    }
gabomdq@8021
   185
gabomdq@8021
   186
    for (i = 0; i < 16; i++) {
gabomdq@8021
   187
        r[i] = tmp[i];
gabomdq@8021
   188
    }
gabomdq@8021
   189
}
gabomdq@8021
   190
gabomdq@8021
   191
/* 
gabomdq@8021
   192
 * Create shader, load in source, compile, dump debug as necessary.
gabomdq@8021
   193
 *
gabomdq@8021
   194
 * shader: Pointer to return created shader ID.
gabomdq@8021
   195
 * source: Passed-in shader source code.
gabomdq@8021
   196
 * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER.
gabomdq@8021
   197
 */
gabomdq@8021
   198
void 
gabomdq@8021
   199
process_shader(GLuint *shader, const char * source, GLint shader_type)
gabomdq@8021
   200
{
gabomdq@8021
   201
    GLint status = GL_FALSE;
gabomdq@8021
   202
    const char *shaders[1] = { NULL };
gabomdq@8833
   203
    char buffer[1024];
gabomdq@8833
   204
    GLsizei length;
gabomdq@8021
   205
gabomdq@8021
   206
    /* Create shader and load into GL. */
gabomdq@8021
   207
    *shader = GL_CHECK(ctx.glCreateShader(shader_type));
gabomdq@8021
   208
gabomdq@8021
   209
    shaders[0] = source;
gabomdq@8021
   210
gabomdq@8021
   211
    GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL));
gabomdq@8021
   212
gabomdq@8021
   213
    /* Clean up shader source. */
gabomdq@8021
   214
    shaders[0] = NULL;
gabomdq@8021
   215
gabomdq@8021
   216
    /* Try compiling the shader. */
gabomdq@8021
   217
    GL_CHECK(ctx.glCompileShader(*shader));
gabomdq@8021
   218
    GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
gabomdq@8021
   219
philipp@8776
   220
    /* Dump debug info (source and log) if compilation failed. */
gabomdq@8021
   221
    if(status != GL_TRUE) {
gabomdq@8833
   222
        ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]);
gabomdq@8833
   223
        buffer[length] = '\0';
gabomdq@8833
   224
        SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr);
gabomdq@8021
   225
        quit(-1);
gabomdq@8021
   226
    }
gabomdq@8021
   227
}
gabomdq@8021
   228
gabomdq@8021
   229
/* 3D data. Vertex range -0.5..0.5 in all axes.
gabomdq@8021
   230
* Z -0.5 is near, 0.5 is far. */
gabomdq@8021
   231
const float _vertices[] =
gabomdq@8021
   232
{
gabomdq@8021
   233
    /* Front face. */
gabomdq@8021
   234
    /* Bottom left */
gabomdq@8021
   235
    -0.5,  0.5, -0.5,
gabomdq@8021
   236
    0.5, -0.5, -0.5,
gabomdq@8021
   237
    -0.5, -0.5, -0.5,
gabomdq@8021
   238
    /* Top right */
gabomdq@8021
   239
    -0.5,  0.5, -0.5,
gabomdq@8021
   240
    0.5,  0.5, -0.5,
gabomdq@8021
   241
    0.5, -0.5, -0.5,
gabomdq@8021
   242
    /* Left face */
gabomdq@8021
   243
    /* Bottom left */
gabomdq@8021
   244
    -0.5,  0.5,  0.5,
gabomdq@8021
   245
    -0.5, -0.5, -0.5,
gabomdq@8021
   246
    -0.5, -0.5,  0.5,
gabomdq@8021
   247
    /* Top right */
gabomdq@8021
   248
    -0.5,  0.5,  0.5,
gabomdq@8021
   249
    -0.5,  0.5, -0.5,
gabomdq@8021
   250
    -0.5, -0.5, -0.5,
gabomdq@8021
   251
    /* Top face */
gabomdq@8021
   252
    /* Bottom left */
gabomdq@8021
   253
    -0.5,  0.5,  0.5,
gabomdq@8021
   254
    0.5,  0.5, -0.5,
gabomdq@8021
   255
    -0.5,  0.5, -0.5,
gabomdq@8021
   256
    /* Top right */
gabomdq@8021
   257
    -0.5,  0.5,  0.5,
gabomdq@8021
   258
    0.5,  0.5,  0.5,
gabomdq@8021
   259
    0.5,  0.5, -0.5,
gabomdq@8021
   260
    /* Right face */
gabomdq@8021
   261
    /* Bottom left */
gabomdq@8021
   262
    0.5,  0.5, -0.5,
gabomdq@8021
   263
    0.5, -0.5,  0.5,
gabomdq@8021
   264
    0.5, -0.5, -0.5,
gabomdq@8021
   265
    /* Top right */
gabomdq@8021
   266
    0.5,  0.5, -0.5,
gabomdq@8021
   267
    0.5,  0.5,  0.5,
gabomdq@8021
   268
    0.5, -0.5,  0.5,
gabomdq@8021
   269
    /* Back face */
gabomdq@8021
   270
    /* Bottom left */
gabomdq@8021
   271
    0.5,  0.5,  0.5,
gabomdq@8021
   272
    -0.5, -0.5,  0.5,
gabomdq@8021
   273
    0.5, -0.5,  0.5,
gabomdq@8021
   274
    /* Top right */
gabomdq@8021
   275
    0.5,  0.5,  0.5,
gabomdq@8021
   276
    -0.5,  0.5,  0.5,
gabomdq@8021
   277
    -0.5, -0.5,  0.5,
gabomdq@8021
   278
    /* Bottom face */
gabomdq@8021
   279
    /* Bottom left */
gabomdq@8021
   280
    -0.5, -0.5, -0.5,
gabomdq@8021
   281
    0.5, -0.5,  0.5,
gabomdq@8021
   282
    -0.5, -0.5,  0.5,
gabomdq@8021
   283
    /* Top right */
gabomdq@8021
   284
    -0.5, -0.5, -0.5,
gabomdq@8021
   285
    0.5, -0.5, -0.5,
gabomdq@8021
   286
    0.5, -0.5,  0.5,
gabomdq@8021
   287
};
gabomdq@8021
   288
gabomdq@8021
   289
const float _colors[] =
gabomdq@8021
   290
{
gabomdq@8021
   291
    /* Front face */
gabomdq@8021
   292
    /* Bottom left */
gabomdq@8021
   293
    1.0, 0.0, 0.0, /* red */
gabomdq@8021
   294
    0.0, 0.0, 1.0, /* blue */
gabomdq@8021
   295
    0.0, 1.0, 0.0, /* green */
gabomdq@8021
   296
    /* Top right */
gabomdq@8021
   297
    1.0, 0.0, 0.0, /* red */
gabomdq@8021
   298
    1.0, 1.0, 0.0, /* yellow */
gabomdq@8021
   299
    0.0, 0.0, 1.0, /* blue */
gabomdq@8021
   300
    /* Left face */
gabomdq@8021
   301
    /* Bottom left */
gabomdq@8021
   302
    1.0, 1.0, 1.0, /* white */
gabomdq@8021
   303
    0.0, 1.0, 0.0, /* green */
gabomdq@8021
   304
    0.0, 1.0, 1.0, /* cyan */
gabomdq@8021
   305
    /* Top right */
gabomdq@8021
   306
    1.0, 1.0, 1.0, /* white */
gabomdq@8021
   307
    1.0, 0.0, 0.0, /* red */
gabomdq@8021
   308
    0.0, 1.0, 0.0, /* green */
gabomdq@8021
   309
    /* Top face */
gabomdq@8021
   310
    /* Bottom left */
gabomdq@8021
   311
    1.0, 1.0, 1.0, /* white */
gabomdq@8021
   312
    1.0, 1.0, 0.0, /* yellow */
gabomdq@8021
   313
    1.0, 0.0, 0.0, /* red */
gabomdq@8021
   314
    /* Top right */
gabomdq@8021
   315
    1.0, 1.0, 1.0, /* white */
gabomdq@8021
   316
    0.0, 0.0, 0.0, /* black */
gabomdq@8021
   317
    1.0, 1.0, 0.0, /* yellow */
gabomdq@8021
   318
    /* Right face */
gabomdq@8021
   319
    /* Bottom left */
gabomdq@8021
   320
    1.0, 1.0, 0.0, /* yellow */
gabomdq@8021
   321
    1.0, 0.0, 1.0, /* magenta */
gabomdq@8021
   322
    0.0, 0.0, 1.0, /* blue */
gabomdq@8021
   323
    /* Top right */
gabomdq@8021
   324
    1.0, 1.0, 0.0, /* yellow */
gabomdq@8021
   325
    0.0, 0.0, 0.0, /* black */
gabomdq@8021
   326
    1.0, 0.0, 1.0, /* magenta */
gabomdq@8021
   327
    /* Back face */
gabomdq@8021
   328
    /* Bottom left */
gabomdq@8021
   329
    0.0, 0.0, 0.0, /* black */
gabomdq@8021
   330
    0.0, 1.0, 1.0, /* cyan */
gabomdq@8021
   331
    1.0, 0.0, 1.0, /* magenta */
gabomdq@8021
   332
    /* Top right */
gabomdq@8021
   333
    0.0, 0.0, 0.0, /* black */
gabomdq@8021
   334
    1.0, 1.0, 1.0, /* white */
gabomdq@8021
   335
    0.0, 1.0, 1.0, /* cyan */
gabomdq@8021
   336
    /* Bottom face */
gabomdq@8021
   337
    /* Bottom left */
gabomdq@8021
   338
    0.0, 1.0, 0.0, /* green */
gabomdq@8021
   339
    1.0, 0.0, 1.0, /* magenta */
gabomdq@8021
   340
    0.0, 1.0, 1.0, /* cyan */
gabomdq@8021
   341
    /* Top right */
gabomdq@8021
   342
    0.0, 1.0, 0.0, /* green */
gabomdq@8021
   343
    0.0, 0.0, 1.0, /* blue */
gabomdq@8021
   344
    1.0, 0.0, 1.0, /* magenta */
gabomdq@8021
   345
};
gabomdq@8021
   346
gabomdq@8021
   347
const char* _shader_vert_src = 
gabomdq@8021
   348
" attribute vec4 av4position; "
gabomdq@8021
   349
" attribute vec3 av3color; "
gabomdq@8021
   350
" uniform mat4 mvp; "
gabomdq@8021
   351
" varying vec3 vv3color; "
gabomdq@8021
   352
" void main() { "
gabomdq@8021
   353
"    vv3color = av3color; "
gabomdq@8021
   354
"    gl_Position = mvp * av4position; "
gabomdq@8021
   355
" } ";
gabomdq@8021
   356
gabomdq@8021
   357
const char* _shader_frag_src = 
gabomdq@8021
   358
" precision lowp float; "
gabomdq@8021
   359
" varying vec3 vv3color; "
gabomdq@8021
   360
" void main() { "
gabomdq@8021
   361
"    gl_FragColor = vec4(vv3color, 1.0); "
gabomdq@8021
   362
" } ";
gabomdq@8021
   363
gabomdq@8021
   364
typedef struct shader_data
gabomdq@8021
   365
{
gabomdq@8021
   366
    GLuint shader_program, shader_frag, shader_vert;
gabomdq@8021
   367
gabomdq@8021
   368
    GLint attr_position;
gabomdq@8021
   369
    GLint attr_color, attr_mvp;
gabomdq@8021
   370
gabomdq@8021
   371
    int angle_x, angle_y, angle_z;
gabomdq@8021
   372
gabomdq@8021
   373
} shader_data;
gabomdq@8021
   374
gabomdq@8021
   375
static void
gabomdq@8021
   376
Render(unsigned int width, unsigned int height, shader_data* data)
gabomdq@8021
   377
{
gabomdq@8021
   378
    float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16];
gabomdq@8021
   379
gabomdq@8021
   380
    /* 
gabomdq@8021
   381
    * Do some rotation with Euler angles. It is not a fixed axis as
gabomdq@8021
   382
    * quaterions would be, but the effect is cool. 
gabomdq@8021
   383
    */
slouken@8841
   384
    rotate_matrix((float)data->angle_x, 1.0f, 0.0f, 0.0f, matrix_modelview);
slouken@8841
   385
    rotate_matrix((float)data->angle_y, 0.0f, 1.0f, 0.0f, matrix_rotate);
gabomdq@8021
   386
gabomdq@8021
   387
    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
gabomdq@8021
   388
slouken@8841
   389
    rotate_matrix((float)data->angle_z, 0.0f, 1.0f, 0.0f, matrix_rotate);
gabomdq@8021
   390
gabomdq@8021
   391
    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
gabomdq@8021
   392
gabomdq@8021
   393
    /* Pull the camera back from the cube */
gabomdq@8021
   394
    matrix_modelview[14] -= 2.5;
gabomdq@8021
   395
slouken@8841
   396
    perspective_matrix(45.0f, (float)width/height, 0.01f, 100.0f, matrix_perspective);
gabomdq@8021
   397
    multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp);
gabomdq@8021
   398
gabomdq@8021
   399
    GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp));
gabomdq@8021
   400
gabomdq@8021
   401
    data->angle_x += 3;
gabomdq@8021
   402
    data->angle_y += 2;
gabomdq@8021
   403
    data->angle_z += 1;
gabomdq@8021
   404
gabomdq@8021
   405
    if(data->angle_x >= 360) data->angle_x -= 360;
gabomdq@8021
   406
    if(data->angle_x < 0) data->angle_x += 360;
gabomdq@8021
   407
    if(data->angle_y >= 360) data->angle_y -= 360;
gabomdq@8021
   408
    if(data->angle_y < 0) data->angle_y += 360;
gabomdq@8021
   409
    if(data->angle_z >= 360) data->angle_z -= 360;
gabomdq@8021
   410
    if(data->angle_z < 0) data->angle_z += 360;
gabomdq@8021
   411
gabomdq@8021
   412
    GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
gabomdq@8021
   413
    GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36));
gabomdq@8021
   414
}
gabomdq@8021
   415
icculus@9278
   416
int done;
icculus@9278
   417
Uint32 frames;
icculus@9278
   418
shader_data *datas;
icculus@9278
   419
icculus@9278
   420
void loop()
icculus@9278
   421
{
icculus@9278
   422
    SDL_Event event;
icculus@9278
   423
    int i;
icculus@9278
   424
    int status;
icculus@9278
   425
icculus@9278
   426
    /* Check for events */
icculus@9278
   427
    ++frames;
icculus@9278
   428
    while (SDL_PollEvent(&event) && !done) {
icculus@9278
   429
        switch (event.type) {
icculus@9278
   430
        case SDL_WINDOWEVENT:
icculus@9278
   431
            switch (event.window.event) {
icculus@9278
   432
                case SDL_WINDOWEVENT_RESIZED:
icculus@9278
   433
                    for (i = 0; i < state->num_windows; ++i) {
icculus@9278
   434
                        if (event.window.windowID == SDL_GetWindowID(state->windows[i])) {
icculus@9278
   435
                            int w, h;
icculus@9278
   436
                            status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
icculus@9278
   437
                            if (status) {
icculus@9278
   438
                                SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
icculus@9278
   439
                                break;
icculus@9278
   440
                            }
icculus@9278
   441
                            /* Change view port to the new window dimensions */
icculus@9278
   442
                            SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
icculus@9278
   443
                            ctx.glViewport(0, 0, w, h);
icculus@9278
   444
                            state->window_w = event.window.data1;
icculus@9278
   445
                            state->window_h = event.window.data2;
icculus@9278
   446
                            /* Update window content */
icculus@9278
   447
                            Render(event.window.data1, event.window.data2, &datas[i]);
icculus@9278
   448
                            SDL_GL_SwapWindow(state->windows[i]);
icculus@9278
   449
                            break;
icculus@9278
   450
                        }
icculus@9278
   451
                    }
icculus@9278
   452
                    break;
icculus@9278
   453
            }
icculus@9278
   454
        }
icculus@9278
   455
        SDLTest_CommonEvent(state, &event, &done);
icculus@9278
   456
    }
icculus@9278
   457
    if (!done) {
icculus@9278
   458
      for (i = 0; i < state->num_windows; ++i) {
icculus@9278
   459
          status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
icculus@9278
   460
          if (status) {
icculus@9278
   461
              SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
icculus@9278
   462
icculus@9278
   463
              /* Continue for next window */
icculus@9278
   464
              continue;
icculus@9278
   465
          }
icculus@9278
   466
          Render(state->window_w, state->window_h, &datas[i]);
icculus@9278
   467
          SDL_GL_SwapWindow(state->windows[i]);
icculus@9278
   468
      }
icculus@9278
   469
    }
philipp@9607
   470
#ifdef __EMSCRIPTEN__
philipp@9607
   471
    else {
philipp@9607
   472
        emscripten_cancel_main_loop();
philipp@9607
   473
    }
philipp@9607
   474
#endif
icculus@9278
   475
}
icculus@9278
   476
gabomdq@8021
   477
int
gabomdq@8021
   478
main(int argc, char *argv[])
gabomdq@8021
   479
{
gabomdq@8021
   480
    int fsaa, accel;
gabomdq@8021
   481
    int value;
icculus@9278
   482
    int i;
gabomdq@8021
   483
    SDL_DisplayMode mode;
icculus@9278
   484
    Uint32 then, now;
gabomdq@8021
   485
    int status;
icculus@9278
   486
    shader_data *data;
gabomdq@8021
   487
gabomdq@8021
   488
    /* Initialize parameters */
gabomdq@8021
   489
    fsaa = 0;
gabomdq@8021
   490
    accel = 0;
gabomdq@8021
   491
gabomdq@8021
   492
    /* Initialize test framework */
gabomdq@8021
   493
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
gabomdq@8021
   494
    if (!state) {
gabomdq@8021
   495
        return 1;
gabomdq@8021
   496
    }
gabomdq@8021
   497
    for (i = 1; i < argc;) {
gabomdq@8021
   498
        int consumed;
gabomdq@8021
   499
gabomdq@8021
   500
        consumed = SDLTest_CommonArg(state, i);
gabomdq@8021
   501
        if (consumed == 0) {
gabomdq@8021
   502
            if (SDL_strcasecmp(argv[i], "--fsaa") == 0) {
gabomdq@8021
   503
                ++fsaa;
gabomdq@8021
   504
                consumed = 1;
gabomdq@8021
   505
            } else if (SDL_strcasecmp(argv[i], "--accel") == 0) {
gabomdq@8021
   506
                ++accel;
gabomdq@8021
   507
                consumed = 1;
gabomdq@8021
   508
            } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) {
gabomdq@8021
   509
                i++;
gabomdq@8021
   510
                if (!argv[i]) {
gabomdq@8021
   511
                    consumed = -1;
gabomdq@8021
   512
                } else {
gabomdq@8021
   513
                    depth = SDL_atoi(argv[i]);
gabomdq@8021
   514
                    consumed = 1;
gabomdq@8021
   515
                }
gabomdq@8021
   516
            } else {
gabomdq@8021
   517
                consumed = -1;
gabomdq@8021
   518
            }
gabomdq@8021
   519
        }
gabomdq@8021
   520
        if (consumed < 0) {
gabomdq@8021
   521
            SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0],
gabomdq@8021
   522
                    SDLTest_CommonUsage(state));
gabomdq@8021
   523
            quit(1);
gabomdq@8021
   524
        }
gabomdq@8021
   525
        i += consumed;
gabomdq@8021
   526
    }
gabomdq@8021
   527
gabomdq@8021
   528
    /* Set OpenGL parameters */
gabomdq@8021
   529
    state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
gabomdq@8021
   530
    state->gl_red_size = 5;
gabomdq@8021
   531
    state->gl_green_size = 5;
gabomdq@8021
   532
    state->gl_blue_size = 5;
gabomdq@8021
   533
    state->gl_depth_size = depth;
gabomdq@8021
   534
    state->gl_major_version = 2;
gabomdq@8021
   535
    state->gl_minor_version = 0;
gabomdq@8021
   536
    state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
gabomdq@8021
   537
gabomdq@8021
   538
    if (fsaa) {
gabomdq@8021
   539
        state->gl_multisamplebuffers=1;
gabomdq@8021
   540
        state->gl_multisamplesamples=fsaa;
gabomdq@8021
   541
    }
gabomdq@8021
   542
    if (accel) {
gabomdq@8021
   543
        state->gl_accelerated=1;
gabomdq@8021
   544
    }
gabomdq@8021
   545
    if (!SDLTest_CommonInit(state)) {
gabomdq@8021
   546
        quit(2);
gabomdq@8021
   547
        return 0;
gabomdq@8021
   548
    }
gabomdq@8021
   549
philipp@10503
   550
    context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context));
gabomdq@8021
   551
    if (context == NULL) {
gabomdq@8021
   552
        SDL_Log("Out of memory!\n");
gabomdq@8021
   553
        quit(2);
gabomdq@8021
   554
    }
gabomdq@8021
   555
    
gabomdq@8021
   556
    /* Create OpenGL ES contexts */
gabomdq@8021
   557
    for (i = 0; i < state->num_windows; i++) {
gabomdq@8021
   558
        context[i] = SDL_GL_CreateContext(state->windows[i]);
gabomdq@8021
   559
        if (!context[i]) {
gabomdq@8021
   560
            SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError());
gabomdq@8021
   561
            quit(2);
gabomdq@8021
   562
        }
gabomdq@8021
   563
    }
gabomdq@8021
   564
gabomdq@8021
   565
    /* Important: call this *after* creating the context */
gabomdq@8021
   566
    if (LoadContext(&ctx) < 0) {
gabomdq@8021
   567
        SDL_Log("Could not load GLES2 functions\n");
gabomdq@8021
   568
        quit(2);
gabomdq@8021
   569
        return 0;
gabomdq@8021
   570
    }
gabomdq@8021
   571
gabomdq@8021
   572
gabomdq@8021
   573
gabomdq@8021
   574
    if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
gabomdq@8021
   575
        SDL_GL_SetSwapInterval(1);
gabomdq@8021
   576
    } else {
gabomdq@8021
   577
        SDL_GL_SetSwapInterval(0);
gabomdq@8021
   578
    }
gabomdq@8021
   579
gabomdq@8021
   580
    SDL_GetCurrentDisplayMode(0, &mode);
gabomdq@8021
   581
    SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format));
gabomdq@8021
   582
    SDL_Log("\n");
gabomdq@8021
   583
    SDL_Log("Vendor     : %s\n", ctx.glGetString(GL_VENDOR));
gabomdq@8021
   584
    SDL_Log("Renderer   : %s\n", ctx.glGetString(GL_RENDERER));
gabomdq@8021
   585
    SDL_Log("Version    : %s\n", ctx.glGetString(GL_VERSION));
gabomdq@8021
   586
    SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS));
gabomdq@8021
   587
    SDL_Log("\n");
gabomdq@8021
   588
gabomdq@8021
   589
    status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
gabomdq@8021
   590
    if (!status) {
gabomdq@8021
   591
        SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
gabomdq@8021
   592
    } else {
gabomdq@8021
   593
        SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n",
gabomdq@8021
   594
                SDL_GetError());
gabomdq@8021
   595
    }
gabomdq@8021
   596
    status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
gabomdq@8021
   597
    if (!status) {
gabomdq@8021
   598
        SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
gabomdq@8021
   599
    } else {
gabomdq@8021
   600
        SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n",
gabomdq@8021
   601
                SDL_GetError());
gabomdq@8021
   602
    }
gabomdq@8021
   603
    status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
gabomdq@8021
   604
    if (!status) {
gabomdq@8021
   605
        SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
gabomdq@8021
   606
    } else {
gabomdq@8021
   607
        SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n",
gabomdq@8021
   608
                SDL_GetError());
gabomdq@8021
   609
    }
gabomdq@8021
   610
    status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
gabomdq@8021
   611
    if (!status) {
gabomdq@8021
   612
        SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value);
gabomdq@8021
   613
    } else {
gabomdq@8021
   614
        SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n",
gabomdq@8021
   615
                SDL_GetError());
gabomdq@8021
   616
    }
gabomdq@8021
   617
    if (fsaa) {
gabomdq@8021
   618
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
gabomdq@8021
   619
        if (!status) {
gabomdq@8021
   620
            SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
gabomdq@8021
   621
        } else {
gabomdq@8021
   622
            SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
gabomdq@8021
   623
                    SDL_GetError());
gabomdq@8021
   624
        }
gabomdq@8021
   625
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
gabomdq@8021
   626
        if (!status) {
gabomdq@8021
   627
            SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
gabomdq@8021
   628
                   value);
gabomdq@8021
   629
        } else {
gabomdq@8021
   630
            SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
gabomdq@8021
   631
                    SDL_GetError());
gabomdq@8021
   632
        }
gabomdq@8021
   633
    }
gabomdq@8021
   634
    if (accel) {
gabomdq@8021
   635
        status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
gabomdq@8021
   636
        if (!status) {
gabomdq@8021
   637
            SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
gabomdq@8021
   638
        } else {
gabomdq@8021
   639
            SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
gabomdq@8021
   640
                    SDL_GetError());
gabomdq@8021
   641
        }
gabomdq@8021
   642
    }
gabomdq@8021
   643
philipp@10503
   644
    datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data));
gabomdq@8021
   645
gabomdq@8021
   646
    /* Set rendering settings for each context */
gabomdq@8021
   647
    for (i = 0; i < state->num_windows; ++i) {
gabomdq@8021
   648
icculus@9278
   649
        int w, h;
gabomdq@8021
   650
        status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
gabomdq@8021
   651
        if (status) {
gabomdq@8021
   652
            SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
gabomdq@8021
   653
gabomdq@8021
   654
            /* Continue for next window */
gabomdq@8021
   655
            continue;
gabomdq@8021
   656
        }
icculus@9278
   657
        SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
icculus@9278
   658
        ctx.glViewport(0, 0, w, h);
gabomdq@8021
   659
gabomdq@8021
   660
        data = &datas[i];
gabomdq@8021
   661
        data->angle_x = 0; data->angle_y = 0; data->angle_z = 0;
gabomdq@8021
   662
gabomdq@8021
   663
        /* Shader Initialization */
gabomdq@8021
   664
        process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER);
gabomdq@8021
   665
        process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER);
gabomdq@8021
   666
gabomdq@8021
   667
        /* Create shader_program (ready to attach shaders) */
gabomdq@8021
   668
        data->shader_program = GL_CHECK(ctx.glCreateProgram());
gabomdq@8021
   669
gabomdq@8021
   670
        /* Attach shaders and link shader_program */
gabomdq@8021
   671
        GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert));
gabomdq@8021
   672
        GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag));
gabomdq@8021
   673
        GL_CHECK(ctx.glLinkProgram(data->shader_program));
gabomdq@8021
   674
gabomdq@8021
   675
        /* Get attribute locations of non-fixed attributes like color and texture coordinates. */
gabomdq@8021
   676
        data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position"));
gabomdq@8021
   677
        data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color"));
gabomdq@8021
   678
gabomdq@8021
   679
        /* Get uniform locations */
gabomdq@8021
   680
        data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp"));
gabomdq@8021
   681
gabomdq@8021
   682
        GL_CHECK(ctx.glUseProgram(data->shader_program));
gabomdq@8021
   683
gabomdq@8021
   684
        /* Enable attributes for position, color and texture coordinates etc. */
gabomdq@8021
   685
        GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position));
gabomdq@8021
   686
        GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color));
gabomdq@8021
   687
gabomdq@8021
   688
        /* Populate attributes for position, color and texture coordinates etc. */
gabomdq@8021
   689
        GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices));
gabomdq@8021
   690
        GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors));
gabomdq@8021
   691
gabomdq@8021
   692
        GL_CHECK(ctx.glEnable(GL_CULL_FACE));
gabomdq@8021
   693
        GL_CHECK(ctx.glEnable(GL_DEPTH_TEST));
gabomdq@8021
   694
    }
gabomdq@8021
   695
gabomdq@8021
   696
    /* Main render loop */
gabomdq@8021
   697
    frames = 0;
gabomdq@8021
   698
    then = SDL_GetTicks();
gabomdq@8021
   699
    done = 0;
icculus@9278
   700
icculus@9278
   701
#ifdef __EMSCRIPTEN__
icculus@9278
   702
    emscripten_set_main_loop(loop, 0, 1);
icculus@9278
   703
#else
gabomdq@8021
   704
    while (!done) {
icculus@9278
   705
        loop();
gabomdq@8021
   706
    }
icculus@9278
   707
#endif
gabomdq@8021
   708
gabomdq@8021
   709
    /* Print out some timing information */
gabomdq@8021
   710
    now = SDL_GetTicks();
gabomdq@8021
   711
    if (now > then) {
gabomdq@8021
   712
        SDL_Log("%2.2f frames per second\n",
gabomdq@8021
   713
               ((double) frames * 1000) / (now - then));
gabomdq@8021
   714
    }
gabomdq@8833
   715
#if !defined(__ANDROID__) && !defined(__NACL__)  
gabomdq@8021
   716
    quit(0);
gabomdq@8021
   717
#endif    
gabomdq@8021
   718
    return 0;
gabomdq@8021
   719
}
gabomdq@8021
   720
gabomdq@8021
   721
#else /* HAVE_OPENGLES2 */
gabomdq@8021
   722
gabomdq@8021
   723
int
gabomdq@8021
   724
main(int argc, char *argv[])
gabomdq@8021
   725
{
gabomdq@8021
   726
    SDL_Log("No OpenGL ES support on this system\n");
gabomdq@8021
   727
    return 1;
gabomdq@8021
   728
}
gabomdq@8021
   729
gabomdq@8021
   730
#endif /* HAVE_OPENGLES2 */
gabomdq@8021
   731
gabomdq@8021
   732
/* vi: set ts=4 sw=4 expandtab: */