ایران سرفراز- نرم افزار وپروژهای دانشجویی


نرم افزار وپروژهای دانشجویی

درس چهارم - Direct3D مباحث پیشرفته

<!-- /* Font Definitions */ @font-face {font-family:Helvetica; panose-1:2 11 5 4 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Courier; panose-1:2 7 4 9 2 2 5 2 4 4; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Tms Rmn"; panose-1:2 2 6 3 4 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Helv; panose-1:2 11 6 4 2 2 2 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"New York"; panose-1:2 4 5 3 6 5 6 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:System; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS 明朝"; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;} @font-face {font-family:Batang; panose-1:2 3 6 0 0 1 1 1 1 1; mso-font-alt:바탕; mso-font-charset:129; mso-generic-font-family:auto; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 151388160 16 0 524288 0;} @font-face {font-family:SimSun; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:宋体; mso-font-charset:134; mso-generic-font-family:auto; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:PMingLiU; panose-1:2 1 6 1 0 1 1 1 1 1; mso-font-alt:新細明體; mso-font-charset:136; mso-generic-font-family:auto; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:1 134742016 16 0 1048576 0;} @font-face {font-family:"MS Gothic"; panose-1:2 11 6 9 7 2 5 8 2 4; mso-font-alt:"MS ゴシック"; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;} @font-face {font-family:Dotum; panose-1:2 11 6 0 0 1 1 1 1 1; mso-font-alt:돋움; mso-font-charset:129; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 151388160 16 0 524288 0;} @font-face {font-family:SimHei; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:黑体; mso-font-charset:134; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:MingLiU; panose-1:2 1 6 9 0 1 1 1 1 1; mso-font-alt:細明體; mso-font-charset:136; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 134742016 16 0 1048576 0;} @font-face {font-family:Mincho; panose-1:2 2 6 9 4 3 5 8 3 5; mso-font-alt:明朝; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;} @font-face {font-family:Gulim; panose-1:2 11 6 0 0 1 1 1 1 1; mso-font-alt:굴림; mso-font-charset:129; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 151388160 16 0 524288 0;} @font-face {font-family:Century; panose-1:2 4 6 3 5 7 5 2 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Angsana New"; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65537 0;} @font-face {font-family:"Cordia New"; panose-1:2 11 3 4 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65537 0;} @font-face {font-family:Mangal; panose-1:0 0 4 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:32768 0 0 0 0 0;} @font-face {font-family:Latha; panose-1:2 0 4 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1048576 0 0 0 0 0;} @font-face {font-family:Sylfaen; panose-1:1 10 5 2 5 3 6 3 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:67110535 0 0 0 159 0;} @font-face {font-family:Vrinda; panose-1:1 1 6 0 1 1 1 1 1 1; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:65539 0 0 0 1 0;} @font-face {font-family:Raavi; panose-1:2 0 5 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131072 0 0 0 0 0;} @font-face {font-family:Shruti; panose-1:2 0 5 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:262144 0 0 0 0 0;} @font-face {font-family:Sendnya; panose-1:0 0 4 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Gautami; panose-1:2 0 5 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:2097152 0 0 0 0 0;} @font-face {font-family:Tunga; panose-1:0 0 4 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:4194304 0 0 0 0 0;} @font-face {font-family:"Estrangelo Edessa"; panose-1:3 8 6 0 0 0 0 0 0 0; mso-font-charset:1; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:-2147459008 0 128 0 0 0;} @font-face {font-family:"Arial Unicode MS"; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:1627421319 -2147483648 8 0 66047 0;} @font-face {font-family:TimesNewRoman; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:auto; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Adobe Caslon Pro Bold"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Adobe Caslon Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Adobe Garamond Pro Bold"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Adobe Garamond Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Arno Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Caption"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Display"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro SmText"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Subhead"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Light Display"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Smbd"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Smbd Caption"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Smbd Display"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Smbd SmText"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arno Pro Smbd Subhead"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Bell Gothic Std Black"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Bell Gothic Std Light"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Bickham Script Pro Regular"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:script; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:7 0 0 0 147 0;} @font-face {font-family:"Bickham Script Pro Semibold"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:script; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:7 0 0 0 147 0;} @font-face {font-family:"Birch Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Blackoak Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Brush Script Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Chaparral Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Charlemagne Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Cooper Std Black"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Eccentric Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Garamond Premr Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Garamond Premr Pro Smbd"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Giddyup Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Hobo Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Kozuka Gothic Pro B"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro B"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Gothic Pro EL"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro EL"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Gothic Pro H"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro H"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Gothic Pro L"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro L"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Gothic Pro M"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro M"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Gothic Pro R"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Gothic Pro R"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro B"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro B"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro EL"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro EL"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro H"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro H"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro L"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro L"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro M"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro M"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Kozuka Mincho Pro R"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"\@Kozuka Mincho Pro R"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:128; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:515 134676480 16 0 131077 0;} @font-face {font-family:"Letter Gothic Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Lithos Pro Regular"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Mesquite Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Minion Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Minion Pro Cond"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Minion Pro Med"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Minion Pro SmBd"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Myriad Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Myriad Pro Cond"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Myriad Pro Light"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Nueva Std Cond"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"OCR A Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Orator Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Poplar Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Prestige Elite Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Rosewood Std Regular"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Stencil Std"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Tekton Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Tekton Pro Cond"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Tekton Pro Ext"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:"Trajan Pro"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:135 0 0 0 155 0;} @font-face {font-family:Marlett; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Lucida Console"; panose-1:2 11 6 9 4 5 4 2 2 4; mso-font-charset:0; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-2147482993 6144 0 0 31 0;} @font-face {font-family:"Lucida Sans Unicode"; panose-1:2 11 6 2 3 5 4 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-2147476737 14699 0 0 63 0;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"Arial Black"; panose-1:2 11 10 4 2 1 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Comic Sans MS"; panose-1:3 15 7 2 3 3 2 2 2 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:Impact; panose-1:2 11 8 6 3 9 2 5 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:Georgia; panose-1:2 4 5 2 5 4 5 2 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Franklin Gothic Medium"; panose-1:2 11 6 3 2 1 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Palatino Linotype"; panose-1:2 4 5 2 5 5 5 3 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-536870009 1073741843 0 0 415 0;} @font-face {font-family:"Trebuchet MS"; panose-1:2 11 6 3 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:Webdings; panose-1:5 3 1 2 1 5 9 6 7 3; mso-font-charset:2; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"MV Boli"; panose-1:2 0 5 0 3 2 0 9 0 0; mso-font-charset:1; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 0 256 0 0 0;} @font-face {font-family:AngsanaUPC; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:222; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65536 0;} @font-face {font-family:BrowalliaUPC; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:222; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65536 0;} @font-face {font-family:"Browallia New"; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65537 0;} @font-face {font-family:CordiaUPC; panose-1:2 11 3 4 2 2 2 2 2 4; mso-font-charset:222; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777219 0 0 0 65536 0;} @font-face {font-family:DilleniaUPC; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:222; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:EucrosiaUPC; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:222; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:FreesiaUPC; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:222; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:IrisUPC; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:222; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:JasmineUPC; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:222; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:KodchiangUPC; panose-1:2 2 6 3 5 4 5 2 3 4; mso-font-charset:222; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:LilyUPC; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:222; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:16777217 0 0 0 65536 0;} @font-face {font-family:Aharoni; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:David; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"David Transparent"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:FrankRuehl; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Levenim MT"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:Miriam; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Miriam Transparent"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Miriam Fixed"; panose-1:0 0 0 9 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Fixed Miriam Transparent"; panose-1:0 0 0 9 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:Narkisim; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:Rod; panose-1:0 0 0 9 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Rod Transparent"; panose-1:0 0 0 9 0 0 0 0 0 0; mso-font-charset:177; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:6145 0 0 0 32 0;} @font-face {font-family:"Traditional Arabic"; panose-1:2 1 0 0 0 0 0 0 0 0; mso-font-charset:178; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:24577 0 0 0 64 0;} @font-face {font-family:"Arabic Transparent"; panose-1:2 1 0 0 0 0 0 0 0 0; mso-font-charset:178; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:8193 0 0 0 64 0;} @font-face {font-family:Andalus; panose-1:2 1 0 0 0 0 0 0 0 0; mso-font-charset:178; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:24577 0 0 0 64 0;} @font-face {font-family:"Simplified Arabic"; panose-1:2 1 0 0 0 0 0 0 0 0; mso-font-charset:178; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:8193 0 0 0 64 0;} @font-face {font-family:"Simplified Arabic Fixed"; panose-1:2 1 0 9 0 0 0 0 0 0; mso-font-charset:178; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:8193 0 0 0 64 0;} @font-face {font-family:Kartika; panose-1:2 2 5 3 3 4 4 6 2 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:8388611 0 0 0 1 0;} @font-face {font-family:"\@MS Gothic"; panose-1:2 11 6 9 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:1 134676480 16 0 131072 0;} @font-face {font-family:FantasyMatrix; panose-1:0 0 4 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:FantasyMatrixSmall; panose-1:0 0 4 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Jokerman Alts LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"University Roman Alts LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Smudger Alts LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"HolidayPi BT"; panose-1:5 12 1 2 1 2 9 2 2 2; mso-font-charset:2; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"OldDreadfulNo7 BT"; panose-1:4 8 8 5 6 1 7 1 8 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"MisterEarl BT"; panose-1:3 8 8 2 2 3 2 2 2 3; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Calligraph421 BT"; panose-1:3 6 7 2 5 4 2 2 2 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Blackletter686 BT"; panose-1:3 4 8 2 2 6 8 4 8 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Cataneo BT"; panose-1:3 2 8 2 4 5 2 6 8 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Staccato222 BT"; panose-1:3 9 7 2 3 4 7 2 4 3; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"ParkAvenue BT"; panose-1:3 2 6 2 5 5 6 8 7 5; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Square721 BT"; panose-1:2 11 5 4 2 2 2 6 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Broadway BT"; panose-1:4 4 9 5 8 11 2 2 5 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:135 0 0 0 27 0;} @font-face {font-family:"Microsoft Sans Serif"; panose-1:2 11 6 4 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:1627421663 -2147483648 8 0 66047 0;} @font-face {font-family:"Scruff LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Odessa LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Highlight LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"One Stroke Script LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Mekanik LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Tiranti Solid LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Pump Demi Bold LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Quixley LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"La Bamba LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Rage Italic LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Ruach LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Westwood LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Smudger LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Milano LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Victorian LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"University Roman LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Academy Engraved LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Orange LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"John Handy LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Jokerman LET"; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:131 0 0 0 9 0;} @font-face {font-family:"Agency FB"; panose-1:2 11 5 3 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Arial Narrow"; panose-1:2 11 5 6 2 2 2 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Arial Rounded MT Bold"; panose-1:2 15 7 4 3 5 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Blackadder ITC"; panose-1:4 2 5 5 5 16 7 2 13 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Bodoni MT"; panose-1:2 7 6 3 8 6 6 2 2 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Bodoni MT Black"; panose-1:2 7 10 3 8 6 6 2 2 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Bodoni MT Condensed"; panose-1:2 7 6 6 8 6 6 2 2 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Book Antiqua"; panose-1:2 4 6 2 5 3 5 3 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Bookman Old Style"; panose-1:2 5 6 4 5 5 5 2 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Bradley Hand ITC"; panose-1:3 7 4 2 5 3 2 3 2 3; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Calisto MT"; panose-1:2 4 6 3 5 5 5 3 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Castellar; panose-1:2 10 4 2 6 4 6 1 3 1; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Century Gothic"; panose-1:2 11 5 2 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Century Schoolbook"; panose-1:2 4 6 4 5 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Copperplate Gothic Bold"; panose-1:2 14 7 5 2 2 6 2 4 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Copperplate Gothic Light"; panose-1:2 14 5 7 2 2 6 2 4 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Curlz MT"; panose-1:4 4 4 4 5 7 2 2 2 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Edwardian Script ITC"; panose-1:3 3 3 2 4 7 7 13 8 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Elephant; panose-1:2 2 9 4 9 5 5 2 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Engravers MT"; panose-1:2 9 7 7 8 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Eras Bold ITC"; panose-1:2 11 9 7 3 5 4 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Eras Demi ITC"; panose-1:2 11 8 5 3 5 4 2 8 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Eras Light ITC"; panose-1:2 11 4 2 3 5 4 2 8 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Eras Medium ITC"; panose-1:2 11 6 2 3 5 4 2 8 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Felix Titling"; panose-1:4 6 5 5 6 2 2 2 10 4; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Forte; panose-1:3 6 9 2 4 5 2 7 2 3; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Franklin Gothic Book"; panose-1:2 11 5 3 2 1 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Franklin Gothic Demi"; panose-1:2 11 7 3 2 1 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Franklin Gothic Demi Cond"; panose-1:2 11 7 6 3 4 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Franklin Gothic Heavy"; panose-1:2 11 9 3 2 1 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Franklin Gothic Medium Cond"; panose-1:2 11 6 6 3 4 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"French Script MT"; panose-1:3 2 4 2 4 6 7 4 6 5; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Garamond; panose-1:2 2 4 4 3 3 1 1 8 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:Gigi; panose-1:4 4 5 4 6 16 7 2 13 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Gill Sans MT Ext Condensed Bold"; panose-1:2 11 9 2 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Gill Sans MT"; panose-1:2 11 5 2 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Gill Sans MT Condensed"; panose-1:2 11 5 6 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Gill Sans Ultra Bold"; panose-1:2 11 10 2 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Gill Sans Ultra Bold Condensed"; panose-1:2 11 10 6 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Gloucester MT Extra Condensed"; panose-1:2 3 8 8 2 6 1 1 1 1; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Goudy Old Style"; panose-1:2 2 5 2 5 3 5 2 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Goudy Stout"; panose-1:2 2 9 4 7 3 11 2 4 1; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Haettenschweiler; panose-1:2 11 7 6 4 9 2 6 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"Imprint MT Shadow"; panose-1:4 2 6 5 6 3 3 3 2 2; mso-font-charset:0; mso-generic-font-family:decorative; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"MS Outlook"; panose-1:5 1 1 0 1 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Maiandra GD"; panose-1:2 14 5 2 3 3 8 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Monotype Corsiva"; panose-1:3 1 1 1 1 2 1 1 1 1; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"OCR A Extended"; panose-1:2 1 5 9 2 1 2 1 3 3; mso-font-charset:0; mso-generic-font-family:modern; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Palace Script MT"; panose-1:3 3 3 2 2 6 7 12 11 5; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Papyrus; panose-1:3 7 5 2 6 5 2 3 2 5; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Perpetua; panose-1:2 2 5 2 6 4 1 2 3 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Perpetua Titling MT"; panose-1:2 2 5 2 6 5 5 2 8 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Pristina; panose-1:3 6 4 2 4 4 6 8 2 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Rage Italic"; panose-1:3 7 5 2 4 5 7 7 3 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:Rockwell; panose-1:2 6 6 3 2 2 5 2 4 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Rockwell Condensed"; panose-1:2 6 6 3 5 4 5 2 1 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Rockwell Extra Bold"; panose-1:2 6 9 3 4 5 5 2 4 3; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Script MT Bold"; panose-1:3 4 6 2 4 6 7 8 9 4; mso-font-charset:0; mso-generic-font-family:script; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Tw Cen MT"; panose-1:2 11 6 2 2 1 4 2 6 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Tw Cen MT Condensed"; panose-1:2 11 6 6 2 1 4 2 2 3; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:"Wingdings 2"; panose-1:5 2 1 2 1 5 7 7 7 7; mso-font-charset:2; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Wingdings 3"; panose-1:5 4 1 2 1 8 7 7 7 7; mso-font-charset:2; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Bookshelf Symbol 7"; panose-1:5 1 1 1 1 1 1 1 1 1; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Lucida Sans"; panose-1:2 11 6 2 3 5 4 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"Lucida Sans Typewriter"; panose-1:2 11 5 9 3 5 4 3 2 4; mso-font-charset:0; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"MS Reference Sans Serif"; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"MS Reference Specialty"; panose-1:5 0 5 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"Tw Cen MT Condensed Extra Bold"; panose-1:2 11 8 3 2 2 2 2 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:7 0 0 0 3 0;} @font-face {font-family:ZWAdobeF; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:536885895 0 0 0 511 0;} @font-face {font-family:"Euro Sign"; panose-1:2 11 6 3 2 2 1 2 1 1; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:3 2 0 0 1 0;} @font-face {font-family:"Lucida Bright"; panose-1:2 4 6 3 7 5 5 2 4 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:7 0 0 0 147 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} ins {mso-style-type:export-only; text-decoration:none;} span.msoIns {mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single;} span.msoDel {mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:aqua;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

درس چهارم - Direct3D مباحث پیشرفته

Mohsen_mahyar@yahoo.com

١

توابع ریاضی و ویژوال بیسیک

٢۶٣

Direct3D در D Studio Max های 3 object موضوع : استفاده از

بسازیم خودمان Direct3D تا بحال ما هر شیی را که می خواستیم در

بوسیله کد نویسی آنرا توصیف کرده ایم . ممکنست این سوال برایتان

پیش آمده باشد که بازیهای تجاری برای تولید کاراکترهای و اشیا

پیچیده سه بعدی چگونه عمل می کنند ؟

منطقی بنظر نمی رسد که اینگونه مدلهای پیچیده بصورت کد وارد

برنامه شده اند زیرا نیاز به هزاران خط برنامه برای هر فریم خواهد بود

های خود را توسط برنامه های دیگری می object . بجای اینکار ما

می کنیم سپس بافتها و load سازیم و آنها را در برنامه خودمان

های مورد نظر را به آنها اختصاص داده و در پایان آنها را material

رندر می کنیم . مزیت دیگر اینکار اینست که شما می توانید براحتی فایل

خود را تغییر دهید و مدلهایی با جزئیات متفاوت برای برنامه object

خود قرار دهید .

مراحل ساخت چنین برنامه هایی بصورت زیر است :

سه بعدی : object 1 - ساخت

اولین چیزی که بایستی بدانید داشتن دانش پایه ای از چگونگی

مدلسازی سه بعدی است . همچنین نیاز به یک نرم افزار مدلسازی مثل

دارید . D Studio Max3

٢۶۴

دارید تا Convertor نیاز به یک Max بعد از ساخت مدل خود در

هستند تبدیل ".X" که با فرمت Direct3D را به فایلهای Max فایلهای

کنید .

های زیادی برای تبدیل فایلهای نرم افزارهای مدلسازی به Convertor

وجود دارند که برخی از آنها عبارتند از : ".X" فایلهای

PolyTrans3D System Translation - برنامه

Deep Exploration - برنامه 2.0

Quick3D - برنامه

DWin - برنامه 3

DirectX Explorer Plugin -

که عبارتند از : DirectX 8.0 SDK - ابزارهای موجود در

X به فایلهای DS برای تبدیل فایلهای 3 Conv3DS برنامه

به Max و DS برای تبدیل فایلهای 3 DX SDK Exporter Plugin

X فایلهای

را به Deep Exploration ها من برنامه plugin از بین این برنامه ها و

شما پیشنهاد می کنم .

٢۶۵

در آدرس زیر می توانید اطلاعات بیشتری در مورد این برنامه بدست

کنید : Download آورید و همچنین آنرا

Exploration 2.0 Deep

s/n: 0XE2A0000000000

REJ1HYXSR1A77Q10 :Authorization s/n

ساخته شده : Object کردن یک Load - 2

direct3D کردن آن در load ، شی مورد نظر را ساختید X زمانیکه فایل

ساده است . برای اینکار نیاز به یک مش داریم که اطلاعات شی ما را

نگهداری کند :

Dim Mesh As D3DXMesh

به شی ، نیاز به تعریف texture و material همچنین برای اختصاص

متغیرهای زیر داریم :

٢۶۶

Dim MeshMaterial As D3DMATERIAL8

As Direct3DTexture8 Dim MeshTexture

می رویم : InitGeometry حال به سراغ بازنویسی روتین

- تعریف متغیرهای مورد نیاز :

Dim mtrlBuffer as D3DXBuffer

String Dim TextureFile as

Dim n as Long

: X - گرفتن داده های شی از فایل

Set Mesh=D3DX.LoadMeshFromX

"&"\"&app.path

yourfilename",D3DMESH_MANAGED,D3DDevice,Nothi

ng,mtrlBuffer,n

: Ambient شی و تنظیم پارامتر materiasl - استخراج اطلاعات

mtrlBuffer,0,MeshMaterial D3DX.BufferGetMaterial

MeshMaterial.Ambient=MeshMaterial.Diffuse

- استخراج نام بافت بکار رفته برای شی :

TextureFile=D3DX.BufferGetTextureName(mtrlBuffer,0)

x

- ساخت بافت :

Then ""<>If TextureFile

MeshTexture=D3DX.CreateTextureFromFile Set

٢۶٧

&"\"&D3DDevice,app.path

,TextureFile,128,128,D3DX_DEFAULT,0

D3DFMT_UNKNOWN,D3DPOOL_MANAGED,D3DX_F

ILTER_LINEAR,D3DX_FILTER_LINEAR,0,Byval

Byval 0,0

End If

3 - رندر نمودن شی : رندر نمودن شی چندان مشکل نیست اما همچنان

باید ماتریسها و تبدیلاتی را که می خواهید ، خودتان مدیریت کنید .

MeshMaterial D3DDevice.SetMaterial

D3DDevice.SetTexture 0,MeshTexture

Mesh.DrawSubset 0

درس دوم - Direct3D مباحث پیشرفته

Direct3D موضوع : مباحث تکمیلی نورپردازی در

٢۶٨

با مبانی نورپردازی آشنا شدید . در Direct3D در بخش اول آموزش

این درس قصد دارم آن مباحث را کاملتر برایتان مطرح کنم .

نورپردازی یکی از بخشهای مهم طراحی یک بازی و یا یک انیمیشن سه

بعدی است . بمنظور پیاده سازی نورپردازی یک صحنه ابتدا باید با

تئوری آن آشنا شوید .

تخمینی از چگونگی Direct3D تئوری نورپردازی : نورپردازی در

عملکرد نور در دنیای واقعی می باشد . چهار نوع اصلی نور در

قابل استفاده است ( همچنین شما می توانید خودتان انواع Direct3D

جدیدی از نور ایجاد کنید که موضوع ما نیست ) :

توسط یک نقطه در فضای سه بعدی ایجاد می شود : Point Light - 1

و دارای سه پارامتر رنگ ، دامنه و تضعیف می باشد . دامنه یک نور

مسافتی است که نور می تواند طی کند . تضعیف ، مقدار کاهش نور در

اثر افزایش مسافت می باشد . نور نقطه ای در تمام جهات تششع می کند

- شبیه یک لامپ حبابی و یا یک شمع

دارای یک موقعیت و یک جهت است و تنها نور را در : Spot Light - 2

یک جهت خاص می تاباند - شبیه یک چراغ قوه . این نور دارای یک زاویه

مخروطی و یک دامنه است .

دارای موقعیت نیست و برای پیاده سازی : Directional Light - 3

نورهایی که از فاصله بسیار دور می آیند - مثل خورشید - مناسب است

.

های یک vertex این نور تضمین می کند که تمام : Ambient Light - 4

صحنه تاریکتر از یک رنگ خاص نباشند .

عملی کردن نورپردازی : ضمن اینکه اغلب کارت های گرافیک سه بعدی از

نورپردازی پشتیبانی می کنند اما این نکته باید مورد توجه قرار گیرد که

بیشتر می شود Direct3D با افزایش تعداد نور در یک صحنه محاسبات

٢۶٩

و این باعث کند شدن رندر صحنه خواهد شد و بنابراین کارت های

گرافیکی سه بعدی نیز دارای یک ماکزیمم تعداد نور هستند - مثلا 16

همچنین توجه داشته باشید که نورهای مختلف - GeForce نور در 2

سریعترین زمان ambient دارای زمان پردازشی متفاوتی هستند . نور

و کندترین point سپس نور ، directional پردازشی را دارد ، سپس نور

است . Spot Light آنها

همچنین نکته دیگری که باید توجه کنید دامنه نور است . اگر نور ، یک

ها تاثیر می vertex منطقه بزرگی را پوشش دهد بر تعداد زیادی از

گذارد و این باعث افزایش محاسبات می شود .

که در درسهای بعدی در مورد آن صحبت می - Specular نورپردازی

کنم و برای ایجاد اشیا درخشان استفاده می شود - نیز زمان پردازشی

زیادی دارد و بهتر است کمتر از آن استفاده شود .

پارامتر دیگری که باید در نظر بگیرید جزئیات هندسه شما می باشد . هر

چه پیچیدگی صحنه بیشتر باشد ، نورپردازی نیز زمان بیشتری را

مصرف می کند .

سایه زنی نیز یک بخش بسیار پیچیده در مدل سازی نور است و

مستقیما Direct3D محاسبات آن بسیار زمان گیر خواهد بود بنابراین

محاسبات سایه زنی را انجام نمی دهد بلکه رنگ نور را بر مبنای جهت

می کند بنابراین قسمت پشتی یک شی که رو به نور scale هر مثلث

نیست ، هیچ نوری را دریافت نمی کند .

را بر مبنای بک بردار نرمال vertex هر Direct3D : بردار نرمال

دریافت می کند به زاویه بین vertex نورپردازی می کند و نوری که یک

بستگی دارد . بردار نرمال توسط سه vertex نور و بردار نرمال آن

مثلثی ایجاد می شود و این بردار نرمال ساخته شده به face یک vertex

٢٧٠

ها اختصاص می یابد . بردار نرمال در واقع سمت یک مثلث را vertex

مشخص می کند بنابراین اگر نور پشت مثلث باشد ، مثلث هیچ نوری را

دریافت نمیکند . بردار نرمال بایستی دارای طول 1 باشد .

مثلثی : face مراحل تولید بردار نرمال یک

در جهت عقربه های ساعت ساخته شده است . face 1 - مطمئن شوید که

شماره یک بسازید . vertex شماره صفر به vertex 2 - یک بردار از

شماره دو بسازید . vertex شماره صفر به vertex 3 - یک بردار از

این دو بردار را بدست ( cross droduct ) 4 - حاصلضرب برداری

آورید .

5 - نتیجه حاصلضرب را نرمال کنید .

Private Function GenerateTriangleNormals(p0 As

UnlitVertex, p1 As UnlitVertex, p2 As UnlitVertex) As

D3DVECTOR

D3DVECTOR Dim v01 As

Dim v02 As D3DVECTOR

Dim vNorm As D3DVECTOR

v01, MakeVector(p1.X, p1.Y, p1.Z), D3DXVec3Subtract

p0.Z)x ,MakeVector(p0.X, p0.Y

D3DXVec3Subtract v02, MakeVector(p2.X, p2.Y, p2.Z),

p0.Y, p0.Z)x ,MakeVector(p0.X

D3DXVec3Cross vNorm, v01, v02

vNorm ,D3DXVec3Normalize vNorm

GenerateTriangleNormals.X = vNorm.X

vNorm.Y = GenerateTriangleNormals.Y

٢٧١

GenerateTriangleNormals.Z = vNorm.Z

End Function

مشترک باشند ( مثل گوشه دو دیوار ) برای vertex در یک face اگر دو

را با روش فوق بدست face ابتدا نرمال دو vertex تولید نرمال این

آورید سپس دو بردار نرمال را با هم جمع کنید و در پایان بردار

حاصلجمع را نرمال کنید .

برپاسازی نورپردازی : اولین چیزی که قبل از برپاسازی نورپردازی

است . برای اینکار باید vertex بایستی اعمال کنیم تغییر ساختار

حذف و سه پارامتر را برای نگهداری vertex را از ساختار color پارامتر

نرمال اضافه کنیم :

Private Type UnlitVertex

X As Single

Single Y As

Z As Single

nx As Single

ny As Single

nz As Single

Single tu As

tv As Single

End Type

Const Unlit_FVF = (D3DFVF_XYZ Or

D3DFVF_NORMAL Or D3DFVF_TEX1)x

٢٧٢

های شی خود بردار نرمال را محاسبه vertex همچنین باید برای تمام

آن بردار face کنید برای مثال اگر شی شما یک مکعب است برای هر 12

نرمال را بدست آورید . در زیر من کد لازم برای ساخت نرمال یکی از این

ها را نوشته ام : face

x(0 ,Cube2(0) = CreateVertex(-1, -1, 1, 0, 0, 0, 0

Cube2(1) = CreateVertex(1, 1, 1, 0, 0, 0, 1, 1)x

CreateVertex(-1, 1, 1, 0, 0, 0, 0, 1)x = (Cube2(2

Cube2(1), ,(vN = GenerateTriangleNormals(Cube2(0

Cube2(2))x

= Cube2(0).nx = vN.X: Cube2(0).ny = vN.Y: Cube2(0).nz

vN.Z

= Cube2(1).nx = vN.X: Cube2(1).ny = vN.Y: Cube2(1).nz

vN.Z

Cube2(2).nx = vN.X: Cube2(2).ny = vN.Y: Cube2(2).nz =

vN.Z

خود اضافه device به material برای برپا سازی نور ابتدا بایستی یک

کنید :

Dim Mtrl As D3DMATERIAL8, Col As

D3DCOLORVALUE

Col.a = 1: Col.r = 1: Col.g = 1: Col.b = 1

Col = Mtrl.Ambient

Mtrl.diffuse = Col

D3DDevice.SetMaterial Mtrl

خود را تنظیم کنید که نور شما را بشناسد device سپس بایستی طوری

٢٧٣

است - یکبار که این خط را D3DLight یک شی از نوع 8 lights -

بنویسید می توانید از نور استفاده کنید اما اگر خصوصیات نور را

تغییر دهید بایستی دوباره این دستور را فراخوانی کنید :

D3DDevice.SetLight 0, Lights

حال باید نور را روشن کنید :

D3DDevice.LightEnable 0, 1

بگوئید که نورپردازی را برای شما انجام Direct3D و در پایان باید به

دهد :

1 ,D3DDevice.SetRenderState D3DRS_LIGHTING

چگونگی ایجاد یک نور : برای ایجاد هر یک از 4 نوع اصلی نور باید به

روشی خاص عمل کنید :

این نوع نورپردازی بسیار ساده است و تنها : Ambient 1 - نورپردازی

یک ambient ایجاد می شود . رنگ SetRenderState با فراخوانی تابع

است : RRGGBB عدد هگزادسیمال بصورت

,D3DDevice.SetRenderState D3DRS_AMBIENT

H202020&

دارای دو پارامتر رنگ و جهت می باشد : : Directional 2 - نورپردازی

٢٧۴

D3DLIGHT_DIRECTIONAL = Lights.Type

Lights.diffuse.r = 1

1 = Lights.diffuse.g

Lights.diffuse.b = 1

Lights.Direction = MakeVector(0, -1, 0)x

دارای سه پارامتر موقعیت ، رنگ و تضعیف می : Point 3 - نورپردازی

باشد :

Lights.Type = D3DLIGHT_POINT

MakeVector(5, 0, 2)x = Lights.position

Lights.diffuse.b = 1

100 = Lights.Range

Lights.Attenuation1 = 0.05

٢٧۵

این نور دارای دو مخروط است که نقاط خارج : Spot 4 - نورپردازی

مخروط اول روشنتر از نقاط داخل آن هستند . دو زاویه برای مخروط

که برحسب - phi و زاویه خارجی theta وجود دارد - زاویه داخلی

رادیان هستند :

D3DLIGHT_SPOT = Lights.Type

Lights.position = MakeVector(-4, 0, 0)x

100 = Lights.Range

Lights.Direction = MakeVector(1, 0, 0)x

x(180 / Lights.Theta = 30 * (Pi

Lights.Phi = 50 * (Pi / 180)x

1 = Lights.diffuse.g

Lights.Attenuation1 = 0.05

٢٧۶

درس سوم - Direct3D مباحث پیشرفته

برای ذخیره سازی اشکال سه Index Buffer موضوع : استفاده از

بعدی

مقدمه : مکعبی که در درسهای قبلی ساختیم را درنظر بگیرید . با دانشی

که اکنون دارید ، دو راه برای ساخت یک مکعب داریم : 1 - استفاده از 36

های مکعب 2 - ساخت مکعب با استفاده face برای تعریف vertex عدد

X از یک مدلساز و ذخیره آن با فرمت

vertex روش اول غیرکارامد است زیرا شما بایستی از تعداد زیادی

برای یک شکل بسیار ساده استفاده کنید . روش دوم مناسب است اما

زمانیکه بخواهیم رنگها و بافتها را تغییر دهیم دچار مشکل خواهیم شد .

Index روش جدیدی که امروز در مورد آن صحبت می کنم استفاده ار

است . Buffer

است که این اعداد مرجعی integer شامل یکسری عدد Index Buffer

هستند . برای Vertex Buffer های ذخیره شده در یک vertex برای

داریم که یک vertex شامل 8 عدد Vertex Buffer مثال فرض کنید یک

با Index Buffer مکعب را برای ما توصیف می کند . ما می توانیم یک

ها را برای ما مشخص vertex 36 عضو بسازیم بطوریکه ترتیب اتصال

شماره 1 face های 0 و 1و 3 برای مشخص کردن Index کنند . مثلا

می vertex مکعب بکار می روند . بنابراین بجای استفاده از 36 عدد

بسازیم . Index Buffer و یک vertex توانیم مکعب را با 8 عدد

بسیار کارامد است اما چندین محدودیت Index Buffer گرچه استفاده از

در استفاده از آن وجود دارد . مهمترین آنها اینست که تمام اندیسهایی که

می کنند بایستی خصوصیات مشابهی share مشابه را vertex یک

داشته باشند - موقعیت ، رنگ ، بافت و نرمال یکسان - برای مثال نمی

٢٧٧

آن یک رنگ داشته باشد . face توانید مکعبی بسازید که هر

ابتدا به متغیرهای زیر نیاز داریم : : Index Buffer ساخت

Dim VBuffer as Direct3DVertexBuffer8

as Direct3DIndexBuffer8 Dim IBuffer

Dim Vlist(0 to 7) as LITVERTEX

as Integer (Dim Ilist(0 to 35

بصورت زیر بازنویسی می شود: InitGeometry تابع

برای مکعب : vertex -1 تولید هشت

x(0 ,0 ,0 ,HFF0000& ,Vlist(0) = CreateLitVertex(-1, -1, -1

x(0 ,0 ,0 ,&HFF00& ,Vlist(1) = CreateLitVertex(-1, 1, -1

x(0 ,0 ,0 ,&HFF& ,Vlist(2) = CreateLitVertex(1, -1, -1

HFF00FF, 0, 0, 0)x& ,Vlist(3) = CreateLitVertex(1, 1, -1

HFFFF00, 0, 0, 0)x& ,CreateLitVertex(-1, -1, 1 = (Vlist(4

HFFFF, 0, 0, 0)x& ,CreateLitVertex(-1, 1, 1 = (Vlist(5

HFFCC00, 0, 0, 0)x& ,1 ,1- ,Vlist(6) = CreateLitVertex(1

HFFFFFF, 0, 0, 0)x& ,Vlist(7) = CreateLitVertex(1, 1, 1

: CreateVertexBuffer توسط تابع Vertex Buffer 2 - ایجاد

= Set VBuffer

D3DDevice.CreateVertexBuffer(Len(Vlist(0)) * 8, 0,

D3DPOOL_DEFAULT)x ,Lit_FVF

٢٧٨

,D3DVertexBuffer8SetData VBuffer, 0, Len(Vlist(0)) * 8, 0

Vlist(0)x

ها : index 3 - تولید

' front

2 = (Ilist(0) = 0: Ilist(1) = 1: Ilist(2

Ilist(3) = 1: Ilist(4) = 3: Ilist(5) = 2

' Right

Ilist(7) = 3: Ilist(8) = 6 :Ilist(6) = 2

Ilist(9) = 3: Ilist(10) = 7: Ilist(11) = 6

' Back

Ilist(12) = 6: Ilist(13) = 7: Ilist(14) = 4

Ilist(17) = 4 :5 = (Ilist(15) = 7: Ilist(16

' Left

0 = (Ilist(18) = 4: Ilist(19) = 5: Ilist(20

Ilist(21) = 5: Ilist(22) = 1: Ilist(23) = 0

' Top

Ilist(25) = 5: Ilist(26) = 3 :Ilist(24) = 1

3 = (Ilist(27) = 5: Ilist(28) = 7: Ilist(29

' Bottom

Ilist(30) = 2: Ilist(31) = 6: Ilist(32) = 0

Ilist(34) = 4: Ilist(35) = 0 :Ilist(33) = 6

: CreateIndexBuffer توسط تابع Index Buffer 4 - ایجاد

D3DDevice.CreateIndexBuffer(Len(Ilist(0)) * = Set IBuffer

D3DPOOL_DEFAULT)x ,36, 0, D3DFMT_INDEX16

٢٧٩

,D3DIndexBuffer8SetData IBuffer, 0, Len(Ilist(0)) * 36, 0

Ilist(0)x

برای رندر کردن این مکعب دو روش وجود دارد : : Render تابع

در این روش از : DrawIndexedPrimitive 1 - استفاده از تابع

ها استفاده می شود : vertex و آرایه IBUffer و VBuffer

Public Sub Render()x

D3DCLEAR_TARGET Or ,D3DDevice.Clear 0, ByVal 0

0 ,D3DCLEAR_ZBUFFER, 0, 1#

D3DDevice.BeginScene

Len(Vlist(0))x ,D3DDevice.SetStreamSource 0, VBuffer

0 ,D3DDevice.SetIndices IBuffer

D3DDevice.DrawIndexedPrimitive

12 ,D3DPT_TRIANGLELIST, 0, 36, 0

D3DDevice.EndScene

0 D3DDevice.Present ByVal 0, ByVal 0, 0, ByVal

End Sub

در این روش از : DrawIndexedPrimitiveUP 2 - استفاده از تابع

استفاده می شود : index و vertex آرایه های

Public Sub Render()x

D3DCLEAR_TARGET Or ,D3DDevice.Clear 0, ByVal 0

0 ,D3DCLEAR_ZBUFFER, 0, 1#

D3DDevice.BeginScene

D3DDevice.DrawIndexedPrimitiveUP

D3DPT_TRIANGLELIST, 0, 8, 12, Ilist(0),

٢٨٠

Len(Vlist(0))x ,(D3DFMT_INDEX16, Vlist(0

D3DDevice.EndScene

ByVal 0 ,0 ,D3DDevice.Present ByVal 0, ByVal 0

End Sub

نکته : برای دریافت برنامه نمونه و یا اطلاعات بیشتر در مورد توابعی که

در این درس استفاده شد با من تماس بگیرید .

درس چهارم - Direct3D مباحث پیشرفته

Vertex/Mesh Animation : موضوع

صحبت Direct3D در این درس در مورد روشهای ساخت انیمیشن در

خواهیم کرد . انیمیشن در فضای سه بعدی در حالتهای مختلفی می تواند

گرافیکی شما و ابزارهایی که ایجاد کرده engine ایجاد شود که بسته به

اید ، دارد . سه روش اصلی ساخت انیمیشن وجود دارد که عبارتند از :

manual ) سازی دستی / درون یابی خطی Tween -

( tweening/linear interpolation

( vector interpolation ) - درون بابی برداری

٢٨١

( interpolation keyframe ) - درون یابی بر اساس فریم کلیدی

1 – روش اول یکی از ساده ترین راههای ساخت انیمیشن است . این

روش در زمانیکه با مدلهای پیچیده سر و کار دارید مناسب نیست – و یا

کردن است که tween این روش نوعی – vertex مدلهایی با تعداد زیادی

ها استفاده می کند . index buffer از مزیت

درون یابی ، چگونگی تغییرات شیی در طول یک زمان مشخص می باشد

. در درسهای قبلی شما درون یابی رنگ را روی یک شی دیدید که در آن

شدن ( . درون fade ) یک رنگ بطور ملایم به رنگ دیگری تبدیل می شد

به A یابی خطی نیز مشابه آن است . برای درون یابی خطی از موقعیت

از فرمول زیر استفاده می شود : B موقعیت

(B*V)+A*(1-V)

ضریب درون یابی است V مختصاتهای مبدا و مقصد هستند و B و A که

را tween که عددی بین صفر و یک می باشد . این فرمول مختصات نقطه

در هر لحظه مشخص می کند .

همانطور که می بینید بکار بردن این فرمول برای یک شی با تعداد زیادی

را پایین می آورد . fram rate بسیار وقت گیر بوده و vertex

و یک مقدار ضریب درون یابی را می گیرد تا نقطه vertex تابع زیر دو

را محاسبه کند : tween

,Private Function TweenVertices(Source As LITVERTEX

Dest As LITVERTEX, TweenAmount As Single) As

LITVERTEX

Dest.X * TweenAmount) + Source.X * ) = TweenVertices.X

(1# - TweenAmount)x

Dest.Y * TweenAmount) + Source.Y * ) = TweenVertices.Y

(1# - TweenAmount)x

٢٨٢

Dest.Z * TweenAmount) + Source.Z * ) = TweenVertices.Z

(1# - TweenAmount)x

Source.color = TweenVertices.color

End Function

هایی با بردار vertex – استفاده کنید UNLIT های vertex اگر شما از

را از tween نرمال – در اینصورت باید کد فوق را تغییر دهید و باید

نرمال مبدا به نرمال مقصد نیز انجام دهید .

نیز تنظیم شده است . در یک tween vertex همانطور که می بینید رنگ

مناسبتر می توانید رنگها ، مختصات بافت و مقادیر tweening تابع

کنید . tween را نیز specular

محدودیتی که این روش دارد اینست که خطی است و برای مدل کردن

حرکتهای غیر خطی درست کار نمی کند .

استفاده کنیم تا یک مکعب را در یک tween حال می خواهیم از تابع

انیمیشن به یک هرم تبدیل کنیم . ابتدا سه شی را بصورت زیر تعریف

می کنیم :

است’ source cube همان current cube در ابتدای انیمیشن ، شی

HFF0000, & ,CubeVertices(0) = CreateLitVertex(-1, -1, -1

x(0 ,0, 0

,0 ,&HFF00& ,CubeVertices(1) = CreateLitVertex(-1, 1, -1

x(0 ,0

,0 ,0 ,&HFF& ,CubeVertices(2) = CreateLitVertex(1, -1, -1

x(0

HFF00FF, 0, & ,CubeVertices(3) = CreateLitVertex(1, 1, -1

x(0 ,0

٢٨٣

HFFFF00, & ,CubeVertices(4) = CreateLitVertex(-1, -1, 1

x(0 ,0, 0

,HFFFF, 0, 0& ,CubeVertices(5) = CreateLitVertex(-1, 1, 1

x(0

HFFCC00, 0, & ,CubeVertices(6) = CreateLitVertex(1, -1, 1

x(0 ,0

HFFFFFF, 0, & ,CubeVertices(7) = CreateLitVertex(1, 1, 1

0, 0)x

مکعب اولیه

,CubeVerticesSource(0) = CreateLitVertex(-1, -1, -1

HFF0000, 0, 0, 0)x&

,CubeVerticesSource(1) = CreateLitVertex(-1, 1, -1

x(0 ,0 ,0 ,&HFF00&

,CubeVerticesSource(2) = CreateLitVertex(1, -1, -1

x(0 ,0 ,0 ,&HFF&

,CubeVerticesSource(3) = CreateLitVertex(1, 1, -1

HFF00FF, 0, 0, 0)x&

,CubeVerticesSource(4) = CreateLitVertex(-1, -1, 1

HFFFF00, 0, 0, 0)x&

,CubeVerticesSource(5) = CreateLitVertex(-1, 1, 1

HFFFF, 0, 0, 0)x&

,CubeVerticesSource(6) = CreateLitVertex(1, -1, 1

HFFCC00, 0, 0, 0)x&

,CubeVerticesSource(7) = CreateLitVertex(1, 1, 1

HFFFFFF, 0, 0, 0)x&

هرم مقصد

,CreateLitVertex(-1, -1, -1 = (CubeVerticesDest(0

HFF0000, 0, 0, 0)x&

٢٨۴

,CreateLitVertex(-0.1, 1, -0.1 = (CubeVerticesDest(1

x(0 ,0 ,0 ,&HFF00&

,&HFF& ,CreateLitVertex(1, -1, -1 = (CubeVerticesDest(2

x(0 ,0 ,0

,CreateLitVertex(0.1, 1, -0.1 = (CubeVerticesDest(3

HFF00FF, 0, 0, 0)x&

,CreateLitVertex(-1, -1, 1 = (CubeVerticesDest(4

HFFFF00, 0, 0, 0)x&

,CreateLitVertex(-0.1, 1, 0.1 = (CubeVerticesDest(5

HFFFF, 0, 0, 0)x&

,CreateLitVertex(1, -1, 1 = (CubeVerticesDest(6

HFFCC00, 0, 0, 0)x&

,CreateLitVertex(0.1, 1, 0.1 = (CubeVerticesDest(7

HFFFFFF, 0, 0, 0)x&

پیکسلهای twen حال باید در یک حلقه با استفاده از تابع

کنیم : update را CubeVertices

Private Sub UpdateAnimation()x

Integer Dim I As

به روز کردن پارامترهای زمان و جهت'

Then If AnimTweenDir = True

AnimTweenFactor = AnimTweenFactor +

(#1*(1000 / ((((GetTickCount() - LastTimeTweened

LastTimeTweened = GetTickCount

Then #1 =< If AnimTweenFactor

AnimTweenFactor = 1#

AnimTweenDir = False

If End

Else

٢٨۵

AnimTweenFactor = AnimTweenFactor -

(LastTimeTweened) / 1000)*1# - ()(((GetTickCount

LastTimeTweened = GetTickCount

Then #0 => AnimTweenFactor If

AnimTweenFactor = 0#

True = AnimTweenDir

End If

End If

ها ' vertex به روز کردن اطلاعات

7 For I = 0 To

CubeVertices(I) = TweenVertices(CubeVerticesSource(I),

AnimTweenFactor)x ,(CubeVerticesDest(I

Next I

’vertex به روز کردن بافر

D3DVertexBuffer8SetData(VBuffer, 0, If

CubeVertices(0)) = ,Len(CubeVertices(0)) * 8, 0

:D3DERR_INVALIDCALL Then GoTo Error

Sub Exit

:Error

Debug.Print “Error occured whilst updating the

animation…”x

End Sub

زمان پایه انیمیشن توسط عبارت زیر تنظیم می شود :

(GetTickCount() - LastTimeTweened) / 1000) * 1#)))

همانطور که می دانید دو نوع انیمیشن وجود دارد : انیمیشن بر مبنای

شماره frame و انیمیشن بر مبنای زمان . در انیمیشن بر مبنای frame

فریم با یک مقدار ثابت در زمان افزایش می یابد اما اگر اینکار باعث می

شود کیفیت انیمیشن در کامپیوترهای با سرعت متفاوت تغییر کند .

٢٨۶

بنابراین انیمیشن را بر مبنای زمان تولید کرده ایم . انیمیشن های بر

مبنای زمان بجای " 1 فریم در هر سیکل " ، " 30 فریم در هر ثانیه "

هستند .

tweening برای انجام عمل D3DX 2 – روش دوم از توابع کتابخانه

استفاده می کند و بنابراین بهبودی در سرعت انیمیشن نسبت به روش

می توانیم عمل D3DX بالا حاصل می شود . با استفاده از کتابخانه

انجام دهیم . لیست vertex درون یابی خطی را برای تمام اجزا اصلی یک

زیر توابعی را برای اینکار نشان می دهد :

انجام درون یابی برای موقعیت و نرمال : : D3DXVec3Lerp - تابع

D3DXVec3Lerp( VOut as D3DVECTOR, V1 as

as D3DVECTOR, S as Single)x D3DVECTOR, V2

VOut = The result of the interpolation -

The source coordinates = V1 -

V2 = The destination coordinates -

interpolation amount - between, but not limited S = The -

the source and 1 is the to, 0.0 - 1.0 scale; where 0 is

destination

: vertex انجام درون یابی برای رنگهای : D3DXColorLerp - تابع

D3DXColorLerp( COut as D3DCOLORVALUE, C1 as

D3DCOLORVALUE, C2 as D3DCOLORVALUE, S as

Single)x

colour COut = The resulting -

C1 = The source colour -

٢٨٧

C2 = The destination colour -

,interpolant S = The -

on a 0.0 to 1.0 scale

انجام درون یابی برای مختصاتهای دوبعدی : D3DXVec2Lerp - تابع

:

VOut = The result of this interpolation -

coordinates V1 = The source -

V2 = The destination coordinates -

to 1.0 scale 0,0 S = The interpolant on a -

تولید یک مسیر منحنی که از دو نقطه : D3DXVec3Hermite - تابع

کنترل عبور می کند :

D3DXVec3Hermite( VOut as D3DVECTOR, V1 as

T1 as D3DVECTOR, V2 as D3DVECTOR, ,D3DVECTOR

T2 as D3DVECTOR, S as Single)x

Result VOut = The -

V1 = The Source Coordinate -

coordinate, this is the T1 = The Tangent at the Source -

.point direction and speed the line will leave the source

V2 = The Destination Coordinate -

Destination coordinate, this is T2 = The Tangent at the -

destination the direction and speed the line will enter the

.point

S = The Interpolant Value -

٢٨٨

استفاده کنیم باید توصیف D3DX برای اینکه بتوانیم از کتابخانه

اضافی ARGB هایمان را تغییر دهیم و بایستی یکسری مقادیر vertex

اضافه کنیم : vertex را به ساختار

Private Type LITVERTEX

X As Single

Single Y As

Z As Single

color As Long

specular As Long

tu As Single

As Single tv

ColorEx As D3DCOLORVALUE

End Type

را بصورت زیر می نویسیم : tween حال تابع

,Private Function TweenVertices(Source As LITVERTEX

Dest As LITVERTEX, TweenAmount As Single) As

LITVERTEX

D3DVECTOR Dim vResult As

Dim vResult2 As D3DVECTOR2

ها ‘ vertex کردن موقعیت Tween

D3DXVec3Lerp vResult, MakeVector(Source.X, Source.Y,

MakeVector(Dest.X, Dest.Y, Dest.Z), ,(Source.Z

TweenAmount

vResult.X = TweenVertices.X

TweenVertices.Y = vResult.Y

TweenVertices.Z = vResult.Z

’ texture کردن اطلاعات Tween

,D3DXVec2Lerp vResult2, MakeVector2D(Source.tu

Source.tv), MakeVector2D(Dest.tu, Dest.tv),

٢٨٩

TweenAmount

vResult2.X = TweenVertices.tu

TweenVertices.tv = vResult2.Y

کردن اطلاعات رنگ ‘ Tween

D3DXColorLerp TweenVertices.ColorEx,

TweenAmount ,Source.ColorEx, Dest.ColorEx

With TweenVertices.ColorEx

G * 255, .R * 255)x. ,TweenVertices.color = RGB(.B * 255

End With

End Function

نکته ای که باید به آن توجه کنید اینست که در تابع فوق برای اشاره به

. ( MakeVector یک بردار ساخته شده است ( توسط تابع ، vertex

3 – روش سوم پر استفاده ترین روش انیمیشن سازی است . اگر شما

انیمیشن های پیچیده با تعداد زیادی شی در آن داشته باشید و اگر

بخواهید تغییرات اشیا را در هر فریم ذخیره کنید ، به حجم بالایی از

منابع ذخیره سازی نیاز است . بجای آن ما با استفاده از یکسری فریم

کلیدی ، فریمهای میانی را پیش بینی می کنیم .

را در هر فریم vertex برای انجام درون یابی فریم کلیدی ، بایستی مقدار

کلیدی بدانیم و نیز بدانیم هر فریم کلیدی در چه زمانی ظاهر می شود .

بنابراین باید برای هر انیمیشن چند فایل را بعنوان فریم کلیدی ذخیره

کنیم .

می load در این درس ما داده های کلیدی انیمیشن را از یکسری فایل

درون برنامه قرار داده می keyframe کنیم بنابراین تمام ثابتهای زمان

شود ( شما می توانید خودتان یک ماژول بنویسید که انیمیشن های

عمومی تر را نیز مدیریت کند . این ماژول باید قادر باشد که یک فرمت

load های مربوطه را texture کند ، اشیا و import استاندارد فایل را

٢٩٠

نماید و سپس خودش ساخت انیمیشن را بطور اتوماتیک انجام دهد و

را فراخوانی کند ) . پس update و یا render برنامه اصلی فقط روتین

از جمع آوری اطلاعات فریم های کلیدی ، باید در هر زمان محاسبه کنیم

که چه مدتی از شروع انیمیشن گذشته است و بنابراین انیمیشن در چه

موقعیتی قرار دارد . سپس محاسبه می کنیم که فریم کلیدی قبلی و فریم

کلیدی بعدی چیست همچنین حساب می کنیم در چه فاصله زمانی از

ایندو قرار داریم . سرانجام یک درون یابی نرمال را انجام می دهیم تا

Mesh اطلاعات فریم جاری بدست آید و این اطلاعات را درون یک شی

می گذاریم و آنرا رندر می کنیم .

صحبت کردم X کردن اشیا از یک فایل load در درسهای قبلی در مورد

صحبت Mesh از یک شی vertex اما در مورد چگونگی گرفتن اطلاعات

برای اینکار دو تابع دارد : D3DX نشد . کتابخانه

اطلاعات یک شی : D3DXMeshVertexBuffer8GetData - تابع

ذخیره می D3DVERTEX را گرفته و در یک آرایه از D3DXMesh

کند :

D3DXMeshVertexBuffer8GetData( D3DXMeshobj As

Unknown, Offset As Long, Size As Long, Flags As Long,

Data As Any) As Long

D3DXMeshobj As Unknown = A D3DXMESH object -

.from that you want to extract the data

Offset As Long = How far into the vertex buffer we want -

reading, 0 is the beginning to start

will be Size As Long = Size of the vertex buffer, this -

Len(D3DVERTEX) * Mesh.GetNumVertices

of the Flags As Long = A combination -

.CONST_D3DLOCKFLAGS, leave as 0

٢٩١

the array that you Data As Any = The first element in -

want the data to be read into, should be an array of

D3DVERTEX vertices

Return Code As Long = Returns D3D_OK for success, or -

either of D3DERR_INVALIDCALL or E_INVALIDARG

for an error

اطلاعات یک بافر : D3DXMeshVertexBuffer8SetData - تابع

قرار می دهد : D3DXMesh را در یک شی vertex

D3DXMeshVertexBuffer8SetData( D3DXMeshobj As

Unknown, Offset As Long, Size As Long, Flags As Long,

Data As Any) As Long

D3DXMeshobj As Unknown = The D3DXMESH object -

data to be placed that defines where you want the

Offset As Long = How far into the Destination vertex -

buffer you want to place the data

bytes, this will be Size As Long = The Size of the buffer in -

Len(D3DVERTEX) * Mesh.GetNumVertices

Combination of the Flags As Long = A -

CONST_D3DLOCKFLAGS, leave as 0

element in the array of data you Data As Any = The first -

want placed in the mesh's vertex buffer

Return Code As Long = D3D_OK for success or -

for D3DERR_INVALIDCALL or E_INVALIDARG

failure

عملیات انجام انیمیشن فریم کلیدی بصورت زیر است :

D3DXMesh به درون شی X کردن اشیا از فایلهای load -

٢٩٢

از این شی vertex - استخراج اطلاعات

- انجام درون یابی بین فریمهای کلیدی

D3DXMesh های درون یابی در یک شی vertex - قرار دادن اطلاعات

باشد – n فرض می کنیم که انیمیشن ما همیشه از زمان صفر تا زمان

برای GetTickCount برحیب میلی ثانیه – بنابراین می توانیم از

توابع زمانی خود استفاده کنیم . همچنین یک ساختار را برای هر فریم

کلیدی بصورت زیر تعریف می کنیم :

Private Type KeyFrame

Mesh As D3DXMesh ’ شده از یک فایل load شی

MatList() As D3DMATERIAL برای هر شی’ 8 material آرایه

Texture’ TexList() As Direct3DTexture آرایه 8

nMaterials ’ هایی که استفاده می کنیم texture ها و material تعداد

As Long

VertexList() As ’ برای این فریم کلیدی vertex داده های

D3DVERTEX

As Long TimeIndex ’ موقعیت این فریم کلیدی در انیمیشن

End Type

استخراج کرده و X حال باید تابعی بنویسیم که اطلاعات را از یک فایل

درون فریم کلیدی قرار دهد :

Private Function CreateKeyFrameFromFile(Filename As

String, TexturePrefix As String, Time As Long) As

KeyFrame

’ Filename : برای شی سه بعدی X نام فایل

این شی در آن قرار دارد : texture پوشه ای که اطلاعات

’ TexturePrefix

  ٢٩٣

' Time : اندیس زمان برای این فریم کلیدی

Long Dim I As

Dim XBuffer As D3DXBuffer

Dim TextureFile As String

Long Dim hResult As

'خواندن اطلاعات از فایل ورودی به حافظه

CreateKeyFrameFromFile.Mesh = Set

D3DX.LoadMeshFromX(Filename,

D3DDevice, Nothing, XBuffer, ,D3DXMESH_MANAGED

CreateKeyFrameFromFile.nMaterials)x

ها ‘ texture ها و material تولید

ReDim

CreateKeyFrameFromFile.MatList(CreateKeyFrameFro

D3DMATERIAL8 mFile.nMaterials) As

ReDim

CreateKeyFrameFromFile.TexList(CreateKeyFrameFrom

Direct3DTexture8 File.nMaterials) As

For I = 0 To CreateKeyFrameFromFile.nMaterials - 1

,D3DX.BufferGetMaterial XBuffer, I

CreateKeyFrameFromFile.MatList(I)x

= CreateKeyFrameFromFile.MatList(I).Ambient

CreateKeyFrameFromFile.MatList (I).diffuse

D3DX.BufferGetTextureName(XBuffer, I)x = TextureFile

Then "" <> If TextureFile

= (Set CreateKeyFrameFromFile.TexList(I

D3DX.CreateTextureFromFileEx(D3DDevice,

D3DX_DEFAULT, ,TextureFile & TexturePrefix

D3DX_DEFAULT, D3DX_DEFAULT, 0,

,D3DFMT_UNKNOWN, D3DPOOL_MANAGED

,0 ,D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR

ByVal 0, ByVal 0)x

If End

 

٢٩۴

Next I

’vertex استخراج داده های

ReDim

CreateKeyFrameFromFile.VertexList(CreateKeyFrameFr

D3DVERTEX omFile.Mesh.GetNumVertices) As

hResult =

D3DXMeshVertexBuffer8GetData(CreateKeyFrameFrom

((Len(CreateKeyFrameFromFile.VertexList(0 ,0 ,File.Mesh

,reateKeyFrameFromFile.Mesh.GetNumVertices, 0 *

((CreateKeyFrameFromFile.VertexList(0

CreateKeyFrameFromFile.TimeIndex = Time

End Function

خطوط زیر را برای ساخت فریم های کلیدی اضافه Initialize در تابع

می کنیم :

nKeyFrames = 4

2500 = kfAnimLength

AnimLastStartAt = GetTickCount()x

KeyFrame ReDim kfAnim(nKeyFrames - 1) As

& kfAnim(0) = CreateKeyFrameFromFile(App.Path

x(0 ,"\" & App.Path ,"frame0.x\"

& kfAnim(1) = CreateKeyFrameFromFile(App.Path

kfAnimLength * (1 / 3))x ,"\" & frame1.x", App.Path\"

& CreateKeyFrameFromFile(App.Path = (kfAnim(2

kfAnimLength * (2 / 3))x ,"\" & frame2.x", App.Path\"

& kfAnim(3) = CreateKeyFrameFromFile(App.Path

kfAnimLength)x ,"\" & frame3.x", App.Path\"

& CreateKeyFrameFromFile(App.Path = kfCurrent

(0 ,"\" & frame0.x", App.Path\"

 

 

٢٩۵

دقت کنید که از یک اندیس زمان برای ساخت فریم های کلیدی استفاده

شده است .

حال باید کدی برای نمایش دادن انیمیشن بنویسیم . ابتدا باید به روشی

تغییرات فریمها را کنترل کنیم :

For I = 0 To nKeyFrames - 2

kfAnim(I).TimeIndex Then =< If CurrentTimeIndex

PrevFrame = I

NextFrame = I + 1

If End

Next I

دو فریم کلیدی و زمان جاری ، index سپس باید با توجه به زمان

پارامتر درون یابی را محاسبه کنیم :

sTime = kfAnim(PrevFrame).TimeIndex

kfAnim(NextFrame).TimeIndex = eTime

cTime = CurrentTimeIndex

sTime - eTime = eTime

cTime = cTime - sTime

sTime = sTime - sTime

cTime / eTime = InterpolateAmount

سپس باید بر اساس این پارامتر عمل درون یابی را روی داده های

انجام دهیم : vertex

For I = 0 To kfCurrent.Mesh.GetNumVertices

'درون یابی مختصاتها

٢٩۶

,D3DXVec3Lerp vTemp3D

MakeVector(kfAnim(PrevFrame).VertexList(I).X,

_ ,kfAnim(PrevFrame).VertexList(I).Y

,(kfAnim(PrevFrame).VertexList(I).Z

MakeVector(kfAnim(NextFrame).VertexList(I).X,

_ ,kfAnim(NextFrame).VertexList(I).Y

InterpolateAmount ,(kfAnim(NextFrame).VertexList(I).Z

vTemp3D.X = kfCurrent.VertexList(I).X

kfCurrent.VertexList(I).Y = vTemp3D.Y

vTemp3D.Z = kfCurrent.VertexList(I).Z

'درون یابی نرمالها

,D3DXVec3Lerp vTemp3D

,MakeVector(kfAnim(PrevFrame).VertexList(I).nx

_ ,kfAnim(PrevFrame).VertexList(I).ny

,(kfAnim(PrevFrame).VertexList(I).nz

,MakeVector(kfAnim(NextFrame).VertexList(I).nx

_ ,kfAnim(NextFrame).VertexList(I).ny

InterpolateAmount ,(kfAnim(NextFrame).VertexList(I).nz

vTemp3D.X = kfCurrent.VertexList(I).nx

vTemp3D.Y = kfCurrent.VertexList(I).ny

kfCurrent.VertexList(I).nz = vTemp3D.Z

'درون یابی اطلاعات بافت

D3DXVec2Lerp vTemp2D,

,MakeVector2D(kfAnim(PrevFrame).VertexList(I).tu

_ ,(kfAnim(PrevFrame).VertexList(I).tv

                      ٢٩٧

,MakeVector2D(kfAnim(NextFrame).VertexList(I).tu

InterpolateAmount ,(kfAnim(NextFrame).VertexList(I).tv

vTemp2D.X = kfCurrent.VertexList(I).tu

kfCurrent.VertexList(I).tv = vTemp2D.Y

Next I

برگردانیم : Mesh حال باید داده تولید شده را به فرمت

= hResult

D3DXMeshVertexBuffer8SetData(kfCurrent.Mesh, 0,

* ((Len(kfCurrent.VertexList(0

kfCurrent.Mesh.GetNumVertices, 0,

kfCurrent.VertexList(0))x

با استفاده از روش فوق می توانید هر تعداد فریم کلیدی را به انیمیشنتان

برای texture اضافه کنید . اشکالی که روش فوق دارد اینست که اطلاعات

در تمام texture تمام فریمهای کلیدی جداگانه ذخیره شده است در حالیکه

texture pooling فریمها ثابت است . در درسهای بعدی از روشی بنام

ها نگهداری کنیم . texture استفاده می کنیم تا تنها یک کپی از

بخش اول - DirectXAudio آموزش

بخش اول - DirectXAudio آموزش

                                                       

                                                                                                                                    

٢٩٨

موضوع : پخش افکتهای صوتی در برنامه های مالتی مدیا

شما تکنیکهای لازم برای DirectXAudio مقدمه : در سلسله مباحث

اضافه کردن موزیک و افکتهای صوتی سریع و دینامیک را به بازیها و

جایگزینی DirectXAudio . برنامه های مالتی مدیا خواهید آموخت

DirectMusic و DirectSound3D ،DirectSound برای بخشهای

می باشد و دارای امکانات بهتر و سریعتری بوده DirectX موجود در 7

و برنامه نویسی آن نیز ساده تر است .

چگونگی پخش افکتهای صوتی را در DirectXAudio در اولین درس از

برنامه هایتان خواهید آموخت .

: DirectSound کردن Initial

اولین مبحثی است که آنرا توضیح خواهم داد . گرچه DirectSound

می DirectX یک نام عمومی برای امکانات صوتی 8 DirectXAudio

تفاوت وجود دارد . Music و Sound باشد اما بین

DirectSound . با پخش افکتهای صوتی ارتباط دارد DirectSound

سخت افزاری و نرم افزاری device از یکسری Direct3D همانند

استفاده می کند و افکتهای صوتی در یکسری بافر ذخیره می شوند .

اضافه کردن کتابخانه ، DirectSound اولین قدم برای برپاسازی

به پروژه تان می باشد . قدم بعدی تعریف متغیرها و DirectX8

به DirectSound های موردنیاز است . برای استفاده از object

متغیرهای زیر نیاز داریم :

Private DX As DirectX8

DirectSound8 Private DS As

Private DSBuffer As DirectSoundSecondaryBuffer8

                              

                                                                          

٢٩٩

DSEnum As DirectSoundEnum8 Private

Private bLoaded As Boolean

واسط DirectSound شی کنترل کننده مرکزی است . 8 DirectX

های پخش صدا است . interface مراقب برای تمام

واقعی را برای پخش audio داده DirectSoundSecondaryBuffer8

اجازه می دهد که اطلاعاتی را DirectSoundEnum ذخیره می کند . 8

های سخت افزاری/نرم افزاری استخراج کنید و متغیر device در مورد

وضعیت می باشد . flag یک bLoaded

های در دسترس را مشخص کنیم device حال در برنامه باید لیست تمام

device . ( این امر کاملاً امکان پذیر است که یک کامپیوتر بیش از یک

داشته باشد ) : DirectSound برای

Private Sub Form_Load()x

bLoaded = False

As Long Dim I

Set DX = New DirectX8

Set DSEnum = DX.GetDSEnum

DSEnum.GetCount For I = 1 To

MsgBox(DSEnum.GetDescription(I))x

Next I

Sub End

های شناخته شده را انتخاب کردیم . حال device فرض کنیم که یکی از

را واقعا برپا کنیم : device بایستی

If bLoaded Then

Set DSBuffer = Nothing

Nothing = Set DS

Set DX = Nothing

 

٣٠٠                                                                                                          

End If

Dim DSBDesc As DSBUFFERDESC

New DirectX8 = Set DX

= Set DS

DX.DirectSoundCreate(DSEnum.GetGuid(devicenumber)

)x

frmMain.hWnd, DS.SetCooperativeLevel

DSSCL_NORMAL

ای است که شما می خواهید با آن device شماره devicenumber متغیر

فایل صوتی شما را توصیف می کند . DSBDesc . کار کنید

بخش دوم - DirectXAudio آموزش

موضوع : پخش افکتهای صوتی در برنامه های مالتی مدیا

را DirectSound کردن آن : تاکنون ما توانستیم play ساخت بافر و

های component کنیم . همانطور که می دانید در تمام initial

داده ها در یکسری بافر ذخیره می شوند . در مورد DirectX

نیز ما یک بافر با نام DirectSound

می سازیم و داده های صوتی را DirectSoundSecondaryBuffer8

در آن قرار می دهیم . برخی پارامتر ها هستند که باید برای بافر تنظیم

بودن بافر ، 8 بیتی یا 16 بیتی بودن بافر ، mono یا stereo : شوند مثل

44 و غیره ) . اگر این پارامترها را khz ،khz فرکانس صوتی ( 22

از اطلاعات فایل صوتی استفاده می کند . DirectSound مشخص نکنیم

                                         

                                                          

٣٠١

در یک کاربرد ساده ، ما تنها یک بافر صوتی از یک فایل ایجاد می کنیم

اما امکان ایجاد چندین بافر بطور همزمان و نیز پخش چندین صدا بطور

همزمان نیز وجود دارد :

DSBDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or

DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME

DS.CreateSoundBufferFromFile(App.Path = Set DSBuffer

Sample.wav", DSBDesc)x\" &

SOUND BUFFER CREATED:"x" MsgBox

bytes" & DSBDesc.lBufferBytes & " :MsgBox "Buffer Size

kb)"x" & (Round(DSBDesc.lBufferBytes / 1024, 3 & ")

& ":MsgBox "Buffer Channel Count

DSBDesc.fxFormat.nChannelsIIf(DSBDesc.fxFormat.nCh

Stereo)")x) " ,"(annels = 1, " (Mono

& " :MsgBox "Buffer Bits per channel

bits"x " & DSBDesc.fxFormat.nBitsPerSample

load در بالا یک بافر صوتی ایجاد شده و اطلاعات صدا از فایل به بافر

شده است .

کنیم : play حال بایستی داده صوتی موجود در بافر را

: loop کردن بافر بصورت Play دستور لازم برای

DSBuffer.Play DSBPLAY_LOOPING

: loop کردن بافر بدون Play دستور لازم برای

DSBuffer.Play DSBPLAY_DEFAULT

٣٠٢

کردن بافر : Stop دستورات لازم برای

DSBuffer.Stop

0 DSBuffer.SetCurrentPosition

کردن بافر : Pause دستور لازم برای

DSBuffer.Stop

تنظیم خصوصیات بافر : سه خصوصیت وجود دارد که در مورد بافر

frequency و volume ،pannig تنظیم می شود

بین اعداد زیر است : pannig محدوده مقادیر

10،000- = DSBPAN_LEFT

DSBPAN_CENTER = 0

DSBPAN_RIGHT = 10,000

بافر را تنظیم کرد : pannig می توان SetPan توسط متد

DSBuffer.SetPan yourValue

صدا را تقویت نمی کند بلکه آنرا تضعیف می نماید DirectSound

ای که فایل صوتی volume عبارت است از volume بنابراین ماکزیمم

بین اعداد volume با آن ضبط شده است . بعبارت دیگر محدود مقادیر

زیر است :

DSBVOLUME_MAX = 0

DSBVOLUME_MIN = -10000

بافر را تنظیم کرد : volume می توان SetVolume توسط متد

٣٠٣

DSBuffer.SetVolume yourValue

عبارت است از : DirectSound محدود فرکانسی

DSBFREQUENCY_MIN = 100 (hz)x

hz) = 100khz x) 100000 = DSBFREQUENCY_MAX

می توان فرکانس بافر را تنظیم کرد : SetFrequency توسط متد

DSBuffer.SetFrequency yourValue

بخش سوم - DirectXAudio آموزش

DirectMusic موضوع : پخش موزیک توسط

مقدمه :

با چگونگی پخش افکتهای DirectXAudio در اولین درس از آموزش

ساده engine صوتی آشنا شدید . اکنون این توانایی را دارید که یک

صوتی بنویسید . در این بخش مبانی پخش موزیک را فرا خواهید گرفت .

پس از این درس شما می توانید یک ماژوال برای پخش موزیکهای پس

زمینه و افکتهای صوتی برای برنامه هایتان ایجاد کنید .

: DirectMusic کردن 8 Initil

٣٠۴

را مقداردهی اولیه کنید . DirectMusic قبل از هر کار بایستی ماژول 8

اینکار بصورت زیر انجام می شود :

Option ExplicitImplements DirectXEvent8

oDX As DirectX8 Private

Private oDMPerf As DirectMusicPerformance8

oDMLoader As DirectMusicLoader8 Private

Private oDMSeg As DirectMusicSegment8

Dim dmParams As DMUS_AUDIOPARAMS

Set oDX = New DirectX8

oDMPerf = oDX.DirectMusicPerformanceCreate Set

oDX.DirectMusicLoaderCreate = Set oDMLoader

oDMPerf.InitAudio frmMain.hWnd,

dmParams, Nothing, ,DMUS_AUDIOF_ALL

128 ,DMUS_APATH_DYNAMIC_STEREO

oDMPerf.SetMasterAutoDownload True

load کمک می کند تا موزیک درون بافر DirectMusicLoader شی 8

شود .

مموزیکی را که باید پخش شود ذخیره DirectMusicSegment شی 8

می کند .

کد فوق کافی است یکبار زمانیکه برنامه آغاز می شود ، اجرا گردد .

داریم اما قبل از DirectMusic اکنون ما یک واسط مقدار دهی شده از

کردن terminate کرده و پخش کنیم چگونگی Load اینکه موزیک را

را در زیر می بینید : DirectMusic

If ObjPtr(oDMSeg)Then Set oDMSeg = Nothing

ObjPtr(oDMLoader)Then Set oDMLoader = Nothing If

Then (If Not (oDMPerf Is Nothing

٣٠۵

oDMPerf.CloseDown

Set oDMPerf = Nothing

End If

Then Set oDX = Nothing (If ObjPtr(oDX

پیغامها :

Input , Sound , مثل DirectX های 8 component در برخی از

را برپا کند messaging برنامه شما بایستی یک سیستم Play و Music

زمان وقوع برخی رخدادهای خاص را بشما گزارش دهد . DirectX تا

این مطلب بخصوص زمانیکه یک موزیک را پخش می کنید مفید است

برای مثال می تواند زمان خاتمه یافتن موزیک را به شما اطلاع دهد و

آنگاه شما می توانید قطعه موزیک بعدی را پخش کنید .

انجام می شوند . کد زیر را در تابع callback پیغامها توسط یک سیستم

قرار دهید : DirectMusic کردن 8 initial تان پس از InitDMusic

oDMPerf.AddNotificationType

DMUS_NOTIFY_ON_SEGMENT

hEvent = oDX.CreateEvent(Me)x

oDMPerf.SetNotificationHandle hEvent

می گوید چه نوع پیغامهایی را می خواهید DirectMusic اولین سطر به

به برنامه تان بفرستد . چندین نوع پیغام وجود دارد :

اطلاعات موزیک فعلی ( = DMUS_NOTIFY_ON_SEGMENT

شروع پخش ، پایان پخش و غیره )

موزیک chord اطلاعات تغییر = DMUS_NOTIFY_ON_CHORD

http://sheidaian.persianblog.com

http://iranmehr.bizhat.com توسط گروه ایران مھر sheidaian.persianblog برگرفتھ از سایت

٣٠۶

event زمانیکه یک = DMUS_NOTIFY_ON_COMMAND

فرمانی صدا زده شود .

اطلاعات = DMUS_NOTIFY_ON_MEASUREANDBEAT

مربوط به موزیک فعلی beat/measure

مربوط event که = DMUS_NOTIFY_ON_PERFORMANCE

می باشد . performance به سطح

recomposition که = DMUS_NOTIFY_ON_RECOMPOSE

می باشد . event

آخرین بخش از پیغام دهی ، تابع اصلی آن می باشد . همانطور که در

دیدید یک توصیف بصورت DirectMusic کردن Initial بخش

callback داشتیم . بخش اصلی تابع Implements DirectXEvent8

است که بین select case شامل یک ، DirectXEvent مربوط به 8

پیغامهای مختلف سوئیچ می کند :

As Private Sub DirectXEvent8_DXCallback(ByVal eventid

Long)x

If eventid = hEvent Then

Dim dmMSG As DMUS_NOTIFICATION_PMSG

If Not oDMPerf.GetNotificationPMSG(dmMSG) Then

Else

dmMSG.lNotificationOption Select Case

Case DMUS_NOTIFICATION_SEGABORT

DMUS_NOTIFICATION_SEGALMOSTEND Case

Case DMUS_NOTIFICATION_SEGEND

DMUS_NOTIFICATION_SEGLOOP Case

Case DMUS_NOTIFICATION_SEGSTART

Case Else

End Select

End If

End If

End Sub

٣٠٧

پخش موزیک / متوقف کردن موزیک :

کنید . اینکار توسط کد load برای پخش یک موزیک ابتدا بایستی آنرا

زیر انجام می شود :

x"\" & oDMLoader.SetSearchDirectory App.Path

& Set oDMSeg = oDMLoader.LoadSegment(App.Path

FILENAME)oDMSeg.SetStandardMidiFile

MID ،WAV : تنها چهار نوع فرمت صوتی را می پذیرد DirectMusic

. SEG و RMI ،

استفاده کنید که DirectXShow بایستی از MP برای پخش فایلهای 3

آنرا در درسهای بعدی خواهید دید .

شد می توانید آنرا load اکنون که داده های فایل صوتی درون بافر

پخش کنید :

oDMSeg.SetRepeats 0

oDMSeg, oDMPerf.PlaySegmentEx

DMUS_SEGF_DEFAULT, 0

تنظیم کنید . اگر این مقدار SetRepets تعداد پخش شدن فایل را با متد

صفر باشد ، آهنگ تنها یکبار پخش می شود و اگر 1- باشد بطور ممتد

پخش خواهد شد .

برای متوقف کردن موزیک از کد زیر استفاده کنید :

DMUS_SEGF_DEFAULT ,oDMPerf.StopEx oDMSeg, 0

٣٠٨

استقاده کنید : SetMasterVolume برای تنظیم میزان صدا از متد

oDMPerf.SetMasterVolume yourvalue

رنج صدا بین 20 + دسی بل تا 200 - دسی بل است .

استفاده کنید : SetMasterTempo از متد Tempo برای تنظیم

oDMPerf.SetMasterTempo yourvalue/ 100

برابر 1 می باشد . عدد 2 سرعت را دو برابر می کند و tempo بطور نرمال

عدد 0 موزیک را قطع می کند

بخش چهارم - DirectXAudio آموزش

DirectSound3D موضوع : ایجاد صدای سه بعدی توسط

مقدمه

تاکنون با چگونگی پخش افکتهای صوتی و موسیقی پس زمینه توسط

آشنا شدید . این مطالب برای کاربردهای ساده DirectXAudiuo

مناسبند اما اینکه فقط ما صدای استریو داشته باشیم کافی نیست و در

کاربردهاب حرفه ای بایستی از صداهای کاملا سه بعدی استفاده کنیم .

با استفاده از افکتهای صوتی سه بعدی می توانیم صدا را در تمام جهتها

برای کاربر شبیه سازی کنیم اما با همه مزایای صدای سه بعدی ، دو

اشکال برای آن وجود دارد : اول اینکه پخش صدای سه بعدی پیچیده تر

٣٠٩

از پخش صدای عادی است و تنها کارت های سخت افزاری جدید بطور

کاملا واقعی از آن پشتیبانی می کنند و دوم اینکه صدای سه بعدی با 4

بلندگو یا بیشتر حاصل می شود – کیفیت حالت 2 بلندگو بد نیست اما

در مقایسه با حالت 4 بلندگو ، بسیار کیفیت صدای سه بعدی پایین است

.

DirectSound3D برپاسازی

برپاسازی صدای سه بعدی چندان پیچیده نیست اما هر بافر صوتی که

را به سیستم تان overhead برای یک صدای سه بعدی می سازید ، یک

اضافه می کند . همچنین برخی درایورها هستند که تنها اجازه ایجاد

تعداد محدودی بافر سه بعدی را در یک لحظه می دهند و نیز اغلب

درایورها تعداد بافرهای سه بعدی که می توان در یک لحظه پخش کرد را

محدود می کنند ( معمولاً 8 تا 16 بافر ) .

اولین قدم در استفاده از صدای سه بعدی تعریف متغیرها و اشیا زیر

است :

Dim DSBuffer As DirectSoundSecondaryBuffer8

DSBuffer3D As DirectSound3DBuffer8 Dim

DirectSound3DListener8 Dim DSBListener As

تنها دو شی آخر برای شما جدید هستند . شی

یک ارائه سه بعدی از بافرهای عادی است . DirectSound3dBuffer8

برای نگهداری داده DirectSoundSecondaryBuffer ما همچنان از 8

برای نگهداری DirectSound3Dbuffer صوتی استفاده می کنیم و از 8

پارامترهای سه بعدی و تنظیمات سه بعدی استفاده می کنیم . شی

٣١٠

است و برای تنظیم listener نیز یک DirectSound3Dlistener8

کردن سرعت و جهت صدا و برخی پارامترهای دیگر استفاده می شود .

مرحله دوم ، ساخت بافر صوتی است . این کار در دو بخش انجام می

شود . اول ما یک بافر صوتی نرمال می سازیم و سپس یک واسط بافر

صوتی سه بعدی را از آن بدست می آوریم :

DSBuffer.Stop If Not (DSBuffer Is Nothing) Then

Set DSBuffer = Nothing

DSBDesc.lFlags = DSBCAPS_CTRL3D Or

DSBCAPS_CTRLVOLUME

Set DSBuffer = DS.CreateSoundBufferFromFile(App.Path

blip.wav", DSBDesc)x\" &

Then 1 < If DSBDesc.fxFormat.nChannels

You can only use mono (1 channel) sounds with " MsgBox

DirectSound3D"x

End If

optLow.Value Then DSBDesc.guid3DAlgorithm = If

GUID_DS3DALG_NO_VIRTUALIZATION

optMedium.Value Then DSBDesc.guid3DAlgorithm = If

GUID_DS3DALG_HRTF_LIGHT

optHigh.Value Then DSBDesc.guid3DAlgorithm = If

GUID_DS3DALG_HRTF_FULL

DSBuffer = DS.CreateSoundBufferFromFile(App.Path Set

DSBDesc)x ,"blip.wav\" &

Set DSBuffer3D = DSBuffer.GetDirectSound3DBuffer()x

سه نکته است که باید به آن دقت شود :

بسیار مهم است . شما اگر DSBCAPS_CTRL3D 1 – اضافه کردن

این پارامتر را بکار نبرید ، قادر نخواهید بود که واسط سه بعدی را

بدست آورید .

تک کاناله ) استفاده کنیم ) Mono 2 – ما بایستی تنها از افکتهای صوتی

٣١١

زیرا افکت صوتی استریو در صدای سه بعدی معنا ندارد زیرا صدا از یک

نقطه در فضای سه بعدی می آید .

3 – سطح الگوریتم سه بعدی – که در پارامتر

NO آمده . حالت DSBDesc.guid3Dalgorhthm

استفاده می کند و روی تمام CPU تنها از VIRTULIZATION

HRTF LIGHT سیستم ها کار می کند اما افکتها مینیمم هستند . حالت

و هم سخت افزار کارت صوتی استفاده می کند و کیفیت CPU هم از

FULL HRTF بهتری را نسبت به خالت اول ارائه می دهد . حالت

بهترین حالت است اما در صورتی درست کار می کند که یک سخت افزار

سه بعدی داشته باشید .

است : listener آخرین پارامتری که باید تنظیم کنیم شی

DSBDesc_2.lFlags = DSBCAPS_CTRL3D Or

DSBCAPS_PRIMARYBUFFER

Set DSBPrimary =

x (DS.CreatePrimarySoundBuffer(DSBDesc_2

DSBPrimary.GetDirectSound3Dlistener = Set DSBListener

,#0 ,#1 ,#0 ,DSBListener.SetOrientation 0#, 0#, 1#

DS3D_IMMEDIATE

تا اینجا صدای سه بعدی ما آماده است و می توانیم برخی پخش بافر را

مشابه درسهای قبلی شروع کنید .

پارامترهای اختیاری :

چند پارامتر وجود دارد که می توان آنها را تغییر داد :

٣١٢

عدد 0 بیشترین میزان صدا و عدد 3000 - کمترین میزان : Volume – 1

صدا را دارد :

Sub If DSBuffer Is Nothing Then Exit

DSBuffer.SetVolume scrlVolume.Value

: listener تنظیم محل : Position – 2

,DSBuffer3D.SetPosition Src_X, 0, Src_Y

DS3D_IMMEDIATE

DSBListener.SetPosition Src_X, 0, Src_Y,

DS3D_IMMEDIATE

تنظیم سرعت و جهت منبع صدا : : Velocity – 3

DS3D_IMMEDIATE ,DSBuffer3D.SetVelocity X, Y, Z

DSBListener.SetVelocity X, Y, Z, DS3D_IMMEDIATE

انحراف صدا از مسیری که می پیماید انحراف : Dppler Effect – 4

سرعت حرکت صدا :

CSng(scrlDoppler.Value), DSBListener.SetDopplerFactor

DS3D_IMMEDIATE

چگونگی تضعیف صدا با تغییر فاصله Rolloff Effect : rolloff – 5

است .

CSng(scrlRolloff.Value), DSBListener.SetRolloffFactor

DS3D_IMMEDIATE

٣١٣

ماکزیمم فاصله ای که یک صدا می تواند شنیده شود : : Distance – 6

DS3D_IMMEDIATE ,DSBuffer3D.SetMaxDistance 250

DSBuffer3D.SetMinDistance 0.01, DS3D_IMMEDIATE

مقدمه – DirectX Input آموزش

مقدمه - DirectX Input آموزش

مقدمه

شما می آموزید که DirectX Input در بخش مباحث برنامه نویسی

چگونه اطلاعات ورودی را از کاربر بگیرید . این اطلاعات می تواند از طریق

کیبرد ، ماوس ، جوی استیک یا گیم پد باشد .

بنابراین در پایان این سلسله مباحث قادر خواهید بود که یک بازی

بنویسید و یا یک برنامه مالتی مدیا که بتواند توسط کاربر کنترل شود .

ساده ترین و سریع ترین روش برای گرفتن داده ها از هر DirectInput

نوع ابزار ورودی می باشد .

مباحث این بخش

بخش اول : چگونگی دریافت اطلاعات از کیبرد

٣١۴

بخش دوم : چگونگی دریافت اطلاعات از ماوس

Action Mapping بخش سوم : راهنمای استفاده از

بخش اول - DirectX Input آموزش

گرفتن اطلاعات ورودی از کیبرد - 1

مقدمه

8 همانطور که از نامش مشخص است به شما اجازه می Direct Input

دهد که بتوانید برنامه هایی بنویسید که توسط هر نوع دستگاه ورودی

کنترل شود .

دارای چندین مزیت نسبت به استفاده از کنترلهای Direct Input 8

,Form_KeyUp ورودی خود ویژوال بیسیک دارد – کنترلهایی مثل

و همچنین قابلیت کنترل - Form_KeyDown, Form_MouseMove

GetCursorPos, از قبیل Win بیشتری نسبت به توابع استاندارد 32

دارد . GetKeyState

سریعتر ، کاراتر و قدرتمند تر بوده و برای ساخت Direct Input 8

بازیها طراحی شده بنابراین باعث کندی برنامه ها نخواهد شد .

برای گرفتن ورودی از کیبرد Direct Input چگونگی کار با 8

وجود دارد : روش DirectX دو روش برای استفاده از کیبرد در 8

که هر دو دارای مزایا و معایبی هستند . event-based و روش polling

استفاده می شود event-based بطور کلی در اغلب طراحیها از روش

زیرا کار با آن راحت تر اسن . در این روش هر پیغام فرستاده شده

٣١۵

می شود و برنامه نیازی به هیچگونه log ازطرف دستگاه ورودی

پردازشی بمنظور منتظر ماندن برای یک پیغام از طرف ورودی ندارد ،

کنترل کمی دقیقتر و راحتر polling بنابر این کاراتر است . در روش

است .

event و بر مبنای polling اگر در مورد برنامه نویسی بر مبنای

اطلاعات کافی ندارید می توانید از منابع موجود در سایتهایی چون

استفاده کنید . GameDev و Gamasutra

Polling روش

مراحل این روش عبارتند از :

به نام TextBox یک فرم ایجاد کرده و یک : Declerations 1 – تعریفات

Vertical Scroll و Locked ،Multiline با خصوصیات txtOutput

در آن قرار دهید . کدهای زیر را در بخش کدنویسی این فرم Bar

بنویسید :

True = Private Const UsePollingMethod As Boolean

Private Const UseEventMethod As Boolean = False

باشد . True ‘نکته مهم اینست که تنها یکی از دو ثابت فوق بایستی

Boolean Private bRunning As

استفاده می شود polling ‘این متغیر برای

DirectX8 Private DX As

Private DI As DirectInput8

DirectInput و شی DirectX ‘تعریف شی اصلی

Private DIDevice As DirectInputDevice8

DIKEYBOARDSTATE Private DIState As

این دو شی برای دسترسی به دستگاه ورودی ( کیبرد ) استفاده می

٣١۶

شوند

Private KeyState(0 To 255) As Boolean

آرایه ای برای تشخیص فشرده شدن کلید

Private Const BufferSize As Long = 10

این مقدار event-based ها . در روش event ‘ سایز بافر نگهدارنده

برابر 10 تا 20 است ( بسته به سرعت polling برابر یک و در روش

حلقه بازی )

Private Declare Sub Sleep Lib "kernel32" (ByVal

dwMilliseconds As Long)x

در صورت بالا بودن نرخ polling برای متوقف کردن حلقه Sleep ‘ تابع

ورودی

این بخش سه مرحله دارد : : Initialisation -2 مقدار دهی اولیه

ها ساخته می شوند . Device در مرحله اول اشیا و

انجام می شود . Device در مرحله دوم تنظیمات مربوط به

می گوئیم که می خواهیم شروع به استفاده Device در مرحله سوم به

از آن کنیم .

کدهای زیر را بنویسید : Form_Load در

Me.Show

Dim I As Long

DIPROPLONG Dim DevProp As

Dim DevInfo As DirectInputDeviceInstance8

BufferSize) As Dim pBuffer(0 To

DIDEVICEOBJECTDATA

Then If UsePollingMethod And UseEventMethod

MsgBox "You must select only one of the constants before

٣١٧

running"x

Unload Me

End

End If

txtOutput.Text = "Using If UsePollingMethod Then

vbCrLf & "Polling Method

txtOutput.Text = "Using Event If UseEventMethod Then

vbCrLf & "Based Method

مقداردهی اولیه روش انتخاب شده

Set DX = New DirectX8

Set DI = DX.DirectInputCreate

DI.CreateDevice("GUID_SysKeyboard")x = DIDevice Set

DIDevice.SetCommonDataFormat

DIFORMAT_KEYBOARD

DIDevice.SetCooperativeLevel frmMain.hWnd,

Or ISCL_NONEXCLUSIVE DISCL_BACKGROUND

برپاسازی بافر

DIPH_DEVICE = DevProp.lHow

DevProp.lData = BufferSize

DIPROP_BUFFERSIZE, DevProp DIDevice.SetProperty

به دایرکت ایکس می گوئیم که می خواهیم از دستگاه ورودی استفاده

کنیم

DIDevice.Acquire

استخراج اطلاعاتی در مورد دستگاه ورودی

Set DevInfo = DIDevice.GetDeviceInfo()x

٣١٨

& " :Product Name" & txtOutput.Text = txtOutput.Text

vbCrLf & DevInfo.GetProductName

& " :Device Type" & txtOutput.Text = txtOutput.Text

vbCrLf & DevInfo.GetDevType

& " :GUID" & txtOutput.Text = txtOutput.Text

vbCrLf & DevInfo.GetGuidInstance

در صورتی که بخواهیم به برنامه خاتمه بدهیم کدهای زیر را می

نویسیم

DIDevice.Unacquire

Nothing = Set DIDevice

Set DI = Nothing

Set DX = Nothing

Me Unload

End

3 – گرفتن ورودی از کیبرد : در این بخش فرض کنید بخواهیم یک بازی

شبیه سازی کنیم . در این حلقه هر بار فشرده Do-Loop را در یک حلقه

شدن کلیدهای کیبرد را چک می کنیم :

If Not Err.Number Then bRunning = True

While bRunning Do

دریافت اطلاعات شامل خواندن وضعیت کیبرد ، خواندن اطلاعات بافر و

سپس خطا

DIState DIDevice.GetDeviceStateKeyboard

٣١٩

DIDevice.GetDeviceData pBuffer, DIGDD_DEFAULT

DI_BUFFEROVERFLOW Then = If Err.Number

Msgbox(“BUFFER OVERFLOW (Compensating)...")x

:ENDOFLOOP GoTo

End If

بررسی فشرده شدن کلیدها

For I = 0 To 255

DIState.Key(I) = 128 And (Not KeyState(I) = True) If

Then

& " { DOWN }" & txtOutput.Text = txtOutput.Text

vbCrLf &((KeyNames(CInt(I

txtOutput.SelStart = Len(txtOutput.Text)x

KeyState(I) = True

If End

Next I

بررسی رها شدن کلید

For I = 0 To BufferSize

KeyState(pBuffer(I).lOfs) = True And pBuffer(I).lData If

Then = 0

KeyState(pBuffer(I).lOfs) = False

& " { UP }" & txtOutput.Text = txtOutput.Text

vbCrLf & ((KeyNames(CInt(pBuffer(I).lOfs

txtOutput.SelStart = Len(txtOutput.Text)x

End If

I Next

Sleep (50)x

DoEvents

:ENDOFLOOP

Loop

٣٢٠

وجود دارد که نام کلید فشارداده شده را KeyName در کد فوق یک تابع

بر می گرداند . بخشی از این تابع را در زیر می بینید :

String Function KeyNames(iNum As Integer) As

Dim aKeys(0 To 255) As String

"DIK_ESCAPE" = (aKeys(1

aKeys(2) = "DIK_1 On main keyboard"x

main keyboard"x aKeys(3) = "DIK_2 On

aKeys(4) = "DIK_3 On main keyboard"x

main keyboard"x aKeys(5) = "DIK_4 On

aKeys(6) = "DIK_5 On main keyboard"x

main keyboard"x aKeys(7) = "DIK_6 On

aKeys(8) = "DIK_7 On main keyboard"x

main keyboard"x aKeys(9) = "DIK_8 On

aKeys(10) = "DIK_9 On main keyboard"x

On main keyboard"x aKeys(11) = "DIK_0

aKeys(12) = "DIK_MINUS On main keyboard"x

DIK_EQUALS On main keyboard"x" = (aKeys(13

aKeys(14) = "DIK_BACK BACKSPACE"x

DIK_TAB"x" = (aKeys(15

aKeys(16) = "DIK_Q"x

aKeys(17) = "DIK_W"x

DIK_E"x" = (aKeys(18

aKeys(19) = "DIK_R"x

aKeys(20) = "DIK_T"x

.

.

.

KeyNames = aKeys(iNum)x

٣٢١

End Function

بخش دوم - DirectX Input آموزش

Event-Based موضوع : کنترل کیبرد با روش

مشابه روش Event-Based مقداردهی اولیه و مفاهیم اصلی در روش

است و تنها بایستی ساختار بخش جمع آوری داده و حلقه Polling

بصورت Event-Based پردازشی را تغییر دهیم . مراحل کار با روش

زیر می باشد :

1 - تعاریف و مقداردهی اولیه : در بخش تعاریف دو تعریف جدید

بصورت زیر داریم :

Dim hEvent As Long

DirectXEvent8 Implements

یک پارامتر هندل برای یک می باشد . hEvent

این امر با DirectX ، نکته : زمانی که کلیدی فشرده یا رها می شود

به برنامه DirectXEvent8_DXCallback فراخوانی تابعی به اسم

گویند ) . Back Function Call شما اطلاع می دهد . ( این نوع توابع را

این تابع به برنامه شما می گوید که یک رویداد اتفق افتاده است و

بایستی بافرها را چک کند .

٣٢٢

تنها تغییری که در بخش مقداردهی اولیه نیاز است ، برپاسازی یک

می باشد : event

If UseEventMethod Then

DX.CreateEvent(frmMain)x = hEvent

DIDevice.SetEventNotification hEvent

If End

اضافه کنید : event در انتهای برنامه نیز کد زیر را برای از بین بردن

hEvent Then DX.DestroyEvent 0 <> If hEvent

برای این بخش کدهایی را در داخل تابع : event 2 - استفاده از

می نویسیم : DirectXEvent8_DXCallback

As Private Sub DirectXEvent8_DXCallback(ByVal eventid

Long)x

'متغیرهای موردنیاز

Dim I As Long

As (Dim pBuffer(0 To BufferSize

DIDEVICEOBJECTDATA

If eventid = hEvent Then

Exit Sub If DIDevice Is Nothing Then

داده را از کیبرد می گیریم event 'درصورت رخ دادن

DIDevice.GetDeviceStateKeyboard DIState

DIGDD_DEFAULT ,DIDevice.GetDeviceData pBuffer

'چک کردن تمام کلیدها برای اینکه متوجه شویم چه اتفاقی افتاده است

For I = 0 To 255

٣٢٣

است . key_down event 'عدد 128 نشان دهنده

DIState.Key(I) = 128 Then If

If pBuffer(0).lData = 128 Then

& " { DOWN }" & txtOutput.Text = txtOutput.Text

vbCrLf & ((KeyNames(CInt(I

If End

End If

'کد فوق برای بررسی فشرده شدن یک کلید بود . کد زیر رها شدن کلید

را بررسی می کند

Then (If (pBuffer(0).lData = 0 And pBuffer(0).lOfs = I

& "{ UP }" & txtOutput.Text = txtOutput.Text

vbCrLf & ((KeyNames(CInt(I

End If

txtOutput.SelStart = Len(txtOutput.Text)x

I Next

End If

End Sub

بخش سوم - DirectX Input آموزش

DirectX Input موضوع : کنترل ماوس با

مقدمه :

برای استفاده از ماوس در برنامه های مالتی مدیا و بازیها همانند کی برد

٣٢۴

می توانیم از امکانات دایرکت ایکس استفاده کنیم . روش کنترل ماوس

بسیار ساده بوده و مشابه کنترل کیبرد می DirectX Input توسط

باشد بنابراین درصورتی که دو درس گذشته را نخوانده این پیشنهاد می

کنم ابتدا آنها را مطالعه کنید .

: Device برپاسازی

علاوه بر متغیرهایی که در بخش کنترل کیبرد تعریف شد بایستی

متغیرهای جدید زیر را نیز در ابتدای برنامه تان تعریف کنید :

Private Const mSpeed As Single = 2

BufferSize As Long = 10 Private Const

Private mPosition As Point

مقدار سرعت حرکت کرسر ماوس را مشخص می کند . mSpeed

می باشد . DI سایز بافر BufferSize

موقعیت جاری کرسر ماوس را نشان می دهد . mPosition

در مرحله بعدی بایستی مقداردهی های اولیه لازم را انجام دهید :

DI.CreateDevice("guid_SysMouse")x = Set DIDevice

Call

DIDevice.SetCommonDataFormat(DIFORMAT_MOUSE)

x

DIDevice.SetCooperativeLevel(frmMain.hWnd, Call

DISCL_EXCLUSIVE)x DISCL_FOREGROUND Or

تفاوت عمده کدهای فوق با کدهای مقداردهی اولیه در بخش کی برد

٣٢۵

تغییر کرده است . در اینجا گفته شده که cooperativelevel آنست که

ما می خواهیم از ماوس بصورت انحصاری در برنامه استفاده کنیم . این

مناسب نیست و بهترست از آن window-base حالت برای برنامه های

هستند استفاده کنید . full screan در بازیهایی که بصورت

خواندن ورودی از ماوس :

event-based و هم polling در این بخش می توانید هم از روش

Direct استفاده کنید . نکته مهمی که در اینجا وجود دارد آنست که

فقط حرکت داده شدن ماوس و کلیک شدن یک دکمه را به شما Input

single click و double click اطلاع می دهد و برای تشخیص حالتهای

خودتان بایستی کد بنویسید برای مثال اگر فاصله زمانی بین دو کلیک

بوده است . double click کمتر از 40 میلی ثانیه باشد آنگاه این یک

کد زیر حرکت داده شدن ماوس و کلیک یکی از سه دکمه آنرا اطلاع می

دهد :

Dim DevData(1 To BufferSize) As

DIDEVICEOBJECTDATA

Dim nEvents As Long

Dim I As Long

DIDevice.GetDeviceData(DevData, = nEvents

DIGDD_DEFAULT)x

nEvents For I = 1 To

Select Case DevData(I).lOfs

Case DIMOFS_X

mPosition.x + (DevData(I).lData * mSpeed)x = mPosition.x

mPosition.x = 0 Then 0 > If mPosition.x

= frmMain.ScaleWidth Then mPosition.x < If mPosition.x

frmMain.ScaleWidth

٣٢۶

imgCursor.Top = mPosition.y

mPosition.x = imgCursor.Left

mPosition.x & "] :lablel(1).Caption = "Mouse Coordinates

x"[" & mPosition.y & " ," &

Case DIMOFS_Y

mPosition.y + (DevData(I).lData * mSpeed)x = mPosition.y

mPosition.y = 0 Then 0 > If mPosition.y

= frmMain.ScaleHeight Then mPosition.y < If mPosition.y

frmMain.ScaleHeight

imgCursor.Top = mPosition.y

mPosition.x = imgCursor.Left

mPosition.x & "] :lablel(1).Caption = "Mouse Coordinates

x"[" & mPosition.y & " ," &

DIMOFS_BUTTON0 Case

& " :label(2).Caption = "Button 0 State

IIf(DevData(I).lData = 0, "Up", "Down")x

DIMOFS_BUTTON1 Case

& " :label(3).Caption = "Button 1 State

IIf(DevData(I).lData = 0, "Up", "Down")x

DIMOFS_BUTTON2 Case

& " :label(4).Caption = "Button 2 State

IIf(DevData(I).lData = 0, "Up", "Down")x

DIMOFS_BUTTON3 Case

& " :label(5).Caption = "Button 3 State

IIf(DevData(I).lData = 0, "Up", "Down")x

End Select

Next I

Do بایستی آنرا در یک حلقه ، Polling برای استفاده از کد فوق در روش

٣٢٧

قرار دهید . while-Loop

بایستی آنرا درون ، Event-Based برای استفاده از کد فوق در روش

قرار دهید . DirectXEvent8_DXCallback روتین

ترفندها

تشخیص فشرده شدن کلیدهای کیبرد

یکی از دوستان سوال کرده بودند که چگونه می توان کلیدهای کیبرد را

حتی وقتی فوکوس روی برنامه ما نیست تشخیص داد مانند دیکشنری

ها که Keylogger فعال می شوند و یا CTRL+F ها که مثلاً با 12

کلیدهای فشرده شده را ثبت می کنند .

من دو روش زیر را برای اینکار پیشنهاد می کنم :

GetAsyncKeyState 1 - استفاده از یک تابع کتابخانه ای به اسم

این تابع ، فشرده شدن یا رها شدن یک . user32.dll موجود در کتابخانه

کردن این تابع بصورت زیر declare کلید را تشخیص می دهد . نحوه

است :

Private Declare Function GetAsyncKeyState Lib "user32"

(ByVal vKey As Long) As Integer

آن کد زیر را قرار event قرار داده و در timer حال در برنامه تان یک

دهید :

For i = 1 To 255

results = 0

٣٢٨

results = GetAsyncKeyState(i)

If results <> 0 Then

Msgbox(Chr(i))

End If

Next

برای مشاهده یک برنامه نمونه به این آدرس مراجعه کنید .

قلاب ، یک ابزار در مکانیزم مدیریت پیغام : Hook 2 - استفاده از قلاب یا

سیستم ویندوز است که توسط آن برنامه ها می توانند یک روتین را

برای مدیریت و پردازش پیغامهای خاصی قبل از اینکه آن پیغامها به

برنامه مقصد برسند نصب نمایند . قلابها باعث کندی سیستم می شوند

زیرا حجم پردازشی سیستم روی هر پیغام را افزایش می دهند بنابراین

بایستی زمانیکه واقعا به قلاب نیاز دارید آنرا نصب نموده و هر چه

زودتر آنرا حذف نمایید . سیستم ویندوز از انواع زیادی از قلابها

پشتیبانی می کند که هر کدام امکان دستیابی به پیغامهای خاصی را مهیا

می نمایند برای مثال یک برنامه کاربردی می تواند با استفاده از قلاب

کیبرد برای مدیریت و پردازش پیغامهای مربوط به آن ( مثل فشرده

شدن یک کلید خاص یا رها شدن آن ) استفاده کند .

برای نصب یک قلاب در برنامه از یک تابع کتابخانه ای به اسم

استفاده می شود . این تابع یک قلاب را به SetWindowsHookEx

کردن این تابع declare زنجیره قلابهای سیستم اضافه می کند . نحوه

بصورت زیر است :

Declare Function SetWindowsHookEx Lib "user32" Alias

"SetWindowsHookExA" (ByVal idHook As Long, ByVal

lpfn As Long, ByVal hmod As Long, ByVal dwThreadId

As Long) As Long

٣٢٩

همچنین برای آزاد کردن یک قلاب و حذف آن از زنجیره قلابها از تابع

استفاده می گردد . نحوه UnhookWindowsHookEx کتابخانه ای

کردن این تابع بصورت زیر است : declare

Declare Function UnhookWindowsHookEx Lib "user32"

(ByVal hHook As Long) As Long

برای ایجاد قلاب کیبرد همچنین نیاز به تعریف یک ثابت است که شماره

قلاب کیبرد در آن قرار دارد :

Public Const WH_KEYBOARD = 2

نوشت که به Callback Function حال بایستی یک تابع پس زمینه یا

ازای فشرده شدن کیبرد اجرا شود و آدرس آنرا ( با استفاده از کلمه

بهمراه ثابت فوق به تابع ( Address Of کلیدی

فرستاد . SetWindowsHookEx

برای اطلاعات بیشتر و مشاهده یک نمونه برنامه به این آدرس مراجعه

کنید

استخراج مشخصات سخت افزاری یک سیستم در وی بی

معرفی می شود که بوسیله آن می توانید Ocx در این بخش یک کنترل

مشخصات سخت افزاری سیستم خود را استحراج کنید .

نام دارد می توانید از اینجا دانلود Hardware Info این کنترل را که

نمایید .

دانلود شده مشاهده خواهید کرد که دو فایل zip پس از باز نمودن فایل

در آن وجود دارد . همچنین یگ فایل راهنما نیز بهمراه ocx و یک فایل dll

٣٣٠

آنها وجود دارد که طریقه استفاده از کنترل را نشان می دهد . برای

استفاده از کنترل فوق وارد محیط ویژال بیسیک شده و سپس وارد

کلیک کنید . Browse شوید . در آنجا روی دکمه Components منوی

را در آنجا باز کرده اید شده و فایل zip وارد پوشه ای که فایل

را انتخاب کنید تا این کنترل به لیست کنترلهای نوار HWInfo.ocx

ابزار شما اضافه شود . حال می توانید از کنترل را روی فرم خود قرار

دهید و از امکانات آن استفاده کنید .

این کنترل دارای خصوصیات زیر است :

مشخصات سازنده مادربورد : BaseBoardManufacturer

نوع چیپ ست مادربورد : BaseBoardProduct

سازنده بایوس : BiosVendor

تاریخ انتشار بایوس : BiosReleaseDate

ورژن بایوس : BiosVersion

سایز حافظه رام بایوس : BiosROMSize

نوع سوکت پردازنده : SocketDesignation

نوع پردازنده : ProcessorType

سازنده پردازنده : ProcessorManufactor

پردازنده ID شماره : ProcessorID

شماره سریال پردازنده : ProcessorSerialNumber

با استفاده از این کنترل همچنین می توان اطلاعات هر چهار هارد دیسک

سیستم را استخراج نمود برای مثال اگر بخواهید اطلاعات IDE

شماره یک ) را بدست آورید از خصوصیات زیر ) Primary Hard

استفاده کنید :

شماره مدل هارددیسک : HardDisk1ModelNumber

شماره سریال هارد دیسک ( شماره : HardDisk1SerialNumber

٣٣١

سریال کارخانه )

خصوصیات دیگری نیز در این کنترل وجود دارد که برای اطلاعات

بیشتر به راهنمای آن مراجعه کنید

یک کنترل خوب برای ویژوال بیسیک

استفاده از یک کنترل خوب در ویژوال بیسیکاین کنترل انواع مختلفی از

و ویندوز 3,1 و مکینتاش و نت XP کلید رو به شکل کلیدهای ویندوز

اسکپ و ... را در اختیار مان می گذارد که نمونه هایی از این رو تو عکس

زیر می بینیم :

رو براتون بگم . VB در اینجا لازم می بینم که نحوه استفاده از کنترلها تو

رو در محلی که پروژه مون قرار دارد ctl ابتدا فایل فایل کنترل که با پسوند

رو انتخاب Add user control آیتم Project کپی میکنیم و بعد از منوی

٣٣٢

را انتخاب Exiting مکنیم می بینیم که پنجره ای ظاهر میشود سربرگ

کرده و بعد فایل کنترل مورد نظر را انتخاب می کنیم می بینیم که این فایل

به پروژه مون اضافه میشود و از طرفی Project Explorer در پنجره

مون اضافه میشود ولی ممکن است که گاهی Toolbox آیکنی نیز در به

این آیکن غیر فعال باشد برای فعال کردن آن کافیست تمام پنجره ها را در

باز کنیم می بینیم که این Project Explorer بسته و دوباره آنرا از VB

Visual آیکن فعال می شود اکنون می توانید از آن کنترل در فرمهایتان در

استفاده کنید . Basic

برای دریافت این کنترل اینجا کلیک کنید .

در ویژوال بیسیک Windows XP Themes ::استفاده از

    

٣٣٣

در ابتدا برای اینکه این مطلب جا بیفتد نظری به شکلهای زیر بیاندازند

شکل 1 - حالت عادی فرم

WinXP Themes شکل 2 - حالت فرم با استفاده از

برگرفته شده از سر واژه های API . ها استفاده کنیم API برای این کار باید از

رابط برنامه نویسی کاربردی) است ) Application Programming Interface

ها توابعی از پیش ساخته شده در سیستم عامل ویندوز هستند که می توانیم از API .

Dll استفاده کنیم . این توابع در چندین فایل Visual Basic انها در برنامه نویسی در

, USER32 , GDI32 , KERNEL موجودند که از جمله این فایلها متوان 32

٣٣۴

باید از تابع Themes WinXP و .... . ما برای استفاده از WINMM

موجود است XP که در کتابخانه ی که در و یندوز InitCommonControls

یک تابع از متد زیر استفاده میکنیم : ( Declare) استفاده می کنیم . برای فراخوانی

Private Declare Function < نام تابع > Lib " Dll () " کتابخانه نام

As Long

با توجه به متد بالا در قسمت InitCommonControls پس برای فراخوانی تابع

فرم در ویژوال بیسیک کد زیر را می نویسیم : General

Lib InitCommonControls Private Declare Function

As Long () "comctl32.dll"

Initialize کد زیر را بنویسید ( رویداد Initialize در رویداد form اکنون برای

وقتی فراخوانی می شود که فرم ایجاد شود ) :

Private Sub Form_Initialize()

InitCommonControls

End Sub

CommandButton , تا اینجا کارمان با فرم تمام شد و اکنون می توانید چند

را به فرم اضافه کنید . و پس از اتمام کار بر . . . , CheckBox , OptionButton

می سازیم . Exe کرده و بصورت Compile روی فرم آنرا

وجود دارد می exe را در همان پوشه ای که فایل Document New Text یک

سازیم و کدهای زیر را در آن کپی می کنیم و بعد آنراذخیره می کنیم . حالا باید نام و

نام .EXE.MANIFEST پسوند فایل را تغییر دهیم و مطابق الگوی مقابل عمل کنیم

exe فایل

برای اینکه نام و پسوند فایل را عوض کنیم نیاز به این داریم که نام و پسوند فایل را به

را Folder Option شده و Control Panel طور کامل ببینیم برای این کار وارد

 

٣٣۵

Hide Extentions For Known شده و تیک View اجرا می کنیم بعد به قسمت

را بر می داریم حالا همه فایلها را با نام و پسوند کامل مشاهده می کنیم و File Type

نام فایل را با توجه به متد بالا تغییر دهیم (F کلید 2 ) Rename میتوانیم با استفاده از

است را txt باشد نام فایل که با پسوند Sample.exeُ بصورت exe مثلا اگر نام فایل

تغییر می دهیم . Sample.exe.MANIFEST به

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

exe نام فایل .EXE.MANIFEST کد مربوط به فایل

<?xml version="1.0" encoding="UTF-8"

standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft com:

asm.v1" manifestVersion="1.0">

<assemblyIdentity type="win32"

processorArchitecture="*" version="6.0.0.0"

name="mash"/>

<description>Enter your Description

Here</description>

<dependency>

<dependentAssembly>

<assemblyIdentity

type="win32"

name="Microsoft.Windows.Common-Controls"

version="6.0.0.0"

language="*"

processorArchitecture="*"

publicKeyToken="6595b64144ccf1df"

/>

</dependentAssembly>

</dependency>

</assembly>

کیبرد فارسی بشه Visual Basic ::چطور تو

٣٣۶

وقتی برنامه مون اجرا شد VB میخواهم براتون بگم که چطور می شه تو

بشه برای ورود اطلاعات از زبان فارسی استفاده کرد

استفاده کرد . تابع API برای اینکار اول باید از یه

به صورت زیر User رو از کتابخانه 32 LoadKeyboardLayout

فراخوانی کنیم :

Public Declare Function LoadKeyboardLayout Lib

"user32" Alias "LoadKeyboardLayoutA" (ByVal

pwszKLID As String, ByVal flags As Long) As Long

بعد از برای فراخوانی تابع باید تابع را در رویداد مورد نظر فراخوانی کرد

شده فراخونی کردم : load مثلا من تابع رو وقتی که فرم برنامه

LoadKeyboardLayout "00000429", 1 ' 00000429

:::::> For Farsi Keyboard

شدن فرم برنامه زبان ویندوز به انگلیسی Unload برای اینکه بعد از

بنویسیم unload برگردد کد زیر را میتوانیم در رویداد

<::::: 00000429 ' LoadKeyboardLayout "00000409", 1

English Keyboardٍ For

:: در ضمن اگر مایل به دیدن کد سایر زبانها هستید یه سری به آدرس زیر

در رجیستری ویندوز بزنید .

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\C

ontrol\Keyboard Layouts

 ٣٣٧

خوب اینجا می خوام یک کد کاربردی دیگه رو بهتون بگم . این کد باعث می

شه که وقتی شما رویداد خاصی رو اجرا مکنید , کلید خاصی از کیبرد اجرا

را Enter هستید و کلید Textbox شود یعنی مثلاً اگر شما روی یک

, Delete,Pagedown, Tab , ..... فشردید عملی معادل فشردن کلید

روی دهد : F1 ,F2

Private Sub TextBox_KeyPress(KeyAscii As

Integer)

If KeyAscii = 13 Then

SendKeys "{tab}"

End If

End Sub

پیشنهاد می کنم . keypress باز هم این کد را در رویداد

در اینجا کدهایی که می توان از طریق این تابع با آنها کار کرد را می بینیم :

Key Code

BACKSPACE {BACKSPACE}, {BS}, or {BKSP}

BREAK {BREAK}

CAPS LOCK {CAPSLOCK}

DEL or DELETE {DELETE} or {DEL}

DOWN ARROW {DOWN}

END {END}

ENTER {ENTER} or ~

ESC {ESC}

HELP {HELP}

HOME {HOME}

INS or INSERT {INSERT} or {INS}

LEFT ARROW {LEFT}

NUM LOCK {NUMLOCK}

 ٣٣٨

PAGE DOWN {PGDN}

PAGE UP {PGUP}

PRINT SCREEN {PRTSC}

RIGHT ARROW {RIGHT}

SCROLL LOCK {SCROLLLOCK}

TAB {TAB}

UP ARROW {UP}

F1 {F1}

F2 {F2}

F3 {F3}

F4 {F4}

F5 {F5}

F6 {F6}

F7 {F7}

F8 {F8}

F9 {F9}

F10 {F10}

F11 {F11}

F12 {F12}

F13 {F13}

F14 {F14}

F15 {F15}

F16 {F16}

آموزش کار با توابع مربوط به زمان و تاریخ

در این برنامه میخوام درباره استفاده از توابع مربوط به زمان و تاریخ

بهتون یه چیزایی بگم. برای تفهیم بیشتر این مطالب همه ی این توابع رو

٣٣٩

در یک مثال کاربردی براتون بیان می کنم که امیدورم براتون مفید واقع

بشه .

:: برای دریافت این برنامه اینجا کلیک کنید .

و یک Label برای این مثال بعد از ایجاد فرم در ویژوال بیسیک چند

شروع می کنیم . این Format به فرم اضافه کنید , ابتدا با تابع Timer

تابع برای فرمت بندی خروجی به کار می رود و ما در اینجا از آن برای

فرمت بندی زمان و تاریخ استفاده می کنیم . شکل کلی این تابع بصورت

زیر است :

Format(expression[, format[, firstdayofweek[,

firstweekofyear]]])

:: برای فرمت بندی زمان و تاریخ در تابع بالا می توان ار فرمت های زیر

استفاده کرد :

format مقادیری پارامتر

Description Format

نمایش زمان و تاریخ با هم General

Long

Date

نمایش تاریخ به طور کامل

Medium

Date

نمایش تاریخ بصورت خلاصه

Short

Date

نمایش تاریخ

Long

Time

نمایش زمان بصورت ساعت , دقیقه ,

٣۴٠

AM/PM ثانیه و

Medium

Time

نمایش زمان بصورت ساعت , دقیقه و

ثانیه

Short

Time

نمایش زمان بصورت ساعت و دقیقه

به کد زیر توجه کنید و نتایج آنرا در نمای برنامه ببینید :

Private Sub Timer1_Timer()

LblTime.Caption = Format(Now, "long time")

'Not Diffrence With ===> LblTime.Caption =

Format(Time, "long time")

LblTime2.Caption = Format(Now, "short

time")

'Not Diffrence With ===> LblTime2.Caption =

Format(Time, "short time")

LblTime3.Caption = Format(Now, "h:m:s")

'Not Diffrence With ===> LblTime3.Caption =

Format(Time, "h:m:s")

LblTime4.Caption = Format(Now, "Medium

Time")

'Not Diffrence With ===> LblTime4.Caption =

Format(Time, "Medium Time")

LblDate.Caption = Format(Now, "long date")

'Not Diffrence With ===> LblDate.Caption =

Format(Date, "long date")

٣۴١

LblDate2.Caption = Format(Now, "short

Date")

'Not Diffrence With ===> LblDate2.Caption =

Format(Date, "short Date")

LblDate3.Caption = Format(Now, "Medium

Date")

'Not Diffrence With ===> LblDate3.Caption =

Format(Date, "Medium Date")

LblTimeDate.Caption = Format(Now, General)

LblDay.Caption = Day(Date)

' Not Diffrence With ====> LblDay.Caption =

Day(Now)

LblMonth.Caption = Month(Date) & " ( " +

MonthName(Month(Date)) + " ) "

' Not Diffrence With ====> LblMonth.Caption

= Month(Now) & " ( " +

MonthName(Month(Date)) + " ) "

LblYear.Caption = Year(Date)

' Not Diffrence With ====> LblDay.Caption =

Year(Now)

LblHour.Caption = Hour(Time)

' Not Diffrence With ====> LblHour.Caption

= Hour(Now)

LblMinute.Caption = Minute(Time)

' Not Diffrence With ====>

LblMinute.Caption = Minute(Now)

LblSecond.Caption = Second(Time)

' Not Diffrence With ====>

٣۴٢

LblSecond.Caption = Second(Now)

End Sub

خوب حالا لازمه که در مورد توابع به کار رفته در مثال بالا توضیحات

بدم :

در بالا به این تابع اشاره شد . : Format 1. تابع

این تابع بخش روز از یک تاریخ را بر می گرداند و : Day 2. تایع

بصورت مقابل به کار می رود :

Day(Date) کار میرود و یا به اینصورت نیز به Day(Now)

این تابع بخش ماه را از یک تاریخ بر می گرداند و : Month 3. تابع

بصورت مقابل به کار می رود :

Month(Date) کار میرود و یا به اینصورت نیز به

Month(Now)

٣۴٣

این تابع بخش سال از یک تاریخ را بر می گرداند و به : Year 4. تابع

صورت مقابل به کار میرود :

Year(Date) کار میرود و یا به اینصورت نیز به Year(Now)

این تابع بخش نام ماه را از یک تاریخ بر می : MonthName 5 . تابع

گرداند و بصورت مقابل به کار می رود :

MonthName(Date) به کار میرود و یا به اینصورت نیز

MonthName(Now)

این تابع بخش ساعت را از یک زمان بر می گرداند و : Hour 6. تابع

بصورت مقابل به کار می رود :

Hour(Time) کار میرود و یا به اینصورت نیز به Hour(Now)

این تابع بخش دقیقه را از یک زمان بر می گرداند و : Minute 7. تابع

بصورت مقابل به کار می رود :

Minute(Time) کار میرود و یا به اینصورت نیز به

Minute(Now)

این تابع بخش ثانیه را از یک زمان بر می گرداند و : Second 8 . تابع

بصورت مقابل به کار می رود :

Second(Time) کار میرود و یا به اینصورت نیز به

Second(Now)

:: در اینجا می خواهم چندتا تابع دیگه برای کار با تاریخ و زمان بهتون بگم

چون فکر مکنم که بکارتون میاد :

٣۴۴

این تابع بخش خاصی از یک تاریخ را بر می گرداند : DataPart تابع

و بصورت زیر می باشد ( اگر یادتون باشه قبلا گفته بودم که مواردی که

در دستور العمل استفاده از تابع در داخل [ ] قرار دارند استفاده از آنها

اجباری نیست ) :

DatePart( interval , Date )

از آنها استفاده کرد به قرار Interval مواردی که می توان برای پارامتر

زیر است :

interval مقادیر پارامتر

Description Interval

روز "d"

روز از سال "y"

ماه "m"

فصلی از سال "q"

سال "yyyy"

هفته "ww"

روز هفته "w"

ثانیه "s"

دقیقه "n"

ساعت "h"

                                          ٣۴۵

20/12/ فکر کنم با این مثال حساب کار دستون بیاد ( اگر تاریخ جاری 2004

باشد ) :

DatePart("d" , now) ===============>

20

این توابع به ترتیب سه عدد : DateSerial و TimeSerial توابع

صحیح را به نوع زمان و تاریخ تبدیل می کنند و شکل کلی آنها بصورت

زیر می باشد :

TimeSerial ( Hour , Minute , Second )

DateSerial ( Year , Month , Day )

فکر کنم دیگر نیازی به تو ضیح بشتر نباشه .

این تابع اختلاف بین دو تاریخ را بر می گرداند و : DateDiff تابع

بصورت زیر استفاده می شود :

DateDiff( Interval , Date1 , Date2 )

می پذیرد همان Interval لازم به ذکر است که مقادیری که پارامتر

به آنها اشاره شد . DatePart مقادیری است که در جدول بالا برای تابع

در زیر با یک مثال کار با این تایع را به پایان می بریم :

DateDiff ( "d" , #20/11/2004# , #20/12/2004# )

======Output=====> 30

این تابع یک رشته را به تاریخ تبدیل می کند . : CVDate تابع

                                                    

                                                                                                                              

٣۴۶

 

   + MOHSEN GHASEMI - ۱۱:۳۱ ‎ب.ظ ; ۱۳۸٩/۳/٢٩