Sign in to follow this  
jagguy2

visual c++ issues

Recommended Posts

Hi, I can use VC++/directx and have a few issues about understanding why we do things with it. Excuse for these basic questions but i am looking on google as we speak. q1) why use DWORD,HRESULT? why not use int or long? q2) why use TCHAR or w_tchar for strings and not string type? q3)assigning directx pointer to structures like this? I can't create such structure using c++ without using dynamic allocation. How can this work? LPDIRECT3D9 g_pD3D = NULL; q4)how can i keep track of how much primary memory i am using with a directx program . q5) using Vc++ with directx means you cant port to a linux or mac OS. Do those 2 OS use OpenGL for game play?

Share this post


Link to post
Share on other sites
A1) Using these inforces compliance with any future changes made to Win32. If Microsoft decide to change what an HRESULT is typedeffed as and you have used it throughout your application then you wont have to change so much. If however you have used the typedeffed type then that would need changing.

A2) You should use std::string and std::wstring wherever possible. However if you need to store a character from a std::wstring then you need to use a wchar_t variable instead of a char. TCHAR is typedeffed to an ascii or wide character depending on the project settings for the application.

A3) LPDIRECT3D9 is typedeffed as IDirect3D9*, so in fact you are assigning NULL to a pointer.

A4) I don't know if D3D has an interface for this.

A5) Windows supports D3D and OpenGL, mac supports OpenGL and so does Linux. You cannot use Direct3D on these platforms. If you wish to cater for multiple platforms then you have to look at writing the rendering code in a more generic mannor such that it can use either OpenGL or Direct3D depending on the target platform.

Hope that helps,

Share this post


Link to post
Share on other sites
thaks for the reply.
you seem to raise more questions for me , sorry.

1) why not use 'unsigned int' instead of DWORD or just an int? int is a standard type and why would this change? there are standard c++ types which I am confused as to why these are not used.

3)LPDIRECT3D9 is typedeffed as IDirect3D9*. i cant create a type def in c++ like this where i have pointer to struct? I need to use new keyword i believe but this works without dynamic allocation.

5) linux and mac cant use directx i believe, so they can only use OpenGL. Is this correct?

Share this post


Link to post
Share on other sites
Quote:
Original post by jagguy2
thaks for the reply.
you seem to raise more questions for me , sorry.

1) why not use 'unsigned int' instead of DWORD or just an int? int is a standard type and why would this change? there are standard c++ types which I am confused as to why these are not used.

3)LPDIRECT3D9 is typedeffed as IDirect3D9*. i cant create a type def in c++ like this where i have pointer to struct? I need to use new keyword i believe but this works without dynamic allocation.

5) linux and mac cant use directx i believe, so they can only use OpenGL. Is this correct?


1) Flexibility. While there is no foreseeable reason to actually change the type of a DWORD, should there ever be a reason, the change will be simple. If I were to write a whole library using int for things that should be returning a DWORD, then for whatever reason Win32 changes to use longs instead of ints then I would have to hunt out ever int in my library to fix it. If I had used DWORD then this would be no problem at all.

As a more realistic example, consider you write a math library, with vectors, matrices etc. You decide to use floats for everything, so your vector is just a structure of 3 floats, all its function take floats as arguments etc. Now, lets say that later during development, you decide that you would rather use doubles for more accuracy. You now have to go through your code changing all the floats to doubles. If you had just typedef'd a VectorUnit and used that instead of floats then you wouldn't have this trouble.

3) I don't understand what you are saying. There's nothing wrong with doing something like "typedef IDirect3D9* LPDIRECT3D9;" There's no issue of allocation here; typedefs are nothing more than a way to give datatypes pseudonyms.

5) That is correct. Windows can use both.

Share this post


Link to post
Share on other sites
hi,


3) if i create a structure in c++ and typedef it the same way with a pointer i am getting an error. So i didnt know how directx can create this.
Also with a structure why do i not need dynamic allocation because the pointer LPDIRECT3D9 g_pD3D hasnt been allocated space. Or do structures work differently to classes/objects for allocating space dynamically?

5) to code for linux and mac i cant use directx so this is a big market share you miss out on.

6) most tutorials i see have managed c++ or c#. Is coding with directx these days usually done with managed c++ and c#? I am just using unmanaged code and c++

Share this post


Link to post
Share on other sites
You aren't typedeffing a struct to a pointer, you never created the struct.

DirectX was created when windows needed graphics on it, it wasn't possible to create games for windows till then, later on OpenGL was created for windows, since windows didn't create it, mac didn't create it and I guess the people who created wasn't from linux community, OpenGL was meant for all the three systems. Microsoft will never port DirectX to mac or linux anyday, and mac and linux don't care about windows.

And this is stuff you shouldn't care about anyway. Follow the standards, know which system works on which OS and be happy :)

Share this post


Link to post
Share on other sites
q1) here are some examples which confuse me with directx

i tried in console program to replicate what is in directx program


DWORD *i = 0;
DWORD *j = new DWORD; //works fine if i print out

i[0]=11;
//i[1]=22;


cout << i[0] <<endl; //error access violation



//in directx
DWORD* attributeBuffer2 = 0;
g_mesh2->LockAttributeBuffer(0, &attributeBuffer2);

