用 SDL2 加载PNG平铺背景并显示前景

上一篇中加载的是BMP,这次可以引用 SDL2_image.lib,加载更多格式的图像。

LoadImage函数做了改动,区别在于不用将surface转换成texture了。

环境:SDL2 + VC++2015

下面的代码将打开background.png和image.png,将background平铺背景,将image作为前景呈现。


  1 #include <stdexcept>
2 #include <string>
3 #include <iostream>
4 #include SDL.h
5 #include SDL_image.h
6
7 //屏幕宽度
8 const int SCREEN_WIDTH = 1600;
9 const int SCREEN_HEIGHT = 900;
10
11 //全局窗口和渲染器
12 SDL_Window window = nullptr;
13 SDL_Renderer
renderer = nullptr;
14
15 //加载图片
16 SDL_Texture LoadImage(std::string file)
17 {
18 SDL_Texture
tex = nullptr;
19 tex = IMG_LoadTexture(renderer, file.c_str());
20 if (tex == nullptr)
21 throw std::runtime_error(Failed to load image: + file + IMG_GetError());
22 return tex;
23 }
24
25 //将表面应用到渲染器
26 void ApplySurface(int x, int y, SDL_Texture tex, SDL_Renderer rend)
27 {
28 SDL_Rect pos;
29 pos.x = x;
30 pos.y = y;
31 SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
32 SDL_RenderCopy(rend, tex, NULL, &pos);
33 }
34
35 int main(int argc, char* argv)
36 {
37 //初始化SDL
38 if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
39 {
40 std::cout << SDL_GetError() << std::endl;
41 return 1;
42 }
43
44 //创建窗口
45 window = SDL_CreateWindow(Lesson 3,
46 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
47 SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
48 if (window == nullptr)
49 {
50 std::cout << SDL_GetError() << std::endl;
51 return 2;
52 }
53
54 //创建渲染器
55 renderer = SDL_CreateRenderer(window, -1,
56 SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
57 if (renderer == nullptr)
58 {
59 std::cout << SDL_GetError() << std::endl;
60 return 3;
61 }
62
63 //创建背景和前景纹理
64 SDL_Texture
background = nullptr, *image = nullptr;
65 try {
66 background = LoadImage(background.png);
67 image = LoadImage(image.png);
68 }
69 catch (const std::runtime_error &e) {
70 std::cout << e.what() << std::endl;
71 return 4;
72 }
73
74 //清空渲染器
75 SDL_RenderClear(renderer);
76
77 //在渲染器内平铺背景
78 int bW, bH;
79 SDL_QueryTexture(background, NULL, NULL, &bW, &bH);
80 for (int y = 0; y <= SCREEN_HEIGHT; y += bH)
81 for (int x = 0; x <= SCREEN_WIDTH; x += bW)
82 ApplySurface(x, y, background, renderer);
83
84
85 //在渲染器中央放置前景
86 int iW, iH;
87 SDL_QueryTexture(image, NULL, NULL, &iW, &iH);
88 int x = SCREEN_WIDTH / 2 - iW / 2;
89 int y = SCREEN_HEIGHT / 2 - iH / 2;
90 ApplySurface(x, y, image, renderer);
91
92 //呈现渲染器
93 SDL_RenderPresent(renderer);
94 SDL_Delay(2000);
95
96 //释放资源
97 SDL_DestroyTexture(background);
98 SDL_DestroyTexture(image);
99 SDL_DestroyRenderer(renderer);
100 SDL_DestroyWindow(window);
101
102 SDL_Quit();
103
104 return 0;
105 }