+ All Categories
Home > Documents > Do it yourself 3D Games with OpenGL Szirmay-Kalos László Dept. of Control Engineering and...

Do it yourself 3D Games with OpenGL Szirmay-Kalos László Dept. of Control Engineering and...

Date post: 19-Dec-2015
Category:
View: 218 times
Download: 0 times
Share this document with a friend
Popular Tags:
79
Do it yourself Do it yourself 3D Games with 3D Games with OpenGL OpenGL Szirmay-Kalos László Dept. of Control Engineering and Information Technology Budapest University of Technology email: [email protected] Web: http://www.iit.bme.hu/~szirmay
Transcript

Do it yourselfDo it yourself3D Games with OpenGL3D Games with OpenGL

Szirmay-Kalos László

Dept. of Control Engineering and Information Technology

Budapest University of Technology

email: [email protected]

Web: http://www.iit.bme.hu/~szirmay

Demo 1: The goalDemo 1: The goal

sgame/SpaceGame I

3D 3D GamesGames

Self EnemyAI

Field objects

Virtual realityVirtual reality

virtual worldavatar

control

rendering interaction

Subtasks of GamesSubtasks of Games

Rendering the scene from the point of view of the avatar (virtual self)

Controlling the avatar through the input devices (keyboard, mouse)

Controlling the „intelligent” virtual objects (AI)

Simulating the physical world

Libraries for input and outputLibraries for input and output

rendering

virtual worldmodell

input

simulation

OpenGL

Windows + GLUT

Interaction schemesInteraction schemes

printfscanf

printfscanf

var1

var2

Program driven:event - variable correspondance: PC

event

state

Eventhandler

Event driven:event - variablecorrespondance: state

Input/Output managementInput/Output management

Operatingsystem

WindowsGLUT

main

DisplayFunc

KeyboadFunc

IdleFunc

OpenGLgraphicshardware

application

initializationcallback registration

callbacksSpecialFunc

OpenGLOpenGL

Rendering API (library)– Rendering of 2D and 3D objects– follows the drawing state concept– Image operations

Independent of the windowing and operation systems– Window management should be done

separately

glX, wgl glu

OpenGLOpenGL

hw

application

gl

GLUT

Xwindow, MS-Windows

Window system

Windowingbridge

Convenience,tessellators

Window management

OpenGL syntax (C API)OpenGL syntax (C API)

glVertex3dv( … )

# of parameters2 - (x, y)3 - (x, y, z), (R, G, B)4 - (x, y, z, h) (R, G, B, A)

Data type b - byteub - unsigned bytes - shorti - intf - floatd - double

Vector or scalarv - vector - scalar

part of OpenGL API

InitializationInitialization

#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>

void main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitWindowSize(600, 600); // initialization glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); glutCreateWindow( "Space Game" );

glutDisplayFunc( DisplayFunc ); // callback registration glutIdleFunc( IdleFunc ); glutKeyboardFunc( KeyboardFunc ); glutSpecialFunc( SpecialKeyboardFunc ); glutMainLoop();}

R,G,B - R,G,B - Z

Demo 2: Demo 2: Single and double bufferingSingle and double buffering

single:sgame/Files/sgamesing.exe

double: sgame/Files/sgame.exe

Double buffering for animationDouble buffering for animation

frame buffer

1.

frame buffer

2.

monitor

glClear(GL_COLOR_BUFFER_BIT);drawing…glutSwapBuffers( );

draw

display

Rendering with OpenGLRendering with OpenGL

world definition modell-view transformperspective transform

1325628 1325628

1.2.

clipping z-buffering display

Why do we need Why do we need perspective transform?perspective transform?

What is seen in a pixel?

perspective transform

x1z1

x2z2

X = d = d

y1z1

y2z2Y = d = d

X = x1 = x2

Y = y1 = y2

Definition of transformationsDefinition of transformations

Tmodell Tview Tperspective

Tmodellview

xyz

XYZ

move, rotatescaleobjects

eye positionviewing directionview up

field of viewaspect ratiofront-back clipping

TviewportXP

YP

