2017-04-13 65 views
1

我目前正在使用OpenGl中的計算着色器,我的目標是從一個紋理渲染到另一個紋理上進行一些修改。但是,它似乎並不像我的計算着色器對紋理有任何影響。OpenGL Compute Shader - glDispatchCompue()不運行

創建計算着色器後,我做了以下

//Use the compute shader program 
(*shaderPtr).useProgram(); 

//Get the uniform location for a uniform called "sourceTex" 
//Then connect it to texture-unit 0 
GLuint location = glGetUniformLocation((*shaderPtr).program, "sourceTex"); 
glUniform1i(location, 0); 

//Bind buffers and call compute shader 
this->bindAndCompute(bufferA, bufferB); 

bindAndCompute()功能看起來是這樣的,其目的是準備通過計算着色器進行訪問,然後運行兩個緩衝器計算着色器。

bindAndCompute(GLuint sourceBuffer, GLuint targetBuffer){ 
    glBindImageTexture(
    0,       //Always bind to slot 0 
    sourceBuffer, 
    0, 
    GL_FALSE, 
    0, 
    GL_READ_ONLY,    //Only read from this texture 
    GL_RGB16F 
); 

    glBindImageTexture(
    1,       //Always bind to slot 1 
    targetBuffer, 
    0, 
    GL_FALSE, 
    0, 
    GL_WRITE_ONLY,    //Only write to this texture 
    GL_RGB16F 
); 

    //this->height is currently 960 
    glDispatchCompute(1, this->height, 1);   //Call upon shader 

    glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 
} 

最後,這裏是計算着色器。我目前只嘗試設置它,使它使第二個紋理完全變白。

#version 440 
#extension GL_ARB_compute_shader : enable 
#extension GL_ARB_shader_image_load_store : enable 

layout (rgba16, binding=0) uniform image2D sourceTex;   //Textures bound to 0 and 1 resp. that are used to 
layout (rgba16, binding=1) uniform image2D targetTex;   //acquire texture and save changes made to texture 

layout (local_size_x=960 , local_size_y=1 , local_size_z=1) in;  //Local work-group size 

void main(){ 

    vec4 result;  //Vec4 to store the value to be written 

    pxlPos = ivec2(gl_GlobalInvocationID.xy);  //Get pxl-pos 

    /* 
    result = imageLoad(sourceTex, pxlPos); 

    ... 
    */ 

    imageStore(targetTex, pxlPos, vec4(1.0f)); //Write white to texture 
} 

現在,當我開始bufferB是空的。當我運行這個時,我期望bufferB變成完全白色。但是,此代碼緩衝區B保持爲空。我的結論是:要麼

答:計算着色器不寫入紋理

B:glDispatchCompute()不會運行在所有

但是,我沒有得到任何錯誤着色器會按照它應該進行編譯。我已經檢查過綁定紋理時正確綁定bufferA其中我已經知道它包含了什麼,然後運行bindAndCompute(bufferA,bufferA)來打開bufferA白色。但是,緩衝區A未變。所以,我一直無法弄清楚爲什麼我的計算着色器沒有效果。如果任何人有什麼我可以嘗試做的想法,將不勝感激。

結束語:這是我在這個網站上詢問的第一個問題。我試圖僅提供相關信息,但我仍然覺得它可能變得太多文字了。如果有關於如何改進這個問題的結構的反饋也是受歡迎的。

--------------------------------------------- ------------------------

編輯:

sourceBuffertargetBuffer發送中的紋理定義如下:

glGenTextures(1, *buffer); 
glBindTexture(GL_TEXTURE_2D, *buffer); 
glTexImage2D(
    GL_TEXTURE_2D, 
    0, 
    GL_RGBA16F,  //Internal format 
    this->width, 
    this->height, 
    0, 
    GL_RGBA,  //Format read 
    GL_FLOAT,  //Type of values in read format 
    NULL   //source 
); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
+0

您可以添加如何定義/初始化'sourceBuffer'和'targetBuffer'嗎? – BDL

回答

0

ima的圖像格式您綁定的ges不匹配着色器中的圖像格式。您綁定了一個RGB16F(每字符48byte)紋理,但在着色器中聲明它的格式爲rgba16(每字符64byte)。

格式必須符合here的規則。假設您在OpenGL中分配了紋理,這意味着每個紋理元素的總大小必須匹配。另請注意,3通道紋理(沒有一些奇怪的例外)不受圖像加載/存儲的支持。

作爲旁註:如果紋理格式大小匹配,則着色器將執行並寫入。但是,當您告訴着色器它們處於16位無符號標準化格式(rgba16)時,您寫入的內容可能是垃圾,因爲您的紋理採用16位浮點格式(RGBA_16F)。儘管這對於計算着色器來說並不重要,但如果您回讀紋理或通過採樣器訪問紋理或將數據>寫入數據> 1.0f或< 0.0f,則無關緊要。如果您需要16位浮點數,請在計算着色器中使用rgba16f

+0

所以,當你指出圖像格式不一致時,我查看了一下(例如注意到我有RGB16F而不是RGBA16F),現在我正在嘗試清理並使用相同的格式。所以,如果我理解它是正確的,如果我的* sourceBuffer *具有特定的格式,我將希望* targetBuffer *具有相同的格式,並且我對它們執行的所有操作都應該使用這些格式,而不是其他格式。我目前的問題是我是混合格式。我在想這是對的嗎? – Hoxbot

+0

好的,我檢查過了。我從另一個函數接收的紋理格式也不一致。現在,我使用相同的格式,我得到了一個輸出。感謝您的建議。 – Hoxbot