使用LWJGL将属性传递给GLSL时遇到问题

时间:2013-08-30 05:29:12

标签: java opengl attributes glsl lwjgl

我正在尝试学习GLSL,我想将float属性发送到我的顶点着色器。现在,这个浮点数只用于设置亮度(我通过in_Light多次输入in_Color并将其分配给out_Color)。无论我尝试传递什么,亮度总是在顶点着色器中似乎等于1.0(在下面的代码中为0.1)。我试过谷歌搜索,我尝试了很多但我只是没有得到什么是错的。位置,纹理坐标和颜色似乎都很好。

以下是我如何绑定属性位置以及更多代码。

    this.vsId = Shader.loadShader(pVertexFilePath, GL20.GL_VERTEX_SHADER);
    this.fsId = Shader.loadShader(pFragmentFilePath, GL20.GL_FRAGMENT_SHADER);

    this.pId = GL20.glCreateProgram();
    GL20.glAttachShader(this.pId, this.vsId);
    GL20.glAttachShader(this.pId, this.fsId);

    GL20.glBindAttribLocation(this.pId, 0, "in_Position");
    GL20.glBindAttribLocation(this.pId, 1, "in_TextureCoord");
    GL20.glBindAttribLocation(this.pId, 2, "in_Color");
    GL20.glBindAttribLocation(this.pId, 3, "in_Light");

    GL20.glLinkProgram(this.pId);

    this.normalMatrixId = GL20.glGetUniformLocation(this.pId, "normalMatrix");
    this.projectionModelViewMatrixId = GL20.glGetUniformLocation(this.pId, "projModelViewMatrix");

这就是我设置每个属性的位置

的方法
    FloatBuffer verticesFloatBuffer = BufferUtils.createFloatBuffer(verticesCount * 36);
    for (VertexData vert : vertices) {verticesFloatBuffer.put(vert.getElements());}
    vertices.clear();
    verticesFloatBuffer.flip();

    GL30.glBindVertexArray(vaoId);

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesFloatBuffer, GL15.GL_STATIC_DRAW);

    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 36, 0);
    GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 36, 12);
    GL20.glVertexAttribPointer(2, 3, GL11.GL_FLOAT, false, 36, 20);
    GL20.glVertexAttribPointer(3, 1, GL11.GL_FLOAT, false, 36, 32);

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

这是上面使用的getElements方法(我手动输入颜色和亮度用于测试目的)。请注意,应该在__Light中的最后一个值是0.1f,并且在顶点着色器中始终为1.f.

public float[] getElements() {
    return new float[]{this.x, this.y, this.z, this.s, this.t, 1.f, 0.f, 1.f, 0.1f};
}

顶点着色器:

#version 430 core

uniform mat4 projModelViewMatrix;
uniform mat3 normalMatrix;

in vec3 in_Position;
in vec2 in_TextureCoord;
in vec3 in_Color;
in float in_Light;

out vec4 pass_Color;
out vec2 pass_TextureCoord;

void main(void) {
    gl_Position = projModelViewMatrix * vec4(in_Position, 1.0);

    pass_TextureCoord = in_TextureCoord;

    pass_Color = vec4(in_Color * in_Light, 1.0);
}

片段着色器(以防万一有人想看到它):

#version 430 core

uniform sampler2D texture_diffuse;

in vec4 pass_Color;
in vec2 pass_TextureCoord;

out vec4 out_Color;

void main(void) {
    out_Color = texture2D(texture_diffuse, pass_TextureCoord) * pass_Color;
}

我传递给顶点着色器的所有其他属性都可以正常工作。

编辑: 就像一个注释,我已经尝试更改着色器以指定位置,例如:

layout (location = 0) in vec3 in_Position;

我还使用了glGetAttributeLocation,它给了我相同的属性位置(0,1,2,3),例如:

GL20.glGetAttribLocation(this.pId, "in_Position");

我还在着色器中添加了一个if语句来检查in_Light的值,它总是等于一个。

EDIT2: 现在我已经将颜色属性更改为vec4并传递了光值来代替alpha工作正常。基于其他试验,以及这个,几乎就好像我出于某种原因不能拥有超过3个属性。

2 个答案:

答案 0 :(得分:4)

GL20.glLinkProgram(this.pId);

GL20.glBindAttribLocation(this.pId, 0, "in_Position");
GL20.glBindAttribLocation(this.pId, 1, "in_TextureCoord");
GL20.glBindAttribLocation(this.pId, 2, "in_Color");
GL20.glBindAttribLocation(this.pId, 3, "in_Light");

在链接程序之前,glBindAttribLocation调用需要。属性位置在链接时是固定的,因此如果你没有绑定任何属性,OpenGL将任意分配它们。

答案 1 :(得分:0)

除了Nicol Bolas提到的那个之外,是的,简单的noob错误。 (想知道我还有多少人;)

我需要在使用glVertexAttribPointer设置每个属性的位置之前添加glEnableVertexAttribArray。似乎前三个属性是自动启用的,但我想这可能会在每个GPU的基础上发生变化?

FloatBuffer verticesFloatBuffer = BufferUtils.createFloatBuffer(verticesCount * 36);
for (VertexData vert : vertices) {verticesFloatBuffer.put(vert.getElements());}
vertices.clear();
verticesFloatBuffer.flip();

GL30.glBindVertexArray(vaoId);

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesFloatBuffer, GL15.GL_STATIC_DRAW);

GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL20.glEnableVertexAttribArray(3);

GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 36, 0);
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 36, 12);
GL20.glVertexAttribPointer(2, 3, GL11.GL_FLOAT, false, 36, 20);
GL20.glVertexAttribPointer(3, 1, GL11.GL_FLOAT, false, 36, 32);

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

感谢所有回复的人!