for(int a = 0; a < 4; a++)
attributeBuffer2[a] = 0; //works fine


/////////
//
q2)
in directx i can do this
LPDIRECT3D9 g_pD3D ;

//but i cant replicate this with typdef


struct Myone
{ int a;
char b;
};

typedef struct Myone aa;
typedef struct Myone *bb;

int main(int argc, char *argv[])
{
aa two;
bb three;

two.a =6;
three->a =8; //error as not not being defined as i didnt use new
so how does directx do it?


cout << two.a <<endl;
cout << three->a <<endl;

Share this post


Link to post
Share on other sites
Look at the signature of the D3DX function.

It doesn't access the address you're pointing to (zero). It takes the pointer variable and assigns a different address to it (probably some internal address). This internal address itself will probably be newed (or point to a static context). That's why there's also a UnlockAttributeBuffer function; to cleanup (and thus invalidate) the memory it allocated.


q2)
DirectX never does this, there's always some function before that will return a LPDIRECTsomething to you. This will allocate the memory internally.

There's nothing magic that DirectX does, it's a necessary evil probably stemming from the different heaps (DirectX resides in a DLL). This means, since DirectX is allocating the objects it also has to release them.

Think of the IDirect-somethings as abstract interfaces. They themselved cannot be instanciated. Every driver will create a derived object but only pass out the interface.

Share this post


Link to post
Share on other sites
q2)I am confused about q2). In the declaration i see this and i dont see anything before this to allocate memory. I need to read up on interfaces as well s this has thrown me.


typedef struct IDirect3D9 *LPDIRECT3D9

q3) something like this below will pass in the pointer to structure (one structure)and return it with space allocated for an array of structures? . I am confused by this.

//vertex is a structure i define.
Vertex *vert;
g_mesh->LockVertexBuffer(0, (void**)&vert);

[Edited by - jagguy2 on January 1, 2008 1:01:11 AM]

Share this post


Link to post
Share on other sites
About q2)

This typedef struct does not allocate memory. It only creates a new type that happens to be a pointer. See it simply as a variable that points to a IDirect3D9 interface.

typedef struct IDirect3D9 *LPDIRECT3D9

The real allocation happens when you call

IDirect3D9 * Direct3DCreate9(
UINT SDKVersion
);



q3) something like this below will pass in the pointer to structure (one structure)and return it with space allocated for an array of structures? . I am confused by this.

//vertex is a structure i define.
Vertex *vert;
g_mesh->LockVertexBuffer(0, (void**)&vert);


Exactly. You pass it an empty contact sheet which has just enough empty space to hold an address.
LockVertexBuffer allocates the memory, writes the address of that memory on your sheet and passes it back to you.

UnlockVertexBuffer releases that memory. After this you still have a sheet with an address, but the address doesn't point to anything valid anymore.

Share this post


Link to post
Share on other sites
ok it is making more sense now but i admit i have much more to know.
I wont ask many more questions as this wil go on for days.


q)D3DXMATERIAL* mtrls = (D3DXMATERIAL*)g_mtrlBuffer->GetBufferPointer();

here we are not using a create function but an assignment to another pointer but neither has been created on the heap

q)creating objects at run time means i need dynamic allocation and is using a std::vector ideal for this eg spawn another ememy etc

Share this post


Link to post
Share on other sites
Quote:
Original post by jagguy2
ok it is making more sense now but i admit i have much more to know.
I wont ask many more questions as this wil go on for days.


q)D3DXMATERIAL* mtrls = (D3DXMATERIAL*)g_mtrlBuffer->GetBufferPointer();

here we are not using a create function but an assignment to another pointer but neither has been created on the heap

q)creating objects at run time means i need dynamic allocation and is using a std::vector ideal for this eg spawn another ememy etc



a1)
I presume that the material buffer (which is derived from ID3DXBuffer) works like this internally:


class D3DXMaterialBuffer : public ID3DXBuffer
{
private: // could be public as well, doesn't matter, as you only get a ID3DXBuffer pointer

D3DXMATERIAL m_InternalBuffer;

LPVOID GetBufferPointer()
{
return (LPVOID)&m_InternalBuffer;
}
};


But it could also use dynamic allocation:

class D3DXMaterialBuffer : public ID3DXBuffer
{
private: // could be public as well, doesn't matter, as you only get a ID3DXBuffer pointer

D3DXMATERIAL* m_pInternalBuffer;

D3DXMaterialBuffer()
{
m_pInternalBuffer = new D3DXMATERIAL();
}

~D3DXMaterialBuffer()
{
delete m_pInternalBuffer;
}

LPVOID GetBufferPointer()
{
return (LPVOID)m_pInternalBuffer;
}
};


In the end it does not matter how it is implemented. You have an interface which will return a pointer to you. You can use the data the pointer points to.
You MUST not call delete on the pointer.

There is no need for dynamic allocation inside, but there could as well be. It does not matter to you.

The object that is pointed to is probably created while the ID3DXBuffer is created for you.

You need to note the concept:
A pointer is just a sheet with an address on it. It can point to something useful, but can also point to some random data (e.g. invalid).

a2)
Lots of the STL containers can be used, most common for this are std::list and std::vector.
It does not matter for the STL container how it's content was created.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this