Upload
vera
View
38
Download
0
Tags:
Embed Size (px)
DESCRIPTION
SAGE Demo 0 Model Viewer. SAGE Lecture Notes Ian Parberry University of North Texas. SAGE Demo 0. Demo 0 has two functions Getting you started on coding with SAGE Providing a tool that artists and programmers can use to check S3D models for compatibility and correctness. Introduction. - PowerPoint PPT Presentation
Citation preview
1
SAGE Demo 0Model Viewer
SAGE Lecture Notes
Ian Parberry
University of North Texas
2
3
SAGE Demo 0
• Demo 0 has two functions– Getting you started on coding with SAGE– Providing a tool that artists and programmers
can use to check S3D models for compatibility and correctness
4
Introduction
• Here’s what we’ll cover in this lecture– Introduction to the SAGE foundation code– Using the foundation code to develop a model
viewer application
5
SAGE Foundation Code
• SAGE is based on foundation code modified from 3D Math Primer for Graphics and Game Development, by Fletcher Dunn and Ian Parberry
6
High Level Overview• The book 3D Math Primer for Graphics and
Game Development provides a code utility library
• Common files are in a folder called common• Utilities are provided for
– the standard math tools covered in class– code for managing
• Windows • DirectX• includes a dialog box for displaying error messages on exit
7
High Level Overview 2
• More utilities:– a renderer– primitive input handlers for mouse & keyboard– a model class, including importer for the S3D
model file format
8
9
10
Files in Common• AABB3.cpp, AABB3.h: Axially aligned
bounding boxes (Section 12.4)• Bitmap.cpp, Bitmap.h: Simple class to hold
a bitmap image• Camera.cpp, Camera.h: Camera class• CommonStuff.h, CommonStuff.cpp:
Common stuff that doesn’t belong elsewhere• EditTriMesh.cpp, EditTriMesh.h:
Editable triangle mesh class (Section 14.5)
11
More Files in Common• EulerAngles.cpp, EulerAngles.h: Euler
angle class (Section 10.3, 11.2)• FontCacheEntry.h, FontCacheEntry.cpp
: Font class• MathUtil.cpp, MathUtil.h: Basic math
utilities• Matrix4x3.cpp, Matrix4x3.h:
Homogenous transformation matrix code (Section 11.5)
12
Even More Files in Common• Model.cpp, Model.h: Simple class for a 3D model• Quaternion.cpp, Quaternion.h: Quaternion class
(Section 10.4, 11.3)• Random.cpp, Random.h, Random2.cpp, Random2.h: Random Number Generator classes
• Renderer.cpp, Renderer.h: Code for the rendering engine
• RotationMatrix.cpp, RotationMatrix.h: Rotation matrix class (Section 11.4)
13
Yet More Files in Common• TextureCacheEntry.cpp, TextureCacheEntry.h:Texture management classes
• TriMesh.cpp, TriMesh.h: Triangle mesh class (Chapter 14)
• Vector2.h, vector3.h: 2D and 3D vector classes (Chapter 6)
14
Your Main Program• You need to provide function mainProgram()• This function should consist of:
initialization
while (!gQuitFlag) { // frame loop
move objects
render objects
process input
}
shutdown
15
Initialization
• Create the application window:
createAppWindow(“My Game");• Select the video mode to mode
• Initialize the renderer (second parameter is whether windowed)gRenderer.init(mode, true);
16
Initialization 2
• Your initialization, eg. Reading in models:Model model;
model.importS3d(“Model.s3d”);
model.cache();
17
Move ObjectsIn vector parlance: add to the location vector
the velocity vector times elapsed time• Similar for orientation• Use the frame rate timer provided by the
renderer: float gRenderer.getTimeStep();
18
Render Objects• Set up the camera
gRenderer.setCamera(cameraLoc, cameraOrient);
gRenderer.setZoom( fovToZoom(degToRad(dFov)));
• Prepare the renderergRenderer.beginScene();gRenderer.clear();
• Set the scene (eg lighting)
19
Render Objects 2• Render the objects using an instance
stackgRenderer.instance(kZeroVector, modelOrient);
model.render();gRenderer.instancePop();
• Show the resultgRenderer.endScene();gRenderer.flipPages();
20
Process Input
• Process input at the end of each frame.
• Support provided in Demo 0 is limited to wrappering the Windows API input.
21
Shutdown
• Shut down the renderergRenderer.shutdown();
• Destroy the application windowdestroyAppWindow();
22
Making it Into a Game Engine• SAGE will add code for some of the features
needed to make a game, for example:– Terrain (Demo 1)– Object manager (Demo 3) – DirectInput (Demo 3)– Particle engine (Demo 5)– Game shell– Sound manager (Demo 6)
• Other things that can be added– Artificial intelligence– Physics– Networking
23
Key Topics
• Renderer
• Camera
• Reference Frames
• Textures
• Render States
• Models
24
Key Topics Cont.
• GameBase
• Resources
• Input
• DirectoryManager
25
Renderer Overview• The render code has the following
responsibilities– Initializing the scene– Drawing everything to the screen– Maintaining game data
• Validating devices• Cleaning up memory
– Maintaining the camera– Restoring a scene– Managing the window
26
Renderer Functions• init() – Initializes the renderer• shutdown() – Cleans up the renderer
before shutdown.• beginScene() – Called at the start of a
frame– Checks to make sure we still have the device
• endScene() – Called at the end of a frame– Checks again to make sure we still have the
device
27
Function Overview Cont.
• flipPages() – Updates the screen
• validateDevice() – Make sure you can still draw
• restoreRenderStates() – Restores render states to their default values
28
Renderer::init()• Initializes the renderer with the following
parameters– VideoMode – The video mode attributes
• xRes – The horizontal resolution of the screen• yRes – The vertical resoulution of the screen• bitsPerPixel – 16, 24, or 32-bit color• refreshHz – The refresh rate of the screen
– Can only use kRefreshRateXxx constants
– shaderDebug – True if you want shader debugging turning on
– windowed – True if you want the game to run in windowed
29
Renderer::flipPages()
• Check to make sure we still have the device
• Update the screen if we have the device
• Update the timing
if (pD3DDevice != NULL) {
HRESULT result = pD3DDevice->Present(NULL,NULL,NULL,NULL);
}
30
Renderer::validateDevice()
• validateDevice() performs the following functions– Test if device is valid– Checks if device is lost, and if so loops until it
returns. HRESULT hr = pD3DDevice->TestCooperativeLevel();
if (hr == D3DERR_DEVICELOST) { while (1) { // let windows process gWindowsWrapper.idle(); // check device to see if it is ready hr = pD3DDevice->TestCooperativeLevel(); if (hr == D3DERR_DEVICENOTRESET) break; }}
31
Renderer::validateDevice() Cont.
– Restores non-managed resources // device is ready! restore all non managed resources
gResourceManager.releaseAll();
// release pointer to buffers b/c these are not in the resource manager if (pOriginalBackBuffer) pOriginalBackBuffer->Release(); if (pOriginalDepthStencil) pOriginalDepthStencil->Release();
pD3DDevice->Reset(&presentParms);
// get pointers to depth buffer and back buffer pD3DDevice->GetRenderTarget(0, &pOriginalBackBuffer); pD3DDevice->GetDepthStencilSurface(&pOriginalDepthStencil); gResourceManager.restoreAll();
restoreRenderStates();
32
Renderer::restoreRenderStates()
• Resets render states to default values setD3DRenderState(D3DRS_ZENABLE, zEnable); setD3DRenderState(D3DRS_ZWRITEENABLE, TRUE); setD3DRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); setD3DRenderState(D3DRS_ALPHABLENDENABLE, blendEnable); setD3DRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); setD3DRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); setD3DRenderState(D3DRS_AMBIENT, ambientLightColor); setD3DRenderState(D3DRS_FOGENABLE, fogEnable); setD3DRenderState(D3DRS_FOGCOLOR, fogColor); setD3DRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); setD3DRenderState(D3DRS_RANGEFOGENABLE, TRUE); setD3DRenderState(D3DRS_FOGSTART, *(DWORD*)(&fogNear)); setD3DRenderState(D3DRS_FOGEND, *(DWORD*)(&fogFar)); setBackfaceMode(backfaceMode); setWireframe(wireframeOn);
33
Renderer::restoreRenderStates() Cont.
• Reset sample states to their default values
• Reset Material properties to their default values
• Reset Lights to their default values
setD3DSamplerState(D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); setD3DSamplerState(D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); setD3DSamplerState(D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); // Set texture wrapping mode setD3DSamplerState(D3DSAMP_ADDRESSU , D3DTADDRESS_WRAP ); setD3DSamplerState(D3DSAMP_ADDRESSV , D3DTADDRESS_WRAP );
34
Camera• The camera provides your view of the scene• The renderer handles camera management, and
gives you access to the camera• Camera Attributes
– Position– Orientation– Zoom– Clipping Planes
35
Clipping Planes
• Creates boundaries for visible objects
• Near Clipping Plane– Objects closer to the camera then the near
clipping plane are culled
• Far Clipping Plane– Object farther away from the camera then the
far clipping plane are culled
36
Reference Frames• How the camera views a scene• Local Space
– The coordinate space in which an object is first defined
• World Space– The space where all objects in a scene are displayed
• Object Space– The coordinate space in which an object is defined
37
Reference Frame Implementation
• Matrix representation
• Using a stack for reference frames– For the model viewer we only use the
reference frame stack to push the current reference frame onto before changing it so that we can pop it off when we are done and leave it unchanged.
38
Textures
• The Renderer manages textures using a texture cache
– This loads the texture into memory
// get a handle to the textureint txtHndl = gRenderer.cacheTexture("myImage.tga", true);// ... processing code// set the texture myImage.tga to be the current texturegRenderer.selectTexture(txtHndl);// draw model
39
Render States Overview• The Fixed-Function Pipeline• Depth Buffer• Alpha Blending• Fog• Wireframe• Texture Clamping• Lighting• Back-Face Culling
40
Depth Buffer
• Z-Culling– Culls objects behind other objects based on
their z-axis position
• Transparency– Typically you have to disable Z-Culling when
drawing transparent objects, and then draw them in z-order from back to front
41
Alpha Blending
• setSourceBlendMode()
• setDestBlendMode()
Color = ColorOld(1.0 – alpha) + ColorNew * Alpha
42
Fog• Obscuring the far clipping plane
– Using fog gradually decreases visibility of objects as they get farther away. This keeps them from just disappearing once they reach the far clipping plane.
• Fog near plane– Objects closer to the camera the near fog plane don’t
get obscured
• Linear Interpolation– Fog in demo 00 is calculated using linear
interpolation. This means the thickness of the fog is directly proportional to the distance from the camera.
43
Wireframe ModesetWireFrame(true);
setWireFrame(false);
44
Texture Clamping
• Tiling– When you tile a texture, it repeats if the uv
coordinates of a vertex are greater than 1.0.
0.0 1.0 2.0
45
Texture Clamping Cont.
• Clamping– When you clamp a texture, uv coordinates
greater than 1.0 are drawn with a solid color
0.0 1.0 2.0
46
Lighting
• Ambient Light– General level of light that affects everything in
the scene the same
• Directional Light– Light with a location and direction.
• Spot Light
• Surface Normals
• Materials
47
Back-Face Culling
• Winding– CullMode
• Clockwise– Polygons defined in a counter-clockwise order are not
drawn
• Counter-Clockwise– Polygons define in a clockwise order are not drawn
• None– All polygons are drawn regardless of their order.
48
Render Functions• DrawPrimitiveUP
– Renders data as a sequence of geometric primitives without using vertex buffers
• DrawPrimitive– Renders a sequence of non-indexed,
geometric primitives from a vertex buffer
• DrawIndexedPrimitive– Renders an indexed geometric primitive using
a vertex buffer and an index buffer
49
Models Overview
• Initialization
• Importing Models
• Rendering Models
• Bounding Boxes
50
Initialization
• BufferUsage Enumeration– NoBuffers
• Don’t buffer the models geometry
– StaticIndexBuffer• Buffer the models geometry and use an index
buffer
– StaticBuffers(default)• Buffer the models geometry without an index buffer
51
Importing Models – Model::imports3d()
• Loads the s3d model from a file in three steps
1. Load the model data from a file
2. Optimize the mesh for rendering
3. Convert it into a renderable format
EditTriMesh editMesh;editMesh.importS3d(s3dFilename, text, defaultDirectory)
editMesh.optimizeForRendering();
fromEditMesh(editMesh);
52
Rendering Models
• render()– Goes through every part of the model and
calls renderPart()
• renderPart()– Selects the texture for this part of the model
and renders its geometry using that texturegRenderer.selectTexture(m_partTextureList[index]);
gRenderer.render( m_vertexBuffer, 0, m_partMeshList[index].getVertexCount(), m_indexBuffer, m_indexOffsets[index], m_partMeshList[index].getTriCount());
53
Bounding Box
• AABB– Axially-Aligning Bounding Box– Used in collision detection
• getBoundingBox(Matrix)– Retrieves the AABB for a model
54
Animated Models• AnimatedModel Class
– Derived from the model class– Loads multiple model files that represents the
frames of the animation and animates them
• Linear Interpolation
– Limitations• Rotations
A = (1 – r)B + rC
Where the rotation is at
Where the rotation should be
Animation Path
55
Animated Model Functions• AnimatedModel(int, int)
– Initializes the model with the following data• framecount – The number of submodels• Animationcount – the number of animation sequences
• setAnimationSequence(int, list<int>)– Specifies a sequence for a models animation
• seqno – The sequence number in the list of sequences• sequence – A list of frames in the animation sequence
56
Animated Model Functions
• selectAnimationFrame(float, int, VertexBuffer)
– Moves the model to a specific frame in its animation
– Parameters• frame – The fractional frame number to be
rendered as an interpolated animation frame• animation – The animation sequence to be run• vb – The vertex buffer to write to.
57
Using Animated Models
void Game::loadModel(){ // ... std::list<const char*> frames; // ... // load frames with list of filenames // ... m_curModel = new AnimatedModel((int)frames.size()); m_curModel->importS3d(frames, false); // ... m_vertexBuffer = m_curModel->getNewVertexBuffer(); // ...}void Game::process(){ // ... float dt = gRenderer.getTimeStep(); totalTime += dt; // ... // load our vertex buffer with the interpolated model if(m_curModel != NULL) m_curModel->selectAnimationFrame(totalTime, 0, *m_vertexBuffer); // ...}
58
GameBase• Base class for game
– The game will inherit this class and implement the methods it needs
• Functions– initiate()
• Initialize the game
– main()• The main loop in the game.• Called be window wrapper each frame
– shutdown()• Clean up memory and exit program
59
Resources• Resources are allocated blocks of memory• The maintain un-managed resources that need
to be restored if the game loses focus• Dynamic Resources
– Resources that change frequently– These are usually the resources that you want to
manage yourself• Static Resources
– Resources that seldom change– These resources are typically set up to be managed
by DirectX
60
Input• InputManager
– The input manager handles the input from devices such as your keyboard, mouse, or joystick
– Uses DirectInput to maintain input– Basic functionality will tell you:
• If a key is down– InputManager::keyDown(keyCode, override)
• If a key has just gone down (It was up last frame)– InputManager::keyJustDown(keyCode, override)
• If a key as just gone up (It was down last frame)– InputManager::keyJustUp(keyCode, override)
• The override is a boolean that is true if you want to ignore the m_keyBoardOn flag
61
DirectoryManager• Default Directories
– You can add default directories to the directory manager for use by your program
• Adding a directory
1. Add a line to the directories.xml
2. Add an enumerated value to the EDirectory type in the DirectoryManager.h file.
3. Add a condition statement to the function DirectoryManager::getResourceIndex() that tests for the xml tag name you used in step
62
Add a line to the directories.xml
<?xml version="1.0" encoding="utf-8"?>
<directories> <models path="\Models"/> <textures path="\Textures"/> <xmls path="\XML"/> <otherstuff path=“\Stuff” /></directories>
63
Add an enumerated value to the EDirectory type
enum EDirectory{ eDirectoryTextures, ///< Any texture for the game eDirectoryModels, ///< Any model for the game eDirectoryXML, ///< Any XML for the game eDirectoryStuff, ///< Any thing I want to be here eDirectoryMax // make sure this is last};
64
Add a statement to the function DirectoryManager::getResourceIndex()
EDirectory DirectoryManager::getResourceIndex( std::string resourceName)
{int index = -1;
if (resourceName == "textures") index = eDirectoryTextures;else if (resourceName == "models") index = eDirectoryModels;else if (resourceName == "xmls") index = eDirectoryXML;else if (resourceName == “otherstuff”) index = eDirectoryStuff;
return (EDirectory)index;}