dim*_*414 10 opengl polygon jogl vertex-array
我正在努力用顶点数组制作一些中等简单的形状,我正在取得一些进展,但现在我想绘制2个(或更多)三角形扇形对象.有没有办法只打一个电话gl.glDrawArrays(GL.GL_TRIANGLE_FAN,...或者我是否需要为每个粉丝单独打电话?
Wikipedia的Triangle strip文章描述了一种叫做原始重启的东西,但是OpenGL的Vertex规范让我觉得这不适用于顶点数组.
绘制多个三角扇的正确方法是什么?这是我目前的绘制方法:
public void draw(GL gl){
if(vertices.length == 0)
return;
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL.GL_COLOR_ARRAY);
gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertBuff);
gl.glColorPointer(3, GL.GL_FLOAT, 0, colorBuff);
gl.glNormalPointer(GL.GL_FLOAT,0, normalBuff);
// drawArrays count is num of points, not indices.
gl.glDrawArrays(GL.GL_TRIANGLES, 0, triangleCount);
gl.glDrawArrays(GL.GL_QUADS, triangleCount, quadCount);
gl.glDrawArrays(GL.GL_TRIANGLE_FAN, triangleCount+quadCount, fanCount);
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL.GL_COLOR_ARRAY);
gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
}
Run Code Online (Sandbox Code Playgroud)
我更新了相关的抽奖部分,如下所示:
for(int i = 0; i < fanLength.length; i++){
gl.glDrawArrays(GL.GL_TRIANGLE_FAN,
triangleCount+quadCount+fanDist[i], fanLength[i]);
}
Run Code Online (Sandbox Code Playgroud)
fanDist是此风扇启动的偏移量(从风扇的起点开始),fanLength是此风扇的长度.
这看起来确实有用,这很好,但是,这是正确的方法吗?有没有更好的办法?
Kos*_*Kos 17
原始重启确实适用于顶点数组和顶点缓冲区 - 如果没有,它就不会真正有用.
但是,它确实与它结合使用是没有用的glDrawArrays.
我们来看看两种技术:
让我来介绍glDrawElements一下:一个电话就好
glDrawArrays(mode, 0, 5);
Run Code Online (Sandbox Code Playgroud)
类似于
GLuint idxs[] = {0, 1, 2, 3, 4}; // C code, but idea's the same in Java
glDrawElements(mode, 5, GL_UNSIGNED_INT, idxs);
Run Code Online (Sandbox Code Playgroud)
因此,您不必指定要从数组中绘制的元素范围,而是指定这些元素的精确索引.
然后你可以使用这样的数组引入原始重启:
GLuint PRIMITIVE_RESTART = 12345; // magic value
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(PRIMITIVE_RESTART);
GLuint idxs[] = {0, 1, 2, 3, PRIMITIVE_RESTART, 4, 5, 6, 7};
glDrawElements(mode, 9, GL_UNSIGNED_INT, idxs);
Run Code Online (Sandbox Code Playgroud)
这将从前4个顶点绘制一个扇形,然后将遇到"符号"以重新启动基元,然后它将绘制最后4个顶点的另一个扇形.
传递给DrawElements的索引不必是连续的范围!它们可以按任何顺序排列,并且可以根据需要重复 - 这是此功能的最佳部分.实际上,最好尽可能频繁地重用一个索引,因为如果结果被缓存,它将仅由顶点着色器处理一次.所以你可以自由地制作缓冲区,如:
GLuint idxs[] = {0, 6, 3, 4, 6, 2, PRIMITIVE_RESTART, 2, 6, 3, 3, 5, 2}; // etc.
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您可能想要使用glMultiDrawElements.
如果你有20个顶点并且你想从第一个开始绘制一个8个顶点的扇形,从10个开始绘制10个顶点的扇形,你可以这样做:
// assuming glVertexPointer is already set
GLuint startingElements[] = {0, 9};
GLuint counts[] = {8, 10};
glMultiDrawArrays(GL_TRIANGLE_FAN, startingElements, counts, 2); // 2 fans
Run Code Online (Sandbox Code Playgroud)
因此,您可以做的工作少一些.
选择你觉得更有用的技术.我会留给你重写一下,在Java/JOGL中,原理是一样的,但你必须Buffer为所有这些使用该类,我想.
| 归档时间: |
|
| 查看次数: |
6127 次 |
| 最近记录: |