test/testgles2.c
changeset 8021 f96e12e0ade9
parent 8014 0a4b6dec7de5
child 8027 21dcb24404c0
     1.1 --- a/test/testgles2.c	Fri Nov 22 10:26:28 2013 -0300
     1.2 +++ b/test/testgles2.c	Fri Nov 22 13:24:53 2013 -0300
     1.3 @@ -1,647 +1,694 @@
     1.4 -/*
     1.5 -  Copyright (r) 1997-2011 Sam Lantinga <slouken@libsdl.org>
     1.6 -
     1.7 -  This software is provided 'as-is', without any express or implied
     1.8 -  warranty.  In no event will the authors be held liable for any damages
     1.9 -  arising from the use of this software.
    1.10 -
    1.11 -  Permission is granted to anyone to use this software for any purpose,
    1.12 -  including commercial applications, and to alter it and redistribute it
    1.13 -  freely.
    1.14 -*/
    1.15 -#include <stdlib.h>
    1.16 -#include <stdio.h>
    1.17 -#include <string.h>
    1.18 -#include <math.h>
    1.19 -
    1.20 -#include "SDL_test_common.h"
    1.21 -
    1.22 -#if defined(__IPHONEOS__) || defined(__ANDROID__)
    1.23 -#define HAVE_OPENGLES2
    1.24 -#endif
    1.25 -
    1.26 -#ifdef HAVE_OPENGLES2
    1.27 -
    1.28 -#include "SDL_opengles2.h"
    1.29 -
    1.30 -static SDLTest_CommonState *state;
    1.31 -static SDL_GLContext *context = NULL;
    1.32 -static int depth = 16;
    1.33 -
    1.34 -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    1.35 -static void
    1.36 -quit(int rc)
    1.37 -{
    1.38 -    int i;
    1.39 -
    1.40 -    if (context != NULL) {
    1.41 -        for (i = 0; i < state->num_windows; i++) {
    1.42 -            if (context[i]) {
    1.43 -                SDL_GL_DeleteContext(context[i]);
    1.44 -            }
    1.45 -        }
    1.46 -
    1.47 -        SDL_free(context);
    1.48 -    }
    1.49 -
    1.50 -    SDLTest_CommonQuit(state);
    1.51 -    exit(rc);
    1.52 -}
    1.53 -
    1.54 -#define GL_CHECK(x) \
    1.55 -        x; \
    1.56 -        { \
    1.57 -          GLenum glError = glGetError(); \
    1.58 -          if(glError != GL_NO_ERROR) { \
    1.59 -            fprintf(stderr, "glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \
    1.60 -            quit(1); \
    1.61 -          } \
    1.62 -        }
    1.63 -
    1.64 -/* 
    1.65 - * Simulates desktop's glRotatef. The matrix is returned in column-major 
    1.66 - * order. 
    1.67 - */
    1.68 -static void
    1.69 -rotate_matrix(double angle, double x, double y, double z, float *r)
    1.70 -{
    1.71 -    double radians, c, s, c1, u[3], length;
    1.72 -    int i, j;
    1.73 -
    1.74 -    radians = (angle * M_PI) / 180.0;
    1.75 -
    1.76 -    c = cos(radians);
    1.77 -    s = sin(radians);
    1.78 -
    1.79 -    c1 = 1.0 - cos(radians);
    1.80 -
    1.81 -    length = sqrt(x * x + y * y + z * z);
    1.82 -
    1.83 -    u[0] = x / length;
    1.84 -    u[1] = y / length;
    1.85 -    u[2] = z / length;
    1.86 -
    1.87 -    for (i = 0; i < 16; i++) {
    1.88 -        r[i] = 0.0;
    1.89 -    }
    1.90 -
    1.91 -    r[15] = 1.0;
    1.92 -
    1.93 -    for (i = 0; i < 3; i++) {
    1.94 -        r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s;
    1.95 -        r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s;
    1.96 -    }
    1.97 -
    1.98 -    for (i = 0; i < 3; i++) {
    1.99 -        for (j = 0; j < 3; j++) {
   1.100 -            r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0);
   1.101 -        }
   1.102 -    }
   1.103 -}
   1.104 -
   1.105 -/* 
   1.106 - * Simulates gluPerspectiveMatrix 
   1.107 - */
   1.108 -static void 
   1.109 -perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r)
   1.110 -{
   1.111 -    int i;
   1.112 -    double f;
   1.113 -
   1.114 -    f = 1.0/tan(fovy * 0.5);
   1.115 -
   1.116 -    for (i = 0; i < 16; i++) {
   1.117 -        r[i] = 0.0;
   1.118 -    }
   1.119 -
   1.120 -    r[0] = f / aspect;
   1.121 -    r[5] = f;
   1.122 -    r[10] = (znear + zfar) / (znear - zfar);
   1.123 -    r[11] = -1.0;
   1.124 -    r[14] = (2.0 * znear * zfar) / (znear - zfar);
   1.125 -    r[15] = 0.0;
   1.126 -}
   1.127 -
   1.128 -/* 
   1.129 - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column
   1.130 - * major. In-place multiplication is supported.
   1.131 - */
   1.132 -static void
   1.133 -multiply_matrix(float *lhs, float *rhs, float *r)
   1.134 -{
   1.135 -	int i, j, k;
   1.136 -    float tmp[16];
   1.137 -
   1.138 -    for (i = 0; i < 4; i++) {
   1.139 -        for (j = 0; j < 4; j++) {
   1.140 -            tmp[j * 4 + i] = 0.0;
   1.141 -
   1.142 -            for (k = 0; k < 4; k++) {
   1.143 -                tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k];
   1.144 -            }
   1.145 -        }
   1.146 -    }
   1.147 -
   1.148 -    for (i = 0; i < 16; i++) {
   1.149 -        r[i] = tmp[i];
   1.150 -    }
   1.151 -}
   1.152 -
   1.153 -/* 
   1.154 - * Create shader, load in source, compile, dump debug as necessary.
   1.155 - *
   1.156 - * shader: Pointer to return created shader ID.
   1.157 - * source: Passed-in shader source code.
   1.158 - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER.
   1.159 - */
   1.160 -void 
   1.161 -process_shader(GLuint *shader, const char * source, GLint shader_type)
   1.162 -{
   1.163 -    GLint status;
   1.164 -    const char *shaders[1] = { NULL };
   1.165 -
   1.166 -    /* Create shader and load into GL. */
   1.167 -    *shader = GL_CHECK(glCreateShader(shader_type));
   1.168 -
   1.169 -    shaders[0] = source;
   1.170 -
   1.171 -    GL_CHECK(glShaderSource(*shader, 1, shaders, NULL));
   1.172 -
   1.173 -    /* Clean up shader source. */
   1.174 -    shaders[0] = NULL;
   1.175 -
   1.176 -    /* Try compiling the shader. */
   1.177 -    GL_CHECK(glCompileShader(*shader));
   1.178 -    GL_CHECK(glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
   1.179 -
   1.180 -    // Dump debug info (source and log) if compilation failed.
   1.181 -    if(status != GL_TRUE) {
   1.182 -        quit(-1);
   1.183 -    }
   1.184 -}
   1.185 -
   1.186 -/* 3D data. Vertex range -0.5..0.5 in all axes.
   1.187 -* Z -0.5 is near, 0.5 is far. */
   1.188 -const float _vertices[] =
   1.189 -{
   1.190 -    /* Front face. */
   1.191 -    /* Bottom left */
   1.192 -    -0.5,  0.5, -0.5,
   1.193 -    0.5, -0.5, -0.5,
   1.194 -    -0.5, -0.5, -0.5,
   1.195 -    /* Top right */
   1.196 -    -0.5,  0.5, -0.5,
   1.197 -    0.5,  0.5, -0.5,
   1.198 -    0.5, -0.5, -0.5,
   1.199 -    /* Left face */
   1.200 -    /* Bottom left */
   1.201 -    -0.5,  0.5,  0.5,
   1.202 -    -0.5, -0.5, -0.5,
   1.203 -    -0.5, -0.5,  0.5,
   1.204 -    /* Top right */
   1.205 -    -0.5,  0.5,  0.5,
   1.206 -    -0.5,  0.5, -0.5,
   1.207 -    -0.5, -0.5, -0.5,
   1.208 -    /* Top face */
   1.209 -    /* Bottom left */
   1.210 -    -0.5,  0.5,  0.5,
   1.211 -    0.5,  0.5, -0.5,
   1.212 -    -0.5,  0.5, -0.5,
   1.213 -    /* Top right */
   1.214 -    -0.5,  0.5,  0.5,
   1.215 -    0.5,  0.5,  0.5,
   1.216 -    0.5,  0.5, -0.5,
   1.217 -    /* Right face */
   1.218 -    /* Bottom left */
   1.219 -    0.5,  0.5, -0.5,
   1.220 -    0.5, -0.5,  0.5,
   1.221 -    0.5, -0.5, -0.5,
   1.222 -    /* Top right */
   1.223 -    0.5,  0.5, -0.5,
   1.224 -    0.5,  0.5,  0.5,
   1.225 -    0.5, -0.5,  0.5,
   1.226 -    /* Back face */
   1.227 -    /* Bottom left */
   1.228 -    0.5,  0.5,  0.5,
   1.229 -    -0.5, -0.5,  0.5,
   1.230 -    0.5, -0.5,  0.5,
   1.231 -    /* Top right */
   1.232 -    0.5,  0.5,  0.5,
   1.233 -    -0.5,  0.5,  0.5,
   1.234 -    -0.5, -0.5,  0.5,
   1.235 -    /* Bottom face */
   1.236 -    /* Bottom left */
   1.237 -    -0.5, -0.5, -0.5,
   1.238 -    0.5, -0.5,  0.5,
   1.239 -    -0.5, -0.5,  0.5,
   1.240 -    /* Top right */
   1.241 -    -0.5, -0.5, -0.5,
   1.242 -    0.5, -0.5, -0.5,
   1.243 -    0.5, -0.5,  0.5,
   1.244 -};
   1.245 -
   1.246 -const float _colors[] =
   1.247 -{
   1.248 -    /* Front face */
   1.249 -    /* Bottom left */
   1.250 -    1.0, 0.0, 0.0, /* red */
   1.251 -    0.0, 0.0, 1.0, /* blue */
   1.252 -    0.0, 1.0, 0.0, /* green */
   1.253 -    /* Top right */
   1.254 -    1.0, 0.0, 0.0, /* red */
   1.255 -    1.0, 1.0, 0.0, /* yellow */
   1.256 -    0.0, 0.0, 1.0, /* blue */
   1.257 -    /* Left face */
   1.258 -    /* Bottom left */
   1.259 -    1.0, 1.0, 1.0, /* white */
   1.260 -    0.0, 1.0, 0.0, /* green */
   1.261 -    0.0, 1.0, 1.0, /* cyan */
   1.262 -    /* Top right */
   1.263 -    1.0, 1.0, 1.0, /* white */
   1.264 -    1.0, 0.0, 0.0, /* red */
   1.265 -    0.0, 1.0, 0.0, /* green */
   1.266 -    /* Top face */
   1.267 -    /* Bottom left */
   1.268 -    1.0, 1.0, 1.0, /* white */
   1.269 -    1.0, 1.0, 0.0, /* yellow */
   1.270 -    1.0, 0.0, 0.0, /* red */
   1.271 -    /* Top right */
   1.272 -    1.0, 1.0, 1.0, /* white */
   1.273 -    0.0, 0.0, 0.0, /* black */
   1.274 -    1.0, 1.0, 0.0, /* yellow */
   1.275 -    /* Right face */
   1.276 -    /* Bottom left */
   1.277 -    1.0, 1.0, 0.0, /* yellow */
   1.278 -    1.0, 0.0, 1.0, /* magenta */
   1.279 -    0.0, 0.0, 1.0, /* blue */
   1.280 -    /* Top right */
   1.281 -    1.0, 1.0, 0.0, /* yellow */
   1.282 -    0.0, 0.0, 0.0, /* black */
   1.283 -    1.0, 0.0, 1.0, /* magenta */
   1.284 -    /* Back face */
   1.285 -    /* Bottom left */
   1.286 -    0.0, 0.0, 0.0, /* black */
   1.287 -    0.0, 1.0, 1.0, /* cyan */
   1.288 -    1.0, 0.0, 1.0, /* magenta */
   1.289 -    /* Top right */
   1.290 -    0.0, 0.0, 0.0, /* black */
   1.291 -    1.0, 1.0, 1.0, /* white */
   1.292 -    0.0, 1.0, 1.0, /* cyan */
   1.293 -    /* Bottom face */
   1.294 -    /* Bottom left */
   1.295 -    0.0, 1.0, 0.0, /* green */
   1.296 -    1.0, 0.0, 1.0, /* magenta */
   1.297 -    0.0, 1.0, 1.0, /* cyan */
   1.298 -    /* Top right */
   1.299 -    0.0, 1.0, 0.0, /* green */
   1.300 -    0.0, 0.0, 1.0, /* blue */
   1.301 -    1.0, 0.0, 1.0, /* magenta */
   1.302 -};
   1.303 -
   1.304 -const char* _shader_vert_src = 
   1.305 -" attribute vec4 av4position; "
   1.306 -" attribute vec3 av3color; "
   1.307 -" uniform mat4 mvp; "
   1.308 -" varying vec3 vv3color; "
   1.309 -" void main() { "
   1.310 -"    vv3color = av3color; "
   1.311 -"    gl_Position = mvp * av4position; "
   1.312 -" } ";
   1.313 -
   1.314 -const char* _shader_frag_src = 
   1.315 -" precision lowp float; "
   1.316 -" varying vec3 vv3color; "
   1.317 -" void main() { "
   1.318 -"    gl_FragColor = vec4(vv3color, 1.0); "
   1.319 -" } ";
   1.320 -
   1.321 -typedef struct shader_data
   1.322 -{
   1.323 -    GLuint shader_program, shader_frag, shader_vert;
   1.324 -
   1.325 -    GLint attr_position;
   1.326 -    GLint attr_color, attr_mvp;
   1.327 -
   1.328 -    int angle_x, angle_y, angle_z;
   1.329 -
   1.330 -} shader_data;
   1.331 -
   1.332 -static void
   1.333 -Render(unsigned int width, unsigned int height, shader_data* data)
   1.334 -{
   1.335 -    float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16];
   1.336 -
   1.337 -    /* 
   1.338 -    * Do some rotation with Euler angles. It is not a fixed axis as
   1.339 -    * quaterions would be, but the effect is cool. 
   1.340 -    */
   1.341 -    rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview);
   1.342 -    rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate);
   1.343 -
   1.344 -    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
   1.345 -
   1.346 -    rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate);
   1.347 -
   1.348 -    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
   1.349 -
   1.350 -    /* Pull the camera back from the cube */
   1.351 -    matrix_modelview[14] -= 2.5;
   1.352 -
   1.353 -    perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective);
   1.354 -    multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp);
   1.355 -
   1.356 -    GL_CHECK(glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp));
   1.357 -
   1.358 -    data->angle_x += 3;
   1.359 -    data->angle_y += 2;
   1.360 -    data->angle_z += 1;
   1.361 -
   1.362 -    if(data->angle_x >= 360) data->angle_x -= 360;
   1.363 -    if(data->angle_x < 0) data->angle_x += 360;
   1.364 -    if(data->angle_y >= 360) data->angle_y -= 360;
   1.365 -    if(data->angle_y < 0) data->angle_y += 360;
   1.366 -    if(data->angle_z >= 360) data->angle_z -= 360;
   1.367 -    if(data->angle_z < 0) data->angle_z += 360;
   1.368 -
   1.369 -    GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
   1.370 -    GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 36));
   1.371 -}
   1.372 -
   1.373 -int
   1.374 -main(int argc, char *argv[])
   1.375 -{
   1.376 -    int fsaa, accel;
   1.377 -    int value;
   1.378 -    int i, done;
   1.379 -    SDL_DisplayMode mode;
   1.380 -    SDL_Event event;
   1.381 -    Uint32 then, now, frames;
   1.382 -    int status;
   1.383 -    shader_data *datas, *data;
   1.384 -
   1.385 -    /* Initialize parameters */
   1.386 -    fsaa = 0;
   1.387 -    accel = 0;
   1.388 -
   1.389 -    /* Initialize test framework */
   1.390 -    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
   1.391 -    if (!state) {
   1.392 -        return 1;
   1.393 -    }
   1.394 -    for (i = 1; i < argc;) {
   1.395 -        int consumed;
   1.396 -
   1.397 -        consumed = SDLTest_CommonArg(state, i);
   1.398 -        if (consumed == 0) {
   1.399 -            if (SDL_strcasecmp(argv[i], "--fsaa") == 0) {
   1.400 -                ++fsaa;
   1.401 -                consumed = 1;
   1.402 -            } else if (SDL_strcasecmp(argv[i], "--accel") == 0) {
   1.403 -                ++accel;
   1.404 -                consumed = 1;
   1.405 -            } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) {
   1.406 -                i++;
   1.407 -                if (!argv[i]) {
   1.408 -                    consumed = -1;
   1.409 -                } else {
   1.410 -                    depth = SDL_atoi(argv[i]);
   1.411 -                    consumed = 1;
   1.412 -                }
   1.413 -            } else {
   1.414 -                consumed = -1;
   1.415 -            }
   1.416 -        }
   1.417 -        if (consumed < 0) {
   1.418 -            fprintf(stderr, "Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0],
   1.419 -                    SDLTest_CommonUsage(state));
   1.420 -            quit(1);
   1.421 -        }
   1.422 -        i += consumed;
   1.423 -    }
   1.424 -
   1.425 -    /* Set OpenGL parameters */
   1.426 -    state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
   1.427 -    state->gl_red_size = 5;
   1.428 -    state->gl_green_size = 5;
   1.429 -    state->gl_blue_size = 5;
   1.430 -    state->gl_depth_size = depth;
   1.431 -    state->gl_major_version = 2;
   1.432 -    state->gl_minor_version = 0;
   1.433 -    state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
   1.434 -
   1.435 -    if (fsaa) {
   1.436 -        state->gl_multisamplebuffers=1;
   1.437 -        state->gl_multisamplesamples=fsaa;
   1.438 -    }
   1.439 -    if (accel) {
   1.440 -        state->gl_accelerated=1;
   1.441 -    }
   1.442 -    if (!SDLTest_CommonInit(state)) {
   1.443 -        return;
   1.444 -        quit(2);
   1.445 -    }
   1.446 -
   1.447 -    context = SDL_calloc(state->num_windows, sizeof(context));
   1.448 -    if (context == NULL) {
   1.449 -        fprintf(stderr, "Out of memory!\n");
   1.450 -        quit(2);
   1.451 -    }
   1.452 -    
   1.453 -    /* Create OpenGL ES contexts */
   1.454 -    for (i = 0; i < state->num_windows; i++) {
   1.455 -        context[i] = SDL_GL_CreateContext(state->windows[i]);
   1.456 -        if (!context[i]) {
   1.457 -            fprintf(stderr, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
   1.458 -            quit(2);
   1.459 -        }
   1.460 -    }
   1.461 -
   1.462 -    if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
   1.463 -        SDL_GL_SetSwapInterval(1);
   1.464 -    } else {
   1.465 -        SDL_GL_SetSwapInterval(0);
   1.466 -    }
   1.467 -
   1.468 -    SDL_GetCurrentDisplayMode(0, &mode);
   1.469 -    printf("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format));
   1.470 -    printf("\n");
   1.471 -    printf("Vendor     : %s\n", glGetString(GL_VENDOR));
   1.472 -    printf("Renderer   : %s\n", glGetString(GL_RENDERER));
   1.473 -    printf("Version    : %s\n", glGetString(GL_VERSION));
   1.474 -    printf("Extensions : %s\n", glGetString(GL_EXTENSIONS));
   1.475 -    printf("\n");
   1.476 -
   1.477 -    status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
   1.478 -    if (!status) {
   1.479 -        printf("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
   1.480 -    } else {
   1.481 -        fprintf(stderr, "Failed to get SDL_GL_RED_SIZE: %s\n",
   1.482 -                SDL_GetError());
   1.483 -    }
   1.484 -    status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
   1.485 -    if (!status) {
   1.486 -        printf("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
   1.487 -    } else {
   1.488 -        fprintf(stderr, "Failed to get SDL_GL_GREEN_SIZE: %s\n",
   1.489 -                SDL_GetError());
   1.490 -    }
   1.491 -    status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
   1.492 -    if (!status) {
   1.493 -        printf("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
   1.494 -    } else {
   1.495 -        fprintf(stderr, "Failed to get SDL_GL_BLUE_SIZE: %s\n",
   1.496 -                SDL_GetError());
   1.497 -    }
   1.498 -    status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
   1.499 -    if (!status) {
   1.500 -        printf("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value);
   1.501 -    } else {
   1.502 -        fprintf(stderr, "Failed to get SDL_GL_DEPTH_SIZE: %s\n",
   1.503 -                SDL_GetError());
   1.504 -    }
   1.505 -    if (fsaa) {
   1.506 -        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
   1.507 -        if (!status) {
   1.508 -            printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
   1.509 -        } else {
   1.510 -            fprintf(stderr, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
   1.511 -                    SDL_GetError());
   1.512 -        }
   1.513 -        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
   1.514 -        if (!status) {
   1.515 -            printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
   1.516 -                   value);
   1.517 -        } else {
   1.518 -            fprintf(stderr, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
   1.519 -                    SDL_GetError());
   1.520 -        }
   1.521 -    }
   1.522 -    if (accel) {
   1.523 -        status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
   1.524 -        if (!status) {
   1.525 -            printf("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
   1.526 -        } else {
   1.527 -            fprintf(stderr, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
   1.528 -                    SDL_GetError());
   1.529 -        }
   1.530 -    }
   1.531 -
   1.532 -    datas = SDL_calloc(state->num_windows, sizeof(shader_data));
   1.533 -
   1.534 -    /* Set rendering settings for each context */
   1.535 -    for (i = 0; i < state->num_windows; ++i) {
   1.536 -
   1.537 -        status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
   1.538 -        if (status) {
   1.539 -            printf("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
   1.540 -
   1.541 -            /* Continue for next window */
   1.542 -            continue;
   1.543 -        }
   1.544 -        glViewport(0, 0, state->window_w, state->window_h);
   1.545 -
   1.546 -        data = &datas[i];
   1.547 -        data->angle_x = 0; data->angle_y = 0; data->angle_z = 0;
   1.548 -
   1.549 -        /* Shader Initialization */
   1.550 -        process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER);
   1.551 -        process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER);
   1.552 -
   1.553 -        /* Create shader_program (ready to attach shaders) */
   1.554 -        data->shader_program = GL_CHECK(glCreateProgram());
   1.555 -
   1.556 -        /* Attach shaders and link shader_program */
   1.557 -        GL_CHECK(glAttachShader(data->shader_program, data->shader_vert));
   1.558 -        GL_CHECK(glAttachShader(data->shader_program, data->shader_frag));
   1.559 -        GL_CHECK(glLinkProgram(data->shader_program));
   1.560 -
   1.561 -        /* Get attribute locations of non-fixed attributes like color and texture coordinates. */
   1.562 -        data->attr_position = GL_CHECK(glGetAttribLocation(data->shader_program, "av4position"));
   1.563 -        data->attr_color = GL_CHECK(glGetAttribLocation(data->shader_program, "av3color"));
   1.564 -
   1.565 -        /* Get uniform locations */
   1.566 -        data->attr_mvp = GL_CHECK(glGetUniformLocation(data->shader_program, "mvp"));
   1.567 -
   1.568 -        GL_CHECK(glUseProgram(data->shader_program));
   1.569 -
   1.570 -        /* Enable attributes for position, color and texture coordinates etc. */
   1.571 -        GL_CHECK(glEnableVertexAttribArray(data->attr_position));
   1.572 -        GL_CHECK(glEnableVertexAttribArray(data->attr_color));
   1.573 -
   1.574 -        /* Populate attributes for position, color and texture coordinates etc. */
   1.575 -        GL_CHECK(glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices));
   1.576 -        GL_CHECK(glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors));
   1.577 -
   1.578 -        GL_CHECK(glEnable(GL_CULL_FACE));
   1.579 -        GL_CHECK(glEnable(GL_DEPTH_TEST));
   1.580 -    }
   1.581 -
   1.582 -    /* Main render loop */
   1.583 -    frames = 0;
   1.584 -    then = SDL_GetTicks();
   1.585 -    done = 0;
   1.586 -    while (!done) {
   1.587 -        /* Check for events */
   1.588 -        ++frames;
   1.589 -        while (SDL_PollEvent(&event)) {
   1.590 -            switch (event.type) {
   1.591 -            case SDL_WINDOWEVENT:
   1.592 -                switch (event.window.event) {
   1.593 -                    case SDL_WINDOWEVENT_RESIZED:
   1.594 -                        for (i = 0; i < state->num_windows; ++i) {
   1.595 -                            if (event.window.windowID == SDL_GetWindowID(state->windows[i])) {
   1.596 -                                status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
   1.597 -                                if (status) {
   1.598 -                                    printf("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
   1.599 -                                    break;
   1.600 -                                }
   1.601 -                                /* Change view port to the new window dimensions */
   1.602 -                                glViewport(0, 0, event.window.data1, event.window.data2);
   1.603 -                                /* Update window content */
   1.604 -                                Render(event.window.data1, event.window.data2, &datas[i]);
   1.605 -                                SDL_GL_SwapWindow(state->windows[i]);
   1.606 -                                break;
   1.607 -                            }
   1.608 -                        }
   1.609 -                        break;
   1.610 -                }
   1.611 -            }
   1.612 -            SDLTest_CommonEvent(state, &event, &done);
   1.613 -        }
   1.614 -        for (i = 0; i < state->num_windows; ++i) {
   1.615 -            status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
   1.616 -            if (status) {
   1.617 -                printf("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
   1.618 -
   1.619 -                /* Continue for next window */
   1.620 -                continue;
   1.621 -            }
   1.622 -            Render(state->window_w, state->window_h, &datas[i]);
   1.623 -            SDL_GL_SwapWindow(state->windows[i]);
   1.624 -        }
   1.625 -    }
   1.626 -
   1.627 -    /* Print out some timing information */
   1.628 -    now = SDL_GetTicks();
   1.629 -    if (now > then) {
   1.630 -        printf("%2.2f frames per second\n",
   1.631 -               ((double) frames * 1000) / (now - then));
   1.632 -    }
   1.633 -#if !defined(__ANDROID__)    
   1.634 -    quit(0);
   1.635 -#endif    
   1.636 -    return 0;
   1.637 -}
   1.638 -
   1.639 -#else /* HAVE_OPENGLES2 */
   1.640 -
   1.641 -int
   1.642 -main(int argc, char *argv[])
   1.643 -{
   1.644 -    printf("No OpenGL ES support on this system\n");
   1.645 -    return 1;
   1.646 -}
   1.647 -
   1.648 -#endif /* HAVE_OPENGLES2 */
   1.649 -
   1.650 -/* vi: set ts=4 sw=4 expandtab: */
   1.651 +/*
   1.652 +  Copyright (r) 1997-2011 Sam Lantinga <slouken@libsdl.org>
   1.653 +
   1.654 +  This software is provided 'as-is', without any express or implied
   1.655 +  warranty.  In no event will the authors be held liable for any damages
   1.656 +  arising from the use of this software.
   1.657 +
   1.658 +  Permission is granted to anyone to use this software for any purpose,
   1.659 +  including commercial applications, and to alter it and redistribute it
   1.660 +  freely.
   1.661 +*/
   1.662 +#include <stdlib.h>
   1.663 +#include <stdio.h>
   1.664 +#include <string.h>
   1.665 +#include <math.h>
   1.666 +
   1.667 +#include "SDL_test_common.h"
   1.668 +
   1.669 +#if defined(__IPHONEOS__) || defined(__ANDROID__)
   1.670 +#define HAVE_OPENGLES2
   1.671 +#endif
   1.672 +
   1.673 +#ifdef HAVE_OPENGLES2
   1.674 +
   1.675 +#include "SDL_opengles2.h"
   1.676 +
   1.677 +typedef struct GLES2_Context
   1.678 +{
   1.679 +#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
   1.680 +#include "../src/render/opengles2/SDL_gles2funcs.h"
   1.681 +#undef SDL_PROC
   1.682 +} GLES2_Context;
   1.683 +
   1.684 +
   1.685 +static SDLTest_CommonState *state;
   1.686 +static SDL_GLContext *context = NULL;
   1.687 +static int depth = 16;
   1.688 +static GLES2_Context ctx;
   1.689 +
   1.690 +static int LoadContext(GLES2_Context * data)
   1.691 +{
   1.692 +#if SDL_VIDEO_DRIVER_UIKIT
   1.693 +#define __SDL_NOGETPROCADDR__
   1.694 +#elif SDL_VIDEO_DRIVER_ANDROID
   1.695 +#define __SDL_NOGETPROCADDR__
   1.696 +#elif SDL_VIDEO_DRIVER_PANDORA
   1.697 +#define __SDL_NOGETPROCADDR__
   1.698 +#endif
   1.699 +
   1.700 +#if defined __SDL_NOGETPROCADDR__
   1.701 +#define SDL_PROC(ret,func,params) data->func=func;
   1.702 +#else
   1.703 +#define SDL_PROC(ret,func,params) \
   1.704 +    do { \
   1.705 +        data->func = SDL_GL_GetProcAddress(#func); \
   1.706 +        if ( ! data->func ) { \
   1.707 +            return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
   1.708 +        } \
   1.709 +    } while ( 0 );
   1.710 +#endif /* _SDL_NOGETPROCADDR_ */
   1.711 +
   1.712 +#include "../src/render/opengles2/SDL_gles2funcs.h"
   1.713 +#undef SDL_PROC
   1.714 +    return 0;
   1.715 +}
   1.716 +
   1.717 +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
   1.718 +static void
   1.719 +quit(int rc)
   1.720 +{
   1.721 +    int i;
   1.722 +
   1.723 +    if (context != NULL) {
   1.724 +        for (i = 0; i < state->num_windows; i++) {
   1.725 +            if (context[i]) {
   1.726 +                SDL_GL_DeleteContext(context[i]);
   1.727 +            }
   1.728 +        }
   1.729 +
   1.730 +        SDL_free(context);
   1.731 +    }
   1.732 +
   1.733 +    SDLTest_CommonQuit(state);
   1.734 +    exit(rc);
   1.735 +}
   1.736 +
   1.737 +#define GL_CHECK(x) \
   1.738 +        x; \
   1.739 +        { \
   1.740 +          GLenum glError = ctx.glGetError(); \
   1.741 +          if(glError != GL_NO_ERROR) { \
   1.742 +            SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \
   1.743 +            quit(1); \
   1.744 +          } \
   1.745 +        }
   1.746 +
   1.747 +/* 
   1.748 + * Simulates desktop's glRotatef. The matrix is returned in column-major 
   1.749 + * order. 
   1.750 + */
   1.751 +static void
   1.752 +rotate_matrix(double angle, double x, double y, double z, float *r)
   1.753 +{
   1.754 +    double radians, c, s, c1, u[3], length;
   1.755 +    int i, j;
   1.756 +
   1.757 +    radians = (angle * M_PI) / 180.0;
   1.758 +
   1.759 +    c = cos(radians);
   1.760 +    s = sin(radians);
   1.761 +
   1.762 +    c1 = 1.0 - cos(radians);
   1.763 +
   1.764 +    length = sqrt(x * x + y * y + z * z);
   1.765 +
   1.766 +    u[0] = x / length;
   1.767 +    u[1] = y / length;
   1.768 +    u[2] = z / length;
   1.769 +
   1.770 +    for (i = 0; i < 16; i++) {
   1.771 +        r[i] = 0.0;
   1.772 +    }
   1.773 +
   1.774 +    r[15] = 1.0;
   1.775 +
   1.776 +    for (i = 0; i < 3; i++) {
   1.777 +        r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s;
   1.778 +        r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s;
   1.779 +    }
   1.780 +
   1.781 +    for (i = 0; i < 3; i++) {
   1.782 +        for (j = 0; j < 3; j++) {
   1.783 +            r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0);
   1.784 +        }
   1.785 +    }
   1.786 +}
   1.787 +
   1.788 +/* 
   1.789 + * Simulates gluPerspectiveMatrix 
   1.790 + */
   1.791 +static void 
   1.792 +perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r)
   1.793 +{
   1.794 +    int i;
   1.795 +    double f;
   1.796 +
   1.797 +    f = 1.0/tan(fovy * 0.5);
   1.798 +
   1.799 +    for (i = 0; i < 16; i++) {
   1.800 +        r[i] = 0.0;
   1.801 +    }
   1.802 +
   1.803 +    r[0] = f / aspect;
   1.804 +    r[5] = f;
   1.805 +    r[10] = (znear + zfar) / (znear - zfar);
   1.806 +    r[11] = -1.0;
   1.807 +    r[14] = (2.0 * znear * zfar) / (znear - zfar);
   1.808 +    r[15] = 0.0;
   1.809 +}
   1.810 +
   1.811 +/* 
   1.812 + * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column
   1.813 + * major. In-place multiplication is supported.
   1.814 + */
   1.815 +static void
   1.816 +multiply_matrix(float *lhs, float *rhs, float *r)
   1.817 +{
   1.818 +	int i, j, k;
   1.819 +    float tmp[16];
   1.820 +
   1.821 +    for (i = 0; i < 4; i++) {
   1.822 +        for (j = 0; j < 4; j++) {
   1.823 +            tmp[j * 4 + i] = 0.0;
   1.824 +
   1.825 +            for (k = 0; k < 4; k++) {
   1.826 +                tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k];
   1.827 +            }
   1.828 +        }
   1.829 +    }
   1.830 +
   1.831 +    for (i = 0; i < 16; i++) {
   1.832 +        r[i] = tmp[i];
   1.833 +    }
   1.834 +}
   1.835 +
   1.836 +/* 
   1.837 + * Create shader, load in source, compile, dump debug as necessary.
   1.838 + *
   1.839 + * shader: Pointer to return created shader ID.
   1.840 + * source: Passed-in shader source code.
   1.841 + * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER.
   1.842 + */
   1.843 +void 
   1.844 +process_shader(GLuint *shader, const char * source, GLint shader_type)
   1.845 +{
   1.846 +    GLint status = GL_FALSE;
   1.847 +    const char *shaders[1] = { NULL };
   1.848 +
   1.849 +    /* Create shader and load into GL. */
   1.850 +    *shader = GL_CHECK(ctx.glCreateShader(shader_type));
   1.851 +
   1.852 +    shaders[0] = source;
   1.853 +
   1.854 +    GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL));
   1.855 +
   1.856 +    /* Clean up shader source. */
   1.857 +    shaders[0] = NULL;
   1.858 +
   1.859 +    /* Try compiling the shader. */
   1.860 +    GL_CHECK(ctx.glCompileShader(*shader));
   1.861 +    GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status));
   1.862 +
   1.863 +    // Dump debug info (source and log) if compilation failed.
   1.864 +    if(status != GL_TRUE) {
   1.865 +        SDL_Log("Shader compilation failed");
   1.866 +        quit(-1);
   1.867 +    }
   1.868 +}
   1.869 +
   1.870 +/* 3D data. Vertex range -0.5..0.5 in all axes.
   1.871 +* Z -0.5 is near, 0.5 is far. */
   1.872 +const float _vertices[] =
   1.873 +{
   1.874 +    /* Front face. */
   1.875 +    /* Bottom left */
   1.876 +    -0.5,  0.5, -0.5,
   1.877 +    0.5, -0.5, -0.5,
   1.878 +    -0.5, -0.5, -0.5,
   1.879 +    /* Top right */
   1.880 +    -0.5,  0.5, -0.5,
   1.881 +    0.5,  0.5, -0.5,
   1.882 +    0.5, -0.5, -0.5,
   1.883 +    /* Left face */
   1.884 +    /* Bottom left */
   1.885 +    -0.5,  0.5,  0.5,
   1.886 +    -0.5, -0.5, -0.5,
   1.887 +    -0.5, -0.5,  0.5,
   1.888 +    /* Top right */
   1.889 +    -0.5,  0.5,  0.5,
   1.890 +    -0.5,  0.5, -0.5,
   1.891 +    -0.5, -0.5, -0.5,
   1.892 +    /* Top face */
   1.893 +    /* Bottom left */
   1.894 +    -0.5,  0.5,  0.5,
   1.895 +    0.5,  0.5, -0.5,
   1.896 +    -0.5,  0.5, -0.5,
   1.897 +    /* Top right */
   1.898 +    -0.5,  0.5,  0.5,
   1.899 +    0.5,  0.5,  0.5,
   1.900 +    0.5,  0.5, -0.5,
   1.901 +    /* Right face */
   1.902 +    /* Bottom left */
   1.903 +    0.5,  0.5, -0.5,
   1.904 +    0.5, -0.5,  0.5,
   1.905 +    0.5, -0.5, -0.5,
   1.906 +    /* Top right */
   1.907 +    0.5,  0.5, -0.5,
   1.908 +    0.5,  0.5,  0.5,
   1.909 +    0.5, -0.5,  0.5,
   1.910 +    /* Back face */
   1.911 +    /* Bottom left */
   1.912 +    0.5,  0.5,  0.5,
   1.913 +    -0.5, -0.5,  0.5,
   1.914 +    0.5, -0.5,  0.5,
   1.915 +    /* Top right */
   1.916 +    0.5,  0.5,  0.5,
   1.917 +    -0.5,  0.5,  0.5,
   1.918 +    -0.5, -0.5,  0.5,
   1.919 +    /* Bottom face */
   1.920 +    /* Bottom left */
   1.921 +    -0.5, -0.5, -0.5,
   1.922 +    0.5, -0.5,  0.5,
   1.923 +    -0.5, -0.5,  0.5,
   1.924 +    /* Top right */
   1.925 +    -0.5, -0.5, -0.5,
   1.926 +    0.5, -0.5, -0.5,
   1.927 +    0.5, -0.5,  0.5,
   1.928 +};
   1.929 +
   1.930 +const float _colors[] =
   1.931 +{
   1.932 +    /* Front face */
   1.933 +    /* Bottom left */
   1.934 +    1.0, 0.0, 0.0, /* red */
   1.935 +    0.0, 0.0, 1.0, /* blue */
   1.936 +    0.0, 1.0, 0.0, /* green */
   1.937 +    /* Top right */
   1.938 +    1.0, 0.0, 0.0, /* red */
   1.939 +    1.0, 1.0, 0.0, /* yellow */
   1.940 +    0.0, 0.0, 1.0, /* blue */
   1.941 +    /* Left face */
   1.942 +    /* Bottom left */
   1.943 +    1.0, 1.0, 1.0, /* white */
   1.944 +    0.0, 1.0, 0.0, /* green */
   1.945 +    0.0, 1.0, 1.0, /* cyan */
   1.946 +    /* Top right */
   1.947 +    1.0, 1.0, 1.0, /* white */
   1.948 +    1.0, 0.0, 0.0, /* red */
   1.949 +    0.0, 1.0, 0.0, /* green */
   1.950 +    /* Top face */
   1.951 +    /* Bottom left */
   1.952 +    1.0, 1.0, 1.0, /* white */
   1.953 +    1.0, 1.0, 0.0, /* yellow */
   1.954 +    1.0, 0.0, 0.0, /* red */
   1.955 +    /* Top right */
   1.956 +    1.0, 1.0, 1.0, /* white */
   1.957 +    0.0, 0.0, 0.0, /* black */
   1.958 +    1.0, 1.0, 0.0, /* yellow */
   1.959 +    /* Right face */
   1.960 +    /* Bottom left */
   1.961 +    1.0, 1.0, 0.0, /* yellow */
   1.962 +    1.0, 0.0, 1.0, /* magenta */
   1.963 +    0.0, 0.0, 1.0, /* blue */
   1.964 +    /* Top right */
   1.965 +    1.0, 1.0, 0.0, /* yellow */
   1.966 +    0.0, 0.0, 0.0, /* black */
   1.967 +    1.0, 0.0, 1.0, /* magenta */
   1.968 +    /* Back face */
   1.969 +    /* Bottom left */
   1.970 +    0.0, 0.0, 0.0, /* black */
   1.971 +    0.0, 1.0, 1.0, /* cyan */
   1.972 +    1.0, 0.0, 1.0, /* magenta */
   1.973 +    /* Top right */
   1.974 +    0.0, 0.0, 0.0, /* black */
   1.975 +    1.0, 1.0, 1.0, /* white */
   1.976 +    0.0, 1.0, 1.0, /* cyan */
   1.977 +    /* Bottom face */
   1.978 +    /* Bottom left */
   1.979 +    0.0, 1.0, 0.0, /* green */
   1.980 +    1.0, 0.0, 1.0, /* magenta */
   1.981 +    0.0, 1.0, 1.0, /* cyan */
   1.982 +    /* Top right */
   1.983 +    0.0, 1.0, 0.0, /* green */
   1.984 +    0.0, 0.0, 1.0, /* blue */
   1.985 +    1.0, 0.0, 1.0, /* magenta */
   1.986 +};
   1.987 +
   1.988 +const char* _shader_vert_src = 
   1.989 +" attribute vec4 av4position; "
   1.990 +" attribute vec3 av3color; "
   1.991 +" uniform mat4 mvp; "
   1.992 +" varying vec3 vv3color; "
   1.993 +" void main() { "
   1.994 +"    vv3color = av3color; "
   1.995 +"    gl_Position = mvp * av4position; "
   1.996 +" } ";
   1.997 +
   1.998 +const char* _shader_frag_src = 
   1.999 +" precision lowp float; "
  1.1000 +" varying vec3 vv3color; "
  1.1001 +" void main() { "
  1.1002 +"    gl_FragColor = vec4(vv3color, 1.0); "
  1.1003 +" } ";
  1.1004 +
  1.1005 +typedef struct shader_data
  1.1006 +{
  1.1007 +    GLuint shader_program, shader_frag, shader_vert;
  1.1008 +
  1.1009 +    GLint attr_position;
  1.1010 +    GLint attr_color, attr_mvp;
  1.1011 +
  1.1012 +    int angle_x, angle_y, angle_z;
  1.1013 +
  1.1014 +} shader_data;
  1.1015 +
  1.1016 +static void
  1.1017 +Render(unsigned int width, unsigned int height, shader_data* data)
  1.1018 +{
  1.1019 +    float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16];
  1.1020 +
  1.1021 +    /* 
  1.1022 +    * Do some rotation with Euler angles. It is not a fixed axis as
  1.1023 +    * quaterions would be, but the effect is cool. 
  1.1024 +    */
  1.1025 +    rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview);
  1.1026 +    rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate);
  1.1027 +
  1.1028 +    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
  1.1029 +
  1.1030 +    rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate);
  1.1031 +
  1.1032 +    multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview);
  1.1033 +
  1.1034 +    /* Pull the camera back from the cube */
  1.1035 +    matrix_modelview[14] -= 2.5;
  1.1036 +
  1.1037 +    perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective);
  1.1038 +    multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp);
  1.1039 +
  1.1040 +    GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp));
  1.1041 +
  1.1042 +    data->angle_x += 3;
  1.1043 +    data->angle_y += 2;
  1.1044 +    data->angle_z += 1;
  1.1045 +
  1.1046 +    if(data->angle_x >= 360) data->angle_x -= 360;
  1.1047 +    if(data->angle_x < 0) data->angle_x += 360;
  1.1048 +    if(data->angle_y >= 360) data->angle_y -= 360;
  1.1049 +    if(data->angle_y < 0) data->angle_y += 360;
  1.1050 +    if(data->angle_z >= 360) data->angle_z -= 360;
  1.1051 +    if(data->angle_z < 0) data->angle_z += 360;
  1.1052 +
  1.1053 +    GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
  1.1054 +    GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36));
  1.1055 +}
  1.1056 +
  1.1057 +int
  1.1058 +main(int argc, char *argv[])
  1.1059 +{
  1.1060 +    int fsaa, accel;
  1.1061 +    int value;
  1.1062 +    int i, done;
  1.1063 +    SDL_DisplayMode mode;
  1.1064 +    SDL_Event event;
  1.1065 +    Uint32 then, now, frames;
  1.1066 +    int status;
  1.1067 +    shader_data *datas, *data;
  1.1068 +
  1.1069 +    /* Initialize parameters */
  1.1070 +    fsaa = 0;
  1.1071 +    accel = 0;
  1.1072 +
  1.1073 +    /* Initialize test framework */
  1.1074 +    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
  1.1075 +    if (!state) {
  1.1076 +        return 1;
  1.1077 +    }
  1.1078 +    for (i = 1; i < argc;) {
  1.1079 +        int consumed;
  1.1080 +
  1.1081 +        consumed = SDLTest_CommonArg(state, i);
  1.1082 +        if (consumed == 0) {
  1.1083 +            if (SDL_strcasecmp(argv[i], "--fsaa") == 0) {
  1.1084 +                ++fsaa;
  1.1085 +                consumed = 1;
  1.1086 +            } else if (SDL_strcasecmp(argv[i], "--accel") == 0) {
  1.1087 +                ++accel;
  1.1088 +                consumed = 1;
  1.1089 +            } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) {
  1.1090 +                i++;
  1.1091 +                if (!argv[i]) {
  1.1092 +                    consumed = -1;
  1.1093 +                } else {
  1.1094 +                    depth = SDL_atoi(argv[i]);
  1.1095 +                    consumed = 1;
  1.1096 +                }
  1.1097 +            } else {
  1.1098 +                consumed = -1;
  1.1099 +            }
  1.1100 +        }
  1.1101 +        if (consumed < 0) {
  1.1102 +            SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0],
  1.1103 +                    SDLTest_CommonUsage(state));
  1.1104 +            quit(1);
  1.1105 +        }
  1.1106 +        i += consumed;
  1.1107 +    }
  1.1108 +
  1.1109 +    /* Set OpenGL parameters */
  1.1110 +    state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
  1.1111 +    state->gl_red_size = 5;
  1.1112 +    state->gl_green_size = 5;
  1.1113 +    state->gl_blue_size = 5;
  1.1114 +    state->gl_depth_size = depth;
  1.1115 +    state->gl_major_version = 2;
  1.1116 +    state->gl_minor_version = 0;
  1.1117 +    state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
  1.1118 +
  1.1119 +    if (fsaa) {
  1.1120 +        state->gl_multisamplebuffers=1;
  1.1121 +        state->gl_multisamplesamples=fsaa;
  1.1122 +    }
  1.1123 +    if (accel) {
  1.1124 +        state->gl_accelerated=1;
  1.1125 +    }
  1.1126 +    if (!SDLTest_CommonInit(state)) {
  1.1127 +        quit(2);
  1.1128 +        return 0;
  1.1129 +    }
  1.1130 +
  1.1131 +    context = SDL_calloc(state->num_windows, sizeof(context));
  1.1132 +    if (context == NULL) {
  1.1133 +        SDL_Log("Out of memory!\n");
  1.1134 +        quit(2);
  1.1135 +    }
  1.1136 +    
  1.1137 +    /* Create OpenGL ES contexts */
  1.1138 +    for (i = 0; i < state->num_windows; i++) {
  1.1139 +        context[i] = SDL_GL_CreateContext(state->windows[i]);
  1.1140 +        if (!context[i]) {
  1.1141 +            SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError());
  1.1142 +            quit(2);
  1.1143 +        }
  1.1144 +    }
  1.1145 +
  1.1146 +    /* Important: call this *after* creating the context */
  1.1147 +    if (LoadContext(&ctx) < 0) {
  1.1148 +        SDL_Log("Could not load GLES2 functions\n");
  1.1149 +        quit(2);
  1.1150 +        return 0;
  1.1151 +    }
  1.1152 +
  1.1153 +
  1.1154 +
  1.1155 +    if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
  1.1156 +        SDL_GL_SetSwapInterval(1);
  1.1157 +    } else {
  1.1158 +        SDL_GL_SetSwapInterval(0);
  1.1159 +    }
  1.1160 +
  1.1161 +    SDL_GetCurrentDisplayMode(0, &mode);
  1.1162 +    SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format));
  1.1163 +    SDL_Log("\n");
  1.1164 +    SDL_Log("Vendor     : %s\n", ctx.glGetString(GL_VENDOR));
  1.1165 +    SDL_Log("Renderer   : %s\n", ctx.glGetString(GL_RENDERER));
  1.1166 +    SDL_Log("Version    : %s\n", ctx.glGetString(GL_VERSION));
  1.1167 +    SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS));
  1.1168 +    SDL_Log("\n");
  1.1169 +
  1.1170 +    status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
  1.1171 +    if (!status) {
  1.1172 +        SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
  1.1173 +    } else {
  1.1174 +        SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n",
  1.1175 +                SDL_GetError());
  1.1176 +    }
  1.1177 +    status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
  1.1178 +    if (!status) {
  1.1179 +        SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
  1.1180 +    } else {
  1.1181 +        SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n",
  1.1182 +                SDL_GetError());
  1.1183 +    }
  1.1184 +    status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
  1.1185 +    if (!status) {
  1.1186 +        SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
  1.1187 +    } else {
  1.1188 +        SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n",
  1.1189 +                SDL_GetError());
  1.1190 +    }
  1.1191 +    status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
  1.1192 +    if (!status) {
  1.1193 +        SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value);
  1.1194 +    } else {
  1.1195 +        SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n",
  1.1196 +                SDL_GetError());
  1.1197 +    }
  1.1198 +    if (fsaa) {
  1.1199 +        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
  1.1200 +        if (!status) {
  1.1201 +            SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
  1.1202 +        } else {
  1.1203 +            SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
  1.1204 +                    SDL_GetError());
  1.1205 +        }
  1.1206 +        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
  1.1207 +        if (!status) {
  1.1208 +            SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
  1.1209 +                   value);
  1.1210 +        } else {
  1.1211 +            SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
  1.1212 +                    SDL_GetError());
  1.1213 +        }
  1.1214 +    }
  1.1215 +    if (accel) {
  1.1216 +        status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
  1.1217 +        if (!status) {
  1.1218 +            SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
  1.1219 +        } else {
  1.1220 +            SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
  1.1221 +                    SDL_GetError());
  1.1222 +        }
  1.1223 +    }
  1.1224 +
  1.1225 +    datas = SDL_calloc(state->num_windows, sizeof(shader_data));
  1.1226 +
  1.1227 +    /* Set rendering settings for each context */
  1.1228 +    for (i = 0; i < state->num_windows; ++i) {
  1.1229 +
  1.1230 +        status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
  1.1231 +        if (status) {
  1.1232 +            SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
  1.1233 +
  1.1234 +            /* Continue for next window */
  1.1235 +            continue;
  1.1236 +        }
  1.1237 +        ctx.glViewport(0, 0, state->window_w, state->window_h);
  1.1238 +
  1.1239 +        data = &datas[i];
  1.1240 +        data->angle_x = 0; data->angle_y = 0; data->angle_z = 0;
  1.1241 +
  1.1242 +        /* Shader Initialization */
  1.1243 +        process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER);
  1.1244 +        process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER);
  1.1245 +
  1.1246 +        /* Create shader_program (ready to attach shaders) */
  1.1247 +        data->shader_program = GL_CHECK(ctx.glCreateProgram());
  1.1248 +
  1.1249 +        /* Attach shaders and link shader_program */
  1.1250 +        GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert));
  1.1251 +        GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag));
  1.1252 +        GL_CHECK(ctx.glLinkProgram(data->shader_program));
  1.1253 +
  1.1254 +        /* Get attribute locations of non-fixed attributes like color and texture coordinates. */
  1.1255 +        data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position"));
  1.1256 +        data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color"));
  1.1257 +
  1.1258 +        /* Get uniform locations */
  1.1259 +        data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp"));
  1.1260 +
  1.1261 +        GL_CHECK(ctx.glUseProgram(data->shader_program));
  1.1262 +
  1.1263 +        /* Enable attributes for position, color and texture coordinates etc. */
  1.1264 +        GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position));
  1.1265 +        GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color));
  1.1266 +
  1.1267 +        /* Populate attributes for position, color and texture coordinates etc. */
  1.1268 +        GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices));
  1.1269 +        GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors));
  1.1270 +
  1.1271 +        GL_CHECK(ctx.glEnable(GL_CULL_FACE));
  1.1272 +        GL_CHECK(ctx.glEnable(GL_DEPTH_TEST));
  1.1273 +    }
  1.1274 +
  1.1275 +    /* Main render loop */
  1.1276 +    frames = 0;
  1.1277 +    then = SDL_GetTicks();
  1.1278 +    done = 0;
  1.1279 +    while (!done) {
  1.1280 +        /* Check for events */
  1.1281 +        ++frames;
  1.1282 +        while (SDL_PollEvent(&event)) {
  1.1283 +            switch (event.type) {
  1.1284 +            case SDL_WINDOWEVENT:
  1.1285 +                switch (event.window.event) {
  1.1286 +                    case SDL_WINDOWEVENT_RESIZED:
  1.1287 +                        for (i = 0; i < state->num_windows; ++i) {
  1.1288 +                            if (event.window.windowID == SDL_GetWindowID(state->windows[i])) {
  1.1289 +                                status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
  1.1290 +                                if (status) {
  1.1291 +                                    SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
  1.1292 +                                    break;
  1.1293 +                                }
  1.1294 +                                /* Change view port to the new window dimensions */
  1.1295 +                                ctx.glViewport(0, 0, event.window.data1, event.window.data2);
  1.1296 +                                /* Update window content */
  1.1297 +                                Render(event.window.data1, event.window.data2, &datas[i]);
  1.1298 +                                SDL_GL_SwapWindow(state->windows[i]);
  1.1299 +                                break;
  1.1300 +                            }
  1.1301 +                        }
  1.1302 +                        break;
  1.1303 +                }
  1.1304 +            }
  1.1305 +            SDLTest_CommonEvent(state, &event, &done);
  1.1306 +        }
  1.1307 +        for (i = 0; i < state->num_windows; ++i) {
  1.1308 +            status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
  1.1309 +            if (status) {
  1.1310 +                SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
  1.1311 +
  1.1312 +                /* Continue for next window */
  1.1313 +                continue;
  1.1314 +            }
  1.1315 +            Render(state->window_w, state->window_h, &datas[i]);
  1.1316 +            SDL_GL_SwapWindow(state->windows[i]);
  1.1317 +        }
  1.1318 +    }
  1.1319 +
  1.1320 +    /* Print out some timing information */
  1.1321 +    now = SDL_GetTicks();
  1.1322 +    if (now > then) {
  1.1323 +        SDL_Log("%2.2f frames per second\n",
  1.1324 +               ((double) frames * 1000) / (now - then));
  1.1325 +    }
  1.1326 +#if !defined(__ANDROID__)    
  1.1327 +    quit(0);
  1.1328 +    return 0;
  1.1329 +#endif    
  1.1330 +    return 0;
  1.1331 +}
  1.1332 +
  1.1333 +#else /* HAVE_OPENGLES2 */
  1.1334 +
  1.1335 +int
  1.1336 +main(int argc, char *argv[])
  1.1337 +{
  1.1338 +    SDL_Log("No OpenGL ES support on this system\n");
  1.1339 +    return 1;
  1.1340 +}
  1.1341 +
  1.1342 +#endif /* HAVE_OPENGLES2 */
  1.1343 +
  1.1344 +/* vi: set ts=4 sw=4 expandtab: */