Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 着色器中的图像模糊效果_C++_Opengl_Glsl_Blur_Post Processing - Fatal编程技术网

C++ 着色器中的图像模糊效果

C++ 着色器中的图像模糊效果,c++,opengl,glsl,blur,post-processing,C++,Opengl,Glsl,Blur,Post Processing,我想在我的游戏中做一些图像效果,比如屏幕模糊,但我有一个问题,它只是使屏幕稍微变暗 这是FBO的课程 GLuint m_fbo; GLuint m_fboTexture; GLuint m_fboDepthBuffer; void FBO::Initialize(float width, float height) { glGenFramebuffersEXT(1, &m_fbo); glGenTextures(1, &m_fboTexture); gl

我想在我的游戏中做一些图像效果,比如屏幕模糊,但我有一个问题,它只是使屏幕稍微变暗

这是FBO的课程

GLuint m_fbo;
GLuint m_fboTexture;
GLuint m_fboDepthBuffer;

void FBO::Initialize(float width, float height)
{
    glGenFramebuffersEXT(1, &m_fbo);
    glGenTextures(1, &m_fboTexture);
    glGenRenderbuffersEXT(1, &m_fboDepthBuffer);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_fboTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glGenerateMipmapEXT(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLuint)width, (GLuint)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_fboDepthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, (GLuint)width, (GLuint)height);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_fboDepthBuffer);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    glDisable(GL_TEXTURE_2D);
}

void FBO::Bind()
{
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
}

void FBO::UnBind()
{
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

void FBO::Clear()
{
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
这就是我在主课上设置它的方式

FBO m_fbo;//create an object

//initialize size
m_fbo.Initiliazie(screen_width, screen_height);
在我的渲染函数中,我这样做

void Render()
{
   SetShaderProgram();//start shader program

   m_fbo.Bind();

   SetShaderImageSampler("texture", 0, m_fbo.m_fboTexture);
   SetShaderUniformVec2("size", (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT);
   SetShaderUniformInt("kernel_size", ksize);

   //draws my texture
   m_spriteBatch->Draw(RecTangle(0, 0, (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT));

   m_fbo.UnBind();

   EndShaderProgram();//end shader program
}
这就是SetShaderImageSampler函数的作用:

void SetShaderImageSampler(char *sSamplerName, U32 nSlot, GLuint nHandle)
{
    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0 + nSlot);
    glBindTexture(GL_TEXTURE_2D, nHandle);
    U32 nSamplerLoc = glGetUniformLocation(m_shaderProgram, sSamplerName);
    glUniform1iARB(nSamplerLoc, nSlot);
}
这是我的spritebatch抽签

void SpriteBatch::Draw(RecTangle rect)
{
    //draws it depending on its center
    float left = -(rect.right/2.0f);
    float right = left + (rect.right);
    float top = -(rect.bottom/2.0f);
    float bottom = top + (rect.bottom);

    //vertices: Vertex(x, y, z, u, v) coordinates
    m_vertex[0] = Vertex(left,  top,    0, 0, 0);
    m_vertex[1] = Vertex(right, top,    0, 1, 0);
    m_vertex[2] = Vertex(right, bottom, 0, 1, 1);
    m_vertex[3] = Vertex(left,  bottom, 0, 0, 1);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &m_vertex[0].m_fX);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &m_vertex[0].m_fU);

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
}
这是我的frag着色器

uniform sampler2D texture;
uniform vec2 size;
uniform int kernel_size;

void main (void)  
{ 
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    vec2 st = gl_TexCoord[0].st;
    vec2 texel = 1.0/size;

    int sum = 0;
    for(int i=-kernel_size; i <= kernel_size; i++) 
    {
            vec4 value = texture2D(texture, st + vec2(0.0, texel.y * i));
            int factor = kernel_size+1 - abs((float)i);
            color += value * factor;
            sum += factor;
    }
    color /= sum;

    gl_FragColor = color;
    gl_FragColor.a = 1.0;
}
均匀二维纹理;
均匀的vec2大小;
统一的int核大小;
真空总管(真空)
{ 
vec4颜色=vec4(0.0,0.0,0.0,1.0);
vec2 st=gl_TexCoord[0]。st;
vec2 texel=1.0/尺寸;
整数和=0;
对于(inti=-kernel_size;i而言,取消绑定应该是

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

可能您没有包含足够的代码,但我没有看到您在渲染方法中实际渲染任何内容


您有一些调用,我假设第一个是激活上下文,然后绑定帧缓冲区并链接着色器变量,但接下来我希望调用以某种方式渲染四边形/网格(即使用glBegin/glEnd部分或顶点缓冲区绑定和渲染)

好的,通常要进行后期处理效果,您需要在帧缓冲区处于活动状态的情况下渲染场景。然后使用后期处理(模糊)渲染全屏四边形着色器处于活动状态,帧缓冲区纹理绑定为采样器。

不介意我现在让它工作。我在错误的位置调用了绑定和取消绑定。

哇,我没有看到。它不再是黑色了。现在我尝试做一些屏幕模糊,但它什么都没做。我更新了问题。我没有包括它,因为我认为它不必要ssary。这是我第一次做图像效果,所以我不知道如何初始化它。但在EndShader程序之后,我正在为地板绘制一个立方体和一个平面等对象,它们有自己的着色器。因此我不确定屏幕模糊是否应该与其他对象着色器一起使用,或者模糊必须在它们自己的着色器中使用着色器。我将更新渲染的其余部分,以便您可以看到我正在谈论的内容。谢谢您的回答。我完全忘记渲染四边形。我现在渲染了四边形,但它没有使其模糊,而是使其变暗。我已更新了我的问题。