###### (This is the documentation for SDL3, which is the current stable version. [SDL2](https://wiki.libsdl.org/SDL2/) was the previous version!) # SDL_CreateSoftwareRenderer Create a 2D software rendering context for a surface. ## Header File Defined in [](https://github.com/libsdl-org/SDL/blob/main/include/SDL3/SDL_render.h) ## Syntax ```c SDL_Renderer * SDL_CreateSoftwareRenderer(SDL_Surface *surface); ``` ## Function Parameters | | | | | ---------------------------- | ----------- | ------------------------------------------------------------------------------------------ | | [SDL_Surface](SDL_Surface) * | **surface** | the [SDL_Surface](SDL_Surface) structure representing the surface where rendering is done. | ## Return Value ([SDL_Renderer](SDL_Renderer) *) Returns a valid rendering context or NULL if there was an error; call [SDL_GetError](SDL_GetError)() for more information. ## Remarks Two other API which can be used to create [SDL_Renderer](SDL_Renderer): [SDL_CreateRenderer](SDL_CreateRenderer)() and [SDL_CreateWindowAndRenderer](SDL_CreateWindowAndRenderer)(). These can _also_ create a software renderer, but they are intended to be used with an [SDL_Window](SDL_Window) as the final destination and not an [SDL_Surface](SDL_Surface). ## Thread Safety You may only call this function from the main thread. ## Version This function is available since SDL 3.1.3. ## Code Examples ```c #include #include SDL_Window *window; SDL_Renderer *renderer; int done; void DrawChessBoard(SDL_Renderer *renderer) { int row = 0, column = 0, x = 0; SDL_FRect rect; SDL_Rect darea; /* Get the Size of drawing surface */ SDL_GetRenderViewport(renderer, &darea); SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(renderer); for (; row < 8; row++) { column = row % 2; x = column; for (; column < 4 + (row % 2); column++) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF); rect.w = (float)darea.w / 8; rect.h = (float)darea.h / 8; rect.x = x * rect.w; rect.y = row * rect.h; x = x + 2; SDL_RenderFillRect(renderer, &rect); } } SDL_RenderPresent(renderer); } void loop() { SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_EVENT_QUIT) { done = 1; return; } if ((e.type == SDL_EVENT_KEY_DOWN) && (e.key.key == SDLK_ESCAPE)) { done = 1; return; } } DrawChessBoard(renderer); /* Got everything on rendering surface, now Update the drawing image on window screen */ SDL_UpdateWindowSurface(window); } int main(int argc, char *argv[]) { SDL_Surface *surface; /* Initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init fail : %s\n", SDL_GetError()); return 1; } /* Create window and renderer for given surface */ window = SDL_CreateWindow("Chess Board", 640, 480, 0); if (!window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n", SDL_GetError()); return 1; } surface = SDL_GetWindowSurface(window); renderer = SDL_CreateSoftwareRenderer(surface); if (!renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Render creation for surface fail : %s\n", SDL_GetError()); return 1; } /* Draw the Image on rendering surface */ done = 0; while (!done) { loop(); } SDL_Quit(); return 0; } ``` ## See Also - [SDL_DestroyRenderer](SDL_DestroyRenderer) ---- [CategoryAPI](CategoryAPI), [CategoryAPIFunction](CategoryAPIFunction), [CategoryRender](CategoryRender)