第15章 《乐趣》Page355~375 纹理,渲染器,代码简化版

运行效果:全屏了

简化之后的代码如下:

//main.cpp
#include <iostream>
#include <SDL2/SDL.h>
#include "sdl_initiator.hpp"
#include "sdl_error.hpp"
#include "sdl_window.hpp"
#include "sdl_surface.hpp"
#include "sdl_renderer.hpp"
#include "sdl_texture.hpp"using namespace std;//加载图片为纹理,并设置透明色
SDL_Texture* LoadBMPTexture(SDL_Renderer* renderer, char const* filename, Uint8 key_r, Uint8 key_g, Uint8 key_b)
{sdl2::BitmapSurface bmp(filename);if(!bmp){return nullptr;}bmp.EnableColorKey(key_r, key_g, key_b, 0);return sdl2::Texture(renderer, bmp._surface).Release();
}
//加载图片为纹理,不透明,不混色
SDL_Texture* LoadBMPTexture(SDL_Renderer* renderer, char const* filename)
{sdl2::BitmapSurface bmp(filename);if(!bmp){return nullptr;}return sdl2::Texture(renderer, bmp._surface).Release();
}
//加载图片为纹理,并设置透明色和混色
SDL_Texture* LoadBMPTexture(SDL_Renderer* renderer, char const* filename, Uint8 key_r, Uint8 key_g, Uint8 key_b, Uint8 alpha_mod, SDL_BlendMode blend_mode = SDL_BLENDMODE_BLEND)
{sdl2::BitmapSurface bmp(filename);if(!bmp){return nullptr;}bmp.EnableColorKey(key_r, key_g, key_b, 0);bmp.SetAlphaMod(alpha_mod);bmp.SetBlendMode(blend_mode);return sdl2::Texture(renderer, bmp._surface).Release();
}
int main(int argc, char* argv[])
{sdl2::Initiator::Instance().Init(SDL_INIT_VIDEO| SDL_INIT_AUDIO| SDL_INIT_EVENTS| SDL_INIT_TIMER);if(!sdl2::Initiator::Instance())//重载转换符{cerr << "初始化就出错,没得玩了!"<< sdl2::last_error() << endl;}//创建并居中显示宽640,高480的游戏窗口sdl2::Window wnd("hello sdl", sdl2::WindowPosition(), 640, 480//使用空的特性标志, sdl2::WindowFlags().FullScreenDesktop());if(!wnd){cerr << sdl2::last_error() << endl;return -1;}//准备窗口的渲染器sdl2::Renderer renderer(wnd._window);if(!renderer){cerr << sdl2::last_error() << endl;return -1;}//重要!修改缩放质量配置sdl2::RendererDriver::HintScaleQuality();//重要!设置虚拟大小renderer.SetLogicalSize(640, 480);//准备背景图(不需要透明和混色)sdl2::Texture bkgnd(LoadBMPTexture(renderer._renderer, "bkgnd.bmp"));if(!bkgnd){cerr << sdl2::last_error() << endl;return -1;}//准备小马图,透明色为白色sdl2::Texture horse(LoadBMPTexture(renderer._renderer, "sdl.bmp", 0xff, 0xff, 0xff));if(!horse){cerr << sdl2::last_error() << endl;return -1;}//准备白云图纹理,透明色为红色,不透明度188(0~255)sdl2::Texture cloud(LoadBMPTexture(renderer._renderer, "cloud.bmp", 0xff, 0, 0, 188));if(!cloud){cerr << sdl2::last_error() << endl;return -1;}//事件循环bool Q = false;while(!Q)//一直循环,直到Q为真{SDL_Event event;//会将队列中拖出的event数据存储到event中while(SDL_PollEvent(&event)){switch(event.type){case SDL_QUIT:Q = true;break;}}//内循环/*外循环:贴骏马图*///贴背景->窗口renderer.CopyFrom(bkgnd._texture);//贴第一朵白云SDL_Rect cloud_rect_1{200, 20, 156, 78};renderer.CopyFrom(cloud._texture, nullptr, &cloud_rect_1);//贴第二朵白云SDL_Rect cloud_rect_2{340, 6, 156, 78};renderer.CopyFrom(cloud._texture, nullptr, &cloud_rect_2);//贴骏马SDL_Rect dst_rect{86, 65, 468, 350};renderer.CopyFrom(horse._texture, nullptr, &dst_rect);renderer.Present();SDL_Delay(1);//防止cpu占用率太高
//        Q = true; //开发过程中,为方便程序退出,暂时这样}//外循环return 0;
}

//sdl_error.cpp
#include "sdl_error.hpp"namespace sdl2
{char const* last_error()
{return SDL_GetError();
}}//sdl2

//sdl_error.hpp
#ifndef SDL_ERROR_HPP_INCLUDED
#define SDL_ERROR_HPP_INCLUDED
#include <SDL2/SDL.h>namespace sdl2
{
char const* last_error();
}#endif // SDL_ERROR_HPP_INCLUDED

//sdl_initiator.hpp
#ifndef SDL_INITIATOR_HPP_INCLUDED
#define SDL_INITIATOR_HPP_INCLUDEDnamespace sdl2
{struct Initiator
{
private: //单例模式,外界无需使用构造函数Initiator(): _init_result(-1){}public:static Initiator& Instance(){static Initiator Instance;return Instance;}~Initiator(){SDL_Quit();}void GetVersion(Uint8& major, Uint8& minor, Uint8& patch){SDL_version ver;SDL_GetVersion(&ver);major = ver.major;minor = ver.minor;patch = ver.patch;}bool Init(Uint32 flags = SDL_INIT_EVERYTHING){_init_result = SDL_Init(flags);return 0 == _init_result;}//    bool operator bool()explicit operator bool() const{return _init_result == 0;}private:int _init_result;
};//Initiator}//sdl2#endif // SDL_INITIATOR_HPP_INCLUDED

//sdl_renderer.hpp
#ifndef SDL_RENDERER_HPP_INCLUDED
#define SDL_RENDERER_HPP_INCLUDEDnamespace sdl2
{
//渲染驱动(方法均为静态)
struct RendererDriver
{static bool HintScaleQuality(char const* quality = "linear"){return SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, quality);}
};struct Renderer
{Renderer(SDL_Window* window, int index = -1, Uint32 flags = 0){_renderer = SDL_CreateRenderer(window, index, flags);}~Renderer(){SDL_assert(_renderer != nullptr);SDL_DestroyRenderer(_renderer);}bool SetLogicalSize(int w, int h){SDL_assert(_renderer != nullptr);return 0 == SDL_RenderSetLogicalSize(_renderer, w, h);}bool CopyFrom(SDL_Texture* src_texture, const SDL_Rect* src_rect = nullptr, const SDL_Rect* dst_rect = nullptr){SDL_assert(_renderer != nullptr);SDL_assert(src_texture != nullptr);return 0 == SDL_RenderCopy(_renderer, src_texture, src_rect, dst_rect);}void Present(){SDL_assert(_renderer != nullptr);SDL_RenderPresent(_renderer);}explicit operator bool() const{return _renderer != nullptr;}SDL_Renderer* _renderer;
};//Renderer}//sdl2#endif // SDL_RENDERER_HPP_INCLUDED

//sdl_surface.hpp
#ifndef SDL_SURFACE_HPP_INCLUDED
#define SDL_SURFACE_HPP_INCLUDEDnamespace sdl2
{struct Surface
{//代管外部创建好的surface指针explicit Surface(SDL_Surface* surface): _surface(surface){}/*父类的析构函数使用虚函数的主要原因是为了确保多态时的正确清理。在C++中,析构函数主要用于释放动态分配的资源。如果父类的析构函数不是虚函数,那么当使用子类指针删除父类对象时,由于没有动态绑定(晚绑定),只会调用父类的析构函数,而不会调用子类的析构函数。这样,子类中的资源可能不会被正确释放,导致内存泄漏或其他问题。如果父类的析构函数是虚函数,那么当使用子类指针删除父类对象时,会根据实际对象的类型动态调用相应的析构函数。这样,既可以释放父类占用的资源,又可以释放子类占用的资源,确保资源的正确释放。因此,为了确保多态时的正确清理,父类的析构函数应该声明为虚函数。*/virtual ~Surface(){SDL_assert(_surface != nullptr);SDL_FreeSurface(_surface);};bool SetAlphaMod(Uint8 alpha){SDL_assert(_surface != nullptr);return 0 == SDL_SetSurfaceAlphaMod(_surface, alpha);}bool SetBlendMode(SDL_BlendMode const& mode){SDL_assert(_surface != nullptr);return 0 == SDL_SetSurfaceBlendMode(_surface, mode);}//    EnableColorKey(Uint32 r, Uint32 g, Uint32 b, Uint32 a)bool EnableColorKey(Uint8 r, Uint8 g, Uint8 b, Uint8 a){SDL_assert(_surface != nullptr);Uint32 key = SDL_MapRGBA(_surface->format, r, g, b, a);return 0 == SDL_SetColorKey(_surface, SDL_TRUE, key);}bool BlitTo(SDL_Surface* dst_surface, SDL_Rect* src_rect, SDL_Rect* dst_rect){SDL_assert(_surface != nullptr);return 0 == SDL_BlitSurface(_surface, src_rect, dst_surface, dst_rect);}explicit operator bool() const{return _surface != nullptr;}SDL_Surface* _surface;
};//来自位图的表层
struct BitmapSurface : public Surface
{explicit BitmapSurface (char const* filename): Surface(SDL_LoadBMP(filename)){}
};}//sdl2#endif // SDL_SURFACE_HPP_INCLUDED

//sdl_texture.hpp
#ifndef SDL_TEXTURE_HPP_INCLUDED
#define SDL_TEXTURE_HPP_INCLUDEDnamespace sdl2
{struct Texture
{Texture(SDL_Texture* texture): _texture(texture){}Texture(SDL_Renderer* renderer, SDL_Surface* surface): _texture(SDL_CreateTextureFromSurface(renderer, surface)){}~Texture(){
//        SDL_assert(_texture != nullptr);//_texture不一定就不空,所以需要修改if(_texture)SDL_DestroyTexture(_texture);}SDL_Texture* Release(){SDL_Texture* tmp;tmp = _texture;
//        *tmp = *_texture; //tmp和_texture已经指向同一数据了_texture = nullptr;return tmp;}explicit operator bool() const{return _texture != nullptr;}SDL_Texture* _texture;
};//Texture}//sdl2#endif // SDL_TEXTURE_HPP_INCLUDED

//sdl_window.hpp
#ifndef SDL_WINDOW_HPP_INCLUDED
#define SDL_WINDOW_HPP_INCLUDED#include <SDL2/SDL.h>namespace sdl2
{struct WindowPosition
{WindowPosition()//默认构造: _x(SDL_WINDOWPOS_CENTERED), _y(SDL_WINDOWPOS_CENTERED){}WindowPosition(int x, int y)//常规初始化: _x(x), _y(y){}~WindowPosition(){}WindowPosition& Centered(bool x_centered = true, bool y_centered = true){if(x_centered)_x = SDL_WINDOWPOS_CENTERED;if(y_centered)_y = SDL_WINDOWPOS_CENTERED;}int _x, _y;
};struct WindowFlags
{//默认构造,用于构建一个没有指定任何特性的普通窗口WindowFlags(): _flags(0){}~WindowFlags(){}WindowFlags& FullScreenDesktop(){_flags &= ~SDL_WINDOW_FULLSCREEN;_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;return *this;}Uint32 _flags;
};struct Window
{Window(char const* title, WindowPosition const& win_position, int x, int y, WindowFlags const& win_flags) //必须有const,否则无法引用右值(){_window = SDL_CreateWindow(title, win_position._x, win_position._y, x, y, win_flags._flags);}~Window(){SDL_DestroyWindow(_window);}bool UpdateSurface(){SDL_assert(_window != nullptr);return 0 == SDL_UpdateWindowSurface(_window);}SDL_Surface* GetSurface(){SDL_assert(_window);return SDL_GetWindowSurface(_window);}explicit operator bool() const{return _window != nullptr;}Uint32 GetID(){SDL_assert(_window != nullptr);return SDL_GetWindowID(_window);}bool SetOpacity(float opacity){SDL_assert(_window != nullptr);return 0 == SDL_SetWindowOpacity(_window, opacity);}void Hide(){SDL_assert(_window != nullptr);SDL_HideWindow(_window);}void Show(){SDL_assert(_window != nullptr);SDL_ShowWindow(_window);}SDL_Window* _window;
};}//sdl2#endif // SDL_WINDOW_HPP_INCLUDED

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/283855.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【日常总结】连接Mysql,打开数据表非常慢

问题 Navicat 连接mysql时&#xff0c;第二次打开非常慢 原因 Mysql服务器端会定时清理长时间不活跃空闲的数据库连接&#xff0c;以此优化数据库的性能。 解决方案 数据库右键---编辑连接--高级---保持连接间隔30秒 带来的问题 每次打开Navicat时&#xff0c;设置设置自动…

【论文解读】Kvazaar 2.0: Fast and Efficient Open-Source HEVC Inter Encoder

时间&#xff1a;2020 级别&#xff1a;SCI 机构&#xff1a;Tampere University 摘要&#xff1a;高效视频编码(HEVC)是当前多媒体应用中经济的视频传输和存储的关键&#xff0c;但解决其固有的计算复杂性需要强大的视频编解码器实现。本文介绍了Kvazaar 2.0 HEVC编码器&…

18位身份证编码校验——我国第二代居民身份证

一道校验居民身份证编码校验码的小题&#xff0c;触发了我对我国第二代身份证整串编码的探究。 (笔记模板由python脚本于2023年12月14日 19:49:46创建&#xff0c;本篇笔记适合掌握Python字符串str基本数据类型&#xff0c;可以熟练应用于代码编写中的coder翻阅) 【学习的细节是…

解决:AttributeError: module ‘scipy.misc’ has no attribute ‘imread’

解决&#xff1a;AttributeError: module ‘scipy.misc’ has no attribute ‘imread’ 文章目录 解决&#xff1a;AttributeError: module scipy.misc has no attribute imread背景报错问题报错翻译报错位置代码报错原因解决方法方法一 scipy版本回退&#xff08;不推荐&#…

微机原理与接口技术——输入输出系统

文章目录 一、端口的概念、分类二、端口的编址方式三、最常用的I/O指令1、直接寻址I/O指令&#xff08;八位端口地址&#xff09;2、DX间接寻址指令&#xff08;端口地址>8位&#xff09; 四、微机系统与I/O端口的信息交换图解无条件传送方式查询方式中断方式&#xff08;CP…

01--二分查找

一. 初识算法 1.1 什么是算法&#xff1f; 在数学和计算机科学领域&#xff0c;算法是一系列有限的严谨指令&#xff0c;通常用于解决一类特定问题或执行计算 不正式的说&#xff0c;算法就是任何定义优良的计算过程&#xff1a;接收一些值作为输入&#xff0c;在有限的时间…

Google Gemini API快速上手(附申请步骤)

前言 12月6日&#xff0c;谷歌发布新一代大模型Gemini的demo, 同时&#xff0c;Bard已将模型更新为Gemini Pro Gemini 是谷歌目前最新最强的大语言模型&#xff0c;支持多模态&#xff08;文字&#xff0c;图片&#xff0c;音频&#xff0c;视频等等&#xff09;处理 美国时…

消息队列kafka详解:Kafka原理分析总结

一、概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统&#xff0c;后成为Apache的一部分&#xff0c;它使用Scala编写&#xff0c;以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark等都支持与Kafka集成。 Kaf…

Javaweb考前复习冲刺(不断更新版)

Javaweb考前复习冲刺 第一章&#xff1a; JavaWeb 入门 JavaWeb是指&#xff1a;以Java作为后台语言的项目工程。 javaweb项目创建的过程&#xff1a; 首先集成Tomcat服务器环境新建dynamic web project部署工程运行 路由含义&#xff1a; ​ http://localhost:8080/工程…

AI数字人直播问题及解决方案!

青否数字人SaaS系统&#xff08;数字人源码&#xff1a;zhibo175&#xff09;目前支持哪些平台使用数字人直播 目前支持的平台有&#xff1a;抖音、快手、视频号、淘宝/天猫、京东、小红书、拼多多&#xff0c;哔哩哔哩&#xff0c;tiktok&#xff0c;阿里国际站&#xff0c;用…

【改进YOLOv8】磁瓦缺陷分类系统:改进LSKNet骨干网络的YOLOv8

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 近年来&#xff0c;随着智能制造产业的不断发展&#xff0c;基于人工智能与机器视觉的自动化产品缺陷检测技术在各行各业中得到了广泛应用。磁瓦作为永磁电机的主…

Python PIP安装pycorrector、kemln报错

本来想装个pycorrector用一下&#xff0c;结果在安装其依赖包kemln的时候疯狂报错&#xff0c;报错关键词包括但不限于Bash、Cmake&#xff0c;C啥的&#xff0c;搜了很多文章&#xff0c;终于摸索到了安装的办法。 1、安装bash 去官网https://gitforwindows.org/下载bash&am…