我的OpenGL应用程序从两个ascii源文件加载其顶点和片段着色器。编译片段着色器会产生以下错误:
0:35(22): error: operands to arithmetic operators must be numeric
0:35(17): error: cannot construct `vec4' from a non-numeric data type
0:40(31): error: too many parameters to `vec4' constructor
许多小时后,到目前为止,我仍然找不到这些错误的原因。这是着色器源:
#version 330
/*
Adapted from phong shader demo at http://www.cs.toronto.edu/~jacobson/phong-demo/
*/
/// precision MEDIUMP float; // Generates a syntax error on non-embedded OpenGL
varying vec3 normalInterp; // Surface normal
varying vec3 vertPos; // Vertex position
uniform int mode; // Rendering mode
uniform float u_Ka; // Ambient reflection coefficient
uniform float u_Kd; // Diffuse reflection coefficient
uniform float u_Ks; // Specular reflection coefficient
uniform float u_shininess; // Shininess
// Material color
/// uniform vec3 u_ambientColor;
uniform vec3 u_diffuseColor;
uniform vec3 u_specularColor;
uniform vec3 u_lightPos; // Light position
varying vec4 ambientColor;
void main() {
vec3 N = normalize(normalInterp);
vec3 L = normalize(u_lightPos - vertPos);
// Lambert's cosine law
float lambertian = max(dot(N, L), 0.0);
float specular = 0.0;
if(lambertian > 0.0) {
vec3 R = reflect(-L, N); // Reflected light vector
vec3 V = normalize(-vertPos); // Vector to viewer
// Compute the specular term
float specAngle = max(dot(R, V), 0.0);
specular = pow(specAngle, u_shininess);
} // This is line 35!
gl_FragColor = vec4(u_Ka * ambientColor +
u_Kd * lambertian * u_diffuseColor +
u_Ks * specular * u_specularColor, 1.0);
但是着色器源文件的“第35行”是结束的“}”,而不是实际的语句。如何解释编译器错误消息上的行号? 有人可以帮我找到这些错误吗?错误消息行号错误时,人们如何调试GLSL代码?
答案 0 :(得分:4)
环顾所提到的行-下一行有错误:
gl_FragColor = vec4(u_Ka * ambientColor +
u_Kd * lambertian * u_diffuseColor +
u_Ks * specular * u_specularColor, 1.0);
定义为ambientColor
的 vec4
用于期望vec3
作为vec4(rgb, a)
构造函数的第一个参数的数学运算。
这样特定的行可能看起来像这样:
gl_FragColor = vec4(ambientColor.rgb * u_Ka
+ u_diffuseColor * lambertian * u_Kd
+ u_specularColor * specular * u_Ks, 1.0);
GLSL日志因供应商而异,但是只要您自己的GLSL代码编号没有混淆,通常行号在日志中看起来是正确的。
0:35(22)
通常是指传递给glShaderSource()
的GLSL代码的第0部分(因为有可能传递字符串数组,而不仅仅是传递单个字符串)在代码的第35行和第22列。