2011-10-10 74 views
3

我试图找出为什么下面GLSL代码不起作用:GLSL预处理

#ifndef VertexPositionType 
#define VertexPositionType vec3 
#endif 

in StandardVertexShaderInputs { 
    VertexPositionType ds_VertexPosition; 
}; 

vec4 ProjectVertexPosition(in vec4 v); 

vec4 ProjectVertexPosition(in vec3 v); 

void main() { 
    gl_Position = ProjectVertexPosition(ds_VertexPosition); 
} 

着色器拒绝编译。该信息登录状态:

错误C1008:未定义的变量“ProjectVertexPosition”

即使它不发出警告的预处理,我得到了预处理符号VertexPositionType不被替换。如果我删除预处理器定义,一切都很好。现在

,说明书说:

的#define和#undef功能被定义为是用于具有和不具有宏 参数宏定义C++预处理器的标准。

也许下面这行是不是一个有效的预处理线?

#define VertexPositionType vec3 
+0

你尝试在多台机器/驱动程序版本GLSL支持通常比HLSL更酥,你可能已经打了一个坏的驱动程序? – Anteru

+0

编号实际上编译NVidia 280.26,着色器版本150 ... – Luca

+6

定义“不起作用” - 无法编译,无法链接,链接正常但不运行,还有其他吗?看看实际的编译器错误(如果有的话)是什么? –

回答

1

你声明的重载函数调用ProjectVertexPosition,但是你从来没有定义的,所以当你去链接程序,你会得到不确定的错误。这个错误可能更有意义的是说'未定义的函数'而不是'未定义的变量'(因为你声明它是一个函数),但我猜测链接器没有足够的信息来知道函数符号和一个可变符号。

这个错误可能是从LinkProgram调用,不CompileShader电话来了,无关与预处理或VertexPositionType

+0

不要告诉我的箱子上发生了什么。你不相信我的分析吗?它不够吗?如果你愿意的话,我可以公开所有的步骤来断言这个问题是关于预处理器的... – Luca

+0

...只是指出它,函数是在另一个着色器对象中定义的,并且错误是从CompileShader信息日志。 – Luca

+4

既然你没有提供任何有关正在发生的事情的信息,我不得不猜测。你没有提供足够的信息来重现这个问题,你所看到的东西似乎与预处理器无关。 –

5

着色器是非法的。 NVIDIA的编译器可能不会随地吐痰了正确的错误,但你的着色是做了错误的事(当然,除了这个事实,你没有提供#version声明。我认为#version 330,但它总是好的是明确约GLSL版本) 。

我只能假设这是一个顶点着色器,因为你写gl_Position。输入接口块在顶点着色器中为非法,就像输出接口块在片段着色器中非法。 AMD的编译器是相当更加明确这一点:

ERROR: 0:5: error(#328) interface block should not apply in 'Vertex Shader in'. 
ERROR: 0:14: error(#143) Undeclared identifier ds_VertexPosition 
ERROR: 0:14: error(#202) No matching overloaded function found ProjectVertexPosition 
ERROR: 0:14: error(#160) Cannot convert from 'const float' to 'Position 4-component vector of float' 
ERROR: error(#273) 4 compilation errors. No code generated 

当我删除的接口块定义,把它当作只是in VertexPositionType ds_VertexPosition;,它编译罚款。

如果我删除了预处理器定义,一切都很好。

然后恭喜你:你找到了一个N​​VIDIA驱动程序的bug。您应该将它报告给它们,因为顶点着色器中不允许输入接口块。

0

你的计划有两个主要问题。 #define不是你的问题。第一个问题是您从不提供vec4 ProjectVertexPosition(in vec# v)函数的实现。您需要提供的声明,例如

vec4 ProjectVertexPosition(in vec3 v) { 
    return normalize(vec4(v, 1.0)); 
} 

,也为in vec4 v版本。去掉define的原因是修复了你的问题,这是因为它使着色器忽略了输入块,而输入块是无效的。在顶点着色器中,你不能使用in块。相反,使用布局和结构或制服和结构。对于顶点着色器,您只需使用制服或布局,而不是纯粹的in s。如果你想使用的布局,做到以下几点:

layout(location = 0) in VertexPositionType ds_VertexPosition; 

对于C/C++方面,做了以下(其中pointCount是点在你的VAO和点的数量是一个GLfloat *包含以点X1,Y1,Z1,X2,Y2,Z2,X3 ...:

GLfloat* points = (GLfloat*) malloc(pointCount * 3 * sizeof(GLfloat)); 
// Set your points however you want here 

GLuint vao; 
glGenVertexArrays(1, &vao); 
glBindVertexArray(vao); 

GLuint vbo; 
glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, 3 * pointCount * sizeof(GLfloat), points, GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
glEnableVertexAttribArray(0); 
free(points); 

// Now to draw (use whatever programId is returned when you link the program) 
glUseProgram(programId); 
glBindVertexArray(vao); 
glDrawArrays(GL_TRIANGLES, 0, pointCount); 
glUseProgram(0);