/* Copyright (C) 2012-2014 Andreas Schiffler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely. */ #include #include #include #include #include #include "SDL_test_common.h" #include "SDL2_gfxPrimitives.h" static SDLTest_CommonState *state; /* Screen size */ #define WIDTH DEFAULT_WINDOW_WIDTH #define HEIGHT DEFAULT_WINDOW_HEIGHT /* viewport border */ #define BORDER 10 #define NUM_RANDOM 4096 /* Coordinates */ static Sint16 rx[NUM_RANDOM], rx[NUM_RANDOM], ry[NUM_RANDOM], ry[NUM_RANDOM]; /* Triangles */ static Sint16 tx1[NUM_RANDOM][3], tx1[NUM_RANDOM][3], ty1[NUM_RANDOM][3], ty1[NUM_RANDOM][3]; /* Squares (made of 2 triangles) */ static Sint16 sx1[NUM_RANDOM][6], sx1[NUM_RANDOM][6], sy1[NUM_RANDOM][6], sy1[NUM_RANDOM][6]; /* Line widths */ static Uint8 lw[NUM_RANDOM]; /* Radii and offsets */ static Sint16 rr1[NUM_RANDOM], rr2[NUM_RANDOM]; /* Start and stop angles */ static Sint16 a1[NUM_RANDOM], a2[NUM_RANDOM]; /* RGB colors and alpha */ static char rr[NUM_RANDOM], rg[NUM_RANDOM], rb[NUM_RANDOM], ra[NUM_RANDOM]; /*! \brief Generate an array of random screen coordinates, radii and RGBA values with an offset for drawing tests. \param seed The seed for random number generation. If negative, uses current time as seed. */ void InitRandomPoints(int seed) { int i; float af; /* Initialize random number generator */ if (seed < 0) { srand((unsigned int)time(NULL)); } else { srand((unsigned int)seed); } for (i=0; i then) { double fps = ((double) numPrimitives * 1000) / (now - then); SDL_snprintf(titletext, TLEN, "Test %2i %20s: %10.1f /sec", testNum, testName, fps); textlength = (Sint16)strlen(titletext); stringRGBA (renderer, WIDTH/2-4*textlength,30-4,titletext,255,255,255,255); SDL_Log(titletext); } } /* --------------------- Tests ------------------------ */ int TestPixel(SDL_Renderer *renderer) { int i; char r,g,b; int step = 1; /* Draw A=255 */ SetViewport(renderer,0,60,WIDTH/2,60+(HEIGHT-80)/2); for (i=0; iw, picture->h, 32, rmask, gmask, bmask, amask); if (picture_again == NULL) { SDL_FreeSurface(picture); return -1; } /* Draw A=255 */ SetViewport(renderer,0,60,WIDTH/2,60+(HEIGHT-80)/2); for (i=0; iformat, 255, 0, 0)); } else if (rx[i] < (WIDTH/3) ) { SDL_FillRect(picture_again, NULL, SDL_MapRGB(picture_again->format, 0, 255, 0)); } else { SDL_FillRect(picture_again, NULL, SDL_MapRGB(picture_again->format, 0, 0, 255)); } texturedPolygon(renderer, &rx[i], &ry[i], 3, picture_again, 0, 0); } /* Clear viewport */ ClearViewport(renderer); /* Accuracy test */ ClearCenter(renderer, "3pt T poly"); rx[0] = WIDTH/2; ry[0] = HEIGHT/2; rx[1] = rx[0] + 5; ry[1] = ry[0] + 5; rx[2] = rx[0] + 10; ry[2] = ry[0] - 5; texturedPolygon(renderer, rx, ry, 3, picture_again, 0, 0); SDL_FreeSurface(picture); SDL_FreeSurface(picture_again); return (4 * NUM_RANDOM) / step; } int TestBigCircle(SDL_Renderer *renderer) { int i, j, k; Uint8 r, g, b, a; int ad; int count = 0; for (i = 0; i < 4; i++) { switch (i) { case 0: SetViewport(renderer, 0, 60, WIDTH / 2, 60 + (HEIGHT - 80) / 2); ad = 0; break; case 1: SetViewport(renderer, WIDTH / 2, 60, WIDTH, 60 + (HEIGHT - 80) / 2); ad = 1; break; case 2: SetViewport(renderer, WIDTH / 2, 80 + (HEIGHT - 80) / 2, WIDTH, HEIGHT); ad = 0; break; case 3: SetViewport(renderer, 0, 80 + (HEIGHT - 80) / 2, WIDTH / 2, HEIGHT); ad = 1; break; } /* Various radii around 255 and 511 */ for (k = 1; k <= 2; k++) { a = 255; for (j = -32; j <= 32; j++) { switch (j & 3) { case 0: r = 255; g = 0; b = 0; break; case 1: r = 0; g = 255; b = 0; break; case 2: r = 0; g = 0; b = 255; break; } circleRGBA(renderer, WIDTH / 2, HEIGHT / (2 - k + 1), (Sint16)(256 * k - 1 + 2 * j), r, g, b, a); a = a - 2 * ad; count++; } } } /* Clear viewport */ ClearViewport(renderer); return count; } int TestBigEllipse(SDL_Renderer *renderer) { int i, j, k; Uint8 r, g, b, a; Uint8 ad; int count = 0; for (i = 0; i < 4; i++) { switch (i) { case 0: SetViewport(renderer, 0, 60, WIDTH / 2, 60 + (HEIGHT - 80) / 2); ad = 0; break; case 1: SetViewport(renderer, WIDTH / 2, 60, WIDTH, 60 + (HEIGHT - 80) / 2); ad = 1; break; case 2: SetViewport(renderer, WIDTH / 2, 80 + (HEIGHT - 80) / 2, WIDTH, HEIGHT); ad = 0; break; case 3: SetViewport(renderer, 0, 80 + (HEIGHT - 80) / 2, WIDTH / 2, HEIGHT); ad = 1; break; } /* Various radii around 255 and 511 */ for (k = 1; k <= 2; k++) { a = 255; for (j = -32; j <= 32; j++) { switch (j & 3) { case 0: r = 255; g = 0; b = 0; break; case 1: r = 0; g = 255; b = 0; break; case 2: r = 0; g = 0; b = 255; break; } ellipseRGBA(renderer, WIDTH / 2, HEIGHT / 2, (Sint16)(256 * k - 1 + 2 * j), (Sint16)(256 * k - 1 - 2 * j), r, g, b, a); ellipseRGBA(renderer, WIDTH / 2, HEIGHT / 2, (Sint16)(256 * k - 1 - 2 * j), (Sint16)(256 * k - 1 + 2 * j), r, g, b, a); a = a - 2 * ad; count += 2; } } } /* Clear viewport */ ClearViewport(renderer); return count; } /* ====== Main */ int main(int argc, char *argv[]) { int i, done, drawn, test = 0; SDL_Event event; Uint32 then, now, frames; int numTests; /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); if (!state) { return 1; } SDL_Log("SDL2_gfx %i.%i.%i: testgfx", SDL2_GFXPRIMITIVES_MAJOR, SDL2_GFXPRIMITIVES_MINOR, SDL2_GFXPRIMITIVES_MICRO); SDL_Log("Platform: %s", SDL_GetPlatform()); for (i = 1; i < argc;) { int consumed; consumed = SDLTest_CommonArg(state, i); if (consumed == 0) { consumed = -1; if (SDL_strcasecmp(argv[i], "--test") == 0) { if (argv[i + 1]) { test = SDL_atoi(argv[i + 1]); consumed = 2; } } } if (consumed < 0) { fprintf(stderr, "Usage: %s %s [--test N]\n", argv[0], SDLTest_CommonUsage(state)); return 1; } i += consumed; } if (!SDLTest_CommonInit(state)) { return 2; } /* Create the windows and initialize the renderers */ for (i = 0; i < state->num_windows; ++i) { SDL_Renderer *renderer = state->renderers[i]; SDL_RendererInfo info; SDL_GetRendererInfo(state->renderers[i], &info); SDL_Log("Renderer %i: %s %s", i, info.name, (info.flags | SDL_RENDERER_ACCELERATED) ? "(Accelerated)" : ""); SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); SDL_RenderClear(renderer); } /* Main render loop */ frames = 0; then = SDL_GetTicks(); done = 0; drawn = 0; while (!done) { /* Check for events */ ++frames; while (SDL_PollEvent(&event)) { SDLTest_CommonEvent(state, &event, &done); switch (event.type) { case SDL_KEYDOWN: { switch (event.key.keysym.sym) { case SDLK_SPACE: { /* Switch to next test */ test++; drawn = 0; break; } } break; } case SDL_MOUSEBUTTONDOWN: { switch (event.button.button) { case SDL_BUTTON_LEFT: { /* Switch to next test */ test++; drawn = 0; break; } case SDL_BUTTON_RIGHT: { /* Switch to prev test */ test--; drawn = 0; break; } } break; } } } if (!drawn) { /* Set test range */ numTests = 28; if (test < 0) { test = (numTests - 1); } else { test = test % numTests; } /* Create random points */ InitRandomPoints(test); /* Draw */ for (i = 0; i < state->num_windows; ++i) { SDL_Renderer *renderer = state->renderers[i]; switch (test) { case 0: { ExecuteTest(renderer, TestPixel, test, "Pixel"); break; } case 1: { ExecuteTest(renderer, TestHline, test, "Hline"); break; } case 2: { ExecuteTest(renderer, TestVline, test, "Vline"); break; } case 3: { ExecuteTest(renderer, TestRectangle, test, "Rectangle"); break; } case 4: { ExecuteTest(renderer, TestRoundedRectangle, test, "RoundedRectangle"); break; } case 5: { ExecuteTest(renderer, TestBox, test, "Box"); break; } case 6: { ExecuteTest(renderer, TestLine, test, "Line"); break; } case 7: { ExecuteTest(renderer, TestAALine, test, "AALine"); break; } case 8: { ExecuteTest(renderer, TestCircle, test, "Circle"); break; } case 9: { ExecuteTest(renderer, TestAACircle, test, "AACircle"); break; } case 10: { ExecuteTest(renderer, TestFilledCircle, test, "FilledCircle"); break; } case 11: { ExecuteTest(renderer, TestEllipse, test, "Ellipse"); break; } case 12: { ExecuteTest(renderer, TestAAEllipse, test, "AAEllipse"); break; } case 13: { ExecuteTest(renderer, TestFilledEllipse, test, "FilledEllipse"); break; } case 14: { ExecuteTest(renderer, TestBezier, test, "Bezier"); break; } case 15: { ExecuteTest(renderer, TestPolygon, test, "Polygon"); break; } case 16: { ExecuteTest(renderer, TestAAPolygon, test, "AAPolygon"); break; } case 17: { ExecuteTest(renderer, TestFilledPolygon, test, "FilledPolygon"); break; } case 18: { ExecuteTest(renderer, TestTrigon, test, "Trigon"); break; } case 19: { ExecuteTest(renderer, TestArc, test, "Arc"); break; } case 20: { ExecuteTest(renderer, TestPie, test, "Pie"); break; } case 21: { ExecuteTest(renderer, TestFilledPie, test, "FilledPie"); break; } case 22: { ExecuteTest(renderer, TestThickLine, test, "ThickLine"); break; } case 23: { ExecuteTest(renderer, TestTexturedPolygon, test, "TexturedPolygon"); break; } case 24: { ExecuteTest(renderer, TestRoundedBox, test, "RoundedBox"); break; } case 25: { ExecuteTest(renderer, TestThickLineAccuracy, test, "ThickLine (Accuracy)"); break; } case 26: { ExecuteTest(renderer, TestBigCircle, test, "Circle (Big)"); break; } case 27: { ExecuteTest(renderer, TestBigEllipse, test, "Ellipse (Big)"); break; } default: { ClearScreen(renderer, "Unknown Test"); break; } } SDL_RenderPresent(renderer); } drawn = 1; } /* Adjust framerate */ SDL_Delay(25); } SDLTest_CommonQuit(state); /* Print out some timing information */ now = SDL_GetTicks(); if (now > then) { double fps = ((double) frames * 1000) / (now - then); printf("%2.2f frames per second\n", fps); } return 0; }