2012-10-08 21 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打電話。