Sign in to follow this  

C++ | DirectX | Class system ?!

This topic is 1094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

just to justify my question I have to say, that I moved from Java to C++.

 

Now my problem is, that I have some objects in my DirectX game. They are drawing fine, but all the code I have for the objects are in the main.cpp class.

And thats a problem for me.

Now in Java, I could create a class and just write all the objects code in there and then just create an instance of it, and call the draw method of the objects class in draw.

 

....

Object object = new Object(blablabla);

..

 

void draw()

{

      ...

      object.draw();

      ...

}

 

Now my question is how to do this in C++/ DirectX ?

 

As you have all these COM objects, that only can be used in the main class and you have to bind it all to buffers and then draw the buffer.

How could I make this constructor based ? So like the Java exaple ?

 

A code exaple would be a great help :-)

 

Edited by Mate

Share this post


Link to post
Share on other sites

I'm not really sure what exactly you are trying to do, but from what I get you just want to have a class encapsulate things. Something like this?:

class Mesh
{
private:
	XMFLOAT4x4 m_WVP;
	ID3D11Buffer* m_vertexBuffer;
	ID3D11Buffer* m_indexBuffer;
	ID3D11EffectTechnique* m_drawTech;
	//etc.
};

class Renderer
{
private:
	ID3D11Device* m_d3dDevice;
	ID3D11DeviceContext m_d3dImmediateContext;

	void draw(Mesh& mesh);
	//etc.
};

class GameApp
{
private:
	std::vector<Mesh*> m_meshes;
public:
	Renderer renderer;

	void renderWorld();
	//etc.
};

void GameApp::renderWorld()
{
	for (auto iter = m_meshes.begin(); iter != m_meshes.end(); iter++)
	{
		renderer.draw(**iter);
	}
}
Edited by lightxbulb

Share this post


Link to post
Share on other sites

In C++ you have header(.h) and implementation files(.cpp, .c, .cxx) you need to create these files yourself and add them to the project. In the header file you specify how the class looks, so which methods and variables it has, in the cpp file you actually implement the methods, this is split from how Java or C# does it. When you want to use a class thats defined in another file you include the header file , with a #include statement, into the file where you want to use the class name.

 

Be careful with including headers in other headers because you can create loops and the compiler can't deal with that. there are other ways to deal with that, forward declarations, but this is a more advanced topic.

 

PS you can use COM in other files as well they dont have to be in the main.cpp file, the main.cpp is usually just the file that defines and implements the main function so the application can start.

Edited by NightCreature83

Share this post


Link to post
Share on other sites

Thank you for the awnsers !
 

I got the header system before. My problem is, that I don't exactly know how to make objects/ meshes with an constructor in C++.

Because I just want to say for example

 

 

...

MeshLaptop laptop;

...

.

laptop::define(bla bla bla);

.

...

void draw()

{

    ...

    laptop::transformRotateDraw(bla bla bla);

    ...

}

 

 

But this didn't worked for C++/ DirectX because of the buffer and this confusing stuff.

 

So I want to make a lot of object instances in a class and draw them over a method. As easy as possible, without a big mess in the main.cpp.

Is that even possible in C++ ? :|

Share this post


Link to post
Share on other sites

Ok, I had a lession in this before, but that shouldn't work for my case, because of the COM object system, right ?

There are a lots of things, the device needs to work with. And this doesnt work class-global, or ?

Share this post


Link to post
Share on other sites

I still don't get what your issue is. What precisely is your issue with COM objects?

Can you elaborate a bit more, rather than just saying "this confusing stuff":

But this didn't worked for C++/ DirectX because of the buffer and this confusing stuff.

 

 

