如何在片段着色器

时间:2017-02-11 04:15:19

标签: opengl fragment glsl shader

请考虑以下问题。
你有一个简单的盒子,里面有一个图像。
你还有两个纹理,一个是红色,另一个是绿色...... 您从绿色纹理初始化您使用过的纹理...
您的窗口首先显示未更改的已使用纹理:

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 个答案:

答案 0 :(得分:1)

你可以做一个“渲染到纹理”。

  1. 将图像渲染为纹理
  2. 将此纹理保存到磁盘
  3. 显示在窗口中。
  4. 这是关于如何准备要渲染的纹理的示例:

    <%= |rate-32.5  |=%> 
    

    上面的代码基本上创建了一对纹理+帧缓冲,因此如果渲染到相关的帧缓冲区,则可以渲染到纹理。为此,你可以这样做:

    // 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); 渲染到窗口,如你所愿...并选择将纹理数据下载到GPU ......这可以通过以下方式完成:< / p>

    _textureId

    glBindTexture(TEXTURE_TARGET, _textureId); glGetTexImage(TEXTURE_TARGET, 0, YOUR_FORMAT, GL_UNSIGNED_BYTE, _data); 是一个缓冲区,其大小足以让您保留位图。