Elementary transformationsElementary transformations glTranslate: r’ = r + p glScale: x’= Sx x; y’= Sy y; z’ = Sz z

glRotate (ex. Rotation around axis z):

r’ = rSx 0 0

0 Sy 0

0 0 Sz

r’ = rcos sin

-sin cos

Homogeneous coordinatesHomogeneous coordinates Translation cannot fit into a 3x3 matrix

– Let us work with 4x4 matrices

[r’, 1] = [r, 1] = [r A + p, 1]

a11 a12 a13 0a21 a22 a23 0

a31 a32 a33 0

p1 p2 p3 1

A

p

[r’,1] = (...([r,1] Tn) Tn-1)... T1) = [r,1] (TnTn-1... T1)

Definition of transformationsDefinition of transformations

world definition

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION); glLoadIdentity( );gluPerspective(fov,w/h,front,back);

glMatrixMode(GL_MODELVIEW); glLoadIdentity( );gluLookAt(eyex, eyey, eyez,

lookatx, lookaty, lookatz, vupx, vupy, vupz);

glTranslatef(px, py, pz); glRotatef(angle, axx, axy, axz);

eye

lookat

fov

w

h

w

h

Scene Definition OpenGLScene Definition OpenGLglBegin(GL_TRIANGLES);

glColor3f( 1, 1, 0 ); glVertex3f( x11, y11, z11 );glVertex3f( x12, y12, z12 );glVertex3f( x13, y13, z13 );

glColor3f( 0, 1, 0 ); glVertex3f( x21, y21, z21 );glVertex3f( x22, y22, z22 );glVertex3f( x23, y23, z23 );

glEnd();

x11,y11,z11

x12,y12,z12

x13,y13,z13

glColor4f(R,G,B,A)

TexturingTexturing

Texture Mapping in OpenGLTexture Mapping in OpenGL

glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, texture_id); // which textureglBegin(GL_TRIANGLES);glTexCoord2f(u1, v1); glVertex3f(x1, y1, z1);glTexCoord2f(u2, v2); glVertex3f(x2, y2, z2);glTexCoord2f(u3, v3); glVertex3f(x3, y3, z3);glEnd();glDisable(GL_TEXTURE_2D);

(u1, v1)

(u2, v2)

(u3, v3)

x1,y1,z1

x2,y2,z2

x3,y3,z3

Definition of TexturesDefinition of TexturesglEnable(GL_TEXTURE_2D);glGenTextures(1, &texture_id);glBindTexture(GL_TEXTURE_2D, texture_id);

// load imageint width, height;unsigned char * image;image = LoadImage( filename, &width, &height );

// store textureglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image );

Images, image formatsImages, image formats Head:

– type, size (width, height) – bits-per-pixel, indexed-true color, lookup table

Body:– width x height number of pixels: (R,G,B) or idx– Encoding, compression (run length, LZW, Huffmann,

FFT, wavelet) Standard formats:

– TARGA, BMP, GIF, JPEG, TIFF, PCX

TARGA (.TGA)TARGA (.TGA)002

9 zeros

lower byte of widthupper byte of widthlower byte of heightupper byte of height

Bits-per-pixel: 2432

Body

Head: Body: b1g1r1

b2g2r2

Definition of surfaces as Definition of surfaces as triangle meshes: Tessellationtriangle meshes: Tessellation1. Find a parametric equation:

x(u,v) = x0 + r cos 2u sin v y(u,v) = y0 + r sin 2u sin vz(u,v) = z0 + r cos v u,v [0,1]

2. Select points in the unit rectangle

Quadrics: SphereQuadrics: Sphere// definitionGLUquadricObj * quadric;quadric = gluNewQuadric( );gluQuadricTexture(quadric, GL_TRUE);

// drawglBindTexture(GL_TEXTURE_2D, texture_id);gluSphere(quadric, R, 16, 10);

Rotating Earth: initRotating Earth: initGLUquadricObj * quadric;unsigned int earth_texture;

