Clearing Framebuffer Texture Attachments + Git Branching // Game Engine series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys my name is china welcome back to my game engine series so last time we did some frame buffer stuff to do with our mouse picking journey check out that video up there if you haven't already and basically today what we're going to focus on is two things i want to talk a little bit about our general kind of get strategy for hazel and for this like game engine series version of hazel because we're going to start creating branches and various other things as we get into more complex features and then the other thing i want to do today is deal with our clear color because basically what we did last time um i'll show you a few things actually what we did last time was inside our um fragment shader we were now able to with our new texture attachment inside our frame buffer we were able to output an integer and in this case we just arbitrarily chose to output 50 into that actual texture so that we could eventually store our entity ids for every pixel that we actually render now the problem with this at the moment is that if we load up a scene like this pink cube for example uh when we're over the pink cube right you can see that it is in fact 50. but for all of the pixels that are just in empty space it's this weird value the reason is this weird value is because if we're not deliberately actually like rendering a pixel into that spot in our texture then it's going to be set to the clear color because that's what that's what we do first we clear the whole screen with a particular value essentially with a particular clear color and then pixels go pixels that we actually rasterize go on top of that well they get overwritten with the new values of whatever pixel we've just rendered so again it's fine for when we're over this but if we're over this kind of empty space we don't want it to be this which is i mean presumably whatever our clear color is and if we go back to editor layout we can see that at the moment we're using this little render um render command set clear color function to set it to like 0.1 0.1 0.1 and then one for the alpha this is clearly great for our rgba kind of main color buffer but not so much for our integer buffer that is supposed to store the entity id instead we'd like it to be negative one so basically what we need to do is clear the second color attachment so we have two color attachments zero and one zero is the main rgba buffer and then one is that kind of gl red integer buffer and again if you don't know what i'm talking about check out the previous episode um we need to clear that to negative one and that's what we're going to do today so we're going to learn about clearing individual frame buffer attachments instead of everything which is what gel clear will do but first let's take a little bit of a look at uh fork actually so fork is a get client that i really like and that i use um this applies to any get client out there i just happen to like fork now we have a whole bunch of stuff here that i haven't actually committed right so this was the last commit on the 23rd of january which was like updated editor layer with frame buffer api changes and uh well no actually it was this one that was just a little extra commit because i forgot to commit to commit like an important part of everything but anyway so you can see that all the changes um that we added were kind of just to do with the new frame buffer api but now we have something that kind of uh i guess puts me on a little bit of a crossroads because we have a whole bunch of changes here that change the way that hazel works but it's not necessarily keeping it stable in a way right so as we embark on this um journey of like mouse picking you know we wind up with uh you know in this case a version of hazel that has an extra an extra like texture attachment inside the frame buffer that outputs the value 50 prints it to the console and i mean doesn't add any value to anything because it's more mouse picking isn't done yet so in this situation what do we do and this again this might be like a little bit of a primitive episode for a lot of you who are building game engines and know how git works but don't forget this series is for everyone so i will cover things like this from time to time so instead of basically um you know keeping everything in the master branch which basically means that we have this master uh branch it is like our kind of main uh well at the moment it's the only kind of flow of the repository i guess every time we commit something we basically take a snapshot of our entire code base and any files we have at that point in time uh and we can kind of scroll through and revert back to anything we want and see what what changes every single time but what if we want like an another copy of that somewhat temporarily right i mean maybe we'll keep it forever maybe we won't but we want to basically divert from the kind of main point of the code base so that people can still access this commit which is which works and which kind of you know has the main let's just say hazel example but then we also want to kind of branch off of that and commit in our own kind of uh you know track of code or whatever as we develop new features that might not might not necessarily be done yet and might not be stable enough for for them to actually be mainline or part of the master branch so what we can do there is just create a new branch basically and again this isn't like a little git tutorial but for those of you who are unaware of why i'm doing this basically what i'm going to do is while we do this mouse picking stuff until it's fully done it's going to be on a separate branch which i'll call mouse picking and then once that is done it's going to be merged back into master so if you're watching this series and you're wondering where the code from this episode will be it's not going to be on the master branch it's going to be on a different branch and i'll actually show you how all of that works as well so in fork we can we can still go ahead and like stage everything but um what you can do with branches is just create a new branch i'll call it mouse picking um and then now i'm well i can check out the mouse picking branch right i'm not going to change my local changes at all right now i'm here and then when i go ahead and commit everything now it's going to be committed into the mouse picking branch which has branched off of master at the at the commit that i was currently at which happens to be the latest commit if people commit in the meantime to master and those branches are now different then you'll have to merge but otherwise it should be pretty straightforward let's stage all of our changes uh now we have so this is actually from last episode all these changes i think i just cleaned up a little bit of the formatting here to make it look nicer and yeah so that looks pretty good so what were the actual changes so we added um geo red integer basically as a format add a gl red integer as a frame buffer format plus uh uh test plus test whatever so i'll come in and push that so now you can see if we go back to all commits we're on the mouse picking branch and we've got this stuff here so i've pushed that as well and i did that on purpose so that i could show you guys who uh want to actually view that code of that particular branch if you go to the hazel github which is um github.comhazel you can just go to hazelengine.com it'll take you here you can see that we have this master branch but then we also have mouse picking so you actually have to click on mouse picking and then you can view the code of what i just committed right and obviously if you want to clone it you can you can go ahead and like uh you know clone the whole repository first and then do like get checkout mouse picking to check out the mouse picking branch you can clone the um or you can pull you can probably clone at yeah you can clone and or pull the mouse picking branch immediately but just by going like get clone like you do here um git clone rehearse recursive but just add a little dash b and then mouse picking and then that will immediately clone the right branch for you sometimes that's useful because branches can be well completely different one branch might be 10 gigabytes one branch might be one gigabyte so you might want to immediately get the branch you're after so you're not just cloning stuff for no reason waiting around thank you wolf by the way will frick for your uh subscription so anyway that's the basic idea we're gonna be on this mouse picking branch a little bit of backstory as to why we like to do stuff like that um but uh we'll be doing a lot more of this in the future just because uh obviously we'll we'll want to leave we basically want to leave master in a decent place so that people who just want to check out hazel and seed actually work will be able to do so without having random stuff show up in their console and potentially you know experience hazel in a broken state which is now something we can do here we could we could even make a commit here that just doesn't even compile i mean probably wouldn't recommend that unless you're doing it for a reason but you could just commit here and not even have it compiled because you have the master branch that is stable and then this is like a development branch and anything goes there okay i think that was probably a little bit of a long-winded explanation there but hopefully uh everyone is on the same page now okay so how do we clear this thing how do we even clear a particular frame buffer um texture attachment well there's a function that we need to run essentially called gel clear text image that allows us to clear an actual texture with a value right so um as always there's this really nice side i think i've mentioned this before but it's a really nice little documentation site for opengl called docs gl um even has a dark theme that is sometimes annoying because i think when you load a page it goes to white first and then flips to like that so it's like a little flash so i don't really like that about it but aside from that it's a great little site keep it on light you can type in a function here and um check it out so it feels all fills all a texture image with a constant value that's a great explanation so far feels all an image contained all right whatever anyway the point is that this um this fills a particular image with a particular value that is inside a texture so you can specify the texture the level um uh level of attachment region filled the format um the type and the data right so the idea is that we should be able to use that with specifically the first color attachment because as you um recall we obviously created two textures here one ended up being an rgba which was color attachment zero technically and we specified all of this in our frame buffer specifications over here we have rgba and red integer so for the red integer which happens to be color index one or sorry texture attachment index one color color attachment index one really um we uh we uh want to clear that with negative one specifically just that one and furthermore it's important that we do this after we run clear so when we have our render command clear over here that will actually clear all of the attachments in the frame buffer to this clear color that's what gel clear does we want to after we clear that we basically need to clear our entity id attachment we'll call it two negative one that's our goal for today so how do we do that and how do we develop an api for that so again the function that we need to run sometimes it helps to write this down so let's go to frame buffer binds and then what i'm going to do is uh call that function gl clear uh text image right geo text uh gluing texture is the first uh parameter so that's actually going to be the texture id now we have a list of all the ids here in color attachments so we know that it's going to be one this should maybe be something that we parameterize though next um is the level zero that's like the mip um format will be uh well in this case gel red integer the internal format type is int because that's what that's the type of i think that's the type of data that we clear with so if i bring back our documentation the type of data whose address is given by data right so this is not necessarily the type of data inside the texture it's the type of data that you're providing with this right so um it'll be an int and we want to basically pass in negative one so we're going to have a value of negative one and then we'll pass in the memory address of value and that's our function if we run this right now it should actually clear everything to negative one now the problem is that we want to obviously make this a little bit more modular so how do we deal with that [Music] okay so to do that let's go back to frame buffer and define an api for this so how do i even come up with an api for this well clear text image i mean like the name itself is decent right um we could say clear attachment clear texture attachment or something like that it's clear that attachments are textures they could be render buffers but we won't worry about that for now we could call it clear attachment we could pass in an index for the attachment so this won't be a renderer id this will just be like zero or one or two depending on which one you actually want to clear um probably should mention that it's the color attachment so maybe we could call a clear color color attachment maybe it doesn't matter i don't know i don't really care about the level i don't think we'll ever parameterize that and then the format also the format we can actually tell from this color attachment thing because aside from keeping color attachments we also have color attachment specifications which line up with these and those specifications of course contain the actual frame buffer texture format so we don't need this now this could be useful right how do we specify that it's an int well again this this is this is where it gets a little bit more complicated so we could assume that if it's gl red integer you're going to be giving it an int whereas if it's a gl rgba you're giving it maybe a float right we could actually imply that um and that might be the best way to go and then finally the value we can leave it as a const void pointer we could actually template this so that we clear it with an end or a float and that way we could also control this because obviously it's the data that you're providing here but again it's just one of those things that i don't know how complicated we want to make these but those are my thoughts regarding designing an api for this particular function that's kind of how i feel about it so anyway um so let's let's actually put this into action now so in the frame buffer class i'm going to uh and and you know when i design apis like this i don't really like to spend too long on them because i think that it's much more beneficial for you for it for an engine programmer and for probably everyone watching this series to just actually implement the code and then have to rewrite it rather than spend a day planning stuff without even knowing what's going to happen with this because when you're learning about game engines and when you're learning about all this technology that you've never done before trying and failing is a lot more bet it's a lot more beneficial too it's a lot better than scratching your head because you you won't even you're not you're not even going to know what to do right you don't know what this stuff is going to be used for in the future because you haven't implemented a full engine right so instead of wasting time kind of thinking about oh but what if i do this or should i allow for that or this just write the code just write the code and then change it it's not immutable right it's not like this is getting printed onto like you know thousands of copies of like this bind of just printed source code and that's it it's written i can't change it it's it's easily um changeable right you can you can mutate this code however you like in the future not going to be huge you know almost never going to be a huge deal so just write the code and get on with your life and get on with you know making the actual feature work rather than concerning yourself over the api so i that's kind of you know that's my opinion that's my kind of uh rule of thumb i guess that's just what i do so that's why i never give a thought you know to this i mean like even looking at some of the stuff here because i was um talking to the stream about this earlier render command set clear color clear like this this stuff is is is like very primitive like you probably wouldn't do something like it's it's fine for now but ultimately speaking frame buffers should probably contain clear colors you know this is a great example of why a frame buffer should maybe contain a clear color because that's another thing we could do by the way we could specify inside frame buffer inside the actual texture specification we could specify a clear color for each texture and that way when you bind a frame buffer it might clear it maybe you don't want to deal with clearing inside a frame buffer maybe that's something that a render pass should do right so maybe the render path should have a clear color but then maybe the frame buffer should have the clear color but then the render path should execute the clear when the render pass when a new render pass is started if a clear is requested anyway this gets very complicated and again you know that's just a kind of a warning to everyone who's watching this series this is i'm not copying this code from an already written engine i mean i do have hazel dev but that's not complete either so i'm not copying it from an already written engine or from a textbook so this stuff will all likely change okay but that's kind of the beauty of it because you get to see an engine at different stages and you get to see the code at different stages as well um and you hopefully get to see the evolution of that which i think is really cool all right anyway um so to do to make this happen uh let's just do it the way that we initially planned which was basically a virtual uh void oops virtual void um what was it clear attachment i'm going to copy this attachment index um and then what do we want well that it no surely we had no that's it attachment index and value is really all we care about so const void value okay um so again it's it's relying on the attachment to provide you with the type and this will only let you pro only let you really provide one value i guess but if it's rgba it might be yeah so there's there it's you could probably add some asserts to make this a little bit more safe but ultimately it's um completely reliant on the frame buffer format and it's tied to that at the moment which you know may or may not be a good thing to be honest this is not a very common function to run so i don't think that uh we're going to end up regretting this too much so let's do our classic little asset to make sure that we're in here um and then we need to actually obtain the format right so let's do this order um spec equals color attachment specifications add attachment index right so by doing this color attachments and color attachment specifications are always equal in size um i think that's one of the first things we do here um is actually resize color attachments to the size of color attachment specifications so we don't need to check both of them um they should always be in sync in fact but uh basically um um so we've got the spec now we can check the format of the spec right the texture format so our the reason we even need this is because in order to run uh so let's get rid of this and let's get our example code down here so in order to actually run this code right we need the renderer id which again is easy so let's let's kind of leave this here as an example and then we'll write our eventual line of code here so color attachments um let me just have a semicolon to get out thing back um our syntax highlighting back so this is just this oh right it's the same it's just attachment index zero is fine now geo red integer is that format that i'm talking about so we should be able to get that from texture format because texture format is going to be set to red integer so um how do we go from a hazel format to an opengl format we write a function so static gl enum [Music] um hazel texture format to gl right we pass in a texture what was it texture format it's a frame buffer texture format uh fb texture format i'll do format and then we just have a little switch statement um and then if i go back to here we can basically see what the formats are and again i you know you don't have to implement all of them at once but this basically ends up being returned glrgba 8 i guess that's kind of going to be an internal format there frame buffer texture format that's what it is oh man i'll do this i might just use this and use these for color formats especially because it seems to be more of like an internal format and then i like to add a little core research false yeah just because that's obviously means that it's going to be an un um an unknown format okay so um now that we've done this and usually i like to align these oops there we go rgba and red integer so now you can see that what we should be able to do right is uh just do utils i might drop this down a line at least for now utils uh hazel fb texture format to gl um spec dot texture format now this is again similar thing can we get a type of data from the format um and i think we actually have something like this already um or we we did something similar we had to have right or did we not did we just do it manually i think we did the mail i think hazeldev has something like this um yeah so or maybe not yeah how does this know what format the data is oh it's always unsigned by okay okay let's copy this gl data type we'll just do gl data type or gel data yeah gel data type from format right so we'll give this format in and then we'll return gl float for this but no it's it's this is going to be unsigned bite i think there's four of them they could both be into though see there's one of those situations where you know what do you really want to provide um okay we'll leave it as end for now um but you could uh there's you know what i would probably do ultimately because i think again the problem is that this is actually nothing to do with this right this is tied with this this is basically just saying hey what what type are you providing because obviously opengl is taking out a const void pointer it could be an int it could be a float it could be four floats it doesn't know right so by providing this here we're just saying this is this is the type of data that we're accepting um what i was going to do is maybe imply that the type has to be related to this but that gets confusing because you can actually have multiple types based on the internal type as well so it's not really a good fit so instead we could call this int and then just say that this is a way to clear attachment with an int and i think that's what i'm kind of going to do so we'll provide an int value here it will do that and then that way these are always going to be the same and you won't accidentally ever provide a float because this function takes an end so i think that's what i'm going to do i was going to make it a little bit more arbitrary but you know you could always add another version of these that's float or even template it if you want to um but i would rather do this and then that's kind of it i think so let's get rid of this we've done it um let's collapse this onto one line because i think it's that's pretty long line we'll make it two um glint and value i think that is pretty much it so we don't need this anymore okay that's the function so now back in editor layer let's see if we can clear it so m um let's do let's actually leave that comment that's helpful so m frame buffer clear attachment one two negative one right uh and that's it i think that should work let's let's take a look all right there you go negative one so if we now open up our pink cube you can see we have a bunch of 50s we have a bunch of negative ones right everything is pretty good okay so that is how we clear a specific texture attachments within frame buffers to a particular value but i hope you guys enjoyed this episode if you did please don't forget to hit the like button below next time we're going to probably finish mouse picking honestly or at least get a good chunk of it done because we're going to actually make it so that when we click or when we hover over an entity we're actually going to get the entity id back and not just the number 50 so that's going to be quite fun don't forget you can help support the series and my channel by going to patreon.com there'll be a link in the description below of this video um you'll get access to hazeldev and to uh all these kind of past recorded live streams that i do where i plan these things and it's just a really good way to help support uh this series and everything that's going on in the community as well thank you guys for all of your support i will see you next time goodbye [Music] you
Info
Channel: The Cherno
Views: 9,353
Rating: undefined out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, game engine, how to make a game engine, game engine series
Id: LPhBiIvDOs0
Channel Id: undefined
Length: 26min 57sec (1617 seconds)
Published: Thu Feb 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.