| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104 |
- #include "core/Background2D.h"
- #include <OgreHardwareBufferManager.h>
- #include <OgreLogManager.h>
- #include <OgreMaterialManager.h>
- #include <OgreException.h>
- #include "core/CameraManager.h"
- #include "core/ConfigVar.h"
- #include "core/DebugDraw.h"
- #include "core/Logger.h"
- #include "core/Timer.h"
- //------------------------------------------------------------------------------
- ConfigVar cv_debug_background2d( "debug_background2d", "Draw background debug info", "false" );
- ConfigVar cv_show_background2d( "show_background2d", "Draw background", "true" );
- ConfigVar cv_background2d_manual( "background2d_manual", "Manual scrolling for 2d background", "false" );
- //------------------------------------------------------------------------------
- Background2D::Background2D():
- m_AlphaMaxVertexCount( 0 ),
- m_AddMaxVertexCount( 0 ),
- m_SubtractMaxVertexCount( 0 ),
- m_MultiplyMaxVertexCount( 0 ),
- m_ScrollEntity( NULL ),
- m_ScrollPositionStart( Ogre::Vector2::ZERO ),
- m_ScrollPositionEnd( Ogre::Vector2::ZERO ),
- m_ScrollType( Background2D::NONE ),
- m_ScrollSeconds( 0 ),
- m_ScrollCurrentSeconds( 0 ),
- m_Position( Ogre::Vector2::ZERO ),
- m_PositionReal( Ogre::Vector2::ZERO )
- ,m_range( Ogre::AxisAlignedBox::BOX_INFINITE )
- // for ffvii
- ,m_virtual_screen_size( 320, 240 )
- {
- m_SceneManager = Ogre::Root::getSingleton().getSceneManager( "Scene" );
- m_RenderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
- CreateVertexBuffers();
- m_AlphaMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DAlpha", "General" );
- Ogre::Pass* pass = m_AlphaMaterial->getTechnique( 0 )->getPass( 0 );
- pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
- pass->setCullingMode( Ogre::CULL_NONE );
- pass->setDepthCheckEnabled( true );
- pass->setDepthWriteEnabled( true );
- pass->setLightingEnabled( false );
- pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
- pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
- pass->setAlphaRejectValue( 0 );
- Ogre::TextureUnitState* tex = pass->createTextureUnitState();
- tex->setTextureName( "system/blank.png" );
- tex->setNumMipmaps( -1 );
- tex->setTextureFiltering( Ogre::TFO_NONE );
- m_AddMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DAdd", "General" );
- pass = m_AddMaterial->getTechnique( 0 )->getPass( 0 );
- pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
- pass->setCullingMode( Ogre::CULL_NONE );
- pass->setDepthCheckEnabled( true );
- pass->setDepthWriteEnabled( true );
- pass->setLightingEnabled( false );
- pass->setSceneBlending( Ogre::SBT_ADD );
- pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
- pass->setAlphaRejectValue( 0 );
- tex = pass->createTextureUnitState();
- tex->setTextureName( "system/blank.png" );
- tex->setNumMipmaps( -1 );
- tex->setTextureFiltering( Ogre::TFO_NONE );
- m_SubtractMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DSubtract", "General" );
- pass = m_SubtractMaterial->getTechnique( 0 )->getPass( 0 );
- pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
- pass->setCullingMode( Ogre::CULL_NONE );
- pass->setDepthCheckEnabled( true );
- pass->setDepthWriteEnabled( true );
- pass->setLightingEnabled( false );
- pass->setSceneBlending( Ogre::SBF_ONE, Ogre::SBF_ONE_MINUS_SOURCE_COLOUR ); // FIXME: SUBTRACT
- pass->setAlphaRejectFunction( Ogre::CMPF_LESS );
- pass->setAlphaRejectValue( 0 );
- tex = pass->createTextureUnitState();
- tex->setTextureName( "system/blank.png" );
- tex->setNumMipmaps( -1 );
- tex->setTextureFiltering( Ogre::TFO_NONE );
- m_MultiplyMaterial = Ogre::MaterialManager::getSingleton().create( "Background2DMultiply", "General" );
- pass = m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 );
- pass->setVertexColourTracking( Ogre::TVC_AMBIENT );
- pass->setCullingMode( Ogre::CULL_NONE );
- pass->setDepthCheckEnabled( true );
- pass->setDepthWriteEnabled( true );
- pass->setLightingEnabled( false );
- pass->setSceneBlending( Ogre::SBT_ADD ); // FIXME: MULTIPLY
- pass->setAlphaRejectFunction( Ogre::CMPF_GREATER );
- pass->setAlphaRejectValue( 0 );
- tex = pass->createTextureUnitState();
- tex->setTextureName( "system/blank.png" );
- tex->setNumMipmaps( -1 );
- tex->setTextureFiltering( Ogre::TFO_NONE );
- m_SceneManager->addRenderQueueListener( this );
- }
- //------------------------------------------------------------------------------
- Background2D::~Background2D()
- {
- m_SceneManager->removeRenderQueueListener( this );
- for( unsigned int i = 0; i < m_Animations.size(); ++i )
- {
- delete m_Animations[ i ];
- }
- DestroyVertexBuffers();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::InputDebug(const QGears::Event& event)
- {
- if( cv_background2d_manual.GetB() == true )
- {
- if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_W)
- {
- m_PositionReal.y += 2;
- }
- else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_A)
- {
- m_PositionReal.x += 2;
- }
- else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_S)
- {
- m_PositionReal.y -= 2;
- }
- else if (event.type == QGears::ET_KEY_IMPULSE && event.param1 == OIS::KC_D)
- {
- m_PositionReal.x -= 2;
- }
- CameraManager::getSingleton().Set2DScroll( m_PositionReal );
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::Update()
- {
- for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
- {
- for( unsigned int j = 0; j < m_Animations.size(); ++j )
- {
- if( m_Animations[ j ]->GetName() == m_AnimationPlayed[ i ].name )
- {
- float delta_time = Timer::getSingleton().GetGameTimeDelta();
- float time = m_Animations[ j ]->GetTime();
- float end_time = m_Animations[ j ]->GetLength();
- // if animation ended
- if( time + delta_time >= end_time )
- {
- // set to last frame of animation
- if( time != end_time )
- {
- m_Animations[ j ]->SetTime( end_time );
- }
- if( m_AnimationPlayed[ i ].state == Background2DAnimation::ONCE )
- {
- for( unsigned int k = 0; k < m_AnimationPlayed[ i ].sync.size(); ++k )
- {
- ScriptManager::getSingleton().ContinueScriptExecution( m_AnimationPlayed[ i ].sync[ k ] );
- }
- m_AnimationPlayed[ i ].sync.clear();
- m_AnimationPlayed[ i ].name = ""; // mark to erase this way
- }
- else // LOOPED
- {
- // in case of looped we need to sync with end
- m_Animations[ j ]->SetTime( time + delta_time - end_time );
- }
- }
- else
- {
- m_Animations[ j ]->AddTime( delta_time );
- }
- }
- }
- }
- // remove stopped animations
- std::vector< AnimationPlayed >::iterator i = m_AnimationPlayed.begin();
- for( ; i != m_AnimationPlayed.end(); )
- {
- if( ( *i ).name == "" )
- {
- i = m_AnimationPlayed.erase( i );
- }
- else
- {
- ++i;
- }
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::UpdateDebug()
- {
- // is this necessary? does it cost to apply camera 2d Scroll?
- // if so maybe move this check to applyScroll
- if( m_PositionReal != GetScreenScroll() )
- {
- applyScroll();
- }
- if( cv_debug_background2d.GetB() == true )
- {
- DEBUG_DRAW.SetTextAlignment( DEBUG_DRAW.LEFT );
- DEBUG_DRAW.SetScreenSpace( true );
- DEBUG_DRAW.SetColour( Ogre::ColourValue( 0.0f, 0.8f, 0.8f, 1.0f ) );
- for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
- {
- DEBUG_DRAW.Text( 150.0f, static_cast<float>(34 + i * 12), "Background 2D animation: " + m_AnimationPlayed[ i ].name );
- }
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::calculateScreenScale( void )
- {
- Ogre::Viewport *viewport( CameraManager::getSingleton().getViewport() );
- Ogre::Real scale_width = static_cast<Ogre::Real>(viewport->getActualWidth());
- Ogre::Real scale_height = static_cast<Ogre::Real>(viewport->getActualHeight());
- scale_width /= m_virtual_screen_size.x;
- scale_height /= m_virtual_screen_size.y;
- m_screen_scale = scale_height;
- m_screen_proportion.x = m_screen_scale / scale_width;
- m_screen_proportion.y = m_screen_scale / scale_height;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::OnResize()
- {
- calculateScreenScale();
- for( unsigned int i = 0; i < m_Tiles.size(); ++i )
- {
- Tile &tile( m_Tiles[ i ] );
- Ogre::Vector2 top_left(static_cast<Ogre::Real>(tile.x), static_cast<Ogre::Real>(- tile.y));
- Ogre::Vector2 top_right(static_cast<Ogre::Real>(tile.x + tile.width), static_cast<Ogre::Real>(top_left.y));
- Ogre::Vector2 bottom_right(static_cast<Ogre::Real>(top_right.x), static_cast<Ogre::Real>(-(tile.y + tile.height)));
- Ogre::Vector2 bottom_left(static_cast<Ogre::Real>(top_left.x), static_cast<Ogre::Real>(bottom_right.y));
- virtualScreenToWorldSpace( top_left );
- virtualScreenToWorldSpace( top_right );
- virtualScreenToWorldSpace( bottom_right );
- virtualScreenToWorldSpace( bottom_left );
- float new_x1 = top_left.x;
- float new_y1 = top_left.y;
- float new_x2 = top_right.x;
- float new_y2 = top_right.y;
- float new_x3 = bottom_right.x;
- float new_y3 = bottom_right.y;
- float new_x4 = bottom_left.x;
- float new_y4 = bottom_left.y;
- Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
- if( m_Tiles[ i ].blending == QGears::B_ALPHA )
- {
- vertex_buffer = m_AlphaVertexBuffer;
- }
- else if( m_Tiles[ i ].blending == QGears::B_ADD )
- {
- vertex_buffer = m_AddVertexBuffer;
- }
- else if( m_Tiles[ i ].blending == QGears::B_SUBTRACT )
- {
- vertex_buffer = m_SubtractVertexBuffer;
- }
- else if( m_Tiles[ i ].blending == QGears::B_MULTIPLY )
- {
- vertex_buffer = m_MultiplyVertexBuffer;
- }
- float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
- writeIterator += m_Tiles[ i ].start_vertex_index * TILE_VERTEX_INDEX_SIZE;
- *writeIterator++ = new_x1;
- *writeIterator++ = new_y1;
- writeIterator += 7;
- *writeIterator++ = new_x2;
- *writeIterator++ = new_y2;
- writeIterator += 7;
- *writeIterator++ = new_x3;
- *writeIterator++ = new_y3;
- writeIterator += 7;
- ///*
- *writeIterator++ = new_x1;
- *writeIterator++ = new_y1;
- writeIterator += 7;
- *writeIterator++ = new_x3;
- *writeIterator++ = new_y3;
- writeIterator += 7;
- //*/
- *writeIterator++ = new_x4;
- *writeIterator++ = new_y4;
- vertex_buffer->unlock();
- }
- applyScroll();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::Clear()
- {
- m_ScrollEntity = NULL;
- m_ScrollPositionStart = Ogre::Vector2::ZERO;
- m_ScrollPositionEnd = Ogre::Vector2::ZERO;
- m_ScrollSeconds = 0;
- m_ScrollCurrentSeconds = 0;
- m_Position = Ogre::Vector2::ZERO;
- m_PositionReal = Ogre::Vector2::ZERO;
- m_range = Ogre::AxisAlignedBox::BOX_INFINITE;
- UnsetScroll();
- for( unsigned int i = 0; i < m_Animations.size(); ++i )
- {
- delete m_Animations[ i ];
- }
- m_Animations.clear();
- for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
- {
- for( unsigned int j = 0; j < m_AnimationPlayed[ i ].sync.size(); ++j )
- {
- ScriptManager::getSingleton().ContinueScriptExecution( m_AnimationPlayed[ i ].sync[ j ] );
- }
- }
- m_AnimationPlayed.clear();
- m_Tiles.clear();
- DestroyVertexBuffers();
- CreateVertexBuffers();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::ScriptAutoScrollToEntity( Entity* entity )
- {
- m_ScrollEntity = entity;
- }
- //------------------------------------------------------------------------------
- Entity*
- Background2D::GetAutoScrollEntity() const
- {
- return m_ScrollEntity;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::ScriptScrollToPosition( const float x, const float y, const ScrollType type, const float seconds )
- {
- LOG_TRIVIAL( "[SCRIPT] Background2d set scroll to position \"" + Ogre::StringConverter::toString( Ogre::Vector2( x, y ) ) + "\"." );
- Ogre::Vector2 position = Ogre::Vector2( x, y );
- m_ScrollEntity = NULL;
- if( type == Background2D::NONE )
- {
- SetScroll( position );
- return;
- }
- m_ScrollPositionStart = m_Position;
- m_ScrollPositionEnd = position;
- m_ScrollType = type;
- m_ScrollSeconds = seconds;
- m_ScrollCurrentSeconds = 0;
- }
- //------------------------------------------------------------------------------
- int
- Background2D::ScriptScrollSync()
- {
- ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
- LOG_TRIVIAL( "[SCRIPT] Wait Background2d scroll for function \"" + script.function + "\" in script entity \"" + script.entity + "\"." );
- m_ScrollSync.push_back( script );
- return -1;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::UnsetScroll()
- {
- m_ScrollType = Background2D::NONE;
- for( unsigned int i = 0; i < m_ScrollSync.size(); ++i )
- {
- ScriptManager::getSingleton().ContinueScriptExecution( m_ScrollSync[ i ] );
- }
- m_ScrollSync.clear();
- }
- //------------------------------------------------------------------------------
- const Ogre::Vector2&
- Background2D::GetScrollPositionStart() const
- {
- return m_ScrollPositionStart;
- }
- //------------------------------------------------------------------------------
- const Ogre::Vector2&
- Background2D::GetScrollPositionEnd() const
- {
- return m_ScrollPositionEnd;
- }
- //------------------------------------------------------------------------------
- Background2D::ScrollType
- Background2D::GetScrollType() const
- {
- return m_ScrollType;
- }
- //------------------------------------------------------------------------------
- float
- Background2D::GetScrollSeconds() const
- {
- return m_ScrollSeconds;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetScrollCurrentSeconds( const float seconds )
- {
- m_ScrollCurrentSeconds = seconds;
- }
- //------------------------------------------------------------------------------
- float
- Background2D::GetScrollCurrentSeconds() const
- {
- return m_ScrollCurrentSeconds;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetScreenScroll( const Ogre::Vector2& position )
- {
- SetScroll( position / m_screen_scale );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetScroll( const Ogre::Vector2& position )
- {
- m_Position = position;
- Ogre::Vector3 pos_3d( m_Position.x, m_Position.y, 0 );
- if( !m_range.contains( pos_3d ) )
- {
- Ogre::Vector3 max_3d( m_range.getMaximum() );
- Ogre::Vector3 min_3d( m_range.getMinimum() );
- Ogre::Vector2 max( max_3d.x, max_3d.y );
- Ogre::Vector2 min( min_3d.x, min_3d.y );
- m_Position.makeCeil( min );
- m_Position.makeFloor( max );
- }
- applyScroll();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::applyScroll()
- {
- if( cv_background2d_manual.GetB() != true )
- {
- m_PositionReal = GetScreenScroll();
- CameraManager::getSingleton().Set2DScroll( m_PositionReal );
- }
- }
- //------------------------------------------------------------------------------
- const Ogre::Vector2&
- Background2D::GetScroll() const
- {
- return m_Position;
- }
- //------------------------------------------------------------------------------
- const Ogre::Vector2
- Background2D::GetScreenScroll() const
- {
- return GetScroll() * m_screen_scale;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetImage( const Ogre::String& image )
- {
- Ogre::LogManager::getSingleton().stream()
- << "Background2D::SetImage " << image;
- Ogre::Pass* pass = m_AlphaMaterial->getTechnique( 0 )->getPass( 0 );
- Ogre::TextureUnitState* tex = pass->getTextureUnitState( 0 );
- tex->setTextureName( image );
- pass = m_AddMaterial->getTechnique( 0 )->getPass( 0 );
- tex = pass->getTextureUnitState( 0 );
- tex->setTextureName( image );
- pass = m_SubtractMaterial->getTechnique( 0 )->getPass( 0 );
- tex = pass->getTextureUnitState( 0 );
- tex->setTextureName( image );
- pass = m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 );
- tex = pass->getTextureUnitState( 0 );
- tex->setTextureName( image );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetRange( const Ogre::Vector4& range )
- {
- SetRange( ( int )range.x, ( int )range.y, ( int )range.z, ( int )range.w );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::SetRange( const int min_x, const int min_y, const int max_x, const int max_y )
- {
- Ogre::LogManager::getSingleton().stream()
- << "Background2D::SetRange " << min_x << " " << min_y << " " << max_x << " " << max_y;
- Ogre::Vector2 half_virtual_screen_size( m_virtual_screen_size / 2 );
- half_virtual_screen_size /= m_screen_proportion;
- m_range.setMaximum( max_x - half_virtual_screen_size.x , max_y - half_virtual_screen_size.y, 1 );
- m_range.setMinimum( min_x + half_virtual_screen_size.x , min_y + half_virtual_screen_size.y, 0 );
- Ogre::LogManager::getSingleton().stream()
- << "Background2D::SetRange " << m_range;
- calculateScreenScale();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::AddTile( const QGears::Tile& tile )
- {
- // TODO: move depth calculation to flevelBackgroundLoader maybe? and let Backgorund2D only handle 0 <= depth <= 1 or so?
- // maybe just move the < 4095 part to flevel background loader?
- Ogre::Real depth( 0.0001f );
- if( tile.depth >= 1 )
- {
- if( tile.depth < 4095 )
- {
- const Ogre::Matrix4 &cam_projection( CameraManager::getSingleton().GetCurrentCamera()->getProjectionMatrixWithRSDepth() );
- Ogre::Vector4 res( 0, 0, -tile.depth, 1 );
- res = cam_projection * res;
- res /= res.w;
- depth = res.z;
- }
- else
- {
- depth = 0.9999f;
- }
- }
- AddTile( tile.destination, tile.width, tile.height, depth, tile.uv, tile.blending );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::AddTile( const Ogre::Vector2& destination, const int width, const int height, const float depth, const Ogre::Vector4& uv, const Blending blending )
- {
- AddTile( static_cast<int>(destination.x), static_cast<int>(destination.y), width, height, depth, uv.x, uv.y, uv.z, uv.w, blending );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::virtualScreenToWorldSpace( Ogre::Vector2& pos ) const
- {
- pos.x /= m_virtual_screen_size.x / 2;
- pos.y /= m_virtual_screen_size.y / 2;
- pos.x *= m_screen_proportion.x;
- pos.y *= m_screen_proportion.y;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::AddTile( const int x, const int y, const int width, const int height, const float depth, const float u1, const float v1, const float u2, const float v2, const Blending blending )
- {
- Ogre::RenderOperation render_op;
- Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
- unsigned int max_vertex_count;
- if( blending == QGears::B_ALPHA )
- {
- render_op = m_AlphaRenderOp;
- vertex_buffer = m_AlphaVertexBuffer;
- max_vertex_count = m_AlphaMaxVertexCount;
- }
- else if( blending == QGears::B_ADD )
- {
- render_op = m_AddRenderOp;
- vertex_buffer = m_AddVertexBuffer;
- max_vertex_count = m_AddMaxVertexCount;
- }
- else if( blending == QGears::B_SUBTRACT )
- {
- render_op = m_SubtractRenderOp;
- vertex_buffer = m_SubtractVertexBuffer;
- max_vertex_count = m_SubtractMaxVertexCount;
- }
- else if( blending == QGears::B_MULTIPLY )
- {
- render_op = m_MultiplyRenderOp;
- vertex_buffer = m_MultiplyVertexBuffer;
- max_vertex_count = m_MultiplyMaxVertexCount;
- }
- else
- {
- LOG_ERROR( "Unknown blending type." );
- return;
- }
- if( render_op.vertexData->vertexCount + TILE_VERTEX_COUNT > max_vertex_count )
- {
- LOG_ERROR( "Max number of tiles reached. Can't create more than " + Ogre::StringConverter::toString( max_vertex_count / TILE_VERTEX_COUNT ) + " tiles." );
- return;
- }
- Tile tile;
- tile.x = x;
- tile.y = y;
- tile.width = width;
- tile.height = height;
- tile.start_vertex_index = render_op.vertexData->vertexCount;
- tile.blending = blending;
- size_t index( m_Tiles.size() );
- m_Tiles.push_back( tile );
- Ogre::Vector2 top_left(static_cast<Ogre::Real>(x), static_cast<Ogre::Real>(-y));
- Ogre::Vector2 top_right(static_cast<Ogre::Real>(x + width), static_cast<Ogre::Real>(top_left.y));
- Ogre::Vector2 bottom_right(static_cast<Ogre::Real>(top_right.x), static_cast<Ogre::Real>(-(y + height)));
- Ogre::Vector2 bottom_left( top_left.x, bottom_right.y );
- virtualScreenToWorldSpace( top_left );
- virtualScreenToWorldSpace( top_right );
- virtualScreenToWorldSpace( bottom_right );
- virtualScreenToWorldSpace( bottom_left );
- float new_x1 = top_left.x;
- float new_y1 = top_left.y;
- float new_x2 = top_right.x;
- float new_y2 = top_right.y;
- float new_x3 = bottom_right.x;
- float new_y3 = bottom_right.y;
- float new_x4 = bottom_left.x;
- float new_y4 = bottom_left.y;
- float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
- writeIterator += render_op.vertexData->vertexCount * TILE_VERTEX_INDEX_SIZE;
- *writeIterator++ = new_x1;
- *writeIterator++ = new_y1;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u1;
- *writeIterator++ = v1;
- *writeIterator++ = new_x2;
- *writeIterator++ = new_y2;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u2;
- *writeIterator++ = v1;
- *writeIterator++ = new_x3;
- *writeIterator++ = new_y3;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u2;
- *writeIterator++ = v2;
- *writeIterator++ = new_x1;
- *writeIterator++ = new_y1;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u1;
- *writeIterator++ = v1;
- *writeIterator++ = new_x3;
- *writeIterator++ = new_y3;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u2;
- *writeIterator++ = v2;
- *writeIterator++ = new_x4;
- *writeIterator++ = new_y4;
- *writeIterator++ = depth;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = 1;
- *writeIterator++ = u1;
- *writeIterator++ = v2;
- render_op.vertexData->vertexCount += TILE_VERTEX_COUNT;
- vertex_buffer->unlock();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::UpdateTileUV( const unsigned int tile_id, const float u1, const float v1, const float u2, const float v2 )
- {
- if( tile_id >= m_Tiles.size() )
- {
- LOG_ERROR( "Tile with id " + Ogre::StringConverter::toString( tile_id ) + " doesn't exist." );
- return;
- }
- Ogre::HardwareVertexBufferSharedPtr vertex_buffer;
- if( m_Tiles[ tile_id ].blending == QGears::B_ALPHA )
- {
- vertex_buffer = m_AlphaVertexBuffer;
- }
- else if( m_Tiles[ tile_id ].blending == QGears::B_ADD )
- {
- vertex_buffer = m_AddVertexBuffer;
- }
- else if( m_Tiles[ tile_id ].blending == QGears::B_SUBTRACT )
- {
- vertex_buffer = m_SubtractVertexBuffer;
- }
- else if( m_Tiles[ tile_id ].blending == QGears::B_MULTIPLY )
- {
- vertex_buffer = m_MultiplyVertexBuffer;
- }
- float* writeIterator = ( float* )vertex_buffer->lock( Ogre::HardwareBuffer::HBL_NORMAL );
- writeIterator += m_Tiles[ tile_id ].start_vertex_index * TILE_VERTEX_INDEX_SIZE;
- writeIterator += 7;
- *writeIterator++ = u1;
- *writeIterator++ = v1;
- writeIterator += 7;
- *writeIterator++ = u2;
- *writeIterator++ = v1;
- writeIterator += 7;
- *writeIterator++ = u2;
- *writeIterator++ = v2;
- writeIterator += 7;
- *writeIterator++ = u1;
- *writeIterator++ = v1;
- writeIterator += 7;
- *writeIterator++ = u2;
- *writeIterator++ = v2;
- writeIterator += 7;
- *writeIterator++ = u1;
- *writeIterator++ = v2;
- vertex_buffer->unlock();
- }
- //------------------------------------------------------------------------------
- void
- Background2D::AddAnimation( Background2DAnimation* animation )
- {
- m_Animations.push_back( animation );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::PlayAnimation( const Ogre::String& animation, const Background2DAnimation::State state )
- {
- bool found = false;
- for( unsigned int i = 0; i < m_Animations.size(); ++i )
- {
- if( m_Animations[ i ]->GetName() == animation )
- {
- found = true;
- m_Animations[ i ]->SetTime( 0 );
- m_Animations[ i ]->AddTime( 0 );
- }
- }
- for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
- {
- if( m_AnimationPlayed[ i ].name == animation )
- {
- m_AnimationPlayed.erase( m_AnimationPlayed.begin() + i );
- }
- }
- if( found == true )
- {
- AnimationPlayed anim;
- anim.name = animation;
- anim.state = state;
- m_AnimationPlayed.push_back( anim );
- }
- else
- {
- LOG_ERROR( "Background2D doesn't has animation \"" + animation + "\"." );
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::ScriptPlayAnimationLooped( const char* name )
- {
- PlayAnimation( Ogre::String( name ), Background2DAnimation::LOOPED );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::ScriptPlayAnimationOnce( const char* name )
- {
- PlayAnimation( Ogre::String( name ), Background2DAnimation::ONCE );
- }
- //------------------------------------------------------------------------------
- int
- Background2D::ScriptAnimationSync( const char* animation )
- {
- for( unsigned int i = 0; i < m_AnimationPlayed.size(); ++i )
- {
- if( m_AnimationPlayed[ i ].name == animation )
- {
- ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
- m_AnimationPlayed[ i ].sync.push_back( script );
- return -1;
- }
- }
- return 1;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::renderQueueEnded( Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation )
- {
- if( cv_show_background2d.GetB() == false )
- {
- return;
- }
- if( queueGroupId == Ogre::RENDER_QUEUE_MAIN )
- {
- m_RenderSystem->_setWorldMatrix( Ogre::Matrix4::IDENTITY );
- m_RenderSystem->_setProjectionMatrix( Ogre::Matrix4::IDENTITY );
- Ogre::Viewport *viewport( CameraManager::getSingleton().getViewport() );
- float width = static_cast<float>(viewport->getActualWidth());
- float height = static_cast<float>(viewport->getActualHeight());
- Ogre::Matrix4 view;
- view.makeTrans( Ogre::Vector3( m_PositionReal.x * 2 / width, -m_PositionReal.y * 2 / height, 0 ) );
- m_RenderSystem->_setViewMatrix( view );
- if( m_AlphaRenderOp.vertexData->vertexCount != 0 )
- {
- m_SceneManager->_setPass( m_AlphaMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
- m_RenderSystem->_render( m_AlphaRenderOp );
- }
- if( m_AddRenderOp.vertexData->vertexCount != 0 )
- {
- m_SceneManager->_setPass( m_AddMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
- m_RenderSystem->_render( m_AddRenderOp );
- }
- if( m_SubtractRenderOp.vertexData->vertexCount != 0 )
- {
- m_SceneManager->_setPass( m_SubtractMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
- m_RenderSystem->_render( m_SubtractRenderOp );
- }
- if( m_MultiplyRenderOp.vertexData->vertexCount != 0 )
- {
- m_SceneManager->_setPass( m_MultiplyMaterial->getTechnique( 0 )->getPass( 0 ), true, false );
- m_RenderSystem->_render( m_MultiplyRenderOp );
- }
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::CreateVertexBuffers()
- {
- m_AlphaMaxVertexCount = 2048 * TILE_VERTEX_COUNT;
- m_AlphaRenderOp.vertexData = new Ogre::VertexData;
- m_AlphaRenderOp.vertexData->vertexStart = 0;
- Ogre::VertexDeclaration* vDecl = m_AlphaRenderOp.vertexData->vertexDeclaration;
- size_t offset = 0;
- vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
- m_AlphaVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AlphaMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
- m_AlphaRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AlphaVertexBuffer );
- m_AlphaRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- m_AlphaRenderOp.useIndexes = false;
- m_AddMaxVertexCount = 256 * TILE_VERTEX_COUNT;
- m_AddRenderOp.vertexData = new Ogre::VertexData;
- m_AddRenderOp.vertexData->vertexStart = 0;
- vDecl = m_AddRenderOp.vertexData->vertexDeclaration;
- offset = 0;
- vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
- m_AddVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_AddMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
- m_AddRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AddVertexBuffer );
- m_AddRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- m_AddRenderOp.useIndexes = false;
- m_SubtractMaxVertexCount = 256 * TILE_VERTEX_COUNT; // FIXME: 256?
- m_SubtractRenderOp.vertexData = new Ogre::VertexData;
- m_SubtractRenderOp.vertexData->vertexStart = 0;
- vDecl = m_SubtractRenderOp.vertexData->vertexDeclaration;
- offset = 0;
- vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
- m_SubtractVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_SubtractMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
- m_SubtractRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_SubtractVertexBuffer );
- m_SubtractRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- m_SubtractRenderOp.useIndexes = false;
- m_MultiplyMaxVertexCount = 256 * TILE_VERTEX_COUNT; // FIXME: 256?
- m_MultiplyRenderOp.vertexData = new Ogre::VertexData;
- m_MultiplyRenderOp.vertexData->vertexStart = 0;
- vDecl = m_MultiplyRenderOp.vertexData->vertexDeclaration;
- offset = 0;
- vDecl->addElement( 0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT3 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE );
- offset += Ogre::VertexElement::getTypeSize( Ogre::VET_FLOAT4 );
- vDecl->addElement( 0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES );
- m_MultiplyVertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer( vDecl->getVertexSize( 0 ), m_MultiplyMaxVertexCount, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false );
- m_MultiplyRenderOp.vertexData->vertexBufferBinding->setBinding( 0, m_AMultiplyVertexBuffer );
- m_MultiplyRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- m_MultiplyRenderOp.useIndexes = false;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::DestroyVertexBuffers()
- {
- delete m_AlphaRenderOp.vertexData;
- m_AlphaRenderOp.vertexData = 0;
- m_AlphaVertexBuffer.setNull();
- m_AlphaMaxVertexCount = 0;
- delete m_AddRenderOp.vertexData;
- m_AddRenderOp.vertexData = 0;
- m_AddVertexBuffer.setNull();
- m_AddMaxVertexCount = 0;
- delete m_SubtractRenderOp.vertexData;
- m_SubtractRenderOp.vertexData = 0;
- m_SubtractVertexBuffer.setNull();
- m_SubtractMaxVertexCount = 0;
- delete m_MultiplyRenderOp.vertexData;
- m_MultiplyRenderOp.vertexData = 0;
- m_MultiplyVertexBuffer.setNull();
- m_MultiplyMaxVertexCount = 0;
- }
- //------------------------------------------------------------------------------
- void
- Background2D::load( const QGears::Background2DFilePtr& background )
- {
- assert( !background.isNull() );
- background->load();
- SetImage( background->getTextureName() );
- m_virtual_screen_size = background->getClip();
- SetRange( background->getRange() );
- const Ogre::Vector3& position( background->getPosition() );
- const Ogre::Quaternion& orientation( background->getOrientation() );
- const Ogre::Radian& fov( background->getFov() );
- CameraManager::getSingleton().Set2DCamera( position, orientation, fov );
- load( background->getTiles() );
- }
- //------------------------------------------------------------------------------
- void
- Background2D::load( const QGears::Background2DFile::TileList& tiles )
- {
- QGears::Background2DFile::TileList::const_iterator it( tiles.begin() );
- QGears::Background2DFile::TileList::const_iterator it_end( tiles.end() );
- size_t tile_index( 0 );
- while( it != it_end )
- {
- AddTile( *it );
- load( tile_index++, it->animations );
- ++it;
- }
- }
- //------------------------------------------------------------------------------
- void
- Background2D::load( const size_t tile_index, const QGears::AnimationMap& animations )
- {
- QGears::AnimationMap::const_iterator it( animations.begin() );
- QGears::AnimationMap::const_iterator it_end( animations.end() );
- while( it != it_end )
- {
- const QGears::String& name( it->first );
- const QGears::Animation& animation( it->second );
- Background2DAnimation* anim( new Background2DAnimation( name, this, tile_index ) );
- anim->SetLength( animation.length );
- QGears::KeyFrameList::const_iterator itk( animation.key_frames.begin() );
- QGears::KeyFrameList::const_iterator itk_end( animation.key_frames.end() );
- while( itk != itk_end )
- {
- anim->AddUVKeyFrame( *(itk++) );
- }
- AddAnimation( anim );
- ++it;
- }
- }
- //------------------------------------------------------------------------------
|