GLColorBuffer GLLensDustFilter::GaussianBlur(GLColorBuffer tex, bool vertical) { SPADES_MARK_FUNCTION(); GLProgram *program = gauss1d; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = tex.GetWidth(); int h = tex.GetHeight(); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("mainTexture"); static GLProgramUniform blur_unitShift("unitShift"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_textureUniform.SetValue(0); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture()); blur_unitShift(program); blur_unitShift.SetValue(vertical ? 0.f : 1.f / w, vertical ? 1.f / h : 0.f); qr.SetCoordAttributeIndex(blur_positionAttribute()); dev->Enable(IGLDevice::Blend, false); GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false); dev->Viewport(0, 0, buf2.GetWidth(), buf2.GetHeight()); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); qr.Draw(); return buf2; }
GLColorBuffer GLDepthOfFieldFilter::Blur(GLColorBuffer buffer, GLColorBuffer coc, Vector2 offset, int divide) { SPADES_MARK_FUNCTION(); // do gaussian blur GLProgram *program = blurProgram; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = buffer.GetWidth(); int h = buffer.GetHeight(); int w2 = w / divide; int h2 = h / divide; static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("texture"); static GLProgramUniform blur_cocUniform("cocTexture"); static GLProgramUniform blur_offset("offset"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_cocUniform(program); blur_offset(program); blur_cocUniform.SetValue(1); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, coc.GetTexture()); blur_textureUniform.SetValue(0); dev->ActiveTexture(0); qr.SetCoordAttributeIndex(blur_positionAttribute()); // x-direction float len = offset.GetLength(); float sX = 1.f / (float)w, sY = 1.f / (float)h; while(len > .5f){ GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w2, h2, false); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); dev->BindTexture(IGLDevice::Texture2D, buffer.GetTexture()); blur_offset.SetValue(offset.x * sX, offset.y * sY); qr.Draw(); buffer = buf2; offset *= .125f; len *= .125f; } return buffer; }
GLColorBuffer GLDepthOfFieldFilter::FinalMix(GLColorBuffer tex, GLColorBuffer blur1, GLColorBuffer blur2, GLColorBuffer coc) { SPADES_MARK_FUNCTION(); // do gaussian blur GLProgram *program = finalMix; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = tex.GetWidth(); int h = tex.GetHeight(); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform1("texture"); static GLProgramUniform blur_textureUniform2("blurTexture1"); static GLProgramUniform blur_textureUniform3("blurTexture2"); static GLProgramUniform blur_textureUniform4("cocTexture"); program->Use(); blur_positionAttribute(program); blur_textureUniform1(program); blur_textureUniform1.SetValue(3); dev->ActiveTexture(3); dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture()); blur_textureUniform2(program); blur_textureUniform2.SetValue(2); dev->ActiveTexture(2); dev->BindTexture(IGLDevice::Texture2D, blur1.GetTexture()); blur_textureUniform3(program); blur_textureUniform3.SetValue(1); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, blur2.GetTexture()); blur_textureUniform4(program); blur_textureUniform4.SetValue(0); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, coc.GetTexture()); qr.SetCoordAttributeIndex(blur_positionAttribute()); dev->Enable(IGLDevice::Blend, false); // x-direction GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); qr.Draw(); return buf2; }
GLColorBuffer GLLensDustFilter::DownSample(GLColorBuffer tex, bool linearize) { SPADES_MARK_FUNCTION(); GLProgram *program = thru; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = tex.GetWidth(); int h = tex.GetHeight(); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("mainTexture"); static GLProgramUniform blur_colorUniform("colorUniform"); static GLProgramUniform blur_texCoordRangeUniform("texCoordRange"); static GLProgramUniform blur_texCoordOffsetUniform("texCoordOffset"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_textureUniform.SetValue(0); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture()); blur_texCoordOffsetUniform(program); blur_texCoordOffsetUniform.SetValue(1.f / w, 1.f / h, -1.f / w, -1.f / h); blur_colorUniform(program); blur_colorUniform.SetValue(1.f,1.f,1.f,1.f); blur_texCoordRangeUniform(program); blur_texCoordRangeUniform.SetValue(0.f, 0.f, (float)((w + 1) & ~1) / w, (float)((h + 1) & ~1) / h); qr.SetCoordAttributeIndex(blur_positionAttribute()); if(linearize){ dev->Enable(IGLDevice::Blend, true); dev->BlendFunc(IGLDevice::SrcColor, IGLDevice::Zero); }else{ dev->Enable(IGLDevice::Blend, false); } GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle((w+1)/2, (h+1)/2, false); dev->Viewport(0, 0, buf2.GetWidth(), buf2.GetHeight()); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); qr.Draw(); return buf2; }
GLColorBuffer GLDepthOfFieldFilter::AddMix(GLColorBuffer buffer1, GLColorBuffer buffer2) { SPADES_MARK_FUNCTION(); // do gaussian blur GLProgram *program = gammaMix; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = buffer1.GetWidth(); int h = buffer1.GetHeight(); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform1("texture1"); static GLProgramUniform blur_textureUniform2("texture2"); static GLProgramUniform blur_unitShift("unitShift"); static GLProgramUniform blur_mix1("mix1"); static GLProgramUniform blur_mix2("mix2"); program->Use(); blur_positionAttribute(program); blur_textureUniform1(program); blur_textureUniform1.SetValue(1); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, buffer1.GetTexture()); blur_textureUniform2(program); blur_textureUniform2.SetValue(0); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, buffer2.GetTexture()); blur_mix1(program); blur_mix2(program); blur_mix1.SetValue(.5f, .5f, .5f); blur_mix2.SetValue(.5f, .5f, .5f); qr.SetCoordAttributeIndex(blur_positionAttribute()); dev->Enable(IGLDevice::Blend, false); // x-direction GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); qr.Draw(); return buf2; }
GLColorBuffer GLDepthOfFieldFilter::UnderSample(GLColorBuffer tex) { SPADES_MARK_FUNCTION(); // do gaussian blur GLProgram *program = passthrough; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); int w = tex.GetWidth(); int h = tex.GetHeight(); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("texture"); static GLProgramUniform blur_colorUniform("colorUniform"); static GLProgramUniform blur_texCoordRangeUniform("texCoordRange"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_textureUniform.SetValue(0); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture()); blur_colorUniform(program); blur_colorUniform.SetValue(1.f,1.f,1.f,1.f); blur_texCoordRangeUniform(program); blur_texCoordRangeUniform.SetValue(0.f, 0.f, 1.f, 1.f); qr.SetCoordAttributeIndex(blur_positionAttribute()); dev->Enable(IGLDevice::Blend, false); GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w/2, h/2, false); dev->Viewport(0, 0, w/2, h/2); dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); qr.Draw(); return buf2; }
GLColorBuffer GLBloomFilter::Filter(GLColorBuffer input) { SPADES_MARK_FUNCTION(); std::vector<Level> levels; IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); static GLProgramAttribute thruPosition("positionAttribute"); static GLProgramUniform thruColor("colorUniform"); static GLProgramUniform thruTexture("texture"); static GLProgramUniform thruTexCoordRange("texCoordRange"); thruPosition(thru); thruColor(thru); thruTexture(thru); thruTexCoordRange(thru); GLProgram *gammaMix = renderer->RegisterProgram("Shaders/PostFilters/GammaMix.program"); static GLProgramAttribute gammaMixPosition("positionAttribute"); static GLProgramUniform gammaMixTexture1("texture1"); static GLProgramUniform gammaMixTexture2("texture2"); static GLProgramUniform gammaMixMix1("mix1"); static GLProgramUniform gammaMixMix2("mix2"); gammaMixPosition(gammaMix); gammaMixTexture1(gammaMix); gammaMixTexture2(gammaMix); gammaMixMix1(gammaMix); gammaMixMix2(gammaMix); thru->Use(); thruColor.SetValue(1.f, 1.f, 1.f, 1.f); thruTexture.SetValue(0); dev->Enable(IGLDevice::Blend, false); // create downsample levels for(int i = 0; i < 6; i++){ GLColorBuffer prevLevel; if(i == 0){ prevLevel = input; }else{ prevLevel = levels.back().buffer; } int prevW = prevLevel.GetWidth(); int prevH = prevLevel.GetHeight(); int newW = (prevW + 1) / 2; int newH = (prevH + 1) / 2; GLColorBuffer newLevel = input.GetManager()->CreateBufferHandle(newW, newH); thru->Use(); qr.SetCoordAttributeIndex(thruPosition()); dev->BindTexture(IGLDevice::Texture2D, prevLevel.GetTexture()); dev->BindFramebuffer(IGLDevice::Framebuffer, newLevel.GetFramebuffer()); dev->Viewport(0, 0, newLevel.GetWidth(), newLevel.GetHeight()); thruTexCoordRange.SetValue(0.f, 0.f, (float)newLevel.GetWidth() * 2.f / (float)prevW, (float)newLevel.GetHeight() * 2.f / (float)prevH); qr.Draw(); dev->BindTexture(IGLDevice::Texture2D, 0); Level lv; lv.w = newW; lv.h = newH; lv.buffer = newLevel; levels.push_back(lv); } dev->Enable(IGLDevice::Blend, true); dev->BlendFunc(IGLDevice::SrcAlpha, IGLDevice::OneMinusSrcAlpha); // composite levels in the opposite direction thruTexCoordRange.SetValue(0.f, 0.f, 1.f, 1.f); for(int i = (int)levels.size() - 1; i >= 1; i--){ int cnt = (int)levels.size() - i; float alpha = (float)cnt / (float)(cnt + 1); alpha = sqrtf(alpha); GLColorBuffer curLevel = levels[i].buffer; GLColorBuffer targLevel = levels[i - 1].buffer; thru->Use(); qr.SetCoordAttributeIndex(thruPosition()); dev->BindTexture(IGLDevice::Texture2D, curLevel.GetTexture()); dev->BindFramebuffer(IGLDevice::Framebuffer, targLevel.GetFramebuffer()); dev->Viewport(0, 0, targLevel.GetWidth(), targLevel.GetHeight()); thruColor.SetValue(1.f, 1.f, 1.f, alpha); qr.Draw(); dev->BindTexture(IGLDevice::Texture2D, 0); } // composite to the final image GLColorBuffer output = input.GetManager()->CreateBufferHandle(); GLColorBuffer topLevel = levels[0].buffer; gammaMix->Use(); qr.SetCoordAttributeIndex(gammaMixPosition()); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, input.GetTexture()); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, topLevel.GetTexture()); dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer()); dev->Viewport(0, 0, output.GetWidth(), output.GetHeight()); gammaMixTexture1.SetValue(0); gammaMixTexture2.SetValue(1); gammaMixMix1.SetValue(.8f, .8f, .8f); gammaMixMix2.SetValue(.2f, .2f, .2f); qr.Draw(); dev->BindTexture(IGLDevice::Texture2D, 0); dev->ActiveTexture(0); return output; }
GLColorBuffer GLFogFilter::Filter(GLColorBuffer input) { SPADES_MARK_FUNCTION(); IGLDevice *dev = renderer->GetGLDevice(); GLQuadRenderer qr(dev); GLProgram *lens = renderer->RegisterProgram("Shaders/PostFilters/Fog.program"); static GLProgramAttribute lensPosition("positionAttribute"); static GLProgramUniform lensShadowMapTexture("shadowMapTexture"); static GLProgramUniform lensCoarseShadowMapTexture("coarseShadowMapTexture"); static GLProgramUniform lensColorTexture("colorTexture"); static GLProgramUniform lensDepthTexture("depthTexture"); static GLProgramUniform lensFov("fov"); static GLProgramUniform lensViewOrigin("viewOrigin"); static GLProgramUniform lensViewAxisUp("viewAxisUp"); static GLProgramUniform lensViewAxisSide("viewAxisSide"); static GLProgramUniform lensViewAxisFront("viewAxisFront"); static GLProgramUniform zNearFar("zNearFar");; static GLProgramUniform fogColor("fogColor"); static GLProgramUniform fogDistance("fogDistance"); dev->Enable(IGLDevice::Blend, false); lensPosition(lens); lensShadowMapTexture(lens); lensCoarseShadowMapTexture(lens); lensColorTexture(lens); lensDepthTexture(lens); lensFov(lens); lensViewOrigin(lens); lensViewAxisUp(lens); lensViewAxisSide(lens); lensViewAxisFront(lens); zNearFar(lens); fogColor(lens); fogDistance(lens); lens->Use(); client::SceneDefinition def = renderer->GetSceneDef(); lensFov.SetValue(tanf(def.fovX * .5f), tanf(def.fovY * .5f)); lensViewOrigin.SetValue(def.viewOrigin.x, def.viewOrigin.y, def.viewOrigin.z); lensViewAxisUp.SetValue(def.viewAxis[1].x, def.viewAxis[1].y, def.viewAxis[1].z); lensViewAxisSide.SetValue(def.viewAxis[0].x, def.viewAxis[0].y, def.viewAxis[0].z); lensViewAxisFront.SetValue(def.viewAxis[2].x, def.viewAxis[2].y, def.viewAxis[2].z); zNearFar.SetValue(def.zNear, def.zFar); Vector3 fogCol = renderer->GetFogColor(); fogCol *= fogCol; // linearize fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z); fogDistance.SetValue(128.f); lensColorTexture.SetValue(0); lensDepthTexture.SetValue(1); lensShadowMapTexture.SetValue(2); lensCoarseShadowMapTexture.SetValue(3); // composite to the final image GLColorBuffer output = input.GetManager()->CreateBufferHandle(); dev->Enable(IGLDevice::Blend, false); qr.SetCoordAttributeIndex(lensPosition()); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, input.GetTexture()); dev->ActiveTexture(1); dev->BindTexture(IGLDevice::Texture2D, input.GetManager()->GetDepthTexture()); dev->ActiveTexture(2); dev->BindTexture(IGLDevice::Texture2D, renderer->GetMapShadowRenderer()->GetTexture()); dev->ActiveTexture(3); dev->BindTexture(IGLDevice::Texture2D, renderer->GetMapShadowRenderer()->GetCoarseTexture()); dev->BindFramebuffer(IGLDevice::Framebuffer, output.GetFramebuffer()); dev->Viewport(0, 0, output.GetWidth(), output.GetHeight()); qr.Draw(); dev->ActiveTexture(0); dev->BindTexture(IGLDevice::Texture2D, 0); return output; }
void GLSoftSpriteRenderer::Render() { SPADES_MARK_FUNCTION(); lastImage = NULL; program->Use(); device->Enable(IGLDevice::Blend, true); device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha); projectionViewMatrix(program); rightVector(program); frontVector(program); viewOriginVector(program); upVector(program); texture(program); depthTexture(program); viewMatrix(program); fogDistance(program); fogColor(program); zNearFar(program); positionAttribute(program); spritePosAttribute(program); colorAttribute(program); projectionViewMatrix.SetValue(renderer->GetProjectionViewMatrix()); viewMatrix.SetValue(renderer->GetViewMatrix()); fogDistance.SetValue(renderer->GetFogDistance()); Vector3 fogCol = renderer->GetFogColor(); fogCol *= fogCol; // linearize fogColor.SetValue(fogCol.x, fogCol.y, fogCol.z); const client::SceneDefinition &def = renderer->GetSceneDef(); rightVector.SetValue(def.viewAxis[0].x, def.viewAxis[0].y, def.viewAxis[0].z); upVector.SetValue(def.viewAxis[1].x, def.viewAxis[1].y, def.viewAxis[1].z); frontVector.SetValue(def.viewAxis[2].x, def.viewAxis[2].y, def.viewAxis[2].z); viewOriginVector.SetValue(def.viewOrigin.x, def.viewOrigin.y, def.viewOrigin.z); texture.SetValue(0); depthTexture.SetValue(1); zNearFar.SetValue(def.zNear, def.zFar); device->ActiveTexture(1); device->BindTexture(IGLDevice::Texture2D, renderer->GetFramebufferManager()->GetDepthTexture()); device->ActiveTexture(0); device->EnableVertexAttribArray(positionAttribute(), true); device->EnableVertexAttribArray(spritePosAttribute(), true); device->EnableVertexAttribArray(colorAttribute(), true); thresLow = tanf(def.fovX * .5f) * tanf(def.fovY * .5f) * 1.8f; thresRange = thresLow * .5f; // full-resolution sprites { GLProfiler::Context measure(renderer->GetGLProfiler(), "Full Resolution"); for (size_t i = 0; i < sprites.size(); i++) { Sprite &spr = sprites[i]; float layer = LayerForSprite(spr); if (layer == 1.f) continue; if (spr.image != lastImage) { Flush(); lastImage = spr.image; SPAssert(vertices.empty()); } Vertex v; v.x = spr.center.x; v.y = spr.center.y; v.z = spr.center.z; v.radius = spr.radius; v.angle = spr.angle; v.r = spr.color.x; v.g = spr.color.y; v.b = spr.color.z; v.a = spr.color.w; float fade = 1.f - layer; v.r *= fade; v.g *= fade; v.b *= fade; v.a *= fade; uint32_t idx = (uint32_t)vertices.size(); v.sx = -1; v.sy = -1; vertices.push_back(v); v.sx = 1; v.sy = -1; vertices.push_back(v); v.sx = -1; v.sy = 1; vertices.push_back(v); v.sx = 1; v.sy = 1; vertices.push_back(v); indices.push_back(idx); indices.push_back(idx + 1); indices.push_back(idx + 2); indices.push_back(idx + 1); indices.push_back(idx + 3); indices.push_back(idx + 2); } Flush(); } // low-res sprites IGLDevice::UInteger lastFb = device->GetInteger(IGLDevice::FramebufferBinding); int sW = device->ScreenWidth(), sH = device->ScreenHeight(); int lW = (sW + 3) / 4, lH = (sH + 3) / 4; int numLowResSprites = 0; GLColorBuffer buf = renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true); device->BindFramebuffer(IGLDevice::Framebuffer, buf.GetFramebuffer()); device->ClearColor(0.f, 0.f, 0.f, 0.f); device->Clear(IGLDevice::ColorBufferBit); device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha); device->Viewport(0, 0, lW, lH); { GLProfiler::Context measure(renderer->GetGLProfiler(), "Low Resolution"); for (size_t i = 0; i < sprites.size(); i++) { Sprite &spr = sprites[i]; float layer = LayerForSprite(spr); if (layer == 0.f) continue; if (spr.image != lastImage) { Flush(); lastImage = spr.image; SPAssert(vertices.empty()); } numLowResSprites++; Vertex v; v.x = spr.center.x; v.y = spr.center.y; v.z = spr.center.z; v.radius = spr.radius; v.angle = spr.angle; v.r = spr.color.x; v.g = spr.color.y; v.b = spr.color.z; v.a = spr.color.w; float fade = layer; v.r *= fade; v.g *= fade; v.b *= fade; v.a *= fade; uint32_t idx = (uint32_t)vertices.size(); v.sx = -1; v.sy = -1; vertices.push_back(v); v.sx = 1; v.sy = -1; vertices.push_back(v); v.sx = -1; v.sy = 1; vertices.push_back(v); v.sx = 1; v.sy = 1; vertices.push_back(v); indices.push_back(idx); indices.push_back(idx + 1); indices.push_back(idx + 2); indices.push_back(idx + 1); indices.push_back(idx + 3); indices.push_back(idx + 2); } Flush(); } // finalize device->ActiveTexture(1); device->BindTexture(IGLDevice::Texture2D, 0); device->ActiveTexture(0); device->BindTexture(IGLDevice::Texture2D, 0); device->EnableVertexAttribArray(positionAttribute(), false); device->EnableVertexAttribArray(spritePosAttribute(), false); device->EnableVertexAttribArray(colorAttribute(), false); // composite downsampled sprite device->BlendFunc(IGLDevice::One, IGLDevice::OneMinusSrcAlpha); if (numLowResSprites > 0) { GLProfiler::Context measure(renderer->GetGLProfiler(), "Finalize"); GLQuadRenderer qr(device); // do gaussian blur GLProgram *program = renderer->RegisterProgram("Shaders/PostFilters/Gauss1D.program"); static GLProgramAttribute blur_positionAttribute("positionAttribute"); static GLProgramUniform blur_textureUniform("mainTexture"); static GLProgramUniform blur_unitShift("unitShift"); program->Use(); blur_positionAttribute(program); blur_textureUniform(program); blur_unitShift(program); blur_textureUniform.SetValue(0); device->ActiveTexture(0); qr.SetCoordAttributeIndex(blur_positionAttribute()); device->Enable(IGLDevice::Blend, false); // x-direction GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true); device->BindTexture(IGLDevice::Texture2D, buf.GetTexture()); device->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer()); blur_unitShift.SetValue(1.f / lW, 0.f); qr.Draw(); buf.Release(); // x-direction GLColorBuffer buf3 = renderer->GetFramebufferManager()->CreateBufferHandle(lW, lH, true); device->BindTexture(IGLDevice::Texture2D, buf2.GetTexture()); device->BindFramebuffer(IGLDevice::Framebuffer, buf3.GetFramebuffer()); blur_unitShift.SetValue(0.f, 1.f / lH); qr.Draw(); buf2.Release(); buf = buf3; device->Enable(IGLDevice::Blend, true); // composite program = renderer->RegisterProgram("Shaders/PostFilters/PassThrough.program"); static GLProgramAttribute positionAttribute("positionAttribute"); static GLProgramUniform colorUniform("colorUniform"); static GLProgramUniform textureUniform("mainTexture"); static GLProgramUniform texCoordRange("texCoordRange"); positionAttribute(program); textureUniform(program); texCoordRange(program); colorUniform(program); program->Use(); textureUniform.SetValue(0); texCoordRange.SetValue(0.f, 0.f, 1.f, 1.f); colorUniform.SetValue(1.f, 1.f, 1.f, 1.f); qr.SetCoordAttributeIndex(positionAttribute()); device->BindFramebuffer(IGLDevice::Framebuffer, lastFb); device->BindTexture(IGLDevice::Texture2D, buf.GetTexture()); device->Viewport(0, 0, sW, sH); qr.Draw(); device->BindTexture(IGLDevice::Texture2D, 0); } else { device->Viewport(0, 0, sW, sH); device->BindFramebuffer(IGLDevice::Framebuffer, lastFb); } buf.Release(); }