1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
1114.
1115.
1116.
1117.
1118.
1119.
1120.
1121.
1122.
1123.
1124.
1125.
1126.
1127.
1128.
1129.
1130.
1131.
1132.
1133.
1134.
1135.
1136.
1137.
1138.
1139.
1140.
1141.
1142.
1143.
1144.
1145.
1146.
1147.
1148.
1149.
1150.
1151.
1152.
1153.
1154.
1155.
1156.
1157.
1158.
1159.
1160.
1161.
1162.
1163.
1164.
1165.
1166.
1167.
1168.
1169.
1170.
1171.
1172.
1173.
1174.
1175.
1176.
1177.
1178.
1179.
1180.
1181.
1182.
1183.
1184.
1185.
1186.
1187.
1188.
1189.
1190.
1191.
1192.
1193.
1194.
1195.
1196.
1197.
1198.
1199.
1200.
1201.
1202.
1203.
1204.
1205.
1206.
1207.
1208.
1209.
1210.
1211.
1212.
1213.
1214.
1215.
1216.
1217.
1218.
1219.
1220.
1221.
1222.
1223.
1224.
1225.
1226.
1227.
1228.
1229.
1230.
1231.
1232.
| unit ShadowMap;
interface
Uses
Direct3D9, D3DX9, C3DModelClass, TV3D65_TLB, SysUtils, Windows, Dialogs,
DXUTMisc, DXUT, DXUTEnum, DXUTCore, DXErr9, Forms;
const SHADOWMAP_SIZE = 512;
const
TMeshVertex_Decl: array[0..3] of TD3DVertexElement9 =
(
(Stream: 0; Offset: 0; _Type: D3DDECLTYPE_FLOAT3; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_POSITION; UsageIndex: 0),
(Stream: 0; Offset: 12; _Type: D3DDECLTYPE_FLOAT3; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_NORMAL; UsageIndex: 0),
(Stream: 0; Offset: 18; _Type: D3DDECLTYPE_FLOAT1; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_TEXCOORD; UsageIndex: 0),
(Stream: 0; Offset: 24; _Type: D3DDECLTYPE_FLOAT1; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_TEXCOORD; UsageIndex: 0)
);
//const
// TMeshVertex_Decl: array[0..3] of TD3DVertexElement9 =
// (
// (Stream: 0; Offset: 0; _Type: D3DDECLTYPE_FLOAT3; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_POSITION; UsageIndex: 0),
// (Stream: 0; Offset: 12; _Type: D3DDECLTYPE_FLOAT3; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_NORMAL; UsageIndex: 0),
// (Stream: 0; Offset: 24; _Type: D3DDECLTYPE_FLOAT2; Method: D3DDECLMETHOD_DEFAULT; Usage: D3DDECLUSAGE_TEXCOORD; UsageIndex: 0),
// {D3DDECL_END()}(Stream:$FF; Offset:0; _Type:D3DDECLTYPE_UNUSED; Method:TD3DDeclMethod(0); Usage:TD3DDeclUsage(0); UsageIndex:0)
// );
//Each line corresponds to one of the elements in TVertex. The data in each line is:
//WORD Stream; WORD Offset; BYTE Type; BYTE Method; BYTE Usage; BYTE UsageIndex
//See http://www.toymaker.info/Games/html/vertex_shaders.html for more information.
type TDXError = record
ErrorNumber: String;
Error: String;
end;
Function GetDXError(ErrorInteger: HRESULT): TDXError;
function HexToDec(Str: string): Integer;
Function ReturnEmptyD3DMatrix(): D3DMatrix;
Function ReturnEmptyTV3DMatrix(): TV_3DMatrix;
function TVMatrixToPD3DXMatrix(InMatrix: TV_3DMATRIX): PD3DXMATRIX;
function TVMatrixToD3DMatrix(InMatrix: TV_3DMATRIX): D3DMATRIX;
function D3DMatrixToTVMatrix(InMatrix: D3DMatrix): TV_3DMATRIX;
function D3DXVector4ToTVVector4(InVector: TD3DXVector4): TV_4DVECTOR;
function _DbgPrint(Str: PChar): cardinal; cdecl; external 'ntoskrnl.exe' name 'DbgPrint';
type
TShadowMap = class
Procedure OnResetDevice();
procedure CreateShadowMapDXObjects();
procedure OnFrameMove();
Procedure OnFrameRender();
////////procedure RenderShadowMap( fElapsedTime: single; pmView: D3DMatrix; pmProj: D3DMatrix);
//////Procedure RenderShadowMap( fElapsedTime: single; pmView: PD3DXMatrix; pmProj: PD3DXMatrix);
////Procedure CalculateShadowMapProjection(fElapsedTime: single; pmView: PD3DXMatrix; pmProj: PD3DXMatrix);
//Procedure CalculateShadowMapProjection();
//Procedure CalculateShadowMapProjection(CalculateDepthBuffer: Boolean);
//Procedure Step2(CalculateDepthBuffer: Boolean);
//Procedure RenderShadowMap(fElapsedTime: single; pmView: PD3DXMatrix; pmProj: PD3DXMatrix);
//Procedure RenderShadowMap();
Procedure RenderScene(RenderShadow: Boolean; pmView: D3DMATRIX; pmProj: D3DMatrix);
//Procedure RenderDXMeshes_NoEffects(vDifTmp: TD3DXVector4);
Procedure RenderDXMeshes_NoEffects(vDifTmp: TD3DXVector4; pmViewTemp: D3DMATRIX);
Procedure RenderDXMeshes_Effects(vDifTmp: TD3DXVector4; pmViewTemp: D3DMATRIX);
//Procedure OnFrameRender(fTime: double; fElapsedTime: Single);
//Procedure Step1();
//Procedure Step1(fTime: double; fElapsedTime: Single);
//Procedure Step6();
private
{ Private Declarations }
public
{ Public Declarations }
g_pTexDef: IDirect3DTexture9;
g_pTexDefPool: TD3DPool;
g_pEffect: ID3DXEffect;
g_pEffect_Pool: ID3DXEffectPool;
//g_pEffect_PoolAddr: ^ID3DXEffectPool;
//g_pEffect_Pool: _D3DPOOL;
g_vCamera: CFirstPersonCamera;
g_lCamera: CFirstPersonCamera;
g_Light: D3DLight9; // The spot light in the scene
g_fLightFov: single; // FOV of the spot light (in radian)
//g_aVertDecl: TMeshVertex_Decl;
//LPDIRECT3DVERTEXDECLARATION9 g_pVertDecl = NULL;// Vertex decl for the sample
g_pVertDecl: IDirect3DVertexDeclaration9;
g_pShadowMap: IDirect3DTexture9;
//g_pShadowMap: Integer;
g_pShadowMapPool: TD3DPool;
g_pDSShadow: IDirect3DSurface9;
g_mShadowProj: TD3DXMatrixA16;
end;
implementation
Uses
Unit1;
//Function TD3DXVector4
Function GetDXError(ErrorInteger: HRESULT): TDXError;
var
TmpDXError: TDXError;
sReturnAddr: String;
ReturnError: String;
begin
sReturnAddr := Uppercase(Format('%0x', [ErrorInteger]));
sReturnAddr := Uppercase(sReturnAddr);
if sReturnAddr = '8000FFFF' then
ReturnError := 'E_UNEXPECTED (Catastrophic failure error.)'
else if sReturnAddr = '80004001' then
ReturnError := 'E_NOTIMPL (Not implemented error.)'
else if sReturnAddr = '8007000E' then
ReturnError := 'E_OUTOFMEMORY (Out of memory error.)'
else if sReturnAddr = '80070057' then
ReturnError := 'E_INVALIDARG (One or more arguments are not valid error.)'
else if sReturnAddr = '80004002' then
ReturnError := 'E_NOINTERFACE (Interface not supported error.)'
else if sReturnAddr = '80004003' then
ReturnError := 'E_POINTER (Pointer not valid error.)'
else if sReturnAddr = '80070006' then
ReturnError := 'E_HANDLE (Handle not valid error.)'
else if sReturnAddr = '80004004' then
ReturnError := 'E_ABORT (Operation aborted error.)'
else if sReturnAddr = '80004005' then
ReturnError := 'E_FAIL (Unspecified error.)'
else if sReturnAddr = '80070005' then
ReturnError := 'E_ACCESSDENIED (General access denied error.)'
else
ReturnError := 'UNKNOWN (Error not looked up.)';
//if ReturnCode < 0 then
//sReturnAddr := '0x' + Format('%0x', [ReturnCode]);
// sReturnAddr0 := '-0x' + Format('%0x', [Abs(ReturnCode)]) + ' - ' + ReturnError
//else if ReturnCode > 0 then
//sReturnAddr0 := Format('%0x', [ReturnCode]) + ' - ' + ReturnError;
TmpDXError.ErrorNumber := sReturnAddr;
TmpDXError.Error := ReturnError;
result := TmpDXError;
end;
function HexToDec(Str: string): Integer;
var
i, M: Integer;
begin
Result:=0;
M:=1;
Str:=AnsiUpperCase(Str);
for i:=Length(Str) downto 1 do
begin
case Str[i] of
'1'..'9': Result:=Result+(Ord(Str[i])-Ord('0'))*M;
'A'..'F': Result:=Result+(Ord(Str[i])-Ord('A')+10)*M;
end;
M:=M shl 4;
end;
end;
Function ReturnEmptyD3DMatrix(): D3DMatrix;
var
OutMatrix: D3DMatrix;
begin
OutMatrix._11 := 0; OutMatrix._12 := 0; OutMatrix._13 := 0; OutMatrix._14 := 0;
OutMatrix._21 := 0; OutMatrix._22 := 0; OutMatrix._23 := 0; OutMatrix._24 := 0;
OutMatrix._31 := 0; OutMatrix._32 := 0; OutMatrix._33 := 0; OutMatrix._34 := 0;
OutMatrix._41 := 0; OutMatrix._42 := 0; OutMatrix._43 := 0; OutMatrix._44 := 0;
result := OutMatrix;
end;
Function ReturnEmptyTV3DMatrix(): TV_3DMatrix;
var
OutMatrix: TV_3DMATRIX;
begin
OutMatrix.m11 := 0; OutMatrix.m12 := 0; OutMatrix.m13 := 0; OutMatrix.m14 := 0;
OutMatrix.m21 := 0; OutMatrix.m22 := 0; OutMatrix.m23 := 0; OutMatrix.m24 := 0;
OutMatrix.m31 := 0; OutMatrix.m32 := 0; OutMatrix.m33 := 0; OutMatrix.m34 := 0;
OutMatrix.m41 := 0; OutMatrix.m42 := 0; OutMatrix.m43 := 0; OutMatrix.m44 := 0;
result := OutMatrix;
end;
(*
function DecToHex(N: int64): string;
begin
if N < 0 then
result := '-' + Format('%0x', [Abs(N)])
else
result := Format(’%0x’, [N]);
end;
*)
function TVMatrixToPD3DXMatrix(InMatrix: TV_3DMATRIX): PD3DXMATRIX;
var
inMX: TV_3DMATRIX;
OutMX: PD3DXMatrix;
begin
{
asm
//Preserve the stack (Though it probably doesn't need to be done
//since we're already inside a procedure and Delphi most likely
//handles stack preservation on it's own anyhow).
push ebx
push esi
push edi
mov eax, inMX.m11
mov OutMX._11, eax
mov eax, inMX.m12
mov OutMX._12, eax
mov eax, inMX.m13
mov OutMX._13, eax
mov eax, inMX.m14
mov OutMX._14, eax
mov eax, inMX.m21
mov OutMX._21, eax
mov eax, inMX.m22
mov OutMX._22, eax
mov eax, inMX.m23
mov OutMX._23, eax
mov eax, inMX.m24
mov OutMX._24, eax
mov eax, inMX.m31
mov OutMX._31, eax
mov eax, inMX.m32
mov OutMX._32, eax
mov eax, inMX.m33
mov OutMX._33, eax
mov eax, inMX.m34
mov OutMX._34, eax
mov eax, inMX.m41
mov OutMX._41, eax
mov eax, inMX.m42
mov OutMX._42, eax
mov eax, inMX.m43
mov OutMX._43, eax
mov eax, inMX.m44
mov OutMX._44, eax
//Restore the stack (Though it probably doesn't need to be done
//since we're already inside a procedure and Delphi most likely
//handles stack preservation on it's own anyhow).
pop edi
pop esi
pop ebx
end;
}
// *Heavy sigh*... Delphi apparently has issues with _.## in the asm statement
// block so apparently all large assignments will need to be in Pascal from
// here on out, unless I figure a way to use ASM. Not sure it would be
// that much more of a speed increase anyhow...
OutMX._11 := inMX.m11;
OutMX._12 := inMX.m12;
OutMX._13 := inMX.m13;
OutMX._14 := inMX.m14;
OutMX._21 := inMX.m21;
OutMX._22 := inMX.m22;
OutMX._23 := inMX.m23;
OutMX._24 := inMX.m24;
OutMX._31 := inMX.m31;
OutMX._32 := inMX.m32;
OutMX._33 := inMX.m33;
OutMX._34 := inMX.m34;
OutMX._41 := inMX.m41;
OutMX._42 := inMX.m42;
OutMX._43 := inMX.m43;
OutMX._44 := inMX.m44;
result := OutMX;
end;
function TVMatrixToD3DMatrix(InMatrix: TV_3DMATRIX): D3DMATRIX;
var
inMX: TV_3DMATRIX;
OutMX: D3DMatrix;
begin
OutMX._11 := inMX.m11;
OutMX._12 := inMX.m12;
OutMX._13 := inMX.m13;
OutMX._14 := inMX.m14;
OutMX._21 := inMX.m21;
OutMX._22 := inMX.m22;
OutMX._23 := inMX.m23;
OutMX._24 := inMX.m24;
OutMX._31 := inMX.m31;
OutMX._32 := inMX.m32;
OutMX._33 := inMX.m33;
OutMX._34 := inMX.m34;
OutMX._41 := inMX.m41;
OutMX._42 := inMX.m42;
OutMX._43 := inMX.m43;
OutMX._44 := inMX.m44;
result := OutMX;
end;
function D3DMatrixToTVMatrix(InMatrix: D3DMatrix): TV_3DMATRIX;
var
InMX: D3DMatrix;
OutMX: TV_3DMATRIX;
begin
OutMX.m11 := inMX._11;
OutMX.m12 := inMX._12;
OutMX.m13 := inMX._13;
OutMX.m14 := inMX._14;
OutMX.m21 := inMX._21;
OutMX.m22 := inMX._22;
OutMX.m23 := inMX._23;
OutMX.m24 := inMX._24;
OutMX.m31 := inMX._31;
OutMX.m32 := inMX._32;
OutMX.m33 := inMX._33;
OutMX.m34 := inMX._34;
OutMX.m41 := inMX._41;
OutMX.m42 := inMX._42;
OutMX.m43 := inMX._43;
OutMX.m44 := inMX._44;
result := OutMX;
end;
function D3DXVector4ToTVVector4(InVector: TD3DXVector4): TV_4DVECTOR;
var
OutVec4: TV_4DVECTOR;
begin
OutVec4.x := InVector.x;
OutVec4.y := InVector.y;
OutVec4.z := InVector.z;
OutVec4.w := InVector.w;
result := OutVec4;
end;
Procedure PreDXClear();
begin
// PreDXClear();
// g_pD3DDevice.Clear(0, nil, D3DCLEAR_TARGET OR D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 77), 1.0, 0);
// PostDXClear();
// g_pD3DDevice.BeginScene();
// PostDXBeginScene();
end;
Procedure PostDXClear();
begin
// PreDXClear();
// g_pD3DDevice.Clear(0, nil, D3DCLEAR_TARGET OR D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 77), 1.0, 0);
// PostDXClear();
// g_pD3DDevice.BeginScene();
// PostDXBeginScene();
end;
Procedure PostDXBeginScene();
begin
// PreDXClear();
// g_pD3DDevice.Clear(0, nil, D3DCLEAR_TARGET OR D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 77), 1.0, 0);
// PostDXClear();
// g_pD3DDevice.BeginScene();
// PostDXBeginScene();
end;
Procedure TShadowMap.CreateShadowMapDXObjects();
var
ReturnCode: HRESULT;
dwShaderFlags: DWORD;
ReturnError: TDXError;
sReturnError: String;
vFromPt: D3DVECTOR;
vLookatPt: D3DVECTOR;
//D3DXMATRIXA16 mIdent;
mIdent: D3DMATRIX;
OrigPos, OrigRot, OrigDir, OrigLookAt: TV_3DVECTOR;
TmpPos, TmpRot, TmpDir, TmpLookAt: TV_3DVECTOR;
begin
//WinMain
// Initialize the camera
//g_VCamera.Create();
//g_LCamera.Create();
//g_VCamera.SetScalers(0.01, 15.0);
//g_LCamera.SetScalers(0.01, 8.0);
// Set up the view parameters for the camera
//vFromPt := D3DXVECTOR3(0.0, 5.0, -18.0);
//vLookatPt := D3DXVECTOR3(0.0, -1.0, 0.0);
//g_VCamera.SetViewParams(vFromPt, vLookatPt);
//vFromPt := D3DXVECTOR3(0.0, 0.0, -12.0);
//vLookatPt := D3DXVECTOR3(0.0, -2.0, 1.0);
//g_LCamera.SetViewParams(vFromPt, vLookatPt);
// Initialize the spot light
g_fLightFov := D3DX_PI / 2.0;
////Write('Error Output');
//_DbgPrint(PChar('Error Output'));
OutputDebugString(PChar('Project 1: Initializing g_Light object'));
g_Light.Diffuse.r := 1.0;
g_Light.Diffuse.g := 1.0;
g_Light.Diffuse.b := 1.0;
g_Light.Diffuse.a := 1.0;
OrigPos := Form1.TVCam.GetPosition();
OrigRot := Form1.TVCam.GetRotation();
OrigDir := Form1.TVCam.GetDirection();
OrigLookAt := Form1.TVCam.GetLookAt();
TmpPos := Sun.GetPosition();
Form1.TVSunCam.SetPosition(TmpPos.X, TmpPos.Y, TmpPos.Z);
Form1.TVSunCam.SetLookAt(0, 0, 0);
TmpPos := Form1.TVSunCam.GetPosition();
TmpRot := Form1.TVSunCam.GetRotation();
TmpLookAt := Form1.TVSunCam.GetLookAt();
TmpDir := Form1.TVSunCam.GetDirection();
//Switch back to main camera and restore all the "current" coordinates
Form1.TVCam.SetPosition(OrigPos.X, OrigPos.Y, OrigPos.Z);
Form1.TVCam.SetRotation(OrigRot.X, OrigRot.Y, OrigRot.Z);
Form1.TVCam.SetLookAt(OrigLookAt.X, OrigLookAt.Y, OrigLookAt.Z);
g_Light.Position := D3DXVECTOR3(TmpPos.x, TmpPos.Y, TmpPos.Z);
g_Light.Direction := D3DXVECTOR3(TmpDir.X, TmpDir.Y, TmpDir.Z);
//D3DXVec3Normalize( ( D3DXVECTOR3* )&g_Light.Direction, ( D3DXVECTOR3* )&g_Light.Direction );
D3DXVec3Normalize(g_Light.Direction, g_Light.Direction);
g_Light.Range := 10.0;
g_Light.Theta := g_fLightFov / 2.0;
g_Light.Phi := g_fLightFov / 2.0;
OutputDebugString(PChar('Project 1: Done Initializing g_Light object'));
//OnCreateDevice
dwShaderFlags := D3DXFX_NOT_CLONEABLE;
// Create the Effect Pool (If shared)
//ReturnCode := D3DXCreateEffectPool(g_pEffect_Pool);
OutputDebugString(PChar('Project 1: Creating EffectPool (g_pEffect_Pool)'));
ReturnCode := D3DXCreateEffectPool(g_pEffect_Pool);
OutputDebugString(PChar('Project 1: Creating Effect From File(C:Program FilesBorlandDelphi7ProjectsCouncil of Eight Game Client Revised (v2)MediaShadersShadowmap.fx), g_pEffect'));
ReturnCode := D3DXCreateEffectFromFile(g_pD3DDevice^, 'C:Program FilesBorlandDelphi7ProjectsCouncil of Eight Game Client Revised (v2)MediaShadersShadowmap.fx', nil, nil, dwShaderFlags, nil, g_pEffect, nil);
if ReturnCode <> 0 then
begin
ReturnError := GetDXError(ReturnCode);
sReturnError := ReturnError.ErrorNumber + ': ' + ReturnError.Error;
ShowMessage('D3DXCreateEffectFromFile Failed with error:' + sReturnError);
end;
// Create vertex declaration
//g_pD3DDevice.CreateVertexDeclaration(@TMeshVertex_Decl, g_pVertDecl);
OutputDebugString(PChar('Project 1: Creating Vertex Declaration based on m_pVertexDeclaration'));
g_pD3DDevice.CreateVertexDeclaration(@TMeshVertex_Decl, m_pVertexDeclaration);
// World transform to identity
D3DXMatrixIdentity(mIdent);
g_pD3DDevice.SetTransform(D3DTS_WORLD, mIdent);
end;
Procedure TShadowMap.OnResetDevice();
var
fAspectRatio: Single;
lr: D3DLOCKED_RECT;
g_LightVec4: TD3DXVector4;
d3dSettings: TDXUTDeviceSettings;
D3DColorTemp: D3DCOLOR;
pCaps: _D3DCAPS9;
ReturnCode: HRESULT;
ReturnError: TDXError;
sReturnError: String;
begin
// g_pEffect.OnResetDevice();
// Create a sprite to help batch calls when drawing many lines of text
//D3DXCreateSprite(g_pD3DDevice^, g_pTextSprite);
// Setup the camera's projection parameters
fAspectRatio := Form1.Width / Form1.Height;
// float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;
// g_VCamera.SetProjParams( D3DX_PI / 4, fAspectRatio, 0.1f, 100.0f );
// g_LCamera.SetProjParams( D3DX_PI / 4, fAspectRatio, 0.1f, 100.0f );
// *********************************************************************
// * NOTE: Do NOT set breakpoints on the D3DXCreateTexture lines!!!!! *
// * Due to Delphi using software breakpoints, on the assembly leve *
// * things get screwed up and the D3DXCreateTexture ALWAYS fails *
// * and fails with a "cryptic" error message! *
// *********************************************************************
OutputDebugString(PChar('Project 1: Recreating g_pTexDef'));
// Create the default texture (used when a triangle does not use a texture)
D3DXCreateTexture(g_pD3DDevice^, 1, 1, 1, D3DUSAGE_DYNAMIC, 21, g_pTexDefPool, g_pTexDef);
g_pTexDef.LockRect(0, lr, nil, 0);
D3DColorTemp := D3DCOLOR_RGBA(255, 255, 255, 255);
lr.pBits := @D3DColorTemp;
g_pTexDef.UnlockRect(0);
OutputDebugString(PChar('Project 1: Done recreating g_pTexDef'));
// Restore the scene objects
//for( int i = 0; i < NUM_OBJ; ++i )
// V_RETURN( g_Obj[i].m_Mesh.RestoreDeviceObjects( pd3dDevice ) );
//V_RETURN( g_LightMesh.RestoreDeviceObjects( pd3dDevice ) );
//g_pD3DDevice.CreateTexture(1, 1, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, g_pTexDef);
OutputDebugString(PChar('Project 1: Initializing g_LightVec4'));
// Restore the effect variables
g_LightVec4.x := g_Light.Diffuse.r;
g_LightVec4.y := g_Light.Diffuse.g;
g_LightVec4.z := g_Light.Diffuse.b;
g_LightVec4.w := g_Light.Diffuse.a;
OutputDebugString(PChar('Project 1: Done Initializing g_LightVec4'));
g_pEffect.SetVector('g_vLightDiffuse', g_LightVec4);
g_pEffect.SetFloat('g_fCosTheta', cos(g_Light.Theta));
// Create the shadow map texture
OutputDebugString(PChar('Project 1: Recreating texture(g_pShadowMap)'));
D3DXCreateTexture(g_pD3DDevice^, SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DUSAGE_RENDERTARGET, g_pShadowMapPool, g_pShadowMap);
// Create the depth-stencil buffer to be used with the shadow map
// We do this to ensure that the depth-stencil buffer is large
// enough and has correct multisample type/quality when rendering
// the shadow map. The default depth-stencil buffer created during
// device creation will not be large enough if the user resizes the
// window to a very small size. Furthermore, if the device is created
// with multisampling, the default depth-stencil buffer will not
// work with the shadow map texture because texture render targets
// do not support multisample.
OutputDebugString(PChar('Project 1: Recreating DepthStencilSurface(g_pDSShadow)'));
g_pD3DDevice.CreateDepthStencilSurface(SHADOWMAP_SIZE,
SHADOWMAP_SIZE,
D3DFMT_D24X8,
D3DMULTISAMPLE_NONE,
0,
TRUE,
g_pDSShadow,
nil);
// Initialize the shadow projection matrix
D3DXMatrixPerspectiveFovLH(g_mShadowProj, g_fLightFov, 1, 0.01, 100.0);
// g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );
// g_HUD.SetSize( 170, pBackBufferSurfaceDesc->Height );
// CDXUTControl* pControl = g_HUD.GetControl( IDC_LIGHTPERSPECTIVE );
// if( pControl )
// pControl->SetLocation( 0, pBackBufferSurfaceDesc->Height - 50 );
// pControl = g_HUD.GetControl( IDC_ATTACHLIGHTTOCAR );
// if( pControl )
// pControl->SetLocation( 0, pBackBufferSurfaceDesc->Height - 25 );
// return S_OK;
OutputDebugString(PChar('******************************************'));
OutputDebugString(PChar('* Now done creating and reseting devices *'));
OutputDebugString(PChar('******************************************'));
end;
//We'll go with this prototype (Of using time as a function of the ShadowMap's Shadowmap)
//for now, but eventually we'll want this tie'ed in probably to the Camera position
//Procedure ShadowMap_OnFrameMove(double fTime, float fElapsedTime, void* pUserContext);
//Procedure ShadowMap_OnFrameMove(double fTime, float fElapsedTime, void* pUserContext);
Procedure TShadowMap.OnFrameMove();
var
TmpAngle: Single;
m: TD3DXMatrixA16;
vR: D3DVECTOR;
MeshAddr: Integer;
D3DMesh: ^ID3DXMesh;
TmpMatrix: D3DMatrix;
begin
MeshAddr := Form1.TVInternals.GetD3DMesh(Form1.Mesh[1].GetIndex);
D3DMesh := @MeshAddr;
//We're using the variables I declared globally for Zak's HLSL Sky code
//AccumulatedTime, ElapsedTime
//g_VCamera = View Camera
//g_LCamera = Light Camera
// Update the camera's position based on user input
//g_VCamera.FrameMove(ElapsedTime);
//g_LCamera.FrameMove(ElapsedTime);
TmpAngle := D3DX_PI * ElapsedTime / 4.0;
D3DXMatrixRotationY(m, TmpAngle);
TmpMatrix := TVMatrixToD3DMatrix(Sun.GetMatrix());
//D3DXMatrixMultiply( g_Obj[1].m_mWorld, &g_Obj[1].m_mWorld, &m );
D3DXMatrixMultiply(TmpMatrix, TmpMatrix, m);
// D3DXMatrixRotationY(m, -D3DX_PI * Sky.GetElapsedTime() / 4.0);
// D3DXMatrixMultiply( &g_Obj[2].m_mWorld, &g_Obj[2].m_mWorld, &m );
vR.x := 0.1;
vR.y := 1.0;
vR.z := -0.2;
// D3DXMatrixRotationAxis(m, vR, -D3DX_PI * Sky.GetElapsedTime() / 6.0);
// D3DXMatrixMultiply( &g_Obj[3].m_mWorld, &m, &g_Obj[3].m_mWorld );
end;
Procedure TShadowMap.OnFrameRender();
var
pmView: PD3DMatrix;
pmView2: D3DMatrix;
//pmView2: TV_3DMATRIX;
pmDeterminant: Single;
mViewToLightProj: TD3DXMatrixA16;
mLightViewTmp: TV_3DMATRIX;
mLightView: TD3DXMatrixA16;
vPos, vUp: TD3DXVector3;
vDir: TD3DXVector4;
pOldRT: IDirect3DSurface9;
pShadowSurf: IDirect3DSurface9;
pOldDS: IDirect3DSurface9;
TmpPos: TV_3DVECTOR;
OrigPos: TV_3DVECTOR;
OrigRot: TV_3DVECTOR;
OrigLookAt: TV_3DVECTOR;
TmpTVMatrix: TV_3DMATRIX;
TmpD3DMatrix: D3DMatrix;
begin
// Light attached to sun.
//mLightView = g_Obj[2].m_mWorld;
{ A
OrigPos := Form1.TVCam.GetPosition();
OrigRot := Form1.TVCam.GetRotation();
OrigLookAt := Form1.TVCam.GetLookAt();
TmpPos := Sky.Sun_GetPosition();
Form1.TVSunCam.SetPosition(TmpPos.X, TmpPos.Y, TmpPos.Z);
Form1.TVSunCam.SetLookAt(0, 0, 0);
mLightView := TVMatrixToD3DMatrix(Form1.TVSunCam.GetMatrix());
Form1.TVCam.SetPosition(OrigPos.X, OrigPos.Y, OrigPos.Z);
Form1.TVCam.SetRotation(OrigRot.X, OrigRot.Y, OrigRot.Z);
Form1.TVCam.SetLookAt(OrigLookAt.X, OrigLookAt.Y, OrigLookAt.Z);
}
{ C
Form1.TVSunCam.SetPosition(TmpPos.X, TmpPos.Y, TmpPos.Z);
Form1.TVSunCam.SetLookAt(0, 0, 0);
mLightView := TVMatrixToD3DMatrix(Sky.Sun_GetTV3DMatrix());
}
// D
OrigPos := Form1.TVCam.GetPosition();
OrigRot := Form1.TVCam.GetRotation();
OrigLookAt := Form1.TVCam.GetLookAt();
TmpPos := Sun.GetPosition();
Form1.TVSunCam.SetPosition(TmpPos.X, TmpPos.Y, TmpPos.Z);
Form1.TVSunCam.SetLookAt(0, 0, 0);
vPos.X := Form1.TVSunCam.GetPosition.X;
vPos.Y := Form1.TVSunCam.GetPosition.Y;
vPos.Z := Form1.TVSunCam.GetPosition.Z;
vDir.x := vDir.x + vPos.x; // vDir denotes the look-at point
vDir.y := vDir.y + vPos.y;
vDir.z := vDir.z + vPos.z;
vDir.w := 0;
vUp := D3DXVector3(0.0, 1.0, 0.0);
D3DXMatrixLookAtLH(mLightView, vPos, PD3DXVector3(@vDir)^, vUp);
Form1.TVCam.SetPosition(OrigPos.X, OrigPos.Y, OrigPos.Z);
Form1.TVCam.SetRotation(OrigRot.X, OrigRot.Y, OrigRot.Z);
Form1.TVCam.SetLookAt(OrigLookAt.X, OrigLookAt.Y, OrigLookAt.Z);
{
// B
mLightViewTmp := ReturnEmptyTV3DMatrix();
mLightViewTmp := Sun.GetMatrix;
mLightView := PD3DXMatrixA16(@mLightViewTmp)^;
vPos := D3DXVector3(mLightView._41, mLightView._42, mLightView._43); // Offset z by -2 so that it's closer to headlight
vDir := D3DXVector4(0.0, 0.0, -1.0, 1.0); // In object space, car is facing -Z
mLightView._41 := 0.0; mLightView._42 := 0.0; mLightView._43 := 0.0; // Remove the translation
D3DXVec4Transform(vDir, vDir, mLightView); // Obtain direction in world space
vDir.w := 0.0; // Set w 0 so that the translation part below doesn't come to play
D3DXVec4Normalize(vDir, vDir);
vPos.x := vPos.x + vDir.x * 4.0; // Offset the center by 4 so that it's closer to the headlight
vPos.y := vPos.y + vDir.y * 4.0;
vPos.z := vPos.x + vDir.z * 4.0;
vDir.x := vDir.x + vPos.x; // vDir denotes the look-at point
vDir.y := vDir.y + vPos.y;
vDir.z := vDir.z + vPos.z;
vUp := D3DXVector3(0.0, 1.0, 0.0);
D3DXMatrixLookAtLH(mLightView, vPos, PD3DXVector3(@vDir)^, vUp);
//.
}
//OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender TV.Clear(False).'));
//Form1.TV.Clear(False);
//OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender TV.Clear(False) finished.'));
// Render the shadow map
pOldRT := nil;
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Getting RenderTarget(pOldRT).'));
g_pD3DDevice.GetRenderTarget(0, pOldRT);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Getting RenderTarget(pOldRT) finished.'));
if SUCCEEDED (g_pShadowMap.GetSurfaceLevel(0, pShadowSurf) ) then
begin
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting RenderTarget(0, pShadowSurf)'));
g_pD3DDevice.SetRenderTarget(0, pShadowSurf);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting RenderTarget(0, pShadowSurf) finished.'));
SAFE_RELEASE( pShadowSurf );
end;
//Render the Shadow Map
OutputDebugString('- Project 1: TShadowMap::OnFrameRender Getting DepthStencilSurface(pOldDS).');
pOldDS := nil;
if SUCCEEDED (g_pD3DDevice.GetDepthStencilSurface(pOldDS) ) then
begin
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Getting DepthStencilSurface(pOldDS) finished.'));
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting DepthStencilSurface(g_pDSShadow).'));
g_pD3DDevice.SetDepthStencilSurface(g_pDSShadow);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting DepthStencilSurface(g_pDSShadow) finished.'));
end;
//All BeginPerfEvent does is Begin a Performance Event - Extremely valuable
//information for profiling the speed of DX stuff. It has been mentioned
//in forums that it does ABSOLUTELY NOTHING to rendering whatsoever, so for
//now, it's safe to rem out.
// try
// DXUT_BeginPerfEvent(DXUT_PERFEVENTCOLOR, 'Shadow Map'); // g:= CDXUTPerfEventGenerator.( DXUT_PERFEVENTCOLOR, L"Shadow Map");
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Calling RenderScene(True).'));
RenderScene(True, mLightView, g_mShadowProj);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender back from Calling RenderScene(True).'));
if pOldDS <> nil then
begin
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting DepthStencilSurface(pOldDS).'));
g_pD3DDevice.SetDepthStencilSurface(pOldDS);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting DepthStencilSurface(pOldDS) finished.'));
pOldDS := nil;
end;
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting RenderTarget(pOldRT).'));
g_pD3DDevice.SetRenderTarget(0, pOldRT);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Setting RenderTarget(pOldRT) finished.'));
SAFE_RELEASE(pOldRT);
// Now that we have the shadow map, render the scene.
// Initialize required parameter
g_pEffect.SetTexture('g_txShadow', g_pShadowMap);
//Form1.TVMath.TVMatrixInverse(pmView2, pmDeterminant, Form1.TVCam.GetMatrix());
pmView2 := TVMatrixToD3DMatrix(Form1.TVCam.GetMatrix());
//pmView2 := Form1.TVCam.GetMatrix();
pmView := PD3DMatrix(@pmView2);
mViewToLightProj := pmView^;
D3DXMatrixInverse(mViewToLightProj, nil, mViewToLightProj);
D3DXMatrixMultiply(mViewToLightProj, mViewToLightProj, mLightView);
// NOTE: g_mShadowProj acts as a factor or a scaling value to constrain
// and/or tighten up the mViewToLightProj matrix. So Theoryetically,
// once it's set at the begining of the project (Inside of
// CreateShadowMapDXObjects) it should never change. So we should be
// be able to assume it's correct since it's only set once.
D3DXMatrixMultiply(mViewToLightProj, mViewToLightProj, g_mShadowProj);
g_pEffect.SetMatrix('g_mViewToLightProj', mViewToLightProj);
g_pEffect.SetTexture('g_txShadow', nil);
// try
// DXUT_BeginPerfEvent(DXUT_PERFEVENTCOLOR, 'Scene'); // CDXUTPerfEventGenerator g( DXUT_PERFEVENTCOLOR, L"Scene" );
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender Calling RenderScene(false).'));
//TmpTVMatrix := Form1.TVCam.GetProjectionMatrix();
TmpD3DMatrix := D3DMatrix(Form1.TVCam.GetProjectionMatrix());
RenderScene(False, pmView^, TmpD3DMatrix);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender back from Calling RenderScene(false).'));
// finally
// DXUT_EndPerfEvent;
// end;
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender C3DModels[0] OnIdle.'));
Form1.C3DModels[0].OnIdle(Form1.TV.TickCount);
OutputDebugString(PChar('- Project 1: TShadowMap::OnFrameRender C3DModels[0] OnIdle finished.'));
g_pEffect.SetTexture('g_txShadow', nil);
end;
Procedure TShadowMap.RenderDXMeshes_NoEffects(vDifTmp: TD3DXVector4; pmViewTemp: D3DMATRIX);
Var
Obj: Integer;
MeshToRender: Integer;
i: Integer;
MeshAddr: Integer;
D3DMesh: ID3DXMesh;
mWorldView: TD3DXMatrixA16;
pmView: D3DMATRIX;
D3DTexture: iDirect3DTexture9;
MaterialIndex: Integer;
TextureIndex: Integer;
TmpTVMatrix: TV_3DMATRIX;
begin
//Make sure that our mWorldView is not having it's value picked up
//from somewhere else in the project.
mWorldView := ReturnEmptyD3DMatrix();
for obj := 1 to MaxMeshes do
begin
If Form1.MeshObjIndexesUsed[obj] = 1 Then
begin
MeshAddr := Form1.TVInternals.GetD3DMesh(Form1.Mesh[obj].GetIndex);
D3DMesh := ID3DXMesh(MeshAddr);
//mWorldView := TVMatrixToD3DMatrix(Form1.Mesh[obj].GetMatrix);
TmpTVMatrix := Form1.Mesh[Obj].GetMatrix();
mWorldView := PD3DXMatrixA16(@TmpTVMatrix)^;
//This MatrixMultiply line causes artifacts for some reason
D3DXMatrixMultiply(mWorldView, mWorldView, pmViewTemp);
g_pEffect.SetMatrix('g_mWorldView', mWorldView);
for i := 0 to Form1.Mesh[obj].GetGroupCount() - 1 do
begin
//Basically we're just getting the material for
//each group of the mesh and the diffuse colors
//for that material then sending that info to
//the effect object.
MaterialIndex := Form1.Mesh[obj].GetMaterial(i);
//vDif stands for vector Diffuse
vDifTmp.x := Form1.TVMaterial.GetDiffuse(MaterialIndex).r;
vDifTmp.y := Form1.TVMaterial.GetDiffuse(MaterialIndex).g;
vDifTmp.z := Form1.TVMaterial.GetDiffuse(MaterialIndex).b;
vDifTmp.w := Form1.TVMaterial.GetDiffuse(MaterialIndex).a;
g_pEffect.SetVector('g_vMaterial', vDifTmp);
Application.ProcessMessages();
//Now we do the same for the textures
TextureIndex := Form1.Mesh[obj].GetTexture(i);
if TextureIndex > 0 then
begin
D3DTexture := iDirect3DTexture9(Form1.TVInternals.GetTexture(TextureIndex));
g_pEffect.SetTexture('g_txScene', D3DTexture);
end
else
g_pEffect.SetTexture('g_txScene', g_pTexDef);
g_pEffect.CommitChanges();
D3DMesh.DrawSubset(i);
end;
end;
end;
end;
Procedure TShadowMap.RenderDXMeshes_Effects(vDifTmp: TD3DXVector4; pmViewTemp: D3DMATRIX);
Var
Obj: Integer;
MeshToRender: Integer;
p: Integer;
CPass: LongWord;
i: Integer;
MeshAddr: Integer;
D3DMesh: ID3DXMesh;
mWorldView: TD3DXMatrixA16;
pmView: D3DMATRIX;
D3DTexture: iDirect3DTexture9;
MaterialIndex: Integer;
TextureIndex: Integer;
TmpTVMatrix: TV_3DMATRIX;
begin
//Make sure that our mWorldView is not having it's value picked up
//from somewhere else in the project.
mWorldView := ReturnEmptyD3DMatrix();
for obj := 1 to MaxMeshes do
begin
If Form1.MeshObjIndexesUsed[obj] = 1 Then
begin
MeshAddr := Form1.TVInternals.GetD3DMesh(Form1.Mesh[obj].GetIndex);
D3DMesh := ID3DXMesh(MeshAddr);
//mWorldView := TVMatrixToD3DMatrix(Form1.Mesh[obj].GetMatrix);
TmpTVMatrix := Form1.Mesh[Obj].GetMatrix();
mWorldView := PD3DXMatrixA16(@TmpTVMatrix)^;
//This MatrixMultiply line causes artifacts for some reason
D3DXMatrixMultiply(mWorldView, mWorldView, pmViewTemp);
g_pEffect.SetMatrix('g_mWorldView', mWorldView);
g_pEffect._Begin(@cPass, 0);
for p := 0 to cPass - 1 do
begin
g_pEffect.BeginPass(p);
for i := 0 to Form1.Mesh[obj].GetGroupCount() - 1 do
begin
//Basically we're just getting the material for
//each group of the mesh and the diffuse colors
//for that material then sending that info to
//the effect object.
MaterialIndex := Form1.Mesh[obj].GetMaterial(i);
//vDif stands for vector Diffuse
vDifTmp.x := Form1.TVMaterial.GetDiffuse(MaterialIndex).r;
vDifTmp.y := Form1.TVMaterial.GetDiffuse(MaterialIndex).g;
vDifTmp.z := Form1.TVMaterial.GetDiffuse(MaterialIndex).b;
vDifTmp.w := Form1.TVMaterial.GetDiffuse(MaterialIndex).a;
g_pEffect.SetVector('g_vMaterial', vDifTmp);
Application.ProcessMessages();
//Now we do the same for the textures
TextureIndex := Form1.Mesh[obj].GetTexture(i);
if TextureIndex > 0 then
begin
D3DTexture := iDirect3DTexture9(Form1.TVInternals.GetTexture(TextureIndex));
g_pEffect.SetTexture('g_txScene', D3DTexture);
end
else
g_pEffect.SetTexture('g_txScene', g_pTexDef);
g_pEffect.CommitChanges();
D3DMesh.DrawSubset(i);
end;
g_pEffect.EndPass;
end; //for p := 0 to cPass - 1 do
g_pEffect._End;
end;
end;
end;
Procedure TShadowMap.RenderScene(RenderShadow: Boolean; pmView: D3DMATRIX; pmProj: D3DMatrix);
var
m: TD3DXMatrixA16;
v: TD3DXVector3;
vPos: TD3DXVector4;
vUp: TD3DXVector3;
v3: TD3DXVector3;
v4: TD3DXVector4;
v9: TD3DXVector4;
OrigPos: TV_3DVECTOR;
OrigRot: TV_3DVECTOR;
OrigLookAt: TV_3DVECTOR;
vDir: TD3DXVector4;
ContinueRenderingMeshes: Boolean;
Obj: Integer;
MeshToRender: Integer;
p: Integer;
i: Integer;
CPass: LongWord;
pMesh: ID3DXMesh;
vDif: TD3DXVector4;
MaterialIndex: Integer;
TextureIndex: Integer;
D3DTexture: Array[1..50] of iDirect3DTexture9;
MeshAddr: Integer;
MeshIndex: Integer;
D3DMesh: ID3DXMesh;
TmpPos: TV_3DVECTOR;
mWorldView: TD3DXMatrixA16;
begin
ElapsedTime := ElapsedTime + 0.00001;
////ElapsedTime := ElapsedTime + 0.0001;
If ElapsedTime > 1 then
ElapsedTime := 0;
Form1.SkyUpdate();
// Set the projection matrix
g_pEffect.SetMatrix('g_mProj', pmProj);
// A
// Light attached to Sun mesh used for Zak's HLSL Sky. Get the sun's world position and direction.
m := TVMatrixToD3DMatrix(Sun.GetMatrix());
v3 := D3DXVector3(m._41, m._42, m._43);
D3DXVec3Transform(vPos, v3, pmView);
//v4 := D3DXVector4(0.0, 0.0, -1.0, 1.0 ); // In object space, car is facing -Z
v4 := D3DXVector4(0.0, 0.0, 0.0, 1.0 );
m._41 := 0.0; m._42 := 0.0; m._43 := 0.0; // Remove the translation
D3DXVec4Transform(v4, v4, m); // Obtain direction in world space
v4.w := 0.0; // Set w 0 so that the translation part doesn't come to play
D3DXVec4Transform(v4, v4, pmView); // Direction in view space
D3DXVec3Normalize(PD3DXVector3(@v4)^, PD3DXVector3(@v4)^);
g_pEffect.SetVector('g_vLightDir', v4);
// vPos += v4 * 4.0f; // Offset the center by 3 so that it's closer to the headlight.
D3DXVec4Scale(v9, v4, 4.0);
D3DXVec4Add(vPos, vPos, v9);
{
// B
OrigPos := Form1.TVCam.GetPosition();
OrigRot := Form1.TVCam.GetRotation();
OrigLookAt := Form1.TVCam.GetLookAt();
TmpPos := Sun.GetPosition();
Form1.TVSunCam.SetPosition(TmpPos.X, TmpPos.Y, TmpPos.Z);
Form1.TVSunCam.SetLookAt(0, 0, 0);
vPos.X := Form1.TVSunCam.GetPosition.X;
vPos.Y := Form1.TVSunCam.GetPosition.Y;
vPos.Z := Form1.TVSunCam.GetPosition.Z;
vDir.x := vDir.x + vPos.x; // vDir denotes the look-at point
vDir.y := vDir.y + vPos.y;
vDir.z := vDir.z + vPos.z;
vDir.w := 0;
vUp := D3DXVector3(0.0, 1.0, 0.0);
Form1.TVCam.SetPosition(OrigPos.X, OrigPos.Y, OrigPos.Z);
Form1.TVCam.SetRotation(OrigRot.X, OrigRot.Y, OrigRot.Z);
Form1.TVCam.SetLookAt(OrigLookAt.X, OrigLookAt.Y, OrigLookAt.Z);
//.
}
//A
g_pEffect.SetVector('g_vLightPos', vPos);
//B
//g_pEffect.SetVector('g_vLightPos', vPos);
// Clear the render buffers
//OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene D3DDevice Clearing (ORing D3DCLEAR_TARGET with D3DCLEAR_ZBUFFER).'));
//Possibly not needed.
// g_pd3dDevice.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, $0000004D, 1.0, 0);
//OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene D3DDevice Clearing (ORing D3DCLEAR_TARGET with D3DCLEAR_ZBUFFER) finished.'));
//Was in here for the longest time, seemed to have an effect for the better
//we're moving it to the top though for some testing
Form1.TV.Clear(False);
{
ElapsedTime := ElapsedTime + 0.00001;
////ElapsedTime := ElapsedTime + 0.0001;
If ElapsedTime > 1 then
ElapsedTime := 0;
Form1.SkyUpdate();
}
if RenderShadow = true then
begin
OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene Setting Technique(RenderShadow).'));
g_pEffect.SetTechnique('RenderShadow');
OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene Setting Technique(RenderShadow) finished.'));
end;
OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene Begining Scene.'));
//if SUCCEEDED(g_pD3DDevice.BeginScene) then
// begin
g_pD3DDevice.BeginScene();
if not RenderShadow then
begin
g_pEffect.SetTechnique('RenderScene');
end;
// RenderDXMeshes_NoEffects(vDif, pmView);
// Form1.Mesh[1].Render();
// Form1.Mesh[2].Render();
// RenderDXMeshes_Effects(vDif, pmView);
OutputDebugString(PChar('--- Project 1: TShadowMap::RenderScene Starting rendering of meshes.'));
// Render the objects
for obj := 0 to MaxMeshes do
begin
If Form1.MeshObjIndexesUsed[obj] = 1 Then
begin
MeshAddr := Form1.TVInternals.GetD3DMesh(Form1.Mesh[obj].GetIndex);
MeshIndex := Form1.Mesh[obj].GetIndex();
D3DMesh := ID3DXMesh(MeshAddr);
OutputDebugString(PChar('---- Project 1: TShadowMap::RenderScene Setting up Mesh:' + IntToStr(obj)));
mWorldView := TVMatrixToD3DMatrix(Form1.Mesh[obj].GetMatrix);
D3DXMatrixMultiply(mWorldView, mWorldView, pmView);
g_pEffect.SetMatrix('g_mWorldView', mWorldView);
D3DMesh.GetNumFaces();
g_pEffect._Begin(@cPass, 0);
for p := 0 to cPass - 1 do
begin
OutputDebugString(PChar('----- Project 1: TShadowMap::RenderScene Starting Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj)));
g_pEffect.BeginPass(p);
for i := 0 to Form1.Mesh[obj].GetGroupCount() - 1 do
begin
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Setting up Material in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj)));
//Basically we're just getting the material for
//each group of the mesh and the diffuse colors
//for that material then sending that info to
//the effect object.
MaterialIndex := Form1.Mesh[obj].GetMaterial(i);
//vDif stands for vector Diffuse
vDif := D3DXVector4(Form1.TVMaterial.GetDiffuse(MaterialIndex).r,
Form1.TVMaterial.GetDiffuse(MaterialIndex).g,
Form1.TVMaterial.GetDiffuse(MaterialIndex).b,
Form1.TVMaterial.GetDiffuse(MaterialIndex).a);
g_pEffect.SetVector('g_vMaterial', vDif);
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Setting up Material in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj) + ' finished.'));
Application.ProcessMessages();
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Setting up Texture in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj)));
//Now we do the same for the textures
TextureIndex := Form1.Mesh[obj].GetTexture(i);
if TextureIndex > 0 then
begin
D3DTexture[i] := iDirect3DTexture9(Form1.TVInternals.GetTexture(TextureIndex));
g_pEffect.SetTexture('g_txScene', D3DTexture[i]);
end
else
g_pEffect.SetTexture('g_txScene', g_pTexDef);
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Setting up Texture in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj) + ' finished.'));
g_pEffect.CommitChanges;
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Drawing Subset #:' + IntToStr(i) + ' in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj)));
//D3DMesh.DrawSubset(i);
Form1.TVInternals.UpdateD3DMesh(MeshIndex);
OutputDebugString(PChar('------ Project 1: TShadowMap::RenderScene Drawing Subset #:' + IntToStr(i) + ' in Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj) + ' finished.'));
end;
g_pEffect.EndPass;
OutputDebugString(PChar('----- Project 1: TShadowMap::RenderScene Pass #:' + IntToStr(p) + ' on Mesh:' + IntToStr(obj) + ' finished.'));
Form1.Mesh[1].Render();
end; //for p := 0 to cPass - 1 do
g_pEffect._End;
end; //If Form1.MeshObjIndexesUsed[obj] = 1 Then
end; //for obj := 0 to MaxMeshes do
OutputDebugString(PChar('--- Project 1: TShadowMap::RenderScene rendering of meshes finished.'));
// Render light
if not RenderShadow then
g_pEffect.SetTechnique('RenderLight');
//mWorldView := TVMatrixToD3DMatrix(Form1.TVSunCam.GetMatrix());
mWorldView := TVMatrixToD3DMatrix(Sun.GetMatrix());
//Inverse line was added to me, in attempt to get material shading back.
//Shouldn't the Inverse line be in here??
// D3DXMatrixInverse(mWorldView, nil, mWorldView);
D3DXMatrixMultiply(mWorldView, mWorldView, pmView);
g_pEffect.SetMatrix('g_mWorldView', mWorldView);
OutputDebugString(PChar('-- Project 1: TShadowMap::RenderScene D3DDevice Ending Scene.'));
Form1.RenderSky();
g_pD3DDevice.EndScene();
// Might not even be needed.
// Form1.TV.RenderToScreen();
//end; //if SUCCEEDED(g_pD3DDevice.BeginScene) then
end;
end.
|