当前位置: 首页 > news >正文

做淘宝客导购网站国家企业信用信息公示官网

做淘宝客导购网站,国家企业信用信息公示官网,北京建设执业网站,做类似于58同城的网站我们可以在资源处理器中使用库 因为我们的资源处理器并不是游戏的一部分#xff0c;所以它可以使用库。我说过我不介意让它使用库#xff0c;而我提到这个的原因是#xff0c;今天我们确实有一个选择——可以使用库。 生成字体位图的两种方式#xff1a;求助于 Windows 或…我们可以在资源处理器中使用库 因为我们的资源处理器并不是游戏的一部分所以它可以使用库。我说过我不介意让它使用库而我提到这个的原因是今天我们确实有一个选择——可以使用库。 生成字体位图的两种方式求助于 Windows 或使用库 基本上我们在资源处理器中有两种方式来实现这一点。一种是直接从Windows获取字体另一种是使用某种库。 最初我的想法是直接展示如何从Windows获取字体因为这样非常直接。当你在Windows上运行资源处理器时你可以直接提取字体而其他平台如Linux也有类似的API可以用来提取字体操作起来也非常简单。 不过经过一番思考尤其是在看到有人提议可以在这里使用库之后我开始重新考虑这个问题。 决定使用 stb 库 如果要使用库的话会选择哪些库。我总是推荐使用STB库因为这些库是由Simon Barrett编写的专门为游戏开发者设计且非常方便集成到项目中。 我的想法是今天可以通过STB库来展示如何获取字体顺便教大家如何使用这些库因为这些库是我推荐的且它们设计得非常简洁易用。由于之前设定的规则是游戏代码中不使用库因此在实际的游戏代码中我们不会使用这些库。这个规则虽然有些随意但也是整个系列的一个原则——游戏的代码要完全由我们从头开始编写。 今天的目的是为了回应大家的请求展示如何使用STB库获取字体同时也可以在之后介绍如何直接通过Windows来获取字体如果有人对此有兴趣的话。而且如果有人想在自己的游戏中使用这个库现在就可以了解如何操作了。 此外STB库的一个好处是它们非常易于使用哪怕是对于那些注重细节的开发者来说也不会像其他一些库那样带来痛苦和困扰。因此使用这些库会非常方便适合各种开发者使用。 stb 库 如果打算使用STB库可以按照以下步骤操作首先搜索“STB libraries”就能找到STB的官方网站网址是stb。在这个页面上提供了很多非常实用的库。 其中STB图像库stb_image是一个很棒的选择能够快速将图像加载功能加入到代码中。这个库只包含一个文件而且支持多种常见的图像格式比如JPEG、PNG、BMP和PSD等。它的实现不会按照完整的规范来读取图像而是只读取游戏开发者通常需要的部分这样能简化使用的复杂度。 如果有人问我如果要用这些库会选择哪些我会推荐这些库因为它们非常简洁易用而且会减少开发过程中的痛苦和困扰。除此之外STB库是公共领域的这意味着没有任何使用限制。你可以自由地分发它们不需要特别的授权或者标注出处。虽然如果使用这些库发布产品时可以适当感谢一下开发者但并不是强制要求的。 在STB官网上每个库都有简单的描述说明它们的用途和功能。总体来说这些库是非常适合开发者使用的特别是当需要快速实现某些功能时STB库可以大大减少开发难度。 https://github.com/nothings/stb stb_truetype 库 如果你特别想处理字体相关的内容特别是想要将字体文件转换为位图格式应该关注的库是stb_truetype。这个库正是实现了我们所需要的功能能够将TrueType字体文件进行栅格化处理生成适合渲染的位图。它完全符合我们资产处理器的需求可以准确地将字体转换为我们需要的格式。 stb_truetype库的功能非常简单明了专门为处理TrueType字体文件设计能够轻松地将字体转换为位图这对于开发过程中需要渲染文字的部分非常有帮助。 stb 库的结构 这些库的结构非常简单明了。每个库都是一个单独的头文件.h 文件。比如 stb_truetype 库它的实现方式很特别。这个库的头文件内部实际上包含了一个预处理指令#define用于决定是否包含库的实现部分。 具体来说如果你只需要头文件中的声明部分可以直接包含这个 .h 文件。如果你还需要实现部分即 .c 文件的代码你只需要在包含头文件之前定义一个预处理指令比如 #define STB_TRUETYPE_IMPLEMENTATION这样编译器就会把实现部分的代码包含进来。如果你没有定义这个预处理指令库的实现部分就不会被编译进项目中只有头文件中的声明部分会被编译。 也就是说这个库的实现方式实际上是将头文件和源文件合并为一个文件。你只需要一个文件就可以使用该库不需要单独的 .h 和 .c 文件。这种方式非常方便尤其适合简单集成的场景。 如果要使用这个库首先需要从 stb_truetype 的官方网站或GitHub页面下载库文件。可以直接获取该文件并将其包含到项目中。虽然可能会遇到一些下载和使用上的小问题但本质上这是一个非常简单和直接的库适合快速集成使用。 使用库 使用 stb_truetype 库的方法其实非常简单下载也很直接。如果你不是 GitHub 专家可以点击 “raw” 按钮然后选择 “另存为” 来保存文件。虽然这不是最推荐的下载方式但对于一些不熟悉 GitHub 操作的人来说这种方式仍然是可行的。 下载之后文件就保存到了本地。与其他库不同stb_truetype 库有一个非常显著的特点就是它的设计非常简洁合理。它只包含一个文件这使得它非常易于维护和集成到项目中。所有的代码都集中在一个文件内不需要多个文件分散管理。这种简单的结构大大减少了整合和管理代码的复杂度。 相比于很多其他库stb_truetype 库的设计思路更符合简洁、高效的编程原则。它的集成非常清晰可以很容易地嵌入到项目中且维护起来非常方便。这也是为什么这种库很适合用于个人项目或者那些追求高效、简单实现的开发者。 库的集成只有两行代码 如果要在项目中使用 stb_truetype 库我们可以直接在代码中引入库文件并开始渲染字体。首先在代码中包含 stb_truetype.h 头文件接着我们需要在代码中通过 #define 来启用库的实现部分。通过定义一个宏告诉编译器我们需要包含实现部分而不仅仅是头文件这时代码就会编译通过并且生效。 这两行代码的操作非常简单不需要额外下载大量文件也不需要配置复杂的构建系统。只需下载一个文件并添加两行代码便能直接在游戏中实现 TrueType 字体的渲染。相比于其他库需要配置复杂的依赖关系、链接设置以及处理大量编译选项stb_truetype 库的简洁性是非常突出的。 这一点尤为重要因为它避免了我们在整合库时遇到的麻烦如链接多个文件或管理依赖项。只需要将一个文件下载到项目中并进行简单配置就能轻松使用 TrueType 字体渲染库。这种简化的流程非常适合快速开发和小型项目也使得后续的维护变得更加方便不必担心额外的复杂依赖或不必要的资源消耗。 在接下来的工作中可以将字体渲染的代码整合进 asset processor资产处理器中并最终生成字体资产文件。这样可以实现将字体数据转化为游戏中所需的格式。 stb 库的文档 在查看 stb_truetype 库时有一个非常棒的特点是库的头文件.h 文件中已经包含了使用文档和示例程序。这意味着即使不记得如何使用这个库也没有关系因为在头文件中已经详细列出了如何使用它。 例如头文件中提供了关于如何将字体数据转换为位图的示例代码。如果需要将字体渲染为适合游戏的位图可以通过库中的函数直接进行。这些示例程序展示了如何将字体图形渲染为一个矩形区域或者如何生成每个字形的单个位图。 特别的是库内置了一些有用的工具函数可以帮助开发者简化操作。例如提供了获取字体字符位图的函数只需要传入一个字形的代码点和矩形区域就能将该字形渲染为一个位图。这种封装大大减少了开发者需要编写的代码量也让使用这个库变得更加简单和方便。 因此通过查看头文件和示例代码开发者可以快速了解如何使用这个库并且利用它提供的功能来实现自己的需求。整体而言stb_truetype 库的设计非常考虑开发者的使用便利减少了很多不必要的复杂度。 栅格化一个字母 这个函数的主要作用是生成给定 Unicode 代码点的位图。为了实现这一点首先需要定义一个函数这个函数会调用 stb_truetype 库中的某个方法该方法可以根据指定的字体信息生成字体位图。 函数内部会声明一个用于存储字体信息的结构体这个结构体是通过传递地址来实现的。接下来需要准备一个缓冲区这个缓冲区用于存储从字体文件中读取的信息。字体文件的内容会被读入这个缓冲区中之后会用来生成字体的位图。 在实现时程序已经具备了读取文件的功能例如 game_platform 中的 debug_read_entire_file 方法它可以帮助读取字体文件。通过这个方法可以快速读取所需的字体文件并将内容存入内存缓冲区。 更重要的是stb_truetype 库本身并没有强制要求传入文件句柄或文件名而是允许传入一个已经准备好的内存缓冲区这样就避免了不必要的依赖和额外的代码操作。它非常灵活能根据使用者的需要进行操作而不是强行要求使用特定的文件读取方式。这种设计方式减少了开发者的负担使得操作更加直观和简便。 举个例子可以选择 Windows 系统中常见的字体文件如 Arial 字体然后通过 debug_read_entire_file 函数读取该文件。这样就可以将字体文件内容加载到内存中之后便可以用来生成位图。 将整个内容传递给 stb_truetype 在读取完字体文件之后接下来会将整个字体文件内容传递给 stb_truetype 库让它进行处理。具体来说我们会调用相应的函数来处理字体文件内容生成所需的位图。 其中一个关键的操作是 stbtt_GetFontOffsetForIndex 函数这个函数的作用是获取字体文件中的某个字体的偏移位置。如果字体文件中包含多个字体文件这个函数就能根据指定的索引返回相应字体的偏移位置。该函数的作用是帮助从一个字体文件中获取指定索引的字体。 当处理完这个步骤后可以继续调用 stb_truetype 中的 stbtt_GetCodepointBitmap 函数来获取字体的位图。这里的“代码点”codepoint是一个唯一的数字标识符用于表示特定的字形比如字母 t、汉字“肉”等字符。 在获取到字体文件后程序会初始化相应的字体结构体然后通过传递这个结构体给 stbtt_GetCodepointBitmap 函数来提取位图信息。这样我们就能从字体文件中提取特定字符的位图数据并将其用于图形渲染等后续操作。 使用 GetCodepointBitmap 首先关于如何获取字体的位图程序会通过调用函数来获取相应的位图信息。这个过程实际上是基于已知的字体参数例如 scale x、scale y、code point、宽度和高度等。通过这些参数程序能够生成一个与指定字符代码点相关的位图。 该函数的返回值是位图数据实际上就是一个单色位图monochrome bitmap。这与我们之前讨论的位图是一样的唯一的区别是这个位图不包含颜色信息而是以黑白形式呈现。这意味着它只是通过0和1来表示像素其中0代表空白像素1代表填充像素。而关于字体的抗锯齿处理也通过这种方式在位图中表现出来。 总的来说获取的位图数据仅包含字体的形状轮廓而不包含任何颜色信息这是因为大多数客户端处理字体时都只需要黑白图像。 字体缩放点和像素 在获取字体位图时首先需要传入一些参数如代码点code point、缩放因子scale x 和 scale y。其中scale x 只是决定了水平的缩放比例而 scale y 则稍微复杂一些。因为在 TrueType 字体文件中scale y 的单位通常是以点points为单位而我们常常需要的是像素pixels。为了简化这一过程库提供了一个实用函数 stbtt_ScaleForPixelHeight这个函数可以根据给定的像素高度来计算出应该传递的正确缩放比例。这样我们就能够方便地将字体缩放到所需的像素大小。 例如假设我们希望获取一个 128 像素高的字形我们只需使用该函数来确定相应的缩放比例然后传入 stb_codepoint_bitmap 函数就可以获得我们想要的字体位图。这时我们传入一个 Unicode 代码点比如字符 ‘n’来获取对应的位图。 一旦获取到位图返回的数据包括多个关键信息位图的宽度width、高度height、X 偏移量x offset和 Y 偏移量y offset。其中宽度和高度表示位图的尺寸X 和 Y 偏移量则表示字符在位图中的位置偏移。 这种方式为字体渲染提供了精确的控制能够方便地获取和调整所需字符的位图信息。 记录返回位图的大小以及 X 和 Y 偏移量 在获取位图时返回的位图是一个紧凑的位图即没有多余的空白区域。对于每个字形位图会尽量紧密地包含该字符不会有额外的空白区域围绕着它。因此位图的尺寸通常会有所不同取决于字符的形状和大小。 位图的 XOffset 和 YOffset 参数用于调整位图的对齐方式。这些偏移量帮助在渲染多个字符时确保字符之间正确对齐。例如字符“A”通常比字符“n”高因此其位图可能需要在Y方向上进行偏移以确保字符之间对齐。这些偏移量确保了字符能够在字体渲染时正确排列。 此外位图返回的可能是从上到下的排列方式因此在处理时可能需要进行垂直翻转上下反转以适应不同的渲染需求。这种垂直翻转是因为位图通常是从顶部到底部绘制的而不是从底部到顶部。 关于内存管理获取位图后可能需要释放内存。虽然文档中没有明确指出是否需要释放但通常情况下像这样的位图数据可能需要显式地释放内存资源。 释放 stb_truetype 分配的内存 在获取位图后我们会进行一些额外的处理确保一切顺利。特别地位图的内存管理非常重要。处理完位图之后需要释放相关的内存资源这时使用 free 函数来释放位图的内存。不过free 函数的参数并不是直接的位图而是需要传递一些用户数据例如传递一个内存管理区域arena来处理内存分配。这是因为位图可能涉及到更复杂的内存管理需求。 至于编译整个过程会经过编译阶段确保代码能够顺利运行。在此过程中可能会遇到一些与音频处理相关的代码需要特别注意。这些步骤看似复杂但通过合理的内存管理和按需编译就能顺利完成字体渲染任务。 欣赏完成得很好的工作 整个过程其实非常简单基本上就是通过这个库来进行接口交互。这个库的设计非常好使用起来非常直接且高效。只需要少量的代码甚至无需处理复杂的依赖和配置就可以在游戏中实现字体渲染功能。相比现代的大型API或者库这种简洁的设计让人觉得很不一样尤其是当看到一些现代的库需要成千上万行代码来完成一些基本的任务时实在是显得不值一提。 这个库的优势在于它非常符合我们的需求——我们需要做的功能只需要调用相应的函数完成后就能直接获得所需的结果不需要考虑复杂的设置或配置。它将复杂的任务简化为简单的调用使得开发过程更加高效和流畅。 如果所有库都能像这个库一样设计得如此简洁和易于集成那么开发过程将会变得更加轻松。相比之下很多现代的API和库往往包含大量的冗余代码和复杂的依赖反而让开发者感到头疼。因此这种库的设计理念和实现方式为开发者提供了极大的便利也让整个开发体验变得更加愉快。 使用字符位图作为加载的位图 在这个过程中我们首先创建了一个空的位图并通过使用字体库加载并处理字形。具体来说首先初始化了一个空的位图然后通过给定的字体数据和参数如宽度和高度生成了一个字母“n”的位图。为了实现这一点我们需要先通过字体库读取并获取字形数据然后将其转换成32位的位图格式每个像素占四个字节。 这个转换过程实际上并不复杂。我们只是通过将从字体数据中读取到的每个像素值转换为目标格式然后填充位图内的每个像素。位图的转换是通过将字形中的每个像素值与其对应的透明度值alpha值进行混合来完成的。混合后的结果就是带有透明度的颜色值。 接下来我们通过一个简单的循环遍历每个像素进行必要的位图数据转换最终生成所需的位图。这里需要注意的是位图的生成是逐行进行的每一行的数据在内存中是连续存储的。 当完成位图的转换后我们还做了一些清理工作确保一切正常进行。接下来将生成的位图存储在合适的位置并在游戏初始化时加载这个位图作为测试使用。然后在游戏启动时可以通过调用相应的代码来生成并显示该位图。 如果没有错误最终的结果应该是成功创建并显示字母“n”的位图。尽管在代码的实际运行中可能还需要做一些细节上的调整例如确保正确显示图像或者解决潜在的内存管理问题但总体流程就是如此。 显示位图 在这个过程中首先决定将位图显示的代码放在头部渲染部分这样可以避免将大量的“头部”文字直接显示到屏幕上。相反选择通过显示测试字体来代替。测试字体的目的是验证位图渲染是否正常工作。 在代码中我们使用了一个名为“加载位图”的功能这个功能要求传递一个内存地址。接着通过传入测试字体的相关数据来加载并显示位图。为了进行正确的渲染需要确保传递给加载位图的内存地址是正确的。 在处理完这些准备工作之后执行代码并运行测试检查位图的显示是否如预期一样正确。如果没有出现错误最终应该能够看到正确渲染出来的字体而不是直接显示的“头部”文本。 测试它 在这个过程中出现了一个问题测试字体并没有正确显示在屏幕上导致感到很失望。为了找出原因决定回到代码中逐步排查问题。通过进入调试模式可以查看之前调用的函数进一步分析哪里出了问题。 通过调试可以看到调用的函数是“MakeNothingsTest”然后逐步跟踪这段代码查看每个步骤确定是哪一部分没有正常执行进而定位到问题所在。 检查 MakeNothingsTest 在调试过程中发现了一些问题。首先检查了加载的字体文件确认文件内容已经成功加载并且包含了大量的字形信息。对于每个字形宽度和高度的值看起来都合适且没有异常。 接着检查了生成的位图。虽然某些字形的 alpha 值设置为 1但在查看过程中发现有些地方存在问题。例如某些 alpha 值为 70显然表明在处理位图时出错了。通过调试逐步排查发现可能是目标位图未正确扩展到 32 位导致颜色或透明度处理出现问题。 为了进一步确认是否有问题检查了源代码中的数据发现某些数据似乎没有按照预期方式工作。尽管设置了正确的 alpha 值但位图的显示效果并未达到预期。通过进一步的调试推测可能是位图在存储或渲染时未能正确应用 alpha 值导致最终结果与预期不符。 总的来说问题在于某些渲染和位图处理上的细节虽然数据看起来正常但由于没有正确处理这些细节最终效果未能正确显示。 调试绘制代码 在调试过程中发现了一个问题。查看了游戏的测试状态和内存确认内存中确实存在数据。然而尽管应该在屏幕上显示内容但实际显示的结果并没有按预期出现。这让人感到困惑因为从内存数据来看一切似乎正常。 目前无法完全理解为什么没有看到任何渲染结果感觉这个问题有些奇怪可能遗漏了某些明显的细节或步骤。需要进一步分析和排查可能的问题以确保渲染流程正常。 MakeEmptyBitmap 已过时缺少一些初始化代码 问题出在没有更新 MakeEmptyBitmap 函数使其遵循新的位图规则。原来的代码已经不适用了需要根据新规则进行一些初始化工作特别是要根据输入调整位图的宽度和高度。可以使用宽度或高度的比例来计算确保适应新的要求。 此外不再关心像素的具体位置或中心等信息只需要根据新的标准进行设置和调整。这些改动会帮助解决渲染问题使位图能够正确显示。 再次测试 显示的不对 忘记跳到下一行 问题出在位图的方向上。当前的位图是按照从上到下的方式排列的而所使用的库默认假设位图是从上到下的top-down而我们的惯例是从下到上bottom-up。这就导致了显示的字符如字母“n”可能会显示反转或错位。 为了修复这个问题需要对加载的位图进行翻转使其符合我们的惯例即将位图从底部到顶部加载这样字母就会正确显示。此时字母的方向和排列应该正常符合预期效果。 这个问题可以通过在代码中添加位图翻转的步骤来解决当前的代码已经处理了从单色到彩色的转换接下来需要在此基础上增加对位图方向的调整。 将字母位图上下翻转 解决问题的方法非常简单。只需要对位图进行翻转操作将位图的行反向排列。具体来说可以通过调整位图的行指针从最后一行开始逆向写入数据。这样就能使位图符合我们的惯例即从下到上。这一操作非常简单并且能够解决显示问题。 使用这个方法后字母和字符应该会正确显示不会出现倒置的情况。这是因为所使用的库默认采用的是自上而下的位图格式而我们的程序需要底部到顶部的位图格式。因此通过翻转位图可以确保一切正常。 总结来说使用这个方法能够快速解决问题。谈到库的使用尤其是图像处理库stb库无疑是一个非常好的选择。它设计得非常简洁易于使用而且功能全面。stb库具有很好的架构设计能够高效地完成大量工作避免了其他库常见的复杂性和问题。因此在大多数情况下推荐使用stb库而其他库的使用则相对较少。 将此代码移到资源构建器中 为了避免在实际的游戏代码中使用任何外部库将所有的库功能移至资源构建器中是一个合理的选择。具体来说处理字体的部分已经从游戏代码中剥离并且移到了资源构建器中。通过这种方式游戏本身仍然不依赖任何库而资源构建器则可以使用外部库如stb库进行处理和加载。 在资源构建器中处理字体的逻辑已经被重新整理这样就可以在构建资源时加载并处理字体等资源。当资源加载到游戏中时我们将其转换为游戏能够使用的格式。虽然可以直接将这些资源存储到资产数组中但接下来的步骤是需要扩展资源格式加入额外的内容例如字符映射表等这些内容是我们需要在文件中存储的以便在游戏加载时能够使用。 目前我们的目标是处理和加载这些资源并将它们转化为游戏能使用的格式这样游戏的运行过程中就可以通过这些格式化的资源正常渲染和显示了。这一过程中的关键是保持游戏代码的简洁和高效避免直接在游戏本体中进行过多的资源处理。 将 game_asset_type_id.h 合并到 game_file_formats.hβ 决定将资产标识符game_asset_type_id和文件格式game_file_formats合并在一起这样的设计是为了简化代码结构并消除不必要的冗余。通过这种方式可以将两个看似不同的功能合并为一个统一的结构从而提高代码的整洁性和可维护性。 在具体操作上原本分开的部分被统一处理删除了一些多余的文件和类型定义使得整体结构更加简化。对这些调整没有太多情感上的纠结目标只是让代码更简洁、更高效。因此尽管删除了一些以前的结构和实现这种改变并不会带来太多遗憾反而是为了更好地推进项目。 为每个字母添加一个位图到资源文件 在这里决定做一些非常不寻常的事情尽管这看起来可能并不是最理想的做法但既然有这个能力就决定尝试一下。想要将一个资产Asset直接用于处理字体font这种方式明显有点过度使用了现有的资产系统。虽然并不建议这么做但考虑到可以这样操作就试试吧。 具体实现上首先定义一个新的资产类型 asset fonts然后在资产构建器中进行处理。接下来为了创建字符集选择从字母 a 到 Z 生成并将其直接插入到资产系统中。每个字符都用一个 code point 标签标记表示它的 Unicode 代码点。 虽然这种做法在理论上是非常低效和不负责任的但目前并不关心执行效率因为这是在进行资产处理阶段。后期可以对这个过程进行优化所以现在可以先不考虑速度问题直接按照这种方式进行处理。这虽然是一种非常不负责任的做法但考虑到目前的开发阶段并不觉得这会造成太大的问题。 重新加载整个字体文件并让 Sean 解析它 计划重新加载整个字体文件并每次解析一次这虽然是很不高效的做法但目前不在乎性能问题。决定使用 AddCharacterAsset 方法来实现字体的加载和处理。这个方法会接收一个资产结构、一个字体文件以及代码点。整个过程的思路是首先使用已有的代码读取整个文件传入字体文件后通过某个函数来释放这个文件的内存。 虽然这一做法显得有些混乱但在目前阶段并不打算关注效率目标是尽快实现功能。发现之前在处理文件时我们已经做了一些内存管理的优化尽管当时没有完全记得细节但代码中确实有处理文件释放的部分。虽然这种做法非常简单粗暴但也证明了开发中会逐步意识到内存管理的重要性最终虽然简单但也合理有效。 干得好 首先决定读取整个字体文件并在使用后释放它因为此时并不需要保持任何不必要的数据。不同于其他情况这次不需要保留任何内容。接下来打算检查 stb 库中的相关功能确保在处理完字体文件后能够释放相应的内存。虽然没有详细检查过但猜测 stb 库在加载字体时可能不会进行内存分配或者是它自己管理内存所以没有特别的释放操作。 最终发现字体数据处理并不需要额外的内存管理它只会返回纯数据不需要额外的操作来释放内存。于是整个清理工作完成了。 接下来重点转移到处理与位图加载和释放相关的工作这虽然看起来有些复杂但也不难处理。这一过程让整体代码变得更加简化也方便了后续的开发工作。 将字体栅格化测试代码调整为资源系统 在处理字体时需要通过 AddCharacterAsset 函数获取合并后的位图。接下来创建一个实际使用该资产的位图。首先需要确保在处理文件之前检查字体文件是否加载成功尽管在这个阶段文件加载是离线的不是必须的但为了稳妥还是做了这一检查。 随后定义一个位图并为其分配内存。此时内存分配的大小应该基于位图的宽度和高度进行计算因此需要申请足够的内存空间。在这里使用 malloc 来分配空间分配的内存大小是位图的宽度乘以高度乘以每个像素所需的字节数。 此外还考虑到位图可能需要填充因此需要处理 pitch这代表了每行的字节数。由于可能存在填充的需求因此在内存分配时需要考虑这一点并在相关代码中加以处理。 最终完成了位图内存的分配和处理为后续的位图加载和使用做好了准备。 将资源系统调整为新的资源类型 如果按照这种方式进行操作就可以先计算所需的内存大小具体来说就是 pitch 乘以 width以确保分配足够的空间。这样在后续处理完毕后就可以直接释放这部分内存而无需关注其他无关的内容。这部分代码的逻辑和之前的实现完全一致因此可以直接复用。 在完成内存分配和释放后还需要处理加载的位图。查看 LoadBMP 发现它返回的是一个 loaded_bitmap 结构因此可以创建一个类似的 LoadGlyphBitmap 方法使其与 LoadBMP 的行为一致。这样就可以通过 LoadGlyphBitmap 加载特定的字符位图而 LoadBMP 继续处理普通的位图。 在 LoadGlyphBitmap 方法中除了文件名之外还需要传入字符的 CodePoint。此外还可能需要处理字体大小相关的逻辑但暂时先不处理后续可以在优化时补充更多的字符对齐等细节。等到后面有空时比如明天或下周再进一步优化字符对齐等问题。 AddCharacterAsset 的逻辑和 AddBitmapAsset 基本一致唯一的区别在于加载 bitmap 的方式。因此可以在 AddCharacterAsset 中直接复用 AddBitmapAsset 的代码只是更改加载位图的方式。例如之前 AddBitmapAsset 是在写入时加载位图因此可以在 AddCharacterAsset 中创建一个类似的代码路径专门用于字体位图的处理。 接着可以在 asset_type 中新增一个 font 类型并让 AddCharacterAsset 走相同的逻辑路径。这样在写入数据时可以判断 Source-Type 是否为 asset_type font然后调用对应的 LoadGlyphBitmap 方法否则就继续走普通的 bitmap 处理逻辑。这样代码路径就可以共享避免重复实现。 在 asset_type font 处理完毕后还需要存储 Codepoint可以直接使用 FirstSampleIndex 存储 Codepoint确保后续能正确匹配字符数据。整体来看整个逻辑非常基础基本上是按照既有的系统进行扩展和适配。当前的目标只是按照系统既定规则实现功能所以就只是按照现有模式继续推进。 AddCharacterAsset 在当前的处理方式中glyphic maps 仅仅是一种记录我们希望执行某个操作的方式。查看具体实现时可以看到对于 add bitmap asset可以使用完全相同的代码。然而代码量似乎较多这是一个值得关注的问题。因此需要考虑是否可以对其进行某种压缩或合并处理以优化整体结构。 由于这是资产处理器而当前的部分更像是一个示例因此可能不会特别关注这个问题。但仍然让人有些犹豫是否需要进行调整。代码中涉及 codepoint 相关的逻辑其余部分基本保持原样没有太大变化。至于 AlignPercentageX目前在这里并不特别重要因为无论如何在处理字体对齐时仍然需要执行其他操作因此可以暂时保持不变。 在代码调试过程中出现了一些错误。其中涉及 TTFFile 变量的使用它实际上被命名为 entire file。此外还有 font file、file name、free、contents 等变量的引用需要确保 contents 仍然有效。results 变量是 results而 add character assets 需要返回 get map id应该是这个返回的内容。当前进度基本接近完成只需进一步确认这些逻辑是否正确。 继续运行我们的生成器ζ 目前的情况有些类似于孤注一掷的尝试因为手头只有一堆代码但对其具体行为并没有清晰的了解。不过既然已经到了这个阶段不妨直接运行看看效果如何。毕竟此时已经接近流程的尾声理论上不会出现什么严重的问题。 当然从技术角度来看仍然有很多可能出错的地方。但既然已经准备好了 test_assets_builder就直接运行它来看看实际结果。然而运行后的情况似乎不太理想输出的结果显示出某些错误需要进一步排查和修正。 调试一下 发现断点一直进不来 从新生成hha 尝试将头部改为字体ι 目前已经成功获取了 heads接下来尝试将其更改为字体。在这一过程中当设置 BitmapID 时将从 GetRandomBitmapFrom 中随机获取一个位图并观察其实际效果。 筛选从喷泉中喷出的字母 如果想让实现变得更有趣一些同时保持 “nothing” 这个主题可以将所使用的字母限定在 N, O, T, H, I, N, G, S 这几个字符内。为了做到这一点可以利用资产标签匹配系统从资产库中筛选出符合条件的标签。 目前的代码并未针对资产标签匹配系统进行优化因此这样使用可能会导致效率较低。如果要提高性能最好预先构建匹配表而不是在运行时强行筛选。不过仍然可以使用 GetBestMatchBitmapFrom 来匹配最合适的资产。 在调用该方法时可以传入 TranState-Assets并将 Asset_Font 作为 type id。此外还需要提供一个 asset vector其中包含 MatchVector 和 WeightVector。这两个向量内唯一的内容就是 Unicode 码点例如假设要匹配 N并且使用的是大写字母就可以按照这个逻辑进行筛选。 具体实现上可以简单地用随机选择的方法从匹配到的字母集合中挑选一个。这里直接使用 random choice 来从 nothings 字母集中选取一个随机字母并将其作为最终的选择结果。 最终的输出结果展示了所选的 N并且成功按照 “nothing” 主题筛选出了符合要求的字母。整体实现基本完成逻辑已经跑通效果也达到了预期。 库成功κ 使用库的成功秘诀在于选择合适的库。绝大多数情况下最好的选择是使用由 Shah 设计的库因为这些库通常遵循特定的风格并且极具实用性。当然也有其他开发者按照相同的风格编写了一些优秀的库这些库也值得考虑。 在选择库时有几个重要的标准需要关注 单文件实现如果一个库只有一个文件那通常是一个很好的信号意味着它易于集成。API 直观易用例如如果需要获取代码点位图而库中正好提供了一个名为 gecko_pipe 的函数能够直接返回所需的位图那就是一个理想的选择。集成简单优秀的库应该不需要复杂的构建选项理想情况下只需要一两行代码即可完成集成而无需额外配置。快速上手如果一个库可以立即投入使用并且能够轻松整合到已有的资产处理流程中那它就是一个优秀的库。 在实际操作中使用符合这些标准的库确实带来了极大的便利。例如在本次实现过程中能够快速集成所需功能而如果使用其他方案可能还需要花费大量时间去调试 Apple 的相关接口。 这次实践清楚地展示了一个关键问题如果要使用外部库应该优先考虑那些结构清晰、简单易用的库。正因如此当被问到 “如果使用库会选择哪些库” 时答案始终是这些设计合理的库而不是那些复杂难用的选项。 ‘A’ 是最适合空字符终止符的 在当前实现中null terminator 的匹配存在一些问题。最优匹配方式需要进行调整以避免 null terminator 被误算在内。 目前的逻辑存在一个小错误原本 array counts 应该是 recount - 1因为 recount 计算时会包含末尾的 null terminator但实际操作时并不希望它被计入。因此更合理的做法是使用 recount nothings - 1这样可以确保不会错误地将 null terminator 作为匹配项。 这个调整可以使得逻辑更加严谨避免 null terminator 影响最终结果同时让匹配过程更加精准。 直到今晚我才明白 CMake 的一个使用场景就是用户编译程序时能够找到库这样你就不需要知道它们的安装位置。但是现在……看起来 STB 方式是唯一合理的默认方式。我想在可预见的未来我已经不再使用 CMake 了 在最初的设想中CMake 似乎有一个合理的使用场景即在用户编译程序时它能够自动找到所需的库而不需要手动指定它们的安装路径。然而现在看来标准的构建方式才是唯一合理的默认选项因此不再考虑继续使用 CMake。 总体来说CMake 等构建工具之所以被使用主要是因为许多库和程序的构建方式本身存在问题。如果代码组织合理即便是一个庞大的代码库也可以仅依靠单文件构建完成。当然这并不意味着所有情况下都应该采用这种方式而是说构建工具本质上是多余的。 使用构建工具通常会导致一系列复杂的问题。例如整个构建流程可能变得异常繁琐开发过程中需要不断调试 Makefile或者因为错误的 CMake 配置导致各种构建失败的问题。此外还可能遇到诸如错误的 CMake 版本、错误的编译器选项等问题导致调试过程极为痛苦。 在实际项目中CMake 可能会带来很多麻烦。例如在尝试静态链接 Clang 时遇到了极大的困难整个构建过程异常复杂最终不得不将经验总结成文档分享给其他开发者以帮助他们避开类似的陷阱。这种复杂性表明完全可以通过合理的代码结构和构建策略来避免 CMake 带来的问题。 因此在项目决策时应该认真考虑是否真的需要 CMake 或其他类似的构建工具。对于许多项目来说避免 CMake 可能会使整个开发流程更加清晰、高效并减少不必要的构建调试工作。 外部库、malloc/free接下来是 Java 虚拟机吗 在外部库的使用上如果涉及到 Java Virtual Machine (JVM)那么对于资产处理器来说完全可以自由选择是否使用 JVM。 资产处理器本身并不被视为游戏核心的一部分而只是一个用于演示如何处理某些任务的工具。因此在资产处理器的实现上如果需要 JVM那完全可以按照需求来决定是否引入。 换句话说在这种情况下是否使用 JVM 完全取决于具体需求。如果觉得 JVM 适合资产处理器的工作流程那就可以放心使用不必过多纠结其对整体架构的影响。 你现在如何写调试信息 如何编写调试信息取决于你需要调试的内容。调试信息的目标是帮助开发者理解程序的运行状态以便快速定位和修复问题。通常调试信息应该包括关键的变量状态、函数调用的顺序、错误日志以及可能导致问题的其他上下文信息。 编写调试信息时可以通过以下几种方式来提高其有效性 明确的标签和时间戳在日志中添加标签如 DEBUG、INFO、ERROR和时间戳帮助区分不同类型的消息并跟踪事件的发生时间。 关键变量的输出输出关键变量的值尤其是那些可能影响程序流程的变量这样可以让调试者看到每一步的状态。 错误信息和堆栈追踪对于异常情况应该记录错误信息和堆栈追踪以便定位问题发生的位置。 函数调用和返回值在调试时记录函数的调用顺序以及返回值特别是那些可能导致程序状态改变的函数。 日志分级根据不同的严重程度分类日志信息例如 INFO 用于常规操作信息DEBUG 用于详细的运行时信息ERROR 用于异常和错误信息。 总之调试信息应当简洁且富有意义帮助开发者理解代码的执行流程和状态从而更有效地发现和解决问题。 换个说法你如何输出句子来查看调试字符串比如 FPS 或错误码 如何生成调试字符串例如 FPS 或错误代码暂时还没有完全解决这个问题。可以先暂时把这个问题放在一边因为这正是下周要讨论的内容。到时候会深入探讨如何处理和输出这些调试信息。所以先记住这个问题等到下周再一起解决。
http://www.pierceye.com/news/190997/

