-1

我刚刚在 OpenGL 3.2 中创建了一个简单的矩形,现在我想添加光照支持。但是,每当我尝试将法线移动到片段着色器时,什么都不会出现。如果我注释掉那条线,它会再次完美运行。造成这种情况的原因是什么?错误日志中没有显示任何内容。

顶点着色器:

#version 150

in vec4 position;
in vec3 inNormal;

out vec3 varNormal;

uniform mat4 modelViewProjectionMatrix;

void main()
{
    //varNormal = inNormal; //If I uncomment this line, nothing shows up    
gl_Position = modelViewProjectionMatrix * position;
}

片段着色器:

#version 150

in vec3 varNormal;

out vec4 fragColor;

void main()
{
fragColor = vec4(1, 1, 1, 1);   
}

并通过法线:



GLuint posAttrib = 0;
GLuint normalAttrib = 1;

glBindAttribLocation(program, posAttrib, "position");
glBindAttribLocation(program, normalAttrib, "normalAttrib");

//Building the VAO's/VBO's
GLfloat posCoords[] = 
{
    -10, 0.0, -10,
    -10, 0.0, 10,
    10, 0.0, 10,
    10, 0.0, -10,   
};

GLfloat normalCoords[] = 
{
    0, 0, 1,
    0, 0, 1,
    0, 0, 1,
    0, 0, 1
};

glGenVertexArrays(1, &vaoName);
glBindVertexArray(vaoName);

GLuint posBuffer;
glGenBuffers(1, &posBuffer);
glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(posCoords), posCoords, GL_STATIC_DRAW);
glEnableVertexAttribArray(posAttrib);   
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);

GLuint normalBuffer;        
glGenBuffers(1, &normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(normalCoords), normalCoords, GL_STATIC_DRAW);
glEnableVertexAttribArray(normalAttrib);
glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);

我没有尝试将我所有的位置和正常坐标放在一个 VBO 中,但我不想使用这种方法。

4

2 回答 2

1

不确定这是您的实际代码还是剪切和粘贴,但调用 glBindAttribLocation 仅在下次调用 glLinkProgram后才会生效。

如果您在调用 glBindAttrib 后没有链接程序,则这些将不会生效,并且您的属性可能会被赋予错误的索引。这可以解释为什么在取消注释正常行后会出现不同的行为。

于 2012-07-16T04:39:33.283 回答
0

可能是解决此问题的最奇怪的原因,但它确实有效。

首先,确保您了解 OpenGL Profiler 的工作原理。Apple Docs提供了一个教程

在 glDrawElements 之前/之后设置断点(或 glDrawArray 取决于您使用的内容)

然后查看程序的顶点属性并确保位置是有序的。

如果不是,请重新排列它们。

从(或任何其他):

enum
{
POSITION_ATTR = 0,
TEXTURE_ATTR=1,
NORMAL_ATTR=2,
};

到:

enum
{
NORMAL_ATTR = 0,
TEXTURE_ATTR=2,
POSITION_ATTR=1,
};

不知道如何以及为什么会发生这种情况,但这是解决问题的方法。

于 2012-10-14T06:56:26.003 回答