void Init( ) { quadric = gluNewQuadric( ); gluQuadricTexture(quadric, GL_TRUE);

glGenTextures(1, &earth_texture); glBindTexture(GL_TEXTURE_2D, earth_texture_id); glTexParameteri(GL_TEXTURE_2D,

GL_TEXTURE_MIN_FILTER, GL_NEAREST);

image = LoadImage(”earth.tga”, &width, &height ); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);}

GLUT timer controlGLUT timer controllong time;

void IdleFunc( ) { // idle call back

float old_time = time; time = glutGet( GLUT_ELAPSED_TIME );

float dt = time - old_time;

AnimateIt( dt ); DrawIt( );

}

Rotating Earth: animate, drawRotating Earth: animate, drawvoid AnimateIt( float dt ) { angle += rot_speed * dt; if (angle > 360.0) angle -= 360.0;}

void DrawIt( ) { glClearColor(0, 0, 0, 0); // R,G,B,A glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix( ); glRotatef( angle, 0, 0, 1 ); glBindTexture(GL_TEXTURE_2D, earth_texture); gluSphere( quadric, 1.0, 16, 10 ); glPopMatrix( ); glutSwapBuffers( );}

Demo 3: Rotating EarthDemo 3: Rotating Earth

sgame/earth/earth1.exe

Earth Revolves around Earth Revolves around the Sun the Sun

dist

rot_angle

rev_angle

void AnimateIt( float dt ) { rot_angle += rot_speed * dt; rev_angle += rev_speed * dt;}

void DrawIt( ) { glPushMatrix( ); glRotatef(rev_angle, 0, 0, 1); glTranslatef(dist, 0, 0 ); glRotatef(rot_angle, 0, 0, 1); glBindTexture(GL_TEXTURE_2D, earth_texture); gluSphere(quadric, 1, 16, 10); glPopMatrix( ); glutSwapBuffers( );}

Demo 3: Rotating Earth Demo 3: Rotating Earth revolves around the Sunrevolves around the Sun

sgame/earth/earth.exe

Creating the spaceCreating the spacevoid DrawIt( ) { glBindTexture(GL_TEXTURE_2D, space_texture);

glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-SS, -SS, -SS);

glTexCoord2f(0, 1); glVertex3i(-SS, SS, -SS);

glTexCoord2f(1, 1); glVertex3i( SS, SS, -SS);

glTexCoord2f(1, 0); glVertex3i( SS, -SS, -SS); ... glEnd();}

SS,SS,SS

-SS,-SS,-SS

GamesGames

virtual worldavatar

control

rendering interaction

AnimateIt(dt), DrawIt()ControlIt(dt)

Game ObjectGame Object ControlIt:

– interacts with the others, ”thinks” and sets the available controls (e.g. rockets)

InteractIt: – communication between two objects

AnimateIt: – moves to the next position and orientation

DrawIt: – renders the object with OpenGL

Simulation loop (Game loop)Simulation loop (Game loop)

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( );}

dt

Game dataflowGame dataflow

InputProcessing:

KeyboardFunc,SpecialFunc

input

Simulate:IdleFunc

virtualworld

Render

Representation of the Representation of the virtual worldvirtual world

Dynamic objects (kill) Different object types (heterogeneous collection) Linked list (hierarchical structures, trees)

ship1 ship2avatar

space sun

world

bulletexplosion

Join: add new element

SpaceshipSpaceship Complex geometry

– quadrilateral mesh Complex texture Physical animation

– forces (gravitation, rockets)– collisions

Behaviour (AI)– control rockets

avoid collisions, escape from avatar, chase avatar

Building a ship: Building a ship: Polygon modelling in MayaPolygon modelling in Maya

Extruding Extruding

Extruding (still)Extruding (still)

Extruding (once more)Extruding (once more)

Extruding (final)Extruding (final)

Smoothing by SubdivisionSmoothing by Subdivision

= 1/2 + 1/16 + 1/16

Subdivision surfacesSubdivision surfaces= 1/4

= 1/4 + 1/4

Subdivision smoothing: Subdivision smoothing: 1 level1 level

Subdivision smoothing: Subdivision smoothing: 2 levels2 levels

TexturingTexturing

modelltexture

Definition of the parameterizationDefinition of the parameterizationin Mayain Maya

