2017-09-27 1 views
0

SDL2의 텍스처로로드 된 스프라이트 시트에서 스프라이트를 렌더링하는 데 문제가 있습니다. 연습은 상단과 하단 모서리에 2 개의 스프라이트를 표시하는 것으로 구성되어 있습니다. 나머지 2 개는 원할 경우 처음 3 개의 스프라이트가 잘 렌더링되지만 이상하게도 4 번째 렌더링은 렌더링되지 않고 동일한 코드 구조를가집니다. 결과적으로 나는 얼어 붙은 검은 색 화면을 얻었고, Mac OS X 10에서 Xcode 9의 SDL_RenderCopy를 호출하는 99 행의 메시지가 나타납니다. 스레드 1 : EXC_BAD_ACCESS 코드 = 1.SDL2의 스프라이트가 표시되지 않습니다.

#include <iostream> 
#include <SDL2/SDL.h> 
#include <SDL2_image/SDL_image.h> 
#include <cstdio> 
#include <cstdlib> 

using namespace std; 

const int SCREEN_WIDTH = 1300; 
const int SCREEN_HEIGHT = 700; 

class WTexture{//Wrapper class to organize all data from texture 

    SDL_Texture * texture; 
    int width; 
    int height; 

public: 

    WTexture(); 
    ~WTexture(); 
    bool loadFromFile(std::string);//Load texture 
    void free();//Frees texture 
    void render(SDL_Rect *, SDL_Rect *); 
    int getWidth(); 
    int getHeight(); 

}; 

bool init();//Initialize SDL 

bool loadMedia();//Load multimedia data, in this case the sprite sheet 
//And initializes coordinates for rendering. 

void close();//Quit and clean up all 

SDL_Window * main_window = NULL; 
SDL_Renderer * renderer = NULL; 

SDL_Rect sprite_coordinates[3];//The rectangles which contains sprites 
//coordinates from the loaded texture (sprite sheet). 

SDL_Rect window_coordinates[3];//The rectangles which contains the 
//coordinates to render sprites in screen 


WTexture texture_wrapper;//An object to store the texture 

WTexture::WTexture(){//Constructor 

    texture = NULL; 
    width = 0; 
    height = 0; 
} 

WTexture::~WTexture(){//Destructor 

    free(); 
} 

bool WTexture::loadFromFile(std::string path){ 

    SDL_Surface * surfaceToTexture = IMG_Load(path.c_str()); 
    if(surfaceToTexture == NULL) 
     fprintf(stderr, "%s\n", IMG_GetError()); 
    else{ 

     SDL_SetColorKey(surfaceToTexture, SDL_TRUE, SDL_MapRGB(surfaceToTexture->format, 0xFF, 0xFF, 0xFF)); 
     SDL_Texture * texture_to_return = SDL_CreateTextureFromSurface(renderer, surfaceToTexture); 
     if(texture_to_return == NULL) 
      fprintf(stderr, "%s\n", IMG_GetError()); 
     else{ 

      texture = texture_to_return; 
      width = surfaceToTexture->w; 
      height = surfaceToTexture->h; 
      SDL_FreeSurface(surfaceToTexture); 

     } 
    } 
    return texture != NULL; 

} 

void WTexture::free(){ 
    if(texture != NULL){ 

     SDL_DestroyTexture(texture); 
     texture = NULL; 
     width = 0; 
     height = 0; 
    } 

} 

void WTexture::render(SDL_Rect * sprite_coords, SDL_Rect * dest_coords){ 

    SDL_RenderCopy(renderer, texture, sprite_coords, dest_coords); 

} 

int WTexture::getWidth(){ 

    return width; 
} 

int WTexture::getHeight(){ 

    return height; 
} 

bool init(){ 

    bool success = false; 
    if(SDL_Init(SDL_INIT_VIDEO) < 0) 
     fprintf(stderr, "%s\n", SDL_GetError()); 
    else{ 

     main_window = SDL_CreateWindow("CLip Rendering", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, 
             SCREEN_HEIGHT, SDL_WINDOW_SHOWN); 
     if(main_window == NULL) 
      fprintf(stderr, "%s\n", SDL_GetError()); 
     else{ 

      renderer = SDL_CreateRenderer(main_window, -1, SDL_RENDERER_ACCELERATED); 
      if(renderer == NULL) 
       fprintf(stderr, "%s\n", SDL_GetError()); 
      else{ 

       SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); 

       if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) 
        fprintf(stderr, "%s\n", "Warning: Couldn't initialize linear filtering"); 
       else{ 

        if(!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) 
         fprintf(stderr, "%s\n", IMG_GetError()); 
        else success = true; 

       } 

      } 

     } 

    } 
    return success; 

} 

