//******************************************************************************* void CWaterEnvMap::update(TGlobalAnimationTime time, IDriver &driver) { if (_LastRenderTime == time) return; _LastRenderTime = time; // First five updates are used to render the cubemap faces (bottom face is not rendered) // Sixth update project the cubemap into a 2D texture uint numTexToRender; if (_UpdateTime > 0) { uint64 currRenderTick = (uint64) (time / (_UpdateTime / (NUM_FACES_TO_RENDER + 1))); numTexToRender = (uint) (currRenderTick - _LastRenderTick); _LastRenderTick = currRenderTick; } else { numTexToRender = NUM_FACES_TO_RENDER + 1; } if (!numTexToRender) return; if (_NumRenderedFaces == 0) { _StartRenderTime = time; } uint lastCubeFacesToRender = std::min((uint) NUM_FACES_TO_RENDER, _NumRenderedFaces + numTexToRender); // we don't render negative Z (only top hemisphere is used) for(uint k = _NumRenderedFaces; k < lastCubeFacesToRender; ++k) { driver.setRenderTarget(_EnvCubic, 0, 0, _EnvCubicSize, _EnvCubicSize, 0, (uint32) k); render((CTextureCube::TFace) k, _StartRenderTime); } _NumRenderedFaces = lastCubeFacesToRender; if (_NumRenderedFaces == NUM_FACES_TO_RENDER && (_NumRenderedFaces + numTexToRender) > NUM_FACES_TO_RENDER) { // render to 2D map driver.setRenderTarget(_Env2D, 0, 0, _Env2DSize, _Env2DSize); doInit(); // driver.activeVertexProgram(NULL); driver.activeVertexBuffer(_FlattenVB); driver.activeIndexBuffer(_FlattenIB); driver.setFrustum(-1.f, 1.f, -1.f, 1.f, 0.f, 1.f, false); driver.setupViewMatrix(CMatrix::Identity); CMatrix mat; //mat.scale(0.8f); driver.setupModelMatrix(mat); _MaterialPassThru.setTexture(0, _EnvCubic); _MaterialPassThru.texConstantColor(0, CRGBA(255, 255, 255, _Alpha)); driver.renderTriangles(_MaterialPassThru, 0, FVB_NUM_TRIS); _NumRenderedFaces = 0; // start to render again } driver.setRenderTarget(NULL); }
void CFXAA::applyEffect() { if (!m_PP) return; CDriverUser *dru = static_cast<CDriverUser *>(m_Driver); IDriver *drv = dru->getDriver(); // backup bool fogEnabled = m_Driver->fogEnabled(); m_Driver->enableFog(false); NL3D::ITexture *renderTarget = drv->getRenderTarget(); nlassert(renderTarget); nlassert(renderTarget->isBloomTexture()); uint width = renderTarget->getWidth(); uint height = renderTarget->getHeight(); bool mode2D = static_cast<CTextureBloom *>(renderTarget)->isMode2D(); nlassert(renderTarget->getUploadFormat() == ITexture::Auto); float fwidth = (float)width; float fheight = (float)height; float pwidth = 1.0f / fwidth; float pheight = 1.0f / fheight; float hpwidth = pwidth * 0.5f; float hpheight = pheight * 0.5f; float n = 0.5f; //if (width != m_Width || height != m_Height) /*{ // Build VB m_Width = width; m_Height = height; CVertexBufferReadWrite vba; m_VB.lock(vba); vba.setValueFloat3Ex(CVertexBuffer::Position, 0, 0.f, 0.f, 0.5f); // BL vba.setValueFloat3Ex(CVertexBuffer::Position, 1, 1.f, 0.f, 0.5f); // BR vba.setValueFloat3Ex(CVertexBuffer::Position, 2, 1.f, 1.f, 0.5f); // TR vba.setValueFloat3Ex(CVertexBuffer::Position, 3, 0.f, 1.f, 0.5f); // TL vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 0, 0.f, 0.f); vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 1, 1.f, 0.f); vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 2, 1.f, 1.f); vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 3, 0.f, 1.f); vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 0, 0.f - hpwidth, 0.f - hpheight, 0.f + hpwidth, 0.f + hpheight); vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 1, 1.f - hpwidth, 0.f - hpheight, 1.f + hpwidth, 0.f + hpheight); vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 2, 1.f - hpwidth, 1.f - hpheight, 1.f + hpwidth, 1.f + hpheight); vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 3, 0.f - hpwidth, 1.f - hpheight, 0.f + hpwidth, 1.f + hpheight); }*/ // create render target CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D); // swap render target CTextureUser texNull; dru->setRenderTarget(texNull); drv->swapTextureHandle(*renderTarget, *otherRenderTarget->getITexture()); drv->setRenderTarget(renderTarget); m_Driver->setMatrixMode2D11(); // debug // m_Driver->clearBuffers(CRGBA(128, 128, 128, 128)); // activate program bool vpok = drv->activeVertexProgram(m_VP); nlassert(vpok); bool ppok = drv->activePixelProgram(m_PP); nlassert(ppok); /*drv->setUniform4f(IDriver::PixelProgram, 0, -n / fwidth, -n / fheight, n / fwidth, n / fheight); // fxaaConsoleRcpFrameOpt drv->setUniform4f(IDriver::PixelProgram, 1, -2.0f / fwidth, -2.0f / fheight, 2.0f / fwidth, 2.0f / fheight); // fxaaConsoleRcpFrameOpt2*/ drv->setUniform2f(IDriver::PixelProgram, 0, 1.0f / fwidth, 1.0f / fheight); // fxaaQualityRcpFrame drv->setUniform1f(IDriver::PixelProgram, 1, 0.75f); // fxaaQualitySubpix drv->setUniform1f(IDriver::PixelProgram, 2, 0.166f); // fxaaQualityEdgeThreshold drv->setUniform1f(IDriver::PixelProgram, 3, 0.0833f); // fxaaQualityEdgeThresholdMin drv->setUniformMatrix(IDriver::VertexProgram, 0, IDriver::ModelViewProjection, IDriver::Identity); // drv->setUniform4f(IDriver::VertexProgram, 9, -hpwidth, -hpheight, hpwidth, hpheight); // render effect m_Mat.getObjectPtr()->setTexture(0, otherRenderTarget->getITexture()); /*drv->activeVertexBuffer(m_VB); drv->renderRawQuads(*m_Mat.getObjectPtr(), 0, 1);*/ m_Driver->drawQuad(m_QuadUV, m_Mat); m_Mat.getObjectPtr()->setTexture(0, NULL); // deactivate program drv->activeVertexProgram(NULL); drv->activePixelProgram(NULL); // restore m_Driver->enableFog(fogEnabled); // recycle render target m_Driver->getRenderTargetManager().recycleRenderTarget(otherRenderTarget); }