Hey!
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.
As is probably obvious, I’m new to C++ and used to higher-level languages.
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)?
Thanks in advance.
main.h:
#include <SDL2/SDL.h>
#include <stdio.h>
#include
#include
#include
#include
#include
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();
//bool mouseDown = false;
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++)
{
/*const unsigned int offset = (texWidth * 4 * y) + x * 4;
pixels[offset + 0] = rand() % 256; // b
pixels[offset + 1] = rand() % 256; // g
pixels[offset + 2] = rand() % 256; // r
pixels[offset + 3] = SDL_ALPHA_OPAQUE; // a
*/
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_UpdateTexture(texture, NULL, pixels, w * sizeof(Uint32));
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
*/
//SDL_UpdateWindowSurface(window);
}
//delete[] pixels;
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}