4
........................................................................................................ 4
....................................................................................................................... 4
....................................................................................................................................... 5
............................................................... 5
........................................................................................................................ 5
......................................................................................................................................... 5
1. XNA Framework .......................................................................................................... 6
OpenGL .................................................................................................................................................... 6
DirectX .................................................................................................................................................. 7
Managed DirectX ....................................................................................................................................... 8
XNA Framework ........................................................................................................................................ 9
1.1. , XNA Framework. ...................................11
1.2. . ..................................................................................................18
1.2.1. DirectX . ........................................................20
1.2.2. Visual Studio 2005 ................................................................24
1.2.3. .....................................................................................................27
1.2.4. . ........................32
................................................................................................................................................33
2. . ........................................................................................................35
2.1. . ................................................................................................35
2.2. . .............................................................................................36
2.3. HLSL ..............................................................................................................................37
2.3.1. ............................................................................................................38
2.3.2. HLSL ..................................................................................................................................40
2.3.3. XNA Framework..........................................................................47
2.4. (PrimitiveType.PointList). ......................................................................................................52
2.4.1. . .................................................58
2.4.2. . .................................................................................................60
2.4.3. ....................................................................................................62
2.4.4. HLSL. ........................................................................66
2.5. ........................................................................................................................................71
2.5.1. (PrimitiveType.LineList). .....................................................................71
5. ...............................................................................................................197
5.1. HLSL ..........................................................................................197
5.1.1. .................................................................................................197
5.1.2. ........................................................................................197
5.1.3. ....................................................................................................198
5.1.4. - ...........................................................................................................199
5.2. NVIDIA FX Composer 2.0 ................................................................................................................202
5.2.1. COLLADA 1.4.1...........................................................................................................203
5.2.2. FX Composer 2.0 ......................................................................205
5.2.3. .....................................................................................................207
5.2.4. . ................................................................................211
5.3. Vertex Shader .................................................................................................214
5.3.1. .................................................................................................................................215
5.3.2. . ................................................................................................................................220
5.3.3. .......................................................................................225
5.4. ..................................................................................................227
5.4.1. XNA Framework ...........................................................230
5.5. ...............................................................................................................232
5.5.1. ........................................................................................233
5.5.2. if HLSL .........................................................................................................243
5.5.3. ......................................................................................................................................247
5.5.4. ..........................................................................263
..........................................................................................................................................264
..............................................................................................................................................265
.NET
. API OpenGL DirectX,
.NET ,
C++. .NET :
API OpenGL DirectX C++
, unsafe-
, , .NET API
.
, C++/CLI
API, : C++/CLI
, .
Microsoft XNA
.NET,
. XNA XNA Framework
.NET ,
. Windows XNA
Framework DirectX, .NET COM- DirectX.
, , ,
.NET, XNA Framework
. , XNA Framework
: ,
, , .. .. XNA Framework
Windows, ,
.NET Framework.
XNA ,
, :
, , CAD- .. ,
XNA:
XNA Framework. XNA Framework
Windows Forms ,
XNA Framework XNA
Framework.
,
. , C#
.NET.
Managed DirectX 2.0.
, Managed DirectX,
. ,
Managed DirectX. , ,
Managed DirectX, .
, , ,
: Managed DirectX 2.0 ,
Managed DirectX 2.0 XNA Framework. .
: XNA Framework. XNA Framework
, Managed DirectX,
, - Visual C++ .NET, .NET
.
, XNA Framework, , , -
5 ,
. , ,
, - ,
XNA Framework
.
, . XNA Framework.
XNA Framework Visual Studio,
.
XNA Framework. XNA
,
. :
, .
, XNA
Framework.
, .
,
; HLSL, - Vertex Shader 1.1
FX Composer 2.0,
.
Visual Studio 2005 Pro SP1,
Visual C# 2005 Express SP1. XNA Framework
,
1.1. ,
Intel GMA 9xx.
, , :
DOC , .
Examples , .
NVIDIA IDE NVIDIA FX Composer 2.0.
Tools
o Debug View .
o .NET Reflector .NET.
o RightMark 3D .
Visual C# 2005 Express XNA Game Studio 1.0 Express.
Visual C# 2005 Express SP1 Visual C# 2005 Express.
XNA Game Studio Express 1.0 XNA, .
XNA Game Studio 2.0 XNA Game Studio.
Visual C# 2005 Express, Visual C# 2005 Express
SP1 XNA Game Studio Express 1.0, Examples ,
read only.
,
. : (Codemasters Software),
(BHV), (NVIDIA), (Microsoft),
(Microsoft), , (NVIDIA), (NVIDIA),
(XNA Dev), , (Intel) (
Intel, ). (AMD),
(NVIDIA) (SolarWind), .
1. XNA Framework
Windows
GDI,
, . GDI
, GDI
. .
, ,
. ,
.
, GDI .
,
, , , , NVIDIA GeForce 5900 Ultra
Canon Laser Shot LBP-1120
. ,
. ,
. (,
,
3D
),
, GDI .
DOS Windows,
Windows.
OpenGL
,
Microsoft
Windows NT 3.5, Windows 95 OSR2
OpenGL
API
. OpenGL
.
, :
OpenGL ,
Windows.
MCI1.
: ,
.
OpenGL API,
. -
, ..,
API.
,
Windows.
OpenGL API, .
OpenGL
(ARB), , Intel,
Microsoft, AMD, NVIDIA, SGI, 3D Labs, Evans & Sutherland ..
,
.. , .
1
, API, ,
, ,
Microsoft.
, OpenGL
Windows, Microsoft API
.
DirectX
API, Microsoft, , WinG [.1].
API
Windows 3.1
Windows 95. 256 .
WinG ,
GDI. , DOS OpenGL 1.1 .
WinG , Microsoft
API
.
RenderMorfics Reality Lab
Windows. Game SDK, DirectX.
- Microsoft Reality Lab API
, DirectX,
DirectX
( 1.1). , DirectX,
,
. 2002- 9- DirectX.
DirectX ,
Microsoft DirectX, ,
.
, DirectX OpenGL 1.1
( DirectX) 7- . , 9- OpenGL
DirectX , OpenGL DirectX.
1.1. DirectX
DirectX
DirectX 1.0
1995
DirectX 2.0
1996
1996
1997-1998
1998-1999
1999
2000-2001
2002-2006
DirectX?
,
- . DirectX COM2-,
. Microsoft
, Intel, ATI, NVIDIA,
2
Creative .. DirectX
,
Win32, GDI MCI.
DirectX 9 3 ( 1.1):
DirectX Graphics, .
DirectInput, : , ,
..
DirectSound, : ,
, MIDI- ..
1.1. DirectX
Managed DirectX
.NET Framework
, C#. , COM-
DirectX C++,
C++, , . ,
C# COM-, DirectX C#
: C#
.NET, unsafe-,
. , COM-
.NET
.
.NET, Microsoft 9-
DirectX COM- DirectX: Managed DirectX. 2005
Managed DirectX,
.NET 2.0, , Managed DirectX
(Generic) .
Managed DirectX 2.0 DirectX, Microsoft.DirectX.dll.
Microsoft.DirectX.dll .NET 2.0
.
.NET- Microsoft Visual Basic, Microsoft Visual C#,
Microsoft Visual J#, Iron Python .. DirectX, Managed DirectX
: Direct3D Graphics, DirectInput DirectSound.
( 1.2), .
3
DirectX : DirectDraw (
), DirectMusic ( ), DirectPlay ( ) DirectShow
( ). ,
DirectX.
DirectX COM-
DirectX. , COM- IDirect3D9 -
Microsoft.DirectX.Direct3D.Device, IDirect3DTexture9 Microsoft.DirectX.Direct3D.Texture
. , Managed DirectX
C++ 4.
1.2. Managed DirectX 2.0
DirectX
Microsoft.DirectX
DirectX
,
:
, ,
..
Microsoft.DirectX.Generic
DirectX
Microsoft.DirectX.Direct3D
DirectX Graphics
3D
Microsoft.DirectX.Direct3D.CustomVertex
DirectX Graphics
Microsoft.DirectX.DirectInput
DirectInput
Microsoft.DirectX.XInput
DirectInput
XBOX
Microsoft.DirectX.DirectSound
DirectSound
,
.
XNA Framework
2005- Microsoft XBOX 360.
Microsoft x86
PowerPC, x86.
, Windows.
, Microsoft : Windows
XBOX 360. ,
, .
Microsoft,
, Windows, XBOX 360.
.NET: , .NET-
IL,
. , .NET-, -, ,
.
:
1. .NET Framework ,
, web-, web-. , ,
, . , .NET Framework
Windows ( System.Windows.Forms,
System.Drawings), Windows .
2. Managed DirectX, DirectX. DirectX
Windows, Managed DirectX API,
Windows. , Managed DirectX
System.Windows.Forms System.Drawing.
4
, DirectX
.
Games
Extended Framework
(Microsoft.Xna.Framework.Game.dll)
Core Framework
(Microsoft.Xna.Framework.dll)
Platform
: Direct3D, XACT, XINPUT, XContent ..
1.2. XNA Framework
1.3. Microsoft.Xna.Framework.dll
XNA
Microsoft.Xna.Framework
Math
: ,
.. Managed DirectX
( )
D3DX, DirectX. XNA
Framework
,
COM.
Microsoft.Xna.Framework.Graphics
Graphics
Microsoft.Xna.Framework.Graphics.PackedVector
Graphics
.
32 ,
Microsoft.Xna.Framework.Audio
Audio
Microsoft.Xna.Framework.Input
Input
(,
, ).
Microsoft.Xna.Framework.Storage
Storage
:
, (Save
Games) ..
, .
XNA Framework .
Microsoft.Xna.Framework.Graphics,
.
1.1. , XNA
Framework.
,
. . , XNA Framework,
( 1.3). GUI5-
Windows Forms, .NET.
6
7
.
MainForm.cs.
.
, View Code
( View Code Solution Explorer).
Microsoft.Xna.Framework.Graphics,
:
using Microsoft.Xna.Framework.Graphics;
XNA Framework
GraphicsDevice, ( ).
GraphicsDevice :
public
GraphicsDevice(GraphicsAdapter
adapter,
DeviceType
deviceType,
IntPtr
renderWindowHandle, CreateOptions creationOptions, params PresentationParameters[]
presentationParameters);
adapter GraphicsAdapter, (
).
GraphicsAdapter.DefaultAdapter.
deviceType , DeviceType (
1.4). DeviceType.Hardware.
renderWindowHandle ,
.
creationOptions CreateOptions,
( 1.5).
CreateOptions.SoftwareVertexProcessing CreateOptions.SingleThreaded.
PresentationParameters PresentationParameters,
PresentationParameters.
, PresentationParameters. 1.6
PresentationParameters.
, .
, ,
CreateOptions.HardwareVertexProcessing ,
. Intel GMA 900 Intel GMA950,
i915G i945G . HardwareVertexProcessing
,
,
.
SoftwareVertexProcessing.
1.4. DeviceType
Hardware
Reference
DirectX SDK.
,
(,
8 GeForce2). ,
,
.
NullReference
-,
( NUL MS-DOS
Windows).
1.5. CreateFlags
HardwareVertexProcessing
GPU9
SoftwareVertexProcessing
CPU.
MixedVertexProcessing
.
. , ,
2.0
GeForce3,
1.1.
1.1 ,
2.0 .
NoWindowChanges
..
.
.
SingleThreaded
.
.
SinglePrecision
.
, double,
7 .
8
9
2.3.
Graphic Processor Unit , .
1.6. PresentationParameters
bool IsFullScreen
false.
,
true.
int BackBufferCount
,
.
,
.
.
,
, .
.
,
BackBufferCount 1.
int BackBufferWidth
.
0, Device
,
10.
int BackBufferHeight
.
0, Device
,
.
Direct3D.SwapEffect SwapEffect
,
.
SwapEffect.Discard
,
.
x86
(FPU) x8611 80-
, . ,
80-
, extended double.
(, float), 80- ,
32- float.
,
(CW) (PC), .
, , 7-, 16- 19-
. . 80-
,
.
PC CW (thread) , ,
. , CreateOptions.SinglePrecision
GraphicsDevice CW ,
7 . ,
, double, 7- .
: , , PC CW ,
10
, .
, ..
11
i486DX ,
(8087, 80287, 80387).
, , ,
.
, , , -, .
, CreateOptions.SinglePrecision ,
.
. ,
- , ,
double. ,
.
,
GraphicsDevice:
GraphicsDevice device=null;
Load
12
GraphicsDevice c ( 1.1) .
1.1
private void MainForm_Load(object sender, EventArgs e)
{
// presentParams
PresentationParameters presentParams = new PresentationParameters();
// ,
presentParams.IsFullScreen = false;
//
presentParams.BackBufferCount = 1;
//
presentParams.SwapEffect = SwapEffect.Discard;
// . 0 (
// ), GraphivsDevice
// presentParams. ,
// , .
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
//
//
//
//
//
//
//
, :
-
-
-
GPU
- presentParams (. )
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle,
CreateOptions.SoftwareVertexProcessing | CreateOptions.SingleThreaded,
presentParams);
}
, .
Clear13 GraphicsDevice,
:
public void Clear(ClearOptions options, Color color, float depth, int stencil);
12
MainForm.
XNA Framework, GraphicsDevice,
(override) ( ) .
.
13
options , .
ClearOptions.Target.
ClearOptions.DepthBuffer ClearOptions.Stencil,
, .
color , .
Microsoft.Xna.Framework.Graphics.Color,
System.Drawing.Color. - XNA
Framework Windows.
depth , .
stencil , .
Clear Paint,
:
private void MainForm _Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearOptions.Target, Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue,
0.0f, 0);
}
Microsoft.Xna.Framework.Graphics.Color . ,
System.Drawing.
GraphicsDevice (override) ,
:
public void Clear(Color color);
color , .
:
private void MainForm_Paint(object sender, PaintEventArgs e)
{
device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
}
Dispose.
FormClosed ( 1.2).
1.2.
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
//
if (device != null)
{
// ()
device.Dispose();
// null
device = null;
}
}
, .NET Dispose
GraphicsDevice ( ,
Finalize, Dispose).
. , Finalize
, Windows Direct3D
, . , GraphicsDevice,
, Direct3D.
.
CreateOptions.SingleThreaded,
.
. ( F5).
, Clear ( ,
F9) ,
. , ?
, ,
.
.
Present GraphicsDevice:
void Present()
Paint
, , .
CD Ch01\Ex01.
1.2. .
GraphicsDevice.Clear ,
:
public void Clear(ClearOptions
Rectangle[] regions);
options,
Color
color,
float
depth,
int
stencil,
rect Microsoft.Xna.Framework.Rectangle,
, .
. Microsoft.Xna.Framework.Rectangle
System.Drawing,
XNA Framework Windows.
Rectangle Microsoft.Xna.Framework,
XNA Framework,
Microsoft.Xna.Framework.Graphics.
,
( 1.6):
1.3.
//
device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
// , .
//
Microsoft.Xna.Framework.Rectangle[] rect = new Microsoft.Xna.Framework.Rectangle[1];
// , 25%
//
rect[0] = new Microsoft.Xna.Framework.Rectangle(ClientSize.Width/4,
ClientSize.Height/4, ClientSize.Width/2, ClientSize.Height/2);
//
device.Clear(ClearOptions.Target, Microsoft.Xna.Framework.Graphics.Color.Green, 0.0f,
0, rect);
1.6. , Clear.
Clear
. , ( 1.7).
, ,
, ( 1.4).
1.7. , Clear
1.4.
// Examples\Ch01\Ex02
private void MainForm_Paint(object sender, PaintEventArgs e)
{
//
device.Clear(Microsoft.Xna.Framework.Graphics.Color.WhiteSmoke);
// ,
Microsoft.Xna.Framework.Rectangle[] rects = new Microsoft.Xna.Framework.Rectangle[32];
int k = 0;
//
for (int j = 0; j < 8; j++)
for (int i = j % 2; i < 8; i += 2)
{
//
rects[k] = new Microsoft.Xna.Framework.Rectangle(i * ClientSize.Width / 8,
j * ClientSize.Height / 8, ClientSize.Width / 8, ClientSize.Height / 8);
k++;
}
// rects
device.Clear(ClearOptions.Target, Microsoft.Xna.Framework.Graphics.Color.Brown, 0.0f, 0,
rects);
device.Present();
}
1.2.1. DirectX .
, Windows XNA Framework
DirectX. , Windows
XNA Framework DirectX.
. ,
.
DirectX DirectX, Start |
All Programs | Microsoft DirectX SDK | DirectX Utilities | DirectX Control Panel.
1.8. ,
, DirectX.
.
Direct3D
Graphics
Direct3D Graphics
.
(, Visual Studio 2005).
Direct3D
Graphics. Debug Output Level,
,
. ,
.
Debugging : Maximum Validation (
, Direct3D Graphics), Enable Shader Debugging
( ) Break on Memory Leaks ( ).
.
(Debug) DirectX Graphics (Retail) .
DirectX .
.
, Use Retail Version of
DirectX Debug Output Level
Direct3D Graphics.
Debug View
Visual Studio 2005 Pro DirectX,
Visual C# 2005 Express .
CD Debug View,
\Tools\DebugView.
DebugView.exe. ( 1.9).
,
, .
Debug View,
.
DirectX, DirectX.
, ( Ch01\Ex02), ,
. Debug Info :
// Direct3D
Direct3D9: :====> ENTER: DLLMAIN(041dd6e0): Process Attach: 0000041c, tid=000016a8
Direct3D9: :====> EXIT: DLLMAIN(041dd6e0): Process Attach: 0000041c
// Direct3D
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
// Direct3D (
// DirectX-, C++)
D3D9 Helper: Enhanced
D3D_DEBUG_INFO
D3DDebugging
disabled;
Application
was
not
compiled
with
// INFO
// . ,
// Software Vertex Processing ( ).
// ,
// CreateOptions.SoftwareVertexProcessing.
Direct3D9: (INFO) :======================= Hal SWVP device selected
Direct3D9: (INFO) :HalDevice Driver Style 9
Direct3D9: :DoneExclusiveMode
Direct3D9: :====> ENTER: DLLMAIN(041dd6e0): Process Detach 0000041c, tid=0000022c
// Direct3D
Direct3D9: (INFO) :MemFini!
// Direct3D
Direct3D9: :====> EXIT: DLLMAIN(041dd6e0): Process Detach 0000041c
Time , .
, .. 0.0 .
, - .
device.Dispose() Close() .
:
Direct3D9: :====> ENTER: DLLMAIN(042dd6e0): Process Attach: 00000298, tid=00000910
Direct3D9: :====> EXIT: DLLMAIN(042dd6e0): Process Attach: 00000298
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
D3D9 Helper: Enhanced
D3D_DEBUG_INFO
D3DDebugging
disabled;
Application
was
not
compiled
with
, ,
,
Finalize ,
Direct3D , . , DirectX
.
Direct3D XNA Framework. ,
Direct3D ,
D3DCREATE_MULTITHREADED. GraphicsDevice,
, ,
CreateOptions.SingleThreaded.
, Direct3D .NET Framework ,
- GraphicsDevice
. ,
Direct3D, .
XNA Framework c DirectX.
, XNA Framework .NET DirectX.
?
XNA Framework
Direct3D.Device.Present, .NET Reflector,
CD Tools\NET Reflector14:
public unsafe void Present()
{
// , Dispose
// GraphicsDevice. Dispose ,
// ObjectDisposedException
InternalHelper.CheckDisposed(this, (void*) this.pComPtr);
// COM IDirect3DDevice9,
// GraphicsDevice.
IDirect3DDevice9* devicePtr1 = this.pComPtr;
// COM- IDirect3DDevice9::Present,
// . , .NET Reflector ,
// , .
int num1 = **(((int*) devicePtr1))[0x44](devicePtr1, 0, 0, 0, 0);
// IDirect3DDevice9::Present ,
// ( COM
// ).
if (num1 < 0)
{
// -2005530520 ( )
if (num1 == -2005530520)
{
// DeviceLost ( )
// . 1.2.4.
EventArgs args1 = EventArgs.Empty;
14
, GraphicsDevice.Present COM-
IDirect3DDevice9::Present COM.
, Windows GraphicsDevice.Present
. ,
.
,
. Visual Studio 2005 :
Debug Release.
Debug .
, .exe
.
,
, .. , ,
,
.
Release .
: ,
, ..
( ), ,
.
Visual Studio ( 1.10). , Debug Release
. ,
Debug, Release
. ,
Release Shareware Version, Release Full Version ..
1.10.
Debug Release ,
, Debug Release-.
.
Release C#
. , Debug.
. Debug .
Properties Solution, 15. ( 1.11).
1.11.
15
16
, , (*.cjproj ..)
, Windows.
Ch01\Ex02 ( )
Output DirectX ( 1.12).
.
1.12. Output.
, Check for arithmetic overflow/underflow,
Advanced Build Setting, Advanced Build Setting Build
( 1.13). :
,
System.OverflowException.
, :
// 16- 32767
short a = 32767;
// 5. a -32764, 32752 !!!
a = (short) (a + 5);
// WriteLine -32764
Console.WriteLine(a);
,
Release. ,
, checked. :
checked
{
a = (short) (a + 5);
}
C#
. [.7], [.8] [.9].
1.2.3.
, (Ex02)
. , , - .
, -
( 1.13).
( 1.14).
, .
.
, Windows Forms Paint
. ,
Resize17 Invalidate, Paint.
1.13. .
1.14.
: ResizeRedraw,
Paint.
Load :
SetStyle(ControlStyles.ResizeRedraw, true);
. ?
, ,
.
( BackColor) .
.
17
Resize
, Paint Form
OnPaintBackground, BackColor.
, GDI+, ,
. ,
-
Paint. , OnPaintBackground
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//
}
, , .
ControlStyles.Opaque, ,
:
SetStyle(ControlStyles.Opaque, true);
Load - .
, , ,
.
,
, Paint.
!
, ,
, . , .
Load. ,
,
, .
,
. XNA Framework Reset
GraphicsDevice:
public void Reset(params PresentationParameters[] presentationParameters);
presentationParameters
PresentationParameters,
.
PresentationParameters.
, PresentationParameters presentParams
Load ( MainForm) Resize
presentParams
Device.Reset ( 1.5).
1.5.
private void MainForm_Resize(object sender, EventArgs e)
{
//
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
//
device.Reset(presentParams);
}
.
Paint, .
- . ?
, . .
.
, Output DirectX,
:
Direct3D ,
, , .
, ,
.
MinimumSize, .
Properties , ,
: , ..
Load
SizeFromClientSize, :
// 1x1 .
// MinimumSize
MinimumSize = SizeFromClientSize(new Size(1, 1));
. , ,
, Windows, .
- . ,
. ,
Resize
0 0 . ,
Windows . ,
Resize ,
:
1.6.
private void MainForm_Resize(object sender, EventArgs e)
{
// ,
if (WindowState != FormWindowState.Minimized)
{
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device.Reset(presentParams);
}
}
18.
1.7 (Ex03).
1.7.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Xna = Microsoft.Xna.Framework;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
18
, (1.2.4).
namespace GSP.XNA.Book.Ch01.Ex03
{
public partial class MainForm : Form
{
GraphicsDevice device=null;
PresentationParameters presentParams;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
SetStyle(ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
MinimumSize = SizeFromClientSize(new Size(1, 1));
presentParams = new PresentationParameters();
presentParams.IsFullScreen = false;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle, CreateOptions.SoftwareVertexProcessing | CreateOptions.SingleThreaded,
presentParams);
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
device.Clear(ClearOptions.Target, XnaGraphics.Color.WhiteSmoke, 0.0f, 0);
Xna.Rectangle[] rects = new Xna.Rectangle[32];
int k = 0;
for (int j = 0; j < 8; j++)
for (int i = j % 2; i < 8; i += 2)
{
rects[k] = new Xna.Rectangle(i * ClientSize.Width / 8,
j * ClientSize.Height / 8, ClientSize.Width / 8, ClientSize.Height / 8);
k++;
}
device.Clear(ClearOptions.Target, XnaGraphics.Color.Brown, 0.0f, 0, rects);
device.Present();
}
private void MainForm_Resize(object sender, EventArgs e)
{
if (WindowState != FormWindowState.Minimized)
{
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device.Reset(presentParams);
}
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (device != null)
{
device.Dispose();
device = null;
}
}
}
}
Microsoft.Xna.Framework
Microsoft.Xna.Framework.Graphics,
Microsoft.Xna.Framework.Color
Microsoft.Xna.Framework.Graphics.Rectangle.
using C# -
System.Drawing.
1.1.
, 10 ( 1.15).
, .
, .
.
public Color(byte r, byte g, byte
b), Color , .
0255 (0 , 255 ).
1.14. 1.1.
,
, CD Ch01\Ex04.
1.2.4.
.
Windows ,
XNA
. . , -
, ,
, .
GraphicsDevice
. XNA Framework DirectX
(Device Lost).
, ,
. , 19
ALT
+ Enter. , :
1. , DirectX.
2. . FAR, ,
(Start | All Programs | Accessories | Command
Prompt)
3. ( Alt + Enter).
Ex03 ,
- Microsoft.Xna.Framework.Graphics.DeviceLostException,
.
GraphicsDevice
GraphicsDeviceStatus:
public GraphicsDeviceStatus GraphicsDeviceStatus { get; }
GraphicsDeviceStatus,
:
Normal
NotReset , Reset
GraphicsDevice.
Lost .
NotReset, ,
GraphicsDevice.Reset, , .
Lost,
Paint .
,
Paint, . XNA Framework
Direct3D.DeviceNotResetException Direct3D.DeviceLostException.
Direct3D.DeviceNotResetException,
GraphicsDevice.Reset()
Form.Invalidate(), Paint.
. Paint 1.8.
1.8.
// Examples\Ch01\Ex05
private void MainForm_Paint(object sender, PaintEventArgs e)
{
try
{
// , DeviceLostException (
// catch)
19
, .
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
// ,
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset();
//
device.Clear(XnaGraphics.Color.WhiteSmoke);
Xna.Rectangle[] rects = new Xna.Rectangle[32];
int k = 0;
for (int j = 0; j < 8; j++)
for (int i = j % 2; i < 8; i += 2)
{
rects[k] = new Xna.Rectangle(i * ClientSize.Width / 8,
j * ClientSize.Height / 8, ClientSize.Width / 8, ClientSize.Height / 8);
k++;
}
device.Clear(ClearOptions.Target, XnaGraphics.Color.Brown, 0.0f, 0, rects);
//
//
//
//
device.Present();
}
DeviceNotResetException, .
Paint
catch (DeviceNotResetException)
{
Invalidate();
}
DeviceLostException,
catch (DeviceLostException)
{
}
1.2
, 1.1,
.
XNA Framework ,
,
-. XNA Framework
Microsoft DirectX .NET. DirectX,
Microsoft.Xna.Framework.dll
Microsoft.Xna.Framework.Game.dll
.NET 2.0 .
.NET-
Microsoft Visual Basic, Microsoft Visual C# , Microsoft Visual J# Iron Python. , XNA
Framework - ,
, , XBOX 360.
XNA Framework : Platform, Core
Framework, Extended Framework Game. Graphics (
Core Framework),
.
,
. , ,
2. .
XNA Framework ,
GDI/GDI+. XNA Framework
, . XNA
Framework : , .
,
. , NVIDIA GeForce 8800 GTX
400 20 [.7].
: ,
, . XNA Framework
x, y z.
, X , Y
, Z ( 2.1).
(-1, -1, 0), (+1, +1, 0).
(-1, 1, 0)
(1, 1, 0)
+Y
(0, 0, 0)
(-1, -1, 0)
+X
(1, -1, 0)
2.1. .
Microsoft.Xna.Framework.Graphics
. VertexPositionColor,
.
:
public VertexPositionColor(Vector3 position, Color color);
position ;
color .
Position Color VertexPositionColor:
public Color Color;
public Vector3 Position;
Microsoft.XNA.Framework.Vector3,
. Vector3 XNA Framework
Vector2 Vector4, , ,
20
.
,
. ,
. , TGV-A
513 / [15], 350 /.
, , . ,
(GPU
Graphics Processor Unit), , ,
.
. XNA Framework
VertexDeclaration, :
public VertexDeclaration(GraphicsDevice graphicsDevice, VertexElement[] elements);
graphicsDevice ,
elements ( VertexElement) c .
elements,
. , elements
. elements? :
4. ( ).
5. (, , 21).
6. , ( , ,
22 ..).
7. .
, , .
, XNA Framework VertexPositionColor (
) ,
:
public static readonly VertexElement[] VertexElements;
,
VertexDeclaration.
2.2. .
,
VertexPositionColor.
, VertexTransformedPositionColor:
VertexDeclaration decl;
, , -
Load .
Paint. ,
, ,
VertexDeclaration Device ,
Load.
DrawUserPrimitives:
DrawUserPrimitives<T>(PrimitiveType
primitiveCount);
21
primitiveType,
T[]
vertexData,
int
vertexOffset,
32- ,
, .
22
5.X.
int
primitiveType , PrimitiveType.
(PrimitiveType.LineList),
(PrimitiveType.LineStrip), (PrimitiveType.TriangleList),
(PrimitiveType.TriangleStrip)
(PrimitiveType.TriangleFan).
vertexData .
vertexOffset . .
,
(, ).
primitiveCount , .
.
:
1.
2.
.
, , Load.
3.
Paint
GraphicsDevice.Clear.
4.
(
, Load).
5.
, GraphicsDevice. VertexDeclaration
, .
6.
GraphicsDevice.DrawUserPrimitives.
7.
, Device.Present.
, . , GPU
, .
,
. ,
DrawUserPrimitives 23.
.
2.3. HLSL
High Level Shader Language (
), HLSL. HLSL
.
, .
8- DirectX. DirectX 8
- , 9-
DirectX ,
. DirectX24,
- HLSL, DirectX 9. XNA Framework
HLSL, XNA Framework Windows
DirectX.
HLSL ,
.
23
DrawUserPrimitives
System.InvalidOperationException Both a valid vertex
shader and pixel shader (or valid effect) must be set on the device before draw
operations may be performed.
24
2.3.1.
2.2 XNA Framework.
( GraphicsDevice.DrawUserPrimitives)
. . ,
GraphicsDevice.DrawUserPrimitives
XNA Framework, (
), ( 2.2).
:
,
,
( )
( )
2.2.
8. ,
.
() . : ,
25 .
, clip space.
: (x, y, z, w).
w:
x y z
( , , ).
w w w
, (1, 2, 3, 4)
1 2 3
( , , ) (0.25,0.5,0.75)
4 4 4
, 3D .
w 1.
(-1, -1, 0, 1),
(1, 1, 0, 1),
(0, 0, 0, 1).
25
5.x.
9.
. -
, .
.
DirectX . ,
Device.DrawUserPrimitives ,
. Managed DirectX XNA Framework Beta 1
, XNA Framework Beta 2 - .
, XNA Framework -.
10. . .
GraphicsDevice.DrawUserPrimitives.
PrimitiveType.TriangleStrip ,
() .
.
2.6.3.
11.
. (, )
.
,
.
12. ,
.
(, ..),
. ,
.
,
. NV40
NVIDIA, GeForce 6800, 6 16
, , 6- 16- . [.8]
13. .
.
, DirectX
. , NVIDIA GeForce 8800 GTX,
GPU G80, 8 , ,
[.7].
, ,
. HLSL
, .
. ,
, :
(),
.
AMD Athlon .
. ,
.
AMD 400 .
400 .
, . ,
400 . ,
400 2400 .
400 .
, 7-
(400/60). , . .
;
. ,
,
. , ,
.
. , 0.017
( 60 ), 28 0.44 ,
100 - 1.33 .. -,
( 2.3).
, .
.
GraphicsDevice.DrawUserPrimitives, .
2.3. .
, .
2.3.2. HLSL
XXI 3dfx GPU Rampage,
. Microsoft
3dfx - ,
DirectX 8. Vertex Shader 1.0 (VS
1.0), Pixel Shader 1.0 (PS 1.0) [.4].
, , ,
26. , Rampage
: 3dfx NVIDIA,
Rampage .
, 27 GPU NV10 (1999 ).
Microsoft DirectX. ,
DirectX-, NV10 - .
NV10 API OpenGL [.17], [.18].
26
(shader)
(shade) .
27
Pixel Shader 0.5
HLSL
(Vertex/Pixel
Shader)
2.4. HLSL-.
HLSL (Effect),
.fx. , 3DS MAX.
(technique). .
,
: High High End, Medium
, Low 29.
,
.
28
,
. . ,
(aqua). , Fill.
, . : .
, .
(w), 1 ( 2.1).
2.1.
float4 MainVS(float3 pos)
{
return float4(pos, 1.0);
}
, , HLSL, C-:
MainVS, float3,
float4. float3 float4, C, C++,
C#? HLSL.
.
HLSL : .
C ( 1.1).
1.1.
bool
, true
false
int
32-
half
16-
float
32-
double
64-
, ,
. , ,
30. ,
31
double float, half - .
. int,
int,
. , :
// a 5
int a = 5;
// b 1
int b = a / 3;
// c 2
int c = b * 2;
? .
int, , float:
// a 5.0
float a = 5.0;
30
, .
, GPU NV3x (GeForce FX) half float 12-
-2 2. GPU ATI R3xx/R4xx 24-
. , GPU
ATI, NVIDIA Intel, 5.
31
// b 1.66667
float b = a / 3.0;
// c 3.33334
float c = b * 2.0;
, , . HLSL
int float:
// a 5.0
float a = 5.0;
// b
float b;
//
float fd = a / 3.0;
//
float ff = frac(fd);
//
b = fd - ff;
// , 0, .
// , frac(2.3) = 0.3, frac(-2.3) = 0.7
if ((fd < 0) && (ff > 0))
b = b + 1;
// c 2.0
float c = b * 2.0;
,
.
- , ,
HLSL.
32. , , int
.
.
, , ,
4. ,
, ( -) .
, GPU ,
( ).
HLSL 2- 4-. N
type ,
(Generic) C#:
vector<type, size>
size , 1, 2, 3 4.
v, float.
vector<float, 4> v;
:
{type}{N}
type
N .
, v :
float4 v;
32
HLSL .
C. ,
v
v:
float4 v=float4(0.2, 0.4, 0.6, 0.8);
N ,
, .. :
N.
:
// (0.1, 0.2)
float2 a={0.1, 0.2};
// (0.3, 0.4)
float2 b=float2(0.3, 0.4);
// . b
// 1.0. c (0.3, 0.4, 1.0)
float3 c=float3(b, 1.0);
// .
// d (0.7, 0.3. 0.4, 1.0)
float4 d=float4(0.7, c);
// . d
// (0.1, 0.2. 0.3, 0.4)
float4 e=float4(a, b);
, HLSL
2.1. , , ,
. DirectX ,
.
, Pos ,
. HLSL
(semantics), ,
. 2.2
. HLSL 3.
, ..
.
0. .
2.2.
POSITION[n]
COLOR[n]
PSIZE[n]
( )
,
. , pos
MainVS POSITION ( 2.2).
2.2.
float4 MainVS(float3 pos:POSITION)
{
return float4(pos, 1.0);
}
, MainVS .
HLSL . ,
,
POSITION ( 2.3).
2.3.
float4 MainVS(float3 pos:POSITION):POSITION
{
return float4(pos, 1.0);
}
- .
.
(aqua) ( 2.4).
2.4.
float4 MainPS() : COLOR
{
return float4(0.0, 1.0, 1.0, 1.0);
}
HLSL 0.0, 1.0.
,
. COLOR DirectX,
MainPS .
,
,
. (technique),
. Fill,
MainVS MainPS ( 2.5).
2.5.
technique Fill
{
pass p0
{
VertexShader = compile vs_1_1 MainVS();
PixelShader = compile ps_1_1 MainPS();
}
}
, technique.
, pass.
. Fill
p0.
,
.
(pass) :
VertexShader = compile { } { };
:
PixelShader = compile { } { };
(shader profile) - ,
. ,
,
. .
, Vertex Shader 1.1 vs_1_1; Pixel Shader 1.4 ps_1_4, Pixel
Shader 2.0 ps_2_0 . Pixel Shader 2.x
: ps_2_a ps_2_b, Pixel Shader 2.x,
NV3x, R4xx. 2.3 2.4
.
2.3.
vs_1_0
1.0
vs_1_1
1.1
vs_2_0
2.0
vs_2_a
2.x
vs_3_0
3.0
2.4.
ps_1_0
1.0
ps_1_1
1.1
ps_1_2
1.2
ps_1_3
1.3
ps_1_4
1.4
ps_2_0
2.0
ps_2_a
2.x ( NV3x)
ps_2_b
2.x ( R4xx)
ps_3_0
3.0
(.
2).
.
.
, , ATI Radeon 9500
(R3xx) , NVIDIA GeForce FX 5200 (NV3x) , Intel GMA 900 .
2, , , ,
vs_1_0, vs_1_1, vs_2_0 ps_1_0, ps_1_1, ps_1_2,
ps_1_3, ps_1_4 ps_2_0. , vs_2_0 ps_2_0
. (technique)
High End, vs_3_0 ps_3_0.
GPU NV3x
ps_2_0 ps_2_a ([.5], [.6]).
GPU, ps_1_4
ps_2_0. NV3x,
ps_1_4.
,
. , , Fill
vs_1_1 ps_1_1:
GeForce3 (NV20).
, , Fill, .
*.fx, ,
SimpleEffect.fx ( 2.6).
2.6.
// . (x, y, z).
// (x, y, z, 1.0)
float4 MainVS(float3 pos:POSITION):POSITION
{
return float4(pos, 1.0);
}
// . .
float4 MainPS():COLOR
{
return float4(0.0, 1.0, 1.0, 1.0);
}
// Fill
technique Fill
{
//
pass p0
{
// . vs_1_1
VertexShader = compile vs_1_1 MainVS();
// . ps_1_1
PixelShader = compile ps_1_1 MainPS();
}
}
C#-.
Techniques
(EffectTechnique)
Passes
(EffectPass)
2.5. Effect.
.
*.fx
Effect.CompiledEffect:
public static CompiledEffect CompileEffectFromFile(string effectFile, CompilerMacro[]
preprocessorDefines, CompilerIncludeHandler includeHandler, CompilerOptions options,
TargetPlatform platform);
effectFile .
options HLSL,
CompilerOptions ( 2.5.). CompilerOptions ,
|. , ,
CompilerOptions.None.
platform TargetPlatform, ,
XNA
Framework
1.0
TargetPlatform.Windows TargetPlatform.Xbox360, .
TargetPlatform.Windows.
2.5. CompilerOptions.
None
Debug
NotCloneable(*)
( )
Clone.
,
,
.
50%.
ForceVertexShaderSoftwareNoOptimizations
Pixel
Shader ( 3.0),
.
ForcePixelShaderSoftwareNoOptimizations
Pixel
Shader ( 3.0),
.
PartialPrecision
,
.
, double
float half.
SkipOptimization
SkipValidation
(
..)
. ,
- ,
.
(*) CompileEffectFromFile.
Effect.CompileEffectFromFile fx- (, - ),
System.IO.IOException
System.IO.FileNotFoundException System.IO.DirectoryNotFoundException.
CompileEffectFromFile
CompiledEffect,
, ( -
..).
public struct CompiledEffect
{
// ,
public string ErrorsAndWarnings { get; }
//
public bool Success { get; }
// Success true,
public byte[] GetEffectCode();
...
}
, GetEffectCode - ,
exe- .NET. ,
. , , -
.
- - ,
-. , Visual C# 2005
Express33 , Content Pipeline, fx nvb. ,
, Content Pipeline, fx-.
-
.
Effect:
public Effect(GraphicsDevice graphicsDevice, byte[] effectCode, CompilerOptions options,
EffectPool pool);
graphicsDevice Direct3D,
byte[] effectCode
CompileEffectFromFile.
options , CompilerOptions
2.5.).
CompilerOptions.NotCloneable,
pool EffectPool,
. fx-,
null.
Effect - .
.
Techniques :
public EffectTechniqueCollection Techniques { get; }
XNA- . ,
Effect
CurrentTechnique.
public EffectTechnique CurrentTechnique { get; set; }
, ,
CurrentTechnique,
EffectTechnique, .
EffectTechnique:
public sealed class EffectTechnique
{
//
public string Name { get; }
//
public EffectPassCollection Passes { get; }
//
public bool Validate();
33
...
}
.
GPU, ( ) .
(technique) GPU (,
ps_1_4 NV2x), XNA Framework .
, , 34.
. EffectTechnique
Validate. , Validate
true, false. ,
.
, ,
, :
GraphicsDevice device;
// , true -
// Load
closing = false;
...
// Load.
CompiledEffect compiledEffect;
try
{
//
compiledEffect = Effect.CompileEffectFromFile(effectFileName, null, null,
CompilerOptions.None, TargetPlatform.Windows);
}
//
catch (IOException ex)
{
//
MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK,
MessageBoxIcon.Error);
// . Close()
// Load, (
// Application.Idle, Close ,
// closing true).
closing = true;
Application.Idle += new EventHandler(Application_Idle);
return;
}
//
if (!compiledEffect.Success)
{
//
MessageBox.Show(String.Format(" : \r\n{0}",
compiledEffect.ErrorsAndWarnings), " ", MessageBoxButtons.OK,
34
, .
MessageBoxIcon.Error);
closing = true;
Application.Idle += new EventHandler(Application_Idle);
return;
}
// - .
effect = new Effect(device, compiledEffect.GetEffectCode(),
CompilerOptions.NotCloneable, null);
// .
if (!effect.CurrentTechnique.Validate())
{
//
MessageBox.Show(String.Format("
\"{1}\"\n\r" +
\"{0}\"
" , GPU",
effect.CurrentTechnique.Name,
MessageBoxButtons.OK,
effectFileName),
"
",
MessageBoxIcon.Error);
closing = true;
Application.Idle += new EventHandler(Application_Idle);
return;
}
, .
, , Effect.Begin:
public void Begin();
(CurrentTechnique) :
passes)
14. Pass .
15. GraphicsDevice.DrawUserPrimitives.
16. End .
Effect.End.
:
Effect effect;
...
// Paint
...
// effect.
effect.Begin();
//
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
//
effect.Begin();
//
device.DrawUserPrimitives(...);
...
device.DrawUserPrimitives(...);
//
effect.End();
}
//
effect.End();
, , ,
.
, foreach,
(effect.CurrentTechnique.Passes),
for.
. 3.3.4.
2.4. (PrimitiveType.PointList).
, , .
XNA Framework .
,
( 2.7).
2.7.
// Examples\Ch02\Ex01
// C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
// , ,
// System.IO
using System.IO;
// XNA Framework
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XnaGraphics = Microsoft.Xna.Framework.Graphics;
namespace GSP.XNA.Book.Ch02.Ex01
{
public partial class MainForm : Form
{
// XNA Framework
GraphicsDevice device = null;
//
PresentationParameters presentParams;
// ( )
VertexPositionColor[] vertices = null;
//
VertexDeclaration decl = null;
// ,
Effect effect = null;
// , true
bool closing = false;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
//
SetStyle(ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
MinimumSize = SizeFromClientSize(new Size(1, 1));
presentParams = new PresentationParameters();
presentParams.IsFullScreen = false;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle, CreateOptions.SoftwareVertexProcessing | CreateOptions.SingleThreaded,
presentParams);
// ,
vertices = new VertexPositionColor[1];
//
decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);
// () , .
// ,
// ,
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f),
XnaGraphics.Color.Aqua);
//
CompiledEffect compiledEffect;
try
{
// -
compiledEffect = Effect.CompileEffectFromFile(effectFileName, null, null,
CompilerOptions.None, TargetPlatform.Windows);
}
//
catch (IOException ex)
{
//
MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK,
MessageBoxIcon.Error);
closing = true;
Application.Idle += new EventHandler(Application_Idle);
return;
}
//
if (!compiledEffect.Success)
{
// ErrorsAndWarnings
//
MessageBox.Show(String.Format(" : \r\n{0}",
compiledEffect.ErrorsAndWarnings), " ", MessageBoxButtons.OK,
MessageBoxIcon.Error);
closing = true;
pass.End();
}
//
effect.End();
//
//
device.Present();
}
//
catch (DeviceNotResetException)
{
Invalidate();
}
catch (DeviceLostException)
{
}
}
// Idle. .
void Application_Idle(object sender, EventArgs e)
{
Close();
}
//
private void MainForm_Resize(object sender, EventArgs e)
{
if (WindowState != FormWindowState.Minimized)
{
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device.Reset(presentParams);
}
}
//
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (device != null)
{
device.Dispose();
device = null;
}
}
}
}
.
( ) ,
:
VertexPositionColor[] vertices = null;
VertexDeclaration decl = null;
, :
Effect effect = null;
Load .
, Load
:
vertices = new VertexPositionColor[1];
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), XnaGraphics.Color.Aqua);
// VertexPositionColor
decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);
Load fx-, -
:
// .
// ,
// .
// 2.7.
CompiledEffect compiledEffect;
// fx-
compiledEffect = Effect.CompileEffectFromFile(effectFileName, null, null,
CompilerOptions.None, TargetPlatform.Windows);
// - .
effect = new Effect(device, compiledEffect.GetEffectCode(), CompilerOptions.NotCloneable,
null);
Close , , MSDN,
. Idle,
Close. : Idle
, Paint. , ,
Idle ,
. Paint
, : ,
Paint .
Paint, .
, .
VertexDeclaration ,
Load:
device.VertexDeclaration = decl;
Load.
,
Reset. ,
.
, , : :
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.PointList, vertices, 0, vertices.Length);
pass.End();
}
effect.End();
, , . ,
.
Visual Studio 2005. Visual Studio
2005,
Windows
Forms
( 2.6). Data
SimpleEffect.fx ( 2.7), , Add | New
Item... . SimpleEffect.fx 2.6.
2.6. .
2.7. SimpleEffect.fx.
Data,
SimpleEffect.fx. , Debug Visual Studio exe- bin\Debug,
Release bin\Release. , ,
,
. , :
Solution Explorer SimpleEffect.fx Properties
Copy to Output Directory Copy if newer ( 2.8).
Visual Studio bin\Debug bin\Release
bin\Debug\Data bin\Release\Data SimpleEffect.fx.
2.7.
CD Ch02\Ex01.
2.8. SimpleEffect.fx.
2.4.1. .
, ,
CreateOptions.SoftwareVertexProcessing,
(CPU). ,
,
GPU.
CreateOptions.HardwareVertexProcessing ,
(, Intel
GMA 900 Intel GMA 950).
? GPU.
GPU ,
CreateOptions.HardwareVertexProcessing,
CreateOptions.SoftwareVertexProcessing.
, GPU. XNA Framework
GraphicsDeviceCapabilities,
. ,
(),
GraphicsDeviceCapabilities :
// GraphicsDeviceCapabilities
public sealed class GraphicsDeviceCapabilities : IDisposable
{
// ,
public GraphicsDeviceCapabilities.PrimitiveCaps PrimitiveCapabilities { get; }
//
public GraphicsDeviceCapabilities.DeclarationTypeCaps DeclarationTypeCapabilities {
get; }
//
public GraphicsDeviceCapabilities.VertexShaderCaps VertexShaderCapabilities { get; }
//
public GraphicsDeviceCapabilities.PixelShaderCaps PixelShaderCapabilities { get; }
//
public GraphicsDeviceCapabilities.DriverCaps DriverCapabilities { get; }
// ,
//
, ,
GraphicsDeviceCapabilities.DeviceCaps DeviceCapabilities:
// DeviceCaps
public struct DeviceCaps
{
// DrawUserPrimitives
public bool SupportsDrawPrimitives2Ex { get; }
// (
//
// )
public bool SupportsHardwareRasterization { get; }
//
public bool SupportsHardwareTransformAndLight { get; }
...
}
,
SupportsHardwareTransformAndLight. ,
GraphicsDeviceCapabilities.DeviceCapabilities.SupportsHardwareTransformAndLight.
true,
CreateOptions.HardwareVertexProcessing,
CreateOptions.SoftwareVertexProcessing.
XNA Framework
GraphicsDeviceCapabilities.
GraphicsDeviceCapabilities :
public GraphicsDeviceCapabilities GraphicsDeviceCapabilities { get; }
:
GraphicsDeviceCapabilities .
: , ,
. , - :
// .
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle,
CreateOptions.SoftwareVertexProcessing | CreateOptions.SingleThreaded, presentParams);
// GPU
if (device.GraphicsDeviceCapabilities.DeviceCapabilities.SupportsHardwareTransformAndLight)
{
//
device.Dispose();
// ,
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle,
CreateOptions.HardwareVertexProcessing | CreateOptions.SingleThreaded,
presentParams);
}
, .
XNA Framework
GraphicsDeviceCapabilities . ,
GraphicsDevice GraphicsAdapter,
. , XNA Framework
GetCapabilities, GraphicsDeviceCapabilities,
:
public GraphicsDeviceCapabilities GetCapabilities(DeviceType deviceType);
deviceType , DeviceType (
1.4).
deviceType? , GetCapabilities ,
(DeviceType.Hardware, DeviceType.Reference
DeviceType.NullReference),
. , deviceType
GetCapabilities, deviceType
(GraphicsDevice).
,
:
GraphicsDeviceCapabilities caps =
GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle,
options, presentParams);
CD Examples\Ch02\Ex02.
2.4.2. .
, (Ex02), ,
. ,
. GraphivsDevice RenderState,
:
public RenderState RenderState {get; }
RenderState, ,
. , RenderState.PointSize :
// 1.0f
float PointSize { get; set; }
2.9 10x10 .
GraphicsDevice.RenderState.PointSize
. ,
, 10x10.
, ,
:
.
2.4.1 , XNA Framework GraphicsDeviceCapabilities
. , PointSize
, :
public float MaxPointSize { get; }
D3D RightMark, CD RightMark D3D.
D3D RightMark, D3D RightMark |
Direct3D 9.0 Information ( Available Tests)
. 2.10 , ATI Radeon 9800
XT 256x256 .
D3D RightMark
100%. D3D RightMark, ;
.
, ,
10x10 (Ex02). Load
new GraphicsDevice :
// 10x10
if (device.GraphicsDeviceCapabilities.MaxPointSize < 10)
{
//
MessageBox.Show(" 10 ",
" ", MessageBoxButtons.OK, MessageBoxIcon.Error);
//
closing = true;
// Idle, ( Close
// Load )
Application.Idle += new EventHandler(Application_Idle);
// Load
return;
}
2.6 MaxPointSize
. ,
64- . , XNA Framework
, , XNA Framework
64- .
.
2.6. GPU.
GPU
( )
64
8192
8192
256
256
256
2.4.3. .
,
.
MouseDown,
. , ,
Paint. 2.8 (Ex04).
2.8.
public partial class MainForm : Form
{
...
//
VertexPositionColor[] vertices = null;
//
int pointCount = 0;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
// ,
// DrawUserPrimitives
maxVertexCount = Math.Min(device.GraphicsDeviceCapabilities.MaxPrimitiveCount,
device.GraphicsDeviceCapabilities.MaxVertexIndex);
// , 16-
vertices = new VertexTransformedPositionColor[16];
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
// ( DrawUserPrimitives
// )
if (pointCount > 0)
{
device.VertexDeclaration = decl;
device.RenderState.PointSize = 10.0f;
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.PointList, vertices, 0,
pointCount);
pass.End();
}
effect.End();
}
device.Present();
...
}
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
//
if (e.Button == MouseButtons.Left)
{
//
if (pointCount == maxVertexCount)
{
//
MessageBox.Show(String.Format(" +
GPU: {0}.", maxVertexCount), "", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
//
if (pointCount == vertices.Length)
{
// ( )
int newSize = vertices.Length * 2;
//
if (newSize > maxVertexCount)
newSize = maxVertexCount;
//
VertexPositionColor[] newVertices = new VertexPositionColor[newSize];
//
vertices.CopyTo(newVertices, 0);
// vertices
vertices = newVertices;
}
// ,
// . XNA
// Framework MouseToLogicalCoords.
vertices[pointCount] = new VertexPositionColor(
Helper.MouseToLogicalCoords(e.Location, ClientSize), XnaGraphics.Color.Aqua);
//
pointCount++;
//
Invalidate();
}
}
}
. , .NET Framework
,
,
. ,
, ,
. :
( ,
),
.
, , Genetic list<>. . ,
DrawUserPrimitives System.Array,
ToArray(),
. , list<>
, , ,
.
,
GraphicsDevice.DrawUserPrimitives. , GraphicsDevice.DrawUserPrimitives
,
. ,
, ,
CPU GPU.
DrawUserPrimitives ,
. ,
, .
GraphicsDeviceCapabilities:
// ,
public int MaxPrimitiveCount { get; }
// , .
public int MaxVertexIndex { get; }
2.7 2.8
. , Intel GMA 900 65535
65534 .
(65534). ATI
. ,
, ,
MaxPrimitiveCount, MaxVertexIndex:
maxVertexCount = Math.Min(device.GraphicsDeviceCapabilities.MaxVertexIndex,
device.GraphicsDeviceCapabilities.MaxPrimitiveCount)
1.048.575
1.048.575
65.535
65.535 1.048.57535
16.777.215
1.048.575
65.534
65.534 16.777.21536
!
,
(blue screen of
death). XNA Framework
XNA- .
, ,
65534 . ? ,
, 18 Intel GMA 900.
, , .
:
, . , 37.
,
. , DrawUserPrimitives
System.IndexOutOfRangeException.
, .
XNA Framework,
-1 .. +1. , , Windows
Y , XNA Framework .
,
Helper, Helper.cs ( 2.9).
, XNA Framework.
2.9.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace GSP.XNA
{
class Helper
{
//
. .
public static Vector3 MouseToLogicalCoords(System.Drawing.Point location,
System.Drawing.Size clientSize)
35
.
.
37
MaxPrimitiveCount.
, .
36
{
Vector3 v;
// [-1, +1]. 0
// Math.Max, 1.
v.X = (float)location.X / (float)Math.Max(clientSize.Width - 1, 1) * 2.0f - 1.0f;
v.Y = 1.0f - (float)location.Y / (float)Math.Max(clientSize.Height - 1, 1)*2.0f;
v.Z = 0.0f;
return v;
}
}
}
2.4.4. HLSL.
, , ,
. , , :
(aqua), ( SimpleEffect.fx)
C#-. ,
vertices[pointCount] = new VertexPositionColor(
Helper.MouseToLogicalCoords(e.Location, ClientSize), XnaGraphics.Color.Aqua);
, .
fx- ,
.
HLSL
.
: (iPos) (iColor).
(oPos) (oColor).
iColor COLOR ( 2.10).
COLOR oColor ,
.
2.10.
void MainVS(in float3 iPos:POSITION, in float4 iColor:COLOR,
out float4 oColor:COLOR)
{
oPos = float4(iPos, 1);
// Color .
oColor = iColor;
}
: in out. in
, . out ,
: out-
. ,
inout. , iColor oColor
Color, ( 2.11).
2.11.
// ( color)
void MainVS(in float3 iPos:POSITION, inout float4 color:COLOR, out float4 oPos:POSITION)
{
oPos = float4(iPos, 1);
}
, 38,
.
HLSL C ( 2.12).
2.12.
// .
//
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
//
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
void MainVS(in VertexInput input, out VertexOutput output)
{
output.pos = float4(input.pos, 1.0f);
output.color = input.color;
}
, :
,
VertexInput. MainVS
(output). , MainVS ,
( 2.13).
2.13.
VertexOutput MainVS(VertexInput input)
{
// output
VertexOutput output;
output.pos = float4(input.pos, 1.0f);
output.color = input.color;
//
return output;
}
.
,
( ). ,
, . ,
. ,
38
(
).
( 2.14).
2.14.
float4 MainPS(float4 color:COLOR):COLOR
{
return color;
}
COLOR. ,
39.
. , COLOR
TEXCOORD ( 2.14). ,
.
ps_1_x ,
ps_2_0.
2.6.
2.14.
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
struct VertexOutput
{
float4 pos : POSITION;
// ,
float4 color : TEXCOORD;
};
ps_3_0
. 4.x.
{
VertexShader = compile vs_2_0 MainVS();
PixelShader = compile ps_2_0 MainPS();
}
}
C#-
, , C#-
:
.
MouseDown ( 2.15).
2.15.
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// ,
if (pointCount == maxVertexCount)
{
MessageBox.Show(String.Format(" +
GPU: {0}.", maxVertexCount), "", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
// .
if (pointCount == vertices.Length)
{
int newSize = vertices.Length * 2;
if (newSize > maxVertexCount)
newSize = maxVertexCount;
VertexPositionColor[] newVertices = new VertexPositionColor[newSize];
vertices.CopyTo(newVertices, 0);
vertices = newVertices;
}
XnaGraphics.Color color;
double delta;
do
{
// R, G, B
byte[] bytes = new byte[3];
rnd.NextBytes(bytes);
//
color = new XnaGraphics.Color(bytes[0], bytes[1], bytes[2]);
//
delta = Math.Pow((color.R - XnaGraphics.Color.CornflowerBlue.R), 2) +
Math.Pow((color.G - XnaGraphics.Color.CornflowerBlue.G), 2) +
Math.Pow((color.B - XnaGraphics.Color.CornflowerBlue.B), 2);
}
// , .
while(delta < 1000);
//
vertices[pointCount] = new VertexPositionColor(Helper.MouseToLogicalCoords(
,
. ,
( 2.11).
,
:
(2.1)
r .
c2 r , c2 g , c2b , .
,
, .
CD Ch02\Ex05.
Color1
Color2
B
2.11. .
2.1
, y=cos(x), x
0720 ( 2.12). ,
CD (Ch02\Ex06).
2.12. y=f(x), .
2.5.
XNA Framework : (PrimitiveType.LineList)
(PrimitiveType.LineStrip).
Device.DrawUserPrimitives .
,
, .. ( 2.13).
. (PrimitiveType.LineStrip) ,
. ,
.. ( 2.14).
v1
v5
v4
v0
v2
v3
2.13. (Direct3D.PrimitiveType.LineList)
v1
v5
v4
v0
v2
v3
2.14. (Direct3D.PrimitiveType.LineStrip)
2.5.1. (PrimitiveType.LineList).
PrimitiveType.LineList
Ex04. ,
. , Paint
, ,
, . 2.16
(Ex07):
2.16
public partial class MainForm : Form
{
...
//
VertexPositionColor[] vertices = null;
//
int lineCount = 0;
// ,
// DrawUserPrimitives
int maxLineCount;
// , , (
// , )
bool AddingLine = false;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
// ,
// DrawUserPrimitives
maxLineCount = Math.Min(device.GraphicsDeviceCapabilities.MaxPrimitiveCount,
device.GraphicsDeviceCapabilities.MaxVertexIndex / 2);
// ,
vertices = new VertexPositionColor[16];
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
if (lineCount > 0)
{
device.VertexDeclaration = decl;
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.LineList, vertices, 0,
lineCount);
pass.End();
}
effect.End();
}
device.Present();
...
}
...
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
//
if (e.Button == MouseButtons.Left)
{
// ,
if (lineCount == maxLineCount)
{
MessageBox.Show(String.Format(" +
GPU: {0}.", maxLineCount), "", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
//
AddingLine = true;
// ,
// .
if (lineCount * 2 >= vertices.Length)
{
int newLineCount = lineCount * 2;
//
if (newLineCount > maxLineCount)
newLineCount = maxLineCount;
VertexPositionColor[] newVertices = new VertexPositionColor[newLineCount*2];
vertices.CopyTo(newVertices, 0);
vertices = newVertices;
}
// .
// [-1, +1] MouseToLogicalCoords,
// 2.4.3.
vertices[lineCount * 2] =
new VertexPositionColor(Helper.MouseToLogicalCoords(e.Location, ClientSize),
XnaGraphics.Color.Aqua);
vertices[lineCount * 2 + 1] = vertices[lineCount * 2];
// 1
lineCount++;
//
Invalidate();
}
}
private void MainForm_MouseMove(object sender, MouseEventArgs e)
{
//
if (AddingLine == true)
{
//
vertices[lineCount * 2 - 1].Position = Helper.MouseToLogicalCoords(e.Location,
ClientSize);
//
Invalidate();
}
}
private void MainForm_MouseUp(object sender, MouseEventArgs e)
{
//
if (e.Button==MouseButtons.Left)
//
AddingLine = false;
}
}
, ,
DrawUserPrimitives. 2.4.3,
,
,
GraphicsDeviceCapabilities.MaxPrimitiveCount
GraphicsDeviceCapabilities.MaxVertexIndex.
PrimitiveType.LineList , ,
,
GraphicsDeviceCapabilities.MaxVertexIndex 2.
,
Ctrl+Z,
.. , ,
2.17.
( 2.15).
2.17.
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode==Keys.Z) && (e.Control==true))
if (AddingLine == false)
{
if (lineCount > 0)
lineCount--;
Invalidate();
}
}
2.15. , (Ex07)
2.5.2. (PrimitiveType.LineStrip).
PrimitiveType.LineStrip. ,
,
.
PrimitiveType.LineStrip , ,
0.8 (Ex08). ,
. ,
( 2.16).
:
0..360
x x0 r sin( )
y y0 r cos( )
x y
x0 y0
, 0 360.
2.18.
2.16. , Direct3D.PrimitiveType.LineStrip.
2.18.
public partial class MainForm : Form
{
GraphicsDevice device = null;
PresentParameters presentParams;
VertexDeclaration decl;
VertexPositionColor[] vertices = null;
// , .
const int LineStripCount = 32;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);
// ,
vertices = new VertexPositionColor[LineStripCount + 1];
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
device.VertexDeclaration = decl;
(2.2)
//
for (int i = 0; i <= LineStripCount; i++)
{
// 2.2
float angle = (float)i / (float)LineStripCount * 2.0f * (float)Math.PI;
// 0.8
float x = 0.8f * (float)Math.Sin(angle);
float y = 0.8f * (float)Math.Cos(angle);
//
int red=(int) (255 * Math.Abs(Math.Sin(angle * 3)));
int green = (int)(255 * Math.Abs(Math.Cos(angle * 2)));
//
vertices[i] = new VertexPositionColor(new Vector3(x, y, 1.0f),
new XnaGraphics.Color(red, green, 0));
};
// , . vertices.Length - 1
// .
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.LineStrip, vertices, 0,
vertices.Length - 1);
pass.End();
}
effect.End();
device.Present();
}
...
}
: Load 2.2
, , .
Paint.
,
;
, GDI+, .
.
.
,
, ( 2.17).
:
17. ,
.
18. ,
.
2.17. .
:
,
. :
19.
:
, 40. 2.3.1 2.2
. ,
, [-1, +1].
. Viewport GraphicsDevice:
public Viewport Viewport { get; set; }
Viewport, ,
:
public struct Viewport
{
// ,
public int Width { get; set; }
// ,
public int Height { get; set; }
// X
public int X { get; set; }
// Y
public int Y { get; set; }
...
}
, Viewport ,
. XNA
Framework X Y , Width Height
. ,
.
100100, ( 2.19).
2.19.
40
// Examples\Ch02\Ex09
private void MainForm_Load(object sender, EventArgs e)
{
// ! ,
//
// System.InvalidOperationException
MinimumSize = SizeFromClientSize(new Size(100, 100));
...
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
if (closing)
return;
try
{
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset();
// .
Viewport viewport = new Viewport();
viewport.Width = 100;
viewport.Height = 100;
// Viewport
device.Viewport = viewport;
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
...
}
}
2.18. ?
20. . ,
.
21. .
,
.
2.18. 100100, .
DirectX
, , .
Ex08:
, . ,
, Clear
. , ,
Helper.cs
( 2.20).
2.20.
// ,
class Helper
{
...
// .
// , .
public static Viewport SquareViewport(System.Drawing.Size clientSize)
{
Viewport viewport = new Viewport();
viewport.Width = Math.Min(clientSize.Width, clientSize.Height);
viewport.Height = viewport.Width;
viewport.X = (clientSize.Width- viewport.Width) / 2;
viewport.Y = (clientSize.Height - viewport.Height) / 2;
return viewport;
}
// .
//
public static Viewport FullScreenViewport(System.Drawing.Size clientSize)
{
Viewport viewport = new Viewport();
viewport.Width = clientSize.Width;
viewport.Height = clientSize.Height;
return viewport;
}
}
, Helper,
2.21.
2.21.
// Ch02\Ex10
private void MainForm_Paint(object sender, PaintEventArgs e)
{
if (closing)
return;
try
{
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset();
//
device.Viewport = Helper.FullScreenViewport(ClientSize);
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
device.Viewport = Helper.SquareViewport(ClientSize);
...
}
}
2.19.
, , .
2.19. , , .
2.2.
, 2.1,
PrimitiveType.PointList PrimitiveType.LineStrip.
: 1, ,
-1 . ( 2.20).
:
(2.3)
red
green
,
y 0, .
2.20.
CD Examples\Ch02\Ex11.
2.6.
XNA Framework
:
PrimitiveType.TriangleList,
PrimitiveType.TriangleFan
PrimitiveType.TriangleStrip. , PrimitiveType.TriangleList.
2.6.1. (PrimitiveType.TriangleList)
:
0-, 1- 2- , 3-, 4- 5- ,
6-, 7- 8- .. ( 2.21).
v1
v5
v4
v7
v0
v2
v3
v6
v8
2.21. , PrimitiveType.TriangleList.
XNA Framework ,
. , ,
2.21 (v0, v1, v2) (v6, v7, v8).
(v3, v4, v5) , .
XNA Framework
.
, . XNA Framework
GraphicsDevice.RenderState.CullMode,
:
public CullMode CullMode { get; set; }
CullMode:
CullMode.None
CullMode.Clockwise ,
CullMode.CounterClockwise ,
.
GraphicsDevice.RenderState.CullMode
CullMode.CounterClockwise, ,
.
CullMode.None.
2.22 (Ex12),
( 2.22).
2.22.
2.22
public partial class MainForm : Form
{
const string effectFileName = "Data\\ColorFill.fx";
GraphicsDevice device = null;
PresentationParameters presentParams;
Effect effect = null;
VertexDeclaration decl = null;
VertexPositionColor[] vertices = null;
FillMode fillMode=FillMode.Solid;
bool closing = false;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
//
vertices = new GraphicsBuffer<TransformedColored>(3);
//
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.4f, 0.0f),
XnaGraphics.Color.Coral);
vertices[1] = new VertexPositionColor(new Vector3(0.4f, -0.4f, 0.0f),
XnaGraphics.Color.LightGreen);
vertices[2] = new VertexPositionColor(new Vector3(-0.4f, -0.4f, 0.0f),
XnaGraphics.Color.Yellow);
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
device.RenderState.CullMode = Cull.None;
device.VertexDeclaration = decl;
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0,
vertices.Length / 3);
pass.End();
}
effect.End();
device.Present();
...
}
...
, .
PrimitiveType.TriangleList.
, 3D 3ds Max Maya
(Wireframe).
, , . XNA Framework
,
.
RenderState.FillMode GraphicsDevice:
FillMode FillMode { get; set; }
FillMode:
FillMode.Point , .
XNA Framework: ,
device.RenderState.PointSize.
FillMode.WireFrame ,
TrianglePrimitive.LineList TrianglePrimitive.LineStrip.
FillMode.Solid .
RenderState.FillMode FillMode.Solid,
.
FillMode (Ex12)
( 2.23).
2.23
public partial class MainForm : Form
{
//
FillMode fillMode=FillMode.Solid;
...
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
device.RenderState.CullMode = Cull.None;
//
device.RenderState.FillMode = fillMode;
//
device.RenderState.PointSize = 3.0f;
...
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0,
verteces.Length / 3);
pass.End();
}
effect.End();
...
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
//
if (e.KeyCode == Keys.Space)
{
//
switch (fillMode)
{
case FillMode.Point:
fillMode = FillMode.WireFrame;
break;
case FillMode.WireFrame:
fillMode = FillMode.Solid;
break;
case FillMode.Solid:
fillMode = FillMode.Point;
break;
}
//
Invalidate();
}
}
}
.
. 41
, .
( 2.23).
,
( 2.24). 4
. ,
, ( 2.25).
( 2.26),
27 . ,
( 2.27), ,
, .
2.23. . .
41
, , [16]
2.24. . .
2.25. . .
2.26. . .
2.27. , 11 .
,
DrawUserPrimitives.
,
n .
.
. , 1
. 1 + 1 = 2.
1 + 1 + 3 = 5, 1 + 1 + 3 + 9 = 14. ,
n :
n1
tc 1 1 3 9 ... 3n1 1 3i
(2.4)
i 0
tc , n .
, , .
[.20] :
n
xi
i 0
1 x n1
1 x
(2.5)
, 2.4 n :
n1
tc 1 3i 1
i 0
1 3( n1)1 3n 1
1 3
2
(2.6)
, ?
, , .
, (n) 11,
311 1
88574 88574 3 = 265722.
2
. ?
.
(n),
tc. (2.6)
3n 2 tc 1
(2.7)
3:
(2.8)
.
:
1.
2.
DrawUserPrimitives.
DrawTriangle
. ,
,
1. ,
0.
2.24.
2.24.
// Examples\Ch02\Ex13
public partial class MainForm : Form
{
// .
// ,
//
const int n = 15;
const string effectFileName = "Data\\ColorFill.fx";
GraphicsDevice device = null;
PresentParameters presentParams;
Effect effect = null;
VertexDeclaration decl = null;
//
VertexPositionColor[] vertices = null;
// ( ,
// )
int currentVertex;
// , vertices .
//
a, b, c
//
pass
void DrawTriangle(Vector2 a, Vector2 b, Vector2 c, int pass)
{
// ,
if (pass <= 0)
return;
//
pass -= 1;
//
vertices[currentVertex] = new VertexPositionColor(new Vector3(ab.X, ab.Y, 0.0f),
XnaGraphics.Color.Black);
vertices[currentVertex + 1] = new VertexPositionColor(new Vector3(ac.X, ac.Y, 0.0f),
XnaGraphics.Color.Black);
vertices[currentVertex + 2] = new VertexPositionColor(new Vector3(bc.X, bc.Y, 0.0f),
XnaGraphics.Color.Black);
//
currentVertex += 3;
//
Vector2 ab = new Vector2((a.X +
Vector2 ac = new Vector2((a.X +
Vector2 bc = new Vector2((b.X +
// ,
//
DrawTriangle(a, ab, ac, pass);
DrawTriangle(b, ab, bc, pass);
DrawTriangle(c, ac, bc, pass);
}
private void MainForm_Load(object sender, EventArgs e)
{
...
// ,
//
int maxTriangleCount = Math.Min(device.GraphicsDeviceCapabilities.MaxPrimitiveCount,
device.GraphicsDeviceCapabilities.MaxVertexIndex / 3);
// 2.8 ,
//
int maxPass = (int) Math.Floor(Math.Log(2 * maxTriangleCount - 1, 3));
// , n
int passes = Math.Min(n, maxPass);
// 2.6 , .
int triangleCount = ((int)Math.Pow(3, passes) + 1) / 2;
//
vertices = new VertexPositionColor[3 * triangleCount];
Text += " : " + passes.ToString();
//
Vector2 a = new Vector2(0.0f, 0.9f);
Vector2 b = new Vector2(-0.9f, -0.9f);
Vector2 c = new Vector2(0.9f, -0.9f);
//
currentVertex = 0;
//
vertices[currentVertex] = new VertexPositionColor(new Vector3(a.X, a.Y, 0.0f),
XnaGraphics.Color.Black);
vertices[currentVertex + 1] = new VertexPositionColor(new Vector3(b.X, b.Y, 0.0f),
XnaGraphics.Color.Black);
vertices[currentVertex + 2] = new VertexPositionColor(new Vector3(c.X, c.Y, 0.0f),
XnaGraphics.Color.Black);
currentVertex += 3;
// pass
CreateTriangle(a, b, c, passes);
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
device.Clear(ClearFlags.Target, Color.White, 0.0f, 0);
device.BeginScene();
//
device.RenderState.CullMode = Cull.None;
//
device.RenderState.FillMode = FillMode.WireFrame;
device.VertexFormat = TransformedColored.Format;
//
device.DrawUserPrimitives(PrimitiveType.TriangleList, verteces.NumberElements/3,
verteces);
device.EndScene();
device.Present();
}
...
}
}
2.3.
, ,
( 2.28). CD Ch02\Ex14.
2.28.
2.6.2. (PrimitiveType.TriangleFan)
, PrimitiveType.TriangleFan,
. (0-, 1- 2-) .
0-, 2- 3- , 0-, 3- 4- .. ( 2.29).
, ,
.
v3
v2
v4
v0
v1
v5
2.29. , PrimitiveType.TriangleFan
, Ex09,
( 1.31).
Load Paint:
22. .
23.
24. LineList TriangleFan
(Space). ,
, ( 2.31).
2.31. ( 18- ), .
(Ex15) 2.25.
2.25.
//
const int slices = 64;
//
FillMode fillMode = FillMode.Solid;
private void MainForm_Load(object sender, EventArgs e)
{
...
//
vertices = new VertexPositionColor[slices + 2];
// ,
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f),
XnaGraphics.Color.White);
//
for (int i = 0; i <= slices; i++)
{
//
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
float x = 0.7f * (float)Math.Sin(angle);
float y = 0.7f * (float)Math.Cos(angle);
//
byte red = (byte)(255 * Math.Abs(Math.Sin(angle * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(angle * 2)));
//
vertices[i + 1] = new VertexPositionColor(new Vector3(x, y, 0.0f),
new XnaGraphics.Color(red, green, 0));
};
...
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
// .
// FullScreenViewport Helper
device.Viewport = Helper.FullScreenViewport(ClientSize);
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
device.Viewport = Helper.SquareViewport(ClientSize);
// (. )
device.RenderState.CullMode = CullMode.None;
//
device.RenderState.FillMode = fillMode;
device.VertexDeclaration = decl;;
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleFan, vertices, 0, vertices.Length
- 2);
pass.End();
}
effect.End();
//
device.Present();
}
//
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
//
if (e.KeyCode == Keys.Space)
{
//
if (fillMode == FillMode.Solid)
fillMode = FillMode.WireFrame;
else
fillMode = FillMode.Solid;
//
Invalidate();
}
}
2.6.3. (PrimitiveType.TriangleStrip)
, PrimitiveType.TriangleStrip,
. 0-, 1- 2- ,
3-, 2- 1- , 2-, 3- 4- ,
5-, 4- 3-, . ( 2.32).
:
, ,
.
RenderState.CullMode (. x.x).
v5
v3
v1
v9
v11
v8
v10
V7
v4
v0
v6
v2
2.32.
, PrimitiveType.LineStrip.
, 2.32 ,
.
y=cos(x)
PrimitiveType.TriangleStrip, ,
0720 (04 ) 10 .
2.1 2.2,
.
.
, ,
( 2.33).
2.33. , ( ,
).
.
2.30 p0, p1, p2 .. p0
, , 0.05 , v0 v1,
10 . ,
(v2v3, v4v5, v6v7, , v2nv2n+1), 0.1 . , ,
, v0, v1, v2, v3,
0.1 , ( 2.34).
2.34.
,
. ,
y=cos(x), ,
y=cos(x) X Y:
y 0.6 cos(2 x)
(2.9)
cos
x , [-1, +1]. x ,
, -1 +1.
0 4 (0...720).
y y , [-0.7, +0.7].
x -1 +1 (2.9),
p0, p1, , pn ( 2.34). ,
v0, v1, , v2n, v2n+1 p0
pn 0.05 .
, : ,
v0v1, v2v3, , v2nv2n+1 p0, p1, , pn.
, Y , :
v0 = p0 - 0.05
v1 = p0 + 0.05
..
(Ex16) 2.26.
2.26.
public partial class MainForm : Form
{
// ,
const int QuadStrips = 100;
//
const int TriStrips = QuadStrips * 2;
...
//
VertexPositionColor[] vertices = null;
//
FillMode fillMode = FillMode.Solid;
...
(2.10)
. ,
y=cos(x), ,
, cos(x) -1 1. (
2.35).
,
, 2.6.3.
2.35. y=cos(x)
y=cos(x)
, v0v1, , v2nv2n+1 Y .
, , .
v0v1, , v2nv2n+1, , 45 ( 2.36):
// v[2*i+1] p[n]
float nx = (float) (5.0 / Math.Sqrt(2.0));
float ny = nx;
// 5 (-1, -1) (+1, +1)
vertices[i * 2] = new VertexPositionColor(new Vector3(x - nx, y - ny, 0.0f),
new XnaGraphics.Color(red, green, 0));
vertices[i * 2 + 1] = new VertexPositionColor(new Vector3(x + nx, y + ny, 0.0f),
new XnaGraphics.Color(red, green, 0));
, ,
, v2iv2i+1 . ,
0.1 , v2iv2i+1
.
v2iv2i+1 0.1 , pi,
:
25. ,
s pi.
26. , n , s .
27. v2i v2i+1 pi
n n .
. , ,
, :
s (
df ( x, y) df ( x, y )
,
)
dx
dy
(2.11)
s ,
f ( x, y) , (f(x, y)=0)
df ( x, y ) df ( x, y )
,
x y
dx
dy
y 0.6 cos(2 x) 0
,
(2.12)
s:
s (sx , s y )
sx
(2.13)
sy
MathCAD
, .
, , MathCAD.
MatCAD
, .
(Ctrl + .) Enter,
( 2.37). MathCAD , , [.22].
2.37. MathCAD.
n a
s n , s :
s
s
(2.14)
n , s a
a ( 0.05)
s s
v2i v2i+1 :
v2i pi n
v2i1 pi n
(2.15)
Paint
. , , ,
. 2.38.
2.38. y=cos(x)
CD-
, PrimitiveType.TriangleStrip
. 2.28
, CD ( 2.39).
2.28
public partial class MainForm : Form
{
// fx-
const string effectFileName = "Data\\ColorFill.fx";
//
const int slices = 100;
// CD-
const float innerRadius = 0.2f;
// CD-
const float outerRadius = 0.7f;
//
FillMode fillMode = FillMode.Solid;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
//
vertices = new VertexPositionColor[slices * 2 + 2];
// CD
for (int i = 0; i <= slices; i++)
{
//
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
//
float sin = (float)Math.Sin(angle);
float cos = (float)Math.Cos(angle);
// CD
float x = innerRadius * sin;
float y = innerRadius * cos;
//
vertices[i * 2] = new VertexPositionColor(new Vector3(x, y, 0.0f),
XnaGraphics.Color.White);
// CD
x = outerRadius * sin;
y = outerRadius * cos;
//
byte red = (byte)(255 * Math.Abs(Math.Sin(angle * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(angle * 2)));
//
vertices[i * 2 + 1] = new VertexPositionColor(new Vector3(x, y, 0.0f),
new XnaGraphics.Color(red, green, 0));
};
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
device.Viewport = Helper.FullScreenViewport(ClientSize);
device.Clear(ClearFlags.Target, Color.CornflowerBlue, 0.0f, 0);
device.Viewport = Helper.SquareViewport(ClientSize);
device.RenderState.CullMode = CullMode.None;
device.RenderState.FillMode = fillMode;
device.VertexDeclaration = decl;
// CD
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleStrip, vertices, 0,
vertices.Length - 2);
pass.End();
}
effect.End();
device.Present();
}
...
}
// , Space
// ()
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
if (fillMode == FillMode.Solid)
fillMode = FillMode.WireFrame;
else
fillMode = FillMode.Solid;
Invalidate();
}
}
}
(Ex19) : ,
( 2.41).
Ex18.
2.41. .
:
, .
. , 45 X Y,
:
x x0 r sin 2 sign(sin )
(2.16)
y y0 r cos 2 sign(cos )
x y .
x0 y0 .
, 0 360 (02).
r .
sign Math.Sign .NET.
, 45 ,
, Ex19,
CD ( 2.39).
2.39.
for (int i = 0; i <= slices; i++)
{
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
float sin = (float)Math.Sin(angle);
float cos = (float)Math.Cos(angle);
// ,
//
float sin2 = sin * sin * Math.Sign(sin);
float cos2 = cos * cos * Math.Sign(cos);
//
float x = innerRadius * sin;
float y = innerRadius * cos;
vertices[i * 2] = new VertexPositionColor(new Vector3(x, y, 0.0f),
XnaGraphics.Color.White);
// 2.16.
x = outerRadius * sin2;
y = outerRadius * cos2;
//
byte red = (byte)(255 * Math.Abs(Math.Sin(angle * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(angle * 2)));
//
vertices[i * 2 + 1] = new VertexPositionColor(new Vector3(x, y, 0.0f),
new XnaGraphics.Color(red, green, 0));
};
2.42. 45 , .
40- .
Ex21 2.42. ,
45 .
, x0, y0,
:
(2.17)
x0 , y0 ,
x , y
x y 2.16,
, :
x x0
r
(cos 2 sign(cos ) sin 2 sign(cos ))
2
y y0
r
(cos 2 sign(cos ) sin 2 sign(cos ))
2
45,
(2.18)
Ex19,
2.18, . :
45 . ( 2.39)
, ,
, . 45
2.17 2.2:
x x0
r
(cos sin )
2
y y0
r
(cos sin )
2
(2.19)
2.39. , . .
2.19 -
( 2.37 2.40). 2.18 2.19 2.40 (Ex20):
2.44. , .
2.40.
//
const float innerRadius = 0.285f;
const float outerRadius = 1.0f;
// ,
readonly float sqrt2 = (float)Math.Sqrt(2.0);
...
for (int i = 0; i <= slices; i++)
{
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
float sin = (float)Math.Sin(angle);
2.4
2.18 2.19 ,
42:
r
n
n
( cos sign(cos ) sin sign(cos ))
2
r
n
n
y y0
( cos sign(cos ) sin sign(cos ))
2
x x0
(2.20)
x , y .
x0 , y0 .
r .
n
, 0 360.
42
, 2.20 , 45
2.45. , . 2.5,
1.3.
CD \Examples\Ch02\Ex21.
2.5
, ,
:
x sin(2 )
(2.21)
y cos(3 )
x , y
, 0 360 (02)
10 (
2.46).
2.46.
, ,
.
, , 2.21
:
x 0.85 sin(2 )
(2.22)
y 0.85 cos(3 )
x, y
k (k x , k y )
kx
d (0.85 sin(2 ))
1.7 cos(2 )
d
ky
d (0.85 cos(3 ))
2.55 sin(3 )
d
(2.23)
k x , k y
, , :
s ( k y , k x )
sx k y 2.55 sin(3 )
(2.24)
s y k x 1.7 cos(2 )
( s ),
( ).
CD \Examples\Ch02\Ex22.
3. .
:
?
?
?
?
. .
, Control protected.
Form,
(protected) .
, Visual Studio,
. , SetStyle,
ControlStyles.Opaque.
, XNA- (
1.2.3).
Control
, SetStyle protected public. Visual Studio
XnaPanel (File | New Project | Class Library,
Name XnaPanel OK). Create directory for
solution, ,
. System.Windows.Forms 3.1.
3.1.
using
using
using
using
43
System;
System.Collections.Generic;
System.Text;
System.Windows.Forms;
namespace GSP.XNA
{
// ( ) XnaPanel, Control
public class XnaPanel : Control
{
//
public XnaPanel()
{
// ,
BackColor = Color.CornflowerBlue;
// 1x1
MinimumSize = new Size(1, 1);
}
// SetStyle Control public
public new void SetStyle(ControlStyles flag, bool value)
{
// Control
base.SetStyle(flag, value);
}
}
}
xnaPanel
, MinimumSize Size(1, 1).
, ,
(. 1.2.3).
, .
,
( 3.2).
Solution Explorer Add | New Project ( 3.3).
Windows Application, Name
(, Test) Ok. ,
XNA Framework using.
3.2. , XnaPanel
3.3. (Solution)
SplitContainer,
Dock Fill , FixedPanel
Panel2. SplitContainer (Group)
Dock. (Label)
: 1, 2, 3.
(Panel) vertex1Panel, vertex2Panel
vertex3Panel. , BorderStyle
FixedSingle. SplitContainer XnaPanel,
xnaPanel , Dock Fill.
, ColorDialog.
.
Load FormClosed ( 3.2).
3.2.
//
GraphicsDevice device = null;
PresentationParameters presentParams;
Effect effect = null;
VertexDeclaration decl = null;
VertexPositionColor[] vertices = null;
bool closing = false;
private void MainForm_Load(object sender, EventArgs e)
{
// xnaPanel
xnaPanel.SetStyle(ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
// presentParams
presentParams = new PresentationParameters();
presentParams.IsFullScreen = false;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = xnaPanel.ClientSize.Width;
presentParams.BackBufferHeight = xnaPanel.ClientSize.Height;
presentParams.SwapEffect = SwapEffect.Discard;
//
GraphicsDeviceCapabilities caps =
GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
// . (IntPtr renderWindowHandle)
// xnaPanel
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
xnaPanel.Handle, options, presentParams);
//
vertices = new VertexPositionColor[3];
//
...
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
//
if (device != null)
{
device.Dispose();
device = null;
}
}
, Load
. this xnaPanel.
Paint Resize xnaPanel ( 3.3).
3.3.
private void xnaPanel_Paint(object sender, PaintEventArgs e)
{
// ,
if (closing)
return;
try
{
// ,
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
// ,
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset(presentParams);
// xnaPanel
device.Viewport = Helper.FullScreenViewport(xnaPanel.ClientSize);
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
//
device.Viewport = Helper.SquareViewport(xnaPanel.ClientSize);
//
device.RenderState.CullMode = CullMode.None;
//
device.VertexDeclaration = decl;
// .
// Microsoft.Xna.Framework.Graphics.Color System.Drawing.Color,
// .
vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.4f, 0.0f),
new XnaGraphics.Color(vertex1Panel.BackColor.R, vertex1Panel.BackColor.G,
vertex1Panel.BackColor.B));
vertices[1] = new VertexPositionColor(new Vector3(0.4f, -0.4f, 0.0f),
new XnaGraphics.Color(vertex2Panel.BackColor.R, vertex2Panel.BackColor.G,
vertex2Panel.BackColor.B));
vertices[2] = new VertexPositionColor(new Vector3(-0.4f, -0.4f, 0.0f),
new XnaGraphics.Color(vertex3Panel.BackColor.R, vertex3Panel.BackColor.G,
vertex3Panel.BackColor.B));
//
effect.Begin();
foreach(EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0,
vertices.Length / 3);
pass.End();
}
effect.End();
//
device.Present();
}
//
catch (DeviceNotResetException)
{
Invalidate();
}
catch (DeviceLostException)
{
}
}
private void xnaPanel_Resize(object sender, EventArgs e)
{
//
if (WindowState != FormWindowState.Minimized)
{
//
presentParams.BackBufferWidth = xnaPanel.ClientSize.Width;
presentParams.BackBufferHeight = xnaPanel.ClientSize.Height;
//
device.Reset(presentParams);
}
}
:
Windows ,
, , xnaPanel
. vertex1Panel
Click:
private void vertex1Panel_Click(object sender, EventArgs e)
{
// sender Panel
Panel panel = (Panel)sender;
//
colorDialog1.Color = panel.BackColor;
//
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
// ,
panel.BackColor = colorDialog1.Color;
// xnaPanel
panelDX.Invalidate();
}
}
, sender,
vertex2Panel vertex3Panel:
Click vertex1Panel_Click.
.
CD Examples\Ch03\Ex01.
Visual Studio 46 :
Solution Explorer Set as
StartUp Project ( 3.4).
46
, F5
3.4.
3.1.
, .
, : ,
, (, ) ( 3.5).
3.5. 3.1.
3.2. .
, .
:
30. ,
Windows (Taskbar).
31. (back)
: XNA
Framework , .
32.
.
Windows Forms,
.
(GraphicsDevice) PresentationParameters.
, IsFullScreen true:
presentParams = new PresentationParameters();
presentParams.IsFullScreen = true;
, , :
33. .
34. ( ..).
35. .
47 (back) BackBufferWidth
BackBufferHeight PresentationParameters. :
// 640 480
presentParams.BackBufferWidth = 640;
presentParams.BackBufferHeight = 480;
,
. ,
.
BackBufferFormat PresentationParameters:
public SurfaceFormat BackBufferFormat { get; set; }
SurfaceFormat , ( 3.1).
,
. , SurfaceFormat.Color,
SurfaceFormat.Bgr32. ,
- ;
, (
3.2.2).
3.1. ,
SurfaceFormat
Unknown
Rgba1010102
Color
32
10
10
10
32
Bgr32
32
Bgr565
16
16
Bgra5551
SurfaceFormat SurfaceFormat.Unknown.
,
. , Windows 32- ,
SurfaceFormat.Bgr32.
.
SurfaceFormat.Unknown
System.InvalidOperationException.
, ,
. , ,
SurfaceFormat.Bgr32, , XNA Framework:
presentParams.BackBufferFormat = SurfaceFormat.Bgr32;
, , SurfaceFormat.Bgr32 32 ,
24 ( , 8 ).
, 8, 16, 32
64 . , 24- 8, 16 32-
, , ,
, . , 24-
47
32 , 24 , 32-
.
, , .
- 85 ,
. LCD
, LCD-
60 .
FullScreenRefreshRateInHz PresentationParameters:
public int FullScreenRefreshRateInHz { get; set; }
,
, , .
FullScreenRefreshRateInHz, ,
Windows /.
System.InvalidOperationException,
.
, 3.4.
3.4.
presentParams = new PresentationParameters();
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
// 640480, 32 ,
//
presentParams.IsFullScreen = true;
presentParams.BackBufferWidth = 640;
presentParams.BackBufferHeight = 480;
presentParams.BackBufferFormat = SurfaceFormat.Bgr32;
presentParams.FullScreenRefreshRateInHz = 0;
GraphicsDeviceCapabilities caps =
GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle,
options, presentParams);
Resize. ,
(
ALT + TAB) Windows , ,
, Resize.
, ( back)
:
3.5.
private void MainForm_Resize(object sender, EventArgs e)
{
// ,
//
if ((!presentParams.IsFullScreen) && (WindowState != FormWindowState.Minimized))
{
presentParams.BackBufferWidth = ClientSize.Width;
presentParams.BackBufferHeight = ClientSize.Height;
device.Reset(presentParams);
}
}
:
3.6.
private void MainForm_Paint(object sender, PaintEventArgs e)
{
if (closing)
return;
try
{
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost)
throw new DeviceLostException();
if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset)
device.Reset(presentParams);
//
device.Viewport = Helper.FullScreenViewport presentParams);
//
device.Clear(XnaGraphics.Color.CornflowerBlue);
// (
// )
device.Viewport = Helper.SquareViewport(presentParams);
// CD- (. 2.6.3)
...
}
catch (DeviceNotResetException)
{
Invalidate();
}
catch (DeviceLostException)
{
}
}
,
,
PresentationParameters presentParams.
:
3.7.
//
public static Viewport SquareViewport(PresentationParameters presentParams)
{
return SquareViewport(new System.Drawing.Size(presentParams.BackBufferWidth,
presentParams.BackBufferHeight));
}
//
public static Viewport FullScreenViewport(PresentationParameters presentParams)
{
return FullScreenViewport(new System.Drawing.Size(presentParams.BackBufferWidth,
presentParams.BackBufferHeight));
, CD- ( 3.6),
Examples\Ch03\Ex03.
3.2.1. .
Ch03\Ex03 ( 3.4) ,
64048032bpp48. ,
System.InvalidOperationException.
. ,
,
:
presentParams = new PresentationParameters();
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.IsFullScreen = true;
// 640480, 32 , 60
presentParams.BackBufferWidth = 640;
presentParams.BackBufferHeight = 480;
presentParams.BackBufferFormat = SurfaceFormat.Bgr32;
presentParams.FullScreenRefreshRateInHz = 60;
try
{
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle,
options, presentParams);
}
catch(InvalidOperationException)
{
// ,
//
presentParams.IsFullScreen = false;
presentParams.BackBufferWidth = 0;
presentParams.BackBufferHeight = 0;
presentParams.BackBufferFormat = SurfaceFormat.Unknown;
presentParams.FullScreenRefreshRateInHz = 0;
48
// :
// , , ..
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle, options, presentParams);
}
, :
- XNA Framework
. XNA Framework
, , , 49.
, ,
.
,
? , ,
, .
LCD-, - (
, 1024768 12801024).
CurrentDisplayMode GraphicsAdapter:
public DisplayMode CurrentDisplayMode { get; }
DisplayMode:
public struct DisplayMode
{
//
public int Width { get; }
//
public int Height { get; }
//
public SurfaceFormat Format { get; }
//
public int RefreshRate { get; }
...
}
, :
3.8.
//
DisplayMode displayMode = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode;
presentParams = new PresentationParameters();
presentParams.IsFullScreen = true;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
// ,
presentParams.BackBufferWidth = displayMode.Width;
presentParams.BackBufferHeight = displayMode.Height;
presentParams.BackBufferFormat = displayMode.Format;
presentParams.FullScreenRefreshRateInHz = displayMode.RefreshRate;
GraphicsDeviceCapabilities caps =
GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
49
3.2.2. .
,
. ,
,
640480 800600.
.
,
, ,
( 3.7). ,
XNA Framework GraphicsAdapter SupportedDisplayModes,
DisplayMode ,
.
3.7. .
, Windows Forms .
3.2. ListBox
displayModeListBox. , Ok
DialogResult OK.
3.2.
Name
DisplayModeForm
Text
FormBorderStyle
FixedDialog
MaximizeBox
False
MinimizeBox
False
, : SelectedDisplayMode,
( 3.9).
3.9.
, Load
:
3.10.
private void MainForm_Load(object sender, EventArgs e)
{
SetStyle(ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
MinimumSize = SizeFromClientSize(new Size(1, 1));
presentParams = new PresentationParameters();
presentParams.IsFullScreen = true;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
//
using (DisplayModeForm displayModeForm = new
DisplayModeForm(GraphicsAdapter.DefaultAdapter))
{
//
displayModeForm.ShowDialog();
// ,
DisplayMode mode = displayModeForm.SelectedDisplayMode;
//
presentParams.BackBufferWidth = mode.Width;
presentParams.BackBufferHeight = mode.Height;
presentParams.BackBufferFormat = mode.Format;
presentParams.FullScreenRefreshRateInHz = mode.RefreshRate;
}
...
//
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle, options, presentParams);
- ,
. Examples\Ch03\Ex05.
. :
/ .
,
3.8. , 1360768,
4:3.
?
. ,
, :
.
,
.
.
, SupportedDisplayModes ,
- (. 3.1 3.2).
-
- . ,
SurfaceFormat.Bgr32, 99.9% SurfaceFormat.Color. ,
, -.
3.2.3. .
Ch03\Ex05 ,
, :
36. ,
.
.
37. , .
:
, ( ),
.
38. ,
. ,
17921344 ,
Width
int
Height
int
Format
SurfaceFormat
SurfaceFormat.Unknown
RefreshRate
int
FullScreen
bool
(false , true )
true
Init
bool
true,
false
ShowSettingForm
bool
true
,
Visual Studio. Solution Explorer
Properties, Setting.settings,
51.
3.3 3.10.
3.9. .
50
, ,
( , , Half-Life 2).
51
Settings
Properties.
3.10.
.
, 3.9
3.4.
3.4. .
Form
( )
Name
SettingsForm
Text
FormatBorderStyle
FixedDialog
MinimizeBox
false
MaximizeBox
false
Name
inWindowCheckBox
Text
GroupBox
Text
Label
Text
ComboBox
(
)
Name
aspectRatioComboBox
DropDownStyle
DropDownList
Label
Text
ComboBox
( )
Name
resolutionComboBox
DropDownStyle
DropDownList
Label
Text
ComboBox
( )
Name
colorDepthComboBox
DropDownStyle
DropDownList
Label
Text
CheckBox
ComboBox
( )
Name
refreshRateComboBox
DropDownStyle
DropDownList
Button
Name
okButton
Text
Ok
Text
Cancel
DialogResult
Cancel
Button
, , ,
( ) .
,
Bgr32 Bgr565. ,
: ,
. (
), .
3.11.
3.11.
//
public struct AspectItem
{
//
public float aspect;
public AspectItem(float aspect)
{
this.aspect = aspect;
}
// (ResolutionItem)
// . true, - false
public bool Compare(float aspect)
{
// (
// ), true
if (this.aspect == 0)
return true;
//
//
//
//
, .
,
. , 1360 x 768 85/48=1.771,
16/9=1.778.
if (Math.Abs(this.aspect - aspect) < this.aspect * 0.01f)
return true;
else
return false;
}
//
public override string ToString()
{
if (aspect == 0)
return "";
if (Compare(4.0f / 3.0f))
return "4 : 3";
if (Compare(5.0f / 4.0f))
return "5 : 4";
if (Compare(16.0f / 9.0f))
return "16 : 9";
return aspect.ToString();
}
}
//
public struct ResolutionItem : IComparable<ResolutionItem>
{
//
public int width;
public int height;
public ResolutionItem(int width, int height)
{
this.width = width;
this.height = height;
}
// X Y
public float Aspect
{
get
{
return (float)width / (float)height;
}
}
//
public override string ToString()
{
return width.ToString() + " x " + height.ToString();
}
// IComparable<ResolutionItem>,
//
public int CompareTo(ResolutionItem other)
{
//
if (width > other.width)
return 1;
if (width < other.width)
return -1;
// , .
// , .
if (height > other.height)
return 1;
if (height < other.height)
return -1;
return 0;
}
}
//
public struct ColorDepthItem : IComparable<ColorDepthItem>
{
//
public SurfaceFormat value;
public ColorDepthItem(SurfaceFormat value)
{
this.value = value;
}
//
public override string ToString()
{
string str;
switch (value)
{
case SurfaceFormat.Bgr32:
str = "32 ({0})";
break;
case SurfaceFormat.Bgr565:
str = "16 ({0})";
break;
case SurfaceFormat.Rgba1010102:
str = "32 ({0})";
break;
case SurfaceFormat.Bgr555:
str = "16 {0}";
break;
default:
str = "{0}";
break;
}
return string.Format(str, value);
}
// IComparable<ColorDepthItem>,
//
public int CompareTo(ColorDepthItem other)
{
if (value > other.value)
return -1;
if (value < other.value)
return 1;
return 0;
}
}
//
public struct RefreshRateItem : IComparable<RefreshRateItem>
{
//
public int value;
public RefreshRateItem(int value)
{
this.value = value;
}
//
public override string ToString()
{
return value.ToString() + " ";
}
// IComparable< RefreshRateItem>,
//
public int CompareTo(RefreshRateItem other)
{
if (value > other.value)
return 1;
if (value < other.value)
return -1;
return 0;
}
}
,
, ( 3.12).
3.12.
public partial class SettingsForm : Form
{
//
SortedDictionary<ResolutionItem, SortedDictionary<ColorDepthItem,
SortedDictionary<RefreshRateItem, bool>>> modeCollection;
// . Properties.Settings
// ( 3.10).
Properties.Settings settings;
//
internal SettingsForm(Properties.Settings settings, GraphicsAdapter adapter)
{
InitializeComponent();
//
this.settings = settings;
// ,
//
if (!settings.Init)
{
settings.Width = adapter.CurrentDisplayMode.Width;
settings.Height = adapter.CurrentDisplayMode.Height;
settings.Format = adapter.CurrentDisplayMode.Format;
settings.RefreshRate = adapter.CurrentDisplayMode.RefreshRate;
settings.FullScreen = true;
}
modeCollection = new SortedDictionary<ResolutionItem,
SortedDictionary<ColorDepthItem, SortedDictionary<RefreshRateItem, bool>>>();
// ,
// modeCollection
foreach (DisplayMode mode in adapter.SupportedDisplayModes)
{
ResolutionItem res = new ResolutionItem(mode.Width, mode.Height);
if (!modeCollection.ContainsKey(res))
modeCollection.Add(res, new SortedDictionary<ColorDepthItem,
SortedDictionary<RefreshRateItem, bool>>());
ColorDepthItem depth = new ColorDepthItem(mode.Format);
if (!modeCollection[res].ContainsKey(depth))
modeCollection[res].Add(depth, new SortedDictionary<RefreshRateItem,
bool>());
RefreshRateItem refresh = new RefreshRateItem(mode.RefreshRate);
if (!modeCollection[res][depth].ContainsKey(refresh))
modeCollection[res][depth].Add(refresh, true);
}
// .
inWindowCheckBox.Checked = !settings.FullScreen;
//
aspectRatioComboBox.Items.Add(new AspectItem());
aspectRatioComboBox.Items.Add(new AspectItem(4.0f / 3.0f));
aspectRatioComboBox.Items.Add(new AspectItem(5.0f / 4.0f));
aspectRatioComboBox.Items.Add(new AspectItem(16.0f / 9.0f));
// ()
aspectRatioComboBox.SelectedIndex = 0;
}
...
}
, ,
. ,
1024x768x32bpp:@85Hz
modeCollection[1024x768][ SurfaceFormat.Brg32][85]52.
, SelectedIndexChanged,
3.13.
3.13.
//
//
private void aspectRatioComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//
52
: modeCollection[new
ResolutionItem(1024, 768)][new ColorDepthItem(SurfaceFormat.Bgr32)][new
RefreshRateItem(85)]. , ,
,
.
colorDepthComboBox.Enabled = true;
refreshRateComboBox.Enabled = true;
okButton.Enabled = true;
}
else
{
//
resolutionComboBox.Enabled = false;
colorDepthComboBox.Enabled = false;
refreshRateComboBox.Enabled = false;
okButton.Enabled = false;
}
}
}
,
SelectedIndexChanged ( 3.14).
3.14.
private void resolutionComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//
ResolutionItem res = (ResolutionItem) resolutionComboBox.SelectedItem;
//
ColorDepthItem currentColorDepth;
// .
// ,
if (colorDepthComboBox.SelectedIndex != -1)
currentColorDepth = (ColorDepthItem)colorDepthComboBox.SelectedItem;
else
currentColorDepth = new ColorDepthItem(settings.Format);
//
colorDepthComboBox.Items.Clear();
//
//
foreach (ColorDepthItem colorDepth in modeCollection[res].Keys)
colorDepthComboBox.Items.Add(colorDepth);
// ,
colorDepthComboBox.SelectedItem = currentColorDepth;
//
if (colorDepthComboBox.SelectedIndex == -1)
colorDepthComboBox.SelectedIndex = 0;
}
, ,
,
,
SelectedIndexChanged ( 3.15).
3.15.
private void colorDepthComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// ( )
ResolutionItem res = (ResolutionItem)resolutionComboBox.SelectedItem;
ColorDepthItem colorDepth = (ColorDepthItem)colorDepthComboBox.SelectedItem;
//
RefreshRateItem currentRefreshRate;
// .
// ,
if (refreshRateComboBox.SelectedIndex != -1)
currentRefreshRate = (RefreshRateItem)refreshRateComboBox.SelectedItem;
else
currentRefreshRate = new RefreshRateItem(settings.RefreshRate);
//
refreshRateComboBox.Items.Clear();
// ,
//
foreach (RefreshRateItem refreshRate in modeCollection[res][colorDepth].Keys)
refreshRateComboBox.Items.Add(refreshRate);
//
refreshRateComboBox.SelectedItem = currentRefreshRate;
// ,
if (refreshRateComboBox.SelectedIndex == -1)
refreshRateComboBox.SelectedIndex = 0;
}
, Ok:
3.16.
private void okButton_Click(object sender, EventArgs e)
{
//
//
settings.FullScreen = !inWindowCheckBox.Checked;
if (!inWindowCheckBox.Checked)
{
settings.Width = ((ResolutionItem)resolutionComboBox.SelectedItem).width;
settings.Height = ((ResolutionItem)resolutionComboBox.SelectedItem).height;
settings.Format = ((ColorDepthItem)colorDepthComboBox.SelectedItem).value;
settings.RefreshRate = ((RefreshRateItem)refreshRateComboBox.SelectedItem).value;
}
// .
//
settings.Init = true;
// . .
settings.ShowSettingForm = false;
DialogResult = DialogResult.OK;
}
.
,
.
. , ,
:
40. , , .
Init Settings true.
41. ,
,
. ?
ShowSettingForm
true . ,
ShowSettingForm true, .
42. , ,
. Load
/config . ,
, /config.
, , ,
,
Load ( 3.17).
3.17.
using System.Diagnostics;
void InitGraphivsDevice()
{
SetStyle(ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
MinimumSize = SizeFromClientSize(new Size(1, 1));
//
settings = new Properties.Settings();
// , /config
string[] args = Environment.GetCommandLineArgs();
bool configParam = false;
if ((args.Length == 2) && (args[1].ToUpper() == "/CONFIG"))
configParam = true;
//
if ((configParam) || (settings.ShowSettingForm) || (!settings.Init))
{
//
using (SettingsForm settingsForm = new SettingsForm(settings,
GraphicsAdapter.DefaultAdapter))
{
//
settingsForm.ShowDialog();
// /config
if (configParam)
{
//
closing = true;
Application.Idle += new EventHandler(Application_Idle);
return;
}
}
}
presentParams = new PresentationParameters();
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
//
presentParams.IsFullScreen = settings.FullScreen;
if (settings.FullScreen)
{
presentParams.BackBufferWidth = settings.Width;
presentParams.BackBufferHeight = settings.Height;
presentParams.BackBufferFormat = settings.Format;
presentParams.FullScreenRefreshRateInHz = settings.RefreshRate;
}
else
{
presentParams.BackBufferWidth = 0;
presentParams.BackBufferHeight = 0;
presentParams.BackBufferFormat = SurfaceFormat.Unknown;
presentParams.FullScreenRefreshRateInHz = 0;
}
//
GraphicsDeviceCapabilities caps = GraphicsAdapter.DefaultAdapter.GetCapabilities(
DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
try
{
//
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle,
options, presentParams);
}
catch (InvalidOperationException)
{
//
closing = true;
Application.Idle += new EventHandler(Application_Idle);
//
if (MessageBox.Show(" . +
" ( ..)?", "", MessageBoxButtons.YesNo,
MessageBoxIcon.Error) == DialogResult.Yes)
{
// ShowSettingForm true,
//
settings.ShowSettingForm = true;
//
settings.Save();
//
Process.Start(Application.ExecutablePath);
}
return;
}
}
private void MainForm_Load(object sender, EventArgs e)
{
//
InitGraphivsDevice();
// , Load
if (closing)
return;
// ( , ,
// ..
...
}
- ,
. CD-
Examples\Ch03\Ex03.
.
.NET Framework 2.0 XML user.config,
:
<Profile Directory>\<Company Name>\<App Name>_<Evidence Type>_<Evidence
Hash>\<Version>\user.config
Profile Directory ,
c:\Documents and Settings\< >\Local Settings\Application Data
Company Name , ,
AssemblyCompany Properties\AssemblyInfo.cs.
App Name , ,
AssemblyProduct Properties\AssemblyInfo.cs.
Evidence Type, Evidence Hash .
Version , , AssemblyVersion
Properties\AssemblyInfo.cs
, h03\Ex06
C:\Documents and Settings\Administrator\Local Settings\Application
Data\GSP_Inc\Ex06__Fullscreen_Dialog._Url_31gvfqvzegievbxah0w1qmgu2s2siyo3\1.0.0.0\user.config.
:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<GSP.XNA.Book.Ch03.Ex06.Properties.Settings>
<setting name="Width" serializeAs="String">
<value>1280</value>
</setting>
<setting name="Height" serializeAs="String">
<value>960</value>
</setting>
<setting name="Format" serializeAs="String">
<value>Bgr32</value>
</setting>
<setting name="RefreshRate" serializeAs="String">
<value>85</value>
</setting>
<setting name="FullScreen" serializeAs="String">
<value>True</value>
</setting>
<setting name="Init" serializeAs="String">
<value>True</value>
</setting>
<setting name="ShowSettingForm" serializeAs="String">
<value>False</value>
</setting>
</GSP.XNA.Book.Ch03.Ex06.Properties.Settings>
</userSettings>
</configuration>
,
. ,
.
3.3. .
, XNA Framework
.
? ,
().
,
25- FPS53.
,
25 .
( ), ( 3.11).
( Timer), 40 (
25 ).
. ,
.
,
. 3.18.
3.11. .
3.18.
// CD Examples\Ch03\Ex07
public partial class MainForm : Form
{
// ,
const string effectFileName = "Data\\ColorFill.fx";
// ()
const float diskMinSpeed = 0.5f;
53
//
const float diskMaxSpeed = 1.3f;
//
const int diskSlices = 32;
//
const float diskRadius = 0.1f;
//
readonly static XnaGraphics.Color diskInnerColor = XnaGraphics.Color.White;
//
readonly static XnaGraphics.Color diskOuterColor = XnaGraphics.Color.Green;
//
const float borderSize = 0.1f;
//
readonly static XnaGraphics.Color borderInnerColor = XnaGraphics.Color.DarkBlue;
//
readonly static XnaGraphics.Color borderOuterColor = XnaGraphics.Color.CornflowerBlue;
GraphicsDevice device = null;
PresentationParameters presentParams;
Effect effect = null;
VertexDeclaration decl = null;
//
VertexPositionColor[] borderVerts = null;
//
VertexPositionColor[] baseDiskVerts = null;
// ,
VertexPositionColor[] diskVerts = null;
FillMode fillMode = FillMode.Solid;
// X
float speedX;
// Y
float speedY;
// X
float posX = 0;
// Y
float posY = 0;
//
Random rnd = new Random();
// ( ..)
Properties.Settings settings;
bool closing = false;
// , diskMinSpeed .. diskMaxSpeed
float RndSpeed()
{
return diskMinSpeed + (float)rnd.NextDouble() * (diskMaxSpeed - diskMinSpeed);
}
// Load
private void MainForm_Load(object sender, EventArgs e)
{
//
InitGraphivsDevice();
if (closing)
return;
//
decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);
// ,
// (PrimitiveType.TriangleStrip)
borderVerts = new VertexPositionColor[10];
borderVerts[0] = new VertexPositionColor(new Vector3(-1.0f, -1.0f, 0.0f),
borderOuterColor);
borderVerts[1] = new VertexPositionColor(new Vector3(-1.0f + borderSize, -1.0f +
borderSize, 0.0f),
borderInnerColor);
borderVerts[2] = new VertexPositionColor(new Vector3(-1.0f, 1.0f, 0.0f),
borderOuterColor);
borderVerts[3] = new VertexPositionColor(new Vector3(-1.0f + borderSize, 1.0f borderSize, 0.0f),
borderInnerColor);
borderVerts[4] = new VertexPositionColor(new Vector3(1.0f, 1.0f, 0.0f),
borderOuterColor);
borderVerts[5] = new VertexPositionColor(new Vector3(1.0f - borderSize, 1.0f borderSize, 0.0f),
borderInnerColor);
// X Y
speedX = RndSpeed();
speedY = RndSpeed();
}
// Paint
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleStrip, borderVerts, 0,
borderVerts.Length - 2);
device.DrawUserPrimitives(PrimitiveType.TriangleFan, diskVerts, 0,
diskVerts.Length - 2);
pass.End();
}
effect.End();
device.Present();
...
}
// Tick , Interval 40
private void timer_Tick(object sender, EventArgs e)
{
// ,
//
posX += speedX * (float)timer.Interval * 0.001f;
posY += speedY * (float)timer.Interval * 0.001f;
//
if (posX >= 1 - diskRadius - borderSize)
{
//
posX = 1 - diskRadius - borderSize;
// .
speedX = -Math.Sign(speedX) * RndSpeed();
}
//
if (posY >= 1 - diskRadius - borderSize)
{
posY = 1 - diskRadius - borderSize;
speedY = -Math.Sign(speedY) * RndSpeed();
}
//
if (posX <= -1 + diskRadius + borderSize)
{
posX = -1 + diskRadius + borderSize;
speedX = -Math.Sign(speedX) * RndSpeed();
}
//
if (posY <= -1 + diskRadius + borderSize)
{
posY = -1 + diskRadius + borderSize;
speedY = -Math.Sign(speedY) * RndSpeed();
}
//
// .
for (int i = 0; i < baseDiskVerts.Length; i++)
{
diskVerts[i].Position.X = baseDiskVerts[i].Position.X + posX;
diskVerts[i].Position.Y = baseDiskVerts[i].Position.Y + posY;
}
//
Invalidate();
}
}
, ,
, .
, baseDiskVerts.
.
. .
! 25 fps .
? .
54.
, . , 25 FPS
25 FPS FPS. ,
25-30 FPS
. ,
, 60 FPS.
,
300 /, 60 FPS . ,
FPS
( ) 60-100 Hz.
Motion Blur55,
.
, . , 64 , .. 0.015 .
Interval 15 .
, : ,
.
?
Windows MSDN. 15 ,
55 . , ,
, .
.
, ,
WM_TIMER, WM_KEYDOWN, WM_CHAR WM_KEYUP
WM_TIMER. , WM_TIMER
,
54
55
, - .
56. ,
, , ,
.
WM_TIMER,
Timer . ,
, ,
.
3.3.1. Idle.
, Timer -
Windows. ,
. , ,
, ,
. ,
. ,
, .
?
, ,
Idle Invalidate.
Idle
System.Enviroment.TickCount, ,
. 3.19.
3.19.
// Examples\Ch03\Ex08
public partial class MainForm : Form
{
// System.Enviroment.TickCount
// Idle.
int lastTick;
private void MainForm_Load(object sender, EventArgs e)
{
...
// System.Enviroment.TickCount
lastTick = Environment.TickCount;
Application.Idle += new EventHandler(Application_Idle);
}
void Application_Idle(object sender, EventArgs e)
{
// , .
if (closing)
{
Close();
return;
}
int currentTick = Environment.TickCount;
// ( ), Idle
float delta = (float)(currentTick - lastTick) * 0.001f;
//
posX += speedX * delta;
posY += speedY * delta;
56
Windows [.28].
//
...
//
lastTick = currentTick;
//
Invalidate();
}
...
}
Ch03\Ex08 , ,
. Idle
Trace.WriteLine(delta), , Visual Studio
Output. , :
delta
delta
delta
delta
delta
delta
delta
delta
delta
delta
delta
=
=
=
=
=
=
=
=
=
=
=
0,078
0
0
0,016
0,015
0
0,016
0,015
0,016
0
0,016
delta,
, .
Idle 15-16 ,
. , -
. MSDN.
Environment.TickCount Win32 GeTickCount, 10
. , 10
Environment.TickCount , .
3.3.2. Stopwatch.
Environment.TickCount
, Microsoft .NET Framework 2.0
System.Diagnostics.Stopwatch, .
.
Stopwatch Start.
ElapsedMilliseconds ,
. , Stop.
Stopwatch Frequency,
,
Stopwatch
, 1 . Frequency
1.870.000.0000, 1/18700000000 = 510-10 .
ElapsedMilliseconds 1
, Stopwatch ElapsedTicks,
. ElapsedTicks
Stopwatch.Frequency. ,
, , ,
, ..,
Stopwatch .
, Stopwatch 3.20.
3.20.
// Examples\Ch03\Ex09
public partial class MainForm : Form
{
//
Stopwatch stopwatch;
// ,
// Idle
long lastTime;
private void MainForm_Load(object sender, EventArgs e)
{
...
//
stopwatch = new Stopwatch();
stopwatch.Start();
lastTime = 0;
// Output
Trace.WriteLine("Accuracy = " + 1.0 / Stopwatch.Frequency + " sec");
Application.Idle += new EventHandler(Application_Idle);
}
void Application_Idle(object sender, EventArgs e)
{
// , .
if (closing)
{
Close();
return;
}
// ,
double currentTime = (double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency;
// ( ), Idle
float delta = (float)(currentTick - lastTick);
//
posX += speedX * delta;
posY += speedY * delta;
//
...
//
lastTime = currentTime;
//
Invalidate();
}
...
}
, , Output .
Output :
Accuracy = 5,3475935828877E-10 sec
delta
delta
delta
delta
delta
delta
delta
delta
delta
delta
delta
=
=
=
=
=
=
=
=
=
=
=
0,035
0,006
0,003
0,002
0,011
0,012
0,012
0,012
0,011
0,013
0,011
,
JIT- Paint.
- - . ,
:
Accuracy = 5,3475935828877E-10 sec
delta = 0,035
delta = 0,022
delta = 0,013
delta = 0,032
delta = 0,015
delta = 0,032
delta = 0,014
delta = 0,032
delta = 0,016
delta = 0,032
delta = 0,014
delta = 0,016
delta = 0,019
, .
3.3.3 .
, CRT- ,
, .
57,
.
, , .
, ,
, ,
. ,
.
XNA Framework
.
PresentationInterval PresentationParameters:
public PresentInterval PresentationInterval { get; set; }
PresentationInterval
PresentInterval:
PresentInterval.Default , PresentInterval.One.
PresentInterval.One
.
57
1 . [.13].
PresentInterval.Immediate , .
PresentInterval.Default PresentInterval.One -,
. PresentInterval.Default
Windows, , ,
. - Windows
, ,
( 3.3.2). , ,
.
PresentInterval.Default, PresentInterval.One ,
. ,
:
, ,
.
, .
,
-
.
, ,
.
( 3.2.3)
(vsynchCheckBox), PresentInterval.One,
PresentInterval.Immediate ( 3.12).
PresentationInterval
Microsoft.Xna.Framework.Graphics.PresentInterval,
( 3.21).
3.12. .
3.21.
// CD- Examples\Ch03\Ex10
//
public partial class MainForm : Form
{
void InitGraphivsDevice()
{
...
presentParams = new PresentationParameters();
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.IsFullScreen = settings.FullScreen;
//
presentParams.PresentationInterval = settings.PresentationInterval;
...
}
...
}
//
public partial class SettingsForm : Form
{
//
internal SettingsForm(Properties.Settings settings, GraphicsAdapter adapter)
{
...
//
if (settings.PresentationInterval == PresentInterval.One)
vsynchCheckBox.Checked = true;
else
vsynchCheckBox.Checked = false;
}
// Ok
private void okButton_Click(object sender, EventArgs e)
{
...
//
if (vsynchCheckBox.Checked)
settings.PresentationInterval = PresentInterval.One;
else
settings.PresentationInterval = PresentInterval.Immediate;
...
}
}
,
Output.
1.0/{ }.
1 , 1000 fps.
.
:
List<int> numbers = new List<int>(3);
...
int s = 0;
// enumerator
IEnumerator enumerator = numbers.GetEnumerator();
//
while (enumerator.MoveNext())
//
s += (int)enumerator.Current;
, . . , GetEnumerator :
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection,
IEnumerable
{
public Enumerator<T> GetEnumerator()
{
return new Enumerator<T>((List<T>) this);
}
...
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
private List<T> list;
private int index;
private int version;
private T current;
internal Enumerator(List<T> list);
public void Dispose();
public bool MoveNext();
public T Current { get; }
object IEnumerator.Current { get; }
void IEnumerator.Reset();
}
}
, GetEnumerator
. -, C# MoveNext
Current Enumerator IEnumerator,
(boxing) Enumerator . , ,
(inline) MoveNext Current ,
. List
foreach for ,
.
. ,
GetEnumerator , .
:
43. foreach
enumerator, , , ,
.
44. MoveNext ,
, .
, ,
enumerator, foreach.
Passes Effect.
EffectPassCollection, :
. EffectPassCollection
List. this.pPass.GetEnumerator
Enumerator List, .
, - IEnumerator
IEnumerator<EffectPass>,
. ,
Paint , 10.000.000 for
foreach ( 3.22).
3.22.
// Examples\Ch03\Ex11
#define TEST
#if TEST
bool testing = true;
#endif
private void MainForm_Paint(object sender, PaintEventArgs e)
{
// TEST
#if TEST
//
if (testing)
{
//
const int n = 10000000;
int sum;
// ,
Trace.WriteLine("Gen 0 collection count: " + GC.CollectionCount(0));
Stopwatch timer = new Stopwatch();
//
timer.Start();
// passes
sum = 0;
EffectPassCollection passes = effect.CurrentTechnique.Passes;
// n
for (int i = 0; i < n; i++)
// passes for
for (int j = 0; j < passes.Count; j++)
sum += (int)passes[j].Name[0];
// ,
double time1 = (double)timer.ElapsedTicks / (double)Stopwatch.Frequency;
//
Trace.WriteLine("-----------for------------");
Trace.WriteLine("Sum : " + sum.ToString());
Trace.WriteLine("Gen 0 collection count: " + GC.CollectionCount(0));
Trace.WriteLine("Time1 : " + time1);
Trace.WriteLine("");
//
timer.Reset();
timer.Start();
sum = 0;
// , foreach
for (int i = 0; i < n; i++)
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
sum += (int)pass.Name[0];
// ,
double time2 = (double)timer.ElapsedTicks / (double)Stopwatch.Frequency;
//
Trace.WriteLine("---------foreach----------");
Trace.WriteLine("Sum : " + sum.ToString());
Trace.WriteLine("Gen 0 collection count: " + GC.CollectionCount(0));
Trace.WriteLine("Time2 : " + time2);
//
Trace.WriteLine("Time2 / Time1 = " + time2 / time1);
Trace.WriteLine("");
testing = false;
}
#endif
}
, , .
Intel Core2 Due E6300 foreach
229 . ,
foreach Paint, ,
. ,
,
.
Microsoft ,
0 1 . , foreach,
, (1.84
0.55) / 915 = 0.0014 . ,
,
. [.27], [.14] [.15].
foreach,
Examples\Ch03\Ex11.
3.3.5.
.
, - . ,
. , ,
, , -
, -
.
,
.
. , ,
.
, ,
.
, ,
.
(
..). ,
.
.
. :
, , 0.005 .
Idle ( 3.23).
3.23.
// ( ),
const float timeStep = 0.005f;
// Idle ( )
const float maxDelta = 5.0f;
void Application_Idle(object sender, EventArgs e)
{
...
//
double currentTime = (double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency;
// Idle maxDelta, lastTime
// Idle
if (currentTime - lastTime > maxDelta)
lastTime = currentTime - maxDelta;
// timeStep
while (lastTime + timeStep < currentTime)
{
posX += speedX * timeStep;
posY += speedY * timeStep;
...
lastTime += timeStep;
}
Invalidate();
}
.
,
5 ( maxDelta).
,
.
,
.
maxDelta 0.2 - 0.5 .
3.4. .
, , .. , ,
() .
,
( , ).
,
. , .
, ,
, , , . ,
0.2,
20% 80% .
, .
:
c cs cd (1 )
(3.1)
cs
cd
, 0 , 1 .
3.4.1. .
.
, ,
, .
,
ROP59,
( 3.13).
ROP
3.13. ROP.
ROP . ,
G70 24 16 ROP.
, ROP
.
ROP
. ROP
:
d op(b s, c d )
(3.2)
d [d r , d g , db , d a ]
op (. 3.5)
s
[ sr , sg , sb , sa ]
[d r , d g , d b , d a ]
b, [br , bg , bb , ba ]
[cr , cg , cb , ca ]
ROP
,
(FSAA Full Scene Anti Aliasing) ..
RenderState
GraphicsDevice. true
AlphaBlendEnable.
public bool AlphaBlendEnable { get; set; }
,
BlendFunction ( 3.5)
RenderState.BlendFunction.
public BlendFunction BlendFunction { get; set; }
3.5. BlendFunction.
Add ( )
Subtract
(
) ( ).
ReverseSubtract
(
) ( ).
59
Max
Min
,
Blend ( 3.6). b
RenderState.SourceBlend, c RenderState.DestinationBlend:
public Blend SourceBlend { get; set; }
public Blend DestinationBlend { get; set; }
3.6. Blend.
BlendFactor
RenderState.BlendFactor.
InverseBlendFactor
(1,
1,
1,
1)
RenderState.BlendFactor.
Zero
(0, 0, 0, 0).
One
(1, 1, 1, 1).
SourceColor
[ sr , sg , sb , sa ] .
InverseSourceColor
[1 sr ,1 sg ,1 sb ,1 sa ] .
SourceAlpha
InverseSourceAlpha
[sa , sa , sa , sa ] .
[1 sa ,1 sa ,1 sa ,1 sa ] .
DestinationColor
InverseDestinationColor
[d r , d g , d b , d a ] .
[1 d r ,1 d g ,1 db ,1 d a ] .
DestinationAlpha
InverseDestinationAlpha
[d a , d a , d a , d a ] .
[1 d a ,1 d a ,1 d a ,1 d a ] .
SourceAlphaSaturation
[ f , f , f ,1] ,
f min( sa , d a ) .
, .
,
:
d r (1 sr ) sr sa d r
d g (1 sg ) sg sa d g
db (1 sb ) sb sa db
(3.3)
,
. , SurfaceFormat.Bgr565 SurfaceFormat.Bgr32
.
,
. sr , s g , sb ,
d r , d g , db ,
BlendFunction.Subtract.
.
sr , s g , sb 3.6
, Blend.InverseSourceColor.
d r , d g , db
sa , Blend.SourceAlpha.
, ROP 3.3
:
device.RenderState.AlphaBlendEnable = true;
device.RenderState.BlendFunction = BlendFunction.Subtract;
device.RenderState.SourceBlend = Blend.InverseSourceColor
device.RenderState.DestinationBlend = Blend.SourceAlpha;
XNA Framework
, RGB Alpha
.
RenderState.SeparateAlphaBlendEnabled true,
RenderState.BlendFunction, RenderState.SourceBlend RenderState.DestinationBlend
R, G B . -
: RenderState.AlphaBlendOperation, RenderState.AlphaSourceBlend,
RenderState.AlphaDestinationBlend. ,
.
3.4.2.
.
, 3.1
ROP XNA Framework. ,
,
RenderState.BlendFactor.
.
3.1 ,
XNA Framework:
// (0 , 255 ).
// RenderState.BlendFactor
// 0..1 255.
const byte opacity = 50;
//
device.RenderState.AlphaBlendEnable = true;
//
device.RenderState.BlendFunction = BlendFunction.Add;
// opacity ( opacity / 255)
device.RenderState.BlendFactor = new XnaGraphics.Color(opacity, opacity, opacity, 0);
// , , opacity / 255
device.RenderState.SourceBlend = Blend.BlendFactor;
// , , 1 - opacity / 255
device.RenderState.DestinationBlend = Blend.InverseBlendFactor;
3.1 (Examples\Ch03\Ex02) ( 3.14).
(TrackBar) ,
3.7.
3.14. , .
3.7. .
TrackBar
Name
opacityTrackBar
Minimum
Maximum
255
TickFrequency
Label
Name
opacityLabel
Label
Text
Scroll
Paint ( 3.24). CD
Examples\Ch03\Ex13.
3.24.
private void opacityTrackBar_Scroll(object sender, EventArgs e)
{
//
opacityLabel.Text = ((float)opacityTrackBar.Value / 255.0f).ToString("0.00");
// xnaPanel
xnaPanel.Invalidate();
}
3.4.3. .
, ,
x sin(2 )
y cos(3 )
x , y
, 0 360 (02)
.
, :
, 0, 360. ,
( 3.15).
,
RenderState.BlendFactor .
- ,
:
device.RenderState.AlphaBlendEnable = true;
device.RenderState.BlendFunction = BlendFunction.Add;
device.RenderState.SourceBlend = Blend.SourceAlpha;
device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
2.5. Idle
Load Paint ( 3.25).
3.15. .
3.25.
// Examples\Ch03\Ex14
public partial class MainForm : Form
{
//
const int QuadStrips = 200;
//
const int TriStrips = QuadStrips * 2;
...
//
VertexPositionColor[] vertices = null;
//
Stopwatch stopwatch = null;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
//
vertices = new VertexPositionColor[TriStrips + 2];
//
for (int i = 0; i <= QuadStrips; i++)
{
//
float angle = 2.0f * (float)Math.PI * (float)i / (float)QuadStrips;
//
float cos = (float)Math.Cos(angle);
float x = 0.85f * (float)Math.Sin(2 * angle);
// ,
// .
Application.Idle -= new EventHandler(Application_Idle);
//
stopwatch.Stop();
}
//
Invalidate();
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
device.RenderState.CullMode = CullMode.None;
device.RenderState.FillMode = fillMode;
//
device.RenderState.AlphaBlendEnable = true;
device.RenderState.BlendFunction = BlendFunction.Add;
device.RenderState.SourceBlend = Blend.SourceAlpha;
device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
device.VertexDeclaration = decl;
//
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleStrip, vertices, 0,
vertices.Length - 2);
pass.End();
}
effect.End();
device.Present();
}
}
Windows Forms,
, Win32.
.
4.
,
XNA
(ScreenSaver), :
, ( 4.1).
? , Windows
.
:
,
, , 60.
,
.
4.1. .
exe- .scr.
, Windows ,
4.1. C++
Scrnsave.lib ( Scrnsavw.lib),
, ..
WM_PAINT
.
, Win32 API
.
60
, Norton Commander
.
4.1.
/s
/c{:n}
. n
Display Properties.
/p {n}
n.
4.1. .
, .
. Windows Forms,
New Project Create directory for solution (
). ,
,
. Firework (Project | Add Class).
Firework (,
). , Firework,
, Firework
FireworkException .
4.1.
class FireworkException : Exception
{
public FireworkException(string message) : base(message) { }
}
Firework .
? .scr,
fx- . Visual Studio
fx- exe-.
ColorFill.fx, , Build Action
Embedded Resource ( 4.2).
61
,
.
4.2. fx- .
Firework 4.2.
4.2.
// CD Examples\Ch04\Ex01
class Firework : IDisposable
{
//
const string effectFileName = "GSP.XNA.Book.Ch04.Ex01.Data.ColorFill.fx";
//
const int slices = 64;
// ( )
public const float diskSpeed = 3.0f;
//
public const float diskRadius = 0.015f;
//
float diskAngle = 0;
// ,
...
//
//
//
//
. :
hWnd .
scintillaSize ( )
scintillaInterval ( )
public Firework(IntPtr hWnd, float scintillaSize, float scintillaInterval)
{
//
this.hWnd = hWnd;
presentParams = new PresentationParameters();
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.PresentationInterval = PresentInterval.One;
try
{
GraphicsDeviceCapabilities caps =
GraphicsAdapter.DefaultAdapter.GetCapabilities(DeviceType.Hardware);
CreateOptions options = CreateOptions.SingleThreaded;
if (caps.DeviceCapabilities.SupportsHardwareTransformAndLight)
options |= CreateOptions.HardwareVertexProcessing;
else
options |= CreateOptions.SoftwareVertexProcessing;
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
hWnd, options, presentParams);
}
// Display
// Properties
catch (DeviceNotSupportedException)
{
//
//
throw new FireworkException(" Direct3D");
}
, , Firework (
4.3).
4.3.
public partial class FullscreenForm : Form
{
Firework firework = null;
public FullscreenForm()
{
InitializeComponent();
}
.
FormBorderStyle None, WindowState Maximized.
,
.
4.2. .
, .
, ,
.
.
,
, .
, Firework ( 4.4).
4.4.
class Scintilla
{
//
const float StartTime = 6.0f;
//
const float MinSpeed = 0.3f;
const float MaxSpeed = 0.45f;
//
const float tSlowing = 0.105f;
//
const float rSlowing = 0.25f;
//
public Color color;
// (..
// )
public float angle;
public float distance;
//
public float time;
//
public float tSpeed;
//
public float rSpeed;
//
public VertexPositionColor Vertex
{
get
{
VertexPositionColor vertex;
//
vertex.Position.X = distance * (float)Math.Sin(angle);
vertex.Position.Y = distance * (float)Math.Cos(angle);
vertex.Position.Z = 0;
//
vertex.Color = new Color(color.R, color.G, color.B, (byte)(255f * time /
StartTime));
return vertex;
}
}
// . diskAngle ,
//
public void Init(float diskAngle)
{
// (
// ). rnd Firework
distance = (float)rnd.NextDouble() * Firework.diskRadius;
//
angle = (float)Firework.rnd.NextDouble() * 2.0f * (float)Math.PI;
//
tSpeed = MinSpeed + (float)Firework.rnd.NextDouble() * (MaxSpeed - MinSpeed);
// 4
rSpeed = Firework.diskSpeed / 4.0f;
// ( )
byte red = (byte)(255 * Math.Abs(Math.Sin((angle - diskAngle) * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos((angle - diskAngle) * 2)));
color = new Color(red, green, 128, 255);
//
time = StartTime;
}
// . delta ,
// Update
public void Update(float delta)
{
//
if (time > 0.0f)
{
//
time = time - delta;
//
tSpeed = Math.Max(tSpeed - tSlowing * delta, 0.0f);
rSpeed = Math.Max(rSpeed - rSlowing * delta, 0.0f);
//
distance += tSpeed * delta;
angle += rSpeed * delta;
}
}
}
:
.
, 5 ( ,
).
, .
, List :
45. .
46. DrawUserPrimitives .
List ToArray() ,
, ,
.
.
,
, .
,
. 4.5
Firework .
4.5.
class Firework : IDisposable
{
...
// ,
const float timeStep = 0.005f;
// Update 1 .
//
const float maxDelta = 1.0f;
// , (5
// )
int maxScintillaCount;
//
const float scintillaProbability = 0.3f;
//
float scintillaSize;
...
// ,
double lastTime = 0;
//
List<Scintilla> scintillas;
//
VertexPositionColor[] scintillasVertices = null;
// ,
int scintillasVertexount = 0;
// , Firework Scintilla
public static Random rnd = new Random();
//
public Firework(IntPtr hWnd, float scintillaSize, float scintillaInterval)
{
this.hWnd = hWnd;
//
this.scintillaSize = scintillaSize;
this.maxScintillaCount = maxScintillaCount;
...
//
scintillas = new List<Scintilla>(16);
//
scintillasVertices = new VertexPositionColor[16];
...
}
//
public void Update()
{
double currentTime = (float)stopwatch.ElapsedTicks / (float)Stopwatch.Frequency;
// maxDelta
if (currentTime - lastTime > maxDelta)
lastTime = currentTime - maxDelta;
// timeStep,
int stepCount = (int)Math.Floor((currentTime - lastTime) / timeStep);
// Update,
float delta = stepCount * timeStep;
//
diskAngle += diskSpeed * delta;
//
...
//
for (int i = 0; i < stepCount; i++)
{
lastTime += timeStep;
//
scintillasVertexount = 0;
// ,
int scintillaCount = rnd.Next(maxScintillaCount + 1);
//
for (int j = 0; j < scintillas.Count; j++)
{
//
scintillas[j].Update(delta);
//
if (scintillas[j].time > 0)
{
//
scintillasVertexount++;
}
else
//
{
//
while (scintillaCount > 0)
{
// ,
scintillaCount--;
// scintillaProbability
if ((Firework.rnd.NextDouble() < scintillaProbability))
{
//
scintillas[j].Init(diskAngle);
//
scintillasVertexount++;
break;
}
}
}
}
//
while (scintillaCount > 0)
{
scintillaCount--;
if ((Firework.rnd.NextDouble() < scintillaProbability))
{
//
scintillas.Add(new Scintilla());
scintillas[scintillas.Count - 1].Init(diskAngle);
scintillasVertexount++;
}
}
}
//
if (scintillasVertexount > scintillasVertices.Length)
{
// . ,
// ( )
scintillasVertices = new VertexPositionColor[Math.Max(scintillasVertexount,
scintillasVertices.Length * 2)];
}
//
int k = 0;
for (int i = 0; i < scintillas.Count; i++)
//
if (scintillas[i].time > 0)
{
scintillasVertices[k] = scintillas[i].Vertex;
k++;
}
}
//
public void Paint()
{
...
device.RenderState.CullMode = CullMode.None;
//
device.RenderState.AlphaBlendEnable = true;
device.RenderState.BlendFunction = BlendFunction.Add;
device.RenderState.SourceBlend = Blend.SourceAlpha;
device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
// ()
device.RenderState.PointSize = scintillaSize;
...
//
if (scintillasVertexount > 0)
{
device.DrawUserPrimitives(PrimitiveType.PointList, scintillasVertices,
0, scintillasVertexount);
}
//
device.DrawUserPrimitives(PrimitiveType.TriangleFan, diskVertices, 0,
diskVertices.Length - 2);
...
}
Load :
private void FullscreenForm_Load(object sender, EventArgs e)
{
...
// , 5
firework = new Firework(Handle, 3.0f, 10f);
...
}
CD Examples\Ch04\Ex02.
4.3. .
, . ,
.
( 4.6).
4.6.
private void FullscreenForm_KeyDown(object sender, KeyEventArgs e)
{
Close();
}
. . ,
-
.
,
10 ( 4.7).
4.7.
public partial class FullscreenForm : Form
{
// , true MouseMove
bool isMouseActive = false;
// MouseMove
System.Drawing.Point mouseLocation;
...
// MouseDown,
private void FullscreenForm_MouseDown(object sender, MouseEventArgs e)
{
Close();
}
// MouseMove
private void FullscreenForm_MouseMove(object sender, MouseEventArgs e)
{
// MouseMove
if (!isMouseActive)
{
isMouseActive = true;
//
mouseLocation = e.Location;
}
else
{
// X Y
// , 10
if ((Math.Abs(e.Location.X - mouseLocation.X) > 10) ||
(Math.Abs(e.Location.Y - mouseLocation.Y) > 10))
{
//
Close();
}
}
}
}
(, Internet Explorer ).
, . ,
, , , ,
( 4.8).
4.8.
// Deactivate ,
//
private void FullscreenForm_Deactivate(object sender, EventArgs e)
{
Close();
}
,
Hide Cursor:
4.9.
private void FullscreenForm_Load(object sender, EventArgs e)
{
Cursor.Hide();
...
}
,
/s. ,
Main Program ( 4.10).
Visual Studio /s, Command line
arguments Debug .
4.10.
static class Program
{
[STAThread]
static void Main()
{
//
string[] args = Environment.GetCommandLineArgs();
// "/S"
if ((args.Length == 2) && (args[1].ToUpper() == "/S"))
{
//
Application.Run(new FullscreenForm());
return;
}
// "/S",
return;
}
}
.scr.
,
. Build Events Post-build event
command line ( 4.3):
copy "$(TargetFileName)" "*.scr"
.scr-
( 4.4). ,
:
Test /s.
Configure () .
Install () Screen Saver Display Properties
.
, . ,
,
( ) Display Properties
. ,
. , .
4.4. .
4.4. .
,
. , .
.
, ,
.
Main.
AllScreens Screen.
( 4.11).
4.11.
static void Main()
{
string[] args = Environment.GetCommandLineArgs();
if ((args.Length == 2) && (args[1].ToUpper() == "/S"))
{
//
foreach (Screen screen in Screen.AllScreens)
{
//
FullscreenForm form = new FullscreenForm(screen);
//
form.Show();
}
// .
// Idle, .
Application.Run();
return;
}
return;
}
, , ,
, .
Load ( 4.12).
4.12.
Screen screen = null;
public FullscreenForm(Screen screen)
{
this.screen = screen;
InitializeComponent();
}
private void FullscreenForm_Load(object sender, EventArgs e)
{
//
// ! Bounds ,
// (.. WindowsState Maximized)
Bounds = screen.Bounds;
...
}
.
, Close
. , Close .
Application.Exit.
Application.Exit
FormClosed.
FormClosing, Application.Exit.
Deactivate: ,
- (
).
Deactivate.
4.13.
4.13.
// FormClosing
private void FullscreenForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (firework != null)
{
firework.Dispose();
firework = null;
}
}
private void FullscreenForm_Deactivate(object sender, EventArgs e)
{
// , Deactivate
if (Application.MessageLoop)
Application.Exit();
}
private void FullscreenForm_MouseDown(object sender, MouseEventArgs e)
{
// Application.Exit (
// Form.Close)
Application.Exit();
}
...
CD Examples\Ch04\Ex04.
4.5. .
.
: ,
, 5 .
,
. :
, 0 ( )
9 ( ), , 5 ,
.
, (Properties
( 4.5):
scintillaSize . 2
scintillaDensity . 5.
4.5. .
Setting)
Load ,
( 4.14).
4.14.
public partial class FullscreenForm : Form
{
Properties.Settings settings;
private void FullscreenForm_Load(object sender, EventArgs e)
{
...
// (
// )
settings = new Properties.Settings();
try
{
// , 5 ,
firework = new Firework(Handle, (float)settings.scintillaSize,
(settings.scintillaDensity + 1) * 5);
}
...
}
4.6 4.2.
4.6. .
4.2. .
SettingsForm
( )
Name
SettingsForm
Text
ShowInTaskbar
false
TopMost
true
MinimizeBox
false
MaximizeBox
false
GroupBox
Text
Label
Text
TrackBar
Name
scintillaSizeTrackBar
Minimum
Maximum
Label
Text
TrackBar
Name
scintillaDensityTrackBar
Minimum
Maximum
Name
okButton
Text
Ok
Name
cancelButton
Text
Button
Button
scintillaSizeTrackBar scintillaDensityTrackBar
scintillaSize scintillaDensity .
Application Settings | Value ( 4.7).
(
4.15).
4.15.
public partial class SettingsForm : Form
{
public SettingsForm()
{
InitializeComponent();
}
// Ok
private void okButton_Click(object sender, EventArgs e)
{
Properties.Settings settings = new Properties.Settings();
//
settings.scintillaSize = scintillaSizeTrackBar.Value;
settings.scintillaDensity = scintillaDensityTrackBar.Value;
//
settings.Save();
//
Close();
}
//
private void cancelButton_Click(object sender, EventArgs e)
{
// ,
Close();
}
}
, 3-
:
.
/C.
/C:n, n Display
Properties. , /C:299792.
, Main Program
:
4.16.
static void Main()
{
// /C
if ((args.Length == 1) || ((args.Length == 2) &&
(args[1].Length >= 2) && (args[1].ToUpper().Substring(0, 3) == "/C")))
{
//
Application.Run(new SettingsForm());
return;
}
}
, , :
( )
Display Properties. , ,
, .
//
center = true;
}
...
}
Main
/C:n ( 4.18).
4.18.
static void Main()
{
...
// ( , ,
// ) /C
if ((args.Length == 1) || ((args.Length >= 2) && args[1].ToUpper() == "/C"))
{
//
Application.Run(new SettingsForm());
return;
}
// /C:n
if ((args.Length == 2) && (args[1].Length > 3) && (args[1].ToUpper().Substring(0, 3) ==
"/C:"))
{
// IntPtr
IntPtr hWnd = (IntPtr)int.Parse(args[1].ToUpper().Substring(3, args[1].Length - 3));
// Display Properties
// hWnd
Application.Run(new SettingsForm(hWnd));
}
...
}
.
MSDN [.26] :
BOOL GetWindowRect(HWND hWnd, LPRECT lpRect);
hWnd ;
lpRect RECT,
.
.NET Framework 2.0 GetWindowRect,
RECT, .
.NET Framework, GetWindowRect RECT,
http://pinvoke.net. Win32 API ,
Win32 ( 4.19).
Win32,
(, x64 Xbox 360).
4.19.
// Win32 API, http://pinvoke.net
using System.Runtime.InteropServices;
, , Load
Display Properties ( 4.20).
4.20.
private void SettingsForm_Load(object sender, EventArgs e)
{
if (center)
{
// RECT
Win32.RECT rect = new Win32.RECT();
// Display Properties
Win32.GetWindowRect(parentHandle, out rect);
// Display Properties
int centerX = (rect.right + rect.left) / 2;
int centerY = (rect.bottom + rect.top) / 2;
// Display Properties
Left = centerX - Width / 2;
Top = centerY - Height / 2;
}
}
CD Examples\Ch04\Ex05.
4.6. .
.
( Screen Saver
Display Properties) .
Display Properties WM_PAINT,
, Display
Properties WM_CLOSE.
, .NET
Framework
Win32. , Win32 ( 4.21).
4.21.
public static class Win32
{
...
// .
public delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
// WNDCLASSEX,
[StructLayout(LayoutKind.Sequential)]
public struct WNDCLASSEX
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public uint style;
public WndProc lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
public string lpszMenuName;
public string lpszClassName;
public IntPtr hIconSm;
}
//
[Flags]
public enum WindowStyles : uint
{
//
WS_CHILD = 0x40000000,
//
WS_VISIBLE = 0x10000000,
//
WS_DISABLED = 0x08000000,
...
}
//
[Flags]
public enum ClassStyles : uint
{
//
CS_PARENTDC = 0x0080,
...
}
// Windows
public enum WindowsMessages : uint
{
WM_CLOSE = 0x10,
WM_DESTROY = 0x2,
WM_PAINT = 0xF,
...
}
//
[DllImport("user32")]
public static extern short RegisterClassEx([In] ref WNDCLASSEX lpwcx);
//
[DllImport("user32.dll")]
public static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName,
string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight,
IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
//
[DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
//
[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr hWnd);
// WM_QUIT,
[DllImport("user32.dll")]
public static extern void PostQuitMessage(int nExitCode);
//
[DllImport("user32.dll")]
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr
lParam);
...
}
Main /P, :
47. .
48. .
49. .
50. Firework.
51. .
, , 4.22.
4.22.
static void Main()
{
...
// /P n
if ((args.Length == 3) && (args[1].ToUpper() == "/P"))
{
//
IntPtr parentHandle = (IntPtr)uint.Parse(args[2]);
//
Win32.RECT rect;
Win32.GetClientRect(parentHandle, out rect);
//
Win32.WNDCLASSEX wndClassEx = new Win32.WNDCLASSEX();
wndClassEx.cbSize = Marshal.SizeOf(wndClassEx);
wndClassEx.style = (uint)Win32.ClassStyles.CS_PARENTDC;
// (. 4.23).
wndClassEx.lpfnWndProc = new Win32.WndProc(WindowProc);
wndClassEx.cbClsExtra = 0;
wndClassEx.cbWndExtra = 0;
wndClassEx.hIcon = IntPtr.Zero;
wndClassEx.hIconSm = IntPtr.Zero;
wndClassEx.hCursor = IntPtr.Zero;
wndClassEx.hbrBackground = IntPtr.Zero;
wndClassEx.lpszMenuName = null;
wndClassEx.lpszClassName = "XNASCREENSAVER";
wndClassEx.hInstance = Marshal.GetHINSTANCE(typeof(Program).Module);
//
if (Win32.RegisterClassEx(ref wndClassEx) == 0)
return;
//
displayHandle = Win32.CreateWindowEx(0, "XNASCREENSAVER", "XNAScreenSaver",
(uint)(Win32.WindowStyles.WS_CHILD | Win32.WindowStyles.WS_VISIBLE |
Win32.WindowStyles.WS_DISABLED), 0, 0, rect.Width, rect.Height, parentHandle,
IntPtr.Zero, Marshal.GetHINSTANCE(typeof(Program).Module), IntPtr.Zero);
try
{
// Firework .
// ,
// .
firework = new Firework(displayHandle, 1.0f, 5);
}
catch (FireworkException ex)
{
MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
// .
Application.Run();
return;
}
return;
}
}
( 4.23):
WM_PAINT .
WM_CLOSE .
WM_DESTROY .
4.23.
//
public static IntPtr WindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
{
switch (uMsg)
{
// WM_PAINT
case (uint)Win32.WindowsMessages.WM_PAINT:
if (firework != null)
{
//
firework.Update();
//
firework.Paint();
}
return IntPtr.Zero;
// WM_CLOSE
case (uint)Win32.WindowsMessages.WM_CLOSE:
if (firework != null)
{
//
firework.Dispose();
firework = null;
}
//
Win32.DestroyWindow(displayHandle);
return IntPtr.Zero;
// WM_DESTROY
case (uint)Win32.WindowsMessages.WM_DESTROY:
//
Win32.PostQuitMessage(0);
return IntPtr.Zero;
default:
return Win32.DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
. ,
( 4.9).
4.9. .
4.7. .
. ,
,
. ,
. , , Visual Studio 2005.
.
, ( Add | New Project | Other Project Types |
Setup and Deployment | Setup Project). ProductName Manufacture
, , ,
Add or Remove Programs.
4.10. .
, , Windows Installer
, Windows
2000 .
,
. ,
Windows Installer, ,
(, Nullsoft Scriptable Install System). Internet
500 .
Windows
.
, , Program
Files. Windows File System (Setup)
Application
Folder
Default
Location
, , Exclude true,
,
.NET Framework 2.0 DirectX, Microsoft
XNA Framework.
4.11. , .
SCRNSAVE.EXE
HKEY_CURRENT_USER\Control Panel\Desktop. ,
.
Solution
View | Registry.
. HKEY_CURRENT_USER Control
Panel ( New | Key), Desktop. Desktop
SCRNSAVE.EXE ( New | String Value)
[TARGETDIR]mysaver.scr ( 4.12),
[TARGETDIR] , , (
\Windows).
mysaver.scr .
4.12. .
, SCRNSAVE.EXE
( Windows XP Service Pack 2). ,
, Windows 3.x, .
, 100%
. Windows
, .
desk.cpl,
Display Properties. ,
, Display
Properties. InstallScreenSaver .
rundll32:
rundll32.exe desk.cpl,InstallScreenSaver { }
, , Windows
rundll32, .
System;
System.Collections.Generic;
System.ComponentModel;
System.Configuration.Install;
namespace SetupCustomActions
{
// RunInstaller, true, ,
//
[RunInstaller(true)]
public partial class SetCurrentScrenSaver : Installer
{
public SetCurrentScrenSaver()
{
InitializeComponent();
}
}
}
// rundll32
Process.Start("rundll32.exe", "desk.cpl,InstallScreenSaver " +
Context.Parameters["ScreenSaver"]);
}
Context.Parameters,
, (
).
.
. Solution
(Setup) View | Custom Actions.
Custom Actions, ,
, , .. Install (,
) Add Custom Action.
, ,
Custom Actions.
Application Folder (, ).
Add Output, Project ,
Custom Actions ( , SetupCustomActions). ,
Primary output (,
) Ok ( 4.13).
4.14. , .
4.15. .
XNAFramework
\Microsoft
Visual
Studio
8\SDK\v2.0\BootStrapper\Packages\.
XNAFramework :
xnafx_redist.msi XNA Framework XNA Game Studio Express 1.0 ( \XNA Game
Studio Express\v1.0\Redist\XNA FX Redist).
product.xml , xnafx_redist.msi.
\En\package.xml
Prerequisite XNA Framework [.12].
, ( Build),
\Setup\Release ,
XNA Framework ?.
4.16. .
4.17. .
,
, ,
,
.
Windows Installer
, , .NET Framework 2.0 XNA Framework 1.0.
5.
, -
. ,
.
HLSL
.
,
.
HLSL, 2.3.
5.1. HLSL
,
HLSL.
5.1.1.
HLSL C.
+, -, *, /, %, ++, --, +=, -=, *=, /= %=.
, . C.
:
float4 a = {1, 2, 3, 4};
float4 b = {5, 6, 7, 8};
// . {1+5, 2+6, 3+7, 4+8} = {6, 8, 10, 12}
float4 c = a+b;
// . d {1*5, 2*6, 3*7, 4*8} = {5, 12, 21, 32}
float4 d = a*b;
,
:
float4 a = {1, 2, 3, 4};
// b {1*2, 2*2, 3*2, 4*2} = {2, 4, 6, 8}
float4 b = a*2;
32-
62. , float4 half4 double4
63.
5.1.2.
DirectX . -,
. ,
[]. ,
:
float4 color = float4(0.2, 0.7, 0.5, 1.0);
// avg 1.6
float avg = (color[0] + color[1] + color[2] + color[3])/4;
,
DirectX
. x r, y g,
62
.
(. 7.x).
63
int4 , HLSL
32-
(. 2.3.2).
z b, w a. , x, y, z, w
, r, g, b, a :
float avg = (color.r + color.g + color.b + color.a)/4;
.
, HLSL
. ,
.
() :
//
float4 a={1, 2, 3, 4};
// b a.
// b (1, 2)
float2 b=a.xy;
// c {1, 1, 2}
float3 c=a.xxy;
// x, y, z . a
// {3, 2, 1, 4}
a.xyz=a.zyx;
,
. . ,
HLSL a.rgzw,
, .
HLSL ,
. .
,
float a=3;
float4 v=float4(a, a, a, a);
:
float a=3;
//
float4 v=a.xxxx;
. HLSL :
=
. :
float a=3;
// v (3, 3, 3, 3)
float4 v=a;
5.1.3.
HLSL
: ,
. HLSL 4.
, .
HLSL . ,
, , 1 .
, . , b
1
a
b=1.0/sqrt(a), b=rsqrt(a).
GPU ( ), . ,
.
HLSL, , b=1.0/sqrt(a)
b=rsqrt(a). ,
.
5.1.4. -
, - :
l ( r g b) / 3
r l
g l
bl
(5.1)
r, g, b ,
. ,
- , -
. ,
PrimitiveType.TriangleStrip -
.
5.1 , -
. ,
56% 640x480, -
6404800.56=172000 . ,
172000/4=43000 (!), .
1280x960 .
,
.
- ( 5.1).
5.1.
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
output.color.b = luminance;
output.color.a = input.color.a;
return output;
}
float4 MainPS(float4 color:COLOR):COLOR
{
return color;
}
technique BlackAndWhiteFill
{
pass p0
{
VertexShader = compile vs_1_1 MainVS();
PixelShader = compile ps_1_1 MainPS();
}
}
5.1
, , .
,
( 5.2).
5.2.
VertexOutput MainVS(VertexInput input)
{
VertexOutput output;
output.pos = float4(input.pos, 1.0f);
// ,
output.color.rgb = (input.color.r+input.color.g+input.color.b)/3.0;
output.color.a = input.color.a;
return output;
}
, HLSL
5.1 r, g, b .
... ,
.
.
. (5.1):
1
1
1
l r g b
3
3
3
(5.2)
, ,
:
1 1 1
l ( , , ) ( r , g , b)
3 3 3
(5.3)
5.3
5.1.
. , 5.1 5.3
dot ( ),
( 5.3).
5.3.
VertexOutput MainVS(VertexInput input)
{
VertexOutput output;
output.pos = float4(input.pos, 1.0f);
// . dot
// (1/3.0, 1/3.0, 1/3.0)
output.color.rgb = dot(input.color.rgb, 1/3.0);
output.color.a = 1.0;
return output;
}
,
- ( 5.1).
, Load ( 5.4),
CD
Examples\Ch05\Ex01.
5.1. , - .
5.4.
public partial class MainForm : Form
{
// , -
const string effectFileName = "Data\\BlackAndWhiteFill.fx";
GraphicsDevice device = null;
PresentationParameters presentParams;
VertexDeclaration decl = null;
//
VertexPositionColor[] vertices = null;
Effect effect = null;
bool closing = false;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
//
...
decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);
vertices = new VertexPositionColor[4];
// .
// -
vertices[0] = new VertexPositionColor(new
XnaGraphics.Color.Green);
vertices[1] = new VertexPositionColor(new
XnaGraphics.Color.YellowGreen);
vertices[2] = new VertexPositionColor(new
XnaGraphics.Color.White);
vertices[3] = new VertexPositionColor(new
XnaGraphics.Color.GreenYellow);
,
Vector3(-0.75f, -0.75f, 0.0f),
Vector3(-0.75f, 0.75f, 0.0f),
Vector3(0.75f, -0.75f, 0.0f),
Vector3(0.75f, 0.75f, 0.0f),
//
...
}
// Paint, Resize, Closed ..
...
}
5.1
(5.1) , ,
. ,
, .
(NTSC) :
(5.4)
, - 5.4.
Ch05\Ex01.
CD Examples\Ch05\Ex02.
NVIDIA FX Composer 2.0 .NET. ,
FX Composer 2.0 .NET Reflector.
64
<profile_GLSL>
<include sid="Blinn" url="Data/Blinn.glsl"/>
</profile_GLSL>
<extra type="import">
<technique profile="NV_import">
<import url="Data/Blinn.fx" compiler_options="" profile="fx"/>
</technique>
</extra>
</effect>
</library_effects>
<library_materials>
<material id="BlinnMaterial" name="Blinn Material">
<instance_effect url="#BlinnEffect">
<!-- -->
</instance_effect>
</material>
</library_materials>
</COLLADA>
, <COLLADA>:
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
</COLLADA>
<COLLADA> , :
<library_images> ;
<library_effects> ;
<library_materials> ;
<library_cameras> ;
<library_lights> ;
<library_geometries> ;
..
<effect>, <library_effects>:
<library_effects>
<effect id="BlinnEffect" name="Blinn Effect">
</effect>
</library_effects>
id , name ,
FX Composer 2. COLLADA
API,
. :
API .
<profile_XXX>,
<effect>:
<profile_CG> Cg. platform
, : ,
"PC-OGL" , API OpenGL PC,
PS3 Playstation 3.
<profile_GLSL> GLSL.
<profile_GLES> API OpenGL ES67.
<profile_COMMON> - ,
(Standard Material) 3ds Max.
67
<profile> ,
: , ..
,
<profile> <code>.
,
HLSL. , (1.4.1) COLLADA
HLSL.
<extra>, FX Composer .fx :
<extra type="import">
<technique profile="NV_import">
<import url="Data/Blinn.fx" compiler_options="" profile="fx"/>
</technique>
</extra>
, fx.
COLLADA .
. ,
, .
68, , ,
, ..
, , , ,
. ,
.
<library_materials>
<material>.
<material>
<instance_effect>, url
<library_effects>,
<instance_effect>
.
<library_effects> <library_materials>
COLLADA, COLLADA FX. FX Composer
2 COLLADA FX,
COLLADA
. , FX Composer 2
COLLADA,
(
).
, .
COLLADA,
FX Composer 2.0.
68
5.4.
FX Composer 2.0 CD- \NVIDIA.
FX Composer http://developer.nvidia.com/ .
70
, ,
.
.
69
FX Composer 2 ,
User Guide Start Page, FX Composer.
1
3
6
5.2. FX Composer 2: 1 , 2 Start Page , 3 Materials, 4
Properties, 5 Render, 6 Animation.
5.4.
View Layouts, FX
Composer. ( Artist, Authoring, Default,
Turning), .
- ,
View | Layouts | Reset Layout.
5.2.3.
FX Composer 2.0 .
FX Composer - . FX Composer.
, , File
| New | New Project. Assets ( 5.4). , ,
COLLADA, 5.2.1.
, Effects Assets <library_effects>, Materials
<library_materials> ..
72
5.4. Assets.
Effects
Add Effect... .
( 5.5). HLSL,
HLSL FX. Effect Name (, BlackAndWhite).
, ,
, .
5.5. .
5.6. .
Effects. , Effects
BlackAndWhite, Collada,
BlackAndWhite.fx ( 5.7).
.fx ,
BlackAndWhite .cg .glsl.
5.7. Effects.
73
BlackAndWhite.fx. 5.1 .
73
, HLSL
.
HLSL, .
Ctrl + F7.
, Tasks ( 5.8),
.
, Output ( 5.9)
View | Output.
5.8. Task .
5.9. Output .
, .
, :
Project.fxcproj FX Composer IDE
. XML.
Document1.dae COLLADA .
BlackAndWhite.fx .
Document1.dae, FX Composer 2.0 , :
<?xml version="1.0"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<contributor>
<author>Sergei Gaidukov</author>
<authoring_tool>NVIDIA FX Composer 2.0</authoring_tool>
<comments/>
<copyright/>
</contributor>
<created>2007-06-04T16:39:20</created>
<keywords>FXComposer, NVIDIA</keywords>
<modified>2007-06-04T16:39:21</modified>
<subject/>
<title/>
</asset>
<library_effects>
<effect id="Effect" name="BlackAndWhite">
<profile_COMMON>
<technique sid="__fxc2_default">
<constant/>
</technique>
</profile_COMMON>
<extra type="import">
<technique profile="NV_import">
<import url="BlackAndWhite.fx" compiler_options="" profile="fx"/>
</technique>
</extra>
</effect>
</library_effects>
</COLLADA>
, <COLLADA> : <asset> ,
, ; <library_effects>.
Effect BlackAndWhite,
: HLSL74 COMMON.
COLLADA ,
COMMON.
.fx-.
FX Composer 2.0,
File | Open | Open Project... .
, .fx-? FX
Composer 2.0 COLLADA,
.fx- File | Open | Open File...
.fx- , , .
, :
.fx-. Assets, Effects,
Add Effect From File... , .
, ,
.
5.2.4. .
,
, .
Shader Perfomance,
NVIDIA .
BlackAndWhite, 5.2.3. Assets
, ,
Analyze Performance, Shader Performance (
5.10), : Startup Form BlackAndWihite.fx. ,
, ,
Analyze Performance.
74
COLLADA HLSL,
<extra>, .
BlackAndWhite.fx
(Analyze a Pass)
(Compare Passes).
, .
75.
p0.
: . BlackAndWhite.fx,
return, - ,
. , BlackAndWhite.fx
Drivers GPU, ForceWare ,
.
. Run
. Table,
5.10. ,
NVIDIA GeForce 7800 GTX ForceWare 162.03
7 ,
491.000.000 . ,
,
. ,
, .
Precision Branches
.
: BlackAndWhite.fx ,
32-.
Graph .
.
Tools | Settings... Settings
FX Composer Enviroment |
ShaderPerf. ... DefaultSelectedGPUs
Selected Default GPUs
( 5.11). ,
GeForce 6 , GPU NV4x G7x.
.
75
5.12. .
,
. , 100.000 . ,
,
GeForce6 (GeForce 6200) 150.000.000 / 100.000 = 1.500
.
GeForce6.
.
Shader
Performance
. ,
, .
, , .
HLSL
C++, . ,
,
.
, , ,
.
GeForce3 GeForce4,
-1 +1.
.
, HLSL,
ASM Editor BlackAndWhite_Asm.txt
:
################################################################
# Technique: BlackAndWhiteFill
# Pass: p0
################################################################
//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.12.589.0000
vs_1_1
def c0, 0.333333343, 1, 0, 0
dcl_position v0
dcl_color v1
add r0.w, v1.y, v1.x
add r0.w, r0.w, v1.z
mul oD0.xyz, r0.w, c0.x
mad oPos, v0.xyzx, c0.yyyz, c0.zzzy
mov oD0.w, v1.w
// approximately 5 instruction slots used
, Microsoft (R)
D3DX9 Shader Compiler 9.12.589.0000,
Vertex Shader 1.1. ,
Vertex Shader.
NVIDIA FX Composer 2.0 ,
.
5.3.1.
, SSE76
x86. ( )
, .
, 128- ,
, , 32- ( 5.13).
W
127
Z
95
Y
63
X
31
, (
5.14):
, (
, ..).
, .
,
.
5.14. .
,
1.1.
Vertex Shader 1.1 Pixel Shader 1.1
GeForce3 (NV20).
( 5.15):
16 v0, v1 v15 , (Input Registers).
96- c0, c1 c95 ... cN ,
(Constant Float Registers).
, 4
. 128 , ..
32- .
GPU. , GPU
- ,
32- .
v0, v1 v15 77, :
, , , ..
dcl_xxx, 5.1. HLSL
76
,
:
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
5.1. ,
HLSL
dcl_position
POSITION
dcl_color
COLOR
dcl_psize
PSIZE
78
dcl_texcoord
TEXCOORD
127
95
63
31
127
v0
c0
v1
c1
v2
c2
v3
c3
v4
c4
v5
c5
v6
c6
v7
c7
v8
c8
v9
c9
v10
c10
v11
c11
v12
c12
v13
c13
v14
c14
v15
c15
95
c16
...
63
31
...
c93
c94
c95
...
...
cN
5.15. .
, , .
def:
78
6.x.
,
c0 (0.333333343, 1, 0, 0).
def c0, 0.333333343, 1, 0, 0
- . ,
0.333333343
(input.color.r+input.color.g+input.color.b)/3.0.
, 1
:
output.pos = float4(input.pos, 1.0f);
5.2. GPU.
GPU
NV2x
96
NV3x
256
NV4x
256
G7x
256
R2xx
192
R3xx
256
R4xx
256
79
8192
8192
, , ,
(. 5.4).
,
. Vertex Shader 1.1
( 5.16):
12 r0, r1 r11
(Temporary Registers).
a0,
(Address Register).
79
127
95
63
31
r0
a0
r1
r2
r3
r4
r5
r6
r7
r8
r9
r10
r11
5.16. .
SSE x86,
- . ,
. ,
2, c5
c7.
c[a0.x + 5].
, ,
HP-11C.
: ,
.
, Vertex Shader 1.1
( 5.17):
oPos (Position Register).
oD0 oD1 (Color Registers). ,
oD0 , oD1 .
oT0, oT1, oT2, oT3, oT4, oT5, oT6, oT7
(Texture Coordinate Register). ,
.
oPts (Point Size Register).
(PrimitiveType.PointList).
oFog, (Fog Register).
oPos
oPts
oD1
oFog
oD2
oT0
oT1
oT2
oT3
oT4
oT5
oT6
oT7
5.17. .
oPos
POSITION
oD0
COLOR, COLOR0
oD1
COLOR1
oT0
TEXCOORD, TEXCOORD0
0T1
TEXCOORD1
oT2
TEXCOORD2
oT3
TEXCOORD3
oT4
TEXCOORD4
oT5
TEXCOORD5
oT6
TEXCOORD6
oT7
TEXCOORD7
oPts
PSIZE
oFog
FOG
, .
, .
,
HLSL, . ,
, .
5.3.2. .
, Vertex Shader 1.1.
x86,
Vertex Shader x86.
:
op dst, src0 [, src1] [, src2]
op .
dst , .
.
Vertex Shader 1.1
: 128. ,
,
.
,
.
MOV
,
x86:
mov dst, src
dst ;
src .
c2 r5:
mov r5, c2
Vertex Shader :
. ,
.
. ,
HLSL .
. , r5
c2 ,
:
mov r5.xyz, -c2.yxz
ADD
ADD :
add dst, src0, src1
dst , .
src0 .
src1 .
SUB
:
sub dst, src0, src1
, ,
.
, x y v2 z w v3
y z r1:
sub r1.yz, v2.xy, v3.zw
MUL
:
mul dst, src0, src1
c0 x c1
r0:
mov r0, c0, c1.xxxx
MAD
:
mad dst, src0, src1, src2
DP3
x, y, z :
dp3 dst, src0, src1
, r1
v0 r0:
dp3 r1, v0, r0
DP4
:
dp4 dst, src0, src1
r1
v0 r0:
dp4 r1.x, v0, r0
FRC {x}
:
frc dst, src0
dst = {src0}
, {2.3}=3, {- 2.3}=0.7
y xy - ( x
y ). xy r0
r1:
frc r0.xy, r1
frc , .
, .
,
Vertex Shader 1.1 frc
.
Vertex Shader 1.1,
frc,
.
RCP 1/x
:
rcp dst, src0
dst.xyzw=1/src0
, GPU ( 10 38).
GPU NVIDIA NV3x Floating-Point Specials: -Inf ( ),
+Inf ( ), NaN ( ) .. , NV3x
1.0/0.0 +Inf. Floating-Point Specials
[.16].
1/r1.w r0.w:
rcp r0.w, r1.w
EXPP 2x 2-3
2 2-3 :
expp dst, src0
dst , .
x , y
, z , w
src0 , 2. .
80:
dest.x
dest.y
dest.z
dest.w
80
=
=
=
=
2floor(src0)
src0 floor(src0)
2src
1
, , .
z 10 (2-3 ).
2r1.w r0.z.
.z.
rcp r0.z, r1.w
EXP 2x 6-7
2 21 (6-7 ):
expp dst, src0
dst.xyzw = 2src0
, 10 .
,
, expp.
2r1.x r0.y:
expp r0.y, r1.x
MIN
,
.
min dst, src0, src1
dst -, .
src0 src1 , .
:
dst = src0;
if (src0.x > src1.x)
dst.x=src1.x;
if (src0.y > src1.y)
dst.y=src1.y;
if (src0.z > src1.z)
dst.z=src1.z;
if (src0.w > src1.w)
dst.w=src1.w;
w r4 r0, x y
r3:
min r3.xy, r4.w, r0
MAX
,
.
max dst, src0, src1
dst -, .
src0 src1 , .
:
dst = src0;
if (src0.x > src1.x)
dst.x=src0.x;
if (src0.y > src1.y)
dst.y=src0.y;
r4 r2, r1:
max r1, r4, r2
SGE
1,
, 0 :
sge dst, src0, src1
dst , .
src0 src1 , .
:
dst.xyzw = 0;
if (src0.x >= src1.x)
dst.x = 1;
if (src0.y >= src1.y)
dst.y = 1;
if (src0.z >= src1.z)
dst.z = 1;
if (src0.w >= src1.w)
dst.w = 1;
SLT
1,
, 0 :
slt dst, src0, src1
dst , .
src0 src1 , .
:
dst.xyzw = 0;
if (src0.x< src1.x)
dst.x = 1;
if (src0.y < src1.y)
dst.y = 1;
if (src0.z < src1.z)
dst.z = 1;
if (src0.w < src1.w)
dst.w = 1;
,
.
DirectX.
Vertex Shader
DirectX (Start | All Programs | Microsoft DirectX SDK | DirectX Documentation | DirectX SDK
Documentation for C++) Index .
Vertex Shader Index
: vs_1_1, vs_2_0, vs_2_x vs_3_0.
5.3.3.
, .
BlackAndWhite.fx.
HLSL ,
, FX Composer 2.0. , :
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
:
vs_1_1
def c0, 0.333333343, 1, 0, 0
dcl_position v0
dcl_color v1
add r0.w, v1.y, v1.x
add r0.w, r0.w, v1.z
mul oD0.xyz, r0.w, c0.x
mad oPos, v0.xyzx, c0.yyyz, c0.zzzy
mov oD0.w, v1.w
Vertex Shader, .
4 c ,
Vertex Shader: vs_1_1, vs_2_0, vs_2_x vs_3_0.
, 1.1.
def, c0 (0.333333343, 1,
0, 0), .
.
dcl_position dcl_color ,
v0, v1.
.
w r0.
x c0, 0.333333343,
3. x, y, z
oD0. ,
HLSL:
output.color.rgb = (input.color.r+input.color.g+input.color.b)/3.0;
, HLSL luminance,
r, g, b .
.
. mad
. , HLSL- ? ? . madd
v0 c0,
oPos, .
, mad
c0:
oPos = v0.xyzx * c0.yyyz + c0.zzzy = v0.xyzx * (1, 1, 1, 0) + (0, 0, 0, 1) = (v0.xyz, 0) +
(0, 0, 0, 1)
, mad HLSL-:
output.pos = float4(input.pos, 1.0f);
, HLSL-:
mov oPos.xyz, v0.xyz
mov oPos.w, c0.y
mad.
, mov - oD0 , ..
output.color.a = input.color.a
5 , 5.2.4, GPU
NV4x G7x 7 . ,
. :
1. HLSL 3
. ,
HLSL dot.
2. , , - (alpha
blending). , -. , ,
- .
, .
, , 5.5:
5.5.
VertexOutput MainVS(VertexInput input)
{
VertexOutput output;
output.pos = float4(input.pos, 1.0f);
// - , ,
// a
output.color.rgba = dot(input.color.rgba, 1.0/3.0);
return output;
}
, FX Composer 2.0, :
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.12.589.0000
vs_1_1
def c0, 0.333333343, 1, 0, 0
dcl_position v0
dcl_color v1
dp4 oD0, v1, c0.x
mad oPos, v0.xyzx, c0.yyyz, c0.zzzy
// approximately 2 instruction slots used
, dp4, mov
- . ,
2.5
( 5 2 ). ( Run
Shader Perfomance) ,
7 3- , 2.3 . GeForce 7800 GTX
1 491.000.000 ,
1.146.000.000 .
5.4.
, ,
, .
, [0..1] ,
. 1,
, 0 , 0..1
.
:
cr = kr or
cg = kg og
cb = kb ob
cr, cg, cb ;
or, og, ob ;
kr, kg, kb .
:
VertexOutput MainVS(VertexInput input)
{
VertexOutput output;
output.pos = float4(input.pos, 1.0f);
//
const float4 filter = float4(0.2, 0.8, 0.5, 1.0);
// ,
output.color = input.color * filter;
(5.4)
return output;
}
. ,
? ,
, filter .
: GPU ,
. ,
.
HLSL
. :
uniform, ,
. , filter,
:
uniform float4 circleColor;
,
. :
uniform float4 circleColor = float4(0.5, 1.0, 0.8, 1.0);
, uniform ,
uniform-. uniform
static, . :
// circleColor
static float4 circleColor=float4(0.5, 1.0, 0.8, 1.0);
static .
, C# :
.
static .
, .
, , .
( 5.6).
5.6.
//
float4 filter;
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
return output;
}
float4 MainPS(float4 color:COLOR):COLOR
{
return color;
}
technique FilterFill
{
pass p0
{
VertexShader = compile vs_1_1 MainVS();
PixelShader = compile ps_1_1 MainPS();
}
}
Registers:
Name
Reg
Size
------------ ----- ---filter
c0
1
Default values:
filter
c0
= { 0, 0, 0, 0 };
vs_1_1
def c1, 1, 0, 0, 0
dcl_position v0
dcl_color v1
mul oD0, v1, c0
mad oPos, v0.xyzx, c1.xxxy, c1.yyyx
// approximately 2 instruction slots used
, float4
filter c0. ,
,
(0, 0, 0, 0).
, filter
c0, .
, , ,
. , , ,
, ,
.
,
. ,
, :
public EffectParameter this[string name] { get; }
, null.
EffectParameter,
SetValue
GetValueXXX. GetValueXXX.
// HLSL float
public float GetValueSingle();
// float: , float[10].
// count
public float[] GetValueSingleArray(int count);
// , (float2)
public Vector2 GetValueVector2();
// , (float2[])
public Vector2[] GetValueVector2Array(int count);
// , (float3)
public Vector3 GetValueVector3();
// , (float3[])
public Vector3[] GetValueVector3Array(int count);
// , (float4)
public Vector4 GetValueVector4();
// , (float4[])
public Vector4[] GetValueVector4Array(int count);
HLSL,
System.InvalidCastException.
SetValueXXX , GetValueXXX
SetValue . , float
GetValueSingle() public void SetValue(float value).
XNA Framework, 5.7 ,
, ,
( 5.18). ,
.
5.18. .
5.7.
public partial class MainForm : Form
{
// , 5.4 ( 5.6)
const string effectFileName = "Data\\FilterFill.fx";
...
Effect effect = null;
// , filter ( )
EffectParameter filterParam;
private void MainForm_Load(object sender, EventArgs e)
{
...
//
CompiledEffect compiledEffect;
compiledEffect = Effect.CompileEffectFromFile(effectFileName, null, null,
CompilerOptions.None, TargetPlatform.Windows);
...
//
effect = new Effect(device, compiledEffect.GetEffectCode(), CompilerOptions.NotCloneable,
null);
...
// EffectParameter, filter
filterParam = effect.Parameters["filter"];
// filter ,
Debug.Assert(filterParam != null, effectFileName + " : filter");
}
// ,
private void filterPanel_Click(object sender, EventArgs e)
{
if (colorDialog.ShowDialog() == DialogResult.OK)
{
//
filterPanel.BackColor = colorDialog.Color;
xnaPanel.Invalidate();
}
}
XNA Framework
:
effect.Parameters["filter"].SetValue(newColor);
, , : -,
, -, ,
XNA Framework
.
Load filter,
EffectParameter.
EffectParameter
Debug.Assert null
, -
.
5.5.
, HLSL Vertex Shader 1.1.
- . ,
, .
4-
: ,
. ,
,
GPU.
, ,
HLSL Vertex Shader 1.1.
5.5.1.
, :
, (
5.8).
5.8.
// ,
float delta = (float)(currentTime - lastTime);
//
diskAngle += diskSpeed * delta;
//
diskVertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f),
XnaGraphics.Color.LightGray);
for (int i = 0; i <= slices; i++)
{
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
float x = diskRadius * (float)Math.Sin(diskAngle + angle);
float y = diskRadius * (float)Math.Cos(diskAngle + angle);
byte red = (byte)(255 * Math.Abs(Math.Sin(angle * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(angle * 2)));
diskVertices[i + 1] = new VertexPositionColor(new Vector3(x, y, 0.0f),
new XnaGraphics.Color(red, green, 128));
};
, .
, , ,
, ,
. :
angle .
angle
.
,
.
,
. Vertex Shader 1.1 ,
,
.
,
5.4.
, .
. , ,
5.3.1 , (, ..)
v0, v1 v15,
, .
5.4. ,
5.8
diskAngle
angle
diskRadius
Angle
red/green
, ,
. , ,
. C#
DiskEffect, ( 5.9).
, - ,
81.
5.9.
//
static class DiskEffect
{
//
public static float angle;
//
//
input
//
output
public static void VertexShader(VertexPositionColor[] input, VertexPositionColor[]
output)
{
// ( ,
//
for (int i = 0; i < input.Length; i++)
{
// .
// angle Y
float a = input[i].Position.Y + angle;
// . X
output[i].Position.X = input[i].Position.X * (float)Math.Sin(a);
output[i].Position.Y = input[i].Position.X * (float)Math.Cos(a);
output[i].Position.Z = 0;
//
output[i].Color = input[i].Color;
}
}
}
,
Ch04\Ex01 ( ).
5.10.
81
5.10.
public partial class MainForm : Form
{
// .
// . -
const string effectFileName = "Data\\ColorFill.fx";
//
const int slices = 64;
//
public const float diskSpeed = 3.0f;
//
public const float diskRadius = 0.018f;
GraphicsDevice device;
PresentationParameters presentParams;
VertexDeclaration diskDeclaration;
//
VertexPositionColor[] diskVertices = null;
// , .
//
VertexPositionColor[] transformedDiskVertices = null;
Effect diskEffect = null;
Stopwatch stopwatch;
bool closing = false;
private void MainForm_Load(object sender, EventArgs e)
{
...
//
device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,
this.Handle, options, presentParams);
//
diskDeclaration = new VertexDeclaration(device,
VertexPositionColor.VertexElements);
//
diskVertices = new VertexPositionColor[slices + 2];
// , (
// )
transformedDiskVertices = new VertexPositionColor[slices + 2];
// (,
// )
diskVertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f),
XnaGraphics.Color.LightGray);
for (int i = 0; i <= slices; i++)
{
float angle = (float)i / (float)slices * 2.0f * (float)Math.PI;
byte red = (byte)(255 * Math.Abs(Math.Sin(angle * 3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(angle * 2)));
//
diskVertices[i + 1] = new VertexPositionColor(new Vector3(diskRadius, angle,
0.0f), new XnaGraphics.Color(red, green, 128));
};
...
//
diskEffect = new Effect(device, compiledEffect.GetEffectCode(),
CompilerOptions.NotCloneable, null);
//
stopwatch = new Stopwatch();
stopwatch.Start();
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
//
float time = (float)stopwatch.ElapsedTicks / (float)Stopwatch.Frequency;
DiskEffect.angle = diskSpeed * time;
//
DiskEffect.VertexShader(diskVertices, transformedDiskVertices);
//
device.VertexDeclaration = diskDeclaration;
//
diskEffect.Begin();
for (int i = 0; i < diskEffect.CurrentTechnique.Passes.Count; i++)
{
EffectPass currentPass = diskEffect.CurrentTechnique.Passes[i];
currentPass.Begin();
//
device.DrawUserPrimitives(PrimitiveType.TriangleFan, transformedDiskVertices,
0, diskVertices.Length - 2);
currentPass.End();
}
diskEffect.End();
device.Present();
}
...
}
CD- Exampes\Ch05\Ex05.
HLSL. 5.9, .
HLSL
( 5.11).
5.11.
// Disk.fx
float angle;
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
,
: DiskEffect
, (transformedDiskVertices).
angle.
5.12.
5.12.
public partial class MainForm : Form
{
//
const string effectFileName = "Data\\Disk.fx";
Effect diskEffect = null;
// EffectParameter, angle
EffectParameter angleParam = null;
private void MainForm_Load(object sender, EventArgs e)
{
...
// EffectParameter, angle
angleParam = diskEffect.Parameters["angle"];
Debug.Assert(angleParam != null, effectFileName + " : angle");
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
...
float time = (float)stopwatch.ElapsedTicks / (float)Stopwatch.Frequency;
// angle
angleParam.SetValue(diskSpeed * time);
//
device.VertexDeclaration = diskDeclaration;
diskEffect.Begin();
for (int i = 0; i < diskEffect.CurrentTechnique.Passes.Count; i++)
{
EffectPass currentPass = diskEffect.CurrentTechnique.Passes[i];
currentPass.Begin();
device.DrawUserPrimitives(PrimitiveType.TriangleFan, diskVertices, 0,
diskVertices.Length - 2);
currentPass.End();
}
diskEffect.End();
device.Present();
...
}
}
, Paint
.
- C#-.
,
82:
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Registers:
Name
Reg
Size
------------ ----- ---angle
c0
1
Default values:
angle
c0
= { 0, 0, 0, 0 };
vs_1_1
def c1, 0.159154937, 0.25, 0.5, -0.00138883968
def c2, 6.28318548, -3.14159274, -2.52398507e-007, 2.47609005e-005
82
, .
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
a = input.pos.y + angle
w r0.
, . ,
- sin cos
( Vertex Shader 1.1 ). ,
,
:
r1.x = a 0.159154937 + 0.25
r1.y = a 0.159154937 + 0.5
0.159154937 , ,
:
1. =
+ 0.25
2
1. =
+ 0.5
2
r0:
0. =
+ 0.25
2
0. =
+ 0.5
2
r0 :
0. =
+ 0.25 6.28318548 3.14159274
2
0. =
+ 0.5 6.28318548 3.14159274
2
, 3.14159274 , 6.28318548 :
+ 0.25
2
0. = 2
+ 0.5
2
,
r0.y MathCad , 83:
0. = 2
a, r0.y [-, +)
cos(a) = cos(r0.y)
, , a [-,
+), . ? ,
,
.
cos(a) . , ,
, ,
.
C x r0 :
r0.x [-, +)
sin(a) = cos(r0.x)
= 0. = 2
+ 0.25
2
= 0. = 2
+ 0.5
2
r0 ,
r1:
1. = 2.52398507 107 2 + 2.47609005 105
1. = 2.52398507 107 2 + 2.47609005 105
r1 ax2 -0.00138883968:
1. = 2.52398507 107 2 + 2.47609005 105 2 0.00138883968
1. = 2.52398507 107 2 + 2.47609005 105 2 0.00138883968
ax2
. r0
84:
0. =
0. =
ax ay
:
0. = 1 0.5 2 + 0.0416 4 0.001388 6 + 2.476 105 8 2.523 107 10
0. = 1 0.5 2 + 0.0416 4 0.001388 6 + 2.476 105 8 2.523 107 10
? , cos(x)
:
2 4 6 8 10
2
+ +
+ + (1)
2! 4! 6! 8! 10!
2 !
, . ,
y r0 , x
( sin(a) = cos(ax), cos(a) = cos(ay)).
cos = 1
83
84
, .
HLSL
.
cos(x)
cos
MathCad,
cos ( 5.19). ,
, 210-3.
, cos,
cos(x)=-cos(x).
5.19. Mathcad.
.
x y oPos.
z w 0 1. , ,
v1.
5.20 ,
HLSL . ,
,
.
. ,
,
R3xx R4xx 1-4
( , , ).
.
,
Vertex Shader 1.1. R2xx
,
Vertex Shader 1.1,
frc, . : R4xx
.. +,
.
, , Vertex
Shader 1.1 (
add mul dp4),
.
, FX Composer 2.0
Vertex Shader 1.1,
, . GeForce
7800 GTX 20 ,
172.000.000 .
,
, .
,
. ,
,
.
5.1
, ,
sin cos. , ,
, .
, ,
.
G8x R6xx ,
, . ,
, ,
.
.
. sin cos ,
. :
float a = input.pos.y + angle;
input.pos.y , angle
, . , sin(input.pos.y)
cos(input.pos.y) Load
, sin(angle) cos(angle)
. ,
,
:
sin(+)=sin()cos()+cos()sin()
(5.5)
cos(+)=cos()cos()-sin()sin()
: Ch05\Ex06,
5.5,
. NVIDIA FX Composer 2.0,
(, , ).
, 5.5
:
. ,
sin(angle).
HLSL, sin(angle), cos(angle), -sin(angle)
.
,
, \Examples\Ch05\Ex07.
5.5.2. if HLSL
, ,
if HLSL vs_1_1.
HLSL if:
if ( )
{
1
}
else
{
2
}
, , : Vertex Shader
1.1 ( , ..).
. C# if,
if,
85. HLSL
vs_1_1 , ,
. , HLSL
if .
,
if. , ,
,
( 5.13).
5.13.
85
,
, if
[.12].
// Examples\Ch05\Ex08
VertexOutput MainVS(VertexInput input)
{
VertexOutput output;
if (input.pos.x != 0)
{
// ,
float a = input.pos.y + angle;
output.pos.xy = input.pos.xx * float2(sin(a), cos(a));
}
else
// , (0.0, 0.0)
output.pos.xy = float2(0.0, 0.0);
output.pos.zw = float2(0.0, 1.0);
output.color = input.color;
return output;
}
FX Composer :
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Registers:
Name
Reg
Size
------------ ----- ---angle
c0
1
Default values:
angle
c0
= { 0, 0, 0, 0 };
vs_1_1
def c1, 0.159154937, 0.25, 0.5, -0.00138883968
def c2, 6.28318548, -3.14159274, -2.52398507e-007, 2.47609005e-005
def c3, 0.0416666418, -0.5, 1, 0
dcl_position v0
dcl_color v1
1. add r0.w, v0.y, c0.x
2. mad r1.xy, r0.w, c1.x, c1.yzzw
3. frc r0.xy, r1
4. mad r0.xy, r0, c2.x, c2.y
5. mul r0.xy, r0, r0
6. mad r1.xy, r0, c2.z, c2.w
7. mad r1.xy, r0, r1, c1.w
8. mad r1.xy, r0, r1, c3.x
9. mad r1.xy, r0, r1, c3.y
10. mad r0.xy, r0, r1, c3.z
11.
12.
13.
14.
15.
16.
mul
mul
slt
mul
mov
mov
, 13 16, 15
18, 20 21 . , 3
. :
G7x VLIW-86 87:
(ADD, MUL, MADD ..) (RCP, SIN, COS
..). ,
G7x .
, NVIDIA
. , ,
G7x. ,
,
.
. 10
float a = input.pos.y + angle
. r0.x
sin(a), r0.y cos(a).
input.pos.x .
input.pos.x ,
input.pos.xx * float2(sin(a), cos(a)).
-input.pos.xinput.pos.x +input.pos.xinput.pos.x :
if (-input.pos.x* input.pos.x < input.pos.x* input.pos.x)
r0.w=1
else
r0.w=0
, r0.w 1, input.pos.x 0, 0
. , ,
r0.w = (input.pos.x!=0)
{
static void Main(string[] args)
{
float a = 1.2f;
float b = 1.4f;
float c = 1.68f;
float mul = a * b;
float delta = c - mul;
Console.WriteLine("a = "
Console.WriteLine("b = "
Console.WriteLine("c = "
Console.WriteLine("sum =
Console.WriteLine("delta
Console.ReadKey();
+
+
+
"
=
(double)a);
(double)b);
(double)c);
+ (double)mul);
" + (double)delta);
}
}
:
a = 1,20000004768372
b = 1,39999997615814
c = 1,67999994754791
sum = 1,6800000667572
delta = -1,19209289550781E-07
, 1.2 1.4 ,
1.68 1.21.4 , -1.1910-7. ,
1.681.21.4.
,
, ( ) .
,
88. a b 10,
1214 168:
a = 12
b = 14
c = 168
sum = 168
delta = 0
, G8x, ,
. ,
mul/slt .
x y
input.pos.x 0: input.pos.x!=0, , input.pos.x==0,
. ,
if (input.pos.x != 0)
{
...
}
else
output.pos.xy = float2(0.0, 0.0);
88
, .
5.5.3.
. .
timeStep.
, maxScintillaCount.
, .
StartTime,
: ,
.
. ,
, ,
.
, 89,
, .. ..
,
:
,
.
.
.
,
.
, , , ..,
( 5.21). ,
,
, , -
.
5.21. .
,
, ,
, .
90. ,
, :
currentTime = time vertexStartTime;
localTime = currentTime % timeLoop;
time , .
vertexStartTime , .
, .
% .
timeLoop , , .
89
()
. ,
.
90
, ,
, .
localTime .
5.22. .
, .
,
.
delta:
// .
//
tSpeed = Math.Max(tSpeed - tSlowing * delta, 0.0f);
//
rSpeed = Math.Max(rSpeed - rSlowing * delta, 0.0f);
//
distance += tSpeed * delta;
//
angle += rSpeed * delta;
,
,
, .
.
= 0
tSpeed ;
tSpeed0 ;
tSlowing ;
t (localtime).
, , (0
) , , . ,
=
(0 ) = 0
2
+
2
, t=0
0 :
02
+ =
2
, C
:
0 = 0 0
= 0 + 0
(5.6)
5.6 ,
0 ,
.
,
0:
= min(localtime,
= 0 + 0
(5.7)
2
, ,
.
, :
0
= min
(localtime,
)
(5.8)
= + 0 + 0
2
2
0 ( );
0 ( );
, ,
. :
, .
,
(.. ).
,
. ,
, C#. ,
, .
, , ,
. ,
( 5.5). ,
, .
,
91.
, , , HLSL
v0, v1 v15. , ,
5.14.
5.5. ,
time
time
timeLoop
timeLoop
diskSpeed
diskSpeed
vertexStartTime
distance0
angle0
tSpeed
rSpeed
5.14.
static class FireworkEffect
{
// .
const float tSlowing = 0.105f;
const float rSlowing = 0.25f;
//
const float liveTime = 4.0f;
//
public
public
public
// .
91
//
//
//
//
//
//
//
//
//
input ,
output
public static void VertexShader(VertexPositionColorTexture[][] input,
VertexPositionColor[][] output)
{
( ).
,
GPU Intel GMA9xx,
// ,
//
float td = Math.Min(localTime, input[j][i].TextureCoordinate.X / tSlowing);
//
float distance = input[j][i].Position.Y + td *
(input[j][i].TextureCoordinate.X - td * tSlowing / 2.0f);
// ,
//
float tr = Math.Min(localTime, input[j][i].TextureCoordinate.Y / rSlowing);
//
float angle = input[j][i].Position.Z + diskSpeed * (time - localTime) +
tr * (input[j][i].TextureCoordinate.Y - tr * rSlowing / 2.0f);
//
output[j][i].Position.X = distance * (float)Math.Sin(angle);
output[j][i].Position.Y = distance * (float)Math.Cos(angle);
output[j][i].Position.Z = 0.0f;
// ,
if ((currentTime >= 0) && (remainTime > 0))
{
Vector4 color = input[j][i].Color.ToVector4();
//
color.W = remainTime / liveTime;
output[j][i].Color = new XnaGraphics.Color(color);
}
else
{
output[j][i].Color = new XnaGraphics.Color(0, 0, 0, 0);
}
}
}
}
}
.
VertexPositionColorTexture, Position
Color TextureCoordinate, X Y .
5.7 5.8 ,
. ,
mad . if, ,
.
, HSLS sin cos .
Load,
( 5.15).
5.15.
public partial class MainForm : Form
{
//
const string effectFileName = "Data\\ColorFill.fx";
const int slices = 64;
const float diskSpeed = 3.0f;
const float diskRadius = 0.018f;
//
const int fireworkVerticesCount = 300000;
// 20
const float timeLoop = 20.0f;
//
const float minSpeed = 0.3f;
//
const float maxSpeed = 0.45f;
//
const float pointSize = 1.0f;
// .
//
VertexDeclaration decl;
//
VertexPositionColorTexture[][] fireworkVertices = null;
// ,
VertexPositionColor[][] transformedFireworkVertices = null;
// , ( )
Effect effect = null;
Random rnd = new Random();
Stopwatch stopwatch;
bool closing = false;
// FPS
// ,
float lastTime = 0;
// ,
int frameCount = 0;
private void MainForm_Load(object sender, EventArgs e)
{
// ,
int maxVerticesCount = Math.Min(device.GraphicsDeviceCapabilities.MaxVertexIndex,
device.GraphicsDeviceCapabilities.MaxPrimitiveCount);
// ,
// fireworkVerticesCount
int arrayCount = (int)Math.Ceiling((float)fireworkVerticesCount /
(float)maxVerticesCount);
//
fireworkVertices = new VertexPositionColorTexture[arrayCount][];
// ,
transformedFireworkVertices = new VertexPositionColor[arrayCount][];
//
for (int k = 0; k < fireworkVerticesCount; k++)
{
// ,
int j = k / maxVerticesCount;
//
int i = k % maxVerticesCount;
//
if (i == 0)
{
//
int remain = fireworkVerticesCount - j * maxVerticesCount;
// maxVerticesCount
remain = Math.Min(remain, maxVerticesCount);
//
fireworkVertices[j] = new VertexPositionColorTexture[remain];
transformedFireworkVertices[j] = new VertexPositionColor[remain];
}
//
fireworkVertices[j][i].Position.X = (float)rnd.NextDouble() * timeLoop;
//
fireworkVertices[j][i].Position.Y = (float)rnd.NextDouble() * diskRadius;
//
fireworkVertices[j][i].Position.Z = (float)rnd.NextDouble() * 2.0f *
(float)Math.PI;
//
fireworkVertices[j][i].TextureCoordinate.X = minSpeed + (float)rnd.NextDouble() *
(maxSpeed - minSpeed);
//
fireworkVertices[j][i].TextureCoordinate.Y = diskSpeed / 4.0f * (1.0f +
0.01f * (float)rnd.NextDouble());
//
byte red = (byte)(255 * Math.Abs(Math.Sin(fireworkVertices[j][i].Position.Z *
3)));
byte green = (byte)(255 * Math.Abs(Math.Cos(fireworkVertices[j][i].Position.Z *
2)));
fireworkVertices[j][i].Color = new XnaGraphics.Color(red, green, 128, 255);
}
}
}
CPU GPU,
300.000 . (, Intel GMA 9xx)
92,
, . , -
92
. 2.4.3.
,
.
, ,
( 5.16).
5.16.
private void MainForm_Paint(object sender, PaintEventArgs e)
{
// GPU
device.RenderState.CullMode = CullMode.None;
device.RenderState.AlphaBlendEnable = true;
device.RenderState.BlendFunction = BlendFunction.Add;
device.RenderState.SourceBlend = Blend.SourceAlpha;
device.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
device.RenderState.PointSize = pointSize;
device.VertexDeclaration = decl;
// ,
float time = (float)stopwatch.ElapsedTicks / (float)Stopwatch.Frequency;
// ,
FireworkEffect.time = time;
FireworkEffect.timeLoop = timeLoop;
FireworkEffect.diskSpeed = diskSpeed;
//
FireworkEffect.VertexShader(fireworkVertices, transformedFireworkVertices);
effect.Begin();
for (int i = 0; i < effect.CurrentTechnique.Passes.Count; i++)
{
EffectPass currentPass = effect.CurrentTechnique.Passes[i];
currentPass.Begin();
//
for (int j = 0; j < transformedFireworkVertices.Length; j++)
{
//
device.DrawUserPrimitives(PrimitiveType.PointList,
transformedFireworkVertices[j], 0, transformedFireworkVertices[j].Length);
}
currentPass.End();
}
effect.End();
// -,
device.RenderState.AlphaBlendEnable = false;
float angle = diskSpeed * time;
//
DiskEffect.angle = angle;
DiskEffect.VertexShader(diskVertices, transformedDiskVertices);
//
...
//
device.Present();
//
frameCount++;
//
if (time - lastTime >= 1)
{
// FPS
Text = ((float)frameCount / (time - lastTime)).ToString();
//
lastTime = time;
frameCount = 0;
}
}
CD \Examples\Ch05\Ex10.
NVIDIA GeForce 7600GT Intel GMA 9xx 5.6.
,
,
. , 10 ,
. ,
, -
.
5.6. Ch05\Ex10 GPU
FPS
10.7
6.3
9.9
PresentationParameters.PresentationInterval
PresentInterval.Immediate,
.
,
. :
. , ,
.
, .
. ,
, Helper (
5.17).
5.17.
class Helper
{
...
// ,
- , C#
HLSL, - ( 5.18).
, C#- HLSL -, HLSL
,
. , ,
.
5.18.
// Firework.fx
//
// tSlowing rSlowing ,
//
static float2 slowing = {0.105, 0.25};
static float liveTime = 4.0;
float diskSpeed;
float time;
float timeLoop;
struct VertexInput
{
float3 pos : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD;
};
struct VertexOutput
{
float4 pos : POSITION;
float4 color : COLOR;
};
{
VertexShader = compile vs_1_1 MainVS();
PixelShader = compile ps_1_1 MainPS();
}
}
( 5.19).
5.19.
public partial class MainForm : Form
{
//
const string diskEffectFileName = "Data\\Disk.fx";
//
const string fireworkEffectFileName = "Data\\Firework.fx";
//
Effect diskEffect = null;
// , angle
EffectParameter angleParam = null;
//
Effect fireworkEffect = null;
// , : diskSpeed, time, timeLoopParam
EffectParameter diskSpeedParam = null;
EffectParameter timeParam = null;
EffectParameter timeLoopParam = null;
. !
,
. ,
,
.
device.VertexDeclaration = fireworkDeclaration;
//
fireworkEffect.Begin();
for (int i = 0; i < fireworkEffect.CurrentTechnique.Passes.Count; i++)
{
EffectPass currentPass = fireworkEffect.CurrentTechnique.Passes[i];
currentPass.Begin();
for (int j = 0; j < fireworkVertices.Length; j++)
{
device.DrawUserPrimitives(PrimitiveType.PointList, fireworkVertices[j],
0, fireworkVertices[j].Length);
}
currentPass.End();
}
fireworkEffect.End();
//
device.RenderState.AlphaBlendEnable = false;
angleParam.SetValue(diskSpeed * time);
//
device.VertexDeclaration = diskDeclaration;
//
...
// FPS
...
}
}
CD Examples\Ch05\Ex11.
Vertex Shader 1.1,
. NVIDIA FX Composer
2.0 , ,
.
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Registers:
Name
-----------diskSpeed
time
timeLoop
Reg
Size
----- ---c0
1
c1
1
c2
1
Default values:
diskSpeed
c0
= { 0, 0, 0, 0 };
time
c1
= { 0, 0, 0, 0 };
timeLoop
c2
= { 0, 0, 0, 0 };
vs_1_1
def c3, 0.0416666418, -0.5, 1, 0
def c4, 4, 9.52380943, 0.104999997, 0.25
def c5, 0.5, 0.159154937, 0.25, -0.00138883968
def c6, 6.28318548, -3.14159274, -2.52398507e-007, 2.47609005e-005
dcl_position v0
dcl_color v1
dcl_texcoord v2
// float currentTime = time - input.pos.x;
1. add r2.w, -v0.x, c1.x
// float localTime = currentTime % timeLoop
2. mul r0.w, r2.w, c2.x
3. add r1.w, c2.x, c2.x
4. sge r0.w, r0.w, -r0.w
5. mad r0.w, r0.w, r1.w, -c2.x
6. rcp r1.w, r0.w
7. mul r3.w, r2.w, r1.w
8.
9.
// input.texcoord / slowing
// float2 t = min(localTime.xx, input.texcoord / slowing).
//
10. mul r0.xy, v2, c4.yxzw
// float localTime = currentTime % timeLoop
11. mul r3.w, r0.w, r1.w
// float2 t = min(localTime.xx, input.texcoord / slowing)
12. min r0.xy, r0, r3.w
// float2 sCoord =
13. mul r1.xy, r0,
14. mad r1.xy, r1,
15. mad r0.xy, r0,
input.pos.yz + t * (input.texcoord
c4.zwzw
-c5.x, v2
r1, v0.yzzw
- t * slowing / 2.0f)
// if. if true,
// , .
33. mul oD0.w, r1.w, r0.w
// output.pos.zw = float2(0.0, 1.0);
34. mov oPos.zw, c3.xywz
// output.color.rgb = input.color.rgb
35. mov oD0.xyz, v1
// approximately 37 instruction slots used
HLSL .
currentTime % timeLoop 8 ( 2- 9-).
, Vertex Shader 1.1 ,
.
C#:
// C#, a%b. ,
// HLSL
static float mod(float a, float b)
{
// (a/b) , (nb=-b)
float cmp;
if (a*b > -a*b)
cmp = 1;
else
cmp = 0;
float nb = cmp * (b + b) - b;
//
float div = a * (1.0f / nb);
//
float frac = div - (float)Math.Floor(div);
//
float result = frac * nb;
return result;
}
,
frc. ,
, frc. ,
, expp, 2n.
2n, , y
- (a floor(a)).
, , , % HLSL
, .
,
HLSL , .
: HLSL
, float remainTime = liveTime localTime,
, .
if,
Vertex Shader 1.1
, && .
, , float2 sCoord = input.pos.yz + t * (input.texcoord t
* slowing / 2.0f) ,
:
( 37 36),
5 ( 42 37)
.
NVIDIA GeForce 7800 GTX 76.000.000 86.000.000
, .. 13%.
,
,
HLSL- , .
5.5.4.
. 5.23
, Excel Ch05\Ex10
Ch05\Ex12 GPU.
90
80
70
60
50
Ex10 (CPU)
40
Ex12 (GPU)
30
20
10
0
GeForce7600GT
HLSL
: , ,
, if.
IDE NVIDIA FX Composer 2.0, ,
, . ,
, ,
.
, HLSL, Vertex Shader.
Vertex Shader 1.1 .
93
, . , ,
. email: gsaf@sura.ru.
, XNA. ,
, , 3D ,
XNA. ,
.
Internet-,
XNA :
http://xna.com/ XNA.
http://creators.xna.com/ , , XNA.