Thanks for watching guys, hope you enjoyed the video! Code for this video will be up on GitHub in a couple of days, give it a try yourself in the meantime! Next episode is already available for Patrons at www.patreon.com/posts/24599249 ❤️
TheChernoProject can you make a new java game tutorial but like that also talking about items and how to add an inventory and also a better collision detection (maybe aabb collision detection)
13:00 For anyone curious: The final keyword can be specified to the compiler that the virtual method you're overriding can't be overwritten in derivative classes. You call also specify it on the class level as well, meaning that the class can no longer be derived from. Useful if you're making a bottom level implementation that you know you won't be changing. This was added in C++11.
This was one of the best episodes of the series, really well explained, not super fast, live coding with some breaks for explaination. Cherno, well done! :)
The polymorphism is not necessary here (neither in the window class). The platform will not be decided at runtime, it's known at compile time. So no need at all for runtime polymorphism. What he could do (and would be better) is to make an implementation class for every supported platform and include the correct one through the preprocessor. That has zero overhead (virtual functions do have overhead) and the code is simpler.
@@SkillTrailMalefiahs Yeah, I like the context, it makes code more readable as you can usually understand enum class function arguments without reading the function signiture, docs or implementation.
believe me dude he has 10x more C++/Programming knowledge than you, he knows that you can do that, he doesnt like it from a code style point of view because it litters the code. The man has built a fully functioning, feature packed game engine ALL ON HIS OWN, you dont think he knows that? I'm not saying he is the be all end all authority when it comes to anything related to programming but you can assume a seasoned programmar like him knows trivial things like that
@@123akash121 Bit of a weirdly defensive attitude to a comment with a helpful tip; doesn't need to be something Cherno doesn't already know for it to be helpful to others. I used discards in place of the variable that wasn't returned from the pair i.e `auto[_, x] = ...` which is an even cleaner way of writing it imo but it wasn't mentioned in this video. Not really an issue though because like you said yourself these are trivial things and you can't expect someone building a game engine by themselves to be able to address or do every trivial thing right if they're busy working on a fully featured engine. You took a really weird view on this guy sharing some knowledge as if the great Cherno himself was offended that his knowledge of std::pair was questioned (yet he's actively encourages these types of discussions from what I've seen). If you don't find value in a comment that's cool, but this is a series for beginners making their own game engine, so tips like what this guy originally posted will be of help to someone.
What is the reason to have public: inline static bool IsKeyPressed(int keycode) { return s_Instance->IsKeyPressedImpl(keycode); } and protected: virtual bool IsKeyPressedImpl(int keycode) = 0; when it could have been only: public: virtual bool IsKeyPressedImpl(int keycode) = 0; ?
Judging by the other comments, the impl versions (short for "implementation) are meant to be used for specific WIndow types, so for example GLFW or HWINDOW. So you would call the IsKeyPressed function which would then call the appropriate implementation that has more platform specific code.
I have a question, at 22:50 why do we need to declare type (Input*) again? and if s_Instance is a private member of an Input class why do we have access to this?
I don't get from where is called the Input* Input::s_Instace = new WindowsInput(); if the only file we are including in the Application.cpp is the Input.h
For anyone getting an error where the s_Instance conversion from Input* to WindowsInput* is inaccessible, make sure to put public before Input in WindowsInput.h
Hello Cherno, thanks for this series, I appreciate it. I wanted to ask for your reason as to why you are using the name GetMousePosition instead of just GetCursorPos like GLFW?
Hello Cherno, Thanks for these videos, I appreciate them quite a lot. I believe that if I started with some other started point I would have given up already. I have a question to ask about this video. I could not help but asking, why you are using the name GetMousePosition instead of GetCursorPos like GLFW?
GetCursorPos is an alright name but not as descriptive as GetMousePosition imo, both mean the same though so it just boils down to personal preference :).
instead of returning a void pointer, maybe we can typedef a PlatformWindow, like #if GLFW typedef PlatformWindow GlfwWindow* #else typedef PlatformWindow void*
I really think I did everything correct, but suddenly at the end when I'm launching the entire project and hovering mouse over the window it throws an error: Debug Assertion Failed! from the sandbox.exe from file: "minkernel/crts/ucrt/src/appcrt/heap/debug_heap.cpp" Line 996. Expression: __acrt_first_block == header. It doesn't occur when the "PushLayer(new ExampleLayer());" is commented. So after some time i noticed that the error started occuring after changing all buildoptions in premake file to runtime and staticruntime. Somebody maybe knows how to fix it? I can provide more information if it will be necessary.
Uhm, idk if you're still have this problem, but solution is the following: make shure you've removed staticruntime line in every other section but "project" (and it has to be toggled "off") in premake file.
@@miloz1950 Hazel itself is a library (dll file) while Sandbox is an application (exe file). /MD and /MDd are the library build options while /MT and MTd are the multi-threaded application build options. Cherno did a video in the playlist already discussing this, I believe its in the Github video. Not much code going on in it, its a talking video so I think a lot of people may have skipped over it. I would need to check again to be certain but there are TWO lines needed to properly set it. One sets the debug/release state (that lowercase d after the MD/MT) while the other determines if its a library or executable.
so confused how he could just use "auto [x, y] = Input::GetMousePosition(); " in the Run loop, how is the Input class aware of the functions we implemented on the WindowsInput? I get we overrode the Implementations on WindowInput, but I would have expected to have to use auto [x, y] = WindowsInput::GetMousePosition();
I stated this series a couple of months late. I am current at video 9, "Event System", and am having trouble getting the code for that episode, along with spdlog, from the GitHub repository using git. git keeps complaining with fairly terse statements. Might anyone suggest a source for learning how to use GitHub, especially for cloning or downloading older versions of the code? Thanks.
@@TheCherno Sure but that relies on the os to reclaim the process memory. I dont think that then ever calls the destructor of input instance. that might not cause issues now but a poblem could only be one refactor away. If it was a smart pointer it would be properly cleaned up on shutdown
Hello am new to the channel and i just feel like The compiler that you are using is too complicated for my liking. I find CodeBlocks easy and to the point. Nonetheless, i love what you are doing hands down. Keep on sharing @TheChernoProject👍🏻👍🏻👍🏻
Thanks for watching guys, hope you enjoyed the video! Code for this video will be up on GitHub in a couple of days, give it a try yourself in the meantime! Next episode is already available for Patrons at www.patreon.com/posts/24599249 ❤️
TheChernoProject can you make a new java game tutorial but like that also talking about items and how to add an inventory and also a better collision detection (maybe aabb collision detection)
Thx
@TheChernoProject. I forked the repo and cloned it, but the external dependencies are missing. Do i need to download them seperately?
@@hannesblack6949 Just-> git clone in the same folder is easy!
13:00 For anyone curious: The final keyword can be specified to the compiler that the virtual method you're overriding can't be overwritten in derivative classes. You call also specify it on the class level as well, meaning that the class can no longer be derived from. Useful if you're making a bottom level implementation that you know you won't be changing. This was added in C++11.
I love people with valuable information like you, thanks a lot!
This was one of the best episodes of the series, really well explained, not super fast, live coding with some breaks for explaination.
Cherno, well done! :)
So glad that I am not the only one who is interested in writing custom engines :)
The polymorphism is not necessary here (neither in the window class). The platform will not be decided at runtime, it's known at compile time. So no need at all for runtime polymorphism.
What he could do (and would be better) is to make an implementation class for every supported platform and include the correct one through the preprocessor. That has zero overhead (virtual functions do have overhead) and the code is simpler.
Thank you Cherno! Your series helps me out!
Polling for yr own sanity sounds wonderfully insane. Hehe
Great video as always. But, what about:
enum class MouseButton : int
{
Left,
Right,
Middle
};
need explicit
MouseButton::Left // sucess
Left // wrong
@@SkillTrailMalefiahs Yeah, I like the context, it makes code more readable as you can usually understand enum class function arguments without reading the function signiture, docs or implementation.
Such a sad face on the thumbnail 😂 great tutorial though as always
Actually, at 22:00, to access values of a pair you can simply do pair.first or pair.second depending on which element you want to access
believe me dude he has 10x more C++/Programming knowledge than you, he knows that you can do that, he doesnt like it from a code style point of view because it litters the code. The man has built a fully functioning, feature packed game engine ALL ON HIS OWN, you dont think he knows that? I'm not saying he is the be all end all authority when it comes to anything related to programming but you can assume a seasoned programmar like him knows trivial things like that
@@123akash121 Bit of a weirdly defensive attitude to a comment with a helpful tip; doesn't need to be something Cherno doesn't already know for it to be helpful to others. I used discards in place of the variable that wasn't returned from the pair i.e `auto[_, x] = ...` which is an even cleaner way of writing it imo but it wasn't mentioned in this video. Not really an issue though because like you said yourself these are trivial things and you can't expect someone building a game engine by themselves to be able to address or do every trivial thing right if they're busy working on a fully featured engine. You took a really weird view on this guy sharing some knowledge as if the great Cherno himself was offended that his knowledge of std::pair was questioned (yet he's actively encourages these types of discussions from what I've seen). If you don't find value in a comment that's cool, but this is a series for beginners making their own game engine, so tips like what this guy originally posted will be of help to someone.
@@123akash121 Were you on your period while writing this?
What is the reason to have
public:
inline static bool IsKeyPressed(int keycode) { return s_Instance->IsKeyPressedImpl(keycode); }
and
protected:
virtual bool IsKeyPressedImpl(int keycode) = 0;
when it could have been only:
public:
virtual bool IsKeyPressedImpl(int keycode) = 0;
?
Judging by the other comments, the impl versions (short for "implementation) are meant to be used for specific WIndow types, so for example GLFW or HWINDOW. So you would call the IsKeyPressed function which would then call the appropriate implementation that has more platform specific code.
I can’t wait ,to see how your game engine will look like ! 🤔😴
I'm from the future; It looks awesome!
I have a question, at 22:50 why do we need to declare type (Input*) again? and if s_Instance is a private member of an Input class why do we have access to this?
I don't get from where is called the Input* Input::s_Instace = new WindowsInput(); if the only file we are including in the Application.cpp is the Input.h
Why do we have to make a separate class for input while we can just use the event system to poll input?
For anyone getting an error where the s_Instance conversion from Input* to WindowsInput* is inaccessible, make sure to put public before Input in WindowsInput.h
Hello Cherno, thanks for this series, I appreciate it. I wanted to ask for your reason as to why you are using the name GetMousePosition instead of just GetCursorPos like GLFW?
I hope Senpai updates the Repository! x3
So, this whole static - instance thing in input is just a workaround, because it is not possible to override static functions?
No, you can override static functions. This is called a singleton, and is used to prevent holding information in a static only class.
Ok, can somebody once again explain to me, why Cherno created two versions of all the methodes (normal ones and ones with Impl at the end)?
Same
The methods with Impl at the end are supposed to be overriden and implemented for each platform
How did you do that multi select and remove thing in 17:50 ?
Shift + Alt + Down (or Up)
ok i can understand the programming but how tf does he type so efficiently
Prior preparation
@@MicheleTurchiarelli and lots of practice.
Its called touch typing
Hello Cherno, Thanks for these videos, I appreciate them quite a lot. I believe that if I started with some other started point I would have given up already. I have a question to ask about this video. I could not help but asking, why you are using the name GetMousePosition instead of GetCursorPos like GLFW?
GetCursorPos is an alright name but not as descriptive as GetMousePosition imo, both mean the same though so it just boils down to personal preference :).
@@dylanclarke9497 Thanks, I guess GetCursorPos might also be more specific to GLFW and the attempt here is to make it more general.
instead of returning a void pointer, maybe we can typedef a PlatformWindow, like #if GLFW typedef PlatformWindow GlfwWindow* #else typedef PlatformWindow void*
I really think I did everything correct, but suddenly at the end when I'm launching the entire project and hovering mouse over the window it throws an error: Debug Assertion Failed! from the sandbox.exe from file: "minkernel/crts/ucrt/src/appcrt/heap/debug_heap.cpp" Line 996. Expression: __acrt_first_block == header. It doesn't occur when the "PushLayer(new ExampleLayer());" is commented. So after some time i noticed that the error started occuring after changing all buildoptions in premake file to runtime and staticruntime. Somebody maybe knows how to fix it? I can provide more information if it will be necessary.
So it works fine with "buildoptions "/MDd"", but with "runtime "Debug"" it throws an error (in Debug profile).
I have the same problem! May I ask you have fixed it?
I'm sorry but I don't remember what I've done to fix it.
Uhm, idk if you're still have this problem, but solution is the following:
make shure you've removed staticruntime line in every other section but "project" (and it has to be toggled "off") in premake file.
@@miloz1950 Hazel itself is a library (dll file) while Sandbox is an application (exe file).
/MD and /MDd are the library build options while /MT and MTd are the multi-threaded application build options.
Cherno did a video in the playlist already discussing this, I believe its in the Github video. Not much code going on in it, its a talking video so I think a lot of people may have skipped over it.
I would need to check again to be certain but there are TWO lines needed to properly set it. One sets the debug/release state (that lowercase d after the MD/MT) while the other determines if its a library or executable.
should WindowsInput be a final?
This is my earliest comment for your video hihihi
so confused how he could just use "auto [x, y] = Input::GetMousePosition(); " in the Run loop, how is the Input class aware of the functions we implemented on the WindowsInput? I get we overrode the Implementations on WindowInput, but I would have expected to have to use auto [x, y] = WindowsInput::GetMousePosition();
in WindowsInput.cpp @23:28 he assigns a new WindowsInput object to Input's static s_Instance variable :
Input *input::s_Instance = new WindowsInput();
do you ever explain how to change screen coordinates to world coordinates for the cursor position?
How and where did you learn how to code?
I learned it all from watching yt videos and google. :D
He went to university and did a lot of research and practice there I think
From DanisTutorials
Still here!
Please push the code on github.
I stated this series a couple of months late. I am current at video 9, "Event System", and am having trouble getting the code for that episode, along with spdlog, from the GitHub repository using git. git keeps complaining with fairly terse statements. Might anyone suggest a source for learning how to use GitHub, especially for cloning or downloading older versions of the code? Thanks.
Check the older commits. Sry for Late reply. :)
12:36 then make it final? thats what its for
@@marklinton4567 final is pretty basic tho right? if you are already learning about virtual and override final should be included
@@marklinton4567 ind thats pretty much exactly what final is for. it doesnt make sense to inherit from windows input
I use final override anywhere applicable.
you never called delete on s_Instance
Why would we need to? There's one instance of it across the entire process, and it exists for the lifetime of the application.
@@TheCherno Sure but that relies on the os to reclaim the process memory. I dont think that then ever calls the destructor of input instance. that might not cause issues now but a poblem could only be one refactor away. If it was a smart pointer it would be properly cleaned up on shutdown
@@gideonunger7284 - What kind of problem?
@@davidste60 Depends on the destructor.
@@gideonunger7284 - How can it if the destructor is not called?
Hello am new to the channel and i just feel like The compiler that you are using is too complicated for my liking. I find CodeBlocks easy and to the point. Nonetheless, i love what you are doing hands down. Keep on sharing @TheChernoProject👍🏻👍🏻👍🏻
Why don't you use Directx?
Because people who watch these series and use Linux would not be able to follow along.
1. Windows only
2. Harder than OpenGL