I’m testing out SDL and made the following test project to see the performance. I want to make an array of points randomly on the screen, then for every pixel in every frame, find the nearest point and set the pixel’s color to that point’s color.
It works, but I’m getting about 1fps. Any obvious mistakes I made? Is this expected speed for the amount of operations I’m doing (50 points, 680x480 pixels)?
main.h:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstring>
#include <cmath>
const int pointsN = 50;
union Color
{
struct
{
uint8_t r, g, b, a;
} color;
uint32_t color_int;
};
struct Point
{
int x;
int y;
Color color;
};
void set_pixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
Uint32 *const target_pixel = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel);
*target_pixel = pixel;
}
float dist(int x1, int y1, int x2, int y2)
{
return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}
Point nearestPoint(struct Point (& points)[pointsN], int x, int y)
{
float smallestSize = -1;
float thisDist;
int closestIndex;
for (size_t i = 0; i < pointsN; i++)
{
thisDist = dist(x, y, points[i].x, points[i].y);
if(thisDist < smallestSize || smallestSize == -1)
{
closestIndex = i;
smallestSize = thisDist;
}
}
return points[closestIndex];
}
main.cpp:
#include "main.h"
int main(int argv, char **args)
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("Error");
return 0;
}
const int w = 680;
const int h = 480;
SDL_Window *window = SDL_CreateWindow("SDL2 Window",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
w, h,
0);
if (!window)
{
std::cout << "Failed to create window\n";
return -1;
}
/*SDL_Surface *window_surface = SDL_GetWindowSurface(window);
if (!window_surface)
{
std::cout << "Failed to get the surface from the window\n";
return -1;
}
*/
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, w, h);
Uint32 pixels[w*h];
Point points[pointsN];
for (size_t i = 0; i < pointsN; i++)
{
Point newpoint;
newpoint.x = rand() % w;
newpoint.y = rand() % h;
newpoint.color.color.r = rand() % 255;
newpoint.color.color.g = rand() % 255;
newpoint.color.color.b = rand() % 255;
newpoint.color.color.a = 255;
points[i] = newpoint;
}
SDL_Event e;
bool keep_window_open = true;
unsigned int frames = 0;
Uint64 start = SDL_GetPerformanceCounter();
while (keep_window_open)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while (SDL_PollEvent(&e) > 0)
{
switch (e.type)
{
case SDL_QUIT:
keep_window_open = false;
break;
}
}
for (size_t y = 0; y < h; y++)
{
for (size_t x = 0; x < w; x++)
{
pixels[(w * y) + x] = nearestPoint(points, x, y).color.color_int;
}
}
for (size_t i = 0; i < pointsN; i++)
{
points[i].x += (rand() % 50 + 1) - 25;
points[i].y += (rand() % 50 + 1) - 25;
}
SDL_UpdateTexture(
texture,
NULL,
pixels,
w * sizeof(Uint32));
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
frames++;
const Uint64 end = SDL_GetPerformanceCounter();
const static Uint64 freq = SDL_GetPerformanceFrequency();
const double seconds = (end - start) / static_cast<double>(freq);
printf("FPS: %f\n", frames / seconds);
}
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}