Framebuffers | Game Engine series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
that's what guys my name is the shona welcome back to my game engine series so last time we took a look at the beginnings of the whole I am GUI Dr situation basically being able to have a docking layout for our window and then that way we can drag panels around and we can dock them and do all that fun stuff check out that video if you haven't already that was last week's episode today we're going to continue on with that but we have kind of the new problem that we got up to last time which was how do we actually take our scene and the whole kind of scene rendering that we have going on and actually display that as part of a docking panel and the answer to that is when you basically need to render it to a texture and then we can actually use that texture as part of I'm GUI something that we are hopefully going to do today so let's jump into the code and take a look at how that's going to work so basically today's episode is gonna be all about frame buffers if you don't know what frame buffers are I don't think I actually have an OpenGL video on that I probably make more OpenGL videos if you guys want to see that as part of the OpenGL series and you want it you want more information on frame buffers in general from me then let me know and I might you know make an episode on that hopefully but as it stands right now I think that I'm missing a lot of things in that in that series unfortunately so that's the way it is let's fade to this so you guys didn't really say anything I don't know I didn't see too much about the FaceCam so if you if you you liked the face cam if you want to keep the face cam and you know let me know if you want me to remove it let me know and I will I will do whatever you guys want because I am such a nice person that way you know also because I can't decide whether I like it so let's not talk too much let's actually do some work because my goal as I mentioned last time last time we took we talked a lot about what we actually wanted to do with hazel in general and I think that I think that a big thing that we wanted to do was obviously other the big thing that I kept talking about was that I want to get it to a state where you guys can actually make 2d games within the hazel with no c++ no no like maybe a little bit of scripting into the program but no like C++ programming or anything should just be able to construct it using the editor so we obviously have a lot of work to do and I'm gonna stop talking about that so this is what we did last time we had this kind of image being displayed with I'm GUI and today what we're going to do is when I kind of build on that and we're going to implement frame buffers so what we need to do is this and it's also it obviously helps to define what what it is you need to do before you start working on it let me just enable this I added this I didn't commit anything last time during the actual episode I did that kind of stuff just making sure that I'm recording I did that kind of stuff afterwards when I actually like stopped recording and then I was like what was kind of useless because if I commit this and push it to the main branch maybe I should have branched and like made a new branch branch branch whatever I still don't think I've decided how I want to say it but anyway I probably should have done that and maybe that way it would be okay but pushing to master you know in a state that did not render the 2d scene draw because we had docking enabled you know but no actual frame buffer setup I thought that was a bit a bit bad to do so I quickly added that little bull in there so because this is what this is the actual view right this is what we have we have this full screen hazel engine kind of editor with this kind of panel that is dockable as long as it's actually part of this window because you can also drag it outside of the window like this if you do this you can see it's actually a separate window over here we have the settings window and you can't dock this I think until it's like you know if you grab it a certain way or whatever it has to be in this view like it is now and then you can like dock it or whatever I don't know sometimes you can like that so it's a bit weird anyway this I'm giving stuff is fairly experimental as far as I know so they haven't finished it so hopefully everything will get better so anyway yeah so we have this we obviously have no scene our goal is instead of rendering this extra let's render the scene to add extra so how do we do that it's actually very simple frame buffers aren't particularly difficult to deal with in OpenGL basically like creating a nice API for them is probably harder than what this is and in fact I did want to I remember maybe we'll do this next time I did want to actually create a new project being a kind of editor project because this is currently in sandbox and it shouldn't be and for that reason that's why I had to do these these crazy hacks but anyway docking is going to be enabled and hopefully we will have something on the screen today that is from our frame buffer so the first thing we want to do is basically look at where we're doing all of our during which is here and what we want to do is instead of rendering this scene and doing like the clear I guess as well and doing all of that stuff just like this we want to first bind a frame buffer do all of our stuff and then just end the scene and that's it and if we have a actual texture attachment into that frame buffer which acts as our color buffer then obviously when our scene gets rendered and all of that stuff gets rasterized it's going to you know it's gonna go into that texture and that texture is going to be what we're going to then display this is very very similar to the actual like swap chain and everything is just an open gel you don't really control the swap chain something like a Vulcan you explicitly make basically frame buffers or textures for each kind of swap chaining image you have so in other words if you're using like triple buffering if you've got double buffering uh triple buffering you would have two or three actual textures and you have to make that as part of the Vulcan swap chain not something that we have to do in OpenGL has done for us and so because of that I actually think it makes this part maybe harder for some people because they're like what what's going on well all that's going on is that again we're creating a texture literally like any other texture there's literally no difference in the simple case there's no difference that's just a regular texture and then we're saying that hey render our scene to this texture instead of rendering our scene to the screen basically even though behind the scenes technically of course it gets rendered still onto an off-screen buffer and then swapped onto the screen now the only other thing to take note of is the fact that a color buffer texture is usually not enough we also usually want a depth buffer texture now technically we run during 2d stuff only and my opinion of how to render 2d heat is pretty much don't use the depth buffer even though we're doing that now this is just for simplicity sake but usually if you're rendering 2d you probably want to avoid that using the death buffer and simply render everything in reverse order that way you'll always kind of you won't get things like the Zed fighting for example because you're rendering stuff in the same axis on the same Z value because you're not there you're not supposed to have a Z value if it's you know you're not supposed to have depth in a 2d scene otherwise it's not really technically it's 3d anyway let's uh let's actually let's get on with it I don't know if you guys like these kind of chats as I don't know if I feel like I've been like between you and me feeling a little bit insecure about this but I just feel like I've I don't know if you guys want to necessarily hear though if you just want me to get to the to actually writing the code because obviously like we're still going to write all the code that we set out to write today it's just that it might result in longer video for you and for that I'm sorry if you're not into that but if you are then great because I feel like talking sometimes all right anyway um so the first step really is to create you know a frame buffer class I'm not gonna write any OpenGL card here to demonstrate how it works because that's probably something for the OpenGL series so once we inside the renderer I'm going to make a new file here called frame buffer dot H and it will also make a frame buffer dot CVP and then under platform OpenGL we're going to make a class called OpenGL a frame buffer because we're going to have an implementation for OpenGL now a frame buffer itself can have a lot of different a lot of and I think some people were complaining about the text being too small transmit more um a lot of other things yeah frame buffers so frame but the the thing that this is way too big the thing that was the thing with frame buffers better sneeze I came back from my sneeze break the thing the thing about frame buffers is that desktop there's a lot of different there's a lot of information that you might want to specify it's or because the way the frame was the way the frame of his work especially if you spent any amount of time with them you'll find is that the this is our McCall this is normal in renderer the way that they work is that rather their use cases and the things that you want them to be able to do is actually quite quite comprehensive because frame buffers can be used for a lot of different things you might be using a frame buffer like we are to simply render this scene you might be using a frame buffer as part of like a post effects pipeline but you also might be using a frame buffer as like a shadow map or like some kind of like what's the cool example I don't like maybe like your character we're characterizing grass and you want the grass to be trampled and so you might be like you know rendering basically the characters position onto like some mask which is like part of a frame buffer so you can then do some cool stuff there too like offset vertex positions and stuff like that like you might be you could use all of that stuff that I've just described uses frame buffers and so in some cases for a shadow map for example you might want a 2048 by 2048 frame buffer and that's that but for something like this you want the frame buffer to be the size of your window maybe you're trying to save some performance like if you're rendering on a phone or something like that and you have like a 4k display on like an Android device you can't render at 4k so what you do is you render it like 1280 by 720 or 1920 by 1080 and then you upscale it at the end so your scene has to get ran into a frame buffer which has a texture that's like 1920 by 1080 or something like that which is exactly half of the resolution of the phone so that might be a factor of like 0.5 or something so anyway you might have a lot of different things at play there and so you might not necessarily want a hard-coded particular size like 2048 by 2048 for a frame buffer you might want it to be a percentage of the screen and if the screen gets resized like on a Windows computer if you go fullscreen or if you just drag the window and you just make the size bigger then you will need to recreate those frame buffers and so that is something that I call like a kind of dynamically resizable frame buffer and then you might have something that isn't like that and that is fixed like a 2048 shadowmap so my point is there are a lot of little things to think about when it comes to frame buffers and that's why I'm going to introduce this new little thing that I like to do which is creating a struct called frame buffer specification and then this is actually a struct of properties this is just something that I've started doing lately in my code I don't really know where I got it from I just kind of because I came up with it I'm sure a lot of people do this though it's very useful instead of basically having a frame buffer constructor that could be very complicated and very long and might have things like you know with hide format you know whether or not the part of the swap chain if it's multi sampled or not you know there's so many different things that you might want to you know do you want to create a color buffer automatically if you want to death buffer like this might be so much stuff to pump to put into a frame buffer constructor that it gets overwhelming so instead and in fact we don't even have a constructor because technically we should be having like a ref framebuffer create because we actually need to create the correct instance but the point is what I like to do for classes like that is create this specification struct and this can have anything and the cool thing is it doesn't just it it's not just that it can have anything it can also have values for anything so for example I could have you know with and I could actually set it to something now this is a bit weird like with width specifically as an example and let me word base um with wit like this is it's weird to have a default width I guess potentially maybe the default which should be whatever the application width is but you know you can do stuff like this you know with high you know we could have for example samples and we could set that to one by default you know that's done that's the equivalent of just having like a default parameter that you set to one or something like that here but the cool thing is we can do that it doesn't have to be in a certain order because we're default parameters you have to have them at the end obviously and they might clash with other overloads and it's just a bit of a disaster but with this you know we can have it this way also probably need a format frame buffer format maybe you know we can set that to a default value you guys kind of get the point like we can I really like this approach and then all we have to do is just pass in like a constant reference of this into here as a constant of specification just spec or something right and this and that's that and then this can get stored as part of the frame buffer class so inside opengl frame buffer you know this this is extends frame buffer and then we basically in like privately here we just store the specification like that and then usually what i mandate is that we basically have to have a virtual virtual one of these virtual frame of a specification get specification ant's return I'm sorry this is pure virtual and then usually like you're and after that depends on the class but you can have a non-constant as well just because sometimes it might help to actually like sometimes you might to change the specification it's just that if you do then if you change it this way then obviously nothing will be notified of the change and if you change the width or height of a frame buffer you probably want to rebuild that frame buffer so that can be a little bit challenging I guess in this situation you probably want something like set specification or you'd manually have to call on specification change or whatever which is why we're gonna leave it Const for now but just know that this is like an option and for some classes it is quite useful as long as you actually call that code correctly and obviously when you're designing in an API you want to make it as much as possible you basically want to make it impossible to incorrectly use your API so yeah okay anyway let's pop over to the CPP file include our PCH include our frame buffer class namespace hazel and and I also want to implement this create function and I also want to include haslett platform and not inside hazel I'm just a platform platform OpenGL [Music] and then obviously what we'll do is what we do in every other render API class like vertex like buffer or something we do a little switch statement so let's copy that and then let's just say render a JP I and that's inside the renderer and then we'll return obviously an Open GL frame buffer and I'm gonna possum that spec okay that's that so I think that looks pretty good to me again with the format we'll deal with that and with specifically how we want to create color buffers and depth buffers and stuff like that might be something to do to deal with as well but what I want to also do here is I want to float some float an idea and that is we're gonna actually have a and I'll call this swap chain targets now this son sounds kind of fancy but what this means and this is just again a lot of this is inspired by hazel dev because obviously I work on those of you don't know which is probably none of you had this right but um I work on a version of hazel in my spare time so not on this not in this series it's called hazel dev it's like the development like branch of hazel and that's got like you know the 3d and the level editor and all that stuff that I'm getting to see ably explaining every time I mention he's all that but obviously that code has a lot of that code base is a lot larger and more mature because I've been using this stuff for like I don't know frame buffers have been in there for like probably over a year so clearly I've added and more stuff to them I've refined them and I've done all that stuff so a lot of stuff is that I'm writing here is inspired in fact I I mean I've got hazel dev open on my other monitor here and I'm probably going to be like to straight-up copying some code from the frame buffer class because I'm not gonna pretend that I have memorized the OpenGL API when it comes to making frame buffers so a lot of the inspiration comes from that and so something that we have there is something called swap chain target now the reason is that at one point hazel did work with Vulcan because I just had a little fun weekend once where I was just like let's jam in Vulcan so I did that into like this 2d version of hazel and I guess will will probably end up doing something as similar I don't know if we'll get around to the dis year but I'd like to because we probably will since we want to do max support and eventually Linux Linux can run up in jail fine Mac the Mac OpenGL story which is not what his videos about so I'm not going to take too long we're talking about this but we basically won't want to use metal on Mac realistically and then so because of that we'll probably end up doing metal before we end up doing Vulcan but again it's not gonna take two so I'm gonna take as long as you guys probably think um Vulcans gonna take a while anyway because it's supportive welcome there was like I made the single swatch and target this basically says that this frame buffer is supposed to be rendering to the Swap chain so in other words this is the equivalent in OpenGL as you find out soon if you haven't already if you don't already know it's the same as saying chilled by an frame buffer zero it's basically saying unbind all of my frame buffers I want to render to the screen so that's what this means so what this is what this allows you to do is it allows you to create a frame buffer that doesn't really exist this is important a little bit later because once we have frame buffers we're going to be introducing something soon ish called render passes and a render pass is not it's not it's it's more of an abstract concept in OpenGL but basically the way that I treat a render pass is a render pass is something that has a frame buffer has a target right so in other words if you want to render something you say render a begin render pass and then that ret and then you pass in a render pass object and that render pass object will contain a target for that render pass at the very minimum at the very minimum that's what a render pass is it's just a frame buffer and so that frame buffer can obviously be just the screen if you want to render directly to the screen then you have you have a frame buffer in that render pass that has a swap chain target of false and what I'm sorry so I print out of true and what that means is that that is not an off-screen buffer that is this screen so please render my render pass to the screen and that's how you eventually get stuff onto the screen in something like OpenGL where you know rendering to the screen means do not have a frame buffer at all this is getting a little bit ahead of myself but I just wanted to explain this video is gonna be now long I just wanted to explain like a little bit of my thought process behind like why you know why why certain things are the way they are because in the future like I'm a little bit more aware of what's going to happen in the future then I guess what I may be explained because if I explain everything like I am right now it takes forever so anyway let's go on let's get on with this so I swap trade target are we rendering to the screen or are we not all right so let's let's jump into OpenGL frame buffer and then obviously you know we construct this the same way we construct all of our classes and like render passes is something that actually easiest in development so in Vulcan there's actually like an object called like a render path so the same way that we have like jail frame buffer like we have frame buffers in OpenGL Vulcan also has render passes so in like a render pass in hazel would translate to an actual real render pass in Vulcan but in OpenGL if that's your api of choice like if your rendering using it OpenGL and hazel then obviously it basically emulates that but the thing is it's not like emulating it as bad in fact I like the concept of render passes I think they make a lot of sense and they actually kind of help you organize your scene all the better in my opinion okay so in goes the cons frame of a specification and then you know I'm I don't really want to do a 180 on this entire card base but the way that we've been setting this stuff up some of the stuff I want to change for example buy it unbind I'm not a big fan of this it's something that a lot of is something that I liked in as part of the OpenGL series I decided to include it in hazel but using it in hazel def and stuff like it's not bad but I don't necessarily like this object-oriented approach all the time so we might be making changes to that so what I'm gonna do is I'm actually not going to well I might have to because we don't have a renderer yet but basically in the future like I would not expect frame buffer to have bind unbind because a frame buffer should just be an object which is essentially a set of data that the renderer then basically looks at and does what it needs to with that data so in other words like you know we're still going to have you know you and 32 T M renderer ID or whatever I think we look at texture yes we're using you and 30 T's for that cool just it could in hazel dev I have like a I have an actual render ID type so sometimes I just like to make sure that I'm doing right thing um anyway [Music] let's press and look hard let's create this stuff specification okay so the idea is here we want to actually create the frame buffer so we'll type in create and the specification has been set now I the way that I like to write this is actually by having bass appeared they could be a public function even called resize and resize basically just resize it recreates it I mean you could call it invalidate you can call it anything you want maybe we'll call it invalidate because resize implies that it should take in at width and height but we're actually reading it from the specification so invalidate basically just says and in hazel dev it's called resize so again like you know not that's really consistent but in this case I thought maybe invalidate would be a better word yeah so invalidate says that the state is not valid so recreated right so what we want to do here is include Gilad and we're gonna write some open GL code finally so this is going to basically say GL create frame buffer frame buffers we're gonna pass in that renderer ID straight away we're going to delete frame buffers in the destructor because I always forget that and then people with full requests come in so we'll bind the frame buffer I'm I don't need to bind it it depends how we use it I guess let me take a look at some hazel dev card so the next step really is to create a color attachment I mean because that's what a frame buffer really is made out of so usually what I do is create textures and then we have like a color buffer attachment so we'll say color attachment now the thing is this should be completely dynamic and customizable you shouldn't necessarily be doing this for every frame buffer because you might not need a frame buffer with a color attachment well maybe you need a frame buffer with full-color attachments well maybe you want to frame buffer with a depth maybe you want it without that so there's a lot of customizability when I comes to this it's just that since we're kind of you know not trying to ride a super super cool spring on with this size the target you're gonna be at extra today because we're not trying to create us like a super uber frame upper class today I think it's fine to do that now I am binding a texture and hazel dev coat but I think I don't need to do that because the idea is what I want to do there's two ways that this goes you can either use I think texture storage or you can use texture image now these are actually different and I think it's just probably text image today I'm not understand sure what the API is text image though since it takes in a target and not a type imply it like it makes me think that it's a bit old but ultimately the difference between an image in a storage is that a storage as far as I'm aware is something that you can't you can't late a sample in a shader because it's like it's just something that OpenGL might need internally for example a depth buffer is not typically something that you sample in a shader like and I just mean in our case obviously in 3d graphics sampling a depth buffer initiator is extremely useful but for what we're doing for example we've never had to do that yet and so therefore if we were adding a depth but for attachment to this we wouldn't necessarily need it to be available as an actual texture that we can bind and then sample from so in that case we could just use two extra storage because we need the storage for it but we don't need the access image implies that it's something that you can actually that you want to sample so again there's probably a I don't know why it's not coming up but there's my brain maybe like I feel I thought guilt extra image to the exists but it doesn't but I don't know I might be completely wrong here because there is texture storage but there's no texture image so maybe social storage is what you're supposed to use but I get I'm not sure if that's ample able whatever maybe someone in the comments knows more than me and would be nice enough to correct me so this visit are the format okay so what we're gonna do RGBA eight so the what that means an RGBA you know eight bits per channel kind of for sorry yeah 8 bits for channel right so one byte per channel for Matt here you know this is something that is likely to change because they imagine it would probably be rendering even though it is a 2d scene rendering in HDR is nice in which case we use GA what is it just float32 air for 1604 what is it is still odd your base he's gonna have I think float16 F or some other format maybe I think you were saying else anyway RGB i-16 f is what you would use for or 32 F is what you would use for like a floating-point texture essentially something that is not in that 0 to 1 range and can be like high dynamic range so that you can store color values greater than your normal kind of range which is useful because then you can you know map them into the appropriate space and do what do whatever you want with them later because you have that extra information but we're just gonna stick with RGB a RGB a 8 this is something I would probably don't even need a here but we'll keep it um this is something that is in the frame buffer format but we're just gonna get this up and running today and then we'll it will probably flush it out maybe next time or my favorite thing to do which is just flesh it out Adam we need it so specification with high it's a border of 0 format this is the data format so this will just be geo RGB a now unsigned byte is the type and so we're basically making a normal texture now you could again abstract this out and hopefully you guys can see that basically this is what I've written here you can abstract this out and just you know basically say you could just create a texture using our texture API I'm not a hundred percent sure if I like that because that means that you have to extend your texture API to be to play nicely with the frame buffer which maybe you want all of Europe and gel code to make a frame buffer inside the frame buffer class and not not abstract your code away into a million other files that's something that can obviously add confusion and make everything a lot harder so in that case you know maybe maybe Dart track it out but for now we'll leave this is we'll try and have all of the code that we need in like all the OpenGL code we need inside this file so that it's a little bit more clear at least for you people at this point so texture parameters like I want to set the minification filter so GL was a text me and filter so this is obviously what happens with some Selenia this is what happens if we're down scaling our texture and up scaling our texture this is the kind of way that we want to interpolate those pixels linear is what we want here and finally we need to attach it so GL frame buffer texture 2d this just attaches the texture so the target is geo frame buffer GL color attachment zero is what we're using here so again you can have a lot of different color attachments like ten well then that was ten that came up yeah ten is tens the maximum amount that no it's not 30 so it's 30 32 different texture attachments is what the actual header file supports the actual rendering capabilities obviously up to your GPU drivers and everything like that so text target is going to be texture 2d and then what else do we have here the texture which is color attachment and then the level which i think is the edges zero the only thing we haven't done is we haven't found this now I don't know if there's a function that's the problem with this new OpenGL stuff there's so many different functions and like a render buffer again is something different something that you maybe that's what I meant by Texas storage in texture because I render buffer I think it's something you can't sample from anyway I don't know I've have too many rendering api's in my head and I always have to look this stuff off and obviously this is very live and I don't have the refugia reference in front of me ok sir anyway let's bind the frame buffer as well we forgot to do that very important with frame buffers specifically that you are bind them because you might not necessarily be binding them all the time like you might not be using them all that time so in that sense it's very important to make sure that you aren't buying them because and what am i doing geo texture 2d because if you forget - then maybe nothing will render onto the screen anymore because you accidentally have some random frame buffer back okay that's that now I will quickly also create a depth buffer so to create a depth buffer what do we need to do let's see so we'll create a texture and this will well I'm just using a texture 2d here one and this will be our def attachment and then we'll do binds texture and we also need to sit boy like multi sampling and stuff like that here which is again something for the future color attachment and depth attachment and yeah these attachments will be dynamic as I mentioned in the future so depth - mint all this fun stuff let's do GL text storage or jail text image beauty so you can use gelled text storage here target is texture 2d a level zero internal format GL depth 24 stencil 8 so will include essential buffer you wit as the witan high source specification with specification high now I'm not sure because this word now but in hazel dev it says I'm actually still doing a text image I've written text image 2d gel texture 2d zero depth stencil 8 we have a lot of stuff here actually I'm going to ensure what this card is with height 0dl depth stencil unsigned int unsigned int 24 8 which is just referred to the first 24 bits being for the depth buffer and then the the next 8 bits being for the stencil buffer and then no so I don't know this is what hazel dev has so clearly this works but I'm gonna try text storage today because we can't return the way that we're making business just for urban gels use then finally we just do frame buffer texture 2d frame buffer and depth stencil attachment we could have made we've made it without the depth the stencil buffer but in this case we'll include it in deputation to 0 all right this is that's it so the last thing that you should do definitely is you should basically just check the frame buffer status so this just basically checks to make sure that you know everything's working so if the frame buffer status right if it's equal to frame buffer complete then the frame buffer is completing done everything correctly so let's wrap that into an assert and then you know we'll say frame buffer is incomplete so this was basically just a little check to make sure that our frame buffer is a plus plus all right that's it finally what I'll do is I will where we out here oh what a long episode the void binds [Music] void on vines so these we are gonna have this for now just because our API kind of needs to have them work we also need to have these so let me just but this is like I probably would remove these in the future just because you shouldn't really be taking a frame buffer object and then calling bind on it that's very much out of con that's violent like that because what is binding a frame buffer just in out out in the open like what does that actually mean doesn't do anything needs to be part of a render pipeline you know it needs to be part of like a literal literal renderer so that's why I like to relieve that stuff up to the renderer anyway so we have these now let's implement them I get specification is something that will just do here so override return spec okay so binds obviously just calls this and I'm Barnes just call this and I don't really like to call Barnes here because I think that's a bit weird or he or other this should just be the opengl card like this fine okay and also because we might not even need to bind them because if there are functions in Europe in jail where you don't need to use the whole state machine things and then we don't firstly use them okay that's that no no this is gonna work um the last thing we actually need there at least right now is if we want to be able to get a color attachment out of this so for now I just add a new entity here called get color attachment renderer ID so what this is going to do is just return the color attachment so this is just that we can bind it as a texture because it the idea is we should just give that to I'm GUI so this now becomes no that's fine I think yep okay so basically if I've done this right which is very questionable but if I've done this right then we just go over here we we frame buff up in hazel then it over here we can just say hazel raft hazel frame buffer then we do frame buffer okay so this is how the whole spec system works so we do hazel frame buffer specification if the spec F and then you can call it something actually good not FB spec but we'll set the width to be well this should be the size of our window which i think is 1280 by 720 I don't even set that window create just takes in I think it just has some default parameters here 1280 720 so just for now you know we'll talk about this more later but we'll set it to 1280 by 720 what else we need I think everything else is yeah samples are set to 1 and we don't even using that and for checkpoint sauce and we're not using that so now we can create the frame buffer so this is hazel frame buffer create we pass in the spec so that's kind of help that's what that's what the card ends up looking like unless you have like either constructor here or you have like some kind of other things that you can set up usually it so you can obviously also set it to like an initialize list like any other struct or class really in C++ now what we need to do is when we render stuff we've always at the clear color and do all that stuff let's do a quick little render a prep we'll do a frame buffer vines and then we'll do an on bones and that's it so now we should be rendering us into a frame buffer what we should then do is decide to draw that on you know I'm GUI so the way that we currently were drawing this was we were doing the checkerboard texture and righty let's do something a bit different let's do and frame buffer yeah renderer get a color attachment render IDs now we're getting the color buffer from that frame buffer which is where everything should have been rented to and we're ordering it let's not draw it as a square cuz it's kind of bad let's do like well 16:9 so if we do 320 by 180 and that'll be 69 and maybe the elbow class that's just you know let's see if this works because I'm very doubtful I probably messed a lot of things up as usual yep okay so what are we looking at here we have a frame okay so the frame F is not complete do we have any other OpenGL exceptions okay levels width and height must be 1 or greater okay so something's weird here invalid value generated there's a clearly a fatal there's another thing that I'm not very happy about in our era so does Chloe happen happen from somewhere here and it looks like some looks like something may have been wrong we are with ah what's this border no this there might have been a place where I accidentally set levels to 0 levels so this should be 1 I believe that's probably it but we should also you know nah she's not happy about the framework mean okay let's let's switch to the hazel that part just to see if that's the issue because obviously this code I have actually tested and is working so let's make sure that that's not the reason and doesn't like it is what a hater okay frame buffer incomplete what did I do you guys probably laughing at me um well for one I mean I didn't bind the texture because I think the reason I didn't automatically bind it by the way is because I was hoping I wouldn't meet you because if yous like there are some I don't know I didn't need to get caught up on this but there are some like OpenGL commands that have stopped taking in this stupid thing here and started taking in the actual ID and they're kind of like named buffers and you know other things I don't know if there's a named texture there's named frame buffer texture made buffer data anyway I I'm kind of using a mix of the older new API which is why you know in this case I'm binding it which is great but I think I wasn't binding the color attachment and that may have been the reason yeah it was a reason okay so now you can see that what have is we have the screen here that's what we're rendering except now it's like a little texture that we can see anyway let's quickly go back to the texture storage because that should work as far as I'm going they're all pro the real problem was me not binding the texture yeah ok great so there you go so now obviously what we want to do is instead of making a tiny like this four four one let's make it 1280 by 720 maybe because that is slightly small so we'll do 1280 720 here and that will be at least a little bit bigger and obviously it'll just be the size of no okay it's tiny why is that why is the image so small isn't that the image size 1280 by 720 hmm that's a bit weird maybe that's yeah that is odd I don't know why the image is so small oh well I guess that's the way that it is everything else looks good to me maybe there's some other sizes controlling it or maybe maybe I'm just a buffoon it's probably the latter because I'm editing the wrong the wrong code path because I forgot I had to because that that by the way something that I made for off camera for another episode for the to make sure that you could rent at the same last time because that's the way it worked you'll ever see we removed any kind of by enabling docking we removed the screen buffer being rounded as I had mentioned and I wanted it to be rendered so I just copied the code I made two code paths I don't know why that was so hard to explain um anyway yeah so there we go here's our you know here's all frayed before you can see that we're rendering it and we're displaying it as just an I'm good image so this is basically like step one write the next step and what we'll do next time is we basically want to take this and actually make a proper eye and glue a panel out of it and then oh and obviously Kiva's are still here they're act they're actually active not in this window so if you click here in the press levitate doesn't work but in this window and there's some things you can do obviously to fix that but ultimately my point is everything still works and you should be able to you know do everything like normal but minimizing the windows also pauses it because that's what we do I think if our main window is minimized we yep if it's minimize we stop updating everything and obviously it minimized is the main window not the window with the scene so there's a few things you need to do if you want to support this specifically which is having multiple windows but if it's all in here then obviously everything works as expected and you'll never be able to do anything about um so yeah so next time what we want to do is basically take the let's say to the full cover view what we want to do next time is take what we've done here and actually make an IM Glee panel out of it so that you know we have the viewport panel basically and then we can we can set the frame buffer size to be whatever these size of the panel is so we take the panel size from I'm GUI make that our texture and frame buffer size and then use that I hope you guys enjoyed this video if you did please hit the like button don't forget that you can help support the series on patreon.com thoughts after the Cherno huge thank you to everyone who does that is the reason why we are here today so huge thank you to everyone I really appreciate it looking forward to next episode I'll probably release it this week because I'm having a lot of fun with this and I obviously want to want to hurry up with this so thank you all for watching I'll see you next time goodbye [Music]
Info
Channel: The Cherno
Views: 41,186
Rating: 4.9543624 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, framebuffers
Id: 93bavRgVcwA
Channel Id: undefined
Length: 45min 22sec (2722 seconds)
Published: Tue Jun 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.