相关文章:

  • 甜品店网站开发背景江宁区住房建设局网站
  • asp.net网站开发视频教程找能做网站的
  • 租房合同范本下载word东莞网络优化
  • 做网站需要会写代码6net快速建站
  • 克拉玛依 网站建设红圈工程项目管理软件
  • 北京网站ui设计公司共青城网站建设公司
  • 电子商务网站设计说明书开发一个网站
  • 网站制作长沙怎么做淘客手机网站
  • 五路居网站建设wordpress php允许上传文件大小
  • 旅游网站的设计代码下列哪些不属于企业网站建设基本原则
  • 房屋租赁网站开发意义做男鞋的网站
  • 网站负责人可以备案北京建设部网站 信息中心
  • 网站建设分录怎么开四川省城乡住房建设部网站首页
  • 刘家窑网站建设公司如何在网络上推广产品
  • 全球建站东莞市的网站公司哪家好
  • 地方网站发展怎么做链接推广产品
  • 上海制造网站公司网站优化做网站优化
  • vs2012做网站wordpress 页眉
  • 北网站建设重庆建设工程查询网站
  • 给我做网站的人老是给我留点尾巴太原本地网站搭建公司
  • 静态页面网站站标代码写进到静态页面了 怎么不显示呢?自助建站网
  • 免费在线代理网站微信会员卡管理系统
  • 和动物做的网站吗做网站销售怎么样
  • 宝塔面板做织梦网站深圳龙华大浪做网站公司
  • 阿里云建网站费用上海网站建设觉策动力
  • 电子商务网站的建设与维护方法h5第三方收款平台
  • 网站建设所需人力设计广告网站
  • php网站发送邮件动态倒计时网站模板
  • 温州建设网站制作wordpress调用文章简介
  • 大庆市建设局网站刘东科技公司做网站