2017-02-11 95 views
2

請考慮以下問題。
你有一個簡單的盒子,裏面顯示的圖像。
你也有兩個紋理,紅色的一個,和綠色的...
您從綠色質地初始化使用texure ...
你的窗口中首先顯示您不變的紋理:
如何在片段着色器中存儲紋理

enter image description here

陰影圓圈圍繞着鼠標顯示紋理的一部分。
當你按下你的鼠標按鈕,下面顯示的陰影區域變爲紅色的質感,
爲:
enter image description here

到目前爲止好。然而,我搜索了不少,但我不能
找到一種方法來存儲從片段着色器的結果
顯示,使用的紋理。總的操作將總結爲形成
第一和第二紋理的混合。

這裏是我的相關片段着色器:

#version 120 
uniform sampler2D red_texture, used_texture; 
uniform bool isMouseClicked; 
uniform float mousex, mousey; 
uniform float radius; //the radius of the painting circle 

void shadePixel(){ ... } 

void main(){ 
    //calculate the distance from mouse origin 
    float distance = sqrt(pow((gl_FragCoord.x - mousex), 2) + pow((gl_FragCoord.y - mousey), 2)); 

    if(distance<=radius && isMouseClicked){ 
    //used_texture <- red_tuxture 
    } 

    if(distance<=radius) shadePixel(); //make circle bound visible 
    else gl_FragColor = texture2D(used_texture, gl_TexCoord[0].xy); 
} 


我想以後檢索的紋理RAM和保存到磁盤的圖像。
那麼,有沒有辦法通過片段着色器來操縱紋理?
預先感謝您。

回答

1

你可以做一個「渲染紋理」。

  1. 圖像渲染到紋理
  2. 節省該紋理磁盤
  3. 顯示在窗口中。

這是如何準備的紋理的實施例被呈現:

// create a texture "_textureId" 
glGenTextures(1, &_textureId); 
glBindTexture(TEXTURE_TARGET, _textureId); 
glTexParameteri(TEXTURE_TARGET, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(TEXTURE_TARGET, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(TEXTURE_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(TEXTURE_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexImage2D(TEXTURE_TARGET, 0, YOUR_INTERNAL_FORMAT, width, height, 0, YOUR_FORMAT, GL_UNSIGNED_BYTE, 0); 

// create the framebuffer "_frameBuffer" and associate to the texture above 
glGenFramebuffers(1, &_frameBuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); 
glBindTexture(TEXTURE_TARGET, _textureId); 
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _textureId, 0); 
GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; 
glDrawBuffers(1, drawBuffers); 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
    // error... 
} 

以上基本上創建一對紋理+幀緩衝器的,所以可以呈現到紋理如果渲染到的代碼幀緩衝區關聯。爲了做到這一點,你可以做這樣的事情:

// do your normal render here... is goes to the image 
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); 

// render whatever you want... glViewPort, glClear, glDrawArrays, etc... 
// ... 

// Switch back to the "default framebuffer" 0... it means, your window. 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

此時,您可以再次,使紋理_textureId的窗口,如你所願......和可選紋理數據下載到GPU。 ..這可以用的東西就像這樣:

glBindTexture(TEXTURE_TARGET, _textureId); 
glGetTexImage(TEXTURE_TARGET, 0, YOUR_FORMAT, GL_UNSIGNED_BYTE, _data); 

哪裏_data是尺寸足夠讓你保持你的位圖緩存。

+0

謝謝,但我希望通過着色器來做到這一點。你知道這是否有可能嗎? –

+0

@FrustratedSoul:你可以在新的硬件上使用計算着色器和'imageStore'。但是我沒有理由不像瓦格納所描述的那樣不使用通過渲染到紋理進行混合的硬件。 – ybungalobill

+0

「,但我希望通過着色器做到這一點:」嗯,你使用片段着色器計算你的圖像(或任何你想要計算的)並將其輸出到紋理,我不明白爲什麼你不好用這個解決方案 – Zouch

相關問題