由GLSL属性类型/版本混淆

时间:2014-07-06 11:22:11

标签: opengl glsl opentk

我应该何时使用以下每种方法接收glsl中的数据?

layout(points) in;
in vec3 pos;
uniform float x;

据我所知,“在”意味着它是属性,而不是制服。所有着色器中都有制服,而在此特定着色器中定义属性。同样的制服通过glUniformTYPE传递,而属性(我不确定)必须通过缓冲区传递。

我试图避免使用opengl内置的函数,比如glMatrix等,因为教程建议这基本上是depricated / old样式。那是对的吗?如果是这样,我如何将索引分配给缓冲区,例如?

1 个答案:

答案 0 :(得分:3)

您粘贴的三行指定了完全不同的内容。

layout(points) in;

这似乎来自几何着色器阶段的输入限定。它声明此几何着色器将GL_POINTS作为输入基元类型(即您必须绘制GL_POINTS)。它通常后跟类似的基元类型的声明,然后从几何着色器输出,例如

layout(triangle_strip, max_vertices=3) out; // drawing triangles

in vec3 pos;

这改为声明这个着色器阶段的通用“输入”,类型为vec3。根据实际的着色器阶段,其含义可能不同。例如,在顶点着色器中,它意味着是一个每顶点属性 - 即一组数据,它是每个顶点唯一的¹。在几何着色器中,您将获得整个基元作为输入。在片段着色器中使用栅格化值。

在顶点着色器的情况下,处理的每个顶点将从一个合适的已配置输入数组中获得自己的“pos”,通常²来自之前已绑定到{{1}的缓冲区对象绑定点并已配置为通过GL_ARRAY_BUFFER调用向该属性提供数据。

OR ,它可能是片段着色器的输入。在这种情况下,它是一个每片段属性,(在默认情况下,没有额外的资格)已经过透视校正插值。例如,顶点着色器可以为每个顶点输出颜色:

glVertexAttribPointer

并且片段着色器可以选择插值颜色:

#version 330
in vec3 position;
in vec3 input_color; // attribute as before

out vec3 color; // output towards the next shader stage

// (potentially) ran once per input vertex
void main() {
    gl_Position = vec4(position, 1.0);
    color = input_color;
}

因此,“in”和“out”的含义取决于它们使用的特定着色器阶段。


#version 330

in vec3 color; // automatically "paired" to the VS output, i.e. the previous shader stage 
               // gets perspective-correct interpolation


out vec4 screenColor; // output => drawn on the screen

// (potentially) ran once per drawn fragment
void main() {
    screenColor = vec4(color, 1.0);
}

这只是意味着“x”是整个着色器程序的float类型的统一。它不能在着色器程序中更改;所有着色器阶段都会看到它(它们只需要声明它)。


  

如果是这样,我如何为缓冲区分配索引?例如?

这是什么意思?


  

是否有关于现代opengl绘图的教程,使这些内容清晰明了并且符合现代标准,同时还涵盖了所有基础知识?

是的,例如http://www.opengl-tutorial.org/

¹此规则有例外,例如属性除数,但让我们保持简单。

²阅读:你应该做什么。您可以避免使用缓冲区并直接指定顶点属性值,但很可能发生的是GL驱动程序将在幕后分配缓冲区。