bool loadMedia(){ 

    bool success = true; 

    if(!texture_wrapper.loadFromFile("/Users/linuxshotgun/Engineering/SDL_tutorial/Sources/spritesheet.png")){ 
     fprintf(stderr, "%s\n", SDL_GetError()); 
     success = false; 
    } 
    else{ 

     //First sprite coords (in left to righ order) 
     sprite_coordinates[0].x = 0;//x coordinate of the top left corner of the sprite 
     sprite_coordinates[0].y = 0;//x coordinate of the top left corner of the sprite 
     sprite_coordinates[0].w = 214;//Width in pixels 
     sprite_coordinates[0].h = 260;//Height in pixels 

     //Second sprite coords 
     sprite_coordinates[1].x = 268; 
     sprite_coordinates[1].y = 0; 
     sprite_coordinates[1].w = 192; 
     sprite_coordinates[1].h = 260; 

     //Third sprite coords 
     sprite_coordinates[2].x = 0; 
     sprite_coordinates[2].y = 266; 
     sprite_coordinates[2].w = 212; 
     sprite_coordinates[2].h = 262; 

     //Fourth sprite coords, this sprite has the problem 
     sprite_coordinates[3].x = 219; 
     sprite_coordinates[3].y = 264; 
     sprite_coordinates[3].w = 190; 
     sprite_coordinates[3].h = 264; 

     //Screen coordinates in wich the sprites will be displayed (in order, first sprite, second). 

     window_coordinates[0].x=0; 
     window_coordinates[0].y=0; 
     window_coordinates[0].w=sprite_coordinates[0].w; 
     window_coordinates[0].h=sprite_coordinates[0].h; 

     window_coordinates[1].x=650; 
     window_coordinates[1].y=0; 
     window_coordinates[1].w=sprite_coordinates[1].w; 
     window_coordinates[1].h=sprite_coordinates[1].h; 

     window_coordinates[2].x=0; 
     window_coordinates[2].y=350; 
     window_coordinates[2].w=sprite_coordinates[2].w; 
     window_coordinates[2].h=sprite_coordinates[2].h; 

     //fourth sprite display coords: Could have a bug 
     window_coordinates[3].x=650; 
     window_coordinates[3].y=350; 
     window_coordinates[3].w=sprite_coordinates[3].w; 
     window_coordinates[3].h=sprite_coordinates[3].h; 

    } 
    return success; 

} 

void close(){ 


    SDL_DestroyRenderer(renderer); 
    renderer = NULL; 
    SDL_DestroyWindow(main_window); 
    main_window = NULL; 
    IMG_Quit(); 
    SDL_Quit(); 


} 


int main(int argc, char *argv[]){ 

    if(!init()){ 
     fprintf(stderr, "%s\n", SDL_GetError()); 
     _Exit(EXIT_FAILURE); 
    } 
    if(!loadMedia()){ 
     fprintf(stderr, "%s\n", SDL_GetError()); 
     _Exit(EXIT_FAILURE); 
    } 
    bool quit = false; 
    SDL_Event event; 
    while(!quit){ 

     while(SDL_PollEvent(&event) != 0){ 

      if(event.type == SDL_QUIT) 
       quit = true; 
     } 

     //Clear screen 
     SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); 
     SDL_RenderClear(renderer); 

     //render top left sprite 
     texture_wrapper.render(&sprite_coordinates[0], &window_coordinates[0]); 
     texture_wrapper.render(&sprite_coordinates[1], &window_coordinates[1]); 
     texture_wrapper.render(&sprite_coordinates[2], &window_coordinates[2]); 
     texture_wrapper.render(&sprite_coordinates[3], &window_coordinates[3]); 

     SDL_RenderPresent(renderer); 

    } 
    close(); 
    return EXIT_SUCCESS; 

} 

답변

0

배열 sprite_coordinates[3]window_coordinates[3] 크기 3가 그렇게 접근 네 번째 스프라이트가 원인 버퍼 오버런 좌표 : 당신이 날 도울 수 있기를 바랍니다, 아래의 코드입니다.

+0

당신은 모든 이유가 있습니다! 그것은 효과가있다! 나는 배열 인덱스가 인덱스 0에서부터 시작된다는 주제와 혼돈 스러웠다. 그래서 크기 3의 배열을 선언하면 4 개의 요소가 유지 될 것이라고 생각했다. 정말 고마워요! –

관련 문제