这一节我们主要讲SDL如何绘制非BMP格式的图片,这个也很简单,这里会用到SDL的一个扩展库,SDL_IMAGE,然后再进行LOAD的时候用SDL_IMAGE里面的一个函数
IMG_LoadTexture,就OK,其他的基本上跟以前的做法没有什么区别。
讲解:
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int TILE_SIZE = 40;
Clesson04::Clesson04()
{
}
Clesson04::~Clesson04()
{
}
//SDL_窗口的销毁
void Clesson04::cleanup(SDL_Window* window)
{
SDL_DestroyWindow(window);
//SDL_QUIT();
}
//Texture,Renderer,Window的销毁,原作者写的函数比这个要好,这个仅仅是一个功能的实现。
void Clesson04::cleanup(SDL_Texture* background, SDL_Texture* image, SDL_Renderer* renderer, SDL_Window* window)
{
if(background)
{
SDL_DestroyTexture(background);
}
if(image)
{
SDL_DestroyTexture(image);
}
if(renderer)
{
SDL_DestroyRenderer(renderer);
}
if(window)
{
SDL_DestroyWindow(window);
}
}
/*
C++的标准输出
*/
void Clesson04::logSDLError(std::ostream &os, const std::string &msg){
os << msg << " error: " << SDL_GetError() << std::endl;
}
/*
用一个图片创建创建一个SDL_Texture(不仅仅是BMP文件了)
*/
SDL_Texture* Clesson04::loadTexture(const std::string &file, SDL_Renderer *ren){
SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
if (texture == nullptr){
logSDLError(std::cout, "LoadTexture");
}
return texture;
}
/*
用SDL_Texture,在指定的位置,指定大小在SDL_Renderer绘制
*/
void Clesson04::renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y, int w, int h){
//Setup the destination rectangle to be at the position we want
SDL_Rect dst;
dst.x = x;
dst.y = y;
dst.w = w;
dst.h = h;
SDL_RenderCopy(ren, tex, NULL, &dst);
}
/*
这个只是指定SDL_Texture在指定的SDL_Renderer上绘制,大小为SDL_Texture的大小。
*/
void Clesson04::renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y){
int w, h;
SDL_QueryTexture(tex, NULL, NULL, &w, &h);
renderTexture(tex, ren, x, y, w, h);
}
int Clesson04::Run(int argc, char* argv[]){
//初始化SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
logSDLError(std::cout, "SDL_Init");
return 1;
}
//创建一个SDL Window和Renderer
SDL_Window *window = SDL_CreateWindow("OAD工作室-SDL渲染非BMP图片", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
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;
}
//Load 两个SDL_Texture,一个前景,一个背景(文件是PNG格式)
std::string path(argv[1]);
const std::string resPath = path;
SDL_Texture *background = loadTexture(resPath + "background.png", renderer);
SDL_Texture *image = loadTexture(resPath + "image.png", renderer);
//Make sure they both loaded ok
if (background == nullptr || image == nullptr){
cleanup(background, image, renderer, window);
SDL_Quit();
return 1;
}
//准备开始绘制
SDL_RenderClear(renderer);
//用背景图,绘制TILE_SIZEXTILE_SIZE,填充整个Renderer
//这个就不是像上一课那样直接绘制4个
int xTiles = SCREEN_WIDTH / TILE_SIZE;
int yTiles = SCREEN_HEIGHT / TILE_SIZE;
//Draw the tiles by calculating their positions
for (int i = 0; i < xTiles * yTiles; ++i){
int x = i % xTiles;
int y = i / xTiles;
renderTexture(background, renderer, x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
//在Renderer的中间绘制一个前景图
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);
//更新Renderer
SDL_RenderPresent(renderer);
bool bRun = true;//程序是否允许
SDL_Event AppEven;//SDL事件
while (bRun) {
if(SDL_WaitEvent(&AppEven))
{
switch (AppEven.type) {
case SDL_KEYDOWN:
bRun = false;
break;
case SDL_QUIT:
bRun = false;
break;
default:
break;
}
}
}
//Destroy the various items
cleanup(background, image, renderer, window);
IMG_Quit();
SDL_Quit();
return 0;
}
代码我们会在教程完了以后整理一下,上传到优快云上,有兴趣的可以直接看原作者的代码。