官方网站开发招标须知课程网站模板

当前位置: 首页 > news >正文

官方网站开发招标须知,课程网站模板,阿里云做电脑网站,app开发公司公司目录 一、说明二、着色器设置2.2 捕获的数据格式2.2 高级交错2.3 双精度和对齐2.4 In-shader规范 三、缓冲区绑定四、反馈过程五、反馈对象5.1 反馈暂停和恢复5.2 绑定暂停的反馈对象。 六、反馈渲染七、局限性 一、说明 转换反馈是捕获由顶点处理步骤生成的基元的过程#xf… 目录 一、说明二、着色器设置2.2 捕获的数据格式2.2 高级交错2.3 双精度和对齐2.4 In-shader规范 三、缓冲区绑定四、反馈过程五、反馈对象5.1 反馈暂停和恢复5.2 绑定暂停的反馈对象。 六、反馈渲染七、局限性 一、说明 转换反馈是捕获由顶点处理步骤生成的基元的过程并将这些基元中的数据记录到缓冲区对象中。这允许保留对象的转换后渲染状态并多次重新提交此数据。 注意将提到处理多个流输出的各种函数。对多个流的反馈需要访问 OpenGL 4.0 或 ARB_transform_feedback3 和 ARB_gpu_shader5。因此如果您无法做到这一点请忽略任何此类讨论。 二、着色器设置 为了捕获基元包含最终顶点处理着色器阶段的程序必须与许多参数链接。这些参数必须在链接程序之前设置而不是在链接程序之后设置。因此如果要使用 glCreateShaderProgram则必须使用 in-shader 规范 API该 API 仅适用于 OpenGL 4.4 或 ARB_enhanced_layouts。 平台问题 NVIDIANV_transform_feedback允许在链接后动态设置这些参数。    唯一对转换反馈很重要的程序对象是提供最后一个顶点处理着色器阶段的程序对象。这些设置可以位于单独程序中的任何其他程序上但只会使用最后一个活动的“顶点处理”着色器阶段上的设置。 变换反馈可以在两种捕获模式之一下运行。在交错模式下所有捕获的输出都进入同一个缓冲区彼此交错。在单独的模式下每个捕获的输出都进入单独的缓冲区。必须在链接时在程序对象上选择此选项。 注意单独的捕获模式并不一定意味着它必须捕获到不同的缓冲区对象中。这仅仅意味着它们被捕获到单独的缓冲区结合点中。同一缓冲区对象的不同区域可以绑定到不同的绑定点从而允许您使用单独的捕获到同一缓冲区对象中。只要绑定区域不重叠这将起作用。 若要定义程序的捕获设置以及捕获哪些输出变量请使用以下函数 void glTransformFeedbackVaryingsGLuint program GLsizei count const char **varyings GLenum bufferMode);bufferMode 是捕获模式。它必须是GL_INTERLEAVED_ATTRIBS或GL_SEPARATE_ATTRIBS 计数是 varyings 数组中的字符串数。此数组指定要捕获的相应着色器阶段的输出变量的名称。提供变量的顺序定义了捕获变量的顺序。这些变量的名称符合命名 GLSL 变量的标准规则。 可以捕获的输出数量以及可以捕获的总分量数量是有限制的。在这些限制内可以捕获任何输出变量包括结构类型、数组、接口块成员的输出。 注意此函数设置程序的所有反馈输出。因此如果您再次调用它在链接之前则会忘记先前的设置。 2.2 捕获的数据格式 转换反馈显式捕获基元。虽然它确实捕获每个顶点的数据但它是在将每个基元拆分为单独的基元之后捕获的。因此如果您使用 GL_TRIANGLE_STRIP 进行渲染并且使用 6 个顶点进行渲染则会产生 4 个三角形。转换反馈将捕获 4 个三角形的数据。由于每个三角形有 3 个顶点因此 TF 将捕获 12 个顶点而不是绘图命令中预期的 6 个顶点。 每个基元都按照处理顺序写入。在基元中写入的顶点数据的顺序是基元组装后的顶点顺序。这意味着例如当使用三角形条带绘制时捕获的基元将每隔三角形切换两个顶点的顺序。这可确保人脸剔除仍将遵循顶点数据初始数组中提供的顺序。 在每个顶点内数据按 varyings 数组指定的顺序写入执行交错渲染时。如果输出变量是聚合 struct/array则聚合的每个成员都按顺序写入。输出基本类型的每个组件都按顺序编写。最终所有数据都紧密地写入在一起尽管捕获双精度浮点数可能会导致填充。 组件将始终是浮点数/双精度、有符号整数或无符号整数使用 GLfloat/GLdouble、GLint 和 GLuint 的大小。不执行包装或归一化。变换反馈系统没有更灵活的顶点格式规范系统的自动模拟。 当然这并不妨碍您在着色器中手动将位打包为无符号整数。 2.2 高级交错 版本中的核心 4.6    自版本以来的核心 4.0    核心 ARB 扩展 ARB_transform_feedback3    上述设置仅提供两种模式所有捕获的输出都进入单独的缓冲区或者它们都进入同一个缓冲区。在许多情况下能够将多个组件写入一个缓冲区同时将其他组件写入其他缓冲区是很有用的。 此外捕获的交错数据是紧密打包的每个变量的分量紧跟在前一个分量之后。如果某些数据发生更改而其他数据未发生更改则能够跳过对某些数据的写入通常很有用。 这些可以通过在 varyings 数组中使用特殊的“varying”名称来实现。这些特殊名称不命名实际的输出变量;它们只会对后续写入产生一些特殊影响。 这些名称及其影响是 gl_NextBuffer这会导致所有后续输出路由到下一个缓冲区索引。缓冲区从 0 开始每次在变化列表中遇到这种情况时缓冲区都会递增 1。 这些缓冲区的数量不得超过可用于转换反馈的缓冲区数。因此这些数量必须严格少于 GL_MAX_TRANSFORM_FEEDBACK_BUFFERS。 gl_SkipComponents#这会导致系统跳过写入 # 个组件其中 # 可能从 1 到 4。跳过的组件所覆盖的内存不会被修改。在这种情况下每个组件都是浮点的大小。    请注意以这种方式跳过的组件仍计入输出组件数量的限制。    可以将 Geometry Shader 中的输出变量声明为转到特定流。这是通过着色器规范控制的但存在某些限制会影响高级组件交织。 同一缓冲区不能捕获两个流向不同流的输出。尝试这样做将导致链接器错误。因此使用具有交错写入的多个流需要使用高级交错将属性路由到不同的缓冲区。 请注意此功能实际上使单独的捕获模式变得多余。与这些设施交错是独立模式的功能超集因为它可以单独捕获每个缓冲区的一个输出。 2.3 双精度和对齐 双精度对准    版本中的核心 4.6    自版本以来的核心 4.0    核心 ARB 扩展 ARB_gpu_shader_fp64    单精度浮点数和整数的对齐方式为 4 个   字节。但是双精度值的对齐方式为 8 个字节。这会导致在捕获转换反馈数据时出现问题。 必须确保组件的对齐。这很容易用浮点数和整数来确保但双精度需要特别小心。由用户来确保所有双精度数据的 8 字节对齐。具体而言您必须确保两件事 每个双精度组件都从 8 字节边界开始。您可能需要使用上面的跳过功能在需要的地方插入填充。    所有进入包含双精度组件的特定缓冲区的顶点数据都必须具有与 8 字节对齐的总顶点数据大小。这可确保第二个顶点将从 8 字节边界开始。因此您可能需要在顶点数据的末尾添加填充。 例如如果要捕获以下内容请按此处定义的顺序 out DataBlock {float var1;dvec2 someDoubles;float var3; };如果要按定义顺序捕获 varyings 数据则在 varyings 数据中需要以下字符串序列 const char varyings[] {DataBlock.var1,gl_SkipComponents1, //Padding the next component to 8-byte alignment.DataBlock.someDoubles,DataBlock.var3,gl_SkipComponents1, //Padding out the entire vertex structure to 8-byte alignment. };如果不这样做则会出现未定义的行为。您只需更改捕获它们的顺序即可避免填充。您不必更改在着色器中定义它们的顺序。 2.4 In-shader规范 In-shader 规范    版本中的核心 4.6    自版本以来的核心 4.4    核心 ARB 扩展 ARB_enhanced_layouts    着色器可以定义变换反馈捕获哪些输出以及它们的捕获方式。当着色器定义它们时查询程序的转换反馈模式将返回交错模式因为高级交错使分隔模式成为交错模式的完整子集。 V·E    布局限定符可用于定义在“变换反馈”操作中捕获哪些输出变量。在着色器中设置这些限定符时它们将完全覆盖通过 glTransformFeedbackVaryings 从 OpenGL 设置转换反馈输出的任何尝试。 使用 xfb_offset布局限定符声明的任何输出变量或输出接口块都将是转换反馈输出的一部分。必须使用整数字节偏移量指定此限定符。偏移量是从顶点的开头写入到当前缓冲区到此特定输出变量的字节数。 包含值的偏移量无论是在数组、结构中还是接口块的成员中如果整个块都有偏移量都是根据先前组件的大小计算的以便按指定的顺序打包它们。任何明确提供的偏移都不允许违反对齐限制。因此如果定义包含双精度直接或间接则偏移量必须对齐 8 字节。 接口模块的成员可以直接在其上指定其偏移量这将覆盖任何计算出的偏移量。此外接口模块的所有成员都不需要写入输出尽管如果您在模块本身上设置xfb_offset则会发生这种情况。对于块的所有成员几何着色器的流分配要求相同但偏移量则不然。 捕获的不同变量被分配给缓冲区绑定索引。对于单独的缓冲区偏移分配是分开的。对于同一缓冲区捕获的两个变量具有重叠的字节偏移量无论是自动计算还是显式分配都是链接器错误。 显式缓冲区分配是通过在与偏移限定符相同的声明上使用 xfb_buffer 限定符进行的。这需要一个整数该整数定义捕获的输出与之关联的缓冲区绑定索引。整数必须小于 GL_MAX_TRANSFORM_FEEDBACK_BUFFERS。 未显式指定缓冲区的全局变量或接口块的任何偏移量都将使用当前缓冲区。当前缓冲区设置如下 layout(xfb_buffer 1) out;对于未显式指定缓冲区的全局变量以下所有偏移量都将使用 1 作为其缓冲区。着色器的初始当前缓冲区为 0。 变量可以在不xfb_offset的情况下分配给它们xfb_buffer。这不执行任何操作将被忽略。 接口块与缓冲区有特殊的关联。每个接口块都与缓冲区相关联无论是否捕获其任何成员。缓冲区可以是上面定义的当前缓冲区也可以是xfb_buffer显式指定的缓冲区。 如前所述不必捕获块的所有成员。但是如果捕获了块的任何成员则必须将它们全部捕获到同一缓冲区中。具体来说就是与该块关联的缓冲区。如果您提供的缓冲区索引与块使用的索引不同则在成员上使用 xfb_buffer 是错误的。 举个例子 layout(xfb_buffer 2) out; // Default buffer of 2.out OutputBlock1 // Block buffer index is implicitly 2. {float val1;layout(xfb_buffer 2, xfb_offset 0) first; // The provided index is the same as the blocks index.layout(xfb_buffer 1, xfb_offset 0) other; // Compile error, due to changing the buffer index for a block member. };每个缓冲区都有步幅的概念。这表示从一个捕获的顶点的开始到下一个顶点的开始的字节计数。它的计算方法是获取具有最高xfb_offset值的输出将其大小添加到该偏移量然后将计算值与缓冲区的基本对齐方式对齐。缓冲区的对齐方式为 4除非它捕获任何双精度值在这种情况下缓冲区的对齐方式为 8。这意味着您不需要像使用外部着色器设置那样手动填充结构以进行对齐。 还可以使用xfb_stride布局限定符显式设置缓冲区的步幅。这允许您在最后添加额外的空间也许可以跳过不会更改的数据。如果指定的步幅为 考虑到该缓冲区捕获的数据的偏移量和计算大小太小。    未正确对齐。它必须至少对齐 4 个字节如果缓冲区捕获任何双精度值则它必须对齐 8 个字节。 缓冲区的步幅设置如下 layout(xfb_buffer 1, xfb_stride 32) out; // Sets stride of buffer 1 to 32. Also, sets buffer 1 to be current.如果缓冲区中捕获的任何输出在空间中重叠或违反填充则会导致链接错误。例如 layout(xfb_buffer 0) out Data {layout(xfb_offset 0) float val1;layout(xfb_offset 4) vec4 val2;layout(xfb_offset 16) float val3; // Compiler error. val2 covers bytes on the range [4, 20). };如果使用的是 Geometry Shader 输出流并且来自不同流的两个输出被路由到同一缓冲区则会导致编译器/链接器错误。 注意将 ARB_enhanced_layouts 用作扩展在较旧的硬件上时如果ARB_transform_feedback3也不可用则只能输出到单个缓冲区。您仍然可以使用偏移量在顶点属性数据之间放置空格但不能将xbf_buffer设置为除 0 以外的任何值。 三、缓冲区绑定 一旦你有一个具有适当设置来记录输出的程序你现在必须设置缓冲区对象来捕获这些值。缓冲区对象及其存储是以通常的方式创建的。改变的是你在哪里使用它们。 当您希望开始转换反馈操作时必须将一个或多个缓冲区绑定到索引GL_TRANSFORM_FEEDBACK_BUFFER绑定点。这是通过使用 glBindBufferRange 函数或等效函数完成的。您提供的偏移量必须是 4 字节对齐的除非捕获到缓冲区中的数据包含双精度值。在这种情况下它必须是 8 字节对齐的。 将缓冲区范围绑定到的索引与设置不同输出位置时使用的缓冲区绑定索引相同。在单独的输出模式下每个列出的输出都进入不同的缓冲区索引从 0 开始按照变化提供的顺序顺序分配。在交错模式下所有输出要么记录到一个缓冲区要么记录到更高级的布局规范机制中指定的缓冲区。 四、反馈过程 绑定缓冲区后可以开始反馈操作。为此请调用以下函数 void glBeginTransformFeedbackGLenum primitiveMode);这将激活转换反馈模式。当变换反馈模式处于活动状态且未暂停时如果执行绘图命令则设置为由最终顶点处理阶段捕获的所有输出都将记录到绑定缓冲区中。这些将跟踪上次记录的位置以便多个绘图命令将添加到记录的数据中。 如果绑定的缓冲区范围不够大无法容纳记录的数据则会导致未定义的行为。 具有当前程序分配给 的输出的所有反馈缓冲区绑定索引都必须具有有效的绑定。否则此函数将失败并显示 OpenGL 错误。 primitiveMode 必须是 GL_POINTS、GL_LINES 或 GL_TRIANGLES 之一。这些模式定义了系统捕获的基元类型。他们还对达到最终原始组装阶段的基元类型施加了限制。该基元基本类型必须与 primitiveMode 匹配。渲染过程的基元类型按给定顺序定义如下 如果 Geometry Shader 处于活动状态则它是 GS 输出的基元类型。 如果曲面细分评估着色器处于活动状态则它是曲面细分过程生成的基元类型。    如果这两个参数都不可用则它是用于呈现的命令的 mode 参数。    虽然转换反馈处于活动状态并且不会暂停但肯定有一些事情是你不能做的 更改GL_TRANSFORM_FEEDBACK_BUFFER缓冲区绑定。    执行从这些缓冲区的任何部分读取或写入的任何操作当然在反馈写入之外。    为这些缓冲区中的任何一个重新分配存储。这包括无效。    更改当前程序。因此无法调用 glUseProgram 或 glBindProgramPipeline。这还包括重新链接相应的程序以及 glUseProgramStages如果目标管道是绑定管道。    要结束反馈模式请调用以下命令 无效 glEndTransformFeedback(); 例如 glUseProgram(g_program); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedback_buffer, buffer_offset, number_of_bytes); glBeginTransformFeedback(GL_LINES); glBindVertexArray(vao); glDrawElements(GL_POINTS, sizeof(pindices)/sizeof(ushort), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); glEndTransformFeedback(); glUseProgram(0);五、反馈对象 转换反馈对象    版本中的核心 4.6    自版本以来的核心 4.0    核心 ARB 扩展 ARB_transform_feedback2    执行转换反馈操作所需的状态集可以封装到 OpenGL 对象中。转换反馈对象是容器对象。这些是以通常的方式创建和管理的包括 glGenTransformFeedbacks、glDeleteTransformFeedbacks 等。 若要绑定转换反馈对象请使用以下命令 void glBindTransformFeedbackGLenum target GLuint id);目标必须始终GL_TRANSFORM_FEEDBACK。如果当前转换反馈对象处于活动状态且未暂停则无法绑定转换反馈对象。 这些对象封装的状态包括 通用缓冲区绑定目标GL_TRANSFORM_FEEDBACK_BUFFER。因此所有对 glBindBufferGL_TRANSFORM_FEEDBACK_BUFFER … 的调用都会将缓冲区附加到当前绑定的反馈对象。 所有索引GL_TRANSFORM_FEEDBACK_BUFFER绑定。因此所有对 glBindBufferRangeGL_TRANSFORM_FEEDBACK_BUFFER … 的调用或任何等效函数都会将缓冲区的给定区域附加到当前绑定的反馈对象。    转换反馈是处于活动状态和/还是暂停状态。    当前反馈操作中记录的基元等的当前计数如果处于活动状态。    因此反馈对象存储要记录到的缓冲区绑定。这样可以轻松地在不同的反馈缓冲区绑定集之间切换而不必每次都绑定它们。 反馈对象 0 是默认的转换反馈对象。您可以像使用任何其他转换反馈对象一样使用它只是不能删除它。 注意上面关于何时对绑定用于转换反馈的缓冲区执行操作是合法的表示法仅适用于附加到当前绑定的反馈对象的缓冲区。因此如果取消绑定当前转换反馈对象则可以再次更改它们。 5.1 反馈暂停和恢复 转换反馈对象不仅适用于轻松交换不同的缓冲区集。您可以暂时停止转换反馈操作执行一些未捕获的渲染然后使用该操作恢复反馈操作。反馈对象将正确跟踪要记录顶点数据的位置。 要暂时暂停反馈操作请调用以下函数 void glPauseTransformFeedback();此时可以通过绑定不同的反馈对象来取消绑定反馈对象。可以更改当前程序等。反馈操作可以无限期暂停并且从处于暂停反馈操作中的缓冲区读取数据是合法的尽管您需要先取消绑定反馈对象。 若要恢复暂停的反馈操作必须执行以下操作 5.2 绑定暂停的反馈对象。 绑定调用 glBeginTransformFeedback 时使用的确切程序或管道对象。 调用此函数 void glResumeTransformFeedback();请注意恢复后原始模式仍将相同。 如果对暂停的反馈对象调用 glEndTransformFeedback它将正确结束该对象的反馈操作。不能对已结束的反馈对象使用 glResumeTransformFeedback。 六、反馈渲染 主条目Vertex_Rendering#Transform_feedback_rendering 若要呈现变换反馈操作捕获的数据可以使用查询对象获取捕获的基元数将该基元数乘以每个基元的顶点数然后将该顶点计数馈送到顶点渲染函数中。但是此过程要求 CPU 从查询对象中读取数据。这可能会引发同步问题。虽然同步对象可以解决其中一些问题但有更好的方法。 反馈对象记录它们在反馈操作中捕获的顶点数。请注意反馈操作仅在调用 glEndTransformFeedback 时完成因此在尝试使用此数据之前必须先调用该操作。 反馈操作完成后反馈对象将具有顶点计数。这可以通过绑定反馈对象并调用以下函数之一来用于渲染目的 glDrawTransform反馈 glDrawTransformFeedbackInstanced glDrawTransformFeedbackStream使用 OpenGL 4.0 或 ARB_transform_feedback3) glDrawTransformFeedbackStreamInstanced使用 OpenGL 4.0 或 ARB_transform_feedback3)这些函数的工作方式类似于 glDrawArrays或 glDrawArraysInstanced。请注意这些函数不执行任何顶点规范设置工作。它们不会自动获取反馈缓冲区并将它们绑定以用作顶点数据。你必须这样做。所有这些函数所做的都是从反馈操作中获取顶点计数。另请注意在第一次转换反馈传递时必须调用非转换 glDraw 函数才能将顶点数据写入转换反馈缓冲区因为转换反馈对象尚不具有顶点计数信息。完成此操作后glDrawTransform* 可以在转换反馈和渲染到屏幕期间使用。 七、局限性 使用单独捕获时可捕获的变量总数有限制。这是GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS至少是 4。此外任何特定变量可以包含的分量数量都有限制。这是GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS至少是 4。如果超过这些限制将导致程序链接错误。 使用交错捕获时限制是可以捕获的组件总数。这是GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS必须至少为 64。双精度组件计为 2。可以通过将缓冲区的所有步幅相加并除以 4 来计算着色器内规范的“组件”数量。该值必须小于此查询值。 使用高级交错将不同的变量路由到不同的缓冲区时可用缓冲区的数量限制GL_MAX_TRANSFORM_FEEDBACK_BUFFERS。 在 OpenGL 4.0 或 ARB_transform_feedback3 之前GL_TRANSFORM_FEEDBACK_BUFFER 的 glBindBufferRange 绑定索引限制为GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS因为多个缓冲区只能用于单独的输出。使用 OpenGL 4.0 或 ARB_transform_feedback3这是GL_MAX_TRANSFORM_FEEDBACK_BUFFERS。