In your example you want the laptop to draw itself - that's bad by design, let your renderer draw the laptop. Check the example I gave you - you have some class Mesh containing its vertex & index buffers, its wvp matrix, a pointer to the draw technique it will use etc. Your renderer given this mesh should be able to draw it (the draw(Mesh& mesh) method). You should store all the meshes you have in some structure, and when you want to draw all of them, you can just iterate over this structure and call draw for each of them. To draw a mesh you usually need the d3d device and device context + the mesh's vertex and index buffers - you could store a pointer to the d3d device and device context in the renderer and the model specific data in the mesh; there could be additional data like textures, draw technique, material, render states etc. Here's something you might find useful: http://rastertek.com/tutdx11.html

Edited by lightxbulb

Share this post


Link to post
Share on other sites

I still don't get what your issue is. What precisely is your issue with COM objects?

Can you elaborate a bit more, rather than just saying "this confusing stuff":

But this didn't worked for C++/ DirectX because of the buffer and this confusing stuff.

 

 

In your example you want the laptop to draw itself - that's bad by design, let your renderer draw the laptop. Check the example I gave you - you have some class Mesh containing its vertex & index buffers, its wvp matrix, a pointer to the draw technique it will use etc. Your renderer given this mesh should be able to draw it (the draw(Mesh& mesh) method). You should store all the meshes you have in some structure, and when you want to draw all of them, you can just iterate over this structure and call draw for each of them. To draw a mesh you usually need the d3d device and device context + the mesh's vertex and index buffers - you could store a pointer to the d3d device and device context in the renderer and the model specific data in the mesh; there could be additional data like textures, draw technique, material, render states etc. Here's something you might find useful: http://rastertek.com/tutdx11.html

I like the idea of making some sort of a buffer for the final data. But the index buffer wouldn't work anymore when I put mulitple meshes in only one buffering structure ...

I mean if I had 3 vertex data buffers and I would translate and rotate them, then I could sent it all to one final buffer, that would get drawn in the rendering class. But this shouldn't work for the index buffer ? Because when I had 3 vertex data holders for each mesh and I would stick them together, the index numbers would raise...

So I mean that the vertex number 2 from the first index buffer is not the same as the vertex number 2 from the second vertex buffer ...

 

Do you have a solution for that ?

Share this post


Link to post
Share on other sites
I like the idea of making some sort of a buffer for the final data.

 

Lest you want to do some optimizations, for now don't do only one buffer. Later you could do it (then you'll just add an offset per index buffer), but as a beginning try with a buffer per mesh. Basically try to go from simple to hard - make the simpler code work, then you could try optimizing it.

Edited by lightxbulb

Share this post


Link to post
Share on other sites

 

Lest you want to do some optimizations, for now don't do only one buffer. Later you could do it (then you'll just add an offset per index buffer), but as a beginning try with a buffer per mesh. Basically try to go from simple to hard - make the simpler code work, then you could try optimizing it.I like the idea of making some sort of a buffer for the final data.

 

 

 

Thank you ! :)

The point, why I didn't make multiple buffers was, that I'm worried about the performence. I'm really paranoid about the performence.

 

Just one thing left : Could you please give me a simple example of an constructor based mesh ? So that I can create multiple instances for a mesh with only a bit of code. Thats what I'm trying to do all time :(.

I have not much experience wiht C++.

So please don't just post a link of some tutorial, thats never the best way.

 

I also know the header thingy aswell. The problem is, that the constructor system/ the whole class system is very different to Java.

Share this post


Link to post
Share on other sites

I'd advise you make a factory to which you can delegate the creation/deletion of meshes. And you'd probably want only a few functions/methods to be able to create a mesh(example MeshFactory::createCube(), MeshFactory::loadMesh(char* filename), MeshFactory::createSphere(unsigned int segments)).

Basically something like this:

class Mesh
{
    //various variables go here - the Mesh may have an empty constructor
}

class MeshFactory
{
private:
    std::map<ID, Mesh*> m_meshes; //keep track of meshes by id
private:
    //various details
    //...
    ID createMeshFromBuffers(const std::vector<Vertex>& vertexBuffer, const std::vector<UINT>& indexBuffer)
    {
         //you'll need the d3d device to create the ID3D11Buffers from the given buffers
    }
public:
    ID createCube()
    {
        //make the vertex and index buffer vectors
        //...
        return createMeshFromBuffers(vertexBuffer, indexBuffer);
    }
    //etc.
}


