Violation Reading

I’m new to Panda3D and trying to get my first app running, based on the tutorial examples, but I’m stuck to second example…

I’m using a custom class to hold the game engine functionality; within its setup() method I initialize panda framework, but I keep getting a reading violation error (either from ntdll.dll or libp3framework) when I call:

NodePath scene = window->load_model(framework.get_models(), "models/environment");

The strange thing is that, if I put the same code inside the main() function, everything runs smoothly.

Is there a “restriction”, namely to avoid using classes and keep the code within the main() function? I’m thinking to use game states classes, that will have different scenes, so it is neccessary to be able to load model from classes outside the main() function.

I’m using Visual Studio 2015 - Windows XP (v140_xp) toolset (which uses WinSDK 7.1A compiler) and compiling also against the Qt framework. Here is the code:

main.cpp

//---------------------------------------------------------------------------
// Include Qt modules
#include <QtCore/QCoreApplication>
#include <QtCore/QSettings>
#include <QtCore/QCommandLineParser>
#include <QtCore/QTranslator>

//---------------------------------------------------------------------------
// Include game engine headers
#include "pandaGameEngine.h"

//---------------------------------------------------------------------------
// Run !!
int main(int argc, char *argv[]) {
	// Create application ...
	QCoreApplication app(argc, argv);
	// ... and set application details
	app.setOrganizationName("...");
	app.setOrganizationDomain("...");
	app.setApplicationName("...");
	app.setApplicationVersion("alpha");

	// Load settings
	QSettings *settings = new QSettings("settings.ini", QSettings::IniFormat);

	// Parse command-line arguments
	QCommandLineParser *cmdlParser = new QCommandLineParser;
	cmdlParser->setApplicationDescription(QCoreApplication::tr("..."));
	cmdlParser->addHelpOption();
	cmdlParser->addVersionOption();
	/* Create argument list */
	cmdlParser->process(app);
	const QStringList args = cmdlParser->positionalArguments();
	/* Read the arguments */
	// Update settings if neccesary
	// ...
	// Clear command-line arguments
	delete cmdlParser;
	cmdlParser = NULL;

	// Load translations
	QTranslator *translator = new QTranslator;
	translator->load(settings->value("gui/language", "english").toString(), ":/resources/translations");
	app.installTranslator(translator);
	delete translator;
	translator = NULL;

	// Start game engine
	pandaGameEngine *gameEngine = new pandaGameEngine(settings);
	gameEngine->start(argc, argv);
	// Delete game engine and exit
	delete gameEngine; gameEngine = NULL;
	delete settings; settings = NULL;

	return 0;
}

pandaGameEngine.h

#ifndef PANDAGAMEENGINE_H
#define PANDAGAMEENGINE_H

//---------------------------------------------------------------------------
// Include Qt modules
#include <QtCore/QObject>
#include <QtCore/QSettings>
#include <QtCore/QVector>

//---------------------------------------------------------------------------
// Include Panda3D modules
#include "pandaFramework.h"
#include "pandaSystem.h"

//---------------------------------------------------------------------------
// Include game engine modules
#include "gameState.h"

//---------------------------------------------------------------------------
// Declare generic game state class
class gameState;

//---------------------------------------------------------------------------
//	pandaGameEngine class
//---------------------------------------------------------------------------
class pandaGameEngine : public QObject
{
	Q_OBJECT

	public:
		explicit pandaGameEngine(QSettings *settings = NULL);
		~pandaGameEngine(void);

		void start(int argc, char *argv[]);

	public slots:
		void changeState(gameState *state);
		void pushState(gameState *state);
		void popState(void);

	protected:
		QSettings *mSettings;

		// Setup engine
		bool setup(int argc, char *argv[]);

		// Handle keyboard events
		// ...
		// Handle mouse events
		// ...
		// Handle joystick events
		// ...
		// Handle multitouch events
		// ...

	private:
		// Panda3D framework
		PandaFramework mFramework;
		WindowFramework *mWindow;

		// Game states
		QVector<gameState*> mStates;
};
//---------------------------------------------------------------------------
#endif // #ifndef PANDAGAMEENGINE_H

pandaGameEngine.cpp

//---------------------------------------------------------------------------
// Include Qt modules
#include <QtCore/QSettings>
#include <QtCore/QDir>
#include <QtCore/QFile>

//---------------------------------------------------------------------------
// Include Panda3D modules
#include "pandaFramework.h"
#include "pandaSystem.h"

//---------------------------------------------------------------------------
// Include game engine modules
#include "pandaGameEngine.h"

//-----------------------------------------------------------------------------------------------------
//																					  GAME ENGINE CLASS
//-----------------------------------------------------------------------------------------------------
//	Create ogreGameEngine object
//---------------------------------------------------------------------------
pandaGameEngine::pandaGameEngine(QSettings *settings) {
	// Load game engine settings
	mSettings = settings;
}
//---------------------------------------------------------------------------
//	Destroy ogreGameEngine object
//---------------------------------------------------------------------------
pandaGameEngine::~pandaGameEngine(void) {
	// Clean up all game states
	while (!mStates.empty()) {
		mStates.back()->exit();
		mStates.pop_back();
	}
	// Close Panda3D framework
	delete mWindow; mWindow = NULL;
	mFramework.close_framework();
}
//-----------------------------------------------------------------------------------------------------
//																					  START GAME ENGINE
//-----------------------------------------------------------------------------------------------------
//	Start game engine
//---------------------------------------------------------------------------
void pandaGameEngine::start(int argc, char *argv[]) {
	if (!setup(argc, argv)) { return; }	// Initialize engine

	/* Start the engine */
	mFramework.main_loop();
}
//-----------------------------------------------------------------------------------------------------
//																					  SETUP GAME ENGINE
//-----------------------------------------------------------------------------------------------------
//	Setup game engine
//---------------------------------------------------------------------------
bool pandaGameEngine::setup(int argc, char *argv[]) {
	// Load the window and set its title.
	mFramework.open_framework(argc, argv);
	mFramework.set_window_title("My Panda3D Window");
	WindowFramework *mWindow = mFramework.open_window();
	// Load the environment model.
	NodePath scene = mWindow->load_model(mFramework.get_models(), "data/models/environment");
	// Reparent the model to render.
	scene.reparent_to(mWindow->get_render());
	// Apply scale and position transforms to the model.
	scene.set_scale(0.25f, 0.25f, 0.25f);
	scene.set_pos(-8, 42, 0);

	return true;
};
//-----------------------------------------------------------------------------------------------------
//																					HANDLE INPUT EVENTS
//-----------------------------------------------------------------------------------------------------
// Keyboard events
//---------------------------------------------------------------------------
// ...
//---------------------------------------------------------------------------
// Handle mouse events
//---------------------------------------------------------------------------
// ...
//---------------------------------------------------------------------------
// Handle joystick events
//---------------------------------------------------------------------------
// ...
//---------------------------------------------------------------------------
// Handle multitouch events
//---------------------------------------------------------------------------
// ...
//-----------------------------------------------------------------------------------------------------
//																							GAME STATES
//-----------------------------------------------------------------------------------------------------
//	Change game state
//---------------------------------------------------------------------------
void pandaGameEngine::changeState(gameState *state) {
	// Cleanup the current state
	if (!mStates.empty()) {
		mStates.back()->exit();
		QObject::disconnect(mStates.back(), SIGNAL(changeState(gameState)), this, SLOT(changeState(gameState)));
		QObject::disconnect(mStates.back(), SIGNAL(pushState(gameState)), this, SLOT(pushState(gameState)));
		QObject::disconnect(mStates.back(), SIGNAL(popState()), this, SLOT(popState()));
		mStates.pop_back();
	}
	// Store and initialize the new state
	mStates.push_back(state);
	QObject::connect(mStates.back(), SIGNAL(changeState(gameState)), this, SLOT(changeState(gameState)));
	QObject::connect(mStates.back(), SIGNAL(pushState(gameState)), this, SLOT(pushState(gameState)));
	QObject::connect(mStates.back(), SIGNAL(popState()), this, SLOT(popState()));
	mStates.back()->enter();
}
//---------------------------------------------------------------------------
//	Push a new game state
//---------------------------------------------------------------------------
void pandaGameEngine::pushState(gameState *state) {
	// Pause current state
	if (!mStates.empty()) {
		mStates.back()->pause();
	}
	// Store and initialize the new state
	mStates.push_back(state);
	QObject::connect(mStates.back(), SIGNAL(changeState(gameState)), this, SLOT(changeState(gameState)));
	QObject::connect(mStates.back(), SIGNAL(pushState(gameState)), this, SLOT(pushState(gameState)));
	QObject::connect(mStates.back(), SIGNAL(popState()), this, SLOT(popState()));
	mStates.back()->enter();
}
//---------------------------------------------------------------------------
//	Pop previous game state
//---------------------------------------------------------------------------
void pandaGameEngine::popState(void) {
	// cleanup the current state
	if (!mStates.empty()) {
		mStates.back()->exit();
		QObject::disconnect(mStates.back(), SIGNAL(changeState(gameState)), this, SLOT(changeState(gameState)));
		QObject::disconnect(mStates.back(), SIGNAL(pushState(gameState)), this, SLOT(pushState(gameState)));
		QObject::disconnect(mStates.back(), SIGNAL(popState()), this, SLOT(popState()));
		mStates.pop_back();
	}
	// Resume previous state
	if (!mStates.empty()) {
		mStates.back()->resume();
	}
}

//---------------------------------------------------------------------------

OK, I’ve step into https://github.com/drivird/drunken-octo-robot examples and found a way to use classes. But now I get the reading violation when exiting…lol! I’ll search deeper…

The PandaFamework manages the WindowFramework object, so you should not attempt to delete the WindowFramework yourself. close_framework will do this for you.