sdl实现texture透明

 sdl可以实现一些图片,文字透明,实现renderer透明。这里说的是texture透明,关于其他透明函数,请查看:点击打开链接

  如果闪退,尝试更改字体路径。

  效果图:


  代码:


#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
//显示的texture的数量
const int TexNum =3;
SDL_Window*window=NULL;
SDL_Renderer*renderer=NULL;

//窗口类
class Window
{
    public:
    //记录是否加载成功
    bool load;
    //构造函数
    Window(char title[20], Uint32 w=720, Uint32 h=1280, int flag=0)
   {
        load=false;
        if (!SDL_Init(SDL_INIT_VIDEO))
        if (window=SDL_CreateWindow(title, 0, 0, w, h, flag))
        if (renderer=SDL_CreateRenderer(window, -1, 0))
        {
            //加载窗口成功
            load=true;
        }
    }
    
    //析构函数
    ~Window()
    {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
    }

    //填充窗口:白色
    void fullWindow()
    {
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderFillRect(renderer, NULL);
    }

    //刷新窗口
    void reflush()
    {
SDL_RenderPresent(renderer);
SDL_RenderClear(renderer);
    }
};

//文字类
class Font
{
    public:
    TTF_Font*font; 
    //构造函数:size为字体大小
    Font(int size=70)
    {
        TTF_Init();
font=TTF_OpenFont("./resource/DroidSansFallback.ttf", size);
    }

    //析构函数
    ~Font()
    {
        TTF_CloseFont(font);
        font=0;
        TTF_Quit();
    }

    //把文字加载成texture
SDL_Texture*loadTex(char*str, int type=4)
    {
        switch (type)
        {
            case 0:TTF_SetFontStyle(font,TTF_STYLE_BOLD);break; //粗体
            case 1:TTF_SetFontStyle(font,TTF_STYLE_ITALIC);break; //斜体
            case 2:TTF_SetFontStyle(font,TTF_STYLE_UNDERLINE);break; //下划线
            case 3:TTF_SetFontStyle(font,TTF_STYLE_STRIKETHROUGH);break; //删除线
            case 4:TTF_SetFontStyle(font,TTF_STYLE_NORMAL);break; //正常
        }

        //文字颜色:黑色
        SDL_Color color={0, 0, 0, 255};
        
SDL_Surface*surface=TTF_RenderUTF8_Blended(font, str, color);

SDL_Texture*texture=SDL_CreateTextureFromSurface(renderer, surface);

SDL_FreeSurface(surface);
        return texture;

    }

};

//纹理类
class Tex
{
    public:
    SDL_Texture*tex[TexNum];
    SDL_Rect box[TexNum];
    Font font;
    //特效texture
    SDL_Texture*texture;
    SDL_Rect TexBox;
    Uint8 alpha=255;
    //构造函数
    Tex()
    {
        char *str[TexNum]={"逐渐透明", "逐渐显现", "退出"}; 
        for (int i=0; i<TexNum; i++)
        {
tex[i]=font.loadTex(str[i]);
        int w,h;
//获取纹理大小
        SDL_QueryTexture(tex[i], NULL, NULL, &w, &h);
//设置纹理的大小
        box[i].w=w;
        box[i].h=h;
        }
//设置纹理的坐标
        box[0].x=50;
        box[0].y=800;
        box[1].x=400;
        box[1].y=800;
        box[2].x=270;
        box[2].y=950;
//设置特效texture
Font BigFont(150);
texture=BigFont.loadTex("texture");
        int w,h;
//获取纹理大小
        SDL_QueryTexture(texture, NULL, NULL, &w, &h);
TexBox.w=w;
TexBox.h=h;
    }

    //析构函数
    ~Tex()
    {
        for (int i=0; i<TexNum; i++)
        {
            if (tex[i]!=NULL)
       SDL_DestroyTexture(tex[i]);
        }
SDL_DestroyTexture(texture);
    }
    //显示tex
    void showTex(int n)
    {
SDL_RenderCopy(renderer, tex[n], NULL, &box[n]);
    }
//显示特效texture
void showTexture(int x=100, int y=250)
{
TexBox.x=x;     TexBox.y=y;
SDL_SetTextureBlendMode(texture,SDL_BLENDMODE_BLEND);//设置texture透明度模式
SDL_SetTextureAlphaMod(texture,alpha);//设置texture透明度
SDL_RenderCopy(renderer, texture, NULL, &TexBox);
	}
};

//按钮类
class Button
{
    SDL_Event event;
    SDL_Rect box[TexNum];
    //屏幕分辨率
    int win_w,win_h;
	public :
	Tex tex;
	int m=-1; //按下和移动时按钮索引
	int n=-1;  //抬起时按钮索引
	//构造函数
	Button()
	{
		//获取屏幕分辨率
SDL_GetWindowSize(window, &win_w, &win_h);
		//获取tex文字大小和坐标
		for (int i=0; i<TexNum; i++)
		{
			box[i].x=tex.box[i].x;
			box[i].y=tex.box[i].y;
			box[i].w=tex.box[i].w;
			box[i].h=tex.box[i].h;
			}
		}
	void touch()
	{
			while (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
//手指按下
case SDL_FINGERDOWN:
//手指滑动
case SDL_FINGERMOTION:{
	//event.tfinger.x和event.tfinger.y值范围:0~1
SDL_Point point={event.tfinger.x*win_w, event.tfinger.y*win_h};
for (int i=0; i<TexNum; i++)
//判断触点是否在box矩形中中
if (SDL_PointInRect(&point, &box[i]))
m=i;
	}break;
//手指抬起
				case SDL_FINGERUP:{
//event.tfinger.x和event.tfinger.y值范围:0~1
SDL_Point point={event.tfinger.x*win_w, event.tfinger.y*win_h};
for (int i=0; i<TexNum; i++)
//判断触点是否在box矩形中
if (SDL_PointInRect(&point, &box[i]))
n=i;
m=-1;
					}break;
				}
			}
		}
	void show()
	{
		//绘画填充矩形
		for (int i=0; i<TexNum; i++)
		{
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 0);
SDL_RenderFillRect(renderer, &box[i]);
			}
		if (m!=-1)
		{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 0);
