首页 > 其他分享 >vulkan/图元重启(Primitive restart)

vulkan/图元重启(Primitive restart)

时间:2023-12-27 17:55:06浏览次数:26  
标签:Primitive GL 函数 OpenGL 重启 图形 vulkan 绘制 restart

在Vulkan /OpenGL 绘制图形时,可能需要绘制多个并不相连的图形。这样的情况下这几个图形没法被当做一个图形来处理。也就需要多次调用 DrawArrays 或 DrawElements. 如果图形很多,可能会需要用一个循环来调用:

for (int i = 0; i < num_objects; i++) {
    glDrawArrays(GL_TRIANGLES,
                object[n]->first_vertex,
                object[n]->vertex_count);
}

Vulkan 中需要如下扩展: VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME 

Vulkan 中需要启动动态状态标志:VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT

Vulkan 中使用vkCmdSetPrimitiveRestartEnableEXT(draw_cmd_buffer,VK_TRUE/ VK_FALSE); 启用或者停止该特性 

每一次调用OpenGL 的绘制函数,都需要一定的资源开销,如果每一帧调用太多次,会对程序的性能产生较大的影响。提高性能的办法就是调用一次绘制函数,画出分散的图形。

一种方法是使用 glMultiDrawElements 函数来代替旧的绘制函数,可以减少调用次数,仅需调用此函数一次即可。但是这个函数在OpenGL ES 没有得到支持。而且使用这个函数,

仍然需要将每一个分散的图形维护一组单独的顶点坐标/纹理坐标,这个是免不了的,这些数据仍然需要分开上传,还是会消耗一定的资源。针对这种情况使用图元重启会更加合适。

考虑通常的情况,当用户绘制 GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_LINE_STRIP, GL_LINE_LOOP 这些图元时,所有的绘制点按照特定的顺序被连起来,以形成一个最终的复杂图形,

也就是说最终的复杂图形由多个相连的三角形或线段组成。像上面提到的情况,想要绘制分散的图形,应该怎么办?

图元重启(Primitive restart) 允许用户绘制不连续的、分散的图形。考虑使用 glDrawElements 函数,绘制时按照indices所指定的顶点的顺序来绘制的。此时可以指定某一个值,

该值表示一个重启的标志。遇到这个值的时候,OpenGL不会绘制图元,而是结束上一段绘制,然后重新启动新的绘制,也就是說用后面的索引所指定的顶点来从头绘制一个图形。

举个例子:比如指定8爲重启的标志,遇到8就重启。上面的是不启用图元重启的情况,即通常的情况。下面的是启用图元重启的情况,我们可以看到,从9开始,又重新从头开始绘制Triangle strip了。

指定重启位置的数值,在桌面版的OpenGL是可以自行设定的,glPrimitiveRestartIndex​ 函数指定重启的标志。在OpenGL ES 无法自行指定,只能用给定的值。

首先设置启用图元重启.

glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

std::array<uint32_t, index_count> indices{0, 4, 3, 7,
UINT32_MAX,
1, 0, 2, 3,
UINT32_MAX,
2, 6, 1, 5,
UINT32_MAX,
1, 5, 0, 4,
UINT32_MAX,
4, 5, 7, 6,
UINT32_MAX,
2, 3, 6, 7};

// Draw triangle strips
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

glDrawElements(GL_TRIANGLE_STRIP, 29, GL_UNSIGNED_INT, 0);

另外,如果 glDrawElements 的mode是points等无效。

标签:Primitive,GL,函数,OpenGL,重启,图形,vulkan,绘制,restart
From: https://www.cnblogs.com/FastEarth/p/17931060.html

相关文章

  • vulkan/descriptorSet
    参考Shaderlayout(binding=0)uniformUniformBufferObject{mat4model;mat4view;mat4proj;}ubo;layout(location=0)invec2inPosition;layout(location=1)invec3inColor;layout(location=2)invec2inTexCoord;layout(location=0)......
  • Docker CLI docker restart 常用命令
    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。Docker是内核虚拟化,不使用Hypervisor是不完全虚拟化,依赖内核的特性实现资源隔离。本文主要介绍DockerCLI中......
  • Restart Study MySQL-01数据库概述(基础)
    C(Chapter)C-01.数据库概述1.为什么要用数据库持久化(persistence):把数据保存到可掉电式存储设备(硬盘)中以供之后使用。大多数情况下,特别是企业应用,数据持久化是将内存中的数据保存到硬盘上加以"固化",而持久化的实现过程大多使用各种关系数据库来完成。持久化的主要作用是将......
  • Vulkan/VkPresentModeKHR
    呈现模式:对于交换链对显示模式的设置应该是最重要的,因为它代表实际显示图像到屏幕的时机。在Vulkan中有四种显示模式:1.VK_PRESENT_MODE_IMMEDIATE_KHR由应用提交的图像立刻被传输到屏幕。这种方式可能导致图像不完整。2.VK_PRESENT_MODE_FIFO_KHR交换链是一个队列,当......
  • Vulkan/Graphics Pipelines
    渲染是vulkan最基础的功能,也是众多图形化应用最核心的部分。vulkan的渲染过程可以当作是通过执行不同阶段的命令以此来在展示设备上渲染出图片的过程。 vulkan中,渲染管线可以看作是一条生产流水线,命令在管线的开头进入,并且在管线内不同阶段执行。每个阶段都有诸如变换,读取命令......
  • Vulkan/Renderpasses
    能将渲染管线和运算管线区别开了的要素之一是——通用,在你使用一个渲染管线渲染图像之后也可能进行其他处理或展示给yoghurt。在复杂的图形应用中,图像需要经过许多通道才能生成,每个通道都负责不同的部分,比如全屏幕的后处理或合成,或渲染UI元素等。这些通道可以由vulkan的一个渲染......
  • Vulkan/FrameBuffer
    帧缓冲(Framebuffer)代表由渲染管线进行渲染的一组图像。它们影响管线的最后几个阶段:深度模板测试,颜色混合,逻辑运算,多重采样等等。一个帧缓冲对象总是附着在一个渲染通道上并且可以用在多个具有相似模板编排的渲染通道中。调用vkCreateFramebuffer创建帧缓冲对象。在VkFramebuffer......
  • Visual Studio 2022:Vulkan 环境配置
    (前置)安装VulkanSDK,并确认安装目录,此后记为%VulkanDir%(例如:C:/VulkanSDK/1.3.261.1)VisualStudio中新建C++项目,进入“项目”>>“[项目名]属性”,上方两个选项设置为“所有配置”“所有平台”C/C++>>常规>>附加包含目录:添加%VulkanDir%/Include(替换%VulkanDir%为实际目录,下同)......
  • General error: 1205 Lock wait timeout exceeded; try restarting transaction【事务
    转载:https://blog.51cto.com/u_12390904/6254246       ......
  • Performance Improvements in .NET 8 -- Exceptions & Reflection & Primitives【翻译
    Exceptions在.NET6中,ArgumentNullException增加了一个ThrowIfNull方法,我们开始尝试提供“抛出助手”。该方法的目的是简洁地表达正在验证的约束,让系统在未满足约束时抛出一致的异常,同时也优化了成功和99.999%的情况,无需抛出异常。该方法的结构是这样的,执行检查的快速路径被......