New to game programming - Can't setup Multi-Threading
Posted: Thu Aug 02, 2018 4:01 am
Ogre Version: 2.2
Operating System: Windows 10
Render System: DirectX
Hey guys I'm jumping straight in to working/learning ogre and have successfully setup and built the standard template that cmake generates, defaulting to a single threaded application. I renamed all references to "Demo" to "SpaceRanchers" and successfully compiled and ran the application.
I am learning how this stuff works by taking a "monkey see monkey do" approach. Conceptually my understanding of what the main .cpp file does as setup through the template is "Overload" the functions found within either MainLoopSingleThreaded.cpp or MainLoopMultiThreaded.cpp with all the custom code and game logic I'm planning to implement.
In other words, in my mind, MainLoopSingleThreaded.cpp and MainLoopMultiThreaded.cpp setup the basic barebones of a running game loop and I will be "building out" my project primarily in SpaceRanchers.cpp. This file, the only one I've edited, only works when told to use MainLoopSingleThreaded.cpp. Here it is:
The errors I've seen manifest in 3 ways, a quiet crash, a HEAP error, or this one:
I'm sure the error generated is random and dependent on when one particular piece of code reaches some point.
I'm in need of some guidance with regards with some fundamental stuff.
Operating System: Windows 10
Render System: DirectX
Code: Select all
Ogre.log (optional) <-- Don't know how to enable
I am learning how this stuff works by taking a "monkey see monkey do" approach. Conceptually my understanding of what the main .cpp file does as setup through the template is "Overload" the functions found within either MainLoopSingleThreaded.cpp or MainLoopMultiThreaded.cpp with all the custom code and game logic I'm planning to implement.
In other words, in my mind, MainLoopSingleThreaded.cpp and MainLoopMultiThreaded.cpp setup the basic barebones of a running game loop and I will be "building out" my project primarily in SpaceRanchers.cpp. This file, the only one I've edited, only works when told to use MainLoopSingleThreaded.cpp. Here it is:
Code: Select all
#define LL_NORMAL = 2
#include "GraphicsSystem.h"
#include "LogicSystem.h"
#include "SpaceRanchersGameState.h"
#include "OgreSceneManager.h"
#include "OgreCamera.h"
#include "OgreRoot.h"
#include "OgreRenderWindow.h"
#include "OgreConfigFile.h"
#include "Compositor/OgreCompositorManager2.h"
//Declares WinMain / main
#include "MainEntryPointHelper.h"
#include "System/MainEntryPoints.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <errno.h>
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#include "shlobj.h"
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMainApp( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow )
#else
int mainApp( int argc, const char *argv[] )
#endif
{
return SpaceRanchers::MainEntryPoints::mainAppMultiThreaded( SPACERANCHERS_MAIN_ENTRY_PARAMS );
}
namespace SpaceRanchers
{
class SpaceRanchersGraphicsSystem : public GraphicsSystem
{
virtual Ogre::CompositorWorkspace* setupCompositor()
{
return GraphicsSystem::setupCompositor();
}
virtual void setupResources(void)
{
GraphicsSystem::setupResources();
Ogre::ConfigFile cf;
cf.load(mResourcePath + "resources2.cfg");
Ogre::String dataFolder = cf.getSetting( "DoNotUseAsResource", "Hlms", "" );
if( dataFolder.empty() )
dataFolder = "./";
else if( *(dataFolder.end() - 1) != '/' )
dataFolder += "/";
dataFolder += "2.0/scripts/materials/PbsMaterials";
addResourceLocation( dataFolder, "FileSystem", "General" );
}
public:
SpaceRanchersGraphicsSystem(GameState *gameState, Ogre::ColourValue backgroundColour = Ogre::ColourValue(1.0f,0.0f,0.0f,1.0f)) :
GraphicsSystem( gameState )
{
mResourcePath = getenv("APPDATA");
mResourcePath += "/DynasoulStudio/SpaceRanchers/Data/";
//It's recommended that you set this path to:
// %APPDATA%/SpaceRanchers/ on Windows
// ~/.config/SpaceRanchers/ on Linux
// macCachePath() + "/SpaceRanchers/" (NSCachesDirectory) on Apple -> Important because
// on iOS your app could be rejected from App Store when they see iCloud
// trying to backup your Ogre.log & ogre.cfg auto-generated without user
// intervention. Also convenient because these settings will be deleted
// if the user removes cached data from the app, so the settings will be
// reset.
// Obviously you can replace "SpaceRanchers" by your app's name.
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
mWriteAccessFolder = + "/";
TCHAR path[MAX_PATH];
if( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_APPDATA, NULL,
SHGFP_TYPE_CURRENT, path ) != S_OK ) )
{
//Need to convert to OEM codepage so that fstream can
//use it properly on international systems.
#if defined(_UNICODE) || defined(UNICODE)
int size_needed = WideCharToMultiByte( CP_OEMCP, 0, path, (int)wcslen(path),
NULL, 0, NULL, NULL );
mWriteAccessFolder = std::string( size_needed, 0 );
WideCharToMultiByte( CP_OEMCP, 0, path, (int)wcslen(path),
&mWriteAccessFolder[0], size_needed, NULL, NULL );
#else
TCHAR oemPath[MAX_PATH];
CharToOem( path, oemPath );
mWriteAccessFolder = std::string( oemPath );
#endif
mWriteAccessFolder += "/SpaceRanchers/";
//Attempt to create directory where config files go
if( !CreateDirectoryA( mWriteAccessFolder.c_str(), NULL ) &&
GetLastError() != ERROR_ALREADY_EXISTS )
{
//Couldn't create directory (no write access?),
//fall back to current working dir
mWriteAccessFolder = "";
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
const char *homeDir = getenv("HOME");
if( homeDir == 0 )
homeDir = getpwuid( getuid() )->pw_dir;
mWriteAccessFolder = homeDir;
mWriteAccessFolder += "/.config";
int result = mkdir( mWriteAccessFolder.c_str(), S_IRWXU|S_IRWXG );
int errorReason = errno;
//Create "~/.config"
if( result && errorReason != EEXIST )
{
printf( "Error. Failing to create path '%s'. Do you have access rights?",
mWriteAccessFolder.c_str() );
mWriteAccessFolder = "";
}
else
{
//Create "~/.config/SpaceRanchers"
mWriteAccessFolder += "/SpaceRanchers/";
result = mkdir( mWriteAccessFolder.c_str(), S_IRWXU|S_IRWXG );
errorReason = errno;
if( result && errorReason != EEXIST )
{
printf( "Error. Failing to create path '%s'. Do you have access rights?",
mWriteAccessFolder.c_str() );
mWriteAccessFolder = "";
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS
mWriteAccessFolder = macCachePath() + "/SpaceRanchers/";
//Create "pathToCache/SpaceRanchers"
mWriteAccessFolder += "/SpaceRanchers/";
result = mkdir( mWriteAccessFolder.c_str(), S_IRWXU|S_IRWXG );
errorReason = errno;
if( result && errorReason != EEXIST )
{
printf( "Error. Failing to create path '%s'. Do you have access rights?",
mWriteAccessFolder.c_str() );
mWriteAccessFolder = "";
}
#endif
}
};
void MainEntryPoints::createSystems( GameState **outGraphicsGameState,
GraphicsSystem **outGraphicsSystem,
GameState **outLogicGameState,
LogicSystem **outLogicSystem )
{
//For Debugging -_-
AllocConsole();
freopen("conin$", "r", stdin);
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);
printf("Debugging Window:\n");
SpaceRanchersGameState *gfxGameState = new SpaceRanchersGameState("Space Ranchers");
GraphicsSystem *graphicsSystem = new SpaceRanchersGraphicsSystem( gfxGameState );
LogicSystem *logicSystem = new LogicSystem(gfxGameState);
GameEntityManager *gameEntityManager = new GameEntityManager(graphicsSystem, logicSystem);
printf("Finished setting up createSystems()\nNotifying systems\n");
gfxGameState->_notifyGraphicsSystem( graphicsSystem );
graphicsSystem->_notifyLogicSystem( logicSystem );
logicSystem->_notifyGraphicsSystem( graphicsSystem );
printf("Finished Notifying Systems\n");
*outGraphicsGameState = gfxGameState;
*outGraphicsSystem = graphicsSystem;
*outLogicSystem = logicSystem;
printf("Finished Hooking Pointers\n");
}
void MainEntryPoints::destroySystems( GameState *graphicsGameState,
GraphicsSystem *graphicsSystem,
GameState *logicGameState,
LogicSystem *logicSystem )
{
delete logicSystem;
delete graphicsSystem;
delete graphicsGameState;
}
const char* MainEntryPoints::getWindowTitle(void)
{
std::string windowTitle = "Space Ranchers ";
windowTitle += SPACERANCHERS_VER;
windowTitle += " - Dynasoul Studio";
char* cstr = new char[windowTitle.length() + 1];
std::strcpy(cstr, windowTitle.c_str());
return cstr;
}
}
I'm sure the error generated is random and dependent on when one particular piece of code reaches some point.
I'm in need of some guidance with regards with some fundamental stuff.