LWJGL - 要交换的属性名称和类型

时间:2016-02-17 00:28:07

标签: java opengl glsl lwjgl

我遇到了一个让我心烦意乱的问题。

我正在研究一个小的LWJGL引擎,并且我遇到着色器问题。现在我正在尝试将纹理添加到我的一个测试着色器中,看起来好像OpenGL正在改变输入属性的类型和名称(或者我是一个白痴)。到目前为止,我的代码看起来像这样:

Program.java(入口点)

program.introspect("vertexPosition");
program.introspect("vertexNormal");
program.introspect("vertexTexture");

程序是我的ShaderProgram类型,其中introspect函数如下所示:

public void introspect(String name)
{
    int location = getAttributeLocation(name);

    IntBuffer size = BufferUtils.createIntBuffer(1);
    IntBuffer type = BufferUtils.createIntBuffer(1);
    GL20.glGetActiveAttrib(myProgramHandle, location, size, type);

    Logger.log(name + " @ " + myDebugName + "." + location);
    Logger.log("\tType: " + ShaderParamType.get(type.get(0)));
    Logger.log("\tSize: " + size.get(0));
}

顶点着色器看起来像这样(从XML文件加载):

#version 410 core
in vec4 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexture;
...

在我的日志文件中,我得到了这个:

vertexPosition @ Test.0
    Type: Vector3f
    Size: 1
vertexNormal @ Test.1
    Type: Vector4f
    Size: 1
vertexTexture @ Test.2
    Type: Vector2f
    Size: 1

如您所见,位置和法线的类型已交换。

ShaderParamType.get只是枚举中的一个函数,它使用开关来获取GL值的枚举值:

switch(value)
{
    case GL_FLOAT:
        return Float;
    case GL_FLOAT_VEC2:
        return Vector2f;
    case GL_FLOAT_VEC3:
        return Vector3f;
    case GL_FLOAT_VEC4:
        return Vector4f;
    ...

此外,即使手动绑定(它们应该显示的方式),我也会得到非常时髦的结果: Error, vertices are not properly aligned 任何帮助将不胜感激!

修改

所以看起来glGetAttribLocation与glGetActiveAttrib没有排列到同一个位置。如果我更改日志记录以将名称记录为从glGetActiveAttrib获取的名称,则类型是正确的但位置不正确(即使在着色器中明确声明了lcations)。如果我绑定属性以匹配日志中的属性,我每次绘制调用只会得到一个多边形,即使禁用了剔除。

修改后的内省:

public int getAttributeLocation(String name) 
    {
        return glGetAttribLocation(myProgramHandle, name);
    }

    public void introspect(String name)
    {
        int location = getAttributeLocation(name);

        if (location != -1)
        {
            IntBuffer size = BufferUtils.createIntBuffer(2);
            IntBuffer type = BufferUtils.createIntBuffer(2);
            String attName = GL20.glGetActiveAttrib(myProgramHandle, location, size, type);

            Logger.log(attName + " @ " + myDebugName + "." + location);
            Logger.log("\tType: %s", ShaderParamType.get(type.get(0)));

            Logger.log("\tSize: " + size.get(0));
        }
    }

日志:

vertexNormal @ Test.0
    Type: Vector3f
    Size: 1
vertexPosition @ Test.1
    Type: Vector4f
    Size: 1
vertexTexture @ Test.2
    Type: Vector2f
    Size: 1

新图片: enter image description here

1 个答案:

答案 0 :(得分:0)

事实证明,我的顶点声明或着色器实际上并不是问题。几个小时后,我确定这个问题出现在我曾经做过的网状建筑实用工具中,我忘记了一个逗号。所以不要看起来像这样:

// X       Y        Z       nX  nY  nZ  U  V
-size.x, -size.y,  size.z,  0,  0,  1,  0, 1,
 size.x, -size.y,  size.z,  0,  0,  1,  1, 1,
-size.x,  size.y,  size.z,  0,  0,  1,  0, 0,
 size.x,  size.y,  size.z,  0,  0,  1,  1, 0,

看起来像这样:

// X       Y        Z       nX  nY  nZ  U  V
-size.x, -size.y,  size.z,  0,  0,  1,  0, 1,
 size.x, -size.y,  size.z,  0,  0,  1,  1, 1
-size.x,  size.y,  size.z,  0,  0,  1,  0, 0,
 size.x,  size.y,  size.z,  0,  0,  1,  1, 0,

注意第二行缺少逗号。这导致我的顶点数据是1个元素短,因此所有的怪异。

同样,对于任何偶然发现这种情况的人来说,getAttributeLocation和getActiveAttribute id不排队的原因是因为他们不应该这样做。 getActiveAttribute调用属性索引,而getAttributeLocation返回数据来自的实际插槽。有关详细信息,请参阅the OpenGL wiki