2017-02-11 61 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

相关问题