[Irrlicht] Hallo Welt-Beispiel funktioniert nicht

Kümmelkorn

Kümmelkorn

Aktives Mitglied
Thread Starter
Dabei seit
06.10.2008
Beiträge
1.941
Reaktionspunkte
127
Hallo Welt!*

Ich würde mich gern ein wenig in die Irrlicht-Engine einarbeiten, aber wie das leider nicht selten der Fall ist, funktioniert erst mal wieder gar nix...

Ich habe mir die Irrlicht-Engine heruntergeladen, die Bibliothek komplimiert und mir ein Projekt eingerichtet, wie es in einer Online-Anleitung stand. Da das mitgelieferte HalloWelt-Beispiel sehr Windowsfokussiert ist, nutze ich als Quellcode eine Mischung aus eben diesem mitgelieferten HalloWelt-Beispiel und der gerade verlinkten Online-Anleitung. (Quellcode siehe unten).

Leider gibt es nach wie vor zwei Probleme:

  1. Selbst wenn ich mich auf den Kopf stelle und weine: Die Textur des Meshs wird und wird nicht geladen... jedenfalls erscheint das Mesh in weiß, genau so, als würde ich den Befehl für das Laden der Textur einfach weglassen! (Der Befehl ist unter der Zeile, die ich mit // -- PROBLEM -- markiert habe)
  2. Wenn ich das im HalloWelt-Beispiel genutze GUIEnviroment einsetze, verhaut es mir das komplette Beispielmesh, sodass ich gar nichts mehr sehe außer ein paar blinkenden Pixeln links oben und dem Zeugs im GUIEnviroment.

Der von mir genutzte Quellcode sieht in der aktuellsten Version so aus:
Code:
#include <OpenGL/OpenGL.h>
#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
/*
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#else*/
#pragma comment(lib, "libIrrlicht.a")
/*#endif*/

// resPath returns the Path for a resource file "file"
char * resPath( char** argv, char* file )
{
    // returns the path to the "Resources" directory
	char	tempPath[1024];
	strncpy( tempPath, argv[0], 1023 );
	int	x = strlen(tempPath) -1;
	while( tempPath[x] != '/' && x > 0 )
		tempPath[x--] = 0;
	
	strncat( tempPath, "../Resources/", 1023 );
	return strncat( tempPath, file, 1023 );
}


int main(int argc, char** argv)
{
	// setting up the device
	IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2d<s32>(512, 384), 16, false, false, false, 0);
	device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
	
	// getting the driver and scenemanager
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	
	// if I include the GUI Enviroment, the sample mesh will dissapear, if a texture is loaded
	//IGUIEnvironment* guienv = device->getGUIEnvironment();
	//guienv->addStaticText(L"Hello World! This is the Irrlicht Software engine!", rect<s32>(10,10,200,22), true);
	
	// loading the mesh works great
	IAnimatedMesh* mesh = smgr->getMesh(resPath(argv,"sydney.md2") );
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
	
	if (node) {
		// setting the lighting to true hides the complete scene, as espected
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(0, 310);
		
		
// -- PROBLEM --

		// so here is the problem: there is no error message, but the mesh displays in white without any texture!
		node->setMaterialTexture( 0, driver->getTexture(resPath(argv,"sydney.bmp")) );
	}
	
	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
	
	while(device->run()) {
		driver->beginScene(true, true, SColor(255,100,101,140));
		smgr->drawAll();
		//guienv->drawAll();
		driver->endScene();
	}
	
	device->drop();
	return 0;
}


*ok, der witz war extrem doof, musste aber mal sein
 
Bist du sicher, dass der erste Parameter von diesem setTexture() ein Array und nicht einfach einen Pointer auf den Pfad in dem das Programm liegt benötigt?
argv ist nämlich ein zwei-dimensionales char-Array in dem die Aufrufeparamter des Programm liegen. Dabei ist der 1. Eintrag des Arrays gleich dem Verzeichnis in dem das Programm ausgeführt wird.
 
  • Gefällt mir
Reaktionen: Kümmelkorn
Ich habe gerade mal in der Irrlicht Dokumentation nachgeschaut: Der Parameter ist als const c8 deklariert, wobei c8 für einen 8-bit char steht. Müsste also passen.


