Calling a function of d3d

Class setup but can not pass needed parameter

  • (2 Pages)
  • +
  • 1
  • 2

26 Replies - 1773 Views - Last Post: 16 June 2010 - 12:35 PM Rate Topic: -----

#1 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Calling a function of d3d

Posted 15 June 2010 - 07:06 AM

I have set up multiple classes in a project that uses a d3dUtility .h and .cpp file. In main, when I go to use one of the d3d functions listed below, I can not seem to pass in my display from a different class. I am missing something integral, just don't know what it is. This is the d3dUtility.cpp function I am wrestling with.
int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
	MSG msg;
	::ZeroMemory(&msg, sizeof(MSG));

	static float lastTime = (float)timeGetTime(); 

	while(msg.message != WM_QUIT)
	{
		if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
		else
        {	
			float currTime  = (float)timeGetTime();
			float timeDelta = (currTime - lastTime)*0.001f;

			ptr_display(timeDelta);

			lastTime = currTime;
        }
    }
    return msg.wParam;
}



And here is the use of that function in main.cpp the way it was originally used before I started breaking things into separate classes.

d3d::EnterMsgLoop(Display);



And here is the class function that was spaghetti'ed in before I started to organize things. I think I am supposed to pass it in differently, but I have tried:

myLight.Display(timeGetTime)
&directionalLight::Display(timeGetTime)



