• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
cozzie

Passing d3d device by reference

13 posts in this topic

Hi,

Would there be any risk in passing a d3d device as a const reference to a function?

To be specific:

 

LPDIRECTDDEVICE9 myDev is basically a pointer: *IDIRECT3DDEVICE9

 

A function used the device for d3d functions as parameter, but doesn't alter the d3d device itself, thats why I think it should be possible.

It compiles and runs, but just curious if it's 'OK'.

 

Example:

 

bool CreateTextures(const LPDIRECTDDEVICE9 &pd3ddev)

{

   D3DXCreateTextureFromFile(......., pd3ddev);

}

0

Share this post


Link to post
Share on other sites
You can do it, but it's fairly pointless. If you're using raw pointers than you might as well pass by value. Using a const reference doesn't give you any benefit here.
0

Share this post


Link to post
Share on other sites

Passing a IDirect3DDevice9 as const should generally cause a compiler error as subsequent usage of that device won't match the signature in the d3d9.h header file.

 

As an example, a "CreateVertexShader" routine you might write that takes the device as a parameter won't compile if the device is passed as const, and will specifically fail on this line:

Device->CreateVertexShader (....

And with this error:

 

error C2662: 'IDirect3DDevice9::CreateVertexShader' : cannot convert 'this' pointer from 'const IDirect3DDevice9' to 'IDirect3DDevice9 &'

 

As an additional consideration, any well-written D3DX function that obeys the rules of COM will increment the reference count on the device (via AddRef) on entry and decrement it (via Release) on exit, so the D3DX function will modify the device.  Also, you can infer that any Device->Create call also increments the reference count on the device from the fact that the device will also leak if the created resource leaks.

0

Share this post


Link to post
Share on other sites
A [tt]const LPDIRECTDDEVICE9 &[/tt] isn't a [tt]const IDirect3DDevice9 * &[/tt], it's a [tt]IDirect3DDevice9 * const &[/tt]. The pointer is [tt]const[/tt], not what is pointed to.
0

Share this post


Link to post
Share on other sites

A [tt]const LPDIRECTDDEVICE9 &[/tt] isn't a [tt]const IDirect3DDevice9 * &[/tt], it's a [tt]IDirect3DDevice9 * const &[/tt]. The pointer is [tt]const[/tt], not what is pointed to.

 

True, my bad.

 

It still won't compile though.

0

Share this post


Link to post
Share on other sites
Are you sure about that? This compiles fine for me:
#include <d3d9.h>

void foo(const LPDIRECT3DDEVICE9 & ptr) {
  ptr->AddRef();
  ptr->CreateVertexShader(0, 0);
  ptr->Release();
}
Again, the pointer is const. What is pointer is pointing to isn't.
0

Share this post


Link to post
Share on other sites

Are you sure about that? This compiles fine for me:

#include <d3d9.h>

void foo(const LPDIRECT3DDEVICE9 & ptr) {
  ptr->AddRef();
  ptr->CreateVertexShader(0, 0);
  ptr->Release();
}
Again, the pointer is const. What is pointer is pointing to isn't.

 

 

Ah, OK.  I tested with "const IDirect3DDevice9 &" which does fail with the error I mentioned (as does "const IDirect3DDevice9 *").  It's not the constness that causes that failure, it's the signatures not matching.

Edited by mhagain
0

Share this post


Link to post
Share on other sites
No, that is the const causing the failure. When you have a const IDirect3DDevice9 *, the IDirect3DDevice9 object pointed to is const, so you can't call non-const member functions like CreateVertexShader(), AddRef() and Release().
0

Share this post


Link to post
Share on other sites
Ok, so what I'm basically doong is making the pointer const,cso it cant point anywhere else.
This basically doesn't do anything (needed).

Would I still be able to execute functions on the d3d device if I made the 'device' it points too, const?
( and how should I do that)

On the other hand, what would be the point if I can release the device etc. And do other things with it anyway.
In that case I can just pass the LPDIRECT3DDEVICE (which is a pointer allready) not being a reference, just by value (of the pointer). This works for sure, because I did that for 'ages', before my 'const implementation' all over my engine.
0

Share this post


Link to post
Share on other sites
Sorry, I'm a bit confused.

Say I wanted to pass the LPDIRECT3DDEVICE9 with the possibility to execute const functions ( and not release etc.) within the receiving function, should I then do:

void MyFunction(const LPDIRECT3DDEVICE9 d3ddev)
{
d3ddev->release; (should give a compiler error)
d3ddev->setrenderstate(....); (should be fine)
}
0

Share this post


Link to post
Share on other sites
IDirect3DDevice9 has no const member functions. You basically can't do anything useful with a pointer to const IDirect3DDevice9. However, a [tt]const LPDIRECT3DDEVICE9[/tt] is a const pointer to a non-const IDirect3DDevice9. When you add const to a typedef of a pointer you get a const pointer type, not a pointer to a const object. It's equivalent to [tt]IDirect3DDevice9 * const[/tt] not [tt]const IDirect3DDevice9 *[/tt].
0

Share this post


Link to post
Share on other sites
OK, so basically there's no reason to do it otherwise then just giving the LPDIRECT3DDEVICE9 as a parameter to the function, which is already a pointer to the idirect3ddevice9,

void LoadTextures(LPDIRECT3DDEVICE9 myDev)
{
D3dxfunction(....., myDev or &myDev)
myDev->setstreamsource etc.
}

This also means that this function is allowed to do everything with the device where myDev points too.
I was hoping there was a way to distinct what and what not a function is allowed to do with the device, but since the idirect3ddevice9 has no const member functions, I think this is a no go.

Would there be a possibility to distinct using the device just as a parameter/ reference when calling other functions who just need to know the device, versus functions who need to execute functions on the device itself:

1. D3dxcreatetexturefromfile(...., myDev);

Versus

2. myDev->avalidfunction (i.e. Reset, release, setpixelshader, setstreamsouce etc.)

That way I might be able to protect misusage of the device, in functions where I just need to pass it as a reference to a d3d(x) function.
0

Share this post


Link to post
Share on other sites
New question;

I've been doing some reading and looking at examples.
What I see often to 'solve' this is:

- the main d3d wrapper class has a ccomptr to the d3d device
- other classes who need access to the device have a private or protected d3d device ccomptr
Which is set when initializing an object of that class
- this 'copy' of the ccomptr to the device is not accesible from outside these classes

This seems like a good solution to me (for my d3dscene, mesh and skybox classes).
Things to think about:

- what if the device that's pointed too changes? (not that I expect this though)
- this doesn't prevent other classes then the main d3d wrapper class, to manipulate things on the device and run member functions on it

What do you think?
0

Share this post


Link to post
Share on other sites
I now implemented it as above, works fine.
I now pass the device pointer only once to an object of my classes, if more then one functions (mostly create or init) need the device pointer, I've created a private member containing a ccomptr where I save the pointer in the init/ create function for that object (which receives the pointer as a function parameter.

Finally I set the device ccomptr to NULL in both the constructor and destructor for these classes (mesh, d3dscene, skybox).
No more ->Release() calls now, with using ccomptr/ smart pointers (for idirect3ddevice9, idirect3dtexture9 and and id3dxmesh objects).

If you have any suggestions or remarks, please reply
0

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  
Followers 0