我遇到了一个让我心烦意乱的问题。
我正在研究一个小的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;
...
此外,即使手动绑定(它们应该显示的方式),我也会得到非常时髦的结果: 任何帮助将不胜感激!
所以看起来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
答案 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。