【发布时间】:2015-02-14 04:22:05
【问题描述】:
我已经实现了将投影纹理复制到 3d 对象上的更大纹理的 CPU 代码,如果你愿意的话,“贴花烘焙”,但现在我需要在 GPU 上实现它。为此,我希望使用计算着色器,因为在我当前的设置中添加 FBO 非常困难。
Example image from my current implementation
这个问题更多的是关于如何使用计算着色器,但对于任何感兴趣的人,这个想法是基于我从用户 jozxyqk 那里得到的答案,在这里看到:https://stackoverflow.com/a/27124029/2579996
写入的纹理在我的代码中称为_texture,而投影的纹理是_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.
}
问题
如果我在主程序对象之外调用updateTex(),我会看到 zero 效果,而如果我在其范围内调用它,如下所示:
glUseProgram(_id); // vert, frag shader pipe
updateTex();
// Pass uniforms to shader
// bind _textureProj & _texture (latter is the one im trying to update)
glUseProgram(0);
然后在渲染时我看到了这个:
问题: 我意识到在主程序对象范围内设置更新方法不是正确的方法,但它是获得任何视觉结果的唯一方法。在我看来,发生的事情是它几乎消除了片段着色器并绘制到屏幕空间......
我该怎么做才能让它正常工作? (我的主要重点是能够将任何东西写入纹理并更新)
如果需要发布更多代码,请告诉我。
【问题讨论】:
-
我不确定您所说的“主程序对象范围”是什么意思。
_programObject->activate();是做什么的? -
您的“主程序范围”是否在单独的线程上?当您在线程之间进行调用时,OpenGL 将无法正常/根本无法运行。
-
@GuyRT - 哦,对不起,也许我在那里用错了词。 _programObject->activate() 本质上是调用 glUseProgram(id) ,其中 id 是 GLint,我将编辑我的问题。
-
@newObjekt 它不在单独的线程上,我可能在那里使用了错误的术语,我的意思是在 glUseProgram() 中
标签: opengl glsl map-projections compute-shader