00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "nel/misc/common.h"
00029 #include "3d/motion_blur.h"
00030 #include "3d/driver.h"
00031 #include "3d/texture.h"
00032 #include "3d/texture_blank.h"
00033 #include "3d/material.h"
00034
00035
00036 namespace NL3D {
00037
00038
00039 CMotionBlur::CMotionBlur() : _Tex(NULL), _X(0), _Y(0), _W(0), _H(0)
00040 {
00041 }
00042
00043
00044
00045 void CMotionBlur::startMotionBlur(uint x, uint y, uint width, uint height)
00046 {
00047 nlassert(width > 0 && height > 0) ;
00048 _X = x ;
00049 _Y = y ;
00050 _W = width ;
00051 _H = height ;
00052 _Tex = new CTextureBlank ;
00053 _Tex->resize(NLMISC::raiseToNextPowerOf2(width), NLMISC::raiseToNextPowerOf2(height)) ;
00054 }
00055
00056 void CMotionBlur::releaseMotionBlur()
00057 {
00058 _Tex = NULL ;
00059 _X = _Y = _W = _H = 0 ;
00060 }
00061
00062 void CMotionBlur::performMotionBlur(IDriver *driver, float motionBlurAmount)
00063 {
00064 nlassert(_Tex) ;
00065 nlassert(driver) ;
00066 nlassert(motionBlurAmount >= 0.f && motionBlurAmount <= 1.f) ;
00067
00068 static CVertexBuffer vb ;
00069 vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag ) ;
00070 vb.setNumVertices(4) ;
00071
00072 uint32 width, height ;
00073 driver->getWindowSize(width, height) ;
00074
00075 float widthRatio = _W / (float) NLMISC::raiseToNextPowerOf2 (_W) ;
00076 float heightRatio = _H / (float) NLMISC::raiseToNextPowerOf2 (_H) ;
00077
00078 driver->setFrustum(0, (float) width, 0, (float) height, -1, 1, false) ;
00079
00080 for (uint sn = 0 ; sn < 2 ; ++sn)
00081 {
00082 vb.setTexCoord(0, sn, CUV(0, 0)) ;
00083 vb.setTexCoord(1, sn, CUV(widthRatio, 0)) ;
00084 vb.setTexCoord(2, sn, CUV(widthRatio, heightRatio)) ;
00085 vb.setTexCoord(3, sn, CUV(0, heightRatio)) ;
00086 }
00087
00088
00089 static CMaterial mbMat ;
00090 static bool matSetup = false ;
00091 if (!matSetup)
00092 {
00093 mbMat.setBlend(true) ;
00094 mbMat.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha) ;
00095 mbMat.setZWrite(false) ;
00096 mbMat.setZFunc(CMaterial::always) ;
00097
00098 mbMat.setTexture(0, _Tex) ;
00099 mbMat.texEnvOpRGB(0, CMaterial::Replace );
00100
00101 mbMat.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha);
00102 mbMat.texEnvOpAlpha(0, CMaterial::Replace);
00103
00104 mbMat.setDoubleSided(true) ;
00105 matSetup = true ;
00106 }
00107
00108
00109 mbMat.setColor(CRGBA(255, 255, 255, (uint8) (255.f * motionBlurAmount) ) ) ;
00110
00111
00112 vb.setVertexCoord(0, CVector((float) _X, 0, 0) ) ;
00113 vb.setVertexCoord(1, CVector((float) (_X + _W), 0 ,0) ) ;
00114 vb.setVertexCoord(2, CVector((float) (_X + _W), 0, (float) (_Y + _H) ) );
00115 vb.setVertexCoord(3, CVector(0 , 0, (float) (_Y + _H) ) ) ;
00116
00117 driver->setupViewMatrix(CMatrix::Identity) ;
00118 driver->setupModelMatrix(CMatrix::Identity) ;
00119
00120
00121 driver->activeVertexBuffer(vb) ;
00122 driver->renderQuads(mbMat, 0, 1) ;
00123
00124
00125
00126
00127
00128 driver->copyFrameBufferToTexture(_Tex, 0, 0, 0, _X, _Y, _W, _H) ;
00129
00130
00131 }
00132
00133
00134 }