环境配置
1.SDL配置
下载源码:http://www.libsdl.org/download-2.0.php
进入到 SDL2-2.0.14\VisualC 用visual studio 2019 打开 SDL.sln
将工程升级到vs2019选择对的,debug|release x64|x86进行编译生成相应的.dll、.pdb和.lib
然后将对应的.dll、.pdb和.lib放到对应目录中,并配置值相应的工程目录
2.QT配置
下载Qt安装包:https://www.qt.io/download(下载opensource版) 清华镜像 https://mirrors.tuna.tsinghua.edu.cn/
下载qt目录下的对应版本双击安装,中途需要登录qt的官网账号,安装时需要安装Qtcreat组件。
进入vsaddin目录再下载和vs版本相匹配的Qt Vs插件安装。
进入VS安装管理器的界面,安装需要环境依赖。
3.vs创建Qt工程
使用VS创建工程,选择QT模板
选择响应的QT版本
创建QT文件,注意勾选文件名小写,保证工程在不同系统上的迁移
管理Qt版本
API介绍
重载定时器函数,在Qt类头文件中声明
#pragma once
#include <QtWidgets/QWidget>
#include "ui_sdlqtrgb.h"
class SdlQtrgb : public QWidget
{
Q_OBJECT
public:
SdlQtrgb(QWidget *parent = Q_NULLPTR);
void timerEvent(QTimerEvent* ev) override; //重载函数后,需要再后边注明 override 防止出错
private:
Ui::SdlQtrgbClass ui;
};
在初始化Qt类函数的最后调用startTime循环调用,则初始化完Qt类后,每隔10ms就调用一次
SdlQtrgb::SdlQtrgb(QWidget *parent)
: QWidget(parent)
{
......
startTimer(10);
}
代码样例
头文件
#pragma once
#include <QtWidgets/QWidget>
#include "ui_sdlqtrgb.h"
class SdlQtrgb : public QWidget
{
Q_OBJECT
public:
SdlQtrgb(QWidget *parent = Q_NULLPTR);
void timerEvent(QTimerEvent* ev) override;
private:
Ui::SdlQtrgbClass ui;
};
类的定义
#include "sdlqtrgb.h"
#include<sdl2/SDL.h>
#include<iostream>
#include<qmessagebox.h>
#pragma comment(lib,"SDL2.lib")
//定义SDL全局变量
static SDL_Window* sdl_win = NULL;
static SDL_Renderer* sdl_render = NULL;
static SDL_Texture* sdl_texture = NULL;
static int sdl_width = 0;
static int sdl_height = 0;
static int pixsel_size = 4;
static unsigned char* rgb = NULL;
//定义Qt类的初始化函数,其中对SDL的固定属性配置进行初始化
SdlQtrgb::SdlQtrgb(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//sdl_width = ui.label->width();
//sdl_height = ui.label->height();
//1.初始化SDL库
if (SDL_Init(SDL_INIT_VIDEO))
{
std::cout << SDL_GetError() << std::endl;
return;
}
//2.创建窗口
sdl_win = SDL_CreateWindowFrom((void*)ui.label->winId()); //将窗口与QT中的类绑定
if (!sdl_win)
{
std::cout << SDL_GetError() << std::endl;
return;
}
//3.创建渲染器
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
if (!sdl_render)
{
std::cout << SDL_GetError() << std::endl;
return;
}
QImage img1("1.jpeg"); QImage img2("2.jpeg");
if (img1.isNull() || img2.isNull())
{
QMessageBox::information(this,"","open image failed!");
return;
}
//做数据对齐
int out_w = img1.width() + img2.width();
int out_h = img1.height() < img2.height() ? img2.height() : img1.height();
//改变窗口大小
sdl_height = out_h;
sdl_width = out_w;
ui.label->move(0, 0);
ui.label->resize(sdl_width, sdl_height);
//4.创建纹理
sdl_texture = SDL_CreateTexture(sdl_render,
SDL_PIXELFORMAT_ABGR8888,
SDL_TEXTUREACCESS_STREAMING,
sdl_width,
sdl_height
);
if (!sdl_texture)
{
std::cout << SDL_GetError() << std::endl;
return;
}
rgb = new unsigned char[sdl_width * sdl_height * pixsel_size];
//合并两幅图像,默认设置为透明
memset(rgb, 0, sdl_width * sdl_height * pixsel_size);
for (int i = 0; i < sdl_height; i++)
{
int b = i * sdl_width * pixsel_size;
if (i < img1.height())
memcpy(rgb + b, img1.scanLine(i), img1.width() * pixsel_size);
b += img1.width()*pixsel_size;
if (i < img2.height())
memcpy(rgb + b, img2.scanLine(i), img2.width() * pixsel_size);
}
startTimer(10); //调用定时器函数
}
//定时器函数,在其中调用SDL对图像进行循环渲染
void SdlQtrgb::timerEvent(QTimerEvent* ev)
{
//static unsigned char tmp = 255;
//tmp--;
//for (int j = 0; j < sdl_height; j++)
//{
// int b = j * sdl_width * pixsel_size;
// for (int i = 0; i < sdl_width * pixsel_size; i += pixsel_size)
// {
// rgb[b + i] = 0; //B
// rgb[b + i + 1] = 255 - tmp; //G
// rgb[b + i + 2] = 0; //R
// rgb[b + i + 3] = 0; //A
// }
//}
SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pixsel_size);
SDL_RenderClear(sdl_render);
SDL_Rect sdl_rect;
sdl_rect.x = 0;
sdl_rect.y = 0;
sdl_rect.w = sdl_width;
sdl_rect.h = sdl_height;
SDL_RenderCopy(sdl_render, sdl_texture, NULL, &sdl_rect);
SDL_RenderPresent(sdl_render);
}
其中Qt窗口的创建,可以使用Qtcreater打开.ui文件内来创建,右上角为类的类型与类名,左下角的为该类的属性配置