 Welcome back cat from scratch episode 11 in this video. I want to revisit a previous topic, which was our Rendering I want to actually improve what we had before in a couple different ways first previously. We had a very flat 2d almost monochromal Representation of what we're looking at without any sense of depth. So we had like wireframes. We had solid Fills right? But because we didn't really have a sense of depth if things were in front of other things if we had to wireframe faces like this You know, you would see both faces overlapping each other Obviously, you know in reality you wouldn't have that you'd have a face like you know like this You wouldn't have faces blocking each other, you know, you wouldn't you wouldn't have faces seen behind each other in you know in Typical implementation of this kind of software and for that we need to implement depth It's not a huge change, but a change nonetheless, but I also want to be able to Customize our display so adding different colors for the the edges colors for the fills different background color and Do all those things in a very nice and neat way So without any further ado, let's just get started I have to change a few files here The main file just for our test case as well as the to draw files straw Let's see draw.h and that's pretty much it. So let's start off with draw.h. I Want to add a few things here? First, you know what let's just get rid of this draw function. Who needs that? That's from a previous video But we're not using that kind of Program anymore. So I want to have a Color structure in that color structure. I want to have three floats are float G and float B and in open GL These floats are between zero and one. So Let me zero dot F or one dot F, you know, for example Then I also want to have a structure for the the draw style I Always do things in caps for some reason. I think I because I have a Problem So I want to have a couple things. I need three colors. I need the color for the fill fill color also line color and background color. I want to also have a Value it could be an int. It could be an enum whatever you want. I'm gonna say it's a car just for the mode and we're gonna say mode of Zero equals lines only one equals Well, I guess fills only and two equals both. Yeah, that's that's fine. And then lastly For now at least we're gonna have a float line with that will we can use that to change how thick the wire frame edges We're gonna we're gonna be on Top of this I want to have like a kind of default constructor. So you don't have to always come over here and you know manually public all these different Values in these structures. I want to make a function that does it for me. So I'm just gonna say struct draw style pointer default Draw style and I'm just gonna literally output at a default draw style will save void With no inputs and then for this draw body This is what we use before to actually render the model to the screen. Let's just change the add one parameter this Let's say struct draw style Draw style that that would be kind of passed in our custom rendering, you know structures here and And draw things in a custom way. So we're done with this file at this point Now in draw.c We're gonna be maliquing some stuff. So we will need I think standard lib If not, I guess we'll find out. I think it's standard lib.h now Let's just before we actually put in those those lines of code Let me just talk about our our vertex and our fragment shaders. So Let me say so previously we had a very flat implementation of our of our render. So this GL position is Kind of the the coordinates in space that the urtex shader is going to be passing along That it's actually drawing the vertex at and we have four components in this vector obviously the first one is Something that's scaled to x second one It's being scaled to you know in the y direction and then the third value should be something But here we have it as zero if you can see So really what we have to do is just literally copy and paste this This y value or x value over here and change a couple things and if you have a question as to why that is You can go watch the previous video And I just let me that zero is for simplicity sake, but in reality The same Math works in in the z-coordinate as well. We're just going to change you to to u3 So we're dotting the u3 with the The difference between the position of the for the vertex and the Look at coordinate And if you have a question about that you can look at the previous video And you'll see but pretty much that is the biggest change we have to make to our vertex shader to accommodate a depth Concept in addition I Want to add something to the fragment shader And that's going to be another uniform now uniforms are shared in between the vertex and product shader so you can put them in In either one or the other, but we're going to put this here So we have a frag color we need we also need a uniform so I'll say uniform the VEC 3 RGB that's going to be what we're going to pass into our fragment shaders or especially both shaders To control the color so uniform VEC 3 RGB and this fragment color is not going to be zero one zero, which is Green right RGB? We're going to pass in those those actual values. So we'll say RGB X RGB Y RGB Z and we have to do a couple more things later on to make this work But we'll get that get there in a few minutes so Now I'll make some more functions here that we will need in upcoming At least this video and probably the next video as well the first one's going to be the actual Default draw style thing that we just defined in the header file So what was that that was a struct? draw style default draw style So now this is just gonna be a function that returns You know a default draw style that we don't want to have to customize every time we could but I don't have public those huge structures manually every time having a function that does it for me is Sort of the way you do things So we'll just to find the structure that we're going to return here. So struct draw style We'll say draw style Equals struct Draw style I can remember how to do this now look size of struct draw style That should be good Now the same thing has to be done for the colors because remember there's three colors per draw style So we'll say fill color So fill line and background we'll call that back I guess and Now we can just go ahead and start to find these things so fill R equals Something Fill G is something And filled B is something now. Let's say you want to keep the fills green by default So let's just say 0.1 f Zero point or I guess 1.0 f 0.1 f that's like a sort of very calm green color and then we can cover that into the draw style structure by saying draw style fill color fill color equals fill Now this sort of logic can be copied and pasted twice more One for the line and one for the background So first out line color equals line And I guess we'll make the lines. Let's become blue so Very calm blue color point one point one one and then lastly this background color. I think we call it BG color Let's call this a BG just for consistency sake okay, and The backgrounds will keep them all black For now we can change this all later. That's the whole point of having a default okay Now the mode we want the default mode so draw style mode to be I Think two was both right both lines and fills That would be a colored wireframe for those that use traditional CAD software and Then lastly, I think the line width so the width of the lines in the wireframe We have to define that so draw style line width equals Let's keep it at one just for the time being now we can return Draw style there we go. That's our default function That will create a default draw style for us whenever we need to pretty simple now This isn't I want to implement now But we won't really use it to its full potential until the next video or next few videos and that's going to be RGB An actual function that stores as an int three coordinates RG and B both, you know one byte values and So we're sort of like three bytes into a four byte Quantity here and so I guess the process is very simple. We'll just define a small function for this We're gonna pass an unsigned cars for R and That way this is not for open GL. This is going to be for The X window the X window uses a Different way to sort of this doesn't use floats for RG and B uses a an int RGB Sort of quantity that can contains all three components and I'll spin that in a few seconds RG unsigned car We return and the composite is very simple. It's it's just they're just a bit shifting so we're returning R shifted 16 plus G Shifted 8 plus B Very simple, okay now to get into the the bulk of this I Said bulk the rally it's only a few small things In our draw body function remember we added a parameter here, which was Draw style Okay, so here's what I what I meant when we create this let me use this X create simple window function Believe it or not these last two zeros correspond to the the Black and white colors or make say the foreground and background colors of the X window and you can you can pull this manually from the Like the actual display that you're on but honestly, it's usually just black and white So we can we just encode this we'll say RGB 0 0 0 And then RGB 255 255 255 and we're never gonna access this RGB function outside of Draw. See so I'm not gonna put it in the header file, but I guess if you wanted to you probably could but I'm not gonna put it in there So that's this but then also for the depth we have these attributes for GLX In this attribute list we can add another one. We have you know GLX red size green size blue size We don't have GLX depth size, which is actually required to have a you know an accurate depth buffer We'll give it 24 bits. You can give it 32. I think you can give it 8 probably 16 So we'll just say GLX depth size 24 and last one has to be none in this attribute list if you recall from the previous video I Think that's it for most of this. We don't have to change pretty much any of this Compile shaders all that here's their code from previous video where we actually Broke out part of the structures that we were using to code everything up Okay, so down here is first thing we have to actually change these uniform locations These are basically the locations in the shaders of all the variables that we're passing in if you recall We did add a variable here. We added RGB So RGB location shader program RGB. Alright, so Here is where we're actually gonna do some some adding in for the depth buffer. I'm gonna comment this out for the time being There's a few things you have to do to have a depth test So what was a depth test a depth test is basically checking What's What face that you've drawn is in front of another face what face would you actually Spend time drawing to the screen and what parts of it for that you need a depth test So it's very simple to create that you just say GL enable GL depth test This is how you enable anything in open GL and then there's a Value GL depth test which you pass into that and turns it on you add a depth mask and GL depth mask True and then a GL depth function you can actually change how it evaluates how deep something is I think we'll keep it on GL less But you can do less than or equal to you can do greater than you can print everything backwards And also there's something called GL depth range, which I was playing around with. I didn't really find any particular Use for it. Maybe I will in the future video, but I'll just put it in here for just for the sake of it But I'll comment it out for for us right now You kind of change where where the depth range is cut off Now We also have to do something called culling faces So basically there's no reason to draw both sides of a face You know if you only if you have ways that you can identify which faces are on the outside of a body And you have them always numbering their nodes clockwise or counterclockwise you can always tell Which face you should draw you don't have to draw the backside of a face because it's going to be inside your part So there's no reason to draw the backside and if you don't want to draw it, it's called culling culling those faces So we can GL enable another thing GL cull face GL front face is GL clockwise so we're considering we have a clockwise and no counting scheme for our front faces Which I believe we do If we ever don't we can change this to counterclockwise and it will work just the same and then we can say GL cull face GL back, so we're gonna cut all the back faces faces that are counterclockwise Numbered so those vertices are not going to be rendered in that in that order now one thing whenever we're going to be rendering lines and Polygon like fills and lines both so a wireframe and solid fill we want to have a GL Polygon offset and the reason why is because if you draw a line and a fill in the same coordinates You'll have z-fighting because they're drawn in the same exact three-dimensional space The open jet doesn't know whether it should be drawing the line the border or the actual solid itself And you'll have a very weird visual effect. And so the way you can get around that is setting an offset in terms of These these two values here you can look up what they do in the in the manual But uh pretty much that's that's the gist of what we have to add in terms of open GL Calls I want to add some other things though right here Remember we do have a draw style structure that we can access and What that we might want to control is for example GL line width you can pass in any value between I think like one and any any number as a float and Have that use as your wireframe line width But remember we have this line width as a as a field in our structure so we can just pull that so we can say if draw style Mode equals I think it was zero and two were both options That had lines Would you set this to draw style? line width See so that's how you might want to use this The structure to control how you're going to operate on your On your render now a couple of things I want to do Let's paste this in here for the time being In our actual render loop this wild one There's one more thing to add for this GL clear every time we're gonna redraw something to the screen or swap the buffers I want to Clear the depth buffer bit so you can say GL was it is it a Depth buffer bit. Yeah, I think it's a depth Buffer bit so that will clear both the color buffer bit and depth buffer bit and it right above this You see this clear color. This is actually the background color so we can simply replace this with draw style background color Are this one is draw style background color G this one is Draw style Background color B now we're set put this Yeah, probably there So now to actually draw wireframes and fills there's two different ways to do that so If I go back up to the top, why just comment it out if you recall was this GL polygon mode This GL line is what you're passing in to draw the triangles Just as the wireframe if this instead of saying GL lines said GL fill you'd be drawing the filled structure You know without any lines so we can actually call the filled one first and then the lines To draw both the fill on the lines. So that's that's the actual plan here so the first thing we'll do is we'll say if we want to draw the the fill so that's going to be if it's mode one or mode two we're going to GL enable something we're going to enable the polygon offset This basically tells the open GL to draw this one a little bit slightly off where it should be Inwards so that we can get the the wireframe to not be hidden behind parts of this fill So Jillian will Jill polygon offset fill Now we have to pass in the color because remember we created a uniform for all these things You know you one you two you three. We also made a uniform for The actual color just in the beginning of this video. So it's a uniform of 3f RGB location and For this this being the fill color. We're passing in the draw style fill color R draw style I'm bound to make a hundred typos in this live coding fill color G and then draw style Fill color B Okay, and this one actually you can take it out of the loop here. That's my mistake I don't just have to be in the if statement And we're gonna draw the elements and then Not swap off or that's that's for later. Oh, we need to have the polygon mode. So it's a GL polygon mode GL front and back. This is what I just had below GL fill Yep, so this settle this if statement here will basically me says if we wanted to draw the fills We're gonna turn on the offset write the fill color into the uniform Actually set that is we were gonna draw front and back GL fills and then draw the elements and then right after that if the if the mode is Zero and two that means if we're drawing the lines or two, sorry Then we can just disable this turn this off Pass the uniform, but instead of having it be the fill color. It's going to be the line color Polygon mode front and back, but not GL fills. Maybe GL line and then draw elements and Then at that point you add GLX swap buffers and yeah, and then we're we're cooking So this this honestly, I think is all we have to change in the actual functions for this. I Do want to go now and edit the The main function here The main file and in this case, we're just gonna simply load that first balloon STL We need to look at still. I guess we'll keep this nodal centroid thing look from we'll keep Draw body so this draw body is going to change from balloon to balloon. This is going to be balloon and Then we're going to pass in a draw style What draw style you ask we have to define that and thankfully we created a function for that We have a struct draw style draw style equals default draw style with no parameters and Honestly, this should work. I'm prepared to see like plenty of Plenty of errors here. Oh Draw. Oh, actually, that's awesome. Let me hold on 105 let me comment this out. We used that draw function before we get rid of it just now so Make run, okay, there you go. So the Goal has been accomplished. So here if you recall we created a A new draw style you can see that we're rendering both a fill a green colored fill as well as a blue wireframe and The depth test is working. You can see things that are in the back are actually in the back Things that are in the front are in the front and shown properly. There's no like weird Z fighting between The lines and the fills you can see this big black here because we've we've actually clipped our clipping plane is now too close to our Park because we zoomed in but that's to be expected Yeah, besides that we are a working part. Let me just do a quick change of those variables really quickly Let's open up the draw. See and change the default values for our Default draw style instead of having it be a green fill. Let's do yellow yellow You can change this to a one instead of it being a blue line. Let's do a Red line, I guess and then instead of it being a black background. Let's do like a I don't know some weird like Gray looking one probably. I don't know and then let's say it's going to be a slightly thicker line recompile Rerun, there you go. You see that guy. We got a yellow hotter balloon slightly thicker red lines and The background is slightly less black Anyway, I hope you enjoyed this video in the next video. I have some fun stuff planned as well. Anyway, thanks for watching