修改 我将GLTextureUnitID从uint更改为int,它导致错误停止显示,但是黑色方块呈现而不是纹理。当我注释掉对SetTexture的调用时,即使我从未在该行之前设置该制服,它仍会呈现正常。
EDIT2: GLTextureUnitID的值为1,而正在设置的纹理的ID为0。
EDIT3: 更改SetTexture函数以获得以下似乎已经解决了问题,但感觉有点像一个肮脏的解决方案。
GL.BindTexture(TextureTarget.Texture2D, (int)texture.GLTextureUnitID);
GL.Uniform1(GLTextureUnitLocation, 0);
原始问题: 我开始在我的项目中添加对纹理文件的支持,但每当我为我的纹理着色器程序调用GL.Uniform1时,我都会收到“InvalidOperation”错误。陌生人,当我注释掉导致错误的函数的调用时,纹理仍然会被渲染。
渲染纹理的四边形的RenderGUI函数是:
public override void RenderGUI()
{
// Translate Matrix to Position of GUI Element
Matrices.Translate(SetMatrixParam.ModelViewMatrix, Position.X, Position.Y, 0);
// Bind Shaders and Send Matrices
Shader.Bind();
Shader.SendMatrices();
// Set Texture Information
Shader.SetTexture(Texture); // <- This causes the error, it's just a call to Uniform1 using a property from the texture object, if commented out the error doesn't appear.
Shader.SetTextureColor(Color4.White);
GL.Begin(BeginMode.Triangles);
// Render Quad
Vector3 topLeft = new Vector3(0, 0, 0);
Vector3 bottomLeft = new Vector3(0, Size.Y, 0);
Vector3 topRight = new Vector3(Size.X, 0, 0);
Vector3 bottomRight = new Vector3(Size.X, Size.Y, 0);
Shader.SetTextureCoord(0, 0); GL.Vertex3(topLeft); // Top Left
Shader.SetTextureCoord(0, 1); GL.Vertex3(bottomLeft); // Bottom Left
Shader.SetTextureCoord(1, 1); GL.Vertex3(bottomRight); // Bottom Right
Shader.SetTextureCoord(0, 0); GL.Vertex3(topLeft); // Top Left
Shader.SetTextureCoord(1, 1); GL.Vertex3(bottomRight); // Bottom Right
Shader.SetTextureCoord(1, 0); GL.Vertex3(topRight); // Top Right
GL.End();
}
正在调用的函数导致出现错误:
public void SetTexture(Texture2D texture)
{
if (texture.GLTextureUnitID == null)
throw new ArgumentException();
GL.Uniform1(GLTextureUnitLocation, (uint)texture.GLTextureUnitID);
}
This can also be found at the github for this project.以及正在使用的Texture2D class和vertex以及fragment着色器以及class handling the shader program that uses those shaders。
答案 0 :(得分:1)
带错误的代码在哪里?
从http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml开始,列表中列出了glUniform1返回GL_INVALID_OPERATION的原因。我建议你仔细检查每一个并确认它是适用还是不适用。
以下是清单:
错误
如果没有当前程序,则生成GL_INVALID_OPERATION 对象
如果统一变量的大小,则生成GL_INVALID_OPERATION 在着色器中声明的大小与指示的大小不匹配 glUniform命令。
如果签名或未签名之一,则生成GL_INVALID_OPERATION 此函数的整数变体用于加载统一变量 类型为float,vec2,vec3,vec4或这些类型的数组,或者如果其中之一 此函数的浮点变体用于加载均匀 int,ivec2,ivec3,ivec4,unsigned int,uvec2,uvec3类型的变量, uvec4,或其中的数组。
如果有符号整数之一,则生成GL_INVALID_OPERATION 此函数的变体用于加载类型的统一变量 unsigned int,uvec2,uvec3,uvec4或其中的数组。
如果是无符号整数之一,则生成GL_INVALID_OPERATION 此函数的变体用于加载类型的统一变量 int,ivec2,ivec3,ivec4或其中的数组。
如果location是无效的制服,则会生成GL_INVALID_OPERATION 当前程序对象和位置的位置不等于 -1
如果count大于1且生成GL_INVALID_OPERATION,则会生成GL_INVALID_OPERATION 表示统一变量不是数组变量。
如果使用a加载采样器,则会生成GL_INVALID_OPERATION glUniform1i和glUniform1iv以外的命令。
答案 1 :(得分:1)
为了将纹理绑定到程序的统一插槽,您需要:
在你的纹理类中,我认为你混淆了纹理单元和gl-name。
以下是纹理绑定的伪代码
Int32 texunit = 0; // assume your shader only have 1 texture-type uniform
Shader.Bind();
GL.Uniform1( Shader.GetUniformLocation( "uniformName" ), texunit );
GL.ActiveTexture( texunit );
GL.BindTexture( TextureTarget.Texture2D, (int)tex.GLTextureUnitID ); // I recommend renaming tex.GLTextureUnitID to tex.GLName
希望这有帮助