第五课:SDL绘制非BMP图片

本文介绍如何利用SDL和SDL_IMAGE库加载和渲染非BMP格式的图片,包括初始化、加载纹理、设置渲染参数及绘制图片等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一节我们主要讲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;
}
代码我们会在教程完了以后整理一下,上传到优快云上,有兴趣的可以直接看原作者的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值