2
\$\begingroup\$

All I'm trying to do is write random data to an array, then display that array to a window. But I can't get SDL_LockTexture to cooperate, it keeps complaining that I'm using the wrong argument. I've tried &pixels, **pixels, and now this weird proxy void construction. None of it works, of course. What is the correct way of doing this?

// gcc C11

#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <stdint.h>


int main(int argc, char *argv[])
{
    if (argc != 3){
        printf("Wrong amount of args given: expected width, height.\n");
        return 1;
    }

    int w = atoi(argv[1]);
    int h = atoi(argv[2]);

    int pixels[w][h];

    uint8_t r,g,b;

    int pitch = w*4;

    void * pixelpointer = &pixels;



    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        fprintf(stderr, "SDL_Init Error: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }

    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_CreateWindowAndRenderer(w, h, 0, &window, &renderer);

    SDL_Texture* buffer = SDL_CreateTexture(renderer,
                          SDL_PIXELFORMAT_RGBA8888,
                          SDL_TEXTUREACCESS_STREAMING, 
                          w,
                          h);

    SDL_LockTexture(buffer,
                    NULL,      // NULL means the *whole texture* here.
                    *pixelpointer,
                    &pitch);

    printf("\nStarting render...\n\nWidth:  %d\nHeight: %d\n", w, h);

    #pragma omp parallel for
    for (int y = 0; y < h; ++y){
        for (int x = 0; x < w; ++x){
            r = rand();
            g = rand();
            b = rand();
            pixels[x][y] = r & g>>8 & b>>16 & 0x000000FF;
        }
    }

    printf("parallel for ends.\n");

    SDL_UnlockTexture(buffer);
    SDL_RenderCopy(renderer, buffer, NULL, NULL);

    SDL_Delay(2000);

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
```
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

void **pixels is a pointer-to-a-pointer; these are typically used (in this kind of context) where the data is of a pointer type but memory management is handled by the function you call.

The correct usage is therefore:

int *pixels = NULL;
SDL_LockTexture (buffer, NULL, (void **) &pixels, &pitch);

After this call your int *pixels pointer will be accessible for writing, and when you call SDL_UnlockTexture the pointer will no longer be valid for use.

\$\endgroup\$
2
  • \$\begingroup\$ It now compiles and runs, but it doesn't render anything (the graphics of the underlying windows/desktop stays). Is it correct to edit the pixel array after locking the texture? \$\endgroup\$
    – AnnoyinC
    Commented Sep 9, 2019 at 9:32
  • \$\begingroup\$ The problem was that I forgot to call RenderPresent :) \$\endgroup\$
    – AnnoyinC
    Commented Sep 9, 2019 at 9:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .