向左右向右走 —— 小时了了的技术博客

关注C++开发技术、架构设计、软件项目管理、软件产品管理等

摘要: 创建纹理 有三个 API 可以用来创建纹理: SDL_CreateTexture 参数少,使用方便,适用于创建简单的纹理 SDL_CreateTextureFromSurface 适用于从已有图像数据创建纹理 SDL_CreateTextureWithProperties 可以指定各种属性,功能强大 阅读全文
posted @ 2024-07-14 20:35 小时了了 阅读(454) 评论(0) 推荐(1) 编辑
摘要: SDL2 创建渲染器时只能指定使用软件渲染还是硬件加速,无法选择使用哪种图形引擎实现硬件加速。SDL3 对此做了优化,可以在创建渲染器时指定 rendering driver 也就是图形引擎,比如在 Windows 平台下可以指定使用 D3D11 也可以指定使用 OpenGL 或者 Vulkan。 阅读全文
posted @ 2024-06-29 14:25 小时了了 阅读(790) 评论(2) 推荐(0) 编辑
摘要: SDL3 提供了 SDL_RenderGeometry 函数绘制几何图形,用法和 OpenGL 差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。 绘制三角形的代码如下: std::array<SDL_Vertex, 3> origin_vertices = { SDL_Vertex { { 1 阅读全文
posted @ 2024-06-23 20:50 小时了了 阅读(474) 评论(0) 推荐(3) 编辑
摘要: 在上一篇文章中我们已经利用 SDL 的日志接口实现了简单的字符串输出,实际上是解决了开发环境搭建问题,接下来我们将在已有代码的基础上继续开发,实现第一个窗口的创建和背景色绘制。 初始化 首先设置日志输出级别: SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE 阅读全文
posted @ 2024-06-13 23:28 小时了了 阅读(752) 评论(0) 推荐(0) 编辑
摘要: 在本系列中我们使用 Windows Terminal + Powershell 组合作为我们在 Windows 系统下的终端工具,Windows 11 自带该环境。你也可以使用任意自己喜欢的终端环境代替,或使用鼠标执行等价的操作。 源码准备 我们使用 git 管理我们的项目,所以首先我们创建一个名为 阅读全文
posted @ 2024-06-10 21:45 小时了了 阅读(1757) 评论(2) 推荐(0) 编辑
摘要: 自 VS2010 起,微软就在 CRT 中集成了并发运行时(Concurrency Runtime),并行模式库(PPL,Parallel Patterns Library)是其中的一个重要组成部分。7 年过去了,似乎大家都不怎么Care这个事情,相关文章少少且多是蜻蜓点水。实际上这个库的设计相当精 阅读全文
posted @ 2017-06-17 10:14 小时了了 阅读(1923) 评论(0) 推荐(1) 编辑
摘要: 有两个 API 可以实现保存 GUID 到 VARIANT InitVariantFromGUIDAsBuffer 以字节数组形式保存,保存类型为 VT_ARRAY | VT_UI1,相当于字节拷贝,理论上效率更高; InitVariantFromGUIDAsString 以字符串形式保存,保存类型 阅读全文
posted @ 2017-02-21 20:41 小时了了 阅读(239) 评论(0) 推荐(0) 编辑
摘要: 这两天写的代码概率性的崩溃在 XMMatrixMultiply() 函数,XMMatrixMultiply() 本身是 inline 函数可以看到崩溃处的代码: vX = _mm_mul_ps(vX,M2.r[0]); 经查,_mm_mul_ps 是 SSE2 指令要求内存地址 16 字节对齐。猜想 阅读全文
posted @ 2016-03-06 14:35 小时了了 阅读(1196) 评论(1) 推荐(1) 编辑
摘要: WRL::ComPtr 取原始指针的地址有两种方式: 显然,operator& 是为COM风格的API设计的,比如下面这种: 在这一点上和 ATL::CComPtr 一致,实现上则有不同。上面这种 API 最容易出现的错误是传了一个非空指针的地址给 ppObj ,然后指针被覆盖导致原来指向的对象无法 阅读全文
posted @ 2016-03-05 23:28 小时了了 阅读(1863) 评论(1) 推荐(1) 编辑
摘要: IStream 和IRandomAccessStream^ 互转 IRandomAccessStream^ -->IStream:CreateStreamOverRandomAccessStream IStream -->IRandomAccessStream^: CreateRandomAcc... 阅读全文
posted @ 2015-10-18 12:04 小时了了 阅读(747) 评论(9) 推荐(1) 编辑
摘要: StorageFile.ContentType 属性,是 string 类型,用来表示文件内容的 MIME 类型。例如,音乐文件可能有 "audio/mpeg" MIME 类型。(MSDN)MIME 类型的定义可以下面的链接找到:MIME Types -http://blogs.msdn.com/b... 阅读全文
posted @ 2015-10-10 19:16 小时了了 阅读(502) 评论(2) 推荐(1) 编辑
摘要: 在UWP中加载文件一般先创建StorageFile 对象,然后调用StorageFile.OpenReadAsync 方法得到一个IRandomAccessStream 接口用来读取数据:1 StorageFile image_file = await StorageFile.GetFileFrom... 阅读全文
posted @ 2015-10-04 17:35 小时了了 阅读(1122) 评论(0) 推荐(0) 编辑
摘要: 纤程(Fiber)和协程(coroutine)是差不多的概念,也叫做用户级线程或者轻线程之类的。Windows系统提供了一组API用户创建和使用纤程,本文中的库就是基于这组API实现的。纤程的概念中有两个关键点: 纤程拥有独立的栈空间和寄存器环境; 纤程在用户态实现调调度,也就是说完全由程序员控制; 阅读全文
posted @ 2014-12-21 21:32 小时了了 阅读(5330) 评论(0) 推荐(2) 编辑
摘要: 提到输入输出流,作为CPPer很自然的就会想到std::iostream,对于文本流的处理,iostream可以说足够强大,应付一般复杂度的需求毫无压力。对二进制流处理却只能用“简陋”来形容,悲催的是,作为一个在多媒体软件领域默默耕耘多年的码农日常打交道最多的偏偏就是二进制流。前些年流行过一本书叫做... 阅读全文
posted @ 2014-08-06 23:15 小时了了 阅读(2263) 评论(1) 推荐(1) 编辑
摘要: StretchBlt:从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩,如果目标设备是窗口DC,则意味着在窗口绘制位图,大致的使用代码如下: 1 void DrawImage(HDC hdc, HBITMAP hbm, const RECT target_rect) 2 { 3 HDC hdcMemory = ::CreateCompatibleDC(hdc); 4 HBITMAP old_bmp = (HBITMAP)::SelectObject(hdcMemory, hbm); 5 6 BITMAP bm = { 0 }; 7 ... 阅读全文
posted @ 2014-04-05 13:53 小时了了 阅读(4173) 评论(0) 推荐(1) 编辑
摘要: 任何产品的用户群体都可以划分为高端和低端。对产品有深入学习研究能熟练应用的是高端用户,不擅长技术只做一些简单应用的是低端用户。这里的高端低端是从“使用产品”的角度来看待的,不同的角度会带来不同的划分方式,比如按用户的参与程度划分成活跃用户和非活跃用户,一个用户可能是高端的活跃用户,也可能是高端的非活跃用户。这里要强调的是下面几个观点:第一,高低端的划分是针对特定产品的,在一类产品中属于高端的用户在另一类产品中可能属于低端用户。这很容易理解,比如我可算是Visual Studio的高端用户,但对Photoshop我就是绝对的低端用户。第二,用户是不断成长的,有一个从低端到高端的过程。开始用一个产 阅读全文
posted @ 2011-11-19 11:00 小时了了 阅读(623) 评论(0) 推荐(0) 编辑
摘要: 经常看到有人问程序员适合做管理吗,或者手底下有牛人比我技术更好怎么办,或者感叹一下做管理好难啊之类的。同时,相当大的一部分程序员都梦想着走所谓专家路线——并不是因为对技术特别有兴趣或者觉得自己特别适合走技术路线,真正的原因是对管理工作的恐惧,觉得自己搞不定定。做管理真的很难吗,程序员出身到底适不适合做管理,我可以斩钉截铁的告诉你:不难!适合!上面的答案显然并不完全正确。不过我们今天我们讨论的并不是管理一个国家那样的管理,也不是管理一个公司或者半个公司这样的管理——绝大部分程序员同志们短时间内都不会有这样的机会,这样的话题也完全超出了我的知识范畴。我们今天讨论的只是基础的简单的管理,小到几个人的 阅读全文
posted @ 2011-11-15 00:05 小时了了 阅读(299) 评论(1) 推荐(0) 编辑
摘要: 前几天为了查找一个BUG花了几乎一整天的时间,然后——就像江湖传说的一样,只改了一行代码就搞定了。至于原因仅仅是因为一个变量未初始化,一秒钟的疏忽却花了一天的代价来弥补,就像那个蚂蚁和大象的段子:风流了一夜,挖一辈子的坑。 这类BUG通常是不稳定重现的测试未必测的出来,测出来了也未必容易定位,若是不小心留到了用户那里可能真的就成了一辈子的坑,永远都解决不掉了。这样的事我想命苦的C++程序员们初入江湖的时候可能都遇到过那么一两回。——声明一下,以前我也搞出过这样的BUG,但从那之后没再犯第二次错误,这次的代码是别人写的。 俗话说人是靠不住的,只有靠制度才有保障,哪怕我们再小心也总有马虎大... 阅读全文
posted @ 2011-11-11 00:38 小时了了 阅读(2146) 评论(9) 推荐(3) 编辑
摘要: 前几天博客园编辑推荐了一篇文章《“品质在于构建过程”吗?》,对决定软件品质的核心要素进行了许多探讨。我今天想讨论的也是这个话题。 “品质在于构建过程”并不是什么惊骇世俗的新观点,实际上类似的说法由来已久,比如“过程决定质量”,“品质在于构建过程”只是有软件行业特色的另一种表达形式而已。那么“过程决定质量”的说法是哪来的呢?答案是工业工程,如果你从事过工业制造行业,比如汽车制造、手机制造之类的,几乎不可能没听说过这句话。首先我们辨析一下工业工程和软件工程这两个概念,下面是来自百度百科的定义:工业工程(Industrial Engineering 简称IE),是从科学管理的基础上发展起来的一... 阅读全文
posted @ 2011-11-05 22:10 小时了了 阅读(1508) 评论(6) 推荐(2) 编辑
摘要: 事情缘起于代码走读会议的一次讨论。基本的需求很简单,就是实现类似下面这样一个函数:HRESULT GetText(/* [out] */BSTR* pText); 很自然地,首先写出来的实现是这样的:HRESULT GetText(/* [out] */BSTR* pText){ ASSERT(pText != NULL); *pText = ::SysAllocString(L"This is the text."); return S_OK;} 它的调用方式如下(这里为了简单起见我们忽略掉了对返回值的判断): BSTR bstText = NULL; GetText(& 阅读全文
posted @ 2011-10-30 11:55 小时了了 阅读(1329) 评论(5) 推荐(5) 编辑