SDL2 Как я могу рендерить пиксели в необработанном формате? - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь визуализировать пользовательское изображение, и мне требуется загрузить файл в память и вывести его через SDL.Изображение является необработанным форматом, и я думаю, что если бы я мог отрендерить

Мой код может быть мусором, поэтому я открыт для изменений с ним.

void Create_SDL_Window()
{

        SDL_Init(SDL_INIT_EVERYTHING);
        IMG_Init(IMG_INIT_PNG);
        window = SDL_CreateWindow("Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        renderer = SDL_CreateRenderer(window, -1, 0);
        printf("Window And Renderer Created!\n");
}






int main(){
FILE* customImage = fopen(Path, "rb");



Create_SDL_Window();

while (!quit){

        void *p;
        p = customImage;

        SDL_Texture* buffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGRA8888,SDL_TEXTUREACCESS_STREAMING, 800, 600);

        SDL_LockTexture(buffer, NULL, &p, &pitch);

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


        SDL_RenderPresent(renderer);



while (SDL_PollEvent(&e)){
        //If user closes the window
        if (e.type == SDL_QUIT){
                quit = true;
        }
        //If user presses any key
        if (e.type == SDL_KEYDOWN){
        //      quit = true;
        }
        //If user clicks the mouse
        if (e.type == SDL_MOUSEBUTTONDOWN){
        ///     quit = true;
                }
        }

        SDL_RenderPresent(renderer);

}

1 Ответ

0 голосов
/ 21 ноября 2018

У тебя есть вещи задом наперед.Вы должны заметить, что SDL_LockTexture принимает указатель на указатель.Это связано с тем, что в SDL уже есть буфер соответствующего размера для текстуры, и ему необходимо указать адрес (и высоту), чтобы вы могли записать в этот буфер.

У вас также есть проблема, которую вы считаете возможнымиспользуйте FILE* в качестве пиксельного буфера.Это совсем не так;FILE* - это указатель на структуру, описывающую файл, а не на его содержимое.

Вам нужно сделать что-то вроде:

// create your empty texture
...
int pitch = 0;
char* p = NULL;
SDL_LockTexture(buffer, NULL, &p, &pitch);
... // Error checking

// now open your file and mmap it
int fd = open(Path, O_RDONLY);
struct stat sb;
fstat(fd, &sb);

const char* memblock = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
... // Error checking

// now you need to copy the data from the file to the pixel buffer
// you claim you are working with 800x600 32bit image data

for (int y = 0; y < 600; ++y)
{
    const char* src = &memblock[y * pitch]; // is this really the pitch of the file? you didn't specify....
    char* dst = &p[y * pitch];
    memcpy(dst, src, 800*4); // width * size of a pixel
}

этот код предполагает, что вы не сделалиошибка где-то еще, например, размер текстуры или формат пикселей.Вы также заметите некоторые неизвестные в коде, которые вам нужно выяснить.

Вы также можете попробовать SDL_UpdateTexture, который примет указатель на пиксели, как вы пытаетесь в своем коде.Тем не менее, он, вероятно, будет намного медленнее, чем SDL_LockTexture, и вам все равно нужно будет на самом деле прочитать файл (или еще лучше mmap его), чтобы передать пиксели.

Еще 3-й вариант,если SDL_Image знает, как читать ваш файл "RAW", значит использовать IMG_Load, чтобы получить SDL_Surface вашего изображения, а затем создать текстуру с этой поверхности, используя SDL_CreateTextureFromSurface

...