You could choose a different architecture of course, there are plenty of books out there that use various architectures when it comes to a 3d renderer.

 

 

I have not much experience wiht C++.

Well I'd advise you get some experience with C++ before going into 3d. I don't believe it's a good idea to be studying 3d rendering in C++ if you don't know well enough the language. Rastertek has some pretty good tutorials, other things would be Frank Luna's book, Jason Zink's book, Jason Gregory's book, but as I said - before you delve into 3d with C++ and direct3d you might want to take some time to study C++.

Edited by lightxbulb

Share this post


Link to post
Share on other sites

Well I'd advise you get some experience with C++ before going into 3d. I don't believe it's a good idea to be studying 3d rendering in C++ if you don't know well enough the language. Rastertek has some pretty good tutorials, other things would be Frank Luna's book, Jason Zink's book, Jason Gregory's book, but as I said - before you delve into 3d with C++ and direct3d you might want to take some time to study C++.

 

 

So .. I'm acutally working on the new class system in the moment smile.png. Like a render class, mesh classes(but I'll change to factory soon).

My only problem is, that I can't use, for example, the device context over a class. It's giving me the error "A non static member has to be relativ to an object". Now ... I translated the error, but it's something like this.

 

Hmm ..

my problem is not the 3D space. I worked on game projects before. On big projects. But I only worked with Java + OpenGL. Now C++ and DirectX is .. kind of new for me. And thats my only problem. The structur and syntax is VERY different.

 

So how could I use the COM objects over classes ?

 

EDIT: The error is fixed. Now .. is there now better performenced way to use a rendering part, than creating an object of it ? :|
I mean it can't be so good for the performence to create instances of classes, or ?
 

Edited by Mate

Share this post


Link to post
Share on other sites

I mean it can't be so good for the performence to create instances of classes, or ?

 

Why do you actually have this impression ? Have you profiled any bottleneck in this regard ?

 

The only thing I can think of you can do wrong is creating (and destroying) buffers/textures and whatnot every frame. You usually create everything you need at app startup (or,  in the context of  game, at level beginning). If you need to change something you have Map/Unmap or UpdateSubresource.

Share this post


Link to post
Share on other sites

Why do you actually have this impression ? Have you profiled any bottleneck in this regard ?

 

The only thing I can think of you can do wrong is creating (and destroying) buffers/textures and whatnot every frame. You usually create everything you need at app startup (or,  in the context of  game, at level beginning). If you need to change something you have Map/Unmap or UpdateSubresource.

 

 

So I sayed that I moved from Java + OpenGL and I sayed that I like Java and OpenGL ways more then DirectX and C++.

 

So don't you ask why I actually moved when I don't want ?

It's because I had already a game on my own Java OpenGL engine. It was good for my impression.

But yeah .. it is running on a i7, 8gb ram and a really good graphics card with only 8-12 fps.

 

So after all I realized that I have to move. And now the paranoia of bad fps is still in my neck.

Share this post


Link to post
Share on other sites

I agree. You switched API and language in the hope it will solve your performance issues. Nonetheless you're not sure it actually will. Then why switch at all.

 

I ask again: Have you profiled your code, with a profiling tool or manually ? And no, looking at FPS alone is not profiling. Do you use [i]graphics[/i] profiling tools ?

 

How many draw calls do you have ? How many state changes ? And in the context of Java: Do you produce massive amounts of garbage each frame ? Also your graphics driver can make troubles: I hear that sometimes OpenGL drivers fall back to software rendering, if you use a feature unavailable in hardware.

 

If you just transliterate from Java/OpenGL to C++/DirectX you very likely have the same performance.

Share this post


Link to post
Share on other sites

