Плавный переход от цветного изображения к черно-белому.
Автор: u_peter
Часто бывает нужно заменить отрендереное на экран цветное изображение на черно-белое (например, при установке игровой паузы). Мой способ выглядит так:
Автор: u_peter
Часто бывает нужно заменить отрендереное на экран цветное изображение на черно-белое (например, при установке игровой паузы). Мой способ выглядит так:
// m_iWidth & m_iHeight - текущее разрешение экрана #define m_iWidth 640 #define m_iHeight 480 // нам потребуются 2 буффера: m_pFrame = new ubyte [m_iWidth*m_iHeight*3]; m_pBuffer = new ubyte [m_iWidth*m_iHeight*3]; void ReplaceBW (float fValue) { if ( !fValue || !m_pFrame || !m_pBuffer) // если fValue == 0, значит изображение полностью цветное return; glDisable( GL_TEXTURE_2D); if ( fValue <= 1.0f) { // 1. get image from screen glFlush( ); glFinish( ); glReadPixels ( 0, 0, m_iWidth, m_iHeight, GL_RGB, GL_UNSIGNED_BYTE, m_pFrame); // 2. convert to bw int j = 0, k = int( fValue*255.0f), s = 0, r, g, b; for ( int i=0; i<m_iWidth*m_iHeight; i++) { r = m_pFrame[j]; g = m_pFrame[j+1]; b = m_pFrame[j+2]; s = ( r + 2*g + b)*k >> 2; // "реальное" соотношение 0.3*r + 0.59*g + 0.11*b, зато это намного быстрее m_pBuffer[j+0] = ( r*( 255-k) + s) >> 8; m_pBuffer[j+1] = ( g*( 255-k) + s) >> 8; m_pBuffer[j+2] = ( b*( 255-k) + s) >> 8; j += 3; } } // 3. draw to frame buffer glRasterPos2i( -m_iWidth/2, -m_iHeight/2); glDrawPixels( m_iWidth, m_iHeight, GL_RGB, GL_UNSIGNED_BYTE, m_pBuffer); }
Обратите внимание на условие
if (fValue <= 1.0f)
Оно нам нужно вот для чего:
Например у нас в программе есть обработчик паузы:
void OnPause(void) { GamePause = 1.0f; m_fPauseAlpha = 0.0f; }
Тогда отрисовка игры может выглядеть так:
if (GamePause.Float( )) { if ( m_fPauseAlpha < 1.0f) m_world->Draw ( m_dGameTime); ReplaceBW( m_fPauseAlpha); m_fPauseAlpha += m_dTime; } else m_world->Draw ( m_dGameTime);
т.е. Пока изображение не стало "окончательно черно-белым" мы перерисовываем игру, постепенно делая изображение все более черно-белым, как только оно становится "окончательно черно-белым" игровой мир больше не перерисовывается, а его изображение берется из m_pBuffer (вот поэтому нам и нужны были 2 буффера).
Конечно описанный метод не являеться самым быстрым, в разных ситуациях возможны другие решения, зато он универсален, работает на любом железе.
1 марта 2004