C++ DirectX 12 Game Engine - [S01E03] - Creating A Game Engine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome to episode 3 of our tutorial series where we'll be making a directx ready game engine in this episode we're going to be building a new project to act as our game engine we'll be creating this as a dynamic linked library or dll for short and we're going to find out exactly what's needed to be able to link this into our blank project program we'll then be looking into how to build the basic framework for our game engine including a generic back-end entry system at the end of this episode we will have a simple structured game engine to power our future projects on so with that being said let's get on with it let's start this episode the same as we have for the last two episodes and go straight to the olympus mods folder we need to create an episode 3 folder and for this i'm just going to duplicate the episode 2 folder and change the name we've done this in the last two episodes and we're going to do it in every episode going forward so please note that this is the last time i'm going to include this step in this series now we've created our episode 3 folder we can go inside it and open our olympus engine solution that we created in the last episode now the visual studio is fully loaded we can see the blank project program that we've been working on this program is going to represent the game that we're actually making but what we need now is an engine to be able to run it on we could build our engine directly into our blank project program but that means we wouldn't be able to use it to run other programs later what we'd really like is a scalable engine that can be used in a multitude of different programs and for this reason we need to create a new project to act as our engine to do this let's come up to our solution right click click on add a new project just the same as before there were lots of great templates that microsoft provides us but we're just going to choose blank project and next we already have a name for our solution so this will just be where to store it and a name for our project i'm going to leave the location as it is predefined but let's change the name to olympus [Music] once that's done we can just click on create and that will give us a new project for our engine to work from we now have a project to work as our game and we have a project to work as our engine that we can then link into our game project just the same as the last project we're going to change this to private and public and resources and set this up in a way that's nice and easy to remember i'm going to try and skip through this section as quickly as possible because we've already learned how to do all of this in episode 1. you'll now see that our folder structure for our engine will now match the same folder structure as our project and that will be handy to keep everything in line the next thing we can do is come up to switch views go to folder view and select on our episode 3 folder we'll now be able to see our olympus project and its folder structure available just the same as we have for our blank project let's create ourselves a source folder to work from we will want to optimize our engine straight out of the gate and for this we are going to need some pre-compiled headers currently in our blank project program we already have a set of files called pre-compiled headers and if we were going to do this for every program then it will become rather confusing one way that we can conquer this is to use the same name for our pre-compiled headers as we did for our program name so i'm going to create two new files one called olympus.h and the other one called olympus.cpp these will act as not only the pre-compiled headers for app engine but they'll also give us a way to link our engine to our blank program using the header files once we've added that we can go back to our switch views click on our solution view and we'll be back to our solution we haven't added those yet so let's once again create a new folder called pch let's add those files now let's go to our source folder select the two files we've just created and import them next we're going to need to set up the configurations for our project so let's go up to our project right click and click on properties the configurations that we're going to use here are mainly going to be the same as our blank project so we're going to go over this nice and quickly let's open our configuration manager and let's just make sure that all instances of the x86 architecture is removed once this is all done we can close this off and we'll be able to see that we're no longer running any instances of x86 let's double click on our blank project and copy the build settings for our projects and just paste those back into our olympus engine these paths are quite generic so we can use them for both of our programs the same once we've done that let's click off of that and just click apply now that's done we can start looking at the configuration type for our engine our blank project is an exe but we only need one executable what we will need is to be able to link this into our program and for this there are two options we could use a static library or a dynamic library we're going to use a dynamic library once that's done just let's just set up some of the generic windows settings to ensure that they're all at the maximum level possible the next thing we need to do is add our pre-compiled headers so let's come into here and go to pre-compiled headers if we come up to here we can just change this to create as we did before and we can now change our standard affix to olympus.h that means that our pre-compiled headers are now fully set up so if we just click apply then we can be confident in the fact that our engine is now set up now that we've finished setting up our configurations we can move on to setting up our pre-compiled headers like always the first thing we're going to need to do is include the name of the pch file for us this is olympus.h we can then move on to our olympus.h file like with all of our header files let's add pragma ones at the top and then what i like to do is include our windows.h with our windows.header file however i want to do something very specific i want to say that we should only be using the windows.h file if we're running on a windows architecture we're not going to be covering any other architecture but it's something that you as a viewer might want to add later let's just add this here and let's say if defined win32 and this is a specific macro that windows gives us to represent that we're running on a windows architecture then please add the windows header file to make this work we'll need to add in an end if as well now that that's done our windows header file will only be operating if it recognizes the win32 macro which at the moment it's not seeming to recognize to make this work we're going to need to come back up to our olympus project and go back into the configurations we come from our link out and come to system we'll see that we're currently set to a console box still this is okay but we're just going to set this to not set for now let's click apply if we come to c plus plus we can come to preprocessors and currently our preprocessors are set to different options let's go to each of these and change under store console to win32 do that for that and just click apply and i'm also going to do that for a release configuration you'll see we've got the debug settings here so i don't want to affect that that's why i'm doing it on both settings and not just on one again let's click apply here and okay come back to all configurations and just go and click ok that'll just hopefully save that for later now we've done that we can see that our win32 macro is now working successfully this is a good start for setting up our game engine but now we're going to need to look into other things such as building the application itself now we've finished setting up our olympus engine project it's time to start thinking about the overall design for our program we now have two specific programs in here our blank project which is our game and our olympus engine which is our engine what we'd really like is a file in our blank project called application and for us to be able to run our entire program from this file let's start by going in and creating a new file for us to use for this process let's go to switch views and go down to our folder view let's go to our episode 3 folder and blank project in our source folder we're going to create a new file and we're going to call this application.h we'll also need our application.cpp in here as well once that's done let's go back to our switch views and back to our solution view we will need to add our files in here as well let's go to add existing files go to our source directory and add our two application files let's ensure that our dot h files always go in the public folder with that done we can start looking into how we would like this to now operate the first thing that we need to do is just add the include files for our application class let's start off with our pch files and then let's add an application.h file as well once we've done that we can move over to our application.h class and i've made us up a class already that gives us the basics of what we need i've called the class application just to keep it nice and easy i've added a constructor and a deconstructor in here just to start and open and close the class i've added an initialize variable or function which will give us an option to run this when we start the application and i've added an update function which can come in here and be run once every time the application loops this is a good way to actually run our application let's just add the refactoring in here for all of these different visual studio is now being rather annoying so let's just do that manually there we go and that is correct in here now this is the way we want this to operate and this is going to be a great way for us to operate but we know from when we were setting up our win main class earlier that this is not specifically how this functions we don't just magically create a class run initialize and update throughout the process we're going to need to make a system to be able to tell else application or our game that this is how we want it to run we do not however want to waste all of our time programming all of this information directly into the game itself we would like to have some background code that just says when when you start up this program please just run from the application class to do that we're going to need to create what we call an interface and an interface will go behind this class just have it basically running as a generic class that is built into every version of the engine but he's dynamic and adaptable for our specific variable of the engine to do that we're going to need to create a new class so let's come up to our switch views come down to folder view episode 3 the olympus engine let's come down to olympus this time now we need to think about how we're going to organize this there's going to be lots of different files that go into our actual engine itself and we need a way to make sure that we know where to find everything this application is going to be based heavily on a windows application and it's only really ever going to come out if we are using windows i'm sure if we were using a different system there would be a whole different set of commands that we would need to input for this reason let's create ourselves basically a windows folder but windows is a platform so let's start by adding ourselves a platform folder once we've created the platform we can actually add windows now the specific type of windows c plus program we are using at the moment is called a win32 program there are other types of windows programs that you could use as well such as a uwp window for this reason i'm going to call this win32 we could put this in its own separate windows file as well platform windows win32 but i think just by putting it as win32 that gives us the amount of folders that we need to just understand this correctly once we've added our win32 application folder let's add a few classes into here we are going to be making an application interface and the standard way of making something like this is to keep the same naming convention but just to add the letter i at the beginning so we're going to create an i application dot h and we're going to create an i application.capp let's just while we're here think about how we want this commonly in our program we have our win main and that's our main entry point you our engine at the moment we don't have a win main and really we would like all of that to be just kept and dealt with by our engine and not so much in our system to do this what i'm going to do is i'm going to make a generic and callable win main function and we're going to place it straight in its own folder and we're going to call this win entry dot h and that's just so that we know that windows will enter by this class now that's all done let's go back to our solution view and have a look and import what we've just created let's start by adding those into our application first so let's come down to our private and our public files in our olympus engine and let's just add the same filters that we added a minute ago that would be platform and win32 we need to do that both times here so let's just add his let's add a win32 folder here as well now we've done that we can just go in and import the files that we just created a moment ago let's go source platform win32 and i'm just going to add all of these in here remember that we need to drop our dot h files into our public file let's start with our application interface class and just let's add the normal pch files we added in normally that's going to be include olympus.h in this case and we are going to be able to include our eye application you'll notice at the moment this is coming up in red it's not recognizing our normal pch file and that's because this program this function is actually located three steps ahead of our olympus.h file we can solve this by adding a forward propagated input directory let's go into our project properties again and we can come in here to see plus plus you can come to general additional include directories and what we're going to do is we're just going to add the source directory of the olympus engine if we add the source here it will add that in and this means that we can now propagate forward in our folder system instead of having to keep going backwards in space inside our own problem program it's a really handy way of just being able to get rid of these little errors where you'd have to go backwards in a folder now we've done that and we've added that to the system we can come back to our application class now the application interface class is basically a set of instructions for how we want our application to run it's basically a promise to say when i'm creating this class the class that's created off of it in the future is guaranteed to be like this and for that reason i'm just going to start by copying and paste our normal application class and putting it into our eye application class this is for all intents and purposes what we want our class to look like i'm just going to add the normal i in front of each of these that's just to show that this is an interface to be able to make this to say we need a contract that says when and how this is going to function we need to add the virtual flag at the beginning of these functions these this says that we're not specifically going to create these right now but when you create this in the future make sure you add these otherwise it won't work correctly if i just add equal zero it just means i don't actually have to create any of these functions right now these would only ever need to be created once we actually created the inhibited class i'm not putting a virtual flag on my constructor i've done it on the deconstructor because we may want to change the way our program is deconstructed but on my constructor we generally want to keep this the same for that reason i am going to refactor that and we will create that in iapplications.cpp this is now a contract for how we want our application class to match and once we've added it together we'll notice that this works fine but we don't have any specific way to actually add this to our blank project the olympus engine files are not actually currently linked to our blank project and vice versa so in the next chapter we're going to be looking into this a dynamic link library is used by telling the application and the compiler that when we start up an application we want to specifically import or export a dll there's a command to be able to do this and that goes directly in here between the class and the i application this is defined as such this one's actually set to import so let's just change that to export it'll work the same for both now this is in here this is telling us that when we build this we want to export the dll and then when we put it back into our application or our blank project we want to then give it a declaration to say that we want to then import that this can become slightly confusing to keep importing and exporting dlls and for that reason there's a specific way that we actually can make this really easy if we come to up to our pch files or in our case here olympus.h we can add this little magic function this is a macro and it says if we are detecting the build dll macro in the predefinitions let's add this line here and if we're not detecting the build dll definition in our predefinitions let's use this one here this one says dll export and this one says dll it imports however both of them are running on the same macro and that is olympus underscore api we can see right now that this one is the one that is in pink and that is because we are not currently running this build dll to start with before i go into how we actually change that let's just add this to our application file so instead of this we can now just put in olympus api and that will work exactly the same if we then come up to our olympus project what we can do is go to our properties come to pre-processes the same as before now we're going to have to do this for both of these let's go to debug and let's add the one we just had now we're in olympus we want build underscore dll here and let's do the same for our release files let's add that in here as well click apply and okay if we now come back to our olympus.h files we'll see that now it's the we have got this available so this is now going to be our dll export now what's the methodology of doing this we've just told it the exact same thing and we've just added it to set it to do it the methodology of this is is that we've now set olympus to use this build dll macro but our blank project is not using this which means it's still going to be using this one so basically if we build these files inside our engine it'll export them but if we try and use them outside of our engine it will import them and that's exactly what we need to be able to use a dll now that's done we can come back to our eye application class and everything's working absolutely fine but we still need a way to be able to tie this into our application.h file what we ideally want to be able to do is we want to be able to just include our i application class here and we want to be able to use this here but our system is not going to recognize this because we haven't actually linked the files together to do that what we need to do is we need to come up to our blank project we need to add the same type of files we added a moment ago so let's go to general let's go to our include directories now what we want to do is we want to include the olympus source file so let's come back to olympus engine let's go to olympus and source click select folder and that's brilliant that will now give us access to the olympus engine files but just the same as we did for the olympus files let's make sure we can forward propagate this system to that let's go back to our blank project and let's import the source folder for our blank project itself that way it means if we need to backstep at all we will not need to we can just grab it straight from forward propagation let's just click ok then and apply now this is a bit of a trap i have forgotten to put this back onto all configurations and for that reason this is only set on the release version let's just copy and paste and let's put this back to all configurations and just put that in there so for those who are eagle eye we should know that this should be platform forward slash win32 forward slash i application that is now imported that incorrectly there that should be working absolutely fine let's just have a look in here to see if we can find any reason as to why this wouldn't be working absolutely fine there is one more step that we do need to do in here we need to come into our references we need to click add reference go to olympus and just add that as a reference that will now reference that into this project so that every time we build this project that will be in there as such the last thing we're going to need to do is we'll just need to come to our pch files and add our olympus file that we actually created that would mean that we can actually import the different files fold over from our uh our dll imports into this program as well once we've done that we can come back to our application.h and we'll see that everything is working absolutely fine and if we were to run this now it would majority work for now we've got our application class and we've got the inherited class that it's built from but we've still got no way of specifically running this at entry in our blank project file at the moment we've got our win main class and this is working fine at the moment but as i say we don't really want to run this class in this fight project we'd rather have this back so what i'm going to do is i'm going to start by just copying and pasting this section here and then i'm just going to edit this out and just comment it so it doesn't run at start i'm going to come back to the win entry file we created earlier and in here i'm just going to add the olympus engine header farm from here i'm going to then add our win main let's get rid of all of this our win main is now located in our engine file to make this work we need a way of referencing our application class from our blank project in our engine and as standard this is generally the wrong way around we would generally never reference our blank project in our engine well as we would in reference our engine and our blank project but we need to find a way to be able to do this because we want our engine to be able to say please run this class at entry the way we can do this let's have a look at this now if we just go auto and then we're going to say the entry application and we need a way of pointing this towards the class we've created in our black project the class we've created in our blank project is going to be based off of an eye application class make a point to that what we could do is we could now make a new class and we could call this entry application let's put that up there as soon this mini function we've just created is going to be has been created on the intention of drawing back the application class from our blank project so we need to create this in a way that we can declare that again later let's just create this as an external class for now and let's make our auto entry application that we just created a moment ago let's turn that into our entry application now i understand this is getting confusing but please bear with me we then need to find a way to be able to declare how we are going to actually declare this inside our class to make this work correctly let's just start by actually adding in the eye application class now that's done this is all working correctly and we've got a few errors but in general everything is working let's go back to our i application class and let's add a new macro this macro is as such and it basically says if we declare this function inside our application with the class that we wanted one that will translate that into our entry point if that can translate into our entry point we can then run it from here this is a little bit confusing but i'll show you how we can now implement that if we come here we can take this as such we can come here now we're going to be very careful and we're going to ensure that we go to our dot cpp file for that and there's a good reason for this let's include our win entry function that we created a moment ago that's in there now that means our win out win main is being called in and we can now click entry app we can change this to application we have now said that through this macro we are going to feed in our application that this macro is then going to translate into our entry point which if then we come to our entry things our entry application we're going to change this around i've just realized it's entry application here an entry app everywhere else inventory application there we go if we now come back to here this is recognized here we're also going to actually need to plant a place to put this external application that we're going to be using so let's go back to our application class and just here outside of our actual class itself let's just pop that down there we now make sure this is here as such you can come back to our wind entry just want to make sure that this is definitely coming up correctly that should work as such the reason this isn't working is because i've named them the same thing so if we just very quickly get rid of this here then that should open that up as such now that this is working correctly let's go back to our application class and let's have a look again at how this is running we're going to create our application at the very beginning we're going to run initialize and then we want to call a loop to update each time let's try and get that working from that for now so we've created our application there we can go entry app and then we could go initialize that means we can now use that at the very beginning when it runs we can actually now test this on its own let's come back to our application class and let's just make a simple message box to say that this is now loaded up let's try and run this now this isn't currently working and one of the main reasons here is it's saying that it cannot find out olympus.dll to conquer this what we need to do is we will need to come up to our olympus.engines file and we come to come to our build file at the moment they're in two separate files because of the way we set it up earlier but they actually need to be in the same files so if we come up here to blank project well olympus we should be able to come in here and we should be able to see a dll now there you have another issue here and this is actually telling me that it doesn't like this here so let's just change that to here for now and let's just build this again down here that's builded successfully and we can now find our olympus.dll file in here let's copy and paste that and let's just put that in our blank project file we were to now come down up to here we can go to blank project we can right click this and click on set as startup project that means if we just now press play out of these two files this one is going to be the one that is run let's click that now and see if we can get our entry box we can now see that from here we've gone through our win entry system we've used our background inheritance to actually run and initialize that however by going into our application class and using this macro it's helped us jump ahead to be able to actually run this class from that we have all of that functionality and the only actual functional class we have in our program at the moment is this one and that's how we make a good game engine now that we've done that we can just stop for a moment and let's go back and wonder how we're gonna get this update feature let's come back down to our win main main file that's here and let's have a look at our windows process not the windows process we want our message loop function let's copy and paste this now and let's bring it across to our win entry let's drop it down here this means now the program is going to continue to run and loop over while they're looking for messages from our system what we could do here is we can say if you get a message let's pick message but if not let's run entry app dot update that is now going to give us not only our initialize function but also our looping function as well let's come back to our application and let's just do this and just put another message box in here for updates and let's just say loop what we're going to need to do is we're going to need to insist that we build our olympus folder and make sure that this is definitely the correct project that we're working from we've just rebuilt our dll so we need to make sure it's completely up to date to be able to run it we place the file in there as such click on play we'll get our first box to say i've loaded up and then repeatedly after that this same message will repeat and loop we've now created a new application to run our blank project from this application has both an initialized function and an update function that we can use to start building our projects on or our game on this is powered in the back end by an engine now with a built-in constructor and a built-in entry function this is a really good start because it means we've got our entire project in just these simple functions that's nice and easy to read and we've got all of our background logic in our engine in the next episode we're going to be looking into what some of the next things that we need to think about when creating a game engine for this reason we're going to be adding some new per game settings and we're also going to be adding a log system so that we can start to read information from our engine and with all that said i wish you the best of luck and we'll see you next time when we'll be making a direct text ready game engine
Info
Channel: OlympusMonsTutorials
Views: 5,450
Rating: undefined out of 5
Keywords: c++ directx 12 game tutorial, c++ directx 12, directx 12 tutorial, directx12 game engine, c++ directx 12 tutorial, c++, Directx, Directx12, directx 12, game, series, lessons, visual studio, game engine, tutorial, precompiled headers, dynamic link libraries, dll, application, engine
Id: YgZSSE3qZqA
Channel Id: undefined
Length: 41min 59sec (2519 seconds)
Published: Wed Mar 17 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.