1
\$\begingroup\$

I am new with SDL, and am making a Conway Game of Life.

I want to make a grid appear on the screen, so of course I could make one manually with SDL_RenderDrawLine and two loops. But I don't want to create this grid every single time, once is enough, after I can just copy it to the screen.

So I want to create the grid once, and save it somewhere, like a texture.

The problem is, how do I draw to a texture ?

From what I understand, SDL_RenderDrawLine will need a renderer (which is associated with a window) and so it won't work for my purpose as it will be drawing to that renderer buffer or something, and then to a window.

How can I do that ? You can load an image instead, but I'll lose the whole point of drawing it algorithmically (what if the tile size change, etc).

EDIT : So I'm trying to use SDL_SetRenderTarget, as well as the correct flag to create the texture. However it simply doesn't show up.

Here is the code that create the whole texture, and should render to it :

// part of my init function for SDL

SDL_SetRenderDrawColor(d_renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(d_renderer);
// Create square grid once
d_grid = SDL_CreateTexture(d_renderer, SDL_GetWindowPixelFormat(d_window), SDL_TEXTUREACCESS_TARGET, WINDOW_WIDTH, WINDOW_HEIGHT);
if (d_grid == NULL){
    fprintf(stderr, "Error creating blank grid texture: %s\n", SDL_GetError());
    return false;
}
SDL_SetRenderTarget(d_renderer, d_grid);
for (x = 0; x < MAP_WIDTH; x++){
    SDL_RenderDrawLine(d_renderer, x * 10, 0, x * 10, WINDOW_HEIGHT);
}
for (y = 0; y < MAP_HEIGHT; y++){
    SDL_RenderDrawLine(d_renderer, 0, y * 10, WINDOW_WIDTH, y * 10);
}
// TODO: Draw the grid to the texture
 SDL_RenderPresent(d_renderer);
// Renderer will now draw to screen again
SDL_SetRenderTarget(d_renderer, NULL);

I've checked it, the two loops does create what I want.

Now when I update the screen:

// Reset display
SDL_RenderClear(d_renderer);
SDL_RenderCopy(d_renderer, d_grid, NULL, NULL);

SDL_SetRenderDrawColor(d_renderer, 0x00, 0x00, 0x00, 0xff);

/* Code used to render the game grid, removed for clarity */

SDL_RenderPresent(d_renderer);

I don't understand how I'm supposed to do. According to LazyFoo tutorial, I need to use the SDL_RenderDraw* function, which will render to the texture, but using SDL_RenderPresent or not doesn't change anything. What am I doing wrong ?

\$\endgroup\$
  • \$\begingroup\$ Do you set the color correctly before rendering the grid to the texture? What happens after you SDL_RenderCopy(d_renderer, d_grid)? How about if you remove SDL_RenderPresent from the grid creation code. Have you tried saving the render texture to a file to see if the grid is properly rendered? Are you sure you are not overdrawing the texture? \$\endgroup\$ – Tyyppi_77 Aug 14 '16 at 16:10
  • \$\begingroup\$ @Tyyppi_77 I added two lines on the post that I forgot to paste (SDL_SetRender... and SDL_RencdrClear). Removing SDL_RenderPresent doesn't work, I tried it a few time before and retried it now. After SDL_RenderCopy(...) it draw the game tiles. Haven't tried to save it to a file, I don't know how to do that yet. I can still try too, but as I said I tried to render it by pasting it into the function that update the diplay, and it work there. \$\endgroup\$ – user96649 Aug 14 '16 at 16:27
  • \$\begingroup\$ What if you remove the tile rendering, and simply render the texture to the screen, and nothing else? \$\endgroup\$ – Tyyppi_77 Aug 14 '16 at 16:28
  • \$\begingroup\$ Damn I'm dumb. I was actually drawing on top of it, after copying it. However I now have another problem : the grid is shown, but I struggle finding a way to set the opacity to 0, so the squares that are drawn can be seen. I'm trying to use BlendMode for the renderer and the texture, to no success right now. \$\endgroup\$ – user96649 Aug 14 '16 at 16:51
  • \$\begingroup\$ That would be another issue, not really related to this question anymore. You might way to try clearing the render texture with transparency, then rendering the grid lines, and finally rendering the grid texture on top of the tiles instead of vice-versa. \$\endgroup\$ – Tyyppi_77 Aug 14 '16 at 18:38
0
\$\begingroup\$

The technology you are looking for is called "render textures". Basically you create a texture that the GPU can render to, and after that you can simply render that texture to the screen.

You can create a render texture with SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_TARGET, width, height);, and render to it using SDL_SetRenderTarget(renderer, texture);. After that, all calls to SDL_Render* functions will draw to that texture. Call SDL_SetRenderTarget(renderer, NULL); to enable back drawing to the screen.

Once you are done with the texture, you can simply render the target texture to the screen with SDL_RenderCopy as usual, or even save it using a little code snippet that converts the texture to a surface.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your reply. I've tried to do it using what you recommended me, but for some reason I can't get it to render to the screen. I'll edit the main post to add more code about what is not working. \$\endgroup\$ – user96649 Aug 14 '16 at 15:45
  • \$\begingroup\$ I was overdrawing on top of it... Thanks a lot for your answer. \$\endgroup\$ – user96649 Aug 14 '16 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.