SDL_RenderFillRect(renderer, &box[m]);	
			}	
			//显示文字
			for (int i=0; i<TexNum; i++)
			tex.showTex(i);
		}
	};

//主函数
int main(int argc, char**argv)
{
    Window win("多个按钮");
    Button button;
    while (win.load)
    {
    	button.touch();
    	button.show();
    	switch (button.n)
    	{
    		case -1:{
button.tex.showTexture();
    			}break;
    		case 0:{
if (button.tex.alpha>0)  //alpha值在0~255,要限制一下
button.tex.alpha--;
button.tex.showTexture();
    			}break;
    		case 1:{
if (button.tex.alpha<255)
button.tex.alpha++;
button.tex.showTexture();
    			}break;
    		case 2:{
    			win.load=false;
    			}break;
  


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用FFmpeg和SDL实现音频播放,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了FFmpeg和SDL库。 2. 创建一个C/C++源文件,并包含必要的头文件: ```c #include <stdio.h> #include <SDL2/SDL.h> #include <libavformat/avformat.h> #include <libavutil/opt.h> #include <libswresample/swresample.h> ``` 3. 初始化FFmpeg和SDL库: ```c av_register_all(); avformat_network_init(); SDL_Init(SDL_INIT_AUDIO); ``` 4. 打开音频文件并解码音频流: ```c AVFormatContext *formatCtx = NULL; if (avformat_open_input(&formatCtx, "audio.mp3", NULL, NULL) != 0) { // 处理打开文件失败的情况 return -1; } if (avformat_find_stream_info(formatCtx, NULL) < 0) { // 处理获取流信息失败的情况 return -1; } int audioStreamIndex = -1; for (int i = 0; i < formatCtx->nb_streams; i++) { if (formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audioStreamIndex = i; break; } } if (audioStreamIndex == -1) { // 处理没有找到音频流的情况 return -1; } AVCodecParameters *codecPar = formatCtx->streams[audioStreamIndex]->codecpar; AVCodec *codec = avcodec_find_decoder(codecPar->codec_id); if (codec == NULL) { // 处理找不到解码器的情况 return -1; } AVCodecContext *codecCtx = avcodec_alloc_context3(codec); if (avcodec_parameters_to_context(codecCtx, codecPar) < 0) { // 处理解码器参数设置失败的情况 return -1; } if (avcodec_open2(codecCtx, codec, NULL) < 0) { // 处理打开解码器失败的情况 return -1; } ``` 5. 配置SDL音频参数: ```c SDL_AudioSpec wantedSpec, obtainedSpec; wantedSpec.freq = codecCtx->sample_rate; wantedSpec.format = AUDIO_S16SYS; wantedSpec.channels = codecCtx->channels; wantedSpec.silence = 0; wantedSpec.samples = 1024;wantedSpec.callback = audio_callback; wantedSpec.userdata = codecCtx; SDL_OpenAudio(&wantedSpec, &obtainedSpec); SDL_PauseAudio(0); ``` 6. 实现SDL音频回调函数: ```c void audio_callback(void *userdata, Uint8 *stream, int len) { AVCodecContext *codecCtx = (AVCodecContext *)userdata; AVPacket packet; static uint8_t audio_buffer[(192000 * 3) / 2]; static unsigned int audio_buffer_size = 0; static unsigned int audio_buffer_index = 0; while (len > 0) { if (audio_buffer_index >= audio_buffer_size) { int ret = av_read_frame(formatCtx, &packet); if (ret < 0) { // 处理读取音频帧失败的情况 break; } if (packet.stream_index == audioStreamIndex) { ret = avcodec_send_packet(codecCtx, &packet); if (ret < 0) { // 处理发送音频帧给解码器失败的情况 break; } ret = avcodec_receive_frame(codecCtx, &frame); if (ret < 0) { // 处理接收解码后的音频帧失败的情况 break; } int data_size = av_samples_get_buffer_size(NULL, codecCtx->channels, frame->nb_samples, codecCtx->sample_fmt, 1); memcpy(audio_buffer, frame->data[0], data_size); audio_buffer_size = data_size; audio_buffer_index = 0; } av_packet_unref(&packet); } int remaining = audio_buffer_size - audio_buffer_index; int to_copy = len > remaining ? remaining : len; memcpy(stream, audio_buffer + audio_buffer_index, to_copy); len -= to_copy; stream += to_copy; audio_buffer_index += to_copy; } } ``` 7. 清理资源并关闭SDL和FFmpeg库: ```c SDL_CloseAudio(); SDL_Quit(); avformat_close_input(&formatCtx); avcodec_free_context(&codecCtx); return 0; ``` 以上是一个简单的示例,演示了如何使用FFmpeg和SDL实现音频播放。您可以根据自己的需求进行调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值