How to create Irricht Device inside C++ Windows from ?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
yoes_san
Posts: 9
Joined: Mon Dec 11, 2006 7:22 am

How to create Irricht Device inside C++ Windows from ?

Post by yoes_san »

I'm pretty new in C++, so bear with me.

I already go through Win32Window tutorial and other C# posts in this forum , I understand that WindowID parameter at device creation are HWND or an EventReciever.

But when I use .Handle of VS2005 generated Control as a parameter for creating device, it throws error:

Code: Select all

error C2664: 'irr::createDevice' : cannot convert parameter 7 from 'System::Windows::Forms::PictureBox ^' to 'irr::IEventReceiver *'
So how can I get an EventReciever for specific PictureBox, or there're any other way to do this?

Here's my current source, without main() that called for the form:

Code: Select all

#pragma once

#include <irrlicht.h>

using namespace irr;

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

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


namespace interface_2 {

	/// <summary>
	/// Summary for form_main
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class form_main : public System::Windows::Forms::Form
	{
	public:
		form_main(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~form_main()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::TextBox^  textBox1;
	private: System::Windows::Forms::Panel^  panel_1;
	private: System::Windows::Forms::PictureBox^  pictureBox1;
	protected: 

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->textBox1 = (gcnew System::Windows::Forms::TextBox());
			this->panel_1 = (gcnew System::Windows::Forms::Panel());
			this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->BeginInit();
			this->SuspendLayout();
			// 
			// textBox1
			// 
			this->textBox1->Location = System::Drawing::Point(12, 12);
			this->textBox1->Name = L"textBox1";
			this->textBox1->Size = System::Drawing::Size(268, 20);
			this->textBox1->TabIndex = 0;
			// 
			// panel_1
			// 
			this->panel_1->Location = System::Drawing::Point(12, 38);
			this->panel_1->Name = L"panel_1";
			this->panel_1->Size = System::Drawing::Size(112, 216);
			this->panel_1->TabIndex = 1;
			// 
			// pictureBox1
			// 
			this->pictureBox1->Location = System::Drawing::Point(130, 38);
			this->pictureBox1->Name = L"pictureBox1";
			this->pictureBox1->Size = System::Drawing::Size(100, 50);
			this->pictureBox1->TabIndex = 2;
			this->pictureBox1->TabStop = false;
			// 
			// form_main
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(292, 266);
			this->Controls->Add(this->pictureBox1);
			this->Controls->Add(this->panel_1);
			this->Controls->Add(this->textBox1);
			this->Name = L"form_main";
			this->Text = L"form_main";
			this->Load += gcnew System::EventHandler(this, &form_main::form_main_Load);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	
	IrrlichtDevice *device; //Declare the device

	void runIrrlichtInWindowsFormTest(PictureBox^ c)
      {         
		 device = createDevice( video::EDT_DIRECT3D8, dimension2d<s32>(400, 350), 16, false, false, false, c->Handle);
	  } 

	private: System::Void form_main_Load(System::Object^  sender, System::EventArgs^  e) {

			runIrrlichtInWindowsFormTest(pictureBox1);

			 }
	};
}
TheC
Posts: 93
Joined: Fri May 05, 2006 7:50 am

Post by TheC »

I haven't had a good experience with .NET and C++

I know C# has a Control.Handle method/variable. So you should use the C++ equivalent. You just need to get the HWND of the picturebox, or of the window or button that you are parenting irrlicht to.
yoes_san
Posts: 9
Joined: Mon Dec 11, 2006 7:22 am

Post by yoes_san »

Ok, so I found an equivalent of .Handle to use with controls in C++ and now there're no errors when creating the device, but I'm not sure whether it actually created or not.

However, when compiled, it can get SceneManager, VideoDriver, can add SceneNode etc - but when call for device->run() loop, the form will not shown.

Here's a code for form_load, I copy everything after device created from tutorial 14, any opinions?:

Code: Select all

	IrrlichtDevice *device; 
	video::IVideoDriver* driver;
	drawSection* section;
	ISceneManager* smgr;
	

	private: System::Void form_main_Load(System::Object^  sender, System::EventArgs^  e) 
	{
				
			HWND hWnd=(HWND)this->pictureBox1->Handle.ToInt32(); //Get HWND of form
			
			SIrrlichtCreationParameters param;
			param.WindowId = reinterpret_cast<s32>(hWnd); // hColorButton
			param.DriverType = video::EDT_OPENGL;

			device = createDeviceEx(param);	

			// setup a simple 3d scene
			irr::scene::ISceneManager* smgr = device->getSceneManager();
			video::IVideoDriver* driver = device->getVideoDriver();

			scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
			cam->setTarget(core::vector3df(0,0,0));

			scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(core::vector3df(0,15,0), 30.0f);
			cam->addAnimator(anim);
			anim->drop();

			scene::ISceneNode* cube = smgr->addCubeSceneNode(20);

			cube->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
			cube->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
			cube->setMaterialFlag( video::EMF_LIGHTING, false );
			cube->setMaterialType( video::EMT_REFLECTION_2_LAYER );

			smgr->addSkyBoxSceneNode(
			driver->getTexture("../../media/irrlicht2_up.jpg"),
			driver->getTexture("../../media/irrlicht2_dn.jpg"),
			driver->getTexture("../../media/irrlicht2_lf.jpg"),
			driver->getTexture("../../media/irrlicht2_rt.jpg"),
			driver->getTexture("../../media/irrlicht2_ft.jpg"),
			driver->getTexture("../../media/irrlicht2_bk.jpg"));

			// show and execute dialog

			ShowWindow(hWnd , SW_SHOW);
			UpdateWindow(hWnd);
			
			//comment this loop out to show the form, otherwise nothing was shown
			while (device->run())
			{
				driver->beginScene(true, true, 0);
				smgr->drawAll();
				driver->endScene();
			}

			device->closeDevice();
			device->drop();
yoes_san
Posts: 9
Joined: Mon Dec 11, 2006 7:22 am

Post by yoes_san »

So, I found that the problem occurs because I called a loop in on_load event which will cause it to run device before drawing a form.

I changed to call for loop in other event and now it run fine.
Post Reply