在SDL2中,我在渲染作为纹理加载的精灵表中的精灵时遇到了问题。练习包括在顶部和底部角落显示2个精灵,以及其他2个我想要的地方,前三个精灵渲染得很好,但奇怪的是,第四个精灵没有渲染,并且具有相同的代码结构。因此,我得到一个黑屏,它被冻结,并且在第99行中有一条消息,我在Mac OS Sierra 10.12.6的XCode 9中调用SDL_RenderCopy说:线程1:EXC_BAD_ACCESS代码=1。希望大家能帮到我,下面是代码:
#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 which 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;
}
1条答案
按热度按时间wgxvkvu91#
数组
sprite_coordinates[3]
和window_coordinates[3]
的大小为3,因此访问第四个子画面坐标会导致缓冲区溢出。