程序代写代做代考 c# 1 Introduction to Graphics Programming

1 Introduction to Graphics Programming

ITP4710

2D/3D Graphics Programming
02
Basic 2D Graphics Programming

When you create a new MonoGame project, one of the easiest method is to use the MonoGame given project templates
Start your Visual Studio 2015
Game1.cs, Program.cs and other files will be added into your project automatically
You will mainly work on Game1.cs file.
Like any C# application, a MonoGame application begins by referencing the assemblies and namespaces required by the program
All necessary MonoGame implemented XNA framework references for Graphics, Input and etc. will be automatically added for you in the default Game1.cs file generated
© VTC 2016
2
MonoGame Template

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Game1 {
public class Game1 : Game {
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

public Game1() {
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = “Content”;
}

© VTC 2016
3
Game1.cs

© VTC 2016
4

/// Initialize:
/// Allows the game to perform any initialization
/// it needs to before starting to run.
/// This is where the game query for any required
/// services and load any non-graphic related content.
protected override void Initialize() {
// TODO: Add your initialization logic here
base.Initialize();
}

/// LoadContent:
/// called once per game to load all contents
protected override void LoadContent() {
// Create a new SpriteBatch for drawing textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use Content to load game content here
}

/// UnloadContent: called once per game to unload contents
protected override void UnloadContent() {
// TODO: Unload any non ContentManager content here
}

© VTC 2016
5

/// Update: Allows the game to run logic such as updating
/// the world, checking for collisions, gathering input,
/// and playing audio.
protected override void Update(GameTime gameTime) {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit(); // Allows the game to exit
// TODO: Add your update logic here
base.Update(gameTime);
}

/// Draw: This is called when the game should draw itself.
protected override void Draw(GameTime gameTime) {
GraphicsDevice.Clear(Color.CornflowerBlue); // Clear bkgd
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}

MonoGame application requires a GraphicsDeviceManager to handle the configuration and management of the graphics device
The GraphicsDevice class is used for drawing
The GraphicsDeviceManager object is initialized in the game class constructor
The SpriteBatch object provides access to methods for drawing images, referred to as sprites, in the game window
One SpriteBatch object is enough to draw all 2D images in your game
SpriteBatch object is initialized in the LoadContent() function.
6
GraphicsDeviceManager And SpriteBatch
© VTC 2016

ContentManager is used to load, manage and dispose of the media content through the content pipeline
When you uses the game template, the root directory of your content will be defined in the constructor as follows:
Content.RootDirectory = “Content”;
That means all your image, audio and models should be placed in the Content folder in your Solution.
The Content object will be used to load these media content in your LoadContent() function.

7
ContentManager
© VTC 2016

After the GraphicsDeviceManager object has been created, Initialize() method will do the one-time game startup event, such as:
Setting window properties (e.g., title or full-screen).
Initializing arrays and other variables.
Initializing vertices for storing position, color, image coordinates and etc.
Setting up your camera to view the 3D game world.
Setting up other game objects
LoadContent() method is used to load binary image and model content through the content pipeline
LoadContent() is called after Initialize()
LoadContent() will also be called to reload your media resources when the DeviceReset event occurs

8
Initialize() and LoadContent()
© VTC 2016

Once the MonoGame application is initialized, it enters a continuous loop that draw and update the game – which we call game loop
By default, a game uses a fixed-step game loop with a default TargetElapsedTime of 1/60th of a second.
In a fixed-step game loop, Game calls Update() once the TargetElapsedTime has elapsed.
After Update() is called, if it is not time to call Update() again, the game will call Draw().
After Draw() is called, if it is not time to call Update() again, the game idles until it is time to call Update().
If Update() takes too long to process, the game will set IsRunningSlowly to true and calls Update() again, without calling Draw() in between.
You can change the default setting by changing the property Game.IsFixedTimeStep and Game.TargetElapsedTime.
9
Game Loop
© VTC 2016

Update() function is called when the game logic needs to be processed.
This might include the management of the game state, the processing of user input, or the updating of simulation data.
You should override this method in your game with game-specific logic.
Draw() function is called when the game needs to re-draw the frame.
You should override this method with game-specific rendering code.
Override the UnloadContent() function to free up your memory resources that is not loaded into the game through the content manager.

© VTC 2016
10
Update(), Draw() and UnloadContent()

© VTC 2016
11
Game Application Flow

Source: http://centurion2.com/XNA/XNA120/xna120.php

YES

11

Building a 2D game is a nice way to start to learn using MonoGame
Much easier to create than 3D games
Cover many basic techniques and get exciting results
2D image animation is very important to an exciting interactive 2D game
2D coordinate system is used to position the images and determine which sections of the image are drawn
Width and height of the window and all images are measured in pixels
X values start from 0 on the left and increase towards the right
Y values start from 0 on the top and increase downwards

12
2D Graphics Game Programming
© VTC 2016

You can change the size of the game screen or toggle full screen by setting the following properties inside the constructor.
graphics.IsFullScreen = false;
graphics.PreferredBackBufferHeight = height;
graphics.PreferredBackBufferWidth = width;
If you want to change the screen setting after calling the constructor, you need to add the following statement after changing the above properties:
graphics.ApplyChanges();
© VTC 2016
13
Screen Size and Full Screen

MonoGame’s Content Manager loads an image to a Texture2D object
MonoGame supports automatic loading of bmp, dds, dib, hdr, jpg, pfm, png, ppm and tga image files.
The Content Pipeline is also extensible to support other media files
Texture2D is an in-memory digital image that is represented as a 2D array of color values, each representing a pixel
To load the image to a Texture2D object,
A Texture2D object should be declared in class level.
Image file should be added into the Content project through MonoGame’s Content Pipeline Tool.
Use the Content object to load the image file to the Texture2D object.

© VTC 2016
14
Loading Image Files to Textures

15
Loading Image Files to Textures
(Step 1)

© VTC 2016

Texture2D objects declared

16
Loading Image Files to Textures
(Step 2)

© VTC 2016

Double-click the Content Pipeline Tool inside the Content folder

17
Loading Image Files to Textures
(Step 2)

© VTC 2016

Click here to add a folder
Or choose Edie/Add from menu
Or click mouse right button after selecting Content item

Click here to add existing image file(s)
Or choose Edie/Add from menu
Or click mouse right button after selecting Content item

Save and Build the Content Project before exiting back to the MonoGame project.

18
Loading Image Files to Textures
(Step 3)

© VTC 2016

Use “Content” object to load the image files to Texture2D objects

A sprite is a 2D image that is integrated into a larger game scene
Sprites can be positioned and animated independent of each other, using the same texture
Large textures may be broken into multiple smaller images in memory for drawing different sprites
SpriteBatch class manages the drawing of your sprites to the screen
To begin drawing sprites, you call the Begin() method on the SpriteBatch object
Draw your sprites in your Draw() method
Call the End() method of the SpriteBatch to end the process
You may want to set the properties of your SpriteBatch object before drawing your sprite. This will be discussed in later slides.
19
Sprite and SpriteBatch
© VTC 2016

protected override void Draw(GameTime gameTime) {
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(texture,
GraphicsDevice.Viewport.Bounds, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
The texture is drawn to the screen by stretching the image to the exact size of your game window
Stretch to the rectangle represented by the second parameter.
new Rectangle(left, top, width, height)
GraphicsDevice.Viewport.Bounds represents the rectangle bounding the window screen.
© VTC 2016
20
Example: Drawing Background Texture

If you don’t want your image stretched, you may call spriteBatch.Draw() function in this way:
spriteBatch.Draw(texture, Vector2.Zero, Color.White);
Vector2.Zero represents (0,0) and such function will draw the image with original size and place it on the top-left corner.
If you want to place your image in the middle, you may try this:
spriteBatch.Draw(texture, new Vector2(
(GraphicsDevice.ViewPort.Width-texture.Width)/2, (GraphicsDevice.ViewPort.Height-texture.Height)/2, Color.White);
© VTC 2016
21
Example: Drawing Background Texture

protected override void Draw(GameTime gameTime) {
Vector2 loc = new Vector2(0, 0); // sprite position
float height = GraphicsDevice.Viewport.Height;
float width = GraphicsDevice.Viewport.Width;
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// draw our background tile in a grid
for (int y=0; y <= height/texture.Height+1; y++) { loc.Y = y * texture.Height; for (int x=0; x <= width/texture.Width+1; x++) { loc.X = x * texture.Width; spriteBatch.Draw(texture, loc, Color.White); } } spriteBatch.End(); base.Draw(gameTime); } © VTC 2016 22 Example: Tiling the Background © VTC 2016 23 Example: Tiling the Background When drawing the sprite, we can tint the image using any color In the previous example, Color.White means no tinting is used. Colors in MonoGame are expressed using four components RGBA – namely Red, Green, Blue and Aplha Many different color constants have been given in MonoGame Custom colors can also be created through various constructors, passing the component values as 0-255 byte values or 0-1 floating point values. The fourth component is called “alpha”, which determines the opacity 1.0f means fully opaque, 0.0f means fully transparent 24 Color in MonoGame © VTC 2016 In the Update() and Draw() methods, a GameTime object is passed as a parameter into the methods This GameTime object counts the time elapsed between frames and total time since the start of the game ElapsedGameTime - The amount of elapsed game time since the last update. ElapsedRealTime - The amount of elapsed real time (wall clock) since the last frame. TotalGameTime - The amount of game time since the start of the game. TotalRealTime - The amount of real time (wall clock) since the start of the game. 25 Time Ticking © VTC 2016 protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); // use sine function to pulse the tint and transparency double radians = gameTime.TotalGameTime.TotalSeconds * Math.PI; float bias = (float)Math.Sin(radians); // clamp the output of sine (-1 .. 1) to the (0 .. 1) range bias = (bias + 1.0f) / 2.0f; Color color1 = new Color(1.0f, bias, bias); // tint color: red Color color2 = new Color(1.0f, 1.0f, 1.0f, bias); batch.Draw(texture, new Vector2(100, 100), color1); batch.Draw(texture, new Vector2(300, 100), color2); spriteBatch.End(); base.Draw(gameTime); } 26 Example – Tinting and Transparent Sprite © VTC 2016 Creating a series of connected sprites that contain the individual frames, you can make an animation The different sprites of course can be stored in individual sprites However, more usually, the series of connected sprites will be stored into a single texture. We called it a tiled sprite. When you want to play your animation, you simply select the appropriate frame from the tiled sprite and draw it to the screen in its proper position 27 Animated Sprites © VTC 2016 You will need to declare variables for tracking your animation, which may include: total number of frames in texture number of rows and columns if multiple row is applied current animation frame number delay between animation frames time since last frame change Width and height of the sprite © VTC 2016 28 Animated Sprites float frameCount = 10; float frameWidth = texture.Width/frameCount; float frameHeight = texture.Height; protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); int frame = (int) (gameTime.TotalGameTime.TotalSeconds*20) % 10; spriteBatch.Draw(texture, new Vector2(100, 100), new Rectangle(frame*frameWidth, 0, frameHeight, frameWidth), Color.White); spriteBatch.End(); base.Draw(gameTime); } 29 Example – Animated Sprites © VTC 2016 Advanced versions of SpriteBatch.Draw() function can have more control on the drawing of the sprite changing the scale of a sprite rotating the sprite sorting the sprite by their distance from the player this requires other spriteBatch setting. spriteBatch.Draw(texture, // the sprite texture location, // Vector2 location rectangle, // null (whole texture) or source rect color, // tinting color rotation, // rotating angle in radians origin, // Vector2 location of rotation center scale, // float or Vector2 scaling factor effect, // flipping factor layerDepth); // sorting depth of sprite // 0 means front, 1 means back © VTC 2016 30 Scaling, Moving and Rotating protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); // use sine function to animate the scale double radians = gameTime.TotalGameTime.TotalSeconds * Math.PI; float scale = (float)Math.Sin(radians); // clamp the output of sine (-1 .. 1) to the (0.5 .. 1.5) range scale = (scale + 1.0f) / 2.0f + 0.5f; batch.Draw( texture, // the sprite texture new Vector2(100, 100), // location to draw the smiley null, // bounds of texture to be drawn Color.White, // no tinting 0.0f, // no rotation (zero radians) new Vector(32,32), // the center of the texture scale, // our calculated scale factor SpriteEffects.None, // draw sprite normally 0.5f); // constant layer depth spriteBatch.End(); base.Draw(gameTime); } © VTC 2016 31 Example – Scaling Sprites Vector2 speed; float rotateSpeed = 0.01f; float rotateAngle; Vector2 loc = new Vector2( GraphicsDevice.ViewPort.Width/2, GraphicsDevice.ViewPort.Height/2); Vector2 smileyCenter = new Vector2( texture.Width/2, texture.Height/2); protected override void Initialize() { Random r = new Random(); speed.X = (float)(r.nextDouble()); speed.Y = (float)(r.nextDouble()); base.Initialize(); } © VTC 2016 32 Example – Bouncing and Rotating Sprite private void Update(GameTime gameTime) { float timeLapse = (float)gameTime.ElapsedGameTime.Milliseconds; if (loc.X > GraphicsDevice.ViewPort.Width-smileyCenter.X) {
loc.X = GraphicsDevice.ViewPort.Width-smileyCenter.X; // move back
speed.X *= -1.0f;
} else if (loc.X – smileyCenter.X < 0) { loc.X = smileyCenter.X; speed.X *= -1.0f; // move back } else loc.X += speed.X * timeLapse; if (loc.Y > GraphicsDevice.ViewPort.Height-smileyCenter.Y) {
loc.Y = GraphicsDevice.ViewPort.Height-smileyCenter.Y; // move back
speed.Y *= -1.0f; // reverse direction
} else if (loc.Y – smileyCenter.Y < 0) { loc.Y = smileyCenter.Y; speed.Y *= -1.0f; // move back } else loc.Y += speed.Y * timeLapse; rotateAngle += rotateSpeed * timeLapse; rotateAngle = rotateAngle % (Math.PI * 2.0f); // 0 .. 2PI } © VTC 2016 33 Example – Bouncing and Rotating Sprite protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); batch.Draw( texture, // the sprite texture loc, // location to draw the smiley null, // whole texture is to be drawn Color.White, // no tint rotateAngle, // rotation smileyCenter, // the center of the rotation 1.0f, // no scaling SpriteEffects.None, // draw sprite normally 0.5f); // constant layer depth spriteBatch.End(); base.Draw(gameTime); } © VTC 2016 34 Example – Bouncing and Rotating Sprite Advanced overloaded version of SpriteBatch.Begin() contains two parameters: SpriteBatch.Begin Method (SpriteSortMode, BlendState); SpriteSortMode represents the sprite drawing order BlendState represents the color blending option Available SpriteSortMode: Deferred, Immediate, BackToFront, FrontToBack, Texture Available BlendState: Additive, AlphaBlend, Opaque, NonPremultiplied © VTC 2016 35 SpriteBatch State Settings When multiple Draw() function calls are made after the default spriteBatch.Begin() function call, the sequence of the drawings seems uncontrolled The images sequence comes random even if you have passed in the sprite depth parameter in calling the Draw() function. If you want to make the image to have a sequence according to the sprite depth, you need to set the sort mode inside the spriteBatch.Begin() function call spriteBatch.Begin(SpriteSortMode.FrontToBack, null); The above setting will made the front textures (the ones with smaller depth) place on the screen first – that is at the back of other images. © VTC 2016 36 Using Sprite Depth Deferred Default mode for SpriteBatch Sprites are not drawn until End() is called Device setting will be applied when End() is called The sprites will be drawn in one batch, in the sequence of calls to Draw() were received (not the sequence of calls) Immediate One active SpriteBatch instance only. Begin() will apply new graphics device settings Sprites will be drawn within each Draw() call Immediate mode is similar to but faster than Deferred mode © VTC 2016 37 SpriteSortMode BackToFront and FrontToBack Device setting will be applied when End() is called When we draw our sprites we can set the layer depth of those sprites to a value is a float between 0.0 (front) and 1.0 (back) The sprites will draw in the order specified by the two modes BackToFront is typically used for transparent sprites FrontToBack is typically used for opaque sprites Texture Same as Deferred mode, except sprites are sorted by texture prior to drawing. Sprites within the same texture will be drawn in a batch © VTC 2016 38 SpriteSortMode for (int i = 0; i < 4; i++) spriteBatch.Draw(texture[i], new Vector2(50 + (50*i), 50 + (50*i)), location[i], Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, i * 0.1f); © VTC 2016 39 Example – Sprite Depth Blend state controls how multiple images combined AlphaBlend Blending the source (image to be drawn) and destination (image already on screen) using source alpha data Default value (i.e., when you are using default Begin() function, or when you enter null in the setting) Opaque Overwriting the destination image using the source image. No alpha value will be considered. Additive Adding the destination data to the source data without using alpha. NonPremultiplied Similar to AlphaBlend, non-premultipled alpha is used if color data does not contain alpha. © VTC 2016 40 Blend States You can import a SpriteFont into a game project and draw text using DrawString() method in SpriteBatch. In your Contente Pipeline Tool, select the Content and right-click your solution explorer. Choose Add > New Item > Sprite Font. Give your sprite font a meaningful name.
An XML file containing font description will be created. Double-click it and choose your text editor to edit the file.
You can modified the fields to alter your font.
FontName
Size – float value, font size in points.
Spacing – float value, amount of spacing in between characters
Style – “Regular”, “Bold”, “Italic” or “Bold, Italic” (case sensitive)
CharacterRegion – specifies which characters in the font are rendered (numbers representing Unicode values)
41
Displaying Text Using SpriteFont
© VTC 2016




Kootenay
14
0
true






~




42
SpriteFont File (comments removed)
© VTC 2016

To actually draw the text on screen, we need to
Create a SpriteFont in additional to the default SpriteBatch object
SpriteFont Font1;
In your LoadContent() method, call Content.Load(), specifying the SpriteFont class and the asset name of the imported font.
Font1 = Content.Load(“MyFont”);
In your Draw() method, after calling Begin() of your SpriteBatch object, call DrawString() to draw your text
spriteBatch.DrawString( Font1, “output text”,
FontPos, Color.LightGreen);
Using the SpriteFont object, we can know the size of a string when it is output to the screen using such font.
Vector2 stringSize = font.MeasureString(“XNA Game Studio”);

© VTC 2016
43
Displaying Text Using SpriteFont

SpriteBatch.DrawString (
SpriteFont sf, String output,
Vector2 pos, Color color)
SpriteBatch.DrawString (
SpriteFont sf, String output,
Vector2 pos, Color color,
float rotate, Vector2 origin,
float/Vector2 scale,
SpriteEffects se, float depth)
© VTC 2016
44
SpriteBatch.DrawString()

Reference
Wikipedia topics
DirectX (http://en.wikipedia.org/wiki/DirectX)
OpenGL (http://en.wikipedia.org/wiki/OpenGL)
Comparison of OpenGL and Direct3D (http://en.wikipedia.org/wiki/Comparison_of_OpenGL_and_Direct3D)
Microsoft XNA (http://en.wikipedia.org/wiki/Microsoft_XNA)
MonoGame Documentation (http://www.monogame.net/documentation/)
Tom Miller and Dean Johnson,
XNA Game Studio 4.0 Programming –
Developing for Windows Phone 7 and Xbox 360,
Addison-Wesley, 2011.
Appendix G
45
© VTC 2016