Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/67.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
Opengl 计算着色器写入纹理_Opengl_Glsl_Map Projections_Compute Shader - Fatal编程技术网

Opengl 计算着色器写入纹理

Opengl 计算着色器写入纹理,opengl,glsl,map-projections,compute-shader,Opengl,Glsl,Map Projections,Compute Shader,我已经实现了将投影纹理复制到3d对象上更大纹理的CPU代码,“贴花烘焙”,如果你愿意的话,但现在我需要在GPU上实现它。为此,我希望使用计算着色器,因为在当前设置中添加FBO非常困难 这个问题更多的是关于如何使用计算着色器的,但是对于任何感兴趣的人来说,这个想法都是基于我从用户jozxyqk那里得到的答案,如下所示: 写入的纹理在我的代码中称为\u texture,而投影的纹理是\u textureProj 简单计算着色器 const char *csSrc[] = { "#versi

我已经实现了将投影纹理复制到3d对象上更大纹理的CPU代码,“贴花烘焙”,如果你愿意的话,但现在我需要在GPU上实现它。为此,我希望使用计算着色器,因为在当前设置中添加FBO非常困难

这个问题更多的是关于如何使用计算着色器的,但是对于任何感兴趣的人来说,这个想法都是基于我从用户jozxyqk那里得到的答案,如下所示:

写入的纹理在我的代码中称为
\u texture
,而投影的纹理是
\u textureProj

简单计算着色器

const char *csSrc[] = {
    "#version 440\n",
    "layout (binding = 0, rgba32f) uniform image2D destTex;\
     layout (local_size_x = 16, local_size_y = 16) in;\
     void main() {\
           ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);\
           imageStore(destTex, storePos, vec4(0.0,0.0,1.0,1.0));\
    }"
};
如你所见,我目前只想将纹理更新为任意(蓝色)颜色

更新功能

void updateTex(){ 
    glUseProgram(_computeShader);
    const GLint location = glGetUniformLocation(_computeShader, "destTex"); 
    if (location == -1){
        printf("Could not locate uniform location for texture in CS");
    }
    // bind texture
    glUniform1i(location, 0); 
    glBindImageTexture(0, *_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
    // ^second param returns the GLint id - that im sure of. 

    glDispatchCompute(_texture->width() / 16, _texture->height() / 16, 1); 
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

    glUseProgram(0);
    printOpenGLError(); // reports no errors.
}
问题 如果我在我的主程序对象之外调用
updateEx()
,我看不到任何效果,而如果我在它的范围内这样调用它:

 glUseProgram(_id); // vert, frag shader pipe
  updateTex();
  // Pass uniforms to shader 
  // bind _textureProj & _texture (latter is the one im trying to update) 
 glUseProgram(0);
然后在渲染时,我看到:

问题: 我意识到在主程序对象范围内设置更新方法不是正确的方法,但是这是获得任何可视化结果的唯一方法。在我看来,所发生的是,它几乎消除了fragmentshader并绘制到屏幕空间

我该怎么做才能让它正常工作?(我的主要重点是能够在纹理和更新中写入任何内容)

请让我知道如果更多的代码需要张贴

我相信在这种情况下,an会更容易、更快,我建议您这样做。但这个问题本身仍然很有道理

我很惊讶看到一个球体,因为你正在将蓝色写入整个纹理(如果纹理大小不是16的倍数,则减去任何边缘位)。我猜这是其他地方的代码

无论如何,您的主要问题似乎是能够在常规渲染的设置代码之外从计算着色器写入纹理我怀疑这与绑定
destTex
图像的方式有关。我不确定
TexUnit
activate
方法的作用,但要将GL纹理绑定到图像单元,请执行以下操作:

int imageUnitIndex = 0; //something unique
int uniformLocation = glGetUniformLocation(...);
glUniform1i(uniformLocation, imageUnitIndex); //program must be active
glBindImageTexture(imageUnitIndex, textureHandle, ...);
见:


最后,当您使用
image2D
时,要使用的屏障是
GL\u SHADER\u IMAGE\u ACCESS\u BARRIER\u BIT
<代码>GL_着色器_存储_屏障_位用于。

我不确定您所说的“主程序对象范围”是什么意思。什么是
\u programObject->activate()执行?您的“主程序范围”是否在单独的线程上?在线程之间进行调用时,OpenGL将无法正常工作。@GuyRT-哦,对不起,也许我在这里使用了错误的术语。_programObject->activate()的本质是它调用glUseProgram(id),id闪烁,我将编辑我的问题。@newObjekt它不在一个单独的线程上,我可能在那里使用了错误的术语,我的意思是在glUseProgram()中。谢谢您的快速回复。事实上,我已经明确地尝试过了(根据你的建议编辑了我的帖子)。我不完全确定格式,但检查后,它的GL_RGB似乎不受加载/存储方法的支持。因此,由于我没有得到GL_RGBA32F的glError,我认为这是一条路要走。另外,您现在看到im使用布局限定符显式绑定到0-仍然不起作用。我怀疑这与格式(不应该)有关,或者纹理加载过程中缺少步骤或其他什么。继续:为了满足我的要求,我似乎已经完成了一个“教科书”实现,所以我将再次尝试使用FBO(并在另一个线程中对此提出问题),但我将保留此代码,评论道。让我知道,如果我应该张贴更多的代码到这个,现在我有点不知道为什么它没有做它应该做的。也许我省略了关键代码,让我知道(谢谢!)。哦,还有一件事:我们看到“蓝色”球体的原因只是因为我在
glUseProgram()
调用中插入了
updateTex()
方法-ie-看起来它删除了片段着色器。我现在知道颜色是基于投影的垂直着色器
vec4位置
,这就是为什么它的蓝色-运行时间,它根据投影仪与曲面的角度更改颜色-完全错误,但这是我看到与计算着色器有关的唯一方式…:(