OpenGL - camera movement

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
next we have 6.2 coordinate systems depth and now we're rendering a full cube and now that we're rendering things which may get drawn on top of each other it's very important that we enable depth testing like calling GL enable depth test if we forget to enable death testing this is what we'll get because what's happening here is the primitives are being rendered in the order they happen to exist in our array of vertices and so sometimes primitives which should be drawn behind others are being rendered after and so they're just being drawn on top of things that they should be behind so don't forget to enable depth testing aside from that there's not really anything new going on here we just have a bunch more vertices to make up all the sides of our cube and down when they render we are rotating on an axis that is not one of the XYZ axis it's a rotation axis that is not one of the three cardinal axes that's why the cube seems to tumble in multiple directions the only other thing that's different here is that when we call draw arrays we specify that we were drawing 36 vertices not just six like we were before here in example six point three coordinate systems multiple we're now rendering the same box but with multiple instances what's going on in the code here is we've added another array cube positions of vector YZ which are the positions where we're going to place our cubes and this is not being put in a GL buffer I'm not actually going to store this on the GPU side instead just in our rendering loop we're taking those cube positions creating a model transform and applying the rotation on it always around this axis but with different angles as determined by the the counter of the loop I set in that model to the uniform and then calling draw arrays each time in the loop so whereas before in each frame we're just making one draw call now we're making multiple this is not ideal because for various reasons draw calls are quite expensive they're significant overhead when you issue a draw call generally we want to keep down the number of draw calls and any one frame and so in a later example we'll look at instancing where with a single draw call we can render the same model multiple times but with different model transforms so the instances are rendered in different places what we have here however is the simpler more obvious solution looking at example 7.1 camera circle now we have camera movement and what's happening here is that our camera is moving around the origin point it's circling around it orbiting and looking always at the origin so each time in the render loop we're setting a new view matrix defined here and we're constructing this view matrix with the convenient look at function the look at function takes three points and the vector from the first point to the second determines what direction we want the camera to look at so imagine the camera positioned here but looking towards this direction and then the third point this is our up direction so for the line between these two points the question is how is the camera rotated on that axis and that is what this is effectively defining by pointing upwards in this case our look at direction is always going to be flat on the XZ plane and up is straight up on the y axis so our camera perspective is always going to be in a sense level with the ground now for the orbiting effect we're changing the position of the camera am i taking the sine and cosine of the time value multiply it by radius we get x and z values that effectively orbit in a circle around the origin and we're always looking at the origin now I'm not going to go into the math of the lookout function it's something you would actually probably figure out for yourself when you realize what we're doing is we're positioning the camera at this location making it point in this direction and rotating around that origin defined by this up vector having established a transform to get a camera into that position remember that we don't really transform any camera instead we transform everything in the world around the camera with the inverse transform so once we've computed that camera transform we get its inverse and that is our view transform so that is what look at is going to return an example 7.2 camera keyboard DT DT stand for Delta time we now have keyboard controls of Vaz de I can move forward back and strafe left and right and in this example we now need some global variables we have first a variable camera position representing where the cameras positioned camera front which is a vector relative from camera position determining which direction the camera is facing camera up which is also relative from camera position determined which way is our up vector and we also are defining Delta time and last frame last frame is going to store the timestamp of the previous frame and Delta time is going to store the difference between the timestamp of this frame and the last frame how much time has elapsed since the last frame and it's a standard game live stuff where when it comes to movements we want to regulate speed of movement based on how much time has actually elapsed because of vagaries in the system you know the the time between frames elapsing is never perfect sometimes it takes much longer in to get from one frame to the next than then normal than average so you should always factor and how much time is actually elapsed between frames that's why we get Delta time that is computed first thing in the render loop where first we get the current frame timestamp get Delta time by subtracting that from last frame and then get last frame by setting that to current frame so that next time around we have it stored and then for our view transform we're using look at again the position of our camera is defined by camera position the place is looking to his camera position plus camera front again camera front is defined relative of the camera position so we need to add it to get a point where the camera is looking at and then the up Direction is defined by camera op which in this example is never going to change camera position though does need to be affected by our keyboard input waz de so down in process input first we want to compute how fast the cameras moving based on Delta time so we just have this constant 2.5 if we increase this we would get faster camera movement if we decreased it we would get slower camera movement and in the case where we hit W to push the camera forward well camera front tells us which way the camera should go and in this example you may have noticed there's no way to change the direction of camera front so it's always gonna be the same in this example but we multiply that times the camera speed and then add the result to camera position we're taking two vectors adding them together and so if we're moving forward this is going to mean that the Z value is decreasing because if we move forward in OpenGL chords then we're going down the negative z axis for s4 moving backwards same deal except we're subtracting so the camera position Z value should get bigger and then for a and D for strafe II left and right we need to get the vector which is the cross product of camera front and camera up because camera front a camera up form a plane and the perpendicular vector is computed from the cross product and that tells us which way to move left the multiply that by camera speed and subtracted from camera position to go left at it when we push D to go right now an example seven point three camera mouse zoom we've added the ability to in addition to Asda to move the camera back and forth and strafe we can use a mouse to change the forward-looking direction of the camera also we can use the mouse wheel to zoom in and out so we're changing effectively the the field of view so in the code now we have a few more global variables including some variables describing the mouse state as we'll see when we look at the mouse handling code and from the mouse State we're going to update these other global variables affecting the camera state yaw and pitch which describe the orientation of the camera the the facing and so from these we will update camera front fov the field of view that's going to be modified by the mouse wheel and the field of view then simply factors into the view transform when we get our perspective matrix the field of view is no longer hard-coded it's from this couple verbal fov now to handle mouse input at the top here we're going to set two callbacks this first one set cursor position callback this callback handles the change of the mouse cursor position and set school callback that's for the mouse wheel so looking at this function first this one's simple we get two inputs one for X offset of the wheel and one for Y offset of the wheel the y offset is for the up and down scrolling x offset is for left of rice code because there are some mouse wheels on some mice that's do scroll left and right but most just scroll up and down so we just care about the y offset and in their field of view we're gonna cap the field of view between the range of 1 and 45 has to be somewhere in that range so only then do we update the field of view and so we take the Y offset and subtract it from field of view I assume Y offset is negative when you scroll down and it's positive when you scroll up and when we scroll up we want to zoom in which means decreasing the field of view so that's why we're subtracting here and then having computed a new field of view we want to make sure it's capped in the range of 1 to 45 so that's what this logic is about for the mouse movement handling there's this key callback up here in the setup code where we set input mode to DFW cursor and cursor disabled this effectively captures the mouse for our window and doesn't display a cursor within it which is what you want for an FPS you wanna be able to move your mouse around while you have focus in the window and you don't want to see the cursor poke out of the window and you definitely don't to see the cursor within the window either so the callback for this it gets an X and y double value 2 noting the position the cursor and for our purposes these values only really have meaning relative to prior values so from one call to the next what we care about is how the x and y values have changed so that's why we have the global last X and last Y values to record what the x and y positions of the previous call were but for the first time this is called we want the x offset and y offset the deltas between the x and y's we want that to be zero and so we have this global first mouse which is starting true but for the first mouse event it's going to set x and y to the positions first thing and disable this so this won't run again in any subsequent coal I find this a little strange I would have just set X offset and YF set to zero for the first coal that would have had the same effect but anyway this gets us what we need and so once we have the X offset on the YF set we multiply them by a sensitivity factor larger the sensitivity value effectively the larger the mouse movements and with an offset and y offset we add them to y'all and pitch respectively for the pitch though we want to make sure it's capped within a range of 89 to negative 89 because certainly you don't want to have your perspective sort of do a back flip so you've exceeded 90 degrees or negative 90 degrees you don't want to do that so that's why we're capping the pitch and from yawn pitch we now need to update camera front we create a front vector where we're competing it's X the Y and the Z using this trigonometry I won't go into the details you can figure out the geometry for yourself if you're curious and lastly we've normalized the vector because we want our camera vector to always have a length of 1 we want it to always be a unit vector so by updating camera front that's going to affect our view matrix and the call to look at and last thing here do be clear that the handlers for the Mouse events those are processed when we call poll events when pull events is called that's when it reads events off of the event queue for the process the events coming from the operating system and when Mouse events are pulled off this cue that's when it calls the mouse handlers you
Info
Channel: Brian Will
Views: 14,988
Rating: 4.7843137 out of 5
Keywords: opengl 3d rendering programming
Id: AWM4CUfffos
Channel Id: undefined
Length: 12min 33sec (753 seconds)
Published: Mon Sep 09 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.