Here is the function
bool directionalLight::Display(float timeDelta)
{
	if( Device )
	{
		// 
		// Update the scene: update camera position.
		//

		static float angle  = (3.0f * D3DX_PI) / 2.0f;
		static float height = 5.0f;
	
		if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
			angle -= 0.5f * timeDelta;

		if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
			angle += 0.5f * timeDelta;

		if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
			height += 5.0f * timeDelta;

		if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
			height -= 5.0f * timeDelta;

		D3DXVECTOR3 position( cosf(angle) * 7.0f, height, sinf(angle) * 7.0f );
		D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
		D3DXMATRIX V;
		D3DXMatrixLookAtLH(&V, &position, &target, &up);

		Device->SetTransform(D3DTS_VIEW, &V);

		//
		// Draw the scene:
		//
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
		Device->BeginScene();

		for(int i = 0; i < 4; i++)
		{
			// set material and world matrix for ith object, then render
			// the ith object.
			Device->SetMaterial(&Mtrls[i]);
			Device->SetTransform(D3DTS_WORLD, &Worlds[i]);
			Objects[i]->DrawSubset(0);
		}

		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}



Any help would be appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Calling a function of d3d

#2 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 07:12 AM

Are you getting any errors? Please post them as-well. It helps us a lot, especially when we can't compile the code.
Was This Post Helpful? 0
  • +
  • -

#3 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 07:20 AM

View Postsarmanu, on 15 June 2010 - 06:12 AM, said:

Are you getting any errors? Please post them as-well. It helps us a lot, especially when we can't compile the code.

Yes, here are the errors I am getting:
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\main.cpp(49) : error C2597: illegal reference to non-static member 'directionalLight::Device'
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\main.cpp(49) : error C2065: 'timeDelta' : undeclared identifier
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\main.cpp(49) : error C2664: 'd3d::EnterMsgLoop' : cannot convert parameter 1 from 'bool' to 'bool (__cdecl *)(float)'
1>        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast


Was This Post Helpful? 0
  • +
  • -

#4 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 07:54 AM

Well, to create a pointer to the member function Display, you would have to do something like this:
// Declare the function pointer:
bool (directionalLight::*my_func_ptr) = &directionalLight::Display;

// Call EnterMsgLoop with the pointer to member function.
// If EnterMsgLoop is non-static member use this:
d3d my_class;
my_class.EnterMsgLoop(my_func_ptr);

// If EnterMsgLoop is static member, use this:
d3d::EnterMsgLoop(my_func_ptr);


Now, that you have my_func_ptr a pointer to Display member function, you need to play with it. Your EnterMsgLoop member function should look like this:
// Pass pointer to member function, remember! The name of the object must be here
// too
int d3d::EnterMsgLoop(bool (directionalLight::*my_func_ptr)(float))
{
    // And now, make use of my_func_ptr:
    directionalLight light;
    
    // more code below ...
    
    // Calculate your timeDelta
    float timeDelta = (currTime - lastTime)*0.001f;
    // Since you deal with pointer to BOOL member function, then let's
    // use bool as result:
    bool result = (light.*my_func_ptr)(timeDelta);
   
    // Do whatever you want based on "result"

    // more code below ...
}


PS: make sure that d3d class recognizes directionalLight class.
See this link for more info.

This post has been edited by sarmanu: 15 June 2010 - 08:03 AM

Was This Post Helpful? 0
  • +
  • -

#5 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:16 AM

Alright, I think I am following you. I am just having a hard time understanding where I would need to declare:
bool (directionalLight::*my_func_ptr) = &directionalLight::Display; 


I understand that I am declaring a pointer, but where in the code should I declare it? Main.cpp?
Was This Post Helpful? 0
  • +
  • -

#6 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:18 AM

It doesn't really matter. You can declare it inside your main() function. You can declare it in another function, and then call that function in main(). It doesn't matter (but of course, don't declare it somewhere in d3d or directionalLight class). Take a look at this example, maybe it helps you understand the structure:
#include <iostream>

class Y
{
public:
	Y() { }
	bool myMethod(float x){ return ((x >= 10) ? true : false); }
};

class X
{
public:
	X() { }

	static void method(bool (Y::*my_func)(float)) 
	{
		Y y;
		bool res = (y.*my_func)(11);

		std::cout << std::boolalpha << res;
	}
};

int main()
{
	bool (Y::*my_func)(float) = &Y::myMethod;

	X::method(my_func);

	return 0;
}


This post has been edited by sarmanu: 15 June 2010 - 08:22 AM

Was This Post Helpful? 0
  • +
  • -

#7 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:25 AM

View Postsarmanu, on 15 June 2010 - 06:54 AM, said:

Well, to create a pointer to the member function Display, you would have to do something like this:
// Declare the function pointer:
bool (directionalLight::*my_func_ptr) = &directionalLight::Display;

// Call EnterMsgLoop with the pointer to member function.
// If EnterMsgLoop is non-static member use this:
d3d my_class;
my_class.EnterMsgLoop(my_func_ptr);

// If EnterMsgLoop is static member, use this:
d3d::EnterMsgLoop(my_func_ptr);


Now, that you have my_func_ptr a pointer to Display member function, you need to play with it. Your EnterMsgLoop member function should look like this:
// Pass pointer to member function, remember! The name of the object must be here
// too
int d3d::EnterMsgLoop(bool (directionalLight::*my_func_ptr)(float))
{
    // And now, make use of my_func_ptr:
    directionalLight light;
    
    // more code below ...
    
    // Calculate your timeDelta
    float timeDelta = (currTime - lastTime)*0.001f;
    // Since you deal with pointer to BOOL member function, then let's
    // use bool as result:
    bool result = (light.*my_func_ptr)(timeDelta);
   
    // Do whatever you want based on "result"

    // more code below ...
}


PS: make sure that d3d class recognizes directionalLight class.
See this link for more info.



I am having trouble finding a place to declare the pointer that does not give me the following error:
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\d3dutility.cpp(17) : error C2440: 'initializing' : cannot convert from 'bool (__thiscall directionalLight::* )(float)' to 'bool directionalLight::* '
1>        There is no context in which this conversion is possible



I originally thought it would be good to declare it in d3dUtility.h and then use it in the d3dUtility.cpp but I keep getting the same error. Any ideas?
Was This Post Helpful? 0
  • +
  • -

#8 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:30 AM

You did something wrong. How did you declare it? How did you call it? Did you take a look at my last post? And I don't recommend it to be declared in a header file. Just declare where you need it.
EDIT: Is Display a static member function?

This post has been edited by sarmanu: 15 June 2010 - 08:33 AM

Was This Post Helpful? 0
  • +
  • -

#9 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:42 AM

View Postsarmanu, on 15 June 2010 - 07:30 AM, said:

You did something wrong. How did you declare it? How did you call it? Did you take a look at my last post? And I don't recommend it to be declared in a header file. Just declare where you need it.
EDIT: Is Display a static member function?

Thank you so much for your help with this, by the way, I really appreciate it.

Alright, I declared it globally in d3dUtility.cpp and then changed the d3dUtility function to use my-func_ptr like you suggested. It doesn't matter where I declare it, I keep getting the same error, believe me I have tried it all over the place. :) Here is the display function which is in directionalLight class.
bool directionalLight::Display(float timeDelta)
{
	if( Device )
	{
		// 
		// Update the scene: update camera position.
		//

		static float angle  = (3.0f * D3DX_PI) / 2.0f;
		static float height = 5.0f;
	
		if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
			angle -= 0.5f * timeDelta;

		if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
			angle += 0.5f * timeDelta;

		if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
			height += 5.0f * timeDelta;

		if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
			height -= 5.0f * timeDelta;

		D3DXVECTOR3 position( cosf(angle) * 7.0f, height, sinf(angle) * 7.0f );
		D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
		D3DXMATRIX V;
		D3DXMatrixLookAtLH(&V, &position, &target, &up);

		Device->SetTransform(D3DTS_VIEW, &V);

		//
		// Draw the scene:
		//
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
		Device->BeginScene();

		for(int i = 0; i < 4; i++)
		{
			// set material and world matrix for ith object, then render
			// the ith object.
			Device->SetMaterial(&Mtrls[i]);
			Device->SetTransform(D3DTS_WORLD, &Worlds[i]);
			Objects[i]->DrawSubset(0);
		}

		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}


It's not static, just a regular old public function of the class. I am just not understanding pointers well enough to figure out why it won't declare it to the function. So, in essence you are saying: hey, here is a pointer to the Display function. Then you want to use that pointer in d3dUtility for the enterMsg function, then in main when we call the function we are saying and don't forget to use the directionalLight pointer that we created for the display. Is that the idea?
Was This Post Helpful? 0
  • +
  • -

#10 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 08:46 AM

Yes. It's not that complicated. And I'd be happy to help if you would post the entire project. Is it that big?
PS: If you decide to post it, please post it as it is right now (including with the func. ptr declaration of yours), so I can actually tell you what's wrong with your modification.

This post has been edited by sarmanu: 15 June 2010 - 08:50 AM

Was This Post Helpful? 0
  • +
  • -

#11 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 09:06 AM

View Postsarmanu, on 15 June 2010 - 07:46 AM, said:

Yes. It's not that complicated. And I'd be happy to help if you would post the entire project. Is it that big?
PS: If you decide to post it, please post it as it is right now (including with the func. ptr declaration of yours), so I can actually tell you what's wrong with your modification.


Here is the project in its entirety. Thanks again for helping me understand this. :)

Attached File(s)


Was This Post Helpful? 0
  • +
  • -

#12 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 09:15 AM

In d3dUtility.cpp, you had:
bool (directionalLight::*my_func_ptr) = &directionalLight::Display;


which is not correct. You forgot the argument type of pointer to member function. Should be:
bool (directionalLight::*my_func_ptr)(float) = &directionalLight::Display;


But why is this global? Just remove it from here, and place it in your WinMain function. Also, directionalLight myLight; is global in main.cpp, why? I recommend you to place this in WinMain too. WinMain overall should look like this:
int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE prevInstance, 
				   PSTR cmdLine,
				   int showCmd)
{
	
	directionalLight myLight;
	if(!d3d::InitD3D(hinstance,
		myLight.Width,myLight.Height, true, D3DDEVTYPE_HAL, &myLight.Device))
	{
		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
		return 0;
	}
		
	if(!myLight.Setup())
	{
		::MessageBox(0, "Setup() - FAILED", 0, 0);
		return 0;
	}

	
	bool (directionalLight::*my_func_ptr)(float) = &directionalLight::Display;
	d3d::EnterMsgLoop(my_func_ptr); 
	myLight.Cleanup();

	myLight.Device->Release();

	return 0;
}



Now, regarding EnterMsgLoop function, just read my second post on this thread, and you will get it to compile.
EDIT: damn, now I see that it was me who forgot that (float), in first place. Sorry about this, it happens when I can't test code. Sorry again for typo.

This post has been edited by sarmanu: 15 June 2010 - 09:40 AM

Was This Post Helpful? 0
  • +
  • -

#13 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 09:44 AM

View Postsarmanu, on 15 June 2010 - 08:15 AM, said:

In d3dUtility.cpp, you had:
bool (directionalLight::*my_func_ptr) = &directionalLight::Display;


which is not correct. You forgot the argument type of pointer to member function. Should be:
bool (directionalLight::*my_func_ptr)(float) = &directionalLight::Display;


But why is this global? Just remove it from here, and place it in your WinMain function. Also, directionalLight myLight; is global in main.cpp, why? I recommend you to place this in WinMain too. WinMain overall should look like this:
int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE prevInstance, 
				   PSTR cmdLine,
				   int showCmd)
{
	
	directionalLight myLight;
	if(!d3d::InitD3D(hinstance,
		myLight.Width,myLight.Height, true, D3DDEVTYPE_HAL, &myLight.Device))
	{
		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
		return 0;
	}
		
	if(!myLight.Setup())
	{
		::MessageBox(0, "Setup() - FAILED", 0, 0);
		return 0;
	}

	
	bool (directionalLight::*my_func_ptr)(float) = &directionalLight::Display;
	d3d::EnterMsgLoop(my_func_ptr); 
	myLight.Cleanup();

	myLight.Device->Release();

	return 0;
}



