SDL2 не отображает несколько окон просмотра - PullRequest
1 голос
/ 31 января 2020

Я работаю над учебными пособиями Lazy Foo по SDL2 и застрял, пытаясь отобразить несколько областей просмотра . Идея состоит в том, чтобы загрузить PNG в качестве текстуры, создать SDL_Rect структуры для 3 различных видовых экранов (вверху слева, вверху справа, внизу), затем скопировать текстуру в каждый видовой экран и, наконец, отобразить все 3 видовых экрана. Мой код отображает только первый видовой экран.

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

Я также пытался изменить Размеры области просмотра, в случае, если проблема была с перекрытием - та же проблема.

Единственный вопрос , который я обнаружил в отношении нескольких областей просмотра, не указывал мне правильное направление. Но это заставило меня задуматься - мой код написан на C, учебник на C ++. Хотя я думаю, что я все правильно перевожу (другие уроки работают нормально), может быть, я упускаю что-то очевидное здесь?

Я компилирую с CFLAGS = -Wall -Wextra -pedantic -std=c99 - без предупреждений или ошибок.

Редактировать: я пытался рендерить заполненные прямоугольники вместо загруженного PNG, но проблема та же - рендерится только первый.

Вот мой код:

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

int init_renderer();
int load_media();
SDL_Texture *load_texture(char *);
void close_renderer();

SDL_Window *g_window = NULL;
SDL_Renderer *g_renderer = NULL;
SDL_Texture *g_texture = NULL;

int main()
{
  if (init_renderer() != 1) {
    return -1;
  }

  if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) {
    printf("Warning: Linear texture filtering not enabled!\n");
  }

  if (load_media() != 1) {
    return -1;
  }

  int quit = 0;
  SDL_Event e;
  while (quit != 1) {
    while (SDL_PollEvent(&e) != 0) {
      if (e.type == SDL_QUIT || e.key.keysym.sym == SDLK_q) {
        quit = 1;
      }
    }

    SDL_SetRenderDrawColor(g_renderer, 0xff, 0xff, 0xff, 0xff);
    SDL_RenderClear(g_renderer);

    SDL_Rect top_left_vp;
    top_left_vp.x = 0;
    top_left_vp.y = 0;
    top_left_vp.w = SCREEN_WIDTH / 2;
    top_left_vp.h = SCREEN_HEIGHT / 2;
    SDL_RenderSetViewport(g_renderer, &top_left_vp);
    SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);

    SDL_Rect top_right_vp;
    top_right_vp.x = SCREEN_WIDTH / 2;
    top_right_vp.y = 0;
    top_right_vp.w = SCREEN_WIDTH / 2;
    top_right_vp.h = SCREEN_HEIGHT / 2;
    SDL_RenderSetViewport(g_renderer, &top_right_vp);
    SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);

    SDL_Rect bottom_vp;
    bottom_vp.x = 0;
    bottom_vp.y = SCREEN_HEIGHT / 2;
    bottom_vp.w = SCREEN_WIDTH;
    bottom_vp.h = SCREEN_HEIGHT / 2;
    SDL_RenderSetViewport(g_renderer, &bottom_vp);
    SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);

    SDL_RenderPresent(g_renderer);
  }

  close_renderer();

  return 0;
}

int init_renderer()
{
  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    printf("Failed to initialize SDL. Error: %s\n", SDL_GetError());
    return 0;
  }

  g_window = SDL_CreateWindow("SDL Tuts",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              SCREEN_WIDTH,
                              SCREEN_HEIGHT,
                              SDL_WINDOW_SHOWN);

  if (g_window == NULL) {
    printf("Failed to create window. Error: %s\n", SDL_GetError());
    return 0;
  }

  g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED);
  if (g_renderer == NULL) {
    printf("Failed to create renderer. Error: %s\n", SDL_GetError());
    return 0;
  }

  SDL_SetRenderDrawColor(g_renderer, 0x29, 0xAB, 0x87, 0xFF);

  int img_flags = IMG_INIT_PNG;
  if (!(IMG_Init(img_flags) & img_flags)) {
    printf("Failed to initialize SDL Image. SDL_Image Error: %s\n", IMG_GetError());
    return 0;
  }

  return 1;
}

int load_media()
{
  g_texture = load_texture("assets/texture.png");
  if (g_texture == NULL) {
    return 0;
  }

  return 1;
}

SDL_Texture *load_texture(char *path)
{
  SDL_Texture *new_texture = NULL;
  SDL_Surface *loaded_surface = IMG_Load(path);
  if (loaded_surface == NULL) {
    printf("Failed to load image. SDL_Image Error: %s\n", IMG_GetError());
  } else {
    new_texture = SDL_CreateTextureFromSurface(g_renderer, loaded_surface);
    if (new_texture == NULL) {
      printf("Failed to create texture from %s. Error: %s\n", path, SDL_GetError());
    }

    SDL_FreeSurface(loaded_surface);
  }

  return new_texture;
}

void close_renderer()
{
  SDL_DestroyTexture(g_texture);
  g_texture = NULL;

  SDL_DestroyRenderer(g_renderer);
  SDL_DestroyWindow(g_window);
  g_renderer = NULL;
  g_window = NULL;

  IMG_Quit();
  SDL_Quit();
}

1 Ответ

0 голосов
/ 01 февраля 2020

Чтобы проверить больше ошибок, вы должны увидеть, что возвращаются вызовы SDL_RenderSetViewPort. Согласно документам , он возвращает int, который равен 0 в случае успеха или отрицательный int в случае ошибки. Вполне возможно, что что-то более глубокое в SDL подходит.

Дополнительные советы для профессионалов: вы можете определить SDL_Rect структуры вне вашего, в то время как l oop, чтобы сэкономить минимальный запас вычислительной мощности. И чтобы сэкономить немного времени на печать, вы можете инициализировать SDL_Rect, используя конструктор списка, вместо того, чтобы вручную пробивать каждое свойство. Например:

SDL_Rect top_left_vp;
top_left_vp.x = 0;
top_left_vp.y = 0;
top_left_vp.w = SCREEN_WIDTH / 2;
top_left_vp.h = SCREEN_HEIGHT / 2;

проще

SDL_Rect top_left_vp = {
    0,
    0,
    SCREEN_WIDTH / 2,
    SCREEN_HEIGHT / 2
};
...