Transcript grafika
Implementation of an Outdoor Shooting Game Szirmay-Kalos László Budapest University of Technology email: [email protected] Web: http://www.iit.bme.hu/~szirmay Demo 1: The objective Virtual reality rendering User input avatar interaction Virtual world Tasks in games Image synthesis from the point of view of the avatar Control of the avatar through input devices (keyboard, mouse) Control of the intelligent virtual objects by artificial intelligence algorithms Simulation of the physical laws (collisions, forces) I/O libraries Windows + GLUT simulation input Virtual world rendering OpenGL I/O management initialization callback registration Operating System Windows main DisplayFunc GLUT KeyboadFunc SpecialFunc callbacks IdleFunc Graphics hardware OpenGL application Rendering with OpenGL Virtual world Viewing transformation 2. Perspective transformation 1. 628 clipping 1325 1325 628 visibility: z-buffer display Geometry definition glBegin(GL_TRIANGLES); x12,y12,z12 x13,y13,z13 x11,y11,z11 glColor3f( 1, 1, glVertex3f( x11, glVertex3f( x12, glVertex3f( x13, 0 ); y11, z11 ); y12, z12 ); y13, z13 ); glColor3f( 0, 1, glVertex3f( x21, glVertex3f( x22, glVertex3f( x23, 0 ); y21, z21 ); y22, z22 ); y23, z23 ); glColor4f(R,G,B,A) glEnd(); Texturing Texture mapping (u2, v2) x3,y3,z3 (u1, v1) (u3, v3) x2,y2,z2 x1,y1,z1 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_id); // glBegin(GL_TRIANGLES); glTexCoord2f(u1, v1); glVertex3f(x1, y1, glTexCoord2f(u2, v2); glVertex3f(x2, y2, glTexCoord2f(u3, v3); glVertex3f(x3, y3, glEnd(); glDisable(GL_TEXTURE_2D); which texture z1); z2); z3); AnimateIt(dt), DrawIt() Games rendering User input avatar interaction ControlIt(dt), InteractIt() Game objects ControlIt: – Interacts, thinks and applies his available controls (e.g. runs, shoots) InteractIt – Looks at the states of other objects, checks collisions AnimateIt: – Moves to its new position according to the elapsed time DrawIt: – Draws itself onto the screen Simulation loop (Game loop) dt void IdleFunc( ) { // idle call back float old_time = time; time = glutGet( GLUT_ELAPSED_TIME ); float dt = time - old_time; avatar -> ProcessInput( ); world -> Control( dt ); world -> Animate( dt ); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); avatar -> SetCameraTransform(); world -> Draw( ); glutSwapBuffers( ); } Data structure of the virtual world Game Objects are dynamic (killing) Game objects are different (heterogeneous collection) Parent-child relationships (owner-weapon) world terrain sky avatar Enemy 1 Enemy 2 Weapon Join: új elem hozzávétele bullet explosion Terrain Complex geometry – Height field Complex texture No Control No Animation Collision detection, Lifts objects Terrain geometry z z y x z = height(x,y) x,y Height function definition: Discrete samples + linear interpolation Discrete samples = B&W Image Height map Triangle mesh Reducing the number of triangles: Level of detail Height-field texturing: projecting the top view y x v u Terrain improvement: Detail map Terrain collision detection if (height(x,y) > z) Collision! z x,y Walking on the terrain: Position(x, y) = (x, y, height(x,y) + legsize) Bi-linear Height field interpolation float Height( float x, float y ) { x += wwidth/2; y += wlength/2; x = x / wwidth * w; y = y / wlength * l; int X = (int)x, Y = (int)y; float h1 = height_field[Y * w + X] * wheight; float h2 = height_field[Y * w + X+1] * wheight; float h3 = height_field[(Y+1) * w + X] * wheight; float h4 = height_field[(Y+1) * w + X+1] * wheight; float xd = x - X; float yd = y - Y; float hx1 = h1 + xd * (h2 - h1); float hx2 = h3 + xd * (h4 - h3); return (hx1 + yd * (hx2 - hx1)); } Sky Image that is textured on something: sphere Sky geometry: dome, sphere No Control No Animation No collision detection Definition of surfaces as triangle meshes: Tessellation 1. Find a parametric equation of a sphere: x(u,v) = x0 + r cos 2u sin v y(u,v) = y0 + r sin 2u sin v z(u,v) = z0 + r cos v u,v [0,1] 2. Select points in the unit rectangle GLU Quadrics: Sphere GLUquadricObj * quadric; // definition quadric = gluNewQuadric( ); gluQuadricTexture(quadric, GL_TRUE); // draw glBindTexture(GL_TEXTURE_2D, sky_texture_id); gluSphere(quadric, sky_radius, 32, 20); Enemy Animated geometry – Defined by keyframes organized as clips Stand, run, attack, die, – + mesh animation Textures (animated) Artificial intelligence Collision detection Keyframe animation: running Inbetweening: Computation of frames from keyframes Nonlinear interpolation linear interpolation keyframes t What and how to interpolate High quality animation: – Newton’s laws: the second derivative of a motion curve is proportional to the force, which acts through an elastic mechanism: interpolation curve is C2 – Even the interpolated frames should meet physical constraints: Bone animation Games: – Linear interpolation – Interpolate the vertices of the mesh: Mesh deformation Example for bone animation Cyclic walk t= 0 Mesh morphing: Time: t Two neighboring keyframes Linear interpolation for each vertex t= 1 Current vertex positions Running as mesh morphing + position animation: position += velocity * dt Motion definition Keyframes are organized into clips Keyframes are designed off line and stored in a file: MD2, MD3, etc. file formats Typical clips in a game: – Run, stand, attack, die, pain, salute, crouch, wave, point, taunt, etc. Clips Stand 40 keyframes Run 5 keyframes Salute 11 keyframes Motion control AI machine AI state time: t Clip = start, stop keyframe Keyframe animation Keyframes stored in an MD2 file Vertex positions of a triangle mesh Artificial Intelligence of an Enemy Dist < 4 && Avatar_angle < 40 Dont Care Escape Dist > 6 Avatar_angle < 20 Dist < 4 && Avatar_angle > 60 Dist < 1 Chase Attack Dist > 1 Collision with the bullet Dying Avatar_angle Avatar Texturing Bullet Geometry: sphere Textured Not intelligent Physical animation Physical animation of the bullet velocity t+dt t force, acceleration acceleration = (0, 0, -g) velocity += acceleration * dt position += velocity * dt The bullet is flying: Animate, Draw void Bullet::AnimateIt( float dt ) { acceleration = Vector(0,0,-g); speed += acceleration * dt; position += speed * dt; } void Bullet::DrawIt( ) { glPushMatrix( ); glTranslate(position.x, position.y, position.z); glBindTexture(GL_TEXTURE_2D, bullet_texture); gluSphere(quadric, 1.0, 16, 10); glPopMatrix( ); } Collision detection between two slow objects Problem with fast objects t given t t+t dist = obj1.position - obj2.position min = obj1.BoundingRadius() + obj2.BoundingRadius() if (dist.Length() < min) Collision! Bullet collision detection Bullet::InteractIt( GameObject * obj ) { if (obj->GetType() == TERRAIN) { Mountain * terrain = (Mountain *)obj; if (terrain->Height(position.x, position.y)> position.z) { KillIt(); world -> Join(new Explosion(position)); } } if ( obj->GetType() == AVATAR || obj->GetType() == ENEMY ) { if (“bounding spheres overlap”) { KillIt(); obj -> KillIt( ); world -> Join(new Explosion(position)); } } } Collision detection with fast objects: ray-tracing position vel2 velocity rel_velocity = velocity - vel2 ray: position + rel_velocity·t If (ray intersects bounding sphere first AND tintersect < dt) Collision! hit_object = world->Intersect(position,velocity,t); world ship1 ship2 avatar space sun bullet explosion Billboards Single semi-transparent texture on an oriented quadrilateral pos pos QUAD QUAD x y z Tmodell position orientation Tview Tperspective camera position camera orientation X Y Z Explosion Seemingly complex, random structure Similar look from all directions Collection of billboards Particle system Particle Systems global force field (smoke) random initial values position: velocity: acceleration: position += velocity * dt velocity += acceleration * dt acceleration = force / weight lifetime age: age += dt; if (age > lifetime) Kill(); size, dsize: weight, dweight: color, dcolor: size += dsize * dt; weight += dweight * dt color += dcolor * dt Explosion settings Rand position = Rand( center, 0.1 ); lifetime = Rand( 2.0, 1.0 ); size = 0.001; dsize = Rand( 1.0, 0.5 ) / lifetime / 2.0; velocity = Rand( CVector(0, 0, 0), 0.4 ); acceleration = Rand( CVector(0, 0, 0), 0.4 ); color = Rand( Color(1, 0.5, 0, 1), Color(0, 0.5, 0, 0) ); dcolor = Color(0, -0.5, 0, -1) / lifetime / 2; Avatar Keyboard controls its behavior: – ProcessInput Its position and orientation will be the camera position and orientation before rendering – SetCameraTransform Avatar :: SetCameraTransform Avatar :: SetCameraTransform( ) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(position.x, position.y, position.z, position.x + head.x, position.y + head.y, position.z + head.z, up.x, up.y, up.z); } eye up = [0, 1, 0] lookat Keyboard control KeyboardFunc SpecialFunc input IsSpace, IsLeft, IsRight, IsUp, IsDown IdleFunc: GameLoop virtual world GLUTWindow GameEngine DisplayFunc IdleFunc KeyPress GameObject position, velocity, acceleration ControlIt(float dt ) AnimateIt(float dt) InteractIt( GameObject * o) DrawIt( ) IntersectIt(Ray r, float& t) world Member Control, Animate, Draw Interact, Intersect, Join next Game engine 500 C++ lines Texture Load( char * fname) Particle avatar Avatar ProcessInput() SetCameraTransform() ParticleSystem TexturedObject BillBoard Emit(int n) DrawIt() Shooting game GameEngine Avatar Self ProcessInput ControlIt InteractIt ParticleSystem Explosion ControlIt Sky DrawIt TexturedObject Enemy Terrain DrawIt DrawIt InteractIt AnimateIt ControlIt SpaceGame 350 C++ lines Indoor games? No terrain Building – Cannot be represented by a height field – Textured triangle mesh Collision: without checking all triangles Fast visibility: quickly eliminating the potentially invisible objects Thanks for your audience