Now, regarding EnterMsgLoop function, just read my second post on this thread, and you will get it to compile.
EDIT: damn, now I see that it was me who forgot that (float), in first place. Sorry about this, it happens when I can't test code. Sorry again for typo.


You are a rockstar! Alright, got it almost there, still having trouble getting the member function to work.
int d3d::EnterMsgLoop(bool (directionalLight::*my_func_ptr)(float)) 
{
	directionalLight myLight;
	
	MSG msg;
	::ZeroMemory(&msg, sizeof(MSG));

	static float lastTime = (float)timeGetTime(); 

	while(msg.message != WM_QUIT)
	{
		if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
		else
        {	
			float currTime  = (float)timeGetTime();
			float timeDelta = (currTime - lastTime)*0.001f;
 

			my_func_ptr(timeDelta);

			lastTime = currTime;
        }
    }
    return msg.wParam;
}


What am I doing wrong here? I proto'd the function this way in d3dUtility.h.
int EnterMsgLoop( 
		bool (directionalLight::*my_func_ptr)(float)); 



I am so close I can feel it!
Was This Post Helpful? 0
  • +
  • -

#14 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Calling a function of d3d

Posted 15 June 2010 - 09:51 AM

my_func_ptr(timeDelta);


This call is wrong, since my_func_ptr is dependant on directionalLight. So, you need an object of directionalLight to make the call. Since you use myLight in main.cpp, let's pass this to our function:
// Second parameter is the object.
int d3d::EnterMsgLoop( bool (directionalLight::*my_func_ptr)(float), directionalLight &light )


