Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


GameCodingNinja

Member Since 18 Aug 2005
Offline Last Active Jan 02 2015 12:39 PM

#5200935 Animated load screens with OpenGL, a simple solution

Posted by GameCodingNinja on 31 December 2014 - 12:09 AM

I came up with a simple solution for animated loading screens since I really don't like the few options that are available for trying to multi-thread parts of OpenGL. My simple solution allows you to load everything from the main thread and run your animation from newly spawned thread. This only works if your using SDL.

The simple solution is...

Use SDL's bitmap software rendering tools to load and render your "loading" animation from a thread. Since this is a completely separate rendering system, there's no OpenGL conflicts. Also, your engine probably has some dependencies that need to be loaded just to get part of your system up and running before even a simple image can be displayed as well as start up the render loop. That's no longer an issue.

I just start the thread that plays the "loading" animation and then load everything. This is happening outside of the game loop, independent of the engine, from within one function.

Here's my code to animate from a thread to show how easy it is to do. I'm just fading the logo in and out while loading sound, textures, etc with my engine.

I thought this was such a cool solution so I thought I'd share. Works great for me. biggrin.png

int CStartUpState::Animate()
{
    // Get window surface
    SDL_Surface * pScreenSurface = SDL_GetWindowSurface( CDevice::Instance().GetWindow() );
    if( pScreenSurface == NULL )
        NGenFunc::PostDebugMsg( "Surface Creation error! - " + std::string(SDL_GetError()) );

    // Create a bitmap surface
    SDL_Surface * pLogoSurface = SDL_LoadBMP( "data/textures/startup/logo.bmp" );
    if( pLogoSurface == NULL )
        NGenFunc::PostDebugMsg( "Logo Surface Creation error! - " + std::string(SDL_GetError()) );

    // Calculate the rect position and scaled size
    SDL_Rect rect;
    rect.w = pLogoSurface->w * CSettings::Instance().GetScreenRatio().GetH();
    rect.h = pLogoSurface->h * CSettings::Instance().GetScreenRatio().GetH();
    rect.x = (pScreenSurface->w - rect.w) / 2;
    rect.y = (pScreenSurface->h - rect.h) / 2;

    SDL_Delay( 200 );

    FadeTo( 500, 0, 255, pLogoSurface, pScreenSurface, rect );

    SDL_Delay( 2000 );

    FadeTo( 500, 255, 0, pLogoSurface, pScreenSurface, rect );

    SDL_Delay( 200 );

    SDL_FreeSurface( pLogoSurface );
    SDL_FreeSurface( pScreenSurface );

    return thread::THREAD_EXIT_CODE;

}  // Animate


void CStartUpState::FadeTo(
    float time, float current, float final, SDL_Surface * pSource, SDL_Surface * pTarget, SDL_Rect & rect )
{
    float inc = (final - current) / time;

    while( time > 0 )
    {
        // First thing we need to do is get our elapsed time
        CHighResTimer::Instance().CalcElapsedTime();

        time -= CHighResTimer::Instance().GetElapsedTime();

        current += inc * CHighResTimer::Instance().GetElapsedTime();

        SDL_SetSurfaceColorMod( pSource, current, current, current );

        if( time < 0 )
        {
            SDL_SetSurfaceColorMod( pSource, final, final, final );
            break;
        }

        SDL_BlitScaled( pSource, NULL, pTarget, &rect );
        SDL_UpdateWindowSurface( CDevice::Instance().GetWindow() );

        SDL_Delay( 5 );
    }

}   // FadeTo

This is where it all happens. The first line of code starts the thread for animating loading screen. The following lines of code is loading everything I need for the engine at this time. The last line waits for the thread to finish. All within one function, completely independent of the OpenGL/SDL game engine.

void CStartUpState::Load()
{
    // Start the animated loading thread
    loadThread.Start( this, &CStartUpState::Animate, "startupStateThread" );

    // Load in any fonts
    CFontMgr::Instance().LoadFromXML( "data/textures/fonts/font.lst" );

    // Shaders must always be loaded first because they are accessed from object data
    CShaderMgr::Instance().LoadFromXML( "data/shaders/shader.cfg" );

    // Load all of the meshes and materials in these groups
    CObjectDataMgr2D::Instance().LoadListTable( "data/objects/2d/objectDataList/dataListTable.lst" );
    CObjectDataMgr2D::Instance().LoadGroup("(menu)");
    CObjectDataMgr2D::Instance().LoadGroup( "(title_screen)" );

    // Load sound resources for the menu
    CSoundMgr::Instance().LoadListTable( "data/sound/soundListTable.lst" );
    CSoundMgr::Instance().LoadGroup("(menu)");

    // Creates the script manager and loads the list table
    CScriptManager::Instance().LoadListTable( "data/objects/2d/scripts/scriptListTable.lst" );

    // Register the script items
    RegisterStdString( CScriptManager::Instance().GetEnginePtr() );
    NScriptGlobals::Register( CScriptManager::Instance().GetEnginePtr() );
    NScriptColor::Register( CScriptManager::Instance().GetEnginePtr() );
    CSpriteScriptComponent2d::Register( CScriptManager::Instance().GetEnginePtr() );

    // Load group specific script items
    CScriptManager::Instance().LoadGroup("(menu)");

    // Create the menu system
    CMenuManager::Instance().LoadFromXML( "data/objects/2d/menu/tree.list" );
    CMenuManager::Instance().ActivateTree("main");

    // Init the currently plugged in game controllers
    CDevice::Instance().InitStartupGamepads();

    // Load the action manager
    CActionManager::Instance().LoadActionFromXML( "data/settings/controllerMapping.cfg" );

    // Wait for the thread to finish
    loadThread.WaitForThread();

}   // Load



#5083699 XAudio2 - Pretty poor huh?

Posted by GameCodingNinja on 06 August 2013 - 05:19 PM

I use XAct. I find it very easy to use and has many powerful features. I'll post some code if anyone is interested.




#5028094 Basic Win32 window with C++

Posted by GameCodingNinja on 02 February 2013 - 08:10 AM

Since your writing a Windows API app in c++, it's all you at that point. If you want easy interface construction, try C#.

 

A simpler way to add controls to a window api c++ app is to use an *.rc file to setup a dialog window as your parent window. Now you can use the MSVS gui to design your window with the needed controls.

 

This example might help you.

http://www.codeproject.com/Articles/227831/A-dialog-based-Win32-C-program




#4943714 Package files - Do we really need them for our game?

Posted by GameCodingNinja on 27 May 2012 - 08:23 AM

For me, the only reason to use a package file is to keep people from messing around or using the resources from the game. So the question is..., is this a legitimate concern?


#4898980 fleshing out your game idea

Posted by GameCodingNinja on 02 January 2012 - 11:22 AM

I find compartmentalizing concepts makes it easier to expand on them and edit them.


Can you share a simple example of what you are talking about? The idea sounds interesting but I'm not sure I'm completely understand.


PARTNERS