2009-12-20 224 views
8

我有一个绘制三维地图视图的应用程序,标记了显示各种特征的线条。 我将地图移植到OpenGL-ES架构,但在解决如何显示虚线时遇到了一些问题。使用OpenGL-ES绘制点划线

做了大量的Google搜索,我发现很多参考文献都提到了从OpenGL-ES中删除虚线和多边形的想法,因为它们可以使用纹理三角形轻松模拟。这很好,但是我找不到真正做这个仿真和/或描述了所涉及步骤的人。

一个例子,我尝试将这个概念原型化时遇到的一个问题是透视将我的线条挤压到看不见的地方,因为它们走向地平线。使用LINE_STRIP,这不会发生,并且这些线在地图上保持不变的宽度。

任何有关如何在透视图中实现虚线恒定宽度线的建议将不胜感激。

+0

您是否尝试过正常的线条 - 它是否会让它们在地平线上消失,或者只有在使用它们时才有质感? – 2009-12-20 23:31:20

+0

正常线条绘制正确,但我无法使用它们。我尝试将纹理应用到LINE_STRIP,但这似乎没有做任何事情。寻找我发现的建议,表明它不会工作,纹理三角形是要走的路。 如果纹理LINE_STRIPs可以工作,那会很好。 PS - 我正在使用egl 1.1。 – Piklor 2009-12-21 01:51:49

回答

5

我相信你可以将纹理应用到一条线上,而不仅仅是一个三角形。您需要为线条的每一端设置纹理坐标;纹理将沿着线条线性插值。

该解决方案的有效性应该是不变的,无论您是使用线条还是线条 - 线条只是一种创建较少顶点的线条的方法。

还有一个问题:随着线条远离相机,纹理图案趋于变得紧凑。发生这种情况是因为纹理坐标插值即使对于直线也是透视正确的(参见GL规范的第3.5节)。

有两种方法来解决这个问题:

  1. 如果你可以计算出一个“Q”坐标的纹理撤销的角度来看,你可以恢复屏幕空间纹理。这种技术可能性能太高。

  2. 您可以在眼部空间中投影纹理(例如glTexGen)。

纹理坐标生成当然是GLES 1.1不可用,但如果你正在使用的顶点的数组,你可以伪造它由:

  • 设置你的纹理坐标数组是你的顶点坐标array和
  • 使用纹理矩阵“变换”顶点。

这种技术的缺点是纹理图案会在固定的屏幕空间 - 也就是纹理不会穿过线条。

+0

谢谢,我会放弃这一点。我之前尝试过纹理线条,但没有得到它的工作 - 我可能早就放弃了。 我想要重复纹理,这样我就可以得到一致的破折号,不管它长了多长。 – Piklor 2010-01-31 20:27:41

+1

没有着色器,我不认为你可以做到这一点,没有计算每个帧的ST坐标。 使用着色器时,您需要: - 在网格上的模型空间中编码线的方向。 - 在顶点着色器中,将其转换为空间坐标。 - 在屏幕空间中生成实际的UV地图(每个像素) - 通过转换(和标准化)的线方向矢量旋转UV地图的采样。 可以这么说,如果你对矩阵变换和坐标空间不太满意,这是非常不平凡的。 :-( – 2010-01-31 21:36:18

+1

此外,你可能想看看这个: http://homepage.mac.com/arekkusu/bugs/invariance/HWAA.html 它看起来像很多消费类GPU不做点画对于水平和垂直的点画(他们得到正确的少数情况之一),简单地投影棋盘重复纹理就足够了 – 2010-01-31 21:43:19

3

如果您只想绘制虚线,只需从GL_LINE_STRIP更改为GL_LINES即可。这样,开放的GL将连接顶点,从而在那里留下空间。它实际上是一个半/半比率的虚线 - glLineStipple(1,0101)的粗略等价物;

IE:顶点数组中

[0,0,1,1,2,2,3,3,4,4,5,5,6,6]

OpenGL将连接(0,0)到(1,1),但不会将(1,1)连接到(2,2)[而它将与GL_LINE_STRIP]连接。然后它将连接(3,3)到(4,4),但不连接(4,4)到(5,5)。最终连接将是(5,5)至(6,6)。

这是什么样子时,我做到了:

Dotted Lines on Android

行不虚50/50 /空的,因为在我的情况,它代表了一个游戏实体每个游戏框的位置 - 和游戏框架不一定都是相等的长度,因此不一致的线条:空间比例。

的代码看起来像这样把它画:

公共无效平局(GL10 GL) { gl.glDisable(GL10.GL_TEXTURE_2D);

gl.glColor4f(color[0], color[1], color[2], color[3]/fade); 
      //pointsBuffer holds the points on the line 
    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, pointsBuffer); 

    gl.glDrawArrays(GL10.GL_LINES, 0, points.length/2); 

    gl.glEnable(GL10.GL_TEXTURE_2D); 

}

另外一个设想创造出更有意点画图案将通过与索引阵列(glDrawElements)代替绘图跳过某些顶点。但是,我没有这方面的例子来向你展示。 :/