2012-10-08 23 views
3

我想在我的游戏中执行图像效果,例如屏幕模糊,但是我有一个问题,它只是使屏幕稍微变暗。着色器中的图像模糊效果

下面是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); 
} 

这是我的碎片着色器

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; 
} 

它工作不太好。我试着改变着色器来做别的事情,但无论如何它只是轻微地变暗。

+0

http://stackoverflow.com/questions/14107979/blur-an-image-of-specific-part-rectangular-circular/14108694#14108694 – junaidsidhu

回答

2

拆散应

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 
+0

哇,我没有看到。那么它不再是黑色了。现在我试图做一些屏幕模糊,但它没有做任何事情。我更新了这个问题。 – Jose

0

也许你还没有足够的包括代码,但我没有看到你实际渲染在Render方法什么。你有一些调用,我认为其中的第一个激活的上下文,然后你绑定帧缓冲区和链接着色器变量,但接下来我希望调用渲染四/网格(即与glBegin/glEnd部分或顶点缓冲区绑定和渲染。)

+0

我没有包括它,因为我认为它没有必要。它是我第一次,我正在做图像效果,所以我不知道如何初始化它。但在EndShaderProgram之后,我正在绘制诸如立方体和飞机之类的物体,并且他们拥有自己的着色器。所以我不确定Screen Blur是否应该与其他对象着色器一起使用,或者模糊必须位于其着色器中。我更新渲染的其余部分,以便您可以看到我在说什么。 – Jose

0

好吧,通常要做后期处理效果,你会呈现与帧缓冲区活跃的场景。然后渲染一个全屏四边形,使您的后期处理(模糊)着色器处于活动状态,并将帧缓冲区纹理绑定为取样器。

+0

感谢您的回复。我完全忘了渲染四边形。我现在把它渲染出来,但不是模糊它,而是使它变暗。我更新了我的问题。 – Jose

0

Nevenmind我现在工作。我在错误的地方给Bind和UnBind打电话。