maandag 19 maart 2018

SDL2 fastest way to draw pixels

When your monitor sync is 60 herz, you've got 16 ms to do your pixel update.
I managed to clear a 1366 by 768 pixelbuffer and upload it to the graphicscard in 0.60ms. This leaves 15 ms to do pixel magic.

In SDL 2, I do the following:

#define DIMx 1366

#define DIMy 768

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,DIMx, DIMy,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN */);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED /*| SDL_RENDERER_PRESENTVSYNC */);

SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, DIMx, DIMy);
SDL_Surface* surface = SDL_CreateRGBSurface(0, DIMx, DIMy, 32, 0, 0, 0, 0);
BYTE* pixels = (BYTE *)surface->pixels;

SDL_Event event;
bool running = true;

SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);

while (running)
{
int pitch = DIMx * 4;
SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
ClearArray(pixels, (DIMx*DIMy/2) );  //0.15 ms (asm: rep stosq)

pixels[0] = 255; //set just one pixel, for example
                pixels[1] = 255;
                pixels[2] = 255;
pixels[3] = 255; 

SDL_UnlockTexture(texture);
SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0.0f, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}

SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}

I hope you can use this code. Activate the SDL_RENDERER_PRESENTVSYNC to have a smooth 60 herz.

Geen opmerkingen:

Een reactie posten