Shader Asset Files | Game Engine series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
how does a guy as my name is Vicenta welcome back to my game entrance series it's a lot of time we talked about blending make sure the each check out of that video if you haven't already and today we're gonna be taking a look at our code and figuring out a better way to do something that we did before seems like this is kind of the way the programming goes in general you write some code and then a little ways down the road you figure out that well actually this kind of sucks there's a better way to do this now of course this isn't me specifically like accidentally writing bad code or than being like oh my gosh that's just as such a better way to do this that I've missed it's more or less me just building hazel incrementally or rather I guess iteratively and that's very common when you're building software to iterate over what you've already got and then change it as time goes on the reason is that our goal here kind of is to try and build up like an MVP a Minimum Viable Product will say as quickly as possible and then kind of retrace our steps and make things a little bit cleaner so I mentioned this a really long time ago I think when we created our first triangle where basically what I want to do is I don't want to spend a year writing code that is then finally going to produce a triangle for us but the car is gonna be rock-solid that's not fun for anyone no one does that really I've never heard of anyone doing that before because it's it's weird what you want to do is write that triangle basically as quickly as possible right not being completely crazy right I mean if we wanted to we could just write everything in one file and we wouldn't have an engine but we have a triangle right I'm not saying do that I'm just saying get that triangle as quickly as possible in a reasonable way right and then we can retrace our steps go over that code and improve it and make it more robust and just better and that's kind of what we're doing here in the shader episode right we wanted to basically load a shader and use the shader all within like 20 minutes and just have it running and that's it right what we're gonna do today is retrace our steps as to how we actually you know compiled shaders and basically change it so that instead just taking in two strings a vertex source string and then a fragment source string we're gonna load it all from one file and this is going to be super simple in fact I've made a video in the OpenGL series is called how I deal with shaders in OpenGL check that out because it's gonna shed some light into what we're gonna be doing here today it's gonna be slightly different than what I did in that video but like for all intents and purposes it is going to be the same so recently we talked about assets and we kind of introduced textures as our first asset and that was fantastic but now what we can do is actually go over to our engine and take a look at other things that should be assets namely shaders right shaders should not be kind of just defined the strings maybe it would be it should like it should be possible for your API to support that because who knows maybe someone wants to build an application in hazel and they want to have a little text editor I am GUI or maybe a custom control that's like a text editor and then you can like write some shader code in and then you can just like see the effects of that live almost like shared a toy or something like that as an as a hazel application that should be possible right now I want to make hazel as open as possible I want to make the API as powerful as possible so that you can do things like that so in other words we probably still want to keep the the I was going to say opportunity but we want to keep the capability of compiling shader code from strings we still want to keep that but we want to introduce them another way of creating shaders and that's going to be from a single file a shadow file now look if we talk about other api's other rendering API is not just OpenGL typically speaking like you wouldn't compile shader source code very often like you would have maybe pre-compiled byte data essentially that is kind of your binary shader and then you just you know run that for example you well you could compile it on a target platform because commonly you know if we look at large-scale games right what they'll do is they'll actually ship with they'll they'll be like a billion permutations and then based on your target hardware it will take the appropriate sections and based on what graphics settings you've chosen as well it'll take appropriate like shader blocks and then combine them all into a shade up locally on your computer right and then take that as like a caged shader and then that's the binary daughter it will load at runtime that's typically what happens obviously we're nowhere near at that stage yet but for us you know we're gonna kind of ignore that as far as I am concerned I don't think OpenGL supports binary shaders I'm not a hundred percent sure I haven't go on that fine to OpenGL itself because as I mentioned like I've been just quite a simple API I don't usually like dealing with it too often but for this for the purposes of this it's just fantastic obviously I'm not hating on Arkham jail at all I'm just saying that professionally I haven't like gone into there too far because you know like no one really ships games for Windows on OpenGL like that's not just not something that's done anyway my point though is that you know withs pervy maybe you can do something like that I'm not 100% sure how all that works so if you know leave a comment below because I will I will investigate this and I'm sure that a quick Google search could clear this out for me but that's besides the point so what we're gonna do is we're gonna take a look at creating shaders as a resource today we're just gonna be really really cool it allows a few things right first of all these are strings right now they're string the static strings in our memory right that's fine but the cool thing about having files is that it's almost like we've introduced a scripting language what we should be able to do theoretically and I mean well we will be able to do this 100% but theoretically what we should be able to do is actually take that file make some changes to the shader go back to hazel and we should see those changes live right there's no reason for that not to work all we have to do is recompile that shader right done reload the file recompile the shader and then that activate that shader instead right I mean if there are errors in the shader maybe don't recompile it maybe just display a message being like quoting from Paul shader but still keep that original shader until we actually get one that compiles successfully but my point is reloadable shaders something that should be really easy with this system so there are benefits to it it's not just the fact that I don't want strings here and I want separate files it's also which would be necessary who wants to have strings as shaders in their code anyway but my point is it comes with other benefits that you may not see I want to give a huge thank you to all the patrons that made this series possible patron record for such the show note is the best way to support the series and everything that I do here on YouTube people who do help support the series get access to something called the hazel development branch which is a way more advanced version of hazel with like 3d rendering and all of that fun stuff I have already done this kind of reloadable shader system in that code base so this will kind of be inspired by that and in fact I'll be taking code from dropping from hazel dev in order to make this stuff happen anyway let's get into the card and see how we can change our shader workflow so these strings here are exactly what I'm talking about I don't want to have these two strings here it's kind of annoying right I still want to be able to do this if I really really have to but I don't want to have these two strings here I want to have them in a file let's talk about what that file might look like I think the best way to write this kind of stuff is to first determine what is the end result right it's the same thing as when you're running an API you know instead of going in and trying to create a shader class just start typing code like shade of you know create and then you know okay I guess I'll pass in like my files so for example in this case we could have assets shaders and then well let's just say what are we actually using out of the shades we're using the texture shader so we'll say we'll say something like texture don't kill a cell right and then that's it that's that's kind of how we want our API to look so in that same spirit all right what we want to do is do the same thing with the shader so I'm gonna create a shirt at first before we even take a look at the code that we need to both load it and read the file from our disk and then also kind of split it up into two shaders because as I mentioned of course OpenGL wants two different strings but we're gonna supply everything in a single file who's gonna be super clean that way okay so if I show all files here we take a look at sandbox we've got assets textures I'm gonna make another folder here called shaders because that's where a lot more about shaders to live and then inside there I'm gonna make a new item I can just use visual studio to do this or of course you could just do this in your file explorer if you wanted to and we're gonna call this texture don't jello sell now I've called a jello sell specifically I don't want to call it like dot shader or anything like that you can call it anything you want August gonna be read in as a string but the reason I pulled your cell because this specifically is GLSL code that's important because in the future it's very likely that we'll stick with a single shading language most likely hlsl which is like the directx shading language and then from there we can cross compile it into GLSL if we need to using something like but anyway that's way in the future we aren't going to bother with that now but basically what I'm saying is we still want to keep this is gel cell because it's going to be useful that way now in the future in the more immediate future before we talk about cross compiling and other api's it's very likely that we'll actually modify GLSL and kind of turn it into our own shading language because it's not that difficult to do and basically it will just enable us to have a few more like keywords in the shading language that will help hazel kind of know the intended usage of certain areas so that's something that will probably happen I would say sooner then like cross compiling and all that fun stuff but we'll see because I don't want to promise anything because I haven't really gotten around to that yet anyway so let's look at what we're doing so what we're dealing with our texture shader we'll start with that one right what I'll do is I'll copy this is the fragment shader alright I'll copy that paste it here and then I will do the same thing with this vertex shader and I'll paste it in so we've got two shaders here obviously we need a way to distinguish between what type of shaders they actually are right so this is a vertex shader and then this is a fragment shader the way that I like to do this is just to type in the word type with like a hash here just the same way that we have hash version is like a preprocessor kind of directive we have the same thing with type and then I'll just type in the time right so this will be about text and then for this one I'm gonna call it fragment this is the fragment shader now you might call it a pixel shader that's fine I'll probably end up supporting both keywords but basically what this will do is have a little indicator for us being like okay this is good the following is going to be a new shader type keep going until you either see another type or until the end of the file right and then the next key word here is going to be the type of shader that it is so vertex fragment pixel you know geometry whatever compute whatever it might be in the future will kind of support that as well and then that's it now how lovely is it can I just point out to have both of your single file right I mean I hate having separate files for shaders DirectX has it usually as a single file as well which is super useful but OpenGL likes to split it up very commonly people will load they're two different shaders as two different files that's super annoying and I don't see the point of that at all you could argue that yes you could reuse the vertex shader for many pixel shaders but in my experience like I don't know I don't think that's that useful because commonly when I've been modifying the pixel shader to do something else I've had to modify the vertex shader as well like they've maybe I've got different uniforms maybe I've got a different vertex layout that all requires modifying that vertex shader anyway so commonly I wouldn't say that there have been too many cases in my life personally where I've been like I've reused the same vertex shader for like five hundred fragment shaders for example that's not gonna happen typically right obviously if you have a system in which you you know assemble shaders from blocks live then you'll very commonly reuse the same vertex block but that's something completely different and in that case you would still load the one file anyway so it doesn't it doesn't matter okay anyway texture there we've got the texture shader fantastic I'm just gonna delete it from here because I'm that bold and of course we will get this to work today so if we go over here to basically I'm just gonna hop over into share to create I'm going to add another trader career so I'm not taking away the easiest in functionality because I do want to keep that in case we want it and then Windows 10 just go away please I really really close to switching to Mac or Linux so there's our share to create function we've got our path I'll just call this file path to make it super explicit we'll come over here I'll just implement this function here quickly and follow along with this it really should be the first function I think because we did put it in that order in the header file then I'll copy this and I think we'll just have this across I think this just becomes file path it just becomes I think this just becomes filepath and that should be it okay I've been shall shout it from afar pop done sorry if we hop on over to OpenGL shader again we will duplicate this constructor and just make it a file path constructor and then if we go over to the CVP file we can take a look at what we need to do so we do everything in a constructor right now which is fine but not really what we want so what I'll do is I will probably make a function a private function here called compile and this is what we'll do basically everything that the constructor did so compile and then we probably want to take in the source code so let's take a look at how we're gonna split this up first and in fact what I'll do is I'll kind of have probably what will happen is both of these constructors will actually intellisense takes forever both of these constructors will actually just call into that compile method and in this this already has it in the right format which is fantastic but then the other constructor which will which we will create right now the other constructor will of course have to read the file first so we'll have our file pub yeah okay so as from reading the file let's get that out of the way quickly so basically what we want to do is take in an input file stream now look I mean in the future a file system in a game engine is a very complex topic like you'd usually have like a virtual file system you usually have to abstract this because obviously it's gonna be different on Android or iOS versus Windows and so you might need to like mount certain directories treat it like as a virtual file system you know you might have all of your assets sort in one binary blob and then you might have to go in there and I'll probably probably be compressed as well and so there's a bunch of things that you need to consider but obviously we're gonna keep it we're gonna be keeping it super simple here and really what's gonna use an iron stream this code in the final ever version of hazel right hypothetically I don't think this will make it right it will be completely different in that I mean realistically we might even have a per platform filesystem so we'd be using something like Windows like create file you know whatever to actually do everything and we need to do instead of using the cpp library so don't worry if you think this is fine oh did something not but if you're gonna get the job down there for now and probably for the foreseeable future for a while because it's definitely gonna be good enough for us so we'll take in a file path and then we will just tell it the between input file and then that we want it to be read as binary now you might be like why on earth you reading a text file is binary it's because we don't want to do any processing to it right this is gonna be completely just in the format that we want it to be in we want to read all of the binary data so that we actually get all the data from the file we don't want single us to take it and try and interpret it as a string that's completely unnecessary and something that I definitely don't want to have so we'll just include air stream here and we should be good so if that input file stream was successfully opened if it's not we could assert it because really you shouldn't be trying to load files that don't exist so what I'll probably do is just write a little warning here the reason I'm writing it well I guess we will make it an arrow the reason I'm not asserting is because maybe this might be permissible like you might try and load a whole bunch of shaders if they don't succeed that could be fine like we should still be able to handle what I guess anyway could not open file and then I guess we will supply the file file as a monument yeah okay that should be pretty good whoops totally cannot close that quote correctly all right so now now we've got our core error which is great so the first thing I want to do is actually see what the file size is and then our strategy is gonna be the greatest string that is that big and then load everything into the string so we'll do in seek G and we'll go to the very end of the file so offset of zero and then to iOS and right this will go to the very end of the file so now our kind of file pointer is at the end of the file then ideally I want to like basically create my string so we'll actually create the string here we'll call this um we're probably I call it result and we'll move this into another into another function because it's getting a bit too messy here anyway so we'll resize the result here and this will just be G which will basically tell us where that actual pointer is so thus since the pointer to the file is at the very end it is the size of the file now we need to basically bring us back to the start so begin and then we can read the file by just calling in dot read we're going to read it into the very first we'll just give it a pointer to the beginning of that string and then of course the size of the string which is the size the file will be our size so we're reading in that many bytes is going around to the string we've obviously resized the string here to the size that we want and that is pretty much it and then obviously at the end we will close that stream okay that's it now all we need to do is process this result so what I'll do is I will call I will make another function here called a rate file and of course will take in a file path to read I'll copy this and I'll put it probably just below the constructor here I may be bled the destructor and opengl shadow read file and then this will just basically be our the contents of this right ok cool so there we go at the end we'll return results so we'll return an empty string if this was not able to be read which is fine and then we can call read file and then now from pop off we have our string for processing so we'll have this our data source okay there we go so now we need to actually split it up into the appropriate number of shaders so we have our shader which has two different types here we now need a function that will basically read through that string and then based on these two types split it up into two strings where one string is this section over here and then the other string is this section over here so let's go ahead and implement that what I'll do is I'll create another function here before compile I'll call this pre process and the of course taking our shader source code so string sourced now what we want to do is split it up into multiple shaders as I've mentioned so we need a way to organize this we could just use something like a pair or a tuple or we could create a struct that has all of our different shader source codes however we don't even know how many we want right because this could contain two shaders vertex shader fragment shader it could contain more right for example we could have a geometry shader in there as well therefore that will be three shares right so because of that what I'll do is I'll actually use a map specifically an unordered map and what this will do unordered map is basically mapper map us from a GL enum which is going to be the shader type and we're storing it as a GL enum so that we can immediately just give it to OpenGL as like so basically the key of this map is going to be the type of shader that we compiled and then obviously the string which is gonna be the source code so that's gonna be our pre process and when we go into compile that's what we will take in right we'll take the simplest reference and this will just be our shader sources okay so back into C++ land well I mean we're always in C++ but I mean into the CPP file we will implement this function and now let's talk about how this is going to work okay so what I've done here is I've cheated a little bit I have taken this code from the hazel development brush because it's already written and there's no point in me writing this for you I will explain all of it in a minute there is one function that still needs to be implemented and that is the shader type from string that's really simple all that does is just convert a string to a shader type super simple function will implement that right now in fact I'll just do this at the top of this file doesn't even need to be in the header file we'll have a static GL enum and then let's see what was the name of that function datatype from string as well of course take in a constant string which is going to be our type and then if the type is going to do equal vs. so this is just the the final kind of tie price of what we see at the end of this so vertex fragment all of that kind of stuff so so if it's third text we'll just return GL vertex shader and then if it's going to be fragments I'll actually toughest down because it's gonna be a long line if it's gonna be fragments all will support pixel as I mentioned before will return a GL fragment shader and of course if we had other shader types then we would return that as well if that doesn't we haven't returned anything we'll just do a poor set here and we'll basically just say there's an unknown data type and then I guess we'll actually have the type here as well we can't format this can we yeah that's gonna be a little bit annoying okay in that case I will just write unknown shadow type we need to probably fix that so that we can actually format things like this but anyway there we go unknown chair type and then we'll return to 0 for our value okay sounds good we're back here let's talk about how this code works it's really quite simple so the first thing that we do is actually figure out basically the token that we're going to split on so type is the keyword that we're looking for hash type that's basically that basically tells us that after that token we're going to the next token is going to be the type of shadow right so what we do is we try and look for the type token through all of our shader source code right at this point this is all of this code and then if we find it right over fact while we keep finding it because obviously we'll look for it as many times as it exists we'll start with the top of the file and we'll kind of go down and for all of the types we want to find them all so while we still have found that type token so for the first time that we run through this code it will be literally on the first line right what we'll do is we'll find the new line the first instance of a new line or a carriage return this will find either right which is what we want and then that gives us the position of that new line if it doesn't exist we'll just print off this that is a syntax error because clearly what we've basically done is I don't know we've just we've probably got something like this or we've got no like lines after it which is a little bit weird so we'll definitely there and then basically begin again is interesting it's going to be the position right of this so in other words this will literally be zero because the first time that we look through this you'll see that in this case it doesn't necessarily have to be zero in this case it's literally the first the first thing that we see in our file is that but you can put other stuff here you might have a comment here that says you know in fact let's do this we'll have a comment here that says basically the texture shader right just so that it kind of explains to us what the shader actually is in this case obviously we have this stuff first and then eventually we have type so once we do run into type that's going to be the position from there we take the length of the token which is and I should really probably just move this over here because I keep referencing it so many times so I'll keep this here hopefully you guys can see everything so we're basically looking for the type token so this type token length is going to be literally five right because it's five characters so we advanced past the beginning position when we advanced five characters so we're now here and then plus one so that brings us obviously gives us a space between the two that brings us to type at vertex now yes I mean look if you really wanted to be pedantic about what that's not my work right unless you trim the whitespace later which you also could do so in this case we're just basically making sure that you have to have one space otherwise you'll get like some certain it won't work or it'll crash you thought because I haven't tested that but whatever so string type so what we'll do here is we'll basically extract that type so we basically take a substring from beginning to end of line - beginning right so begin of course being the beginning of your token so from here to the end of line right which is going to be right here and then if it isn't exactly vertex or fragment or pixel right we're gonna say invalid shader type specified now of course that's a that's just in the cert and I could easily just come up here and try and get the shadow type from string and if it returns zero we assert so we could do that could be a way to optimize this in fact I think I will do that so we'll basically say shader type from string and then type because we know that if it returned if it returns zero that in itself will check right it'll do this course out here but also it will cache another as because this will return zero and by asserting it we're saying it has to not be zero so envelop the trailer type specify so yes if you leave a space like this right it will in fact return in assert for you instead of crashing waves good alright next line position we find the next five first not off right so we find the next line and then from there we try and find the next type token right which is going to be which is going to be type fragment in this case and then if we find it all right we do it we don't bunch of stuff here so let me just maybe tap this down and then try and split this up by parameter so you guys can see better basically what we're doing here is taking a substring from the next line position which is basically the beginning of line four for the first time that we run this right we're taking a substring from that to hopefully what is the end either the end of the file or the end of like until we find the next shadow type which is what this code is doing and then after that we'll of course go back up here and see if position is still not n pause which means that it found another token and we'll repeat rinse repeat the process again so that's kind of how we end up splitting this into several types now of course look I mean this code is not bulletproof and more claiming that it is you probably want to maybe clean this up but for my purposes of course all I'm doing is splitting this up as quickly as possible and that this is pretty simple and it works for most cases but of course if you do something stupid and you have like too many spaces or you just do the wrong thing it will most likely assert and let you know okay cool I'll just clean this up the kinetic like the way that looks and we can finally start feeding this stuff into a compiler so pre process returns our unordered map so now that we've got that so I'll come over here so about the shader sauce right then we're going to get the shader sources I'll call it right so maybe I'll just call this sauce just to make it a little bit easier to read so we'll do our pre process which by the way could do other thing in this pipe called a pre process could do other things as well if we have other like maybe we have more than just type in one split on we have other kind of metadata that we want to read out so we can definitely do that as well we'll give it the source and now what we want to do is to compile we want to pass our shader sources okay and so compile is going to take this entire code that we had in the constructor we're going to get rid of it and then we're going to go down into compile which I don't think we created acted weak so avoid OpenGL shader compiled and then yeah it is our shader sources will paste this in and basically what we want to do is convert this into some kind of a loop that will iterate over our shader sources map right so we'll say for what are the value K babe shader sources so just to make this super obvious we'll have our GL enum shader type right but it's gonna be a video first and then we'll have our STD string shader so we can just I mean obviously talking about shaders so we'll just hey type and its source and then that will be key value second I'm taking that by reference of course because we don't want to copy a string now since we are taking this in as a Const right which is fine cuz we don't wanna multiply it we'll just have to label this as a Const string source okay cool so now that's done what when you want to do is instead of creating this a vertex shader right if I just copy that's not probably get rid of the comments now it's pretty clear what's happening anyway glu int will say data type right or rather watershed shader so this is going to be our GL creator and then instead of our vertex shader of course we're not taking in the type so we're creating a shadow of that type right next line occurred actually we'll just grab this whole section here and we'll kind of work through it so next line of course we're taking in these sources as a C string so this will just be a source C string instead of shader source we now have a sorry it's at a vertex shader we now have shader right and then this which what did that used to be so we had source alright this used to be called source I say so we took that as we'll just say sauce see string to make that a bit more obvious okay and then the comparator which is gonna be our shader and this is obviously going to be shader again for the compiled status we'll get the log leg pulled all of that stuff shader now in this case it says the vertex shader compilation fails so we definitely need to have a way to convert that to a string if we add the opposite of this function we could probably use it I'm probably not too fast about this we could just say like shader compilation failure right this is just directly from that opengl wiki and then obviously we have an assert here so if so it will kind of put a breakpoint in here and when we break here we can easily take a look at what the type is and then see what it was so it would be nice in the future to know what what failed exactly but I'm not gonna bother with that now okay so we'll kind of get rid of these comments and I think that's it so if you look at this and we have a return yeah I don't know if you necessarily want time maybe we'll just make it a break so that we don't keep compiling the register shaders but anyway so that should be it there's nothing here in specific to vertex traders as you can see we're basically compiling whatever the type is right and then we just create our shader and then we use that everywhere and that is pretty much it right so this will this this kind of for loop now should compile both our vertex and fragment shaders which is pretty cool so we'll get rid of everything else you see how long this is we don't need any of that anymore if we come back over here now there's actually other stuff that we need right so now we have that gel create program and when we need to attach all of our shaders and then we need to link them and then we need to do all of that and then check the link status of course so this stuff can be fixed by simply reordering this stuff right so GL attached shader for example if the compilation actually succeeded we can just attach it to our program by just attaching a shader to program calling attach here after we've checked whether or not is successfully compiled now for that to happen the program has to be up here so what we'll do is we'll just take this and move it up here totally fine so we create a program now the thing is if it failed maybe we want to set the render ID to something else and program because of that I think what I'll do is I will keep that Glu into program up here and then we'll only assign the render ID to do the program at the end so that way we'll never end up with a valid shader program I'll just be like zero or whatever even though I think zero is valid it will just be kind of not set until we know that everything worked out so that way we can easily check whether or not a shader is in a like successful state or not so this disappears now everything else I think should work the only thing that doesn't is this whole detached shader and delete shader business so we need to basically keep track of the OpenGL shader IDs super easy to do right we know how many there are here so what we should be able to do is easily just create a vector or something like this you could create the the thing is it's dynamic so we can't really create it on the stack and once we use like alakay or something like that so we'll just have a vector of GL enums right and this will be called our will say GL shader IDs right and then into here we'll put we'll make it so that is the right size so shader sources dot size will be the size of this right so now we've done that all we need to do is come down over here and then once we've actually created this we basically just need to push this push this back into our shader IDs okay so that's the enum being pushed back so now we have a list of these now I can't remember if this actually creates that many elements or if it resizes it to that capacity because we want the one that resizes it so we'll see if this works if it doesn't we'll change it to be don't resize because I don't know at the API I remember that well okay so that's pretty much it now if we want to like delete shaders or whatever we just need to have a full loop that goes through all of that so ordered for order I don't we can just yeah full order will say ID in GL shader IDs right GL shader IDs will go through and just delete that and basically we'll do the same thing for this section here with detached shaders so we basically just do that okay so now we're successfully keeping track of all that stuff so that we can let it detach it and everything is pretty much done so if that is successful we of course set our render ID to our program we'll do that as the last thing that we actually do so that it in case we run into this for example it doesn't happen and that looks pretty good to me so now we need to fix it up for this and that's pretty simple as well basically all we need to do is create that shader sources thing so STD unordered and I'll just copy it I was going to type it out and then always the one with what I do that so we'll create this sources thing alright and then in two sources we will add GL vertex shader to be our vertex sauce and then GL fragment shader of course to be our fragment sauce so fragment sauce alright and then now we can pass this in to compile will call this sources and that's pretty much it right so we've basically and we now support reading in from a file and splitting it up and doing all that stuff but also you can just apply it manually so we've got both of these now we can test out both of these right so back in the sandbox app texture shader don't reset so Hazel say to create this now becomes basically what we test it out before which i think is that's here so this is our texture shader right so we'll take this share to create that we wrote before and we'll just put what's pop it into yeah hey so okay to create and i think that should be pretty good this is our flat color shader which i think are we still using we're not using just a texture shader are we okay well we had a triangle here let's maybe I don't know if I want to bring back the triangle so we've got this auto we should still have our grid right that's our flat color shader so that way we're test if but the texture shader which is loaded from a file and then also the black collar shader which isn't make sure whether those work like they're supposed to and of course to get some compilation issues so let's take a look right so Jill enum undeclared identifier that's because we're not including OpenGL in the header file so we can just do that of course it's totally fine because the only place that we include that header file is going to be inside our shared of those CBP which means that we never actually see that GL had a file inside the sandbox out because if we did it wouldn't work actually sir that's a good way to validate that ok another build error it's ok so it looks like we are including in the place that we shouldn't be because it's saying it can't open it so that is interesting I didn't think all right we are the reason we are is because we're being super bad for including it here because we're actually dynamic casting it well when we need to actually upload uniforms because we don't have a proper API for that so that's terrible we definitely shouldn't be doing that now you can see why that's a bad idea so to kind of fix this up really all I'm going to do is I'll get rid of the include here I'll look at what GL enum is right as an unsigned end so what I can do is just move this type def over here into our OpenGL shader so this is of course to do remove because it's not what we should be doing but it will make our code work for now and the last thing we need to do is of course return that header file otherwise none of our OpenGL definitions are going to exist at all ok and as you can see we now have this here so we're taking in shaders both from files for this and then also the texture shader sorry well let me refresh that we're taking and share is from just strings which is this grid and then this these two textures are being taken in from a shader that is a file ok so pretty cool stuff we support both files and normal shader strings I hope you guys enjoyed this video if you did you hit the like button you can also help support the series by going to pay for a couple special the churner as I did it mention earlier huge thank you to all of those supporters that make this series possible now we could go a lot further with this in fact I think next episode we might we might create something called a shader library so at the moment what we're doing is every time we need a shader we have to kind of like learn it right so what we do is we load our shader and then that's it it's kind of maintained by ourselves is maintained by the client that shader object is stored in kind of a variable that is inside actual sandbox lair now that's not great because if we suddenly want to use our shader all across our engine right we have no way of retrieving it so we need something called a shader library which is basically a kind of system that lets us just ask it for a certain shade of by a certain name so for example hey give me the texture shader I want it and then now we have the texture object we can bind it when you do whatever we want with it so that's definitely something that we will explore probably next episode but we'll see how we go because there's so much stuff to come up I'll see you guys next time goodbye [Music]
Info
Channel: The Cherno
Views: 18,641
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: 8wFEzIYRZXg
Channel Id: undefined
Length: 39min 10sec (2350 seconds)
Published: Sun Sep 01 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.