opengl 地图应用程序中的标签

M K*_*atz 5 opengl rendering texturing labeling

精简版

如何在 OpenGL 映射应用程序中绘制短文本标签,而无需在用户放大和缩小时手动重新计算坐标?

长版

我有一个基于 OpenGL 的映射应用程序,我需要能够绘制最多约 250k 点的数据集。每个点都可以有一个简短的文本标签,通常长约 4 或 5 个字符。

目前,我使用包含所有字符的单个文本来执行此操作。对于每个点,我为其标签中的每个字符定义了一个四边形。因此,带有“Fred”标签的点将有四个与之关联的四边形,每个四边形使用纹理坐标到该单个纹理中以绘制其对应的字符。

当我绘制地图时,我在地图坐标(例如,经度/纬度)中绘制地图点本身。然后我计算屏幕坐标中每个点的位置,并再次更新屏幕坐标中每个点的标签四边形的四个角点。(例如,如果我确定该点是在屏幕点 100, 150 处绘制的,我可以将该点标签中第一个字符的四边形设置为从左上角 105, 155 开始且宽度为6 像素和 12 像素的高度,适合特定字符。然后第二个字符可能从 120、155 等开始。)然后一旦所有这些标签字符四边形都正确定位,我使用正交屏幕绘制它们投影。

问题是更新所有这些字符四边形坐标的过程很慢,对于具有 150k 点的特定测试数据集大约需要半秒(这意味着,由于每个标签大约有四个字符长,因此大约有 150k * [每个点 4 个字符] * [每个字符 4 个坐标对] 每次更新时需要设置的坐标对。

如果地图应用程序不涉及缩放,我就不需要在每次刷新时重新计算所有这些坐标。我可以只计算一次标签坐标,然后简单地移动我的查看矩形以显示正确的区域。但是通过缩放,我不知道如何在不进行坐标计算的情况下使其工作,因为否则字符会随着放大而变大而随着缩小而变小。

我想要的(以及我理解的 OpenGL 没有提供)是一种告诉 OpenGL 应该在固定屏幕坐标矩形中绘制四边形的方法,但是该矩形的左上角位置应该与地图坐标空间中的给定点。所以我想要一个原始层次结构(一个给定的地图点是它的标签字符四边形的父级)和在这个层次结构中混合两个不同坐标系的能力。

我试图了解是否有一些我可以设置的魔法变换矩阵可以完成所有这些形式,但我不知道该怎么做。

我考虑过的另一种替代方法是在每个点上使用着色器来处理计算该点的标签字符四边形坐标。我以前没有使用过着色器,我只是想了解 (a) 是否可以使用着色器来做到这一点,以及 (b) 计算着色器代码中的所有这些点是否实际上比我自己计算它们更能帮到我. (顺便说一下,我已经确认最大的瓶颈是计算四边形坐标,而不是将更新的坐标上传到 GPU。后者需要一些时间,但它是计算,更新坐标的绝对数量,占据了那半秒的大部分时间。)

(当然,另一种选择是首先更聪明地了解需要在给定视图中绘制哪些标签。但现在我想专注于假设需要绘制所有标签的解决方案。)

M K*_*atz 1

只是为了跟进该决议:

我并没有真正解决这个问题,但我最终在绘制标签时变得更加聪明。我能够快速确定是否要绘制太多字符(即,在具有典型点密度的典型屏幕上,标签太靠近而无法以有用的方式读取),然后我简单地根本不贴标签。如上所述,一次绘制大约 5000 个字符时,重新计算字符坐标不会出现明显的减慢。