I agree. You switched API and language in the hope it will solve your performance issues. Nonetheless you're not sure it actually will. Then why switch at all.

 

I ask again: Have you profiled your code, with a profiling tool or manually ? And no, looking at FPS alone is not profiling. Do you use graphics profiling tools ?

 

How many draw calls do you have ? How many state changes ? And in the context of Java: Do you produce massive amounts of garbage each frame ? Also your graphics driver can make troubles: I hear that sometimes OpenGL drivers fall back to software rendering, if you use a feature unavailable in hardware.

 

If you just transliterate from Java/OpenGL to C++/DirectX you very likely have the same performance.

 

 

Yeah, thats true. The language at it's own can't change the performence. You actually could programm it the same way. But Java/OpenGL doesn't give you the same possibilities for the rendering part. What I write in C++ in 100 lines, I properly write in Java within 30 lines. This makes it more comfortable for me, but you can't interact the same in 30 lines, than in 100 lines. Like I never used a complicated buffer system in Java, in C++ I do.

I mean .. I had buffers, but not this amount and type of.

 

So the thing is, that you can write the same game in C++ with better performence. Now that my game is really performence eating, I prperly have to choose the way I don't like. But when I learned one of business then it's that the way you don't like is the way, where you CAN raise the most money and experience of.

 

EDIT:

 

I started rewriting the code today. Now I want to make 100% clear, readable and less linked code. And I'm building in a system to precisionly detet errors and avoid them quickly and efficent. :-) When I'm finished, I optimize it like you guys said so thanks at all. I think, 2 days ago, I wouldn't even think at rewriting anything.

 

And to the upper part : Java isn't even clearly made for games. DirectX is a game library, OpenGL is a graphics library. Another reason, why DirectX has better performence.

Edited by Mate

Share this post


Link to post
Share on other sites
I started rewriting the code today. Now I want to make 100% clear, readable and less linked code. And I'm building in a system to precisionaly detet errors and avoid them quickly and efficent. :-) When I'm finished, I optimize it like you guys said so thanks at all. I think, 2 days ago, I wouldn't even think at rewriting anything.

 

 

It's certainly better to have readable and well architected code. I'd recommend you check out design patterns: http://www.gameprogrammingpatterns.com/http://sourcemaking.com/http://en.wikipedia.org/wiki/Design_Patterns

 

 

 

 Java isn't even clearly made for games. DirectX is a game library, OpenGL is a graphics library. Another reason, why DirectX has better performence.

C++ isn't "even clearly made for games" either. Sure it provides greater freedom, but it's not "better" than Java. And I don't believe that DirectX "has better performance" than OpenGL.

Share this post


Link to post
Share on other sites

 

 

 Java isn't even clearly made for games. DirectX is a game library, OpenGL is a graphics library. Another reason, why DirectX has better performence.

C++ isn't "even clearly made for games" either. Sure it provides greater freedom, but it's not "better" than Java. And I don't believe that DirectX "has better performance" than OpenGL.

 

 

Ehm sorry ... I wanted to say OpenGL and not Java sad.png. Gives a new definition of the sentence. biggrin.png
Sure DirectX has better performence IN GAMES. DirectX is made for games. OpenGL is not made for that. As they created it, there main goal was the graphics, not the performence.

And I never sayed that C++ is better. I sayed, it's the better chose for a demanding game. And C++ on it self doesn't make the difference, DirectX does. But DirectX is only avalable for C++ so .. you have to use C++ with DirectX.

And even when it wouldn't be forced, C++ has more freedom and more freedom means more way to enhance the performence, in this case.

 

 

So then I'll take a look at the patterns ..

 

 

EDIT :
 

Is there any structure in C++ compareable to the "List" structure from Java ?
I could need something like this :)

So the main attributes are that you don't have to set a final amount of index values, you can add items of the same type by some command

