Upload
letitia-hutchinson
View
218
Download
0
Embed Size (px)
Citation preview
Advanced techniques for the development of 2D Windows 8 games using Direct X and C++
Markus JostCEO, Lead Programmer, Codebox [email protected]
Agenda
AgendaRecap first Session 5’Quick overview of first session
Cross-Device UI Design 5’ Multi-Resolution, Multi-Aspect-Ratio and Multi-Screensize support
Performance tuning 15’ Saving Memory with Atlases Improving Render-Time with Sprite-Batching Fill-Rate and Alpha Blending
Advanced Techniques 15’ Sprite-Collections Different 2D Animation systems Particle Systems Fonts
Questions 5’
Cross-Device UI Design
Chapter 1/4
Multi-Resolution Support
The Problem: We have resolutions between ~640x480 and 2560x1600 (13,3x) On hi-res screens we want hi-res assets, on low-res screens there’s no memory for
that High DPI != large screen. Screen size changes everything!
The Solution: We define different sets for all assets
Low: 512x384 Med: 1024x768 High: 2048x1536
Then we load the closest set e.g. for iPhone 4 (960x640) we load the Med-set Then we scale if necessary e.g. iPhone 4 scale-factor = 960 / 1024 = 0.9375
Backbuffer or custom
Multi-Aspect-Ratio Support (1/2)
The Problem: The Aspect-Ratio can be between 4:3 and 16:9 We don’t like black bars Cropping the width or height can have an impact on gameplay
The Solution: Is tricky. Every asset needs to be handled accordingly
Illustrating design thoughts by sample
Multi-Aspect-Ratio Support (2/2)
iPad (4:3) iPhone 4 (3:2) iPhone 5 (16:9)
Native resolution of design frame
Custom store UI (screen size issue)
Fixed Width because of gameplay
Adjusted floor level to not hide behind Bottom UI
UI components are sticky to borders
-> loss of Gameworld-Height
Further loss of Gameworld-Height would be unacceptable
-> Adding borders to not change gameplay
Performance tuning
Chapter 2/4
Memory basics By ‘Memory’ we mean RAM. Phones usually have shared RAM while PC’s can have
dedicated GPU RAM While an iPad1 has less than 90MB available, a PC can have more than 4GB
dedicated RAM Loading Textures or DirectX Resources into RAM is costly DirectX resources are unmanaged Older GPU’s resize Textures to ‘power of 2’
E.g. a 120x200 Image uses 128x256 pixels in memory Using ‘power of 2’ Textures allows for some GPU optimizations While a png or jpeg is compressed, Textures in RAM are not
There are compression formats for DirectX or OpenGL that the GPU can handle, but they are very ‘lossy’ and usually not used in 2D games
E.g. a 2048x2048 png that is 2MB becomes 16MB in RAM Maximum Texture Dimensions are limited
E.g. 1024x1024 on older phones, 2048x2048 on newer phones and tablets
Improving Memory Usage
Texture Atlases
© Gango Games
Improves Memory usage dramatically
Improves loading times Improves Rendering if done
correctly Render Subparts of Images by using
correct TextureCoordinates
<?xml version="1.0" encoding="UTF-8"?><!-- Created with TexturePacker http://texturepacker.com--><!-- $TexturePacker:SmartUpdate:963678140e0adc4acab0c90e39ea3d54$ --><!--Format:n => name of the spritex => sprite x pos in texturey => sprite y pos in texturew => sprite width (may be trimmed)h => sprite height (may be trimmed)oX => sprite's x-corner offset (only available if trimmed)oY => sprite's y-corner offset (only available if trimmed)oW => sprite's original width (only available if trimmed)oH => sprite's original height (only available if trimmed)r => 'y' only set if sprite is rotated--><TextureAtlas imagePath="FlySplash.png" width="512" height="1024"> <sprite n="fly_mouth_frame1.png" x="416" y="210" w="56" h="102" r="y"/> <sprite n="fly_mouth_frame2.png" x="416" y="106" w="56" h="102" r="y"/> <sprite n="fly_mouth_frame3.png" x="416" y="2" w="56" h="102" r="y"/> <sprite n="fly_splash_solid.png" x="2" y="2" w="412" h="298"/> <sprite n="fly_wings_frame1.png" x="2" y="412" w="228" h="108"/> <sprite n="fly_wings_frame2.png" x="232" y="314" w="228" h="108"/> <sprite n="fly_wings_frame3.png" x="2" y="302" w="228" h="108"/></TextureAtlas>
Improve Loading Times
Build-time processing media Pre-process your media assets such
as shaders, textures and meshes Load runtime formats
Pipeline Direct3D 11: http://code.msdn.microsoft.com/windowsapps/Direct3D-Resource-Loading-25406148
Choose right PrimitiveType
PointList
v1v2
v3v4
LineList
v1v2
v3v4
LineStrip
v1v2
v3v4
TriangleList TriangleStrip TriangleFan
Improve Render-Time
Sprite-BatchingSort and defer draw-calls
Changing texture disturbs GPU -> sort calls by Texture Reduce number of draw calls by merging vertices (CPU,
Trianglelist) Can cause problems with semi-transparent textures (no-
drawing order) Use Instancing for increasing Performance of Rendering
No Texture switch, 1 context switch, reuse mesh-data, draw calls on GPU
Increase performance by rendering front-to-back (depth-buffer / depth-test)
Needs z-information Does not work with semi-transparent textures
=> Keeping in mind that the number of draw calls and texture-switches should be reduced, many ways or combinations can be possible. Be creative!
SpriteBatch Sample: http://code.msdn.microsoft.com/windowsapps/Direct3D-sprite-sample-97ae6262
Fill-Rate
The Problem: Drawing a Texture means writing each pixel to the Backbuffer On “not-so-good” GPUs that’s slow Phones have them. And in addition they have ridiculous resolutions. The number of times the same Screen-Pixel is written is what I call Fill-
Rate
The Solution: Avoid Alpha Blending whenever possible Use depth-information to reduce number of pixel-writes
(good in 3D with no alpha) Merge layers when possible Just be careful with rendering too many layers
Fill-Rate
Sample optimization
Up to 104 hi-res alpha blended images Adding up to 6 «pixel writes»
optimization
Step 1: render card without alpha border-> Filling depth buffer front to back-> Make use of SpriteBatching
Step 2: render full card using alpha blending back to front
Advanced Techniques
Chapter 3/4
Sprite-Collections
Basically means adding hierarchy to Sprites
Sprite-Level0
x:100 y:100 angle: -10 degrees
(0,0)x
y
x2y2
Sprite-Level1
x:-150 y:-100
angle: 0
Sprite-Level1x:100 y:-60 angle: 15
Allows to move, rotate and scale group of Sprites
Parts can be individually controlled with respect to parent Sprites
Needed for Bone Animations
Sample Pseudo Code for setting Transform:
Vector<Sprite*> parents = getParentSprites();Matrix translation = Matrix.Identity;foreach(Sprite *s in parents) { translation *= s.getTranslationMatrix();}translation *= getTranslationMatrix();
SetTranslation(translation);
SpriteSheet AnimationCreate animation sequences from an Atlas Pros:
High level of detail Easy to implement
Cons: Very High Memory use Low FPS resolution Hand drawn frames take time
Animating (1/3)
Animating (2/3)
Bone AnimationsCreate animations using a tool (e.g. Flash) combining body parts Pros:
Way less memory consumption Allows many many animations to reuse
same texture parts Runs at max FPS Artists are used to using Flash Fast creation
Cons: Low level of details Restrictions in design More work to implement
Animating (3/3)
3D AnimationsUse 3D Animations made with 3DSMax or any other 3D Animation Tool Pros:
Smooth Animations High Level of Details Depending on LOD, fast production
Cons: Doesn’t mix well with 2D GPU intense Also Memory intense due to Animation
data
Particle Systems
Used for example for smoke, fire, dust, snow, rain etc.
Lots of tiny textures that face the camera Each particle has its own state
Position Rotation Scale Color 1 Texture…
Using PointSprites, particles have only 1 vertex Usually alpha blended -> performance
Avoid filling Particle Sytsems Supported by most GPUs
Particle Systems
Sample
Particle Systems
Implementation
Ss = Vh * Si * sqrt(1/(A + B * De + C *( De2 )))
Vh : Viewport heightSi : Initial point sizeDe
2 : The Distance from eye to positionA, B, C : User defined values
float fPointSize = 1.0f, fPointScaleB = 1.0f;
m_d3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, true); //create vertices?m_d3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, true); //use scale function?
m_d3dDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&fPointSize)); m_d3dDevice->SetRenderState(D3DRS_POINTSCALE_B, *((DWORD*)&fPointScaleB)); m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,true); m_d3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);m_d3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_PSIZE | D3DFVF_DIFFUSE) struct D3DVERTEX { float fX, fY, fZ, fSize; DWORD dwColor; };
D3DXCreateTextureFromFile(m_d3dDevice,"texture.png",&pTex);
m_d3dDevice->SetTexture(0,pTex);m_d3dDevice->SetStreamSource(0,pVB,0,sizeof(D3DVERTEX)); m_d3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, numPoints);
Physics
Box2D Written in C++, open Source, zlib licensed Very sophisticated and widely used Easy to learn and implement
Check out the manual: http://www.box2d.org/manual.html
Fonts
On Windows 8Use DirectWrite to format and layout textUse Direct2D to render the textSample can be found here: http://code.msdn.microsoft.com/windowsapps/DWriteHelloWorld-760793d2
On Windows Phone 8Use XAML
Or use BitmapFontsCheck Out: http://directxtk.codeplex.com/Or use a tool like Glyph Designer: http://www.71squared.com/en/glyphdesigner
BitmapFonts
XML + PNG
Questions?
Chapter 4/4
© 2013 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a
commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.