SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
SDL_Texture *texture = nullptr;
SDL_Surface *loadedImage = SDL_LoadBMP(file.c_str());
texture = SDL_CreateTextureFromSurface(ren, loadedImage);
SDL_FreeSurface(loadedImage);
return texture;
}
//渲染纹理(渲染图片)
void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y){
SDL_Rect dst;
dst.x = x;
dst.y = y;
SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);//获取图像的宽、高
SDL_RenderCopy(ren, tex, NULL, &dst);//纹理复制给渲染器
}
int main()
{
//初始化SDL、Window、前景、后景}
SDL_Init(SDL_INIT_VIDEO)
SDL_CreateWindow("Lesson 2", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)
SDL_Texture *background = loadTexture(resPath + "background.bmp", renderer);
SDL_Texture *image = loadTexture(resPath + "image.bmp", renderer);
while(1){SDL_RenderClear(renderer);SDL_QueryTexture(background, NULL, NULL, &bW, &bH);//获取背景的宽、高
renderTexture(background, renderer, 0, 0);renderTexture(background, renderer, bW, 0);renderTexture(background, renderer, 0, bH);renderTexture(background, renderer, bW, bH);SDL_QueryTexture(image, NULL, NULL, &iW, &iH);//获取前景的宽、高
renderTexture(image, renderer, x, y);SDL_RenderPresent(renderer);//渲染
SDL_Delay(1000);}
最后的效果图
完整代码如下
#include <iostream> #include <SDL.h> #include "res_path.h" #include "cleanup.h" /* * Lesson 2: Don't Put Everything in Main */ //Screen attributes const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; /* * Log an SDL error with some error message to the output stream of our choice * @param os The output stream to write the message too * @param msg The error message to write, format will be msg error: SDL_GetError() os << msg << " error: " << SDL_GetError() << std::endl; } /* * Loads a BMP image into a texture on the rendering device * @param file The BMP image file to load */ SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){ SDL_Texture *texture = nullptr; //Load the image SDL_Surface *loadedImage = SDL_LoadBMP(file.c_str()); //If the loading went ok, convert to texture and return the texture if (loadedImage != nullptr){ texture = SDL_CreateTextureFromSurface(ren, loadedImage); SDL_FreeSurface(loadedImage); //Make sure converting went ok too if (texture == nullptr){ logSDLError(std::cout, "CreateTextureFromSurface"); } } else { logSDLError(std::cout, "LoadBMP"); } return texture; } /* * Draw an SDL_Texture to an SDL_Renderer at position x, y, preserving * the texture's width and height * @param tex The source texture we want to draw * @param ren The renderer we want to draw too * @param x The x coordinate to draw too * @param y The y coordinate to draw too */ void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y){ //Setup the destination rectangle to be at the position we want SDL_Rect dst; dst.x = x; dst.y = y; //Query the texture to get its width and height to use SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h); SDL_RenderCopy(ren, tex, NULL, &dst); } int main(int, char**){ //Start up SDL and make sure it went ok if (SDL_Init(SDL_INIT_VIDEO) != 0){ logSDLError(std::cout, "SDL_Init"); return 1; } //Setup our window and renderer if (window == nullptr){ logSDLError(std::cout, "CreateWindow"); SDL_Quit(); return 1; } SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (renderer == nullptr){ logSDLError(std::cout, "CreateRenderer"); cleanup(window); SDL_Quit(); return 1; } //The textures we'll be using const std::string resPath = getResourcePath("Lesson2"); SDL_Texture *background = loadTexture(resPath + "background.bmp", renderer); SDL_Texture *image = loadTexture(resPath + "image.bmp", renderer); //Make sure they both loaded ok if (background == nullptr || image == nullptr){ cleanup(background, image, renderer, window); SDL_Quit(); return 1; } //A sleepy rendering loop, wait for 3 seconds and render and present the screen each time for (int i = 0; i < 3; ++i){ //Clear the window SDL_RenderClear(renderer); //Get the width and height from the texture so we know how much to move x,y by //to tile it correctly int bW, bH; SDL_QueryTexture(background, NULL, NULL, &bW, &bH); //We want to tile our background so draw it 4 times renderTexture(background, renderer, 0, 0); renderTexture(background, renderer, bW, 0); renderTexture(background, renderer, 0, bH); renderTexture(background, renderer, bW, bH); //Draw our image in the center of the window //We need the foreground image's width to properly compute the position //of it's top left corner so that the image will be centered int iW, iH; SDL_QueryTexture(image, NULL, NULL, &iW, &iH); int x = SCREEN_WIDTH / 2 - iW / 2; int y = SCREEN_HEIGHT / 2 - iH / 2; renderTexture(image, renderer, x, y); //Update the screen SDL_RenderPresent(renderer); //Take a quick break after all that hard work SDL_Delay(1000); }