(in Java it's " listname.add[buffer3] " for example), and you could get the size of the structure by " listname.lenght "

(I know, that there is a way to get it in C++ anyway).

Edited by Mate

Share this post


Link to post
Share on other sites
Sure DirectX has better performence IN GAMES.

 

Where did you read this?

 

 

And even when it wouldn't be forced, C++ has more freedom and more freedom means more way to enhance the performence, in this case.

More freedom can also mean an easier way to break things + some things require more effort to do in C++.

 

 

 

Is there any structure in C++ compareable to the "List" structure from Java ?

You are looking for the stl library - that's why I said learn c++ before trying to code a 3d engine on it. std::list would do the job. Check out this: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

You might find this useful too: http://www.cplusplus.com/reference/stl/

Share this post


Link to post
Share on other sites

std::list might not be the most appropriate data structure to use in C++ depending on what you're doing. I don't know if Java's 'list' is a linked list or not either. Google says Java's List by itself is just an interface so you probably mean either ArrayList or LinkedList . std:list is most like LinkedList and std::vector is most like ArrayList. There are many other data structures to look into. std::deque never gets as much attention as it should since it can be a good compromise between std::list and std::vector.

Share this post


Link to post
Share on other sites
If I were to be really blunt you might do well with a bit of humility, to me reading all your posts so far most of them seem to have this air of "Well this only works this way so I can't do this thing, I know it works this way!" when in reality a lot of the things you've said so far don't even make sense.

Java has negatives over C++ yes, if you had a team of AAA developers trying to squeeze every ounce of performance out of the language than C++ is probably going to give them a much wider range of control than something like Java or C# ever would, that's why we still use C++.

But Java isn't inherently just going to give your game 12 FPS, your game probably was performing badly because it needed to be optimized or it was trying to do way too much in way the wrong ways.

I also don't really get your confusion over COM, COM is weird yes but it's really just a bunch of references to hidden internal objects somewhere. There's no "main class" your COM objects do not have to be created in a main class, main is not a class it is a free function.

Even the stuff you said about static vs objects, a lot of how that works is almost identical between C++, C# and Java. If you were abusing the heck out of new in C++ I would at least understand, but I really don't understand a lot of your issues. Most of your issues just seem to come from you not having popped open a tutorial and trying to learn C++ first before you make a game.

You should stop making so many assumptions and actually ask some questions, it would make you sound less arrogant. Not to be rude but nobody really cares if you "worked on a bunch of big projects, very experienced blah blah blah" if you clearly don't even know what you're talking about.

Share this post


Link to post
Share on other sites

std::list might not be the most appropriate data structure to use in C++ depending on what you're doing. I don't know if Java's 'list' is a linked list or not either. Google says Java's List by itself is just an interface so you probably mean either ArrayList or LinkedList . std:list is most like LinkedList and std::vector is most like ArrayList. There are many other data structures to look into. std::deque never gets as much attention as it should since it can be a good compromise between std::list and std::vector.

I know you are trying to link std containers to how they work in C# or Java, but what you are saying is incorrect.

  • std::list is implemented as a double linked list, and thus is always a linked list, a list in C# or Java is only an access interface the container underneath can be anything.
  • std::vector is always an array, and it has more in common with a naked array in any language than any other container.
  • std::deque is implementation dependant on how it works, for small queues it usually is an std::vector, but it could also be a more complicated datastructure, where it conceptually resembles a linked list of arrays, but this is usually stored as an array of pointers to those memory blocks

std::deque should be used when you need to be able to add or remove elements from both ends of the queue with O(1) access time, usually these things are used for commandlists where you get from the front and add at the back.
 

Edited by NightCreature83

Share this post


Link to post
Share on other sites


I don't know if Java's 'list' is a linked list or not either

I actually meant to say I don't know if the OP's 'list' is a linked list or not. I know that Java's list is just an interface (I said so in the following sentence). Other than that I don't think you contradicted anything I said so much as expand and clarified it so thanks for that. +1 to you.

Share this post


Link to post
Share on other sites

This topic is 1094 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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