效果图如下
本文主要将我们通过创建窗口、渲染上下文工具、纹理工具、矩形框工具;其需要主要的是:首先我们在显示BMP时,需要先创建好窗口,再使用渲染工具对窗口进行格式刷,使用纹理工具和渲染工具配合进行BMP图片显示,矩形框的作用就是显示BMP图片的大小。
下面小例子就是当鼠标点击时,会通过texture纹理工具,使用渲染拷贝一份纹理显示至window窗口
cpp
#include "playthread.h"
#include <SDL2/SDL.h>
#include <QDebug>
#include <QFile>
//#号自动添加双引号""
#define END(judge,SDL_Init) \
if(judge) \
{\
qDebug() << #SDL_Init << "error" << SDL_GetError();\
goto end;\
}
playThread::playThread(QObject *parent) : QThread(parent)
{
//监听线程,线程结束后自动释放线程内存
connect(this,&playThread::finished,this,&playThread::deleteLater);
}
playThread::~playThread()
{
disconnect();//?
requestInterruption();
quit();
wait();
qDebug() << "析构了";
}
void playThread::run()
{
//创建窗口
SDL_Window *window = nullptr;
//渲染上下文
SDL_Renderer *renderer = nullptr;
//纹理(直接跟特定驱动程序相关的像素数据)
SDL_Texture *texture = nullptr;
//矩形框
SDL_Rect dstRect = {0,0,50,50};
//初始化子系统
END(SDL_Init(SDL_INIT_VIDEO),SDL_Init);
//创建一个窗口
//标题-X-Y-width-height
window = SDL_CreateWindow("SDL修改渲染目标",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
500,
500,
SDL_WINDOW_SHOWN);
END(!window,SDL_CreateWindow);
//创建渲染上下文--用于渲染图形到窗口
//这SDL_RENDERER_ACCELERATED -- 个标志告诉 SDL 尝试创建一个使用硬件加速的渲染器
//SDL_RENDERER_PRESENTVSYNC -- 这个标志使渲染器的呈现操作同步到显示器的垂直同步(VSync)
renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED |
SDL_RENDERER_PRESENTVSYNC);
//如果创建失败
if(!renderer)
{
renderer = SDL_CreateRenderer(window,-1,0);
END(!renderer,SDL_CreateRenderer);
}
//创建纹理
texture = createTexture(renderer);
END(!texture,SDL_CreateTextureFromSurface);
//设置渲染目标为windows -- nullptr默认为windows
END(SDL_SetRenderTarget(renderer,nullptr),SDL_SetRenderTarget);
//设置绘制颜色(画笔颜色)
END(SDL_SetRenderDrawColor(renderer,0,0,0,SDL_ALPHA_OPAQUE),SDL_SetRenderDrawColor);
//用绘制颜色(画笔颜色)清除渲染目标---也就是覆盖
END(SDL_RenderClear(renderer),SDL_RenderClear);
//拷贝纹理到渲染目标
END(SDL_RenderCopy(renderer,texture,nullptr,&dstRect),SDL_rSDL_RenderCopyen);
//更新所有的渲染操作到屏幕上
SDL_RenderPresent(renderer);
//等待退出事件
while(!isInterruptionRequested())
{
SDL_Event event;
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
{
goto end;
break;
}
case SDL_MOUSEBUTTONUP:
{
showClick(event,renderer,texture);
break;
}
}
}
end:
SDL_DestroyRenderer(renderer);
SDL_DestroyTexture(texture);
SDL_DestroyWindow(window);
SDL_Quit();//初始化子系统后必须做一个退出操作
}
SDL_Texture *playThread::createTexture(SDL_Renderer *renderer)
{
//创建一个纹理对象
SDL_Texture *texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGB24,
SDL_TEXTUREACCESS_TARGET,
50,50);
if(!texture)
{
//创建失败
return nullptr;
}
//设置纹理为渲染目标
if(SDL_SetRenderTarget(renderer,texture))
{
return nullptr;
}
//设置颜色
if(SDL_SetRenderDrawColor(renderer,255,255,0,SDL_ALPHA_OPAQUE))
{
return nullptr;
}
//画图形
SDL_Rect rect = {0,0,50,50};
if(SDL_RenderDrawRect(renderer,&rect))
{
return nullptr;
}
if(SDL_RenderDrawLine(renderer,0,0,50,50))
{
return nullptr;
}
if(SDL_RenderDrawLine(renderer,50,0,0,50))
{
return nullptr;
}
return texture;
}
void playThread::showClick(SDL_Event &event, SDL_Renderer *renderer,SDL_Texture *texture)
{
SDL_MouseButtonEvent btn = event.button;
int w = 0,h = 0;
if(SDL_QueryTexture(texture,nullptr,nullptr,&w,&h))
{
return;
}
int x = btn.x - (w >> 1);
int y = btn.y - (h >> 1);
SDL_Rect dstRect = {x,y,w,h};
//SDL_RenderClear(renderer);
//赋值纹理到渲染目标
SDL_RenderCopy(renderer,texture,nullptr,&dstRect);
//更新渲染操作到屏幕上
SDL_RenderPresent(renderer);
}