(0,0)(1,1)

Definition of the parameterizationDefinition of the parameterization

Creating a texture for the shipCreating a texture for the ship

Textured shipTextured ship

Animate: using NewtonAnimate: using Newton’s laws’s lawsforcem

void Ship :: AnimateIt( float dt ) { acceleration = force/m; velocity += acceleration * dt; position += velocity * dt;}

void Ship :: DrawIt() { glPushMatrix( ); glTranslatef(position.x, position.y, position.z); glBegin( GL_QUADS ); ... ; glEnd( ); glPopMatrix();}

velocity

position

Orientation ControlOrientation Control

void Ship :: DrawIt() { glPushMatrix( ); glTranslatef(position.x, position.y, position.z);

Vector modell_head( 0, 0, 1 ); Vector world_head = velocity.UnitVector(); Vector rotate_axis = modell_head % world_head;

float cos_rotate_angle = world_head * modell_head; glRotatef( acos(cos_rotate_angle)* 180 / M_PI, rotate_axis.x,rotate_axis.y,rotate_axis.z); glBegin( GL_QUADS ); ... ; glEnd( ); glPopMatrix( ); }

modell_head

world_head = velocity.UnitVector();

Ship :: ControlItShip :: ControlItvoid Ship :: ControlIt( float dt ) { force = Vector(0, 0, 0); Interact( world );}

ship1 ship2avatar

space sun

world

bulletexplosion

void Ship::InteractIt( GameObject * object )

Ship: InteractItShip: InteractItvoid Ship :: InteractIt( GameObject * object ) { if ( object->GetType( ) == PLANET ) {

}

if ( object->GetType( ) == AVATAR ) {

}}

F = f m·M r2

avatar avatar

bullet

aiming angle

Ship: InteractItShip: InteractIt

if ( object->GetType( ) == PLANET ) { Planet * planet = (Planet *)object; Vector dist = planet->position - position; float r = dist.Length(); force += dist * f * mass * planet->mass /r/r/r;

if ( r < planet->Radius() * 2 )force += (position - planet->position)/r;

if ( r < planet->Radius()+BoundingRadius() )Kill();

}

F = f m·M r2

Ship: InteractItShip: InteractIt

if ( object->GetType( ) == AVATAR ) { Avatar * avatar = (Avatar *)object; Vector goal = avatar -> position - position; force += goal * 0.05;

cosaim = velocity.UnitVector()*goal.UnitVector(); if (cosaim > 0.9) {

world-> Join( new Bullet(position, velocity)); }}

avatar avatar

bullet

aim

Collision detection between Collision detection between two slow objectstwo slow objects

dist = obj1.position - obj2.positionmin = obj1.BoundingRadius() + obj2.BoundingRadius()if (dist.Length() < min) Collision!

given t

Problem with fast objects

t

t + t

BulletBullet Seemingly complex geometry Similar look from all directions Easier to define its image

Hit detection = fast collision detectiontransparent

BillboardsBillboards Single semi-transparent texture on an

oriented quadrilateral

pos

pos

QUAD

QUAD

Tmodell Tview Tperspectivexyz

XYZ

positionorientation

camera positioncamera orientation

Bullet :: DrawItBullet :: DrawItvoid Bullet :: DrawIt() {

Set transformation to compensate the rotation of the camera transform

glEnable(GL_BLEND); // transparency glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);

glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-size, -size); glTexCoord2f(1, 0); glVertex2f(size, -size); glTexCoord2f(1, 1); glVertex2f(size, size); glTexCoord2f(0, 1); glVertex2f(-size, size); glEnd();

glDisable(GL_BLEND);}

How can we store How can we store transparent textures?transparent textures?

Some image file formats allow not only RGB triplets, but also RGBA quadruples

Store the texture into two images– image 1: rgb– image 2: a gray-scale image of alpha

Compensate camera Compensate camera transformtransform

float viewMatrix[16];glGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);

glMultMatrixf( viewMatrix );

0001tx, ty, tz

Rotation invert

pos.x, pos.y, pos.z

Collision detection with fast objects: Collision detection with fast objects:

ray-tracingray-tracing

velocity

rel_velocity = velocity - vel2ray: position + rel_velocity·t

If (ray intersects bounding sphere first AND tintersect < dt) Collision!

hit_object = world->Intersect(position,velocity,t);

ship1 ship2 avatar space sun

world

bulletexplosion

position

vel2

Bullet :: ControlItBullet :: ControlItvoid Bullet :: ControlIt( float dt ) { GameObject * hit_object = world -> Intersect(position, velocity, t);

if ( t > 0 && t <= dt ) {Kill(); // bullet disappearsVector hit_point = position + velocity * t;int hit_type = hit_object -> GetType();if ( hit_type == AVATAR ) exit(1); // player is killedelse { world -> Join( new Explosion( hit_point ) ); if (hit_type == SHIP) hit_object -> Kill();}

} age += dt; if ( age > 10 ) Kill(); // bullet disappears}

ExplosionExplosion Seemingly complex, randomly

animated structure

Similar look from all directions Collection of billboards

Particle system

Particle SystemsParticle Systems

position: position += velocity * dtvelocity: velocity += acceleration * dtacceleration: acceleration = force / weight

lifetimeage: age += dt; if (age > lifetime) Kill();

size, dsize: size += dsize * dt;weight, dweight: weight += dweight * dtcolor, dcolor: color += dcolor * dt

global force field(smoke)

randominitialvalues

Explosion settingsExplosion settings

position = Rand( center, 0.1 ); // initially focusedlifetime = Rand( 2.0, 1.0 );

size = 0.001; // initially smalldsize = Rand( 1.0, 0.5 ) / lifetime / 2.0;

velocity = Rand( Vector(0, 0, 0), 0.4 ); // symmetricacceleration = Rand( Vector(0, 0, 0), 0.4 );

// from yellow opaque animate to reddish transparent color = Rand( Color(1, 0.5, 0, 1), Color(0, 0.5, 0, 0) );dcolor = Color(0, -0.5, 0, -1) / lifetime / 2;

Rand(mean, var) mean

var

AvatarAvatar

Keyboard controls its behavior:– ProcessInput

Its position and orientation will be the camera position and orientation before rendering– SetCameraTransform

Like a ship but is not drawn– Control: gravitation, bullet collision

Avatar :: SetCameraTransformAvatar :: SetCameraTransformAvatar :: SetCameraTransform( ) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(position.x, position.y, position.z,

position.x + velocity.x, position.y + velocity.y, position.z + velocity.z,

up.x, up.y, up.z);}

eye

lookat

up = [0, 1, 0]

Keyboard ProcessingKeyboard Processing

KeyboardFuncSpecialFunc

input

IdleFunc:GameLoop

virtualworld

IsSpace, IsLeft, IsRight, IsUp, IsDown

Avatar :: ProcessInputAvatar :: ProcessInputAvatar :: ProcessInput( GLUTWindow * input ) { if ( input->IsSpace( ) )// shoot

world -> Join(new Bullet(position, velocity));

Vector head = velocity.UnitVector();

if ( input->IsUp() ) force += up * (-1); if ( input->IsDown() ) force += up; if ( input->IsLeft() ) force += up % head; if ( input->IsRight() ) force += head % up;}

Game Game EngineEngine

GameObjectposition, velocity, accelerationControlIt(float dt )AnimateIt(float dt)InteractIt( GameObject * o) DrawIt( )IntersectIt(Ray r, float& t)

MemberControl, Animate, DrawInteract, Intersect, Join

TexturedObject

next

AvatarProcessInput()

SetCameraTransform()

TextureLoad( char * fname)

BillBoardDrawIt()

ParticleSystemEmit(int n)

Particle

GLUTWindow

GameEngineDisplayFunc

IdleFuncKeyPress

world

avatar

500 C++ lines

Space GameSpace Game

TexturedObjectAvatar BillBoard

SpaceDrawIt

PlanetDrawIt

AnimateIt

SelfProcessInput

ControlItInteractIt

BulletControlIt

ShipDrawIt

InteractItControlIt

GameEngine

SpaceGame

350 C++ lines


Recommended