and call my_func_ptr inside EnterMsgLoop:
(light.*my_func_ptr)(timeDelta);



Now, in main.cpp, you have to call:
d3d::EnterMsgLoop(my_func_ptr, myLight); 



PS: don't forget to modify the function prototype of EnterMsgLoop too.
PS2: I hope you understood the change, all I did is to pass myLight from main.cpp to your function.
PS3: Are you sure you want to deal with function pointers, if you say you don't handle them very well? It could be easier without them, for you.

This post has been edited by sarmanu: 15 June 2010 - 09:58 AM

Was This Post Helpful? 1
  • +
  • -

#15 Scorpiobuzz  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 66
  • Joined: 06-February 09

Re: Calling a function of d3d

Posted 15 June 2010 - 10:09 AM

View Postsarmanu, on 15 June 2010 - 08:51 AM, said:

my_func_ptr(timeDelta);


This call is wrong, since my_func_ptr is dependant on directionalLight. So, you need an object of directionalLight to make the call. Since you use myLight in main.cpp, let's pass this to our function:
// Second parameter is the object.
int d3d::EnterMsgLoop( bool (directionalLight::*my_func_ptr)(float), directionalLight &light )


and call my_func_ptr inside EnterMsgLoop:
(light.*my_func_ptr)(timeDelta);



Now, in main.cpp, you have to call:
d3d::EnterMsgLoop(my_func_ptr, myLight); 



PS: don't forget to modify the function prototype of EnterMsgLoop too.
PS2: I hope you understood the change, all I did is to pass myLight from main.cpp to your function.
PS3: Are you sure you want to deal with function pointers, if you say you don't handle them very well? It could be easier without them, for you.


Yeah, I want to learn how do it right, I can trace the way you are working them, and it makes sense, I have a few more classes to add to the project and that is where I will get my real practice in. I need to know how to do it. :) Thanks for your instruction and patience with me, I appreciate it and will pass it on. :)

It's still not compiling, but the problem has changed.
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\directionallight.cpp(163) : error C2758: 'directionalLight::Width' : must be initialized in constructor base/member initializer list
1>        c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\directionallight.h(19) : see declaration of 'directionalLight::Width'
1>c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\directionallight.cpp(163) : error C2758: 'directionalLight::Height' : must be initialized in constructor base/member initializer list
1>        c:\users\william\documents\visual studio 2008\projects\laws_wk4_3d_assignment\laws_wk4_3d_assignment\directionallight.h(20) : see declaration of 'directionalLight::Height'


I am guessing this has to do with the fact that in directionalLight.h I just have a simple constructor
directionalLight()


I am going to need something fancier, aren't I?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2