OpenGL 在 VBO 中分离多边形 [英] OpenGL Separating Polygons Inside VBO

查看:61
本文介绍了OpenGL 在 VBO 中分离多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用一个 VBO 来绘制相互分离的多边形.当我绘制多边形时,OpenGL 不知道从哪里开始一个新的多边形并绘制这些多边形.

I am trying to use one VBO to draw polygons separated from each other. When i draw the polygons, OpenGL cannot know where to start a new polygon and draws the polygons united.

我如何在 VBO(或 IBO)上放置一个断点来告诉 OpenGL 开始一个新的多边形.

How can i put a break point on VBO (or IBO) to tell OpenGL to start a fresh polygon.

抱歉,这似乎是一个新手问题,我搜索了问题和教程,但找不到答案.

Sorry it seems a newbie question, i searched for questions and tutorials but couldn't find the answer.

感谢您的评论:)

我正在尝试创建一个 dxf 查看器.Dxf 文件具有带实心影线的多边形,所以我认为使用 GL_POLYON 而不是镶嵌会更快(我可能在这里错了).

I am trying to create a dxf viewer. Dxf files has polygons with solid hatch so i thought that it would be faster to use GL_POLYON rather than tessellation (i might have been wrong here).

我的绘图函数查看每个对象并对文件中的每个图元进行绘图调用.看起来这种方法很慢.所以我决定为每个 uniqe 类型使用一个顶点数组和一个缓冲区.

My drawing function looks at each object and makes a draw call for every primitive in file. It looks that this type of approach is slow. So i decided to use one vertex array and one buffer for every uniqe type.

对于线,不需要知道结尾,因为每条线必须有 2 个顶点.但是多边形可能有不同数量的顶点,我应该告诉 opengl 新多边形的开始位置.

For lines, there is no need to know the endings since every line must have 2 vertices. But polygons may have different number of vertices and i should tell opengl where a new polygon begins.

void draw_scene(/*function variables*/){
    Shader::shader_use();

    glEnableClientState(GL_VERTEX_ARRAY);
    unsigned long int i;
    unsigned long int count = objects.size();
    for(i = 0; i < objects.size(); i++){
        glBindVertexArray(objects[i]->vao);
        glDrawArrays(objects[i]->primitive_type, 0, objects[i]->vertice_count);
        glBindVertexArray(0);
    }
    glDisableClientState(GL_VERTEX_ARRAY);
    Shader::shader_close();
}

以上代码尚未优化.我想在一次调用中绘制具有相同基本类型的对象.认为如果可以将它们放在一个顶点缓冲区中,那么我将能够在一次调用中绘制它们.因此,每种类型(点、线等)都有一个 VAO.

The above code hasn't been optimised yet. I want to draw the objects with same primitive type in one call. Thought that if could put them in one vertex buffer then i would be able to draw them in one call. So there will be one VAO for each type (points, lines etc).

事实上我不知道是否有更好的解决方案.因为即使我可以将它们放在一个缓冲区中,也很难修改原始顶点,因为它们都将放在一个数组中.修改一个顶点会导致所有相同类型的顶点都被重新读取.

In fact i don't know if there might be a better solution. Because even if i can put those in one buffer, then it would be hard to modify primitive vertices since they all would have been put in one array. Modifying one vertice would cause all vertices of same type to be re-read.

我还搜索了一次绑定多个 vao 的方法,以免进行过多的绘制调用.但是我找不到方法.

I also searched to bind multiple vao's at once to not to make too many draw calls. But i couldn't find a method.

非常感谢您的帮助:)

推荐答案

部分内容已在评论中提及.

Part of this was already covered in the comments.

GL_POLYGON 基元类型已弃用,在 OpenGL 核心配置文件中不可用.幸运的是,它可以很容易地替换为 GL_TRIANGLE_FAN.GL_TRIANGLE_FAN 使用相同的顶点顺序,因此您可以直接将 GL_POLYGON 替换为 GL_TRIANGLE_FAN,而无需更改任何其他内容.

The GL_POLYGON primitive type is deprecated, and not available in the OpenGL Core Profile. Fortunately it can easily be replace with GL_TRIANGLE_FAN. GL_TRIANGLE_FAN uses the same vertex order, so you can directly replace GL_POLYGON with GL_TRIANGLE_FAN, without changing anything else.

GL_TRIANGLE_FAN 只能直接绘制凸多边形,无需使用任何更复杂的三角剖分.但是对于 GL_POLYGON 也是如此,所以这不是一个新的限制.

Only convex polygons can directly be drawn with GL_TRIANGLE_FAN without using any more elaborate triangulation. But the same was true for GL_POLYGON, so that's not a new restriction.

有几种方法:

  1. 您可以使用 glMultiDrawArrays().glDrawArrays() 需要一个起始索引和一个大小,glMultiDrawArrays() 需要一个数组.因此,它可用于用单个调用替换任意数量的 glDrawArrays() 调用.

  1. You can use glMultiDrawArrays(). Where glDrawArrays() takes one start index and one size, glMultiDrawArrays() takes an array of each. So it can be used to replace an arbitrary number of glDrawArrays() calls with a single call.

您可以使用原始重启.这样做的缺点是您需要一个索引数组,否则可能不需要.除此之外,它很简单.您可以通过以下方式启用它:

You can use primitive restart. The downside of this is that you need an index array, which may not have been necessary otherwise. Apart from that, it's straightforward. You enable it with:

glPrimitiveRestartIndex(0xffff);
glEnable(GL_PRIMITIVE_RESTART);

您可以使用任何您想要的索引作为重新启动索引,但通常的策略是使用最大可能的索引,如果您使用类型为 GL_UNSIGNED_SHORT 的索引,则为 0xffff.如果您至少使用 OpenGL 4.3 或 OpenGL ES 3.0,您还可以将以上内容替换为:

You can use any index you want as the restart index, but it's common policy to use the maximum possible index, which is 0xffff if you use indices of type GL_UNSIGNED_SHORT. If you use at least OpenGL 4.3, or OpenGL ES 3.0, you can also replace the above with:

glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

然后你设置一个索引数组,在你想要开始一个新多边形的每个位置插入一个 0xffff 值,并像往常一样绑定索引数组.然后,您可以使用单个 glDrawElements() 调用绘制所有多边形.

Then you set up an index array where you insert a 0xffff value at every position you want to start a new polygon, and bind the index array as usual. Then you can draw all the polygons with a single glDrawElements() call.

这篇关于OpenGL 在 VBO 中分离多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