Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 奇怪的着色器损坏_C++_Glsl_Shader - Fatal编程技术网

C++ 奇怪的着色器损坏

C++ 奇怪的着色器损坏,c++,glsl,shader,C++,Glsl,Shader,我正在和着色器一起工作,我观察到一些非常奇怪的行为。我已加载此顶点着色器: #version 150 uniform float r; uniform float g; uniform float b; varying float retVal; attribute float dummyAttrib; void main(){ retVal = dummyAttrib+r+g+b; //deleting dummyAttrib = corruption gl_Positio

我正在和着色器一起工作,我观察到一些非常奇怪的行为。我已加载此顶点着色器:

#version 150

uniform float r;
uniform float g;
uniform float b;
varying float retVal;
attribute float dummyAttrib;

void main(){
    retVal = dummyAttrib+r+g+b; //deleting dummyAttrib = corruption
    gl_Position = gl_ModelViewProjectionMatrix*vec4(100,100,0,1);
}
首先,我使用
glDrawArrays(GL_POINTS,01000)
使用这个着色器进行渲染,没有什么特别的,只是使用着色器程序。如果运行此着色器并将“点大小”设置为可见的值,您应该会在屏幕中间看到白色正方形(我使用的是
glOrtho2d(0200,0200)
DummyAttrib
只是一些attrib-如果没有,我的着色器将不会运行。此外,我还需要实际使用该属性,所以通常我会执行类似于
float c=dummyAttrib
的操作。这也是我想问的第一个问题,为什么会这样

但是,如果您将带有注释的行(
retval=…
)更改为
retval=r+g+b,则这将很好
并添加上面提到的行以使用attrib(
float c=dummyAttrib
),奇怪的事情就会发生。首先,你再也看不到那个方块了,所以我必须设置转换反馈来观察发生了什么

我已经在字段的每个元素中将dummyAttrib设置为5,r=g=b=1。对于当前代码,转换反馈的结果是8-这正是您所期望的。然而,像上面那样修改它会得到像250.128这样的奇怪值,每次我以某种方式修改代码(只是重新排序调用),这个值都会改变。只要我将
dummyAttrib
返回到
retVal
的计算中,一切都神奇地修复了

这就是我认为存在某种着色器损坏的原因。我使用的着色器加载界面与我以前在项目中使用的相同,这些都是完美的,但是它们以正常的方式使用属性,而不仅仅是实际运行着色器的虚拟属性

这两个问题可能有关联。总之,着色器在没有任何属性的情况下不会运行,如果该属性未用于设置片段着色器或变换反馈中使用的变量,则着色器将损坏


PS:当我写这篇文章时,我突然想到,似乎每个不用于传递到下一阶段的变量都是opt-out。这也可以选择退出属性,然后该着色器将没有属性,无法正常工作。这可能是司机的过错吗?我有Radeon 3870HD和当前catalyst版本2010.1105.19.41785。

如果您人为使用(
float c=dummyAttrib
),该属性将被优化。问题是在这种情况下,网格准备逻辑做了什么。如果它从GL查询已使用的属性,它将一无所获。如果未传递顶点属性,则不会绘制基本体(我的Radeon 2400HD在任何Catalyst上的行为)


因此,基本上,如果GL报告属性根本不存在,您应该传递一个人工的未使用属性(例如,在一些未初始化的缓冲区中,每个顶点1字节)。如果其他人在选择退出属性时也经历了相同的行为,那就太好了。我先在这里问过,但如果我昨天没有得到答案,我会整天在不同的catalyst版本之间切换。然而,如何查询属性是否已被选择退出?我使用了
glGetActiveAttrib
,它在名称中返回“dummyAttrib”。还有,从单元化缓冲区传递1字节意味着什么?这听起来像是访问冲突。如果
glGetActiveAttrib
在这两种情况下都返回您
dummyAttrib
,那么它看起来就像一个谜,您需要向ATI发送一个测试用例。在已分配但未初始化的缓冲区中传递1字节/顶点属性不会违反访问权限。第二种情况是什么?我在链接着色器后立即查询。对于那个未初始化的缓冲区-我知道你现在的意思,但和我现在做的有什么区别(除了字节比浮点小四倍之外)?我如何设置属性,而实际上GL会报告存在不可用的属性。我可以通过内置属性来实现这一点,但我不想弄乱这些(我不知从哪里得到了足够多的奇怪bug)第一种情况:
retVal=dummyAttrib+r+g+b
;第二种情况:
c=dummyAttrib
;GL向您报告着色器使用的属性。您仍然可以通过draw调用传递任何数据。(不需要内置属性)我将着色器修改为
c=dummyAttrib
retVal=5。我仍然可以通过
glGetActiveAttrib
获得该属性名,但是变换反馈的结果应该是5,并且是0-这意味着着色器不工作,dummyAttrib被选择退出。然而,这必须在运行时发生,更具体地说是在绘图调用中,因为如果在链接阶段完成,我无法毫无问题地查询该属性。我在drawArrays之前绑定了那个空的但分配的缓冲区,但什么都没有改变,我知道它不会改变。也许我没抓住你说的重点?