Allerdings bin ich trotzdem einen Schritt weiter: Das Problem scheint darin zu liegen, dass Irrlicht die Dateien im Ordner Resource nicht findet!

Wenn ich mein kompiliertes Programm nämlich aus dem Terminal heraus starte, findet Irrlicht nicht einmal das Mesh (die .md2 Datei). Selbst wenn ich den Pfad manuell eingebe (also IAnimatedMesh* mesh = smgr->getMesh("../Resources/sydney.md2" );).

Kann mir jemand sagen, wie man in OS X Anwendungen mit C/C++ auf die Resource-Dateien zugreifen kann? Meine Executable liegt ja in MyApp.app/Contents/MacOS/MyApp, mein Resources-Ordner liegt in MyApp.app/Contents/Resources. Der Resources Ordner enthält meine sydney.md2 und sydney.bmp.

Ein relativer Pfad "../Resources/sydney.md2" funktioniert leider nicht. Was soll ich denn stattdessen tun?

lieben Gruß, Micha
 
  • Gefällt mir
Reaktionen: Kümmelkorn
Hallo,

vielen Dank für den Hinweis, der hat mich schon mal ein gutes Stück vorwärts gebracht! Laut Terminalausgabe werden nun alle Dateien ordentlich gefunden und geladen (jedenfalls steht dort "mesh loaded" und "texture loaded").

Leider gibt es weiterhin zwei Probleme:

  1. Trotz scheinbar erfolgreichem laden bleibt das 3D Objekt weiß, die Textur wird nicht angezeigt.
  2. bei der Zeile, die ich mit // --- WARNUNG --- markiert habe, erscheint in Xcode beim compilieren immer eine Warnmeldung: warning: adress of local variable 'resource' returned. Leider bin ich nicht so fit in Zeigern. Was bedeutet die Warnung? In der Zeile deklariere ich doch nur einen Zeiger? Da wird doch gar nix returned?


Mein aktueller Quellcode sieht wie folgt aus:

Code:
#include <OpenGL/OpenGL.h>
#include <Carbon/Carbon.h>
#include <CoreFoundation/CFBundle.h>
#include <CoreFoundation/CFString.h>
#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "libIrrlicht.a")

// function provides some Mac OS X specific source code to load files from the resources of the application bundle.
char * resPath(char **argv, char* name, char* type ) 
{




	char resource[1024]; // --- WARNUNG --- 




	
	CFURLRef cfBundleURL = CFBundleCopyResourceURL( CFBundleGetMainBundle(),	 
							   CFStringCreateWithCString(kCFAllocatorDefault,
											 name, 
											 kCFStringEncodingISOLatin1), 
							   CFStringCreateWithCString(kCFAllocatorDefault, 
											 type, 
											 kCFStringEncodingISOLatin1), 
							   NULL );
	
	
	CFStringGetCString( CFURLCopyPath(cfBundleURL),
			    resource,
			    1023,
			    kCFStringEncodingISOLatin1);
	
	return resource;
}

int main(int argc, char** argv)
{
	IrrlichtDevice *device = createDevice(EDT_OPENGL, 
						 dimension2d<s32>(512, 384), 
						  16,
						  false, 
						  false, 
						  false, 
						  0);
	device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
	
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	
	IAnimatedMesh* mesh = smgr->getMesh( resPath(argv, "sydney", "md2") );
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
	
	if (node) 
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(0, 310);
		
		// -- PROBLEM -- Irrlicht still displays just a white mesh without texture!
		node->setMaterialTexture( 0, driver->getTexture( resPath(argv, "sydney", "bmp") ));
	}
	
	smgr->addCameraSceneNode(0, 
				 vector3df(0,30,-40), 
				 vector3df(0,5,0));
	
	while(device->run()) 
	{
		driver->beginScene(true, 
				   true, 
				   SColor(255,100,101,140));
		smgr->drawAll();
		driver->endScene();
	}
	
	device->drop();
	return 0;
}
 
Zuletzt bearbeitet:
Hab die Lösung gefunden: Meine ATI Radeon X1600 unterstützt keine sog. NPOT-Texturen (No-Power of two = nicht-quadratisch). Ein simples anpassen der Texturedatei und das Problem war gelöst :)

Trotzdem danke für eure Hilfe - insbesondere CFBundle, das kann man immer gebrauchen :)
 
Zurück
Oben Unten