简洁版本
如何在 OpenGL 映射应用程序中绘制短文本标签,而无需在用户放大和缩小时手动重新计算坐标?
长版
我有一个基于 OpenGL 的映射应用程序,我需要能够在其中绘制多达 250k 点的数据集。每个点都可以有一个短文本标签,通常大约 4 或 5 个字符长。
目前,我使用包含所有字符的单个文本来执行此操作。对于每个点,我为其标签中的每个字符定义一个四边形。因此,带有“Fred”标签的点将有四个与之关联的四边形,每个四边形使用纹理坐标到该单个纹理中来绘制其对应的字符。
当我绘制地图时,我在地图坐标(例如,经度/纬度)中绘制地图点本身。然后我计算屏幕坐标中每个点的位置,并更新每个点的标签四边形的四个角点,再次在屏幕坐标中。(例如,如果我确定该点在屏幕点 100、150 处绘制,我可以将点标签中第一个字符的四边形设置为从左上点 105、155 开始且宽度为6 像素和 12 像素的高度,适合特定字符。然后第二个字符可能从 120、155 等开始。)然后,一旦所有这些标签字符四边形都正确定位,我使用正交屏幕绘制它们投影。
问题是更新所有这些字符四边形坐标的过程很慢,对于具有 150k 点的特定测试数据集大约需要半秒(这意味着,由于每个标签大约有四个字符长,所以大约有 150k * [每点 4 个字符] * [每个字符 4 个坐标对] 每次更新时需要设置的坐标对。
如果地图应用程序不涉及缩放,我不需要在每次刷新时重新计算所有这些坐标。我可以只计算一次标签坐标,然后简单地移动我的查看矩形以显示正确的区域。但是对于缩放,如果不进行坐标计算,我看不到如何使它工作,因为否则角色会在放大时变大,在缩小时变小。
我想要的(以及我理解 OpenGL 没有提供的)是一种告诉 OpenGL 应该在固定的屏幕坐标矩形中绘制四边形的方法,但是该矩形的左上角位置应该是固定距离地图坐标空间中的给定点。所以我想要一个原始层次结构(给定的地图点是它的标签字符四边形的父级)和在这个层次结构中混合两个不同坐标系的能力。
我试图了解是否有一些我可以设置的魔法转换矩阵可以完成这一切,但我不知道该怎么做。
我考虑的另一种选择是在每个点上使用着色器来处理计算该点的标签字符四边形坐标。我以前没有使用过着色器,我只是想了解 (a) 是否可以使用着色器来执行此操作,以及 (b) 在着色器代码中计算所有这些点是否真的比我自己计算它们更重要. (顺便说一句,我已经确认最大的瓶颈是计算四边形坐标,而不是将更新的坐标上传到 GPU。后者需要一些时间,但它是计算,更新的坐标的绝对数量,占据了那半秒的大部分时间。)
(当然,另一种选择是更聪明地了解首先需要在给定视图中绘制哪些标签。但现在我想专注于解决方案,假设所有标签都需要绘制。)