GLSL 统一 ivec 未设置,并且在询问时具有默认(错误)值
GLSL uniform ivec doesn't set and has default (wrong) value when is being asked
我有一个包含多个GLSL程序(OpenGL 3.3(的场景。这些程序使用不同的着色器,这些着色器是相似的,但(将(有一些差异。我有一个统一的ivec4 char1
,对所有版本命名相同,对所有程序都具有相同的含义和价值。此制服用于dot1(...)
函数,该函数用于着色器中的main()
函数。
fragment3d.glsl:
#version 330 core
smooth in vec4 vertexPosition;
smooth in vec4 vertexColor;
smooth in vec4 vertexNormal;
out vec4 fragmentColor;
uniform ivec4 char1;
uniform float shineness;
float dot1(vec4 x, vec4 y)
{
float result = 0.0;
for (int i = 0; i < 4; i++)
{
result += char1[i] * x[i] * y[i];
}
return result;
}
void main()
{
if (vertexNormal == vec4(0.0, 0.0, 0.0, 0.0))
{
fragmentColor = vertexColor;
}
else
{
vec4 lightDirection = vec4(1.0, 0.0, 0.0, 0.0) - vertexPosition;
float lightNormInverse = inversesqrt(dot1(lightDirection, lightDirection));
lightDirection *= lightNormInverse;
float diffuseCoefficient = dot1(lightDirection, vertexNormal);
vec4 reflectedDirection = 2 * diffuseCoefficient * vertexNormal - lightDirection;
diffuseCoefficient = abs(diffuseCoefficient);
float specularCoefficient = max(dot1(reflectedDirection, lightDirection), 0.0);
if (specularCoefficient > 0.0 && shineness > 0.0)
{
specularCoefficient = pow(specularCoefficient, shineness);
}
vec3 diffuseColor = clamp(vertexColor.rgb * diffuseCoefficient, 0.0, 1.0);
vec3 specularColor = clamp(vec3(0.5, 0.5, 0.5) * specularCoefficient, 0.0, 1.0);
fragmentColor.rgb = diffuseColor + specularColor;
fragmentColor.a = 1.0 - diffuseCoefficient * (1.0 - vertexColor.a);
}
}
fragment3d-new.glsl
#version 330 core
smooth in vec4 geometryPosition;
smooth in vec4 geometryNormal;
smooth in vec4 geometryColor;
out vec4 fragmentColor;
uniform ivec4 char1;
uniform float shineness;
float dot1(vec4 x, vec4 y)
{
float result = 0.0;
for (int i = 0; i < 4; i++)
{
result += char1[i] * x[i] * y[i];
}
return result;
}
void main()
{
if (geometryNormal == vec4(0.0, 0.0, 0.0, 0.0))
{
fragmentColor = geometryColor;
}
else
{
vec4 lightDirection = vec4(1.0, 0.0, 0.0, 0.0) - geometryPosition;
float lightNormInverse = inversesqrt(dot1(lightDirection, lightDirection));
lightDirection *= lightNormInverse;
float diffuseCoefficient = dot1(lightDirection, geometryNormal);
vec4 reflectedDirection = 2 * diffuseCoefficient * geometryNormal - lightDirection;
diffuseCoefficient = abs(diffuseCoefficient);
float specularCoefficient = max(dot1(reflectedDirection, lightDirection), 0.0);
if (specularCoefficient > 0.0 && shineness > 0.0)
{
specularCoefficient = pow(specularCoefficient, shineness);
}
vec3 diffuseColor = clamp(geometryColor.rgb * diffuseCoefficient, 0.0, 1.0);
vec3 specularColor = clamp(vec3(0.5, 0.5, 0.5) * specularCoefficient, 0.0, 1.0);
fragmentColor.rgb = diffuseColor + specularColor;
fragmentColor.a = 1.0 - diffuseCoefficient * (1.0 - geometryColor.a);
}
}
初始化C++代码为:
glUseProgram(0);
if (m_glProgram[GEOMETRY] != 0)
{
glDeleteProgram(m_glProgram[GEOMETRY]);
}
if (m_glProgram[TRIANGLE] != 0)
{
glDeleteProgram(m_glProgram[TRIANGLE]);
}
if (m_glProgram[TEXTURE] != 0)
{
glDeleteProgram(m_glProgram[TEXTURE]);
}
GLuint vertexShaderGeometry = compileShader(GL_VERTEX_SHADER, vertex, ss);
GLuint fragmentShaderGeometry = compileShader(GL_FRAGMENT_SHADER, fragment, ss);
vector<GLuint> shadersGeometry = {vertexShaderGeometry, fragmentShaderGeometry};
m_glProgram[GEOMETRY] = compileProgram(shadersGeometry, ss);
glUseProgram(m_glProgram[GEOMETRY]);
m_glUniform[GEOMETRY_PROJECTION] = glGetUniformLocation(m_glProgram[GEOMETRY], "projection"); // Set in changeProjection(...)
m_glUniform[GEOMETRY_ORIENTATION] = glGetUniformLocation(m_glProgram[GEOMETRY], "orientation"); // Set in changeOrientation(...)
m_glUniform[GEOMETRY_MODE] = glGetUniformLocation(m_glProgram[GEOMETRY], "mode"); // Set here
m_glUniform[GEOMETRY_CHAR1] = glGetUniformLocation(m_glProgram[GEOMETRY], "char1"); // Set here
m_glUniform[GEOMETRY_SHANENESS] = glGetUniformLocation(m_glProgram[GEOMETRY], "shineness"); // Set here? For now it is hardcoded.
cleanProgram(m_glProgram[GEOMETRY], shadersGeometry);
if (m_glUniform[GEOMETRY_MODE] >= 0 && dim == 2)
{
// TODO Add configuration for Poincare model.
// For now, Beltrami-Klein is hardcoded.
glUniform1i(m_glUniform[GEOMETRY_MODE], 1);
}
if (m_glUniform[GEOMETRY_CHAR1] >= 0)
{
GLint char1[4];
char1[0] = m_projected.chars(0);
char1[1] = 1;
char1[2] = m_projected.chars(1);
char1[3] = m_projected.chars(1, 2);
glUniform4iv(m_glUniform[GEOMETRY_CHAR1], 1, char1);
}
if (m_glUniform[GEOMETRY_SHANENESS] >= 0)
{
// Add it to configuration. For now it is hardcoded.
glUniform1f(m_glUniform[GEOMETRY_SHANENESS], 1.0);
}
////////////////////////////////////////////////////////
if (dim == 3)
{
GLuint vertexShaderNew3d = compileShader(GL_VERTEX_SHADER, "vertex3d-new.glsl", ss);
GLuint geometryShaderNew3d = compileShader(GL_GEOMETRY_SHADER, "geometry3d-new.glsl", ss);
GLuint fragmentShaderNew3d = compileShader(GL_FRAGMENT_SHADER, "fragment3d-new.glsl", ss);
m_glProgram[TRIANGLE] = compileProgram({vertexShaderNew3d, geometryShaderNew3d, fragmentShaderNew3d}, ss);
glUseProgram(TRIANGLE);
m_glUniform[PLANE_3D_PROJECTION] = glGetUniformLocation(m_glProgram[TRIANGLE], "projection"); // Set in changeProjection(...)
m_glUniform[PLANE_3D_ORIENTATION] = glGetUniformLocation(m_glProgram[TRIANGLE], "orientation"); // Set in changeOrientation(...)
m_glUniform[PLANE_3D_CHAR1] = glGetUniformLocation(m_glProgram[TRIANGLE], "char1"); // Set here
m_glUniform[PLANE_3D_SHANENESS] = glGetUniformLocation(m_glProgram[TRIANGLE], "shineness"); // Set here? For now it is hardcoded.
cout << "m_glProgram[PLANE_3D] = " << m_glProgram[TRIANGLE] << endl;
cout << "m_glUniform[PLANE_3D_PROJECTION] = " << m_glUniform[PLANE_3D_PROJECTION] << endl;
cout << "m_glUniform[PLANE_3D_ORIENTATION] = " << m_glUniform[PLANE_3D_ORIENTATION] << endl;
cout << "m_glUniform[PLANE_3D_CHAR1] = " << m_glUniform[PLANE_3D_CHAR1] << endl;
cout << "m_glUniform[PLANE_3D_SHANENESS] = " << m_glUniform[PLANE_3D_SHANENESS] << endl;
if (m_glUniform[PLANE_3D_CHAR1] >= 0)
{
GLint char1[4];
char1[0] = m_projected.chars(0);
char1[1] = 1;
char1[2] = m_projected.chars(1);
char1[3] = m_projected.chars(1, 2);
cout << "Before setting: "; for (int i = 0; i < 4; i++) {cout << char1[i] << ' ';} cout << endl;
glUniform4iv(m_glUniform[PLANE_3D_CHAR1], 1, char1);
glGetUniformiv(m_glProgram[TRIANGLE], m_glUniform[PLANE_3D_CHAR1], char1);
cout << "Read after setting: "; for (int i = 0; i < 4; i++) {cout << char1[i] << ' ';} cout << endl;
glGetUniformiv(m_glProgram[GEOMETRY], m_glUniform[GEOMETRY_CHAR1], char1);
cout << "Similar for GEOMETRY: "; for (int i = 0; i < 4; i++) {cout << char1[i] << ' ';} cout << endl;
}
if (m_glUniform[PLANE_3D_SHANENESS] >= 0)
{
// Add it to configuration. For now it is hardcoded.
glUniform1f(m_glUniform[PLANE_3D_SHANENESS], 1.0);
}
}
由于某种原因,ivec4 char1
制服设置正确,可以从具有m_glProgram[GEOMETRY]
和均匀m_glUniform[GEOMETRY_CHAR1]
的第一个着色器读取,但在具有m_glProgram[TRIANGLE]
和均匀m_glUniform[PLANE_3D_CHAR1]
的第二个着色器中没有正确设置。此代码的输出为:
m_glProgram[PLANE_3D] = 5
m_glUniform[PLANE_3D_PROJECTION] = 1262
m_glUniform[PLANE_3D_ORIENTATION] = 1261
m_glUniform[PLANE_3D_CHAR1] = 1263
m_glUniform[PLANE_3D_SHANENESS] = 1264
Before setting: 0 1 1 1
Read after setting: 0 0 0 0
Similar for GEOMETRY: 0 1 1 1
这意味着准备好的矢量[0, 1, 1, 1]
在第一个着色器/程序中正确设置,而不是在第二个着色器/程序中。对其值的查询返回默认值[0, 0, 0, 0]
。这是怎么回事?
如果按glUniform4iv
设置统一变量,则着色器程序必须作为当前渲染状态的一部分进行安装,因为glUniform4iv
将值设置为当前着色器程序对象的默认统一块。请参阅glUseProgram
。
TRIANGLE
是存储在容器m_glProgram
中的着色器程序对象的索引,但不是着色器程序对象本身。
这意味着glUseProgram(TRIANGLE)
不会做你期望它做的事情。
将其更改为:
glUseProgram(m_glProgram[TRIANGLE]);
相关文章:
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 错误:当我从"WinDbg"打开可执行文件时,找不到符号文件。默认导出 ntdll 的符号.dll
- 默认/样板代码在Visual Studio 2017中给我错误.E1574.虚幻.但构建成功了
- VS2019:资源文件错误:中性(默认)(未知子语言:0x8)
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- 默认构造函数上的分段错误
- GLSL 统一 ivec 未设置,并且在询问时具有默认(错误)值
- 删除使数据处于"错误状态"的默认构造函数的模式?
- C++17 中的歧义错误(模板模板参数和默认参数问题)
- 编译器错误:没有合适的默认构造函数可用
- 处于默认参数位置的 Lambda 无法访问好友成员。这是编译器错误吗?
- 错误 C2512:没有可用的适当默认构造函数:在构造函数中声明带有参数的对象!
- 非默认析构函数会导致不完整的类型错误
- Eclipse 构建错误在默认的 hello world 上
- 使用默认构造函数引用成员变量初始化错误
- 默认模板类型给出错误,但显式类型不会
- C++中出现意外的编译错误:将默认值传递给函数参数
- 默认构造函数不同声明的链接器错误
- 使用std :: map时,包含unique_ptr的结构中的默认破坏者会导致编译错误
- 由于不变成员而具有可能已删除的默认构造函数,因此解决编译器错误