├── LICENSE
├── README.mkd
├── bin
├── fmodex.dll
├── fx
│ ├── pp_combine.hlsl
│ ├── pp_common.hlsl
│ ├── pp_resolve.hlsl
│ ├── qnoise.hlsl
│ └── snoise.hlsl
├── live_coding.exe
├── media
│ ├── bgm.mp3
│ └── tex.bmp
└── save
│ ├── aegis.hlsl
│ ├── clouds.hlsl
│ ├── guitar.hlsl
│ ├── julia.hlsl
│ ├── julia3d.hlsl
│ ├── mandelbox.hlsl
│ ├── mandelbrot4d.hlsl
│ ├── mandelbulb.hlsl
│ ├── menger.hlsl
│ ├── penrose.hlsl
│ ├── piano.hlsl
│ ├── sierpinski.hlsl
│ ├── sphere.hlsl
│ └── tunnel.hlsl
├── live_coding.sln
├── live_coding.vcxproj
├── snap.png
└── src
├── ayw
├── common_helper.h
├── constant.hpp
├── vector.hpp
└── vector_helper.hpp
├── common.cpp
├── common.hpp
├── d3d_app.cpp
├── d3d_app.hpp
├── editable_text.cpp
├── editable_text.hpp
├── hr_timer.cpp
├── hr_timer.hpp
├── keywords.hpp
├── main.cpp
├── post_process.cpp
├── post_process.hpp
├── shader_header.cpp
├── shader_header.hpp
├── sound_player.cpp
├── sound_player.hpp
├── syntax_highlighter.cpp
├── syntax_highlighter.hpp
├── text_editor.cpp
└── text_editor.hpp
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Yuwen Wu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.mkd:
--------------------------------------------------------------------------------
1 | This is a live coding tool for HLSL, inspired by:
2 |
3 | - iq. http://www.iquilezles.org/live/index.htm
4 | - githole. https://github.com/githole/Live-Coder
5 |
6 | 
7 |
8 | + Dependencies
9 |
10 | [If you won't bother the compiling stuff, just run bin/live_coding.exe and play around.]
11 |
12 | To compile, you will need following libs:
13 |
14 | - DirectSDK, June 2010.
15 | - Boost 1.41(or newer).
16 | - FMOD 4.32(or newer).
17 |
18 | Only vs2010 project is provided, so please use vs2010 to compile.
19 |
20 | + Live Coding
21 |
22 | The program only runs on Win7. The way of typing codes is very like vs2010 except mouse is not supported, you can only use keyboard to move caret and input.
23 |
24 | Following list some shortkeys, see src/TextEditor.cpp for more.
25 |
26 | - Ctrl + 'S' : save codes to file and compile.
27 | - Ctrl + 'O' : open an existing file.
28 | - Ctrl + 'M' : turn on/off music.
29 | - Ctrl + '-' : decrease volume.
30 | - Ctrl + '=' : increase volume.
31 |
32 | - Tab : auto jump (when the next char is ')' or '}').
33 | - Ctrl + ',' : jump into next scope.
34 | - Ctrl + '.' : jump out of current scope.
35 | - Ctrl + 'C' : copy current selection. (or current line if select none)
36 | - Ctrl + 'L' : cut current line.
37 |
38 | - F1 : toggle show/hide text editor.
39 | - F2 : toggle antialiasing.
40 |
41 | Have fun!
42 |
--------------------------------------------------------------------------------
/bin/fmodex.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atyuwen/hlsl_live_coding/c402d73ff80d81e84f1241109d8b93e729853061/bin/fmodex.dll
--------------------------------------------------------------------------------
/bin/fx/pp_combine.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D src_texture0 : register(t0);
2 | Texture2D src_texture1 : register(t1);
3 |
4 | float4 ps_main(in float4 sc : SV_POSITION) : SV_TARGET
5 | {
6 | int3 p = int3(sc.xy, 0);
7 | float4 col0 = src_texture0.Load(p);
8 | float4 col1 = src_texture1.Load(p);
9 | return lerp(saturate(col0), saturate(col1), col1.a);
10 | }
11 |
--------------------------------------------------------------------------------
/bin/fx/pp_common.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float2 subpixel_jitter;
4 | }
5 |
6 | void vs_main(in float3 in_pos : POSITION,
7 | in float2 in_tex : TEXCOORD,
8 | out float2 out_tex: TEXCOORD,
9 | out float4 out_pos: SV_POSITION)
10 | {
11 | out_pos = float4(in_pos.xy, 0, 1);
12 | out_tex = in_tex + subpixel_jitter;
13 | }
14 |
15 | float4 ps_main(in float2 in_tex : TEXCOORD) : SV_TARGET
16 | {
17 | return float4(0.3, 0.3, 0.3, 1);
18 | }
19 |
--------------------------------------------------------------------------------
/bin/fx/pp_resolve.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float2 interleave;
4 | }
5 |
6 | Texture2D src_texture0 : register(t0);
7 |
8 | float4 resolve(in float4 sc : SV_POSITION) : SV_TARGET
9 | {
10 | int3 p = int3(sc.xy, 0);
11 | float3 col = src_texture0.Load(p).rgb;
12 | return float4(saturate(col), 0.02);
13 | }
14 |
15 | float4 halfres_resolve(in float4 sc : SV_POSITION) : SV_TARGET
16 | {
17 | int2 p = int2(sc.xy);
18 | clip(-abs(fmod(p, 2) - interleave));
19 | float3 col = src_texture0.Load(int3(p / 2, 0)).rgb;
20 | return float4(saturate(col), 0.08);
21 | }
22 |
23 | float4 halfres_copy(in float4 sc : SV_POSITION) : SV_TARGET
24 | {
25 | int3 p = int3(sc.xy / 2, 0);
26 | return saturate(src_texture0.Load(p));
27 | }
28 |
--------------------------------------------------------------------------------
/bin/fx/qnoise.hlsl:
--------------------------------------------------------------------------------
1 | // migrated from iq's GLSL code
2 |
3 | float4 __hash(float4 n)
4 | {
5 | return frac(sin(n) * 43758.5453);
6 | }
7 |
8 | float qnoise(float2 x)
9 | {
10 | float2 p = floor(x);
11 | float2 f = frac(x);
12 | f = f * f * (3.0 - 2.0 * f);
13 | float n = p.x + p.y * 57.0;
14 | float4 h = __hash(n + float4(113, 114, 170, 171));
15 | float2 v = lerp(h.xz, h.yw, f.x);
16 | return lerp(v.x, v.y, f.y);
17 | }
18 |
19 | float qnoise(float3 x)
20 | {
21 | float3 p = floor(x);
22 | float3 f = frac(x);
23 | f = f * f * (3.0 - 2.0 * f);
24 |
25 | float n = dot(p, float3(1, 57, 113));
26 | float4 h0 = __hash(n + float4(0, 57, 113, 170));
27 | float4 h1 = __hash(n + float4(1, 58, 114, 171));
28 |
29 | float4 u = lerp(h0, h1, f.x);
30 | float2 v = lerp(u.xz, u.yw, f.y);
31 | return lerp(v.x, v.y, f.z);
32 | }
33 |
--------------------------------------------------------------------------------
/bin/fx/snoise.hlsl:
--------------------------------------------------------------------------------
1 | // Simplex noise function.
2 | // Migrated from Ian McEwan's glsl code, see: https://github.com/ashima/webgl-noise
3 | // Copyright (C) 2011 Ashima Arts. All rights reserved.
4 |
5 | #define __mod289(x) ((x) - floor((x) * (1.0 / 289.0)) * 289.0)
6 |
7 | #define __permute(x) (__mod289((((x) * 34.0) + 1.0) * (x)))
8 |
9 | #define __taylor_inv_sqrt(x) (1.79284291400159 - 0.85373472095314 * (x))
10 |
11 | float snoise(float2 v)
12 | {
13 | const float4 C = float4( 0.211324865405187, // (3.0-sqrt(3.0))/6.0
14 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
15 | -0.577350269189626, // -1.0 + 2.0 * C.x
16 | 0.024390243902439); // 1.0 / 41.0
17 | // First corner
18 | float2 i = floor(v + dot(v, C.yy));
19 | float2 x0 = v - i + dot(i, C.xx);
20 |
21 | // Other corners
22 | float2 i1;
23 | i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
24 | float4 x12 = x0.xyxy + C.xxzz;
25 | x12.xy -= i1;
26 |
27 | // Permutations
28 | i = __mod289(i); // Avoid truncation effects in permutation
29 | float3 p = __permute(__permute(i.y + float3(0.0, i1.y, 1.0)) + i.x + float3(0.0, i1.x, 1.0));
30 |
31 | float3 m = max(0.5 - float3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
32 | m = m * m;
33 | m = m * m;
34 |
35 | // Gradients: 41 points uniformly over a line, mapped onto a diamond.
36 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
37 | float3 x = 2.0 * frac(p * C.www) - 1.0;
38 | float3 h = abs(x) - 0.5;
39 | float3 ox = floor(x + 0.5);
40 | float3 a0 = x - ox;
41 |
42 | // Normalise gradients implicitly by scaling m
43 | m *= __taylor_inv_sqrt(a0*a0 + h*h);
44 |
45 | // Compute final noise value at P
46 | float3 g;
47 | g.x = a0.x * x0.x + h.x * x0.y;
48 | g.yz = a0.yz * x12.xz + h.yz * x12.yw;
49 | return 130.0 * dot(m, g);
50 | }
51 |
52 | float snoise(float3 v)
53 | {
54 | const float2 C = float2(1.0/6.0, 1.0/3.0);
55 | const float4 D = float4(0.0, 0.5, 1.0, 2.0);
56 |
57 | // First corner
58 | float3 i = floor(v + dot(v, C.yyy) );
59 | float3 x0 = v - i + dot(i, C.xxx) ;
60 |
61 | // Other corners
62 | float3 g = step(x0.yzx, x0.xyz);
63 | float3 l = 1.0 - g;
64 | float3 i1 = min( g.xyz, l.zxy );
65 | float3 i2 = max( g.xyz, l.zxy );
66 |
67 | float3 x1 = x0 - i1 + C.xxx;
68 | float3 x2 = x0 - i2 + C.yyy; // 2.0 * C.x = 1/3 = C.y
69 | float3 x3 = x0 - D.yyy; // -1.0 + 3.0 * C.x = -0.5 = -D.y
70 |
71 | // Permutations
72 | i = __mod289(i);
73 | float4 p = __permute( __permute( __permute(
74 | i.z + float4(0.0, i1.z, i2.z, 1.0))
75 | + i.y + float4(0.0, i1.y, i2.y, 1.0))
76 | + i.x + float4(0.0, i1.x, i2.x, 1.0));
77 |
78 | // Gradients: 7x7 points over a square, mapped onto an octahedron.
79 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
80 | float n_ = 0.142857142857; // 1.0/7.0
81 | float3 ns = n_ * D.wyz - D.xzx;
82 |
83 | float4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p, 7*7)
84 |
85 | float4 x_ = floor(j * ns.z);
86 | float4 y_ = floor(j - 7.0 * x_ ); // mod(j, N)
87 |
88 | float4 x = x_ * ns.x + ns.yyyy;
89 | float4 y = y_ * ns.x + ns.yyyy;
90 | float4 h = 1.0 - abs(x) - abs(y);
91 |
92 | float4 b0 = float4(x.xy, y.xy);
93 | float4 b1 = float4(x.zw, y.zw);
94 |
95 | float4 s0 = floor(b0) * 2.0 + 1.0;
96 | float4 s1 = floor(b1) * 2.0 + 1.0;
97 | float4 sh = -step(h, 0);
98 |
99 | float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy ;
100 | float4 a1 = b1.xzyw + s1.xzyw * sh.zzww ;
101 |
102 | float3 p0 = float3(a0.xy, h.x);
103 | float3 p1 = float3(a0.zw, h.y);
104 | float3 p2 = float3(a1.xy, h.z);
105 | float3 p3 = float3(a1.zw, h.w);
106 |
107 | //Normalise gradients
108 | float4 norm = __taylor_inv_sqrt(float4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
109 | p0 *= norm.x;
110 | p1 *= norm.y;
111 | p2 *= norm.z;
112 | p3 *= norm.w;
113 |
114 | // Mix final noise value
115 | float4 m = max(0.6 - float4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
116 | m = m * m;
117 | return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
118 | }
119 |
120 | float4 __grad4(float j, float4 ip)
121 | {
122 | const float4 ones = float4(1.0, 1.0, 1.0, -1.0);
123 | float4 p,s;
124 |
125 | p.xyz = floor(frac(float3(j, j, j) * ip.xyz) * 7.0) * ip.z - 1.0;
126 | p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
127 | s = 1.0 - step(0.0, p);
128 | p.xyz = p.xyz + (s.xyz * 2.0 - 1.0) * s.www;
129 |
130 | return p;
131 | }
132 |
133 | // (sqrt(5) - 1) / 4 = F4, used once below
134 | #define __F4 0.309016994374947451
135 |
136 | float snoise(float4 v)
137 | {
138 | const float4 C = float4( 0.138196601125011, // (5 - sqrt(5)) / 20 = G4
139 | 0.276393202250021, // 2 * G4
140 | 0.414589803375032, // 3 * G4
141 | -0.447213595499958); // -1 + 4 * G4
142 |
143 | // First corner
144 | float4 i = floor(v + dot(v, float4(__F4, __F4, __F4, __F4)));
145 | float4 x0 = v - i + dot(i, C.xxxx);
146 |
147 | // Other corners
148 |
149 | // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
150 | float4 i0;
151 | float3 isX = step( x0.yzw, x0.xxx );
152 | float3 isYZ = step( x0.zww, x0.yyz );
153 | i0.x = isX.x + isX.y + isX.z;
154 | i0.yzw = 1.0 - isX;
155 | i0.y += isYZ.x + isYZ.y;
156 | i0.zw += 1.0 - isYZ.xy;
157 | i0.z += isYZ.z;
158 | i0.w += 1.0 - isYZ.z;
159 |
160 | // i0 now contains the unique values 0,1,2,3 in each channel
161 | float4 i3 = clamp( i0, 0.0, 1.0 );
162 | float4 i2 = clamp( i0-1.0, 0.0, 1.0 );
163 | float4 i1 = clamp( i0-2.0, 0.0, 1.0 );
164 |
165 | float4 x1 = x0 - i1 + C.xxxx;
166 | float4 x2 = x0 - i2 + C.yyyy;
167 | float4 x3 = x0 - i3 + C.zzzz;
168 | float4 x4 = x0 + C.wwww;
169 |
170 | // Permutations
171 | i = __mod289(i);
172 | float j0 = __permute( __permute( __permute( __permute(i.w) + i.z) + i.y) + i.x);
173 | float4 j1 = __permute( __permute( __permute( __permute (
174 | i.w + float4(i1.w, i2.w, i3.w, 1.0 ))
175 | + i.z + float4(i1.z, i2.z, i3.z, 1.0 ))
176 | + i.y + float4(i1.y, i2.y, i3.y, 1.0 ))
177 | + i.x + float4(i1.x, i2.x, i3.x, 1.0 ));
178 |
179 | // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
180 | // 7*7*6 = 294, which is close to the ring size 17*17 = 289.
181 | float4 ip = float4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
182 |
183 | float4 p0 = __grad4(j0, ip);
184 | float4 p1 = __grad4(j1.x, ip);
185 | float4 p2 = __grad4(j1.y, ip);
186 | float4 p3 = __grad4(j1.z, ip);
187 | float4 p4 = __grad4(j1.w, ip);
188 |
189 | // Normalise gradients
190 | float4 norm = __taylor_inv_sqrt(float4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
191 | p0 *= norm.x;
192 | p1 *= norm.y;
193 | p2 *= norm.z;
194 | p3 *= norm.w;
195 | p4 *= __taylor_inv_sqrt(dot(p4,p4));
196 |
197 | // Mix contributions from the five corners
198 | float3 m0 = max(0.6 - float3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
199 | float2 m1 = max(0.6 - float2(dot(x3,x3), dot(x4,x4) ), 0.0);
200 | m0 = m0 * m0;
201 | m1 = m1 * m1;
202 | return 49.0 * ( dot(m0 * m0, float3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
203 | + dot(m1 * m1, float2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
204 | }
205 |
--------------------------------------------------------------------------------
/bin/live_coding.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atyuwen/hlsl_live_coding/c402d73ff80d81e84f1241109d8b93e729853061/bin/live_coding.exe
--------------------------------------------------------------------------------
/bin/media/bgm.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atyuwen/hlsl_live_coding/c402d73ff80d81e84f1241109d8b93e729853061/bin/media/bgm.mp3
--------------------------------------------------------------------------------
/bin/media/tex.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atyuwen/hlsl_live_coding/c402d73ff80d81e84f1241109d8b93e729853061/bin/media/tex.bmp
--------------------------------------------------------------------------------
/bin/save/aegis.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 fft;
6 | }
7 |
8 | bool rect(int2 p, int l, int r, int b, int t)
9 | {
10 | return (l <= p.x && p.x <= r && b <= p.y && p.y <= t);
11 | }
12 |
13 | float4 ps_main(in float2 in_tex : TEXCOORD) : SV_TARGET
14 | {
15 | float progress = fmod(time.x, 300) / 300;
16 | int2 p = in_tex * view.xy;
17 | if (p.x > 640 || p.y > 320) return float4(0.1, 0.1, 0.1, 1);
18 | p.y = 320 - p.y;
19 |
20 | float3 c = 0.15;
21 | if (rect(p, 14, 625, 30, 308))
22 | c = 0.3;
23 | if (rect(p, 15, 624, 31, 307))
24 | c = 0.1;
25 |
26 | if (rect(p, 14, 625, 15, 17))
27 | {
28 | float s = (p.x - 14) / 610.0;
29 | if (s < progress)
30 | c = lerp(float3(0.2, 0.3, 0.4), float3(0.8, 0.4, 0.5), s);
31 | else c = 0.1;
32 | if (p.y == 15) c += 0.15;
33 | }
34 |
35 | float l = progress * 606 + 14;
36 | if (rect(p, l, l + 6, 10, 21)) c = 0;
37 | if (rect(p, l, l + 5, 11, 21)) c = 0.4;
38 | if (rect(p, l + 1, l + 5, 11, 20)) c = 0.3;
39 |
40 | p = int2(p.x - 16, p.y - 32);
41 | float2 fq = p / float2(19, 5);
42 | int2 q = floor(fq);
43 | int2 r = p - q * float2(19, 5);
44 | if (q.x >= 0 && q.x < 32 && q.y >= 0 && q.y < 55)
45 | {
46 | c = float3(0.16, 0.18, 0.19);
47 | float v = snoise(float2(q.x, 20 * time.x) * 0.1) * 0.4 + 0.1 + fft.xz;
48 | if (q.y < v * 55)
49 | {
50 | float2 s = q / float2(31, 59);
51 | c = lerp(float3(0.4, 0.12, 0.1), float3(0.1, 0.4, 0.5), s.x);
52 | c = lerp(c, c + 0.6, s.y);
53 | }
54 |
55 | if (r.x > 17 || r.y > 3) c = 0.15;
56 |
57 | float m = abs(fq.y / 55 - 0.5) * 2;
58 | c += pow(m, 12) * float3(0.2, 0.23, 0.26);
59 | }
60 | return float4(c, 1);
61 | }
62 |
--------------------------------------------------------------------------------
/bin/save/clouds.hlsl:
--------------------------------------------------------------------------------
1 | // migrated from iq's GLSL code
2 | // Created by inigo quilez - iq/2013
3 |
4 | cbuffer Parameters : register(b0)
5 | {
6 | float4 time;
7 | float4 view;
8 | float4 freq;
9 | float4 mpos;
10 | }
11 |
12 | float fbm(float3 p)
13 | {
14 | float f;
15 | f = 0.5000 * qnoise(p); p = p * 2.02;
16 | f += 0.2500 * qnoise(p); p = p * 2.03;
17 | f += 0.1250 * qnoise(p); p = p * 2.01;
18 | f += 0.0625 * qnoise(p);
19 | return f;
20 | }
21 |
22 | float4 map(in float3 p)
23 | {
24 | float d = 0.5 - p.y;
25 | d += 3.0 * fbm( p*1.0 - float3(1.0,0.1,0.0) * time.x);
26 | float4 res = saturate(d);
27 | res.xyz = lerp(1.15*float3(1.0,0.95,0.8), float3(0.7,0.7,0.7), res.x);
28 | return res;
29 | }
30 |
31 | static float3 sundir = float3(-1,0,0);
32 |
33 | float4 raymarch(in float3 ro, in float3 rd)
34 | {
35 | float4 sum = 0;
36 | float t = 0.0;
37 | for(int i = 0; i < 44; i++)
38 | {
39 | float3 pos = ro + t*rd;
40 | float4 col = map( pos );
41 | float dif = saturate((col.w - map(pos+0.3*sundir).w)/0.6);
42 | float3 brdf = float3(0.65,0.68,0.7)*1.35 + 0.45*float3(0.7, 0.5, 0.3)*dif;
43 |
44 | col.xyz *= brdf;
45 | col.a *= 0.35;
46 | col.rgb *= col.a;
47 |
48 | sum = sum + col*(1.0 - sum.a);
49 | t += max(0.1,0.05*t);
50 | }
51 | sum.xyz /= (0.001+sum.w);
52 | return saturate(sum);
53 | }
54 |
55 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
56 | {
57 | float2 p = tc * 2 - 1;
58 | p *= float2(view.x * view.w, -1);
59 | float2 mo = -1 + 2 * mpos.xy / view.xy;
60 |
61 | // camera
62 | float3 ro = 4.0*normalize(float3(cos(2.75-3.0*mo.x), 0.7+(mo.y+1.0), sin(2.75-3.0*mo.x)));
63 | float3 ta = float3(0.0, 1.0, 0.0);
64 | float3 ww = normalize( ta - ro);
65 | float3 uu = normalize(cross( float3(0.0,1.0,0.0), ww ));
66 | float3 vv = normalize(cross(ww,uu));
67 | float3 rd = normalize( p.x*uu + p.y*vv + 1.5*ww );
68 |
69 | float4 res = raymarch( ro, rd );
70 | float sun = saturate(dot(sundir,rd));
71 | float3 col = float3(0.6,0.71,0.75) - rd.y*0.2*float3(1.0,0.5,1.0) + 0.15*0.5;
72 | col += 0.2*float3(1.0,.6,0.1) * pow(sun, 8.0);
73 | col *= 0.95;
74 | col = lerp(col, res.xyz, res.w);
75 | col += 0.1*float3(1.0,0.4,0.2) * pow(sun, 2.0);
76 |
77 | return float4( col, 1.0 );
78 | }
79 |
--------------------------------------------------------------------------------
/bin/save/guitar.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float body(float3 p)
10 | {
11 | p.x *= 0.6;
12 | float d1 = length(p.xy) - 0.4;
13 | p.y -= 0.5;
14 | float d2 = length(p.xy) - 0.18;
15 | float d = lerp(d1, d2, saturate((p.y + 0.9) * 0.8));
16 | d = max(d, abs(p.z) - 0.1);
17 | return d;
18 | }
19 |
20 | float neck(float3 p, out float id)
21 | {
22 | id = 1;
23 | p.y -= 1;
24 | float t = min(p.y + 0.7, 1.21);
25 | float h = saturate(p.y + 0.7 - 1.21);
26 | p.z -= 0.114 - saturate(t) * 0.02 - h * 0.15;
27 | if (p.z > -0.012) id = 2;
28 | p.x *= (1 + 0.3 * t) - min(12 * h, 0.4 + h);
29 | p.y *= (1 + h * abs(p.x));
30 | float s = clamp((t - 0.32) * 10, 0.3, 1);
31 | float d = length(p.xz * float2(1, s)) - 0.05;
32 | p.z += 0.3;
33 | s = fmod(pow(t, 0.48) + 2.005, 0.036) - 0.002;
34 | s = saturate(0.004 - s * s * 800 * t);
35 | if (s > 0 && p.z > 0.3) id = 3;
36 | p.z -= s;
37 | d = max(d, length(p.xz) - 0.3);
38 | d = max(d, abs(p.y) - 0.74);
39 | return d * 0.7;
40 | }
41 |
42 | float inner(float3 p)
43 | {
44 | p.y -= 0.32;
45 | float d1 = max(length(p.xy) - 0.1, -p.z);
46 | float d2 = max(length(p.xy) - 0.2, abs(p.z) - 0.09);
47 | return min(d1, d2);
48 | }
49 |
50 | float bridge(float3 p, out float id)
51 | {
52 | id = 1;
53 | p.y += 0.06;
54 | p.z += clamp(abs(p.x) * 0.12, 0.01, 0.02) - 0.11;
55 | float d = length(max(abs(p) - float3(0.15, 0.02, 0.02), 0)) * 0.9;
56 | float d2 = length(max(abs(p - float3(0, 0.012, 0)) - float3(0.07, 0.003, 0.027), 0));
57 | if (d2 < d) {d = d2; id = 2;}
58 | if (abs(p.x) > 0.06) return d;
59 | p.x = fmod(p.x + 2, 0.02) - 0.01;
60 | p.z -= 0.025;
61 | float d3 = length(p.xyz) - 0.005;
62 | if (d3 < d) {d = d3; id = 3;}
63 | return d;
64 | }
65 |
66 | float screws(float3 p)
67 | {
68 | float t = min(p.y - 1.53, 0.18);
69 | p.z -= 0.075 - 0.15 * t;
70 | p.y = fmod(t - p.z * 0.2, 0.06) - 0.03;
71 | p.x = abs(p.x) - 0.033;
72 | float r = p.z < 0 ? 0.01 : 0.005;
73 | float d = max(length(p.xy) - r, abs(p.z) - 0.035);
74 | d = min(d, max(length(p.xy) - 0.009, abs(p.z) - 0.02));
75 | p.z += 0.024;
76 | d = min(d, max(length(p.yz) - 0.004, abs(p.x) - 0.03));
77 |
78 | // handle
79 | p.x -= 0.02 + 0.05 * t;
80 | float h = length(p.xyz) - 0.014;
81 | p.x -= 0.01;
82 | h = max(h, length(max(abs(p.xyz) - float3(0.01, 0.01, 0.004), 0)));
83 | d = min(d, h);
84 | return d * 0.9;
85 | }
86 |
87 | float strings(float3 p)
88 | {
89 | p.y -= 0.72;
90 | float t = min(p.y + 0.785, 1.57);
91 | p.x *= (1 + 0.4 * t);
92 | if (abs(p.x) > 0.06) return 1e3;
93 |
94 | float f = saturate(p.y - 0.78);
95 | if (p.y > 0) p.y *= 0.65 + 3.6 * abs(p.x);
96 | p.x += clamp(-sign(p.x) * 0.2 * f, -abs(p.x), abs(p.x));
97 | p.z += 0.15 * f;
98 |
99 | float r = 0.0006 - p.x * 0.006;
100 | p.z -= 0.125 - 0.015 * t;
101 | p.x = fmod(p.x + 2, 0.02) - 0.01;
102 | float d = length(p.xz) - r;
103 | d = max(d, abs(p.y) - 0.785);
104 | return d;
105 | }
106 |
107 | float2 DE(float3 p)
108 | {
109 | // bounding box
110 | float3 bb = saturate(abs(p.xyz) - float3(0.5, 2, 0.3));
111 | if (any(bb)) return float2(length(bb) + 0.01, -1);
112 |
113 | float d = body(p);
114 | float id = 1;
115 | float sid = 0;
116 | float t = neck(p, sid);
117 | if (t < d) {d = t; id = 2 + sid * 0.1;}
118 | t = -inner(p);
119 | if (t > d) {d = t; id = 3;}
120 | t = bridge(p, sid);
121 | if (t < d) {d = t; id = 4 + sid * 0.1;}
122 | t = screws(p);
123 | if (t < d) {d = t; id = 5;}
124 | t = strings(p);
125 | if (t < d) {d = t; id = 6;}
126 | return float2(d, id);
127 | }
128 |
129 | float4 ray_marching(float3 ro, float3 rd)
130 | {
131 | float3 p = ro;
132 | for (int i = 0; i < 64; ++i)
133 | {
134 | float2 d = DE(p);
135 | p += d.x * rd;
136 | if (d.x < 0.0001) return float4(p, d.y);
137 | }
138 |
139 | float t = (-0.4 - ro.y) / rd.y;
140 | float3 floorp = ro + t * rd;
141 | if (t > 0) return float4(floorp, 0);
142 | return float4(ro, -1);
143 | }
144 |
145 | float3 brdf(float3 diff, float m, float3 N, float3 L, float3 V)
146 | {
147 | float3 H = normalize(V + L);
148 | float3 F = 0.05 + 0.95 * pow(1 - dot(V, H), 5);
149 | float3 R = F * pow(max(dot(N, H), 0), m);
150 | return diff + R * (m + 8) / 8;
151 | }
152 |
153 | float4 shade(float3 ro, float3 rd)
154 | {
155 | float4 rm = ray_marching(ro, rd);
156 | if (rm.w < 0) return float4(0, 0, 0, 0);
157 |
158 | float3 p = rm.xyz;
159 | float k = DE(p).x;
160 | float gx = DE(p + float3(1e-5, 0, 0)).x - k;
161 | float gy = DE(p + float3(0, 1e-5, 0)).x - k;
162 | float gz = DE(p + float3(0, 0, 1e-5)).x - k;
163 | float3 N = normalize(float3(gx, gy, gz));
164 |
165 | float ao = 0;
166 | ao += DE(p + 0.01 * N).x * 50;
167 | ao += DE(p + 0.02 * N).x * 10;
168 |
169 | float3 L = normalize(float3(-0.1, 1, 1));
170 | float sr = ray_marching(p + 0.001 * L, L).w;
171 | float shadow = sr > 0 ? 0 : 1;
172 |
173 | float3 diff = 0.8;
174 | float m = 10;
175 | if (rm.w < 0.9) // floor
176 | {
177 | shadow = saturate(0.4 + 0.6 * shadow + 0.3 * length(p.xz));
178 | return float4(float3(0.02, 0.02, 0.02) * shadow, 1);
179 | }
180 | if (rm.w < 1.9) // body
181 | {
182 | float3 C = float3(0.8, 0.6, 0.2);
183 | float s = length(p.xy - float2(0, 0.32));
184 | if (abs(s - 0.12) < 0.008) C = float3(0.01, 0.004, 0);
185 |
186 | diff = lerp(float3(0.02, 0.008, 0.001), C, saturate(N.z));
187 | float r = qnoise(200 * p.xzz + 2 * qnoise(5 * p.yyz));
188 | diff *= (r * 0.3 + 0.7);
189 | if (abs(abs(p.z) - 0.08) < 0.005) diff = 0.8;
190 | }
191 | else if (rm.w < 2.25) // neck
192 | {
193 | diff = float3(0.3, 0.18, 0.1) * (0.7 + qnoise(300 * p) * 0.3);
194 | if (rm.w > 2.15) diff *= 0.4;
195 | }
196 | else if (rm.w < 2.9)
197 | {
198 | diff = float3(0.8, 0.6, 0.4);
199 | m = 80;
200 | }
201 | else if (rm.w < 3.9) // inner
202 | {
203 | diff = float3(0.25, 0.2, 0.15) * (0.5 + 0.5 * qnoise(400 * p.xzz));
204 | }
205 | else if (rm.w < 4.15) // bridge
206 | {
207 | diff = 0;
208 | }
209 | else if (rm.w < 4.25)
210 | {
211 | diff = 0.7;
212 | }
213 | else if (rm.w < 4.35)
214 | {
215 | diff = 0.04; m = 80;
216 | }
217 | else if (rm.w < 5.9) // screws
218 | {
219 | m = 50;
220 | }
221 | else // strings
222 | {
223 | m = 50;
224 | }
225 | float3 f = brdf(diff, m, N, L, -rd);
226 |
227 | float3 A = 0.2;
228 | float3 C = (saturate(dot(N, L)) * f * shadow + A * diff) * ao;
229 | return float4(C, 1);
230 | }
231 |
232 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
233 | {
234 | float3 p = float3((tc * 2 - 1), 0);
235 | p.xy *= float2(view.x * view.w, -1);
236 |
237 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.4, 0.3, 7);
238 | float4 rot;
239 | sincos(param.x, rot.x, rot.y);
240 | sincos(param.y, rot.z, rot.w);
241 |
242 | float3 rt = float3(0, 0.6, 0);
243 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
244 | ro = ro * param.z;
245 |
246 | float3 cd = normalize(rt - ro);
247 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
248 | float3 cu = cross(cr, cd);
249 |
250 | float3 rd = normalize(p.x * cr + p.y * cu + 5 * cd);
251 | float4 radiance = shade(ro, rd);
252 |
253 | float3 col = float3(0.02, 0.02, 0.02);
254 | col = lerp(col, radiance.rgb, radiance.a);
255 | return float4(pow(col, 0.45), 1);
256 | }
257 |
--------------------------------------------------------------------------------
/bin/save/julia.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float4 ps_main(in float2 in_tex : TEXCOORD) : SV_TARGET
10 | {
11 | float2 p = (in_tex - 0.5) * 3.0;
12 | p -= mpos.xy * 0.003;
13 | p *= 1 / max(0.5, 1 + mpos.z * 0.1);
14 | float t = time.x - step(0.4, freq.x) * 0.5;
15 | float2 c = float2(0.3 + sin(t * 0.3) * 0.2, 0.5 + snoise(time.xy * 0.1) * 0.3);
16 |
17 | float3 trap = 10;
18 | for (int i; i < 32; ++i)
19 | {
20 | p = float2(p.x * p.x - p.y * p.y, 2 * p.x * p.y) + c;
21 | float l = length(p);
22 | trap = min(trap, float3(p, l));
23 | if (l > 1.5) break;
24 | }
25 |
26 | float3 col = 0.5 * lerp(float3(0.1, 0.3, 0.4), float3(0.2, 0.9, 0.8), trap.x * 0.1);
27 | col += 0.3 * lerp(float3(0.1, 0.0, 0.4), float3(0.8, 0.2, 0.9), trap.y * 0.1);
28 | col += 0.2 * lerp(float3(0.8, 0.4, 0.1), float3(0.0, 1.3, 0.5), trap.z);
29 |
30 | return float4(col, 1);
31 | }
32 |
--------------------------------------------------------------------------------
/bin/save/julia3d.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float3 mul3d(float3 a, float3 b)
10 | {
11 | float3 c;
12 | c.x = dot(a.xy, b.xz) - dot(a.yz, b.yz);
13 | c.y = dot(a.xy, b.yx);
14 | c.z = dot(a.xz, b.zx);
15 | return c;
16 | }
17 |
18 | float DE(float3 p)
19 | {
20 | float3 b = float3(0.24, 0.38, 0.83);
21 | float3 c = p;
22 | float3 d = 1;
23 | float r = length(c);
24 | for (int i = 0; i < 16 && r < 3; ++i)
25 | {
26 | d = 2 * mul3d(c, d);
27 | c = mul3d(c, c) + b;
28 | r = length(c);
29 | }
30 | float dr = length(d);
31 | return 0.5 * log(r) * r / dr;
32 | }
33 |
34 | float4 ray_marching(float3 ro, float3 rd)
35 | {
36 | for (int i = 0; i < 64; ++i)
37 | {
38 | float d = DE(ro);
39 | ro += d * rd;
40 | if (d < 0.01) return float4(ro, i);
41 | }
42 | return float4(ro, -1);
43 | }
44 |
45 | float4 shade(float3 ro, float3 rd)
46 | {
47 | float4 rm = ray_marching(ro, rd);
48 | if (rm.w < 0) return float4(0, 0, 0, 0);
49 |
50 | float3 p = rm.xyz;
51 | float k = DE(p);
52 | float gx = DE(p + float3(1e-5, 0, 0)) - k;
53 | float gy = DE(p + float3(0, 1e-5, 0)) - k;
54 | float gz = DE(p + float3(0, 0, 1e-5)) - k;
55 | float3 N = normalize(float3(gx, gy, gz));
56 |
57 | float ao = 0;
58 | ao += DE(p + 0.2 * N) * 2.5;
59 | ao += DE(p + 0.5 * N) * 1.0;
60 |
61 | float3 L = normalize(float3(-2, 1, 0.5));
62 | float3 C = float3(0.3, 0.2, 0.8);
63 | float D = 0.7;
64 | float A = 0.1;
65 | float3 col = (A + D * saturate(dot(L, N))) * ao * C;
66 | return float4(col , 1);
67 | }
68 |
69 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
70 | {
71 | float3 p = float3((tc * 2 - 1), 0);
72 | p.xy *= float2(view.x * view.w, -1);
73 |
74 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.4, 0.3, 18);
75 | float4 rot;
76 | sincos(param.x, rot.x, rot.y);
77 | sincos(param.y, rot.z, rot.w);
78 |
79 | float3 rt = float3(0, 0, 0);
80 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
81 | ro = ro * param.z;
82 |
83 | float3 cd = normalize(rt - ro);
84 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
85 | float3 cu = cross(cr, cd);
86 |
87 | float3 rd = normalize(p.x * cr + p.y * cu + 10 * cd);
88 | float4 radiance = shade(ro, rd);
89 |
90 | float3 col = float3(0.02, 0.02, 0.02);
91 | col = lerp(col, radiance.rgb, radiance.a);
92 | return float4(pow(col, 0.45), 1);
93 | }
--------------------------------------------------------------------------------
/bin/save/mandelbox.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float DE(float3 p)
10 | {
11 | const float scale = 9;
12 | const float3 boxfold = float3(1, 1, 1);
13 | const float spherefold = 0.2;
14 |
15 | float4 c0 = float4(p, 1);
16 | float4 c = c0;
17 | for (int i = 0; i < 4; ++i)
18 | {
19 | c.xyz = clamp(c.xyz, -boxfold, boxfold) * 2 - c.xyz;
20 | float rr = dot(c.xyz, c.xyz);
21 | c *= saturate(max(spherefold / rr, spherefold));
22 | c = c * scale + c0;
23 | }
24 | return ((length(c.xyz) - (scale - 1)) / c.w - pow(scale, -3));
25 | }
26 |
27 | float4 ray_marching(float3 ro, float3 rd)
28 | {
29 | for (int i = 0; i < 128; ++i)
30 | {
31 | float d = DE(ro);
32 | ro += d * rd;
33 | if (d < 0.001) return float4(ro, i);
34 | }
35 | return float4(ro, -1);
36 | }
37 |
38 | float4 shade(float3 ro, float3 rd)
39 | {
40 | float4 rm = ray_marching(ro, rd);
41 | if (rm.w < 0) return float4(0, 0, 0, 0);
42 |
43 | float3 p = rm.xyz;
44 | float k = DE(p);
45 | float gx = DE(p + float3(1e-5, 0, 0)) - k;
46 | float gy = DE(p + float3(0, 1e-5, 0)) - k;
47 | float gz = DE(p + float3(0, 0, 1e-5)) - k;
48 | float3 N = normalize(float3(gx, gy, gz));
49 | float3 L = normalize(float3(-1, 1, 2));
50 |
51 | float3 C = float3(0.5, 0.8, 0.9);
52 | float shadow = saturate(DE(p + L * 0.1) - k) / 0.1;
53 | float ao = 1 - rm.w / 128; ao = ao * ao;
54 | float A = 0.1;
55 | float3 col = (A + saturate(dot(L, N)) * shadow) * ao * C;
56 |
57 | return float4(col , 1);
58 | }
59 |
60 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
61 | {
62 | float3 p = float3((tc * 2 - 1), 0);
63 | p.xy *= float2(view.x * view.w, -1);
64 |
65 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.5) + float3(0.4, 0.3, 40);
66 | float4 rot;
67 | sincos(param.x, rot.x, rot.y);
68 | sincos(param.y, rot.z, rot.w);
69 |
70 | float3 rt = float3(0, 0, 0);
71 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
72 | ro = ro * param.z;
73 |
74 | float3 cd = normalize(rt - ro);
75 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
76 | float3 cu = cross(cr, cd);
77 |
78 | float3 rd = normalize(p.x * cr + p.y * cu + 3 * cd);
79 | float4 radiance = shade(ro, rd);
80 |
81 | float3 col = float3(0.02, 0.02, 0.02);
82 | col = lerp(col, radiance.rgb, radiance.a);
83 | return float4(pow(col, 0.45), 1);
84 | }
85 |
--------------------------------------------------------------------------------
/bin/save/mandelbrot4d.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float4 mul4d(float4 a, float4 b)
10 | {
11 | float4 c;
12 | c.x = a.x * b.x - dot(a.yzw, b.yzw);
13 | c.yzw = cross(a.yzw, b.yzw) + b.x * a.yzw + a.x * b.yzw;
14 | return c;
15 | }
16 |
17 | float DE(float3 p)
18 | {
19 | float4 c = 0;
20 | float4 d = 0;
21 | float r = 0;
22 | for (int i = 0; i < 16 && r < 3; ++i)
23 | {
24 | d = 2 * mul4d(c, d) + 1;
25 | p.z = -p.z; // to break the boring symmetry
26 | c = mul4d(c, c) + float4(p, 0);
27 | r = length(c);
28 | }
29 | float dr = length(d);
30 | return 0.5 * log(r) * r / dr;
31 | }
32 |
33 | float4 ray_marching(float3 ro, float3 rd)
34 | {
35 | for (int i = 0; i < 64; ++i)
36 | {
37 | float d = DE(ro);
38 | ro += d * rd;
39 | if (d < 0.002) return float4(ro, i);
40 | }
41 | return float4(ro, -1);
42 | }
43 |
44 | float4 shade(float3 ro, float3 rd)
45 | {
46 | float4 rm = ray_marching(ro, rd);
47 | if (rm.w < 0) return float4(0, 0, 0, 0);
48 | float ao = 1 - rm.w / 64;
49 | float3 C = lerp(float3(0.8, 0.0, 0.3), float3(0.8, 0.8, 0.9), abs(snoise(rm.xyz)));
50 | return float4(C * ao, 1);
51 | }
52 |
53 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
54 | {
55 | float3 p = float3((tc * 2 - 1), 0);
56 | p.xy *= float2(view.x * view.w, -1);
57 |
58 | float3 param = mpos.xyz * float3(-0.002, 0.005, -0.1) + float3(0.2, 1.0, 14);
59 | float4 rot;
60 | sincos(param.x, rot.x, rot.y);
61 | sincos(param.y, rot.z, rot.w);
62 |
63 | float3 rt = float3(0, 0, 0);
64 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
65 | ro = ro * param.z;
66 |
67 | float3 cd = normalize(rt - ro);
68 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
69 | float3 cu = cross(cr, cd);
70 |
71 | float3 rd = normalize(p.x * cr + p.y * cu + 10 * cd);
72 | float4 radiance = shade(ro, rd);
73 |
74 | float3 col = float3(0.02, 0.02, 0.02);
75 | col = lerp(col, radiance.rgb, radiance.a);
76 | return float4(pow(col, 0.45), 1);
77 | }
--------------------------------------------------------------------------------
/bin/save/mandelbulb.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float DE(float3 p)
10 | {
11 | float3 c = p;
12 | float r = length(c);
13 | float dr = 1;
14 | for (int i = 0; i < 4 && r < 3; ++i)
15 | {
16 | float xr = pow(r, 7);
17 | dr = 6 * xr * dr + 1;
18 |
19 | float theta = atan2(c.y, c.x) * 8;
20 | float phi = asin(c.z / r) * 8;
21 | r = xr * r;
22 | c = r * float3(cos(phi) * cos(theta), cos(phi) * sin(theta), sin(phi));
23 |
24 | c += p;
25 | r = length(c);
26 | }
27 | return 0.35 * log(r) * r / dr;
28 | }
29 |
30 | float4 ray_marching(float3 ro, float3 rd)
31 | {
32 | for (int i = 0; i < 64; ++i)
33 | {
34 | float d = DE(ro);
35 | ro += d * rd;
36 | if (d < 0.001) return float4(ro, i);
37 | }
38 | return float4(ro, -1);
39 | }
40 |
41 | float4 shade(float3 ro, float3 rd)
42 | {
43 | float4 rm = ray_marching(ro, rd);
44 | if (rm.w < 0) return float4(0, 0, 0, 0);
45 |
46 | float3 p = rm.xyz;
47 | float k = DE(p);
48 | float gx = DE(p + float3(1e-5, 0, 0)) - k;
49 | float gy = DE(p + float3(0, 1e-5, 0)) - k;
50 | float gz = DE(p + float3(0, 0, 1e-5)) - k;
51 | float3 N = normalize(float3(gx, gy, gz));
52 |
53 | float ao = 0;
54 | ao += DE(p + 0.1 * N) * 2.5;
55 | ao += DE(p + 0.2 * N) * 1.0;
56 |
57 | float3 L = normalize(float3(-1, 1, 2));
58 | float4 S = ray_marching(p + N * 0.01, L);
59 | float3 C = lerp(float3(0.6, 0.8, 0.6), float3(1.0, 0.0, 0.0), rm.w / 64);
60 | float D = 0.7 * (S.w < 0 ? 1 : 0);
61 |
62 | float A = 0.1;
63 | float3 col = (A + D * saturate(dot(L, N))) * ao * C;
64 | return float4(col , 1);
65 | }
66 |
67 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
68 | {
69 | float3 p = float3((tc * 2 - 1), 0);
70 | p.xy *= float2(view.x * view.w, -1);
71 |
72 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.4, 0.3, 4.5);
73 | float4 rot;
74 | sincos(param.x, rot.x, rot.y);
75 | sincos(param.y, rot.z, rot.w);
76 |
77 | float3 rt = float3(0, 0, 0);
78 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
79 | ro = ro * param.z;
80 |
81 | float3 cd = normalize(rt - ro);
82 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
83 | float3 cu = cross(cr, cd);
84 |
85 | float3 rd = normalize(p.x * cr + p.y * cu + 3 * cd);
86 | float4 radiance = shade(ro, rd);
87 |
88 | float3 col = float3(0.02, 0.02, 0.02);
89 | col = lerp(col, radiance.rgb, radiance.a);
90 | return float4(pow(col, 0.45), 1);
91 | }
--------------------------------------------------------------------------------
/bin/save/menger.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float box(float3 p)
10 | {
11 | p = abs(p) - 1;
12 | return min(max(p.x,max(p.y,p.z)), 0) + length(max(p, 0));
13 | }
14 |
15 | float DE(float3 p)
16 | {
17 | float d = box(p);
18 | float scale = 1.0;
19 | for(int i = 0; i < 4; ++i)
20 | {
21 | float3 a = fmod(p + 1, 2 * scale) - scale;
22 | scale /= 3;
23 | float3 r = abs(a / scale);
24 | float da = max(r.x, r.y);
25 | float db = max(r.y, r.z);
26 | float dc = max(r.z, r.x);
27 | float c = min(da, min(db, dc)) - 1;
28 | d = max(d, -c * scale);
29 | }
30 | return d;
31 | }
32 |
33 | float4 ray_marching(float3 ro, float3 rd)
34 | {
35 | for (int i = 0; i < 64; ++i)
36 | {
37 | float d = DE(ro);
38 | ro += d * rd;
39 | if (d < 0.001) return float4(ro, i);
40 | }
41 | return float4(ro, -1);
42 | }
43 |
44 | float4 shade(float3 ro, float3 rd)
45 | {
46 | float4 rm = ray_marching(ro, rd);
47 | if (rm.w < 0) return float4(0, 0, 0, 0);
48 |
49 | float3 p = rm.xyz;
50 | float k = DE(p);
51 | float gx = DE(p + float3(1e-5, 0, 0)) - k;
52 | float gy = DE(p + float3(0, 1e-5, 0)) - k;
53 | float gz = DE(p + float3(0, 0, 1e-5)) - k;
54 | float3 N = normalize(float3(gx, gy, gz));
55 |
56 | float ao = 0;
57 | ao += DE(p + 0.2 * N) * 2.5;
58 | ao += DE(p + 0.5 * N) * 1.0;
59 |
60 | float3 L = normalize(float3(-2, 1, 1));
61 | float4 S = ray_marching(p + N * 0.001, L);
62 | float3 C = float3(0.3, 0.2, 0.3) + 0.2 * snoise(p * 100);
63 | float D = 0.7 * (S.w < 0 ? 1 : 0);
64 | float A = 0.1;
65 | float3 col = (A + D * saturate(dot(L, N))) * ao * C;
66 | return float4(col , 1);
67 | }
68 |
69 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
70 | {
71 | float3 p = float3((tc * 2 - 1), 0);
72 | p.xy *= float2(view.x * view.w, -1);
73 |
74 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.4, 0.3, 18);
75 | float4 rot;
76 | sincos(param.x, rot.x, rot.y);
77 | sincos(param.y, rot.z, rot.w);
78 |
79 | float3 rt = float3(0, 0, 0);
80 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
81 | ro = ro * param.z;
82 |
83 | float3 cd = normalize(rt - ro);
84 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
85 | float3 cu = cross(cr, cd);
86 |
87 | float3 rd = normalize(p.x * cr + p.y * cu + 10 * cd);
88 | float4 radiance = shade(ro, rd);
89 |
90 | float3 col = float3(0.02, 0.02, 0.02);
91 | col = lerp(col, radiance.rgb, radiance.a);
92 | return float4(pow(col, 0.45), 1);
93 | }
--------------------------------------------------------------------------------
/bin/save/penrose.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float box(float3 p, float3 s)
10 | {
11 | p = abs(p) - s;
12 | return min(max(p.x,max(p.y,p.z)), 0) + length(max(p, 0));
13 | }
14 |
15 | float3 rotateY(float3 p, float sint, float cost)
16 | {
17 | float3 np;
18 | np.y = p.y;
19 | np.x = dot(p.xz, float2(cost, sint));
20 | np.z = dot(p.xz, float2(-sint, cost));
21 | return np;
22 | }
23 |
24 | float partA(float3 p)
25 | {
26 | float k = saturate(sin(time.x * 2) * 0.5 - 0.2);
27 | p = rotateY(p, sin(k), cos(k));
28 |
29 | float a = box(p, float3(1, 6, 1));
30 | p = rotateY(p, 0, 1);
31 | p.xy -= float2(2, 5);
32 | a = min(a, box(p, float3(3, 1, 1)));
33 | return a;
34 | }
35 |
36 | float partB(float3 p)
37 | {
38 | float k = saturate(sin(time.x * 2) * 0.5 - 0.2);
39 | p = rotateY(p, sin(k), cos(k));
40 |
41 | float3 op = p;
42 | p = rotateY(p, -1, 0);
43 | p.xy -= float2(2, -5);
44 | return box(p, float3(3, 1, 1));
45 | }
46 |
47 | float partC(float3 p)
48 | {
49 | p.xy -= float2(8, 5);
50 | p = rotateY(p, 0, 1);
51 | float c = box(p, float3(3, 1, 1));
52 | p = rotateY(p, -1, 0);
53 | p.xz -= float2(-2, 2);
54 | c = min(c, box(p, float3(3, 1, 1)));
55 | return c;
56 | }
57 |
58 | float DE(float3 p)
59 | {
60 | float a = partA(p);
61 | float b = partB(p);
62 | float c = partC(p);
63 | return min(min(a, b), c);
64 | }
65 |
66 | float4 ray_marching(float3 ro, float3 rd)
67 | {
68 | float4 A = float4(ro, 0);
69 | int i = 0;
70 | for (i = 0; i < 64; ++i)
71 | {
72 | float d = partA(A.xyz);
73 | A += float4(d * rd, d);
74 | if (d < 0.0003) break;
75 | }
76 | if (i > 63) A.w = 1000;
77 |
78 | float4 B = float4(ro, 0);
79 | for (i = 0; i < 64; ++i)
80 | {
81 | float d = partB(B.xyz);
82 | B += float4(d * rd, d);
83 | if (d < 0.0003) break;
84 | }
85 | if (i > 63) B.w = 1000;
86 |
87 | float4 C = float4(ro, 0);
88 | for (i = 0; i < 64; ++i)
89 | {
90 | float d = partC(C.xyz);
91 | C += float4(d * rd, d);
92 | if (d < 0.0003) break;
93 | }
94 | if (i > 63) C.w = 1000;
95 |
96 | float4 AB = A.w < B.w ? A : B;
97 | if (B.w < 100) return AB;
98 | return AB.w < C.w ? AB : C;
99 | }
100 |
101 | float4 shade(float3 ro, float3 rd)
102 | {
103 | float4 rm = ray_marching(ro, rd);
104 | if (rm.w > 100) return float4(0, 0, 0, 0);
105 |
106 | float3 p = rm.xyz - rd * 0.001;
107 | float k = DE(p);
108 | float gx = DE(p + float3(1e-5, 0, 0)) - k;
109 | float gy = DE(p + float3(0, 1e-5, 0)) - k;
110 | float gz = DE(p + float3(0, 0, 1e-5)) - k;
111 | float3 N = normalize(float3(gx, gy, gz));
112 |
113 | float3 col = float3(0.85, 0.53, 0.64);
114 | if (abs(N.x) > 0.5) col = float3(0.47, 0.52, 0.68);
115 | if (abs(N.y) > 0.3) col = float3(0.9, 0.9, 0.8);
116 | return float4(col, 1);
117 | }
118 |
119 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
120 | {
121 | float3 p = float3((tc * 2 - 1), 0);
122 | p.xy *= float2(view.x * view.w, -1);
123 |
124 | const float sinphi = sqrt(3.0) / 3.0;
125 | const float cosphi = sqrt(2.0 / 3.0);
126 |
127 | // ortho view
128 | p.x *= cosphi;
129 | float3 ro = p * 20 + float3(2, 14, 20);
130 | float3 rd = float3(0, -sinphi, -cosphi);
131 |
132 | // 45 degree
133 | const float sc45 = sqrt(2.0) / 2.0;
134 | ro = rotateY(ro, sc45, sc45);
135 | rd = rotateY(rd, sc45, sc45);
136 |
137 | // shading
138 | float4 radiance = shade(ro, rd);
139 |
140 | float3 A = float3(0.8, 0.7, 0.6);
141 | if (frac((sin(tc.x * 122.39) + tc.y) * 239.383) < 0.001) A = 1.0;
142 | float3 B = float3(0.2, 0.8, 0.7);
143 | float3 col = lerp(A, B, 0.4 * tc.x + 0.7 * tc.y);
144 | col = lerp(col, radiance.rgb, radiance.a);
145 | return float4(col, 1);
146 | }
--------------------------------------------------------------------------------
/bin/save/piano.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 fft;
6 | }
7 |
8 | float white_keys(float3 p)
9 | {
10 | float ox = p.x;
11 | p.x = fmod(abs(ox + 0.03), 0.06) - 0.03;
12 | float d1 = length(max(abs(p) - float3(0.023, 0.002, 0.2), 0)) - 0.005;
13 | p.y += 0.04;
14 | float d2 = length(max(abs(p) - float3(0.023, 0.04, 0.18), 0)) - 0.002;
15 |
16 | int r = fmod(floor(ox / 0.06) + 70, 7);
17 | if (r == 0 || r == 4) return min(d1, d2);
18 |
19 | p.x = fmod(abs(ox), 0.06) - 0.03;
20 | p.z -= 0.1;
21 | float3 t = abs(p) - float3(0.02, 0.1, 0.15);
22 | float d3 = min(max(t.x, max(t.y, t.z)), 0) + length(max(t, 0));
23 | return max(min(d1, d2), -d3);
24 | }
25 |
26 | float black_keys(float3 p)
27 | {
28 | int r = fmod(floor(p.x / 0.06) + 70, 7);
29 | if (r == 0 || r == 4) return 1000;
30 | p.x = fmod(abs(p.x), 0.06) - 0.03;
31 | p.x *= (1 + 10 * p.y);
32 | p.y += 0.5 * p.z * p.z;
33 | p.z -= 0.08;
34 | p.y -= 0.014;
35 | return length(max(abs(p) - float3(0.01, 0.03, 0.122), 0)) - 0.003;
36 | }
37 |
38 | float boards(float3 p)
39 | {
40 | p.z += 0.3;
41 | p.y += 0.065;
42 | float d1 = length(max(abs(p) - float3(2, 0.05, 0.02), 0)) - 0.01;
43 | p.z -= 0.53;
44 | float d2 = length(max(abs(p) - float3(2, 0.13, 0.007), 0)) - 0.01;
45 | return min(d1, d2);
46 | }
47 |
48 | float2 piano(float3 p)
49 | {
50 | float d1 = white_keys(p);
51 | float d2 = black_keys(p);
52 | float d3 = boards(p);
53 | float2 t = d1 < d2 ? float2(d1, 1) : float2(d2, 2);
54 | return t.x < d3 ? t : float2(d3, 3);
55 | }
56 |
57 | float4 ray_marching(float3 ro, float3 rd)
58 | {
59 | for (int i = 0; i < 32; ++i)
60 | {
61 | float2 dm = piano(ro);
62 | if (dm.x < 0.001) return float4(ro, dm.y);
63 | ro += rd * dm.x;
64 | }
65 | return float4(ro, -1);
66 | }
67 |
68 | float3 brdf(float3 diff, float m, float3 N, float3 L, float3 V)
69 | {
70 | float3 H = normalize(V + L);
71 | float3 F = 0.05 + 0.95 * pow(1 - dot(V, H), 5);
72 | float3 R = F * pow(max(dot(N, H), 0), m);
73 | return diff + R * (m + 8) / 8;
74 | }
75 |
76 | float3 lit_white_keys(float3 p, float3 N)
77 | {
78 | float3 V = normalize(float3(0, 3, -5));
79 | float3 L = normalize(float3(3, 3, -1));
80 | float3 C = 2 * brdf(0.9, 50, N, L, V) * max(dot(N, L), 0.1);
81 | float ao = 0;
82 | ao += 0.5 * (0.02 - piano(p + 0.02 * N).x);
83 | ao += 0.25 * (0.04 - piano(p + 0.04 * N).x);
84 | ao += 0.125 * (0.06 - piano(p + 0.06 * N).x);
85 | ao = max(1 - 50 * ao, 0.2);
86 | float shadow = 0;
87 | shadow += black_keys(p + 0.02 * L).x;
88 | shadow += black_keys(p + 0.04 * L).x;
89 | shadow += black_keys(p + 0.06 * L).x;
90 | shadow = min(60 * shadow, 1.0);
91 | return C * ao * shadow;
92 | }
93 |
94 | float3 lit_black_keys(float3 p, float3 N)
95 | {
96 | float3 V = normalize(float3(0, 3, -5));
97 | float3 L = normalize(float3(0, 3, 2));
98 | return 2 * brdf(0, 50, N, L, V);
99 | }
100 |
101 | float3 lit_boards(float3 p, float3 N)
102 | {
103 | float3 V = normalize(float3(0, 3, -5));
104 | float3 L = normalize(float3(0, 3, 2));
105 | return max(brdf(0, 50, N, L, V), 0.005);
106 | }
107 |
108 | float4 do_lighting(float3 ro, float3 rd)
109 | {
110 | float4 rm = ray_marching(ro, rd);
111 | if (rm.w < 0) return float4(0, 0, 0, 0);
112 |
113 | float gx = (piano(rm.xyz + float3(0.0001, 0, 0)) - piano(rm.xyz - float3(0.0001, 0, 0))).x;
114 | float gy = (piano(rm.xyz + float3(0, 0.0001, 0)) - piano(rm.xyz - float3(0, 0.0001, 0))).x;
115 | float gz = (piano(rm.xyz + float3(0, 0, 0.0001)) - piano(rm.xyz - float3(0, 0, 0.0001))).x;
116 | float3 N = normalize(float3(gx, gy, gz));
117 |
118 | if (rm.w < 1.5) return float4(lit_white_keys(rm.xyz, N), 1);
119 | else if (rm.w < 2.5) return float4(lit_black_keys(rm.xyz, N), 1);
120 | else return float4(lit_boards(rm.xyz, N), 1);
121 | }
122 |
123 | #define FSAA 0
124 |
125 | float4 ps_main(in float2 in_tex : TEXCOORD) : SV_TARGET
126 | {
127 | float2 p = (in_tex - 0.5) * 2 * float2(1, -view.y / view.x);
128 | if (abs(p.y) > 200.0 / 1024.0) return 0;
129 |
130 | float3 ro = float3(0, 3, -5);
131 | float3 rt = float3(0, 0, 0);
132 | float3 cd = normalize(rt - ro);
133 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
134 | float3 cu = cross(cr, cd);
135 |
136 | float3 rd = normalize(p.x * cr + p.y * cu + 5 * cd);
137 | float4 radiance = do_lighting(ro, rd);
138 |
139 | float3 col = 0.06 - 0.06 * length(p - float2(0.2, 0.3));
140 | col = lerp(col, radiance.rgb, radiance.a);
141 | return float4(pow(col, 0.45), 1);
142 | }
143 |
--------------------------------------------------------------------------------
/bin/save/sierpinski.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float DE(float3 p)
10 | {
11 | for (int i = 0; i < 16; ++i)
12 | {
13 | if (p.x + p.y < 0) p.xy = -p.yx;
14 | if (p.x + p.z < 0) p.xz = -p.zx;
15 | if (p.z + p.y < 0) p.zy = -p.yz;
16 | p = 2 * p - 1;
17 | }
18 | return length(p - 1) * pow(2, -16);
19 | }
20 |
21 | float4 ray_marching(float3 ro, float3 rd)
22 | {
23 | for (int i = 0; i < 64; ++i)
24 | {
25 | float d = DE(ro);
26 | ro += d * rd;
27 | if (d < 0.003) return float4(ro, i);
28 | }
29 | return float4(ro, -1);
30 | }
31 |
32 | float4 shade(float3 ro, float3 rd)
33 | {
34 | float4 rm = ray_marching(ro, rd);
35 | if (rm.w < 0) return float4(0, 0, 0, 0);
36 |
37 | float aol = 1 - rm.w / 64.0;
38 | float3 diff = float3(0.1, 0.2, 0.2);
39 | diff += float3(0.08, 0.04, 0.02) * snoise(rm.xyz * 10);
40 | return float4(diff * (aol * aol), 1);
41 | }
42 |
43 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
44 | {
45 | float3 p = float3((tc * 2 - 1), 0);
46 | p.xy *= float2(view.x * view.w, -1);
47 |
48 | float3 gx = normalize(float3( 1, -1, 0));
49 | float3 gy = normalize(float3( 1, 1, 1));
50 | float3 gz = normalize(float3(-1, -1, 2));
51 |
52 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.2, 0, 8);
53 | float4 rot;
54 | sincos(param.x, rot.x, rot.y);
55 | sincos(param.y, rot.z, rot.w);
56 |
57 | float3 rt = float3(0.25, 0.25, 0.25);
58 | float3 ro = rot.x * rot.w * gx + abs(rot.y) * rot.z * gy + rot.y * gz;
59 | ro = ro * param.z;
60 |
61 | float3 cd = normalize(rt - ro);
62 | float3 cr = normalize(cross(cd, gy));
63 | float3 cu = cross(cr, cd);
64 |
65 | float3 rd = normalize(p.x * cr + p.y * cu + 5 * cd);
66 | float4 radiance = shade(ro, rd);
67 |
68 | float3 col = float3(0.02, 0.02, 0.02);
69 | col = lerp(col, radiance.rgb, radiance.a);
70 | return float4(pow(col, 0.45), 1);
71 | }
--------------------------------------------------------------------------------
/bin/save/sphere.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | float sphere(float3 p, float r)
10 | {
11 | return length(p - r) - r;
12 | }
13 |
14 | float corner(float3 p)
15 | {
16 | return min(p.x, min(p.y, p.z));
17 | }
18 |
19 | float2 DE(float3 p)
20 | {
21 | float d1 = sphere(p, 1);
22 | float d2 = corner(p);
23 | return d1 < d2 ? float2(d1, 1) : float2(d2, 2);
24 | }
25 |
26 | float4 ray_marching(float3 ro, float3 rd)
27 | {
28 | for (int i = 0; i < 128; ++i)
29 | {
30 | float2 d = DE(ro);
31 | ro += d.x * rd;
32 | if (d.x < 0.001) return float4(ro, d.y);
33 | }
34 | return float4(ro, -1);
35 | }
36 |
37 | float3 brdf(float3 diff, float m, float3 N, float3 L, float3 V)
38 | {
39 | float3 H = normalize(V + L);
40 | float3 F = 0.05 + 0.95 * pow(1 - dot(V, H), 5);
41 | float3 R = F * pow(max(dot(N, H), 0), m);
42 | return diff + R * (m + 8) / 8;
43 | }
44 |
45 | float fbm(float3 p)
46 | {
47 | float f;
48 | f = 0.5000 * qnoise(p); p = p * 2.02;
49 | f += 0.2500 * qnoise(p); p = p * 2.03;
50 | f += 0.1250 * qnoise(p); p = p * 2.01;
51 | f += 0.0625 * qnoise(p);
52 | return f;
53 | }
54 |
55 | float4 shade(inout float3 ro, inout float3 rd)
56 | {
57 | float4 rm = ray_marching(ro, rd);
58 | if (rm.w < 0) return 0;
59 |
60 | float3 diff, N;
61 | float m, r;
62 | if (rm.w < 1.5)
63 | {
64 | float s = abs(sin(5.6 * fbm(rm.xyz * 3.4)));
65 | diff = lerp(float3(0.55, 0.3, 0.25), float3(1, 1, 1), s);
66 | N = rm.xyz - 1;
67 | m = 50;
68 | r = saturate(1 - abs(dot(-rd, N)) + 0.2);
69 | }
70 | else
71 | {
72 | float s = saturate(length(step(0.01, fmod(rm.xyz, 0.3))) - 1);
73 | diff = s * float3(0.4, 0.4, 0.4) + float3(0.2, 0.2, 0.2) + 0.1 * qnoise(rm.xyz * 78);
74 | diff = diff / (1 + dot(rm.xyz, rm.xyz));
75 | N = normalize(1 - step(0.001, rm.xyz));
76 | m = 10;
77 | r = 0;
78 | }
79 |
80 | float ao = 0.2;
81 | ao += saturate(DE(rm.xyz + 0.1 * N).x) * 4;
82 | ao += saturate(DE(rm.xyz + 0.2 * N).x) * 2;
83 | ao += saturate(DE(rm.xyz + 0.4 * N).x) * 1;
84 |
85 | float3 L = normalize(float3(0.6, 1, 1));
86 | float shadow = exp((DE(rm.xyz + 0.6 * L).x - 0.6) * 3);
87 |
88 | float3 f = brdf(diff, m, N, L, -rd);
89 | float3 C = saturate(dot(N, L) + 0.3) * f * ao * shadow;
90 | rd = reflect(rd, N);
91 | ro = rm.xyz + rd * 0.01;
92 | return float4(C, r);
93 | }
94 |
95 | float4 ps_main(in float2 tc : TEXCOORD) : SV_TARGET
96 | {
97 | float3 p = float3((tc * 2 - 1), 0);
98 | p.xy *= float2(view.x * view.w, -1);
99 |
100 | float3 param = mpos.xyz * float3(-0.005, 0.005, -0.1) + float3(0.8, 0.7, 12);
101 | float4 rot;
102 | sincos(param.x, rot.x, rot.y);
103 | sincos(param.y, rot.z, rot.w);
104 |
105 | float3 rt = float3(1, 1.2, 1);
106 | float3 ro = float3(rot.x * rot.w, abs(rot.y) * rot.z, rot.y);
107 | ro = ro * param.z;
108 |
109 | float3 cd = normalize(rt - ro);
110 | float3 cr = normalize(cross(cd, float3(0, 1, 0)));
111 | float3 cu = cross(cr, cd);
112 |
113 | float3 rd = normalize(p.x * cr + p.y * cu + 5 * cd);
114 | float4 col = shade(ro, rd);
115 | if (col.a > 0)
116 | {
117 | float4 col2 = shade(ro, rd);
118 | col = lerp(col, col2, col.a);
119 | }
120 | return float4(pow(col.rgb, 0.45), 1);
121 | }
122 |
--------------------------------------------------------------------------------
/bin/save/tunnel.hlsl:
--------------------------------------------------------------------------------
1 | cbuffer Parameters
2 | {
3 | float4 time;
4 | float4 view;
5 | float4 freq;
6 | float4 mpos;
7 | }
8 |
9 | Texture2D tex;
10 | SamplerState samp;
11 |
12 | float4 ps_main(in float2 in_tex : TEXCOORD) : SV_TARGET
13 | {
14 | float2 p = (in_tex - 0.5) * 2 + mpos.xy * view.zw;
15 | float a = atan2(p.y, p.x);
16 | float r = length(p);
17 | float2 tc = float2(a / 6.28, 0.3 * time.x + 0.1 / r);
18 | float3 s = tex.Sample(samp, tc);
19 | s *= 1 + step(0.4, freq.x);
20 | s *= r * r;
21 | return float4(s, 1);
22 | }
23 |
--------------------------------------------------------------------------------
/live_coding.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "live_coding", "live_coding.vcxproj", "{B42C522B-FC98-4041-B882-1916C8D7759A}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {B42C522B-FC98-4041-B882-1916C8D7759A}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {B42C522B-FC98-4041-B882-1916C8D7759A}.Debug|Win32.Build.0 = Debug|Win32
14 | {B42C522B-FC98-4041-B882-1916C8D7759A}.Release|Win32.ActiveCfg = Release|Win32
15 | {B42C522B-FC98-4041-B882-1916C8D7759A}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/live_coding.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | false
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | {B42C522B-FC98-4041-B882-1916C8D7759A}
47 | live_coding
48 |
49 |
50 |
51 | Application
52 | true
53 | MultiByte
54 |
55 |
56 | Application
57 | false
58 | true
59 | MultiByte
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | $(SolutionDir);$(ExecutablePath)
73 |
74 |
75 | E:\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)
76 |
77 |
78 | E:\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)
79 |
80 |
81 | $(ExcludePath)
82 | $(SolutionDir)\bin\
83 | $(ProjectName)_debug
84 |
85 |
86 | $(SolutionDir);$(ExecutablePath)
87 |
88 |
89 | E:\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)
90 |
91 |
92 | E:\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)
93 |
94 |
95 | $(ExcludePath)
96 | $(SolutionDir)\bin\
97 |
98 |
99 |
100 | Level3
101 | Disabled
102 | E:\FMOD SoundSystem\FMOD Programmers API Windows\api\inc
103 |
104 |
105 | true
106 | E:\FMOD SoundSystem\FMOD Programmers API Windows\api\lib
107 | fmodex_vc.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
108 |
109 |
110 |
111 |
112 | Level3
113 | MaxSpeed
114 | true
115 | true
116 | E:\FMOD SoundSystem\FMOD Programmers API Windows\api\inc
117 |
118 |
119 | true
120 | true
121 | true
122 | E:\FMOD SoundSystem\FMOD Programmers API Windows\api\lib
123 | fmodex_vc.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atyuwen/hlsl_live_coding/c402d73ff80d81e84f1241109d8b93e729853061/snap.png
--------------------------------------------------------------------------------
/src/ayw/common_helper.h:
--------------------------------------------------------------------------------
1 | // file: common_helper.h
2 | // path: AywProc\AywProc\core\include
3 | // purpose: define some common macros
4 | //
5 | // author: atyuwen
6 | // homepage: http://code.google.com/p/aywproc/
7 | //
8 | // created: 2010/05/26
9 | // history:
10 | //
11 | //////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef _COMMON_HELPER_H_
14 | #define _COMMON_HELPER_H_
15 |
16 | #define DECLARE_CONVERSION_TO_POINTER(Type, addr) \
17 | Type * ptr() \
18 | { \
19 | return (Type *)(addr); \
20 | } \
21 | const Type * ptr() const \
22 | { \
23 | return (const Type *)(addr); \
24 | }
25 |
26 | #define DECLARE_SUBSCRIPT_OPERATOR(Type, addr) \
27 | Type & operator [] (size_t i) \
28 | { \
29 | return (addr)[i]; \
30 | } \
31 | const Type & operator [] (size_t i) const \
32 | { \
33 | return (addr)[i]; \
34 | }
35 |
36 | #define DECLARE_NATIVE_ITERATOR(Type, addr, n) \
37 | typedef Type value_type; \
38 | typedef value_type* iterator; \
39 | typedef const value_type* const_iterator; \
40 | iterator begin() {return iterator(addr);} \
41 | iterator end() {return iterator(addr) + (n);} \
42 | const_iterator begin() const {return const_iterator(addr);} \
43 | const_iterator end() const {return const_iterator(addr) + (n);}
44 |
45 | #endif // _COMMON_HELPER_H_
--------------------------------------------------------------------------------
/src/ayw/constant.hpp:
--------------------------------------------------------------------------------
1 | // file: constant.hpp
2 | // path: AywProc\AywProc\core\include
3 | // purpose: define some mathematical constants
4 | //
5 | // author: atyuwen
6 | // homepage: http://code.google.com/p/aywproc/
7 | //
8 | // created: 2010/04/21
9 | // history:
10 | //
11 | //////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef _CONSTANT_HPP_
14 | #define _CONSTANT_HPP_
15 |
16 | namespace Ayw
17 | {
18 | static const float c_pi = 3.14159265f; // [ pi ]
19 | static const float c_pi_r = 0.318309886f; // [ 1 / pi ]
20 | static const float c_e = 2.71828183f; // [ e ]
21 | static const float c_ln2 = 0.693147181f; // [ ln(2) ]
22 | static const float c_ln2_r = 1.44269504f; // [ 1/ln(2) = log2(e) ]
23 | static const float c_ln10 = 2.30258509f; // [ ln(10)]
24 | static const float c_ln10_r = 0.434294482f; // [ 1/ln(10) = log10(e) ]
25 | static const float c_sqrt2 = 1.41421356f; // [ sqrt(2)]
26 | static const float c_sqrt2_r = 0.707106781f; // [ 1 / sqrt(2) ]
27 |
28 | static const float c_eps = 1.0e-9f;
29 | }
30 |
31 | #endif // _CONSTANT_HPP_
--------------------------------------------------------------------------------
/src/ayw/vector.hpp:
--------------------------------------------------------------------------------
1 | // file: vector.hpp
2 | // path: AywProc\AywProc\core\include
3 | // purpose: vector template class
4 | //
5 | // author: atyuwen
6 | // homepage: http://code.google.com/p/aywproc/
7 | //
8 | // created: 2010/04/20
9 | // history:
10 | //
11 | //////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef _VECTOR_HPP_
14 | #define _VECTOR_HPP_
15 |
16 | #include
17 | #include
18 | #include
19 |
20 | #include "common_helper.h"
21 | #include "vector_helper.hpp"
22 |
23 | namespace Ayw
24 | {
25 | template struct vector_2t;
26 | template struct vector_3t;
27 | template struct vector_4t;
28 |
29 | typedef vector_2t float2;
30 | typedef vector_3t float3;
31 | typedef vector_4t float4;
32 |
33 | template
34 | struct vector_2t
35 | {
36 | public:
37 | vector_2t(Type nx = Type(), Type ny = Type())
38 | : x(nx)
39 | , y(ny)
40 | {
41 | }
42 |
43 | public:
44 | DECLARE_CONVERSION_TO_POINTER(Type, &x)
45 | DECLARE_SUBSCRIPT_OPERATOR(Type, &x)
46 | DECLARE_NATIVE_ITERATOR(Type, &x, 2)
47 | DECLARE_SWIZZLING_FOR_VECTOR_2T();
48 |
49 | public:
50 | Type length_sqr() const
51 | {
52 | return x * x + y * y;
53 | }
54 |
55 | Type length() const
56 | {
57 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
58 | return std::sqrt(length_sqr());
59 | }
60 |
61 | vector_2t& normalize()
62 | {
63 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
64 | return (*this) /= length();
65 | }
66 |
67 | public:
68 | vector_2t& operator += (const vector_2t &rhs)
69 | {
70 | x += rhs.x;
71 | y += rhs.y;
72 | return *this;
73 | }
74 |
75 | vector_2t& operator -= (const vector_2t &rhs)
76 | {
77 | x -= rhs.x;
78 | y -= rhs.y;
79 | return *this;
80 | }
81 |
82 | vector_2t& operator *= (Type scale)
83 | {
84 | x *= scale;
85 | y *= scale;
86 | return *this;
87 | }
88 |
89 | vector_2t& operator /= (Type scale)
90 | {
91 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
92 | Type scale_r = 1 / scale;
93 | return (*this) *= scale_r;
94 | }
95 |
96 | vector_2t& operator *= (const vector_2t &rhs)
97 | {
98 | x *= rhs.x;
99 | y *= rhs.y;
100 | return *this;
101 | }
102 |
103 | vector_2t& operator /= (const vector_2t &rhs)
104 | {
105 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
106 | x /= rhs.x;
107 | y /= rhs.y;
108 | return *this;
109 | }
110 |
111 | public:
112 | Type x;
113 | Type y;
114 | };
115 |
116 | template
117 | struct vector_3t
118 | {
119 | public:
120 | vector_3t(Type nx = Type(), Type ny = Type(),Type nz = Type())
121 | : x(nx)
122 | , y(ny)
123 | , z(nz)
124 | {
125 | }
126 |
127 | public:
128 | DECLARE_CONVERSION_TO_POINTER(Type, &x)
129 | DECLARE_SUBSCRIPT_OPERATOR(Type, &x)
130 | DECLARE_NATIVE_ITERATOR(Type, &x, 3)
131 | DECLARE_SWIZZLING_FOR_VECTOR_3T();
132 |
133 | public:
134 | Type length_sqr() const
135 | {
136 | return x * x + y * y + z * z;
137 | }
138 |
139 | Type length() const
140 | {
141 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
142 | return std::sqrt(length_sqr());
143 | }
144 |
145 | vector_3t& normalize()
146 | {
147 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
148 | return (*this) /= length();
149 | }
150 |
151 | public:
152 | vector_3t& operator += (const vector_3t &rhs)
153 | {
154 | x += rhs.x;
155 | y += rhs.y;
156 | z += rhs.z;
157 | return *this;
158 | }
159 |
160 | vector_3t& operator -= (const vector_3t &rhs)
161 | {
162 | x -= rhs.x;
163 | y -= rhs.y;
164 | z -= rhs.z;
165 | return *this;
166 | }
167 |
168 | vector_3t& operator *= (Type scale)
169 | {
170 | x *= scale;
171 | y *= scale;
172 | z *= scale;
173 | return *this;
174 | }
175 |
176 | vector_3t& operator /= (Type scale)
177 | {
178 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
179 | Type scale_r = 1 / scale;
180 | return (*this) *= scale_r;
181 | }
182 |
183 | vector_3t& operator *= (const vector_3t &rhs)
184 | {
185 | x *= rhs.x;
186 | y *= rhs.y;
187 | z *= rhs.z;
188 | return *this;
189 | }
190 |
191 | vector_3t& operator /= (const vector_3t &rhs)
192 | {
193 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
194 | x /= rhs.x;
195 | y /= rhs.y;
196 | z /= rhs.z;
197 | return *this;
198 | }
199 |
200 | public:
201 | Type x;
202 | Type y;
203 | Type z;
204 | };
205 |
206 | template
207 | struct vector_4t
208 | {
209 | public:
210 | vector_4t(Type nx = Type(), Type ny = Type(), Type nz = Type(), Type nw = Type())
211 | : x(nx)
212 | , y(ny)
213 | , z(nz)
214 | , w(nw)
215 | {
216 | }
217 |
218 | public:
219 | DECLARE_CONVERSION_TO_POINTER(Type, &x)
220 | DECLARE_SUBSCRIPT_OPERATOR(Type, &x)
221 | DECLARE_NATIVE_ITERATOR(Type, &x, 4)
222 | DECLARE_SWIZZLING_FOR_VECTOR_4T();
223 |
224 | public:
225 | Type length_sqr() const
226 | {
227 | return x * x + y * y + z * z + w * w;
228 | }
229 |
230 | Type length() const
231 | {
232 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
233 | return std::sqrt(length_sqr());
234 | }
235 |
236 | vector_4t& normalize()
237 | {
238 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
239 | return (*this) /= length();
240 | }
241 |
242 | public:
243 | vector_4t& operator += (const vector_4t &rhs)
244 | {
245 | x += rhs.x;
246 | y += rhs.y;
247 | z += rhs.z;
248 | w += rhs.w;
249 | return *this;
250 | }
251 |
252 | vector_4t& operator -= (const vector_4t &rhs)
253 | {
254 | x -= rhs.x;
255 | y -= rhs.y;
256 | z -= rhs.z;
257 | z -= rhs.w;
258 | return *this;
259 | }
260 |
261 | vector_4t& operator *= (Type scale)
262 | {
263 | x *= scale;
264 | y *= scale;
265 | z *= scale;
266 | w *= scale;
267 | return *this;
268 | }
269 |
270 | vector_4t& operator /= (Type scale)
271 | {
272 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
273 | Type scale_r = 1 / scale;
274 | return (*this) *= scale_r;
275 | }
276 |
277 | vector_4t& operator *= (const vector_4t &rhs)
278 | {
279 | x *= rhs.x;
280 | y *= rhs.y;
281 | z *= rhs.z;
282 | w *= rhs.w;
283 | return *this;
284 | }
285 |
286 | vector_4t& operator /= (const vector_4t &rhs)
287 | {
288 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
289 | x /= rhs.x;
290 | y /= rhs.y;
291 | z /= rhs.z;
292 | w /= rhs.w;
293 | return *this;
294 | }
295 |
296 | public:
297 | Type x;
298 | Type y;
299 | Type z;
300 | Type w;
301 | };
302 |
303 | //////////////////////////////////////////////////////////////////////////
304 | // negation
305 | template
306 | vector_2t operator - (const vector_2t &operand)
307 | {
308 | return vector_2t(-operand.x, -operand.y);
309 | }
310 |
311 | template
312 | vector_3t operator - (const vector_3t &operand)
313 | {
314 | return vector_3t(-operand.x, -operand.y, -operand.z);
315 | }
316 |
317 | template
318 | vector_4t operator - (const vector_4t &operand)
319 | {
320 | return vector_4t(-operand.x, -operand.y, -operand.z, -operand.w);
321 | }
322 |
323 | //////////////////////////////////////////////////////////////////////////
324 | // addition
325 | template
326 | vector_2t operator + (const vector_2t &lhs, const vector_2t &rhs)
327 | {
328 | return vector_2t (lhs.x + rhs.x, lhs.y + rhs.y);
329 | }
330 |
331 | template
332 | vector_3t operator + (const vector_3t &lhs, const vector_3t &rhs)
333 | {
334 | return vector_3t (lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
335 | }
336 |
337 | template
338 | vector_4t operator + (const vector_4t &lhs, const vector_4t &rhs)
339 | {
340 | return vector_4t (lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
341 | }
342 |
343 | //////////////////////////////////////////////////////////////////////////
344 | // subtraction
345 | template
346 | vector_2t operator - (const vector_2t &lhs, const vector_2t &rhs)
347 | {
348 | return vector_2t (lhs.x - rhs.x, lhs.y - rhs.y);
349 | }
350 |
351 | template
352 | vector_3t operator - (const vector_3t &lhs, const vector_3t &rhs)
353 | {
354 | return vector_3t (lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
355 | }
356 |
357 | template
358 | vector_4t operator - (const vector_4t &lhs, const vector_4t &rhs)
359 | {
360 | return vector_4t (lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
361 | }
362 |
363 | //////////////////////////////////////////////////////////////////////////
364 | // multiplication : vector * scalar
365 | template
366 | vector_2t operator * (const vector_2t &lhs, const S& scale)
367 | {
368 | return vector_2t (lhs.x * scale, lhs.y * scale);
369 | }
370 |
371 | template
372 | vector_3t operator * (const vector_3t &lhs, const S& scale)
373 | {
374 | return vector_3t (lhs.x * scale, lhs.y * scale, lhs.z * scale);
375 | }
376 |
377 | template
378 | vector_4t operator * (const vector_4t &lhs, const S& scale)
379 | {
380 | return vector_4t (lhs.x * scale, lhs.y * scale, lhs.z * scale, lhs.w * scale);
381 | }
382 |
383 | //////////////////////////////////////////////////////////////////////////
384 | // multiplication : scalar * vector
385 | template
386 | vector_2t operator * (const S& scale , const vector_2t &rhs)
387 | {
388 | return vector_2t (rhs.x * scale, rhs.y * scale);
389 | }
390 |
391 | template
392 | vector_3t operator * (const S& scale , const vector_3t &rhs)
393 | {
394 | return vector_3t (rhs.x * scale, rhs.y * scale, rhs.z * scale);
395 | }
396 |
397 | template
398 | vector_4t operator * (const S& scale , const vector_4t &rhs)
399 | {
400 | return vector_4t (rhs.x * scale, rhs.y * scale, rhs.z * scale, rhs.w * scale);
401 | }
402 |
403 | //////////////////////////////////////////////////////////////////////////
404 | // division : vector / scalar
405 | template
406 | vector_2t operator / (const vector_2t &lhs, const S& scale)
407 | {
408 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
409 | Type scale_r = static_cast(1) / scale;
410 | return lhs * scale_r;
411 | }
412 |
413 | template
414 | vector_3t operator / (const vector_3t &lhs, const S& scale)
415 | {
416 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
417 | Type scale_r = static_cast(1) / scale;
418 | return lhs * scale_r;
419 | }
420 |
421 | template
422 | vector_4t operator / (const vector_4t &lhs, const S& scale)
423 | {
424 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
425 | Type scale_r = static_cast(1) / scale;
426 | return lhs * scale_r;
427 | }
428 |
429 | //////////////////////////////////////////////////////////////////////////
430 | // piecewise multiplication : vector * vector
431 | template
432 | vector_2t operator * (const vector_2t &lhs, const vector_2t &rhs)
433 | {
434 | return vector_2t (lhs.x * rhs.x, lhs.y * rhs.y);
435 | }
436 |
437 | template
438 | vector_3t operator * (const vector_3t &lhs, const vector_3t &rhs)
439 | {
440 | return vector_3t (lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
441 | }
442 |
443 | template
444 | vector_4t operator * (const vector_4t &lhs, const vector_4t &rhs)
445 | {
446 | return vector_4t (lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w);
447 | }
448 |
449 | //////////////////////////////////////////////////////////////////////////
450 | // piecewise division : vector / vector
451 | template
452 | vector_2t operator / (const vector_2t &lhs, const vector_2t &rhs)
453 | {
454 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
455 | return vector_2t (lhs.x / rhs.x, lhs.y / rhs.y);
456 | }
457 |
458 | template
459 | vector_3t operator / (const vector_3t &lhs, const vector_3t &rhs)
460 | {
461 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
462 | return vector_3t (lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);
463 | }
464 |
465 | template
466 | vector_4t operator / (const vector_4t &lhs, const vector_4t &rhs)
467 | {
468 | BOOST_STATIC_ASSERT(boost::is_floating_point::value);
469 | return vector_4t (lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w);
470 | }
471 |
472 | //////////////////////////////////////////////////////////////////////////
473 | // normalization
474 | template
475 | vector_2t normalize(const vector_2t &operand)
476 | {
477 | vector_2t vec(operand);
478 | return vec.normalize();
479 | }
480 |
481 | template
482 | vector_3t normalize(const vector_3t &operand)
483 | {
484 | vector_3t vec(operand);
485 | return vec.normalize();
486 | }
487 |
488 | template
489 | vector_4t normalize(const vector_4t &operand)
490 | {
491 | vector_4t vec(operand);
492 | return vec.normalize();
493 | }
494 |
495 | //////////////////////////////////////////////////////////////////////////
496 | // dot product
497 | template
498 | Type dot(const vector_2t &lhs, const vector_2t &rhs)
499 | {
500 | return lhs.x * rhs.x + lhs.y * rhs.y;
501 | }
502 |
503 | template
504 | Type dot(const vector_3t &lhs, const vector_3t &rhs)
505 | {
506 | return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
507 | }
508 |
509 | template
510 | Type dot(const vector_4t &lhs, const vector_4t &rhs)
511 | {
512 | return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w;
513 | }
514 |
515 | //////////////////////////////////////////////////////////////////////////
516 | // cross product
517 | template
518 | Type cross(const vector_2t &lhs, const vector_2t &rhs)
519 | {
520 | return lhs.x * rhs.y - lhs.y * rhs.x;
521 | }
522 |
523 | template
524 | vector_3t cross(const vector_3t &lhs, const vector_3t &rhs)
525 | {
526 | return vector_3t (
527 | lhs.y * rhs.z - lhs.z * rhs.y,
528 | rhs.x * lhs.z - lhs.x * rhs.z,
529 | lhs.x * rhs.y - lhs.y * rhs.x);
530 | }
531 | }
532 |
533 | #include "vector_helper.hpp"
534 |
535 | #endif // _VECTOR_HPP_
--------------------------------------------------------------------------------
/src/ayw/vector_helper.hpp:
--------------------------------------------------------------------------------
1 | // file: vector_helper.hpp
2 | // path: AywProc\AywProc\core\include
3 | // purpose: define some macros to generate implementation codes for
4 | // swizzle operations
5 | // author: atyuwen
6 | // homepage: http://code.google.com/p/aywproc/
7 | //
8 | // created: 2010/04/21
9 | // history:
10 | //
11 | //////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef MOUNT_VECTOR_HELPER_MACROS
14 | #define MOUNT_VECTOR_HELPER_MACROS
15 |
16 | #include
17 |
18 | #define SEQ_VECTOR_2T (x)(y)
19 | #define SEQ_VECTOR_3T (x)(y)(z)
20 | #define SEQ_VECTOR_4T (x)(y)(z)(w)
21 |
22 | #define IMPL_SWIZZLE_OP_TO_2T(_, seq) \
23 | vector_2t BOOST_PP_SEQ_CAT(seq)() const \
24 | { \
25 | return vector_2t(BOOST_PP_SEQ_ENUM(seq)); \
26 | }
27 |
28 | #define IMPL_SWIZZLE_OP_TO_3T(_, seq) \
29 | vector_3t BOOST_PP_SEQ_CAT(seq)() const \
30 | { \
31 | return vector_3t(BOOST_PP_SEQ_ENUM(seq)); \
32 | }
33 |
34 | #define IMPL_SWIZZLE_OP_TO_4T(_, seq) \
35 | vector_4t BOOST_PP_SEQ_CAT(seq)() const \
36 | { \
37 | return vector_4t(BOOST_PP_SEQ_ENUM(seq)); \
38 | }
39 |
40 | #define GEN_SWIZZLE_OP_2T_TO_2T() \
41 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_2T, (SEQ_VECTOR_2T)(SEQ_VECTOR_2T))
42 |
43 | #define GEN_SWIZZLE_OP_2T_TO_3T() \
44 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_3T, (SEQ_VECTOR_2T)(SEQ_VECTOR_2T)(SEQ_VECTOR_2T))
45 |
46 | #define GEN_SWIZZLE_OP_2T_TO_4T() \
47 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_4T, (SEQ_VECTOR_2T)(SEQ_VECTOR_2T)(SEQ_VECTOR_2T)(SEQ_VECTOR_2T))
48 |
49 | #define GEN_SWIZZLE_OP_3T_TO_2T() \
50 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_2T, (SEQ_VECTOR_3T)(SEQ_VECTOR_3T))
51 |
52 | #define GEN_SWIZZLE_OP_3T_TO_3T() \
53 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_3T, (SEQ_VECTOR_3T)(SEQ_VECTOR_3T)(SEQ_VECTOR_3T))
54 |
55 | #define GEN_SWIZZLE_OP_3T_TO_4T() \
56 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_4T, (SEQ_VECTOR_3T)(SEQ_VECTOR_3T)(SEQ_VECTOR_3T)(SEQ_VECTOR_3T))
57 |
58 | #define GEN_SWIZZLE_OP_4T_TO_2T() \
59 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_2T, (SEQ_VECTOR_4T)(SEQ_VECTOR_4T))
60 |
61 | #define GEN_SWIZZLE_OP_4T_TO_3T() \
62 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_3T, (SEQ_VECTOR_4T)(SEQ_VECTOR_4T)(SEQ_VECTOR_4T))
63 |
64 | #define GEN_SWIZZLE_OP_4T_TO_4T() \
65 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(IMPL_SWIZZLE_OP_TO_4T, (SEQ_VECTOR_4T)(SEQ_VECTOR_4T)(SEQ_VECTOR_4T)(SEQ_VECTOR_4T))
66 |
67 | #define DECLARE_SWIZZLING_FOR_VECTOR_2T() \
68 | GEN_SWIZZLE_OP_2T_TO_2T() \
69 | GEN_SWIZZLE_OP_2T_TO_3T() \
70 | GEN_SWIZZLE_OP_2T_TO_4T()
71 |
72 | #define DECLARE_SWIZZLING_FOR_VECTOR_3T() \
73 | GEN_SWIZZLE_OP_3T_TO_2T() \
74 | GEN_SWIZZLE_OP_3T_TO_3T() \
75 | GEN_SWIZZLE_OP_3T_TO_4T()
76 |
77 | #define DECLARE_SWIZZLING_FOR_VECTOR_4T() \
78 | GEN_SWIZZLE_OP_4T_TO_2T() \
79 | GEN_SWIZZLE_OP_4T_TO_3T() \
80 | GEN_SWIZZLE_OP_4T_TO_4T()
81 |
82 | #else // unmount these macros
83 |
84 | #undef MOUNT_VECTOR_HELPER_MACROS
85 |
86 | #undef SEQ_VECTOR_2T
87 | #undef SEQ_VECTOR_3T
88 | #undef SEQ_VECTOR_4T
89 |
90 | #undef IMPL_SWIZZLE_OP_TO_2T
91 | #undef IMPL_SWIZZLE_OP_TO_3T
92 | #undef IMPL_SWIZZLE_OP_TO_4T
93 |
94 | #undef GEN_SWIZZLE_OP_2T_TO_2T
95 | #undef GEN_SWIZZLE_OP_2T_TO_3T
96 | #undef GEN_SWIZZLE_OP_2T_TO_4T
97 | #undef GEN_SWIZZLE_OP_3T_TO_2T
98 | #undef GEN_SWIZZLE_OP_3T_TO_3T
99 | #undef GEN_SWIZZLE_OP_3T_TO_4T
100 | #undef GEN_SWIZZLE_OP_4T_TO_2T
101 | #undef GEN_SWIZZLE_OP_4T_TO_3T
102 | #undef GEN_SWIZZLE_OP_4T_TO_4T
103 |
104 | #undef DECLARE_SWIZZLING_FOR_VECTOR_2T
105 | #undef DECLARE_SWIZZLING_FOR_VECTOR_3T
106 | #undef DECLARE_SWIZZLING_FOR_VECTOR_4T
107 |
108 | #endif
--------------------------------------------------------------------------------
/src/common.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 |
3 | void MessageBoxf(tstring format, ...)
4 | {
5 | va_list args;
6 | TCHAR msg[1024];
7 | va_start(args, format);
8 | wvsprintf(msg, format.c_str(), args);
9 | va_end(args);
10 | MessageBox(NULL, msg, TEXT("debug"), MB_OK);
11 | }
12 |
--------------------------------------------------------------------------------
/src/common.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _COMMON_HPP_INCLUDED_
2 | #define _COMMON_HPP_INCLUDED_
3 |
4 | #define NOMINMAX
5 | #define WIN32_LEAN_AND_MEAN
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #pragma comment(lib, "d3d11.lib")
20 | #pragma comment(lib, "d3d10_1.lib")
21 | #pragma comment(lib, "d3dx11.lib")
22 | #pragma comment(lib, "d3dx10.lib")
23 | #pragma comment(lib, "dxgi.lib")
24 | #pragma comment(lib, "d2d1.lib")
25 | #pragma comment(lib, "dwrite.lib")
26 |
27 | #include "ayw/vector.hpp"
28 | using Ayw::float2;
29 | using Ayw::float3;
30 | using Ayw::float4;
31 |
32 | #include
33 | #include
34 |
35 | #ifdef UNICODE
36 | #define tchar wchar_t
37 | #define tstring std::wstring
38 | #else
39 | #define tchar char
40 | #define tstring std::string
41 | #endif
42 |
43 | template
44 | DestType lexical_cast_no_exception(const SrcType& arg)
45 | {
46 | try
47 | {
48 | return boost::lexical_cast(arg);
49 | }
50 | catch (boost::bad_lexical_cast &)
51 | {
52 | return DestType();
53 | }
54 | }
55 |
56 | #define to_string(arg) lexical_cast_no_exception(arg)
57 | #define to_wstring(arg) lexical_cast_no_exception(arg)
58 | #define to_tstring(arg) lexical_cast_no_exception(arg)
59 |
60 | void MessageBoxf(tstring format, ...);
61 |
62 | #define SAFE_RELEASE(p) if (p != NULL) {p->Release(); p = NULL;}
63 |
64 | #endif // _COMMON_HPP_INCLUDED_
--------------------------------------------------------------------------------
/src/d3d_app.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 |
3 | #include
4 | #include
5 | #include
6 | #include "ayw/vector.hpp"
7 | #include "ayw/constant.hpp"
8 | #include "d3d_app.hpp"
9 | using namespace Ayw;
10 |
11 | const tstring g_app_title = TEXT("LiVE HLSL");
12 |
13 | const int g_aa_sample = 4;
14 | const float g_aa_warm_time = 0.2f;
15 |
16 | struct ShaderParameters
17 | {
18 | float4 time; // time related parameters
19 | float4 view; // (view width, view height, 1 / width, 1 / height)
20 | float4 freq; // the short time FFT of the background music
21 | float4 mpos; // (mouse.x, mouse.y, mouse.wheel, 0)
22 | };
23 |
24 | ShaderParameters g_shader_param;
25 |
26 | //////////////////////////////////////////////////////////////////////////
27 | // static accessors
28 | //////////////////////////////////////////////////////////////////////////
29 | D3DApp g_app;
30 |
31 | D3DApp* D3DApp::GetApp()
32 | {
33 | return &g_app;
34 | }
35 |
36 | ID3D11Device* D3DApp::GetD3D11Device()
37 | {
38 | return g_app.m_d3d11_device;
39 | }
40 |
41 | ID3D11DeviceContext* D3DApp::GetD3D11DeviceContext()
42 | {
43 | return g_app.m_d3d11_device_context;
44 | }
45 |
46 | IDWriteFactory* D3DApp::GetDWriteFactory()
47 | {
48 | return g_app.m_dwrite_factory;
49 | }
50 |
51 | HRTimer* D3DApp::GetTimer()
52 | {
53 | return &g_app.m_timer;
54 | }
55 |
56 | PostProcessPtr D3DApp::GetPostProcess()
57 | {
58 | return g_app.m_custom_pp;
59 | }
60 |
61 | SoundPlayerPtr D3DApp::GetSoundPlayer()
62 | {
63 | return g_app.m_sound_player;
64 | }
65 |
66 | //////////////////////////////////////////////////////////////////////////
67 | // constructor / destructor
68 | //////////////////////////////////////////////////////////////////////////
69 | D3DApp::D3DApp()
70 | : m_hinstance(NULL)
71 | , m_hwnd(NULL)
72 | , m_swap_chain(NULL)
73 | , m_d3d11_device(NULL)
74 | , m_d3d11_device_context(NULL)
75 | , m_depthstencil_buffer(NULL)
76 | , m_back_buffer_rtv(NULL)
77 | , m_depthstencil_view(NULL)
78 | , m_back_buffer(NULL)
79 | , m_d3d10_device(NULL)
80 | , m_dwrite_factory(NULL)
81 | , m_d2d_rendertarget(NULL)
82 | , m_d2d_texture(NULL)
83 | , m_shared_texture(NULL)
84 | , m_keyed_mutex11(NULL)
85 | , m_keyed_mutex10(NULL)
86 | , m_parameter_buffer(NULL)
87 | , m_jitter_buffer(NULL)
88 | , m_interleave_buffer(NULL)
89 | , m_custom_texture(NULL)
90 | , m_hide_editor(false)
91 | , m_mouse_wheel(0)
92 | , m_half_resolution(false)
93 | , m_aa_enabled(false)
94 | , m_aa_control_time(0)
95 | , m_aa_frame_idx(false)
96 | {
97 | ZeroMemory(m_offscreen_textures, sizeof(m_offscreen_textures));
98 | ZeroMemory(m_offscreen_srvs, sizeof(m_offscreen_srvs));
99 | ZeroMemory(m_offscreen_rtvs, sizeof(m_offscreen_rtvs));
100 | }
101 |
102 | D3DApp::~D3DApp()
103 | {
104 | SAFE_RELEASE(m_interleave_buffer);
105 | SAFE_RELEASE(m_jitter_buffer);
106 | SAFE_RELEASE(m_parameter_buffer);
107 | SAFE_RELEASE(m_custom_texture);
108 |
109 | for (int i = 0; i != ARRAYSIZE(m_offscreen_textures); ++i)
110 | {
111 | SAFE_RELEASE(m_offscreen_rtvs[i]);
112 | SAFE_RELEASE(m_offscreen_srvs[i]);
113 | SAFE_RELEASE(m_offscreen_textures[i]);
114 | }
115 |
116 | SAFE_RELEASE(m_depthstencil_buffer);
117 | SAFE_RELEASE(m_back_buffer_rtv);
118 | SAFE_RELEASE(m_depthstencil_view);
119 | SAFE_RELEASE(m_back_buffer);
120 |
121 | SAFE_RELEASE(m_dwrite_factory);
122 | SAFE_RELEASE(m_d2d_rendertarget);
123 | SAFE_RELEASE(m_d2d_texture);
124 |
125 | SAFE_RELEASE(m_shared_texture);
126 | SAFE_RELEASE(m_keyed_mutex11);
127 | SAFE_RELEASE(m_keyed_mutex10);
128 |
129 | SAFE_RELEASE(m_d3d11_device_context);
130 | SAFE_RELEASE(m_d3d10_device);
131 | SAFE_RELEASE(m_d3d11_device);
132 | SAFE_RELEASE(m_swap_chain);
133 | }
134 |
135 | //////////////////////////////////////////////////////////////////////////
136 | // public interfaces
137 | //////////////////////////////////////////////////////////////////////////
138 | bool D3DApp::Initialize(HINSTANCE hinstance, int width, int height)
139 | {
140 | m_hinstance = hinstance;
141 | m_width = width;
142 | m_height = height;
143 |
144 | if (!InitializeWindow())
145 | {
146 | MessageBox(NULL, TEXT("Error creating window"), TEXT("Error"), MB_OK | MB_ICONERROR);
147 | return false;
148 | }
149 | if (!InitializeD3D())
150 | {
151 | MessageBox(NULL, TEXT("Error initializing D3D"), TEXT("Error"), MB_OK | MB_ICONERROR);
152 | return false;
153 | }
154 | if (!InitializeScene())
155 | {
156 | MessageBox(NULL, TEXT("Error initializing scene"), TEXT("Error"), MB_OK | MB_ICONERROR);
157 | return false;
158 | }
159 | if (!InitializeShaders())
160 | {
161 | MessageBox(NULL, TEXT("Error initializing shaders"), TEXT("Error"), MB_OK | MB_ICONERROR);
162 | return false;
163 | }
164 |
165 | m_text_editor = TextEditorPtr(new TextEditor);
166 | if (!m_text_editor->Initialize(m_d2d_rendertarget))
167 | {
168 | MessageBox(NULL, TEXT("Error initializing text editor"), TEXT("Error"), MB_OK | MB_ICONERROR);
169 | return false;
170 | }
171 |
172 | m_sound_player = SoundPlayerPtr(new SoundPlayer);
173 | if (!m_sound_player->Initialize())
174 | {
175 | MessageBox(NULL, TEXT("Error initializing sound player"), TEXT("Error"), MB_OK | MB_ICONERROR);
176 | return false;
177 | }
178 | m_sound_player->PlaySound(TEXT("media/bgm.mp3"), true);
179 | m_sound_player->SetMute(true);
180 |
181 | m_timer.Start();
182 | RegisterTimerEvents();
183 | return true;
184 | }
185 |
186 | int D3DApp::Run()
187 | {
188 | MSG msg;
189 | ZeroMemory(&msg, sizeof(msg));
190 | while (true)
191 | {
192 | if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
193 | {
194 | if (msg.message == WM_QUIT) break;
195 | TranslateMessage(&msg);
196 | DispatchMessage(&msg);
197 | }
198 | else
199 | {
200 | m_timer.SyncTick(1.0f / 60);
201 | UpdateScene(m_timer.GetDeltaTime());
202 | RenderScene();
203 | }
204 | }
205 | return msg.wParam;
206 | }
207 |
208 | void D3DApp::Destroy()
209 | {
210 |
211 | }
212 |
213 | int D3DApp::GetWidth() const
214 | {
215 | return m_width;
216 | }
217 |
218 | int D3DApp::GetHeight() const
219 | {
220 | return m_height;
221 | }
222 |
223 | float2 D3DApp::GetMousePos(int from_event /*= 0*/) const
224 | {
225 | if (from_event == 0) return m_mouse_pos;
226 |
227 | if (m_recorded_mouse_pos.find(from_event) != m_recorded_mouse_pos.end())
228 | {
229 | return m_mouse_pos - m_recorded_mouse_pos.at(from_event);
230 | }
231 | return float2(0, 0);
232 | }
233 |
234 | float D3DApp::GetMouseWheel() const
235 | {
236 | return m_mouse_wheel;
237 | }
238 |
239 | //////////////////////////////////////////////////////////////////////////
240 | // window procedure
241 | //////////////////////////////////////////////////////////////////////////
242 | LRESULT CALLBACK D3DApp::WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
243 | {
244 | D3DApp* app = D3DApp::GetApp();
245 | TextEditorPtr editor = app->m_text_editor;
246 | switch (message)
247 | {
248 | case WM_DESTROY:
249 | PostQuitMessage(0);
250 | return 0;
251 | case WM_KEYDOWN:
252 | {
253 | bool held_control = (GetKeyState(VK_CONTROL) & 0x80) != 0;
254 | bool held_shift = (GetKeyState(VK_SHIFT) & 0x80) != 0;
255 | UINT key_code = static_cast(wparam);
256 |
257 | if (key_code == VK_F1)
258 | {
259 | app->m_hide_editor = !app->m_hide_editor;
260 | return 0;
261 | }
262 | else if (key_code == VK_F2)
263 | {
264 | if (app->m_sound_player)
265 | {
266 | bool mute = app->m_sound_player->GetMute();
267 | app->m_sound_player->SetMute(!mute);
268 | }
269 | return 0;
270 | }
271 | else if (key_code == VK_F3)
272 | {
273 | app->m_aa_enabled = !app->m_aa_enabled;
274 | app->m_aa_control_time = 0;
275 | return 0;
276 | }
277 | else if (key_code == VK_F4)
278 | {
279 | app->m_half_resolution = !app->m_half_resolution;
280 | app->m_aa_control_time = 0;
281 | return 0;
282 | }
283 | else if (key_code == VK_OEM_PLUS && held_control)
284 | {
285 | if (app->m_sound_player) app->m_sound_player->ChangeVolume(0.1f);
286 | return 0;
287 | }
288 | else if (key_code == VK_OEM_MINUS && held_control)
289 | {
290 | if (app->m_sound_player) app->m_sound_player->ChangeVolume(-0.1f);
291 | return 0;
292 | }
293 | else if (key_code == 'N' && held_control)
294 | {
295 | if (editor) editor->NewFile();
296 | app->m_recorded_mouse_pos.clear();
297 | app->m_mouse_wheel = 0;
298 | app->m_hide_editor = false;
299 | g_shader_param.mpos = float4(0, 0, 0, 0);
300 | app->m_aa_control_time = 0;
301 | return 0;
302 | }
303 | else if (key_code == 'O' && held_control)
304 | {
305 | if (editor) editor->OpenFile();
306 | app->m_recorded_mouse_pos.clear();
307 | app->m_mouse_wheel = 0;
308 | g_shader_param.mpos = float4(0, 0, 0, 0);
309 | app->m_aa_control_time = 0;
310 | return 0;
311 | }
312 | else if (key_code == 'S' && held_control)
313 | {
314 | if (editor) editor->SaveFile(held_shift);
315 | app->m_aa_control_time = 0;
316 | return 0;
317 | }
318 | break;
319 | }
320 |
321 | case WM_LBUTTONDOWN:
322 | case WM_RBUTTONDOWN:
323 | case WM_MBUTTONDOWN:
324 | app->m_recorded_mouse_pos[message] = float2(
325 | static_cast(GET_X_LPARAM(lparam)), static_cast(GET_Y_LPARAM(lparam)));
326 | break;
327 |
328 | case WM_LBUTTONUP:
329 | app->m_recorded_mouse_pos.erase(WM_LBUTTONDOWN);
330 | break;
331 | case WM_RBUTTONUP:
332 | app->m_recorded_mouse_pos.erase(WM_RBUTTONDOWN);
333 | break;
334 | case WM_MBUTTONUP:
335 | app->m_recorded_mouse_pos.erase(WM_MBUTTONDOWN);
336 | app->m_mouse_wheel = 0;
337 | break;
338 |
339 | case WM_MOUSEMOVE:
340 | app->m_mouse_pos = float2(
341 | static_cast(GET_X_LPARAM(lparam)), static_cast(GET_Y_LPARAM(lparam)));
342 | break;
343 |
344 | case WM_MOUSEWHEEL:
345 | app->m_mouse_wheel += GET_WHEEL_DELTA_WPARAM(wparam) / static_cast(WHEEL_DELTA);
346 | break;;
347 | }
348 |
349 | if (editor && !app->m_hide_editor)
350 | {
351 | if (editor->HandleWindowMessage(hwnd, message, wparam, lparam))
352 | {
353 | return 0;
354 | }
355 | }
356 |
357 | return DefWindowProc(hwnd, message, wparam, lparam);
358 | }
359 |
360 | //////////////////////////////////////////////////////////////////////////
361 | // timer events procedure
362 | //////////////////////////////////////////////////////////////////////////
363 | void D3DApp::RegisterTimerEvents()
364 | {
365 | m_timer.AddEvent(0.1f, boost::bind(&D3DApp::TimerEventsProc, this, _1, _2), TEXT("update_title"));
366 | }
367 |
368 | void D3DApp::TimerEventsProc(int cnt, const tstring& tag)
369 | {
370 | if (tag == TEXT("update_title"))
371 | {
372 | float delta_time = m_timer.GetDeltaTime();
373 | float fps = 1.0f / std::max(delta_time, Ayw::c_eps);
374 | float cpu_time = m_timer.GetCPUDeltaTime() * 1000;
375 | float gpu_time = m_timer.GetGPUDeltaTime() * 1000;
376 |
377 | char title[512] = {0};
378 | sprintf_s(title,
379 | TEXT("%s [ ShowEditor(F1):%s | BgMusic(F2):%s | Anti-Aliasing(F3):%s | Half-Res(F4):%s ] [ FPS:%.1f | CPU:%.1fms | GPU:%.1fms ]"),
380 | g_app_title.c_str(),
381 | !m_hide_editor ? TEXT("on") : TEXT("off"),
382 | !m_sound_player->GetMute() ? TEXT("on") : TEXT("off"),
383 | m_aa_enabled ? TEXT("on") : TEXT("off"),
384 | m_half_resolution ? TEXT("on") : TEXT("off"),
385 | fps,
386 | cpu_time,
387 | gpu_time);
388 |
389 | SetWindowText(m_hwnd, title);
390 | }
391 | }
392 |
393 | //////////////////////////////////////////////////////////////////////////
394 | // private subroutines
395 | //////////////////////////////////////////////////////////////////////////
396 | bool D3DApp::InitializeWindow()
397 | {
398 | WNDCLASSEX wc;
399 | tstring wnd_class = TEXT("aywd3dapp");
400 | wc.cbSize = sizeof(WNDCLASSEX);
401 | wc.style = CS_HREDRAW | CS_VREDRAW;
402 | wc.lpfnWndProc = D3DApp::WindowProc;
403 | wc.cbClsExtra = NULL;
404 | wc.cbWndExtra = NULL;
405 | wc.hInstance = m_hinstance;
406 | wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
407 | wc.hCursor = LoadCursor(NULL, IDC_ARROW);
408 | wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
409 | wc.lpszMenuName = NULL;
410 | wc.lpszClassName = wnd_class.c_str();
411 | wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
412 | if (!RegisterClassEx(&wc))
413 | {
414 | return false;
415 | }
416 |
417 | RECT rect = {0, 0, m_width, m_height};
418 | DWORD wnd_style = WS_OVERLAPPEDWINDOW & (~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
419 | AdjustWindowRect(&rect, wnd_style, FALSE);
420 | m_hwnd = CreateWindowEx(
421 | NULL,
422 | wnd_class.c_str(),
423 | g_app_title.c_str(),
424 | wnd_style,
425 | CW_USEDEFAULT,
426 | CW_USEDEFAULT,
427 | rect.right - rect.left,
428 | rect.bottom - rect.top,
429 | NULL,
430 | NULL,
431 | m_hinstance,
432 | this);
433 |
434 | if (m_hwnd == NULL)
435 | {
436 | return false;
437 | }
438 |
439 | ShowWindow(m_hwnd, SW_SHOWNORMAL);
440 | UpdateWindow(m_hwnd);
441 |
442 | GetClientRect(m_hwnd, &rect);
443 | m_width = rect.right - rect.left;
444 | m_height = rect.bottom - rect.top;
445 | return true;
446 | }
447 |
448 | bool D3DApp::InitializeD3D()
449 | {
450 | // describe our SwapChain Buffer
451 | DXGI_MODE_DESC mode_desc;
452 | ZeroMemory(&mode_desc, sizeof(DXGI_MODE_DESC));
453 | mode_desc.Width = m_width;
454 | mode_desc.Height = m_height;
455 | mode_desc.RefreshRate.Numerator = 60;
456 | mode_desc.RefreshRate.Denominator = 1;
457 | mode_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
458 | mode_desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
459 | mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
460 |
461 | // describe our SwapChain
462 | DXGI_SWAP_CHAIN_DESC swapchain_desc;
463 | ZeroMemory(&swapchain_desc, sizeof(DXGI_SWAP_CHAIN_DESC));
464 | swapchain_desc.BufferDesc = mode_desc;
465 | swapchain_desc.SampleDesc.Count = 1;
466 | swapchain_desc.SampleDesc.Quality = 0;
467 | swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
468 | swapchain_desc.BufferCount = 1;
469 | swapchain_desc.OutputWindow = m_hwnd;
470 | swapchain_desc.Windowed = TRUE;
471 | swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
472 |
473 | // create DXGI factory to enumerate adapters
474 | IDXGIFactory1 *dxgi_factory;
475 | HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory);
476 |
477 | // use the first adapter
478 | IDXGIAdapter1 *adapter;
479 | hr = dxgi_factory->EnumAdapters1(0, &adapter);
480 | dxgi_factory->Release();
481 |
482 | // create our Direct3D 11 Device and SwapChain
483 | hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
484 | NULL, NULL, D3D11_SDK_VERSION, &swapchain_desc, &m_swap_chain, &m_d3d11_device, NULL, &m_d3d11_device_context);
485 |
486 | // initialize Direct2D, Direct3D 10.1, DirectWrite
487 | InitializeDWrite(adapter);
488 |
489 | // release the Adapter interface
490 | adapter->Release();
491 |
492 | // create our BackBuffer and Render Target
493 | hr = m_swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_back_buffer);
494 | hr = m_d3d11_device->CreateRenderTargetView(m_back_buffer, NULL, &m_back_buffer_rtv);
495 |
496 | // describe our Depth/Stencil Buffer
497 | D3D11_TEXTURE2D_DESC depthstencil_desc;
498 | depthstencil_desc.Width = m_width;
499 | depthstencil_desc.Height = m_height;
500 | depthstencil_desc.MipLevels = 1;
501 | depthstencil_desc.ArraySize = 1;
502 | depthstencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
503 | depthstencil_desc.SampleDesc.Count = 1;
504 | depthstencil_desc.SampleDesc.Quality = 0;
505 | depthstencil_desc.Usage = D3D11_USAGE_DEFAULT;
506 | depthstencil_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
507 | depthstencil_desc.CPUAccessFlags = 0;
508 | depthstencil_desc.MiscFlags = 0;
509 |
510 | // create the Depth/Stencil View
511 | m_d3d11_device->CreateTexture2D(&depthstencil_desc, NULL, &m_depthstencil_buffer);
512 | m_d3d11_device->CreateDepthStencilView(m_depthstencil_buffer, NULL, &m_depthstencil_view);
513 |
514 | // set render target views and depth stencil view
515 | m_d3d11_device_context->OMSetRenderTargets(1, &m_back_buffer_rtv, m_depthstencil_view);
516 |
517 | // create a shader resource review from the texture D2D will render to
518 | hr = m_d3d11_device->CreateShaderResourceView(m_shared_texture, NULL, &m_d2d_texture);
519 |
520 | // create off-screen textures
521 | CD3D11_TEXTURE2D_DESC offscreen_tex_desc(DXGI_FORMAT_R16G16B16A16_FLOAT, m_width, m_height);
522 | offscreen_tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
523 | offscreen_tex_desc.MipLevels = 1;
524 | for (int i = 0; i != ARRAYSIZE(m_offscreen_textures); ++i)
525 | {
526 | m_d3d11_device->CreateTexture2D(&offscreen_tex_desc, NULL, &m_offscreen_textures[i]);
527 | m_d3d11_device->CreateShaderResourceView(m_offscreen_textures[i], NULL, &m_offscreen_srvs[i]);
528 | m_d3d11_device->CreateRenderTargetView(m_offscreen_textures[i], NULL, &m_offscreen_rtvs[i]);
529 | }
530 |
531 | // create a constant buffer
532 | D3D11_BUFFER_DESC buffer_desc;
533 | ZeroMemory(&buffer_desc, sizeof(D3D11_BUFFER_DESC));
534 | buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
535 | buffer_desc.ByteWidth = sizeof(ShaderParameters);
536 | buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
537 | buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
538 | buffer_desc.MiscFlags = 0;
539 | hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_parameter_buffer);
540 |
541 | buffer_desc.ByteWidth = sizeof(float4);
542 | hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_jitter_buffer);
543 | hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_interleave_buffer);
544 |
545 | // create a texture from file
546 | D3DX11CreateShaderResourceViewFromFile(m_d3d11_device, TEXT("media/tex.bmp"), NULL, NULL, &m_custom_texture, &hr);
547 |
548 | return true;
549 | }
550 |
551 | void D3DApp::SetViewport(int width, int height)
552 | {
553 | // set view port
554 | D3D11_VIEWPORT view_port;
555 | view_port.Width = static_cast(width);
556 | view_port.Height = static_cast(height);
557 | view_port.MinDepth = 0.0f;
558 | view_port.MaxDepth = 1.0f;
559 | view_port.TopLeftX = 0;
560 | view_port.TopLeftY = 0;
561 | m_d3d11_device_context->RSSetViewports(1, &view_port);
562 | }
563 |
564 | bool D3DApp::InitializeDWrite(IDXGIAdapter1* adapter)
565 | {
566 | // create our Direc3D 10.1 Device
567 | HRESULT hr = D3D10CreateDevice1(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL,D3D10_CREATE_DEVICE_BGRA_SUPPORT,
568 | D3D10_FEATURE_LEVEL_9_3, D3D10_1_SDK_VERSION, &m_d3d10_device);
569 |
570 | // create Shared Texture that Direct3D 10.1 will render on
571 | D3D11_TEXTURE2D_DESC shared_tex_desc;
572 | ZeroMemory(&shared_tex_desc, sizeof(shared_tex_desc));
573 | shared_tex_desc.Width = m_width;
574 | shared_tex_desc.Height = m_height;
575 | shared_tex_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
576 | shared_tex_desc.MipLevels = 1;
577 | shared_tex_desc.ArraySize = 1;
578 | shared_tex_desc.SampleDesc.Count = 1;
579 | shared_tex_desc.Usage = D3D11_USAGE_DEFAULT;
580 | shared_tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
581 | shared_tex_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
582 | hr = m_d3d11_device->CreateTexture2D(&shared_tex_desc, NULL, &m_shared_texture);
583 |
584 | // get the keyed mutex for the shared texture (for D3D11)
585 | hr = m_shared_texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyed_mutex11);
586 |
587 | // get the shared handle needed to open the shared texture in D3D10.1
588 | IDXGIResource *shared_resource10;
589 | HANDLE shared_handle10;
590 | hr = m_shared_texture->QueryInterface(__uuidof(IDXGIResource), (void**)&shared_resource10);
591 | hr = shared_resource10->GetSharedHandle(&shared_handle10);
592 | shared_resource10->Release();
593 |
594 | // open the surface for the shared texture in D3D10.1
595 | IDXGISurface1 *shared_surface10;
596 | hr = m_d3d10_device->OpenSharedResource(shared_handle10, __uuidof(IDXGISurface1), (void**)(&shared_surface10));
597 | hr = shared_surface10->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyed_mutex10);
598 |
599 | // create D2D factory
600 | ID2D1Factory *d2d_factory;
601 | hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), (void**)&d2d_factory);
602 | D2D1_RENDER_TARGET_PROPERTIES rendertaget_properties;
603 | ZeroMemory(&rendertaget_properties, sizeof(rendertaget_properties));
604 | rendertaget_properties.type = D2D1_RENDER_TARGET_TYPE_HARDWARE;
605 | rendertaget_properties.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED);
606 | hr = d2d_factory->CreateDxgiSurfaceRenderTarget(shared_surface10, &rendertaget_properties, &m_d2d_rendertarget);
607 | shared_surface10->Release();
608 | d2d_factory->Release();
609 |
610 | // DirectWrite
611 | hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
612 | reinterpret_cast(&m_dwrite_factory));
613 |
614 | m_d3d10_device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
615 | return true;
616 | }
617 |
618 | bool D3DApp::InitializeScene()
619 | {
620 | return true;
621 | }
622 |
623 | bool D3DApp::InitializeShaders()
624 | {
625 | m_custom_pp = PostProcessPtr(new PostProcess);
626 |
627 | m_combine_pp = PostProcessPtr(new PostProcess);
628 | if (!m_combine_pp->LoadPixelShaderFromFile(TEXT("pp_combine.hlsl"), TEXT("ps_main")))
629 | {
630 | return false;
631 | }
632 |
633 | m_resolve_pp = PostProcessPtr(new PostProcess(true));
634 | if (!m_resolve_pp->LoadPixelShaderFromFile(TEXT("pp_resolve.hlsl"), TEXT("resolve")))
635 | {
636 | return false;
637 | }
638 |
639 | m_halfres_resolve_pp = PostProcessPtr(new PostProcess(true));
640 | if (!m_halfres_resolve_pp->LoadPixelShaderFromFile(TEXT("pp_resolve.hlsl"), TEXT("halfres_resolve")))
641 | {
642 | return false;
643 | }
644 |
645 | m_halfres_copy_pp = PostProcessPtr(new PostProcess(true));
646 | if (!m_halfres_copy_pp->LoadPixelShaderFromFile(TEXT("pp_resolve.hlsl"), TEXT("halfres_copy")))
647 | {
648 | return false;
649 | }
650 |
651 | return true;
652 | }
653 |
654 | void D3DApp::UpdateScene(float delta_time)
655 | {
656 | m_text_editor->Update(delta_time);
657 | m_sound_player->Update(delta_time);
658 |
659 | // get sound spectrum
660 | std::vector spectrum;
661 | m_sound_player->GetSpectrum(1024, spectrum);
662 | float low_freq = *std::max_element(spectrum.begin(), spectrum.begin() + 16 );
663 | float mid_low_freq = *std::max_element(spectrum.begin() + 16, spectrum.begin() + 64 );
664 | float mid_high_freq = *std::max_element(spectrum.begin() + 64, spectrum.begin() + 128);
665 | float high_freq = *std::max_element(spectrum.begin() + 128, spectrum.begin() + 256);
666 | float4 freq(low_freq, mid_low_freq, mid_high_freq, high_freq);
667 |
668 | // mouse interaction
669 | float2 mouse_pos = GetMousePos(WM_RBUTTONDOWN);
670 | float mouse_wheel = GetMouseWheel();
671 | float4 mpos(mouse_pos.x, mouse_pos.y, mouse_wheel, 0);
672 | float4 delta = mpos - g_shader_param.mpos;
673 | if (m_aa_enabled)
674 | {
675 | if (delta.length_sqr() > 1e-3) m_aa_control_time = 0;
676 | else m_aa_control_time += std::min(delta_time, g_aa_warm_time * 0.5f);
677 | }
678 |
679 | // update shader parameters
680 | const float smooth_factor = 0.8f;
681 | g_shader_param.time = float4(m_timer.GetTime(), 0, 0, 0);
682 | g_shader_param.view = float4(static_cast(m_width), static_cast(m_height), 1.0f / m_width, 1.0f / m_height);
683 | g_shader_param.freq = g_shader_param.freq * smooth_factor + freq * (1 - smooth_factor);
684 | g_shader_param.mpos = g_shader_param.mpos * smooth_factor + mpos * (1 - smooth_factor);
685 | }
686 |
687 | void D3DApp::RenderScene()
688 | {
689 | m_timer.BeginGPUTimming();
690 | SetViewport(m_width, m_height);
691 | m_d3d11_device_context->ClearRenderTargetView(m_back_buffer_rtv, float4(0, 0, 0, 1).ptr());
692 | m_d3d11_device_context->ClearDepthStencilView(m_depthstencil_view, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 255);
693 |
694 | bool enable_aa = false;
695 | if (m_aa_enabled && m_aa_control_time > g_aa_warm_time)
696 | {
697 | enable_aa = true;
698 | static std::vector perm(g_aa_sample * g_aa_sample);
699 | if (m_aa_frame_idx == 0)
700 | {
701 | for (int i = 0; i != perm.size(); ++i) perm[i] = i;
702 | std::random_shuffle(perm.begin(), perm.end());
703 | }
704 |
705 | // stratified sampling
706 | int sample = perm[m_aa_frame_idx];
707 | float2 jitter(static_cast(sample % g_aa_sample), static_cast(sample / g_aa_sample));
708 | float2 offset = float2(g_aa_sample / 2.0f, g_aa_sample / 2.0f);
709 | offset += float2(static_cast(rand()), static_cast(rand())) / RAND_MAX;;
710 | jitter = (jitter - offset) / float2(static_cast(m_width * g_aa_sample), static_cast(m_height * g_aa_sample));
711 | if (m_half_resolution)
712 | {
713 | jitter = jitter * 2.0f;
714 | float interleave_x = static_cast(sample % g_aa_sample >= (g_aa_sample / 2));
715 | float interleave_y = static_cast(sample / g_aa_sample >= (g_aa_sample / 2));
716 | UpdateConstantBuffer(m_interleave_buffer, float4(interleave_x, interleave_y, 0, 0));
717 | }
718 |
719 | UpdateConstantBuffer(m_jitter_buffer, float4(jitter.x, jitter.y, 0, 0));
720 | m_d3d11_device_context->VSSetConstantBuffers(0, 1, &m_jitter_buffer);
721 |
722 | m_aa_frame_idx = (m_aa_frame_idx + 1) % (g_aa_sample * g_aa_sample);
723 | }
724 | else
725 | {
726 | m_aa_frame_idx = 0;
727 | }
728 |
729 | if (m_half_resolution) SetViewport(m_width / 2, m_height / 2);
730 | {
731 | UpdateConstantBuffer(m_parameter_buffer, g_shader_param);
732 | m_custom_pp->SetParameters(0, m_parameter_buffer);
733 | if (m_custom_texture != NULL)
734 | {
735 | m_custom_pp->InputPin(0, m_custom_texture);
736 | }
737 | m_custom_pp->OutputPin(0, m_offscreen_rtvs[enable_aa | m_half_resolution]);
738 | m_custom_pp->Apply();
739 | }
740 | if (m_half_resolution) SetViewport(m_width, m_height);
741 |
742 | if (enable_aa)
743 | {
744 | UpdateConstantBuffer(m_jitter_buffer, float4(0, 0, 0, 0));
745 | m_d3d11_device_context->VSSetConstantBuffers(0, 1, &m_jitter_buffer);
746 |
747 | if (m_half_resolution)
748 | {
749 | m_halfres_resolve_pp->SetParameters(0, m_interleave_buffer);
750 | m_halfres_resolve_pp->InputPin(0, m_offscreen_srvs[1]);
751 | m_halfres_resolve_pp->OutputPin(0, m_offscreen_rtvs[0]);
752 | m_halfres_resolve_pp->Apply();
753 | }
754 | else
755 | {
756 | m_resolve_pp->InputPin(0, m_offscreen_srvs[1]);
757 | m_resolve_pp->OutputPin(0, m_offscreen_rtvs[0]);
758 | m_resolve_pp->Apply();
759 | }
760 | }
761 | else if (m_half_resolution)
762 | {
763 | m_halfres_copy_pp->InputPin(0, m_offscreen_srvs[1]);
764 | m_halfres_copy_pp->OutputPin(0, m_offscreen_rtvs[0]);
765 | m_halfres_copy_pp->Apply();
766 | }
767 |
768 | RenderOverlay();
769 | m_combine_pp->InputPin(0, m_offscreen_srvs[0]);
770 | m_combine_pp->InputPin(1, m_d2d_texture);
771 | m_combine_pp->OutputPin(0, m_back_buffer_rtv);
772 | m_combine_pp->Apply();
773 |
774 | m_timer.EndGPUTimming();
775 | m_swap_chain->Present(0, 0);
776 | }
777 |
778 | void D3DApp::RenderOverlay()
779 | {
780 | // release the d3d11 device
781 | m_keyed_mutex11->ReleaseSync(0);
782 |
783 | // switch to the d3d10.1 device
784 | m_keyed_mutex10->AcquireSync(0, 5);
785 |
786 | // draw d2d content
787 | m_d2d_rendertarget->BeginDraw();
788 |
789 | // clear d2d background
790 | m_d2d_rendertarget->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f));
791 |
792 | // draw text editor
793 | if (!m_hide_editor)
794 | {
795 | m_text_editor->Render(m_d2d_rendertarget);
796 | }
797 |
798 | // end draw
799 | m_d2d_rendertarget->EndDraw();
800 |
801 | // release the d3d10.1 device
802 | m_keyed_mutex10->ReleaseSync(1);
803 |
804 | // switch back to the d3d11 device
805 | m_keyed_mutex11->AcquireSync(1, 5);
806 | }
807 |
--------------------------------------------------------------------------------
/src/d3d_app.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _D3D_APP_HPP_INCLUDED_
2 | #define _D3D_APP_HPP_INCLUDED_
3 |
4 | #include "hr_timer.hpp"
5 | #include "post_process.hpp"
6 | #include "text_editor.hpp"
7 | #include "sound_player.hpp"
8 |
9 | class D3DApp
10 | {
11 | public:
12 | D3DApp();
13 | virtual ~D3DApp();
14 |
15 | public:
16 | bool Initialize(HINSTANCE hinstance, int width, int height);
17 | int Run();
18 | void Destroy();
19 |
20 | int GetWidth() const;
21 | int GetHeight() const;
22 |
23 | float2 GetMousePos(int from_event = 0) const;
24 | float GetMouseWheel() const;
25 |
26 | public:
27 | static D3DApp* GetApp();
28 | static ID3D11Device* GetD3D11Device();
29 | static ID3D11DeviceContext* GetD3D11DeviceContext();
30 | static IDWriteFactory* GetDWriteFactory();
31 | static HRTimer* GetTimer();
32 | static PostProcessPtr GetPostProcess();
33 | static SoundPlayerPtr GetSoundPlayer();
34 |
35 | public:
36 | static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
37 | void RegisterTimerEvents();
38 | void TimerEventsProc(int cnt, const tstring& tag);
39 |
40 | private:
41 | bool InitializeWindow();
42 | bool InitializeD3D();
43 | bool InitializeScene();
44 | bool InitializeShaders();
45 |
46 | void UpdateScene(float delta_time);
47 | void RenderScene();
48 |
49 | void SetViewport(int width, int height);
50 |
51 | template
52 | void UpdateConstantBuffer(ID3D11Buffer *buffer, const T& content)
53 | {
54 | D3D11_MAPPED_SUBRESOURCE res;
55 | m_d3d11_device_context->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
56 | *static_cast(res.pData) = content;
57 | m_d3d11_device_context->Unmap(buffer, 0);
58 | }
59 |
60 | bool InitializeDWrite(IDXGIAdapter1* adapter);
61 | void RenderOverlay();
62 |
63 | private:
64 | HINSTANCE m_hinstance;
65 | int m_width;
66 | int m_height;
67 | HWND m_hwnd;
68 | HRTimer m_timer;
69 |
70 | IDXGISwapChain* m_swap_chain;
71 | ID3D11Device* m_d3d11_device;
72 | ID3D11DeviceContext* m_d3d11_device_context;
73 | ID3D11Texture2D* m_back_buffer;
74 | ID3D11Texture2D* m_depthstencil_buffer;
75 | ID3D11RenderTargetView* m_back_buffer_rtv;
76 | ID3D11DepthStencilView* m_depthstencil_view;
77 |
78 | ID3D11Texture2D* m_offscreen_textures[2];
79 | ID3D11RenderTargetView* m_offscreen_rtvs[2];
80 | ID3D11ShaderResourceView* m_offscreen_srvs[2];
81 |
82 | ID3D10Device1* m_d3d10_device;
83 | IDWriteFactory* m_dwrite_factory;
84 | ID2D1RenderTarget* m_d2d_rendertarget;
85 | ID3D11ShaderResourceView* m_d2d_texture;
86 |
87 | ID3D11Texture2D* m_shared_texture;
88 | IDXGIKeyedMutex* m_keyed_mutex11;
89 | IDXGIKeyedMutex* m_keyed_mutex10;
90 |
91 | PostProcessPtr m_custom_pp;
92 | PostProcessPtr m_resolve_pp;
93 | PostProcessPtr m_combine_pp;
94 | PostProcessPtr m_halfres_resolve_pp;
95 | PostProcessPtr m_halfres_copy_pp;
96 | ID3D11Buffer* m_parameter_buffer;
97 | ID3D11ShaderResourceView* m_custom_texture;
98 | ID3D11Buffer* m_jitter_buffer;
99 | ID3D11Buffer* m_interleave_buffer;
100 |
101 | TextEditorPtr m_text_editor;
102 | bool m_hide_editor;
103 | SoundPlayerPtr m_sound_player;
104 |
105 | std::map m_recorded_mouse_pos;
106 | float2 m_mouse_pos;
107 | float m_mouse_wheel;
108 |
109 | bool m_half_resolution;
110 | bool m_aa_enabled;
111 | int m_aa_frame_idx;
112 | float m_aa_control_time;
113 | };
114 |
115 | #endif // _D3D_APP_HPP_INCLUDED_
--------------------------------------------------------------------------------
/src/editable_text.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 | #include "editable_text.hpp"
3 |
4 | #include
5 |
6 | //////////////////////////////////////////////////////////////////////////
7 | // constructor / destructor
8 | //////////////////////////////////////////////////////////////////////////
9 | EditableText::EditableText()
10 | {
11 | SetCaretPos(0);
12 | SetSelection(0, 0);
13 | UpdateHorizenPos();
14 | }
15 |
16 | EditableText::~EditableText()
17 | {
18 |
19 | }
20 |
21 | bool EditableText::Selection::IsValid(int text_length /* = -1 */) const
22 | {
23 | if (start_pos == end_pos) return false;
24 |
25 | if (text_length >= 0)
26 | {
27 | if (start_pos > static_cast(text_length)) return false;
28 | if (end_pos > static_cast(text_length)) return false;
29 | }
30 |
31 | return true;
32 | }
33 |
34 | //////////////////////////////////////////////////////////////////////////
35 | // public interfaces
36 | //////////////////////////////////////////////////////////////////////////
37 | void EditableText::SetText(const std::wstring& text)
38 | {
39 | m_text = text;
40 | SetCaretPos(0);
41 | UpdateHorizenPos();
42 |
43 | m_undo_records.clear();
44 | m_redo_records.clear();
45 | }
46 |
47 | void EditableText::SetCaretPos(size_t pos, bool extend_selection /*= false*/)
48 | {
49 | SetCaretPosInner(pos, extend_selection);
50 | UpdateHorizenPos();
51 | }
52 |
53 | void EditableText::MoveCharLeft(bool extend_selection /*= false*/)
54 | {
55 | if (m_caret_pos > 0)
56 | {
57 | SetCaretPos(m_caret_pos - 1, extend_selection);
58 | }
59 | }
60 |
61 | void EditableText::MoveCharRight(bool extend_selection /*= false*/)
62 | {
63 | size_t pos = m_caret_pos;
64 | SetCaretPos(pos + 1, extend_selection);
65 | }
66 |
67 | void EditableText::MoveWordLeft(bool extend_selection /*= false*/)
68 | {
69 | int pos = m_caret_pos - 1;
70 | for (; pos >= 0; --pos)
71 | {
72 | if (!isspace(m_text[pos])) break;
73 | if (pos != m_caret_pos - 1 && m_text[pos] == '\n') break;
74 | }
75 |
76 | if (pos < 0 || m_text[pos] == '\n')
77 | {
78 | SetCaretPos(pos + 1, extend_selection);
79 | }
80 | else if (!isalnum(m_text[pos]) && m_text[pos] != '_')
81 | {
82 | SetCaretPos(pos, extend_selection);
83 | }
84 | else
85 | {
86 | for (; pos >= 0; --pos)
87 | {
88 | if (!isalnum(m_text[pos]) && m_text[pos] != '_') break;
89 | }
90 | SetCaretPos(pos + 1, extend_selection);
91 | }
92 | }
93 |
94 | void EditableText::MoveWordRight(bool extend_selection /*= false*/)
95 | {
96 | size_t pos = m_caret_pos;
97 | if (pos < m_text.length() && m_text[pos] == '\n') pos += 1;
98 |
99 | if (pos == m_caret_pos)
100 | {
101 | for (; pos < m_text.length(); ++pos)
102 | {
103 | if (!isalnum(m_text[pos]) && m_text[pos] != '_') break;
104 | }
105 | if (pos == m_caret_pos && pos < m_text.length()) pos += 1;
106 | }
107 |
108 | for (; pos < m_text.length(); ++pos)
109 | {
110 | if (!isspace(m_text[pos]) || m_text[pos] == '\n') break;
111 | }
112 |
113 | SetCaretPos(pos, extend_selection);
114 | }
115 |
116 | void EditableText::MoveLineUp(bool extend_selection /*= false*/)
117 | {
118 | size_t pos = GetLineBeginPos(m_caret_pos);
119 | if (pos > 0)
120 | {
121 | pos = GetLineBeginPos(pos - 1);
122 | }
123 |
124 | size_t end_pos = GetLineEndPos(pos);
125 | pos = std::min(pos + m_horizen_pos, end_pos);
126 | SetCaretPosInner(pos, extend_selection);
127 | }
128 |
129 | void EditableText::MoveLineDown(bool extend_selection /*= false*/)
130 | {
131 | size_t pos = GetLineEndPos(m_caret_pos);
132 | if (pos < m_text.length())
133 | {
134 | pos = GetLineEndPos(pos + 1);
135 | }
136 |
137 | size_t start_pos = GetLineBeginPos(pos);
138 | pos = std::min(start_pos + m_horizen_pos, pos);
139 | SetCaretPosInner(pos, extend_selection);
140 | }
141 |
142 | void EditableText::MoveLineBegin(bool extend_selection /*= false*/)
143 | {
144 | size_t pos = GetLineBeginPos(m_caret_pos);
145 | SetCaretPos(pos, extend_selection);
146 | }
147 |
148 | void EditableText::MoveLineHome(bool extend_selection /*= false*/)
149 | {
150 | size_t pos = GetLineBeginPos(m_caret_pos);
151 | for (; pos < m_text.length(); ++pos)
152 | {
153 | if (!isspace(m_text[pos]) || m_text[pos] == '\n') break;
154 | }
155 | SetCaretPos(pos, extend_selection);
156 | }
157 |
158 | void EditableText::MoveLineEnd(bool extend_selection /*= false*/)
159 | {
160 | size_t pos = GetLineEndPos(m_caret_pos);
161 | SetCaretPos(pos, extend_selection);
162 | }
163 |
164 | void EditableText::MoveTextBegin(bool extend_selection /*= false*/)
165 | {
166 | SetCaretPos(0, extend_selection);
167 | }
168 |
169 | void EditableText::MoveTextEnd(bool extend_selection /*= false*/)
170 | {
171 | SetCaretPos(m_text.length(), extend_selection);
172 | }
173 |
174 | void EditableText::MoveToLine(size_t line, bool extend_selection /*= false*/)
175 | {
176 | size_t pos = GetTextPos(line, 0);
177 | SetCaretPos(pos, extend_selection);
178 | }
179 |
180 | void EditableText::InsertChar(wchar_t c)
181 | {
182 | std::wstring str(1, c);
183 | InsertText(str);
184 | }
185 |
186 | void EditableText::InsertText(const std::wstring& text)
187 | {
188 | DeleteSelection();
189 | m_text.insert(m_text.begin() + m_caret_pos, text.begin(), text.end());
190 | SetCaretPos(m_caret_pos + text.length());
191 |
192 | EditOperation op = {EO_Insert, m_caret_pos - text.length(), text};
193 | m_undo_records.push_back(op);
194 | m_redo_records.clear();
195 | }
196 |
197 | void EditableText::DeleteSelection()
198 | {
199 | if (!m_selection.IsValid()) return;
200 |
201 | size_t left = std::min(m_selection.start_pos, m_selection.end_pos);
202 | size_t right = std::max(m_selection.start_pos, m_selection.end_pos);
203 | std::wstring text_to_del(m_text.begin() + left, m_text.begin() + right);
204 | m_text.erase(m_text.begin() + left, m_text.begin() + right);
205 | SetCaretPos(left);
206 |
207 | EditOperation op = {EO_Delete, left, text_to_del};
208 | m_undo_records.push_back(op);
209 | m_redo_records.clear();
210 | }
211 |
212 | void EditableText::CopyToClipboard() const
213 | {
214 | if (!m_selection.IsValid()) return;
215 |
216 | if (OpenClipboard(NULL))
217 | {
218 | if (EmptyClipboard())
219 | {
220 | size_t left = std::min(m_selection.start_pos, m_selection.end_pos);
221 | size_t right = std::max(m_selection.start_pos, m_selection.end_pos);
222 | std::wstring selected_text = m_text.substr(left, right - left);
223 |
224 | size_t num_bytes = sizeof(wchar_t) * (selected_text.length() + 1);
225 | HGLOBAL clipboard_data = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, num_bytes);
226 |
227 | if (clipboard_data != NULL)
228 | {
229 | void* memory = GlobalLock(clipboard_data);
230 | if (memory != NULL)
231 | {
232 | memcpy(memory, selected_text.c_str(), num_bytes);
233 | GlobalUnlock(clipboard_data);
234 | if (SetClipboardData(CF_UNICODETEXT, clipboard_data) != NULL)
235 | {
236 | clipboard_data = NULL;
237 | }
238 | }
239 | GlobalFree(clipboard_data);
240 | }
241 | }
242 | CloseClipboard();
243 | }
244 | }
245 |
246 | void EditableText::PasteFromClipboard()
247 | {
248 | DeleteSelection();
249 |
250 | if (OpenClipboard(NULL))
251 | {
252 | HGLOBAL clipboard_data = GetClipboardData(CF_UNICODETEXT);
253 | if (clipboard_data != NULL)
254 | {
255 | void* memory = GlobalLock(clipboard_data);
256 | wchar_t* text = reinterpret_cast(memory);
257 | InsertText(text);
258 | }
259 | }
260 | }
261 |
262 | void EditableText::Undo()
263 | {
264 | if (m_undo_records.empty()) return;
265 |
266 | EditOperation op = m_undo_records.back();
267 | m_undo_records.pop_back();
268 | m_redo_records.push_back(op);
269 |
270 | if (op.type == EO_Delete)
271 | {
272 | m_text.insert(m_text.begin() + op.pos, op.text.begin(), op.text.end());
273 | SetCaretPos(op.pos + op.text.length());
274 | }
275 | else if (op.type == EO_Insert)
276 | {
277 | m_text.erase(m_text.begin() + op.pos, m_text.begin() + op.pos + op.text.length());
278 | SetCaretPos(op.pos);
279 | }
280 | }
281 |
282 | void EditableText::Redo()
283 | {
284 | if (m_redo_records.empty()) return;
285 |
286 | EditOperation op = m_redo_records.back();
287 | m_redo_records.pop_back();
288 | m_undo_records.push_back(op);
289 |
290 | if (op.type == EO_Insert)
291 | {
292 | m_text.insert(m_text.begin() + op.pos, op.text.begin(), op.text.end());
293 | SetCaretPos(op.pos + op.text.length());
294 | }
295 | else if (op.type == EO_Delete)
296 | {
297 | m_text.erase(m_text.begin() + op.pos, m_text.begin() + op.pos + op.text.length());
298 | SetCaretPos(op.pos);
299 | }
300 | }
301 |
302 | const std::wstring& EditableText::GetText() const
303 | {
304 | return m_text;
305 | }
306 |
307 | size_t EditableText::GetTextPos(size_t line, size_t column) const
308 | {
309 | size_t cur_line = 0;
310 | size_t pos = 0;
311 | for (; pos < m_text.length(); ++pos)
312 | {
313 | if (cur_line == line) break;
314 | if (m_text[pos] == '\n') ++cur_line;
315 | }
316 |
317 | size_t line_end = GetLineEndPos(pos);
318 | if (line_end - pos < column) return line_end;
319 | return pos + column;
320 | }
321 |
322 | size_t EditableText::GetCaretPos() const
323 | {
324 | return m_caret_pos;
325 | }
326 |
327 | size_t EditableText::GetCaretLine() const
328 | {
329 | return std::count_if(m_text.begin(), m_text.begin() + m_caret_pos,
330 | [](wchar_t c) {return c == '\n';});
331 | }
332 |
333 | EditableText::Selection EditableText::GetSelection() const
334 | {
335 | return m_selection;
336 | }
337 |
338 | //////////////////////////////////////////////////////////////////////////
339 | // private subroutines
340 | //////////////////////////////////////////////////////////////////////////
341 | void EditableText::SetSelection(size_t start, size_t end)
342 | {
343 | m_selection.start_pos = start;
344 | m_selection.end_pos = end;
345 | }
346 |
347 | void EditableText::SetSelectionStart(size_t start)
348 | {
349 | m_selection.start_pos = start;
350 | }
351 |
352 | void EditableText::SetSelectionEnd(size_t end)
353 | {
354 | m_selection.end_pos = end;
355 | }
356 |
357 | size_t EditableText::GetLineBeginPos(size_t current_pos) const
358 | {
359 | int pos = current_pos - 1;
360 | for (; pos >= 0; --pos)
361 | {
362 | if (m_text[pos] == '\n') break;
363 | }
364 | return pos + 1;
365 | }
366 |
367 | size_t EditableText::GetLineEndPos(size_t current_pos) const
368 | {
369 | size_t pos = current_pos;
370 | for (; pos < m_text.length(); ++pos)
371 | {
372 | if (m_text[pos] == '\n') break;
373 | }
374 | return pos;
375 | }
376 |
377 | void EditableText::SetCaretPosInner(size_t pos, bool extend_selection /*= false*/)
378 | {
379 | pos = std::min(pos, m_text.length());
380 | m_caret_pos = pos;
381 |
382 | if (extend_selection)
383 | {
384 | SetSelectionEnd(m_caret_pos);
385 | }
386 | else
387 | {
388 | SetSelection(m_caret_pos, m_caret_pos);
389 | }
390 | }
391 |
392 | void EditableText::UpdateHorizenPos()
393 | {
394 | size_t pos = GetLineBeginPos(m_caret_pos);
395 | m_horizen_pos = m_caret_pos - pos;
396 | }
397 |
--------------------------------------------------------------------------------
/src/editable_text.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _EDITABLE_TEXT_HPP_INCLUDED_
2 | #define _EDITABLE_TEXT_HPP_INCLUDED_
3 |
4 | #include
5 | #include
6 |
7 | class EditableText
8 | {
9 | public:
10 | enum EditType
11 | {
12 | EO_Insert,
13 | EO_Delete,
14 | };
15 |
16 | struct EditOperation
17 | {
18 | EditType type;
19 | size_t pos;
20 | std::wstring text;
21 | };
22 |
23 | struct Selection
24 | {
25 | size_t start_pos;
26 | size_t end_pos;
27 | bool IsValid(int text_length = -1) const;
28 | };
29 |
30 | public:
31 | EditableText();
32 | virtual ~EditableText();
33 |
34 | public:
35 | void SetText(const std::wstring& text);
36 | void SetCaretPos(size_t pos, bool extend_selection = false);
37 |
38 | void MoveCharLeft(bool extend_selection = false);
39 | void MoveCharRight(bool extend_selection = false);
40 | void MoveWordLeft(bool extend_selection = false);
41 | void MoveWordRight(bool extend_selection = false);
42 |
43 | void MoveLineUp(bool extend_selection = false);
44 | void MoveLineDown(bool extend_selection = false);
45 | void MoveLineBegin(bool extend_selection = false);
46 | void MoveLineHome(bool extend_selection = false);
47 | void MoveLineEnd(bool extend_selection = false);
48 | void MoveTextBegin(bool extend_selection = false);
49 | void MoveTextEnd(bool extend_selection = false);
50 | void MoveToLine(size_t line, bool extend_selection = false);
51 |
52 | void InsertChar(wchar_t c);
53 | void InsertText(const std::wstring& text);
54 | void DeleteSelection();
55 |
56 | void CopyToClipboard() const;
57 | void PasteFromClipboard();
58 |
59 | void Undo();
60 | void Redo();
61 |
62 | const std::wstring& GetText() const;
63 | size_t GetTextPos(size_t line, size_t column) const;
64 |
65 | size_t GetCaretPos() const;
66 | size_t GetCaretLine() const;
67 | Selection GetSelection() const;
68 |
69 | private:
70 | void SetSelection(size_t start, size_t end);
71 | void SetSelectionStart(size_t start);
72 | void SetSelectionEnd(size_t end);
73 |
74 | size_t GetLineBeginPos(size_t current_pos) const;
75 | size_t GetLineEndPos(size_t current_pos) const;
76 |
77 | void SetCaretPosInner(size_t pos, bool extend_selection = false);
78 | void UpdateHorizenPos();
79 |
80 | private:
81 | std::wstring m_text;
82 | size_t m_caret_pos;
83 | size_t m_horizen_pos;
84 | Selection m_selection;
85 |
86 | std::vector m_undo_records;
87 | std::vector m_redo_records;
88 | };
89 |
90 | #endif // _EDITABLE_TEXT_HPP_INCLUDED_
--------------------------------------------------------------------------------
/src/hr_timer.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 | #include "hr_timer.hpp"
3 | #include "d3d_app.hpp"
4 | #include
5 |
6 | //////////////////////////////////////////////////////////////////////////
7 | // constructor / destructor
8 | //////////////////////////////////////////////////////////////////////////
9 | HRTimer::HRTimer()
10 | : m_count_start(0)
11 | , m_count_tick(0)
12 | , m_count_delta(0)
13 | , m_count_delta_busy(0)
14 | , m_count_per_second(1)
15 | , m_count_delta_gpu(0)
16 | , m_count_per_second_gpu(1)
17 | , m_first_tick(true)
18 | , m_query_idx(0)
19 | , m_query_number(0)
20 | , m_query_skipped(false)
21 | {
22 | ZeroMemory(m_query_timestamp_start, sizeof(m_query_timestamp_start));
23 | ZeroMemory(m_query_timestamp_end, sizeof(m_query_timestamp_end));
24 | ZeroMemory(m_query_timestamp_disjoint, sizeof(m_query_timestamp_disjoint));
25 | }
26 |
27 | HRTimer::~HRTimer()
28 | {
29 | timeEndPeriod(1);
30 |
31 | for (int i = 0; i != gpu_query_buffer_size; ++i)
32 | {
33 | SAFE_RELEASE(m_query_timestamp_start[i]);
34 | SAFE_RELEASE(m_query_timestamp_end[i]);
35 | SAFE_RELEASE(m_query_timestamp_disjoint[i]);
36 | }
37 | }
38 |
39 | //////////////////////////////////////////////////////////////////////////
40 | // public interfaces
41 | //////////////////////////////////////////////////////////////////////////
42 | void HRTimer::Start()
43 | {
44 | timeBeginPeriod(1);
45 |
46 | LARGE_INTEGER frequency_count;
47 | QueryPerformanceFrequency(&frequency_count);
48 | m_count_per_second = frequency_count.QuadPart;
49 | QueryPerformanceCounter(&frequency_count);
50 | m_count_start = frequency_count.QuadPart;
51 |
52 | CD3D11_QUERY_DESC query_timestamp_desc(D3D11_QUERY_TIMESTAMP);
53 | CD3D11_QUERY_DESC query_timestamp_disjoint_desc(D3D11_QUERY_TIMESTAMP_DISJOINT);
54 |
55 | for (int i = 0; i != gpu_query_buffer_size; ++i)
56 | {
57 | D3DApp::GetD3D11Device()->CreateQuery(&query_timestamp_desc, &m_query_timestamp_start[i]);
58 | D3DApp::GetD3D11Device()->CreateQuery(&query_timestamp_desc, &m_query_timestamp_end[i]);
59 | D3DApp::GetD3D11Device()->CreateQuery(&query_timestamp_disjoint_desc, &m_query_timestamp_disjoint[i]);
60 | }
61 | }
62 |
63 | void HRTimer::Tick()
64 | {
65 | LARGE_INTEGER frequency_count;
66 | QueryPerformanceCounter(&frequency_count);
67 | m_count_delta = frequency_count.QuadPart - m_count_tick;
68 | m_count_tick = frequency_count.QuadPart;
69 |
70 | if (m_first_tick)
71 | {
72 | m_count_delta = 0;
73 | m_first_tick = false;
74 | }
75 | else
76 | {
77 | m_count_delta = std::max(0, m_count_delta);
78 | }
79 |
80 | TickTimerEvents(GetDeltaTime());
81 | }
82 |
83 | void HRTimer::SyncTick(float sync_period)
84 | {
85 | if (m_first_tick)
86 | {
87 | m_count_delta_busy = 0;
88 | return Tick();
89 | }
90 |
91 | LARGE_INTEGER frequency_count;
92 | QueryPerformanceCounter(&frequency_count);
93 | m_count_delta_busy = frequency_count.QuadPart - m_count_tick;
94 | float delta_time = static_cast(m_count_delta_busy) / m_count_per_second;
95 | if (delta_time < sync_period)
96 | {
97 | int waiting_ms = static_cast((sync_period - delta_time) * 1000);
98 | if (waiting_ms > 1) Sleep(waiting_ms - 1);
99 | do
100 | {
101 | Sleep(0);
102 | QueryPerformanceCounter(&frequency_count);
103 | long long count_delta = frequency_count.QuadPart - m_count_tick;
104 | delta_time = static_cast(count_delta) / m_count_per_second;
105 | } while (delta_time < sync_period);
106 | }
107 |
108 | Tick();
109 | }
110 |
111 | float HRTimer::GetTime() const
112 | {
113 | LARGE_INTEGER frequency_count;
114 | QueryPerformanceCounter(&frequency_count);
115 | return static_cast(frequency_count.QuadPart - m_count_start) / m_count_per_second;
116 | }
117 |
118 | float HRTimer::GetDeltaTime() const
119 | {
120 | return static_cast(m_count_delta) / m_count_per_second;
121 | }
122 |
123 | float HRTimer::GetCPUDeltaTime() const
124 | {
125 | return static_cast(m_count_delta_busy) / m_count_per_second;
126 | }
127 |
128 | float HRTimer::GetGPUDeltaTime() const
129 | {
130 | return static_cast(m_count_delta_gpu) / m_count_per_second_gpu;
131 | }
132 |
133 | void HRTimer::BeginGPUTimming()
134 | {
135 | if (m_query_number == gpu_query_buffer_size)
136 | {
137 | m_query_skipped = true;
138 | return;
139 | }
140 |
141 | m_query_skipped = false;
142 | D3DApp::GetD3D11DeviceContext()->Begin(m_query_timestamp_disjoint[m_query_idx]);
143 | D3DApp::GetD3D11DeviceContext()->End(m_query_timestamp_start[m_query_idx]);
144 | }
145 |
146 | void HRTimer::EndGPUTimming()
147 | {
148 | if (!m_query_skipped)
149 | {
150 | D3DApp::GetD3D11DeviceContext()->End(m_query_timestamp_end[m_query_idx]);
151 | D3DApp::GetD3D11DeviceContext()->End(m_query_timestamp_disjoint[m_query_idx]);
152 | m_query_idx = (m_query_idx + 1) % gpu_query_buffer_size;
153 | m_query_number += 1;
154 | }
155 |
156 | int feeded = 0;
157 | for (; feeded != m_query_number; ++feeded)
158 | {
159 | int read_idx = (m_query_idx - m_query_number + feeded + gpu_query_buffer_size) % gpu_query_buffer_size;
160 |
161 | UINT64 timestamp_start;
162 | UINT64 timestamp_end;
163 | D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timestamp_disjoint;
164 |
165 | bool query_complete = true;
166 | query_complete &= D3DApp::GetD3D11DeviceContext()->GetData(
167 | m_query_timestamp_start[read_idx], ×tamp_start, sizeof(timestamp_start), 0) == S_OK;
168 | query_complete &= D3DApp::GetD3D11DeviceContext()->GetData(
169 | m_query_timestamp_end[read_idx], ×tamp_end, sizeof(timestamp_end), 0) == S_OK;
170 | query_complete &= D3DApp::GetD3D11DeviceContext()->GetData(
171 | m_query_timestamp_disjoint[read_idx], ×tamp_disjoint, sizeof(timestamp_disjoint), 0) == S_OK;
172 |
173 | if (!query_complete) break;
174 |
175 | if (!timestamp_disjoint.Disjoint)
176 | {
177 | m_count_per_second_gpu = timestamp_disjoint.Frequency;
178 | m_count_delta_gpu = timestamp_end - timestamp_start;
179 | }
180 | }
181 | m_query_number -= feeded;
182 | }
183 |
184 | void HRTimer::RemoveEvent(const tstring& tag)
185 | {
186 | for (auto it = m_timer_events.begin(); it != m_timer_events.end();)
187 | {
188 | if (it->tag == tag) it = m_timer_events.erase(it);
189 | else ++it;
190 | }
191 | }
192 |
193 | void HRTimer::TickTimerEvents(float delta_time)
194 | {
195 | for (auto it = m_timer_events.begin(); it != m_timer_events.end();)
196 | {
197 | it->cur_time += delta_time;
198 | if (it->cur_time > it->tot_time)
199 | {
200 | // issue callback
201 | (it->callback)(it->cur_count, it->tag);
202 | it->cur_time = 0;
203 | if (++(it->cur_count) == it->tot_count)
204 | {
205 | it = m_timer_events.erase(it);
206 | continue;
207 | }
208 | }
209 | ++it;
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/hr_timer.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _HR_TIMER_HPP_INCLUDED_
2 | #define _HR_TIMER_HPP_INCLUDED_
3 |
4 | #include
5 | #include
6 |
7 | typedef boost::function TimerEventCallBack;
8 |
9 | static const int gpu_query_buffer_size = 4;
10 |
11 | class HRTimer
12 | {
13 | struct TimerEvent
14 | {
15 | tstring tag;
16 | int cur_count;
17 | int tot_count;
18 | float cur_time;
19 | float tot_time;
20 | TimerEventCallBack callback;
21 | };
22 |
23 | public:
24 | HRTimer();
25 | ~HRTimer();
26 |
27 | public:
28 | void Start();
29 | void Tick();
30 | void SyncTick(float sync_period);
31 |
32 | float GetTime() const;
33 | float GetDeltaTime() const;
34 | float GetCPUDeltaTime() const;
35 |
36 | void BeginGPUTimming();
37 | void EndGPUTimming();
38 | float GetGPUDeltaTime() const;
39 |
40 | template
41 | void AddEvent(float interval, Func callback, const tstring& tag = TEXT(""), int tot_cnt = 0)
42 | {
43 | TimerEvent evt = {
44 | tag,
45 | 0,
46 | tot_cnt,
47 | 0,
48 | interval,
49 | TimerEventCallBack(callback)
50 | };
51 | m_timer_events.push_back(evt);
52 | }
53 |
54 | void RemoveEvent(const tstring& tag);
55 |
56 | private:
57 | void TickTimerEvents(float delta_time);
58 |
59 | private:
60 | long long m_count_start;
61 | long long m_count_tick;
62 | long long m_count_delta;
63 | long long m_count_delta_busy;
64 | long long m_count_per_second;
65 |
66 | long long m_count_delta_gpu;
67 | long long m_count_per_second_gpu;
68 |
69 | ID3D11Query *m_query_timestamp_start[gpu_query_buffer_size];
70 | ID3D11Query *m_query_timestamp_end[gpu_query_buffer_size];
71 | ID3D11Query *m_query_timestamp_disjoint[gpu_query_buffer_size];
72 | int m_query_idx;
73 | int m_query_number;
74 | bool m_query_skipped;
75 |
76 | bool m_first_tick;
77 | std::list m_timer_events;
78 | };
79 |
80 | #endif // _HR_TIMER_HPP_INCLUDED_
--------------------------------------------------------------------------------
/src/keywords.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _KEYWORDS_INCLUDED_HPP_
2 | #define _KEYWORDS_INCLUDED_HPP_
3 |
4 | #include
5 | #include
6 |
7 | #define MAKE_SUFFIX_1D(_, i, s) L#s##L#i,
8 | #define MAKE_SUFFIX_2D_1(_, j, s) L#s##L"1"##L"x"##L#j,
9 | #define MAKE_SUFFIX_2D_2(_, j, s) L#s##L"2"##L"x"##L#j,
10 | #define MAKE_SUFFIX_2D_3(_, j, s) L#s##L"3"##L"x"##L#j,
11 | #define MAKE_SUFFIX_2D_4(_, j, s) L#s##L"4"##L"x"##L#j,
12 |
13 | #define DECLARE_TYPE_1D(type) \
14 | L###type, BOOST_PP_REPEAT_FROM_TO(2, 5, MAKE_SUFFIX_1D, type)
15 |
16 | #define DECLARE_TYPE_2D(type) \
17 | BOOST_PP_REPEAT_FROM_TO(1, 5, MAKE_SUFFIX_2D_1, type) \
18 | BOOST_PP_REPEAT_FROM_TO(1, 5, MAKE_SUFFIX_2D_2, type) \
19 | BOOST_PP_REPEAT_FROM_TO(1, 5, MAKE_SUFFIX_2D_3, type) \
20 | BOOST_PP_REPEAT_FROM_TO(1, 5, MAKE_SUFFIX_2D_4, type)
21 |
22 | #define DECLARE_SEMANTIC(semantic, n) \
23 | L###semantic, BOOST_PP_REPEAT(n, MAKE_SUFFIX_1D, semantic)
24 |
25 | static const std::wstring kewords[] =
26 | {
27 | DECLARE_TYPE_1D(bool)
28 | DECLARE_TYPE_1D(int)
29 | DECLARE_TYPE_1D(half)
30 | DECLARE_TYPE_1D(float)
31 | DECLARE_TYPE_2D(float)
32 | L"blendstate", L"break", L"buffer",
33 | L"cbuffer", L"class", L"compile", L"const", L"continue",
34 | L"depthstencilstate", L"depthstencilview", L"discard", L"do", L"double", L"define",
35 | L"else", L"extern", L"endif",
36 | L"false", L"for",
37 | L"geometryshader",
38 | L"if", L"in", L"inline", L"ifdef", L"ifndef", L"inout", L"interface",
39 | L"matrix",
40 | L"namespace", L"nointerpolation",
41 | L"out",
42 | L"pass", L"pixelshader", L"precise",
43 | L"rasterizerstate", L"rendertargetview", L"return", L"register",
44 | L"sampler", L"sampler1D", L"sampler2D", L"sampler3D", L"samplerCUBE", L"SamplerState", L"SamplerComparisonState", L"shared", L"stateblock", L"stateblock_state", L"static", L"string", L"struct", L"switch",
45 | L"tbuffer", L"technique", L"technique10", L"texture", L"Texture1D", L"Texture1DArray", L"Texture2D", L"Texture2DArray", L"Texture2DMS", L"Texture2DMSArray", L"Texture3D", L"TextureCube", L"TextureCubeArray", L"true", L"typedef",
46 | L"uniform",
47 | L"vector", L"vertexshader", L"void", L"volatile", L"while",
48 | };
49 |
50 | static const std::wstring semantics[] =
51 | {
52 | DECLARE_SEMANTIC(binormal, 12)
53 | DECLARE_SEMANTIC(blendindices, 12)
54 | DECLARE_SEMANTIC(blendweight, 12)
55 | DECLARE_SEMANTIC(color, 16)
56 | DECLARE_SEMANTIC(depth, 16)
57 | DECLARE_SEMANTIC(normal, 12)
58 | DECLARE_SEMANTIC(position, 12)
59 | DECLARE_SEMANTIC(positiont, 0)
60 | DECLARE_SEMANTIC(psize, 12)
61 | DECLARE_SEMANTIC(tangent, 12)
62 | DECLARE_SEMANTIC(texcoord, 16)
63 | DECLARE_SEMANTIC(color, 16)
64 | DECLARE_SEMANTIC(fog, 0)
65 | DECLARE_SEMANTIC(tessfactor, 12)
66 | DECLARE_SEMANTIC(vface, 0)
67 | DECLARE_SEMANTIC(vpos, 0)
68 | DECLARE_SEMANTIC(sv_clipdistance, 8)
69 | DECLARE_SEMANTIC(sv_culldistance, 8)
70 | DECLARE_SEMANTIC(sv_coverage, 0)
71 | DECLARE_SEMANTIC(sv_depth, 0)
72 | DECLARE_SEMANTIC(sv_dispatchthreadid, 0)
73 | DECLARE_SEMANTIC(sv_domainlocation, 0)
74 | DECLARE_SEMANTIC(sv_groupid, 0)
75 | DECLARE_SEMANTIC(sv_groupindex, 0)
76 | DECLARE_SEMANTIC(sv_groupthreadid, 0)
77 | DECLARE_SEMANTIC(sv_gsinstanceid, 0)
78 | DECLARE_SEMANTIC(sv_insidetessfactor, 0)
79 | DECLARE_SEMANTIC(sv_isfrontface, 0)
80 | DECLARE_SEMANTIC(sv_position, 0)
81 | DECLARE_SEMANTIC(sv_rendertargetarrayindex, 0)
82 | DECLARE_SEMANTIC(sv_sampleindex, 0)
83 | DECLARE_SEMANTIC(sv_target, 8)
84 | DECLARE_SEMANTIC(sv_tessfactor, 0)
85 | DECLARE_SEMANTIC(sv_viewportarrayindex, 0)
86 | DECLARE_SEMANTIC(sv_instanceid, 0)
87 | DECLARE_SEMANTIC(sv_primitiveid, 0)
88 | DECLARE_SEMANTIC(sv_vertexid, 0)
89 | };
90 |
91 | static const std::wstring global_funcs[] =
92 | {
93 | L"abs",
94 | L"acos",
95 | L"all",
96 | L"AllMemoryBarrier",
97 | L"AllMemoryBarrierWithGroupSync",
98 | L"any",
99 | L"asdouble",
100 | L"asfloat",
101 | L"asfloat",
102 | L"asin",
103 | L"asint",
104 | L"asint",
105 | L"asuint",
106 | L"asuint",
107 | L"atan",
108 | L"atan2",
109 | L"ceil",
110 | L"clamp",
111 | L"clip",
112 | L"cos",
113 | L"cosh",
114 | L"countbits",
115 | L"cross",
116 | L"D3DCOLORtoUBYTE4",
117 | L"ddx",
118 | L"ddx_coarse",
119 | L"ddx_fine",
120 | L"ddy",
121 | L"ddy_coarse",
122 | L"ddy_fine",
123 | L"degrees",
124 | L"determinant",
125 | L"DeviceMemoryBarrier",
126 | L"DeviceMemoryBarrierWithGroupSync",
127 | L"distance",
128 | L"dot",
129 | L"dst",
130 | L"EvaluateAttributeAtCentroid",
131 | L"EvaluateAttributeAtSample",
132 | L"EvaluateAttributeSnapped",
133 | L"exp",
134 | L"exp2",
135 | L"f16tof32",
136 | L"f32tof16",
137 | L"faceforward",
138 | L"firstbithigh",
139 | L"firstbitlow",
140 | L"floor",
141 | L"fmod",
142 | L"frac",
143 | L"frexp",
144 | L"fwidth",
145 | L"GetRenderTargetSampleCount",
146 | L"GetRenderTargetSamplePosition",
147 | L"GroupMemoryBarrier",
148 | L"GroupMemoryBarrierWithGroupSync",
149 | L"InterlockedAdd",
150 | L"InterlockedAnd",
151 | L"InterlockedCompareExchange",
152 | L"InterlockedCompareStore",
153 | L"InterlockedExchange",
154 | L"InterlockedMax",
155 | L"InterlockedMin",
156 | L"InterlockedOr",
157 | L"InterlockedXor",
158 | L"isfinite",
159 | L"isinf",
160 | L"isnan",
161 | L"ldexp",
162 | L"length",
163 | L"lerp",
164 | L"lit",
165 | L"log",
166 | L"log10",
167 | L"log2",
168 | L"mad",
169 | L"max",
170 | L"min",
171 | L"modf",
172 | L"mul",
173 | L"noise",
174 | L"normalize",
175 | L"pow",
176 | L"Process2DQuadTessFactorsAvg",
177 | L"Process2DQuadTessFactorsMax",
178 | L"Process2DQuadTessFactorsMin",
179 | L"ProcessIsolineTessFactors",
180 | L"ProcessQuadTessFactorsAvg",
181 | L"ProcessQuadTessFactorsMax",
182 | L"ProcessQuadTessFactorsMin",
183 | L"ProcessTriTessFactorsAvg",
184 | L"ProcessTriTessFactorsMax",
185 | L"ProcessTriTessFactorsMin",
186 | L"radians",
187 | L"rcp",
188 | L"reflect",
189 | L"refract",
190 | L"reversebits",
191 | L"round",
192 | L"rsqrt",
193 | L"saturate",
194 | L"sign",
195 | L"sin",
196 | L"sincos",
197 | L"sinh",
198 | L"smoothstep",
199 | L"sqrt",
200 | L"step",
201 | L"tan",
202 | L"tanh",
203 | L"tex1D",
204 | L"tex1D",
205 | L"tex1Dbias",
206 | L"tex1Dgrad",
207 | L"tex1Dlod",
208 | L"tex1Dproj",
209 | L"tex2D",
210 | L"tex2D",
211 | L"tex2Dbias",
212 | L"tex2Dgrad",
213 | L"tex2Dlod",
214 | L"tex2Dproj",
215 | L"tex3D",
216 | L"tex3D",
217 | L"tex3Dbias",
218 | L"tex3Dgrad",
219 | L"tex3Dlod",
220 | L"tex3Dproj",
221 | L"texCUBE",
222 | L"texCUBE",
223 | L"texCUBEbias",
224 | L"texCUBEgrad",
225 | L"texCUBElod",
226 | L"texCUBEproj",
227 | L"transpose",
228 | L"trunc",
229 | };
230 |
231 | static const std::wstring extend_funcs[] =
232 | {
233 | L"snoise",
234 | L"qnoise",
235 | };
236 |
237 | static const std::wstring member_funcs[] =
238 | {
239 | L"Append",
240 | L"RestartStrip",
241 | L"CalculateLevelOfDetail",
242 | L"CalculateLevelOfDetailUnclamped",
243 | L"Gather",
244 | L"GetDimensions",
245 | L"GetSamplePosition",
246 | L"Load",
247 | L"Sample",
248 | L"SampleBias",
249 | L"SampleCmp",
250 | L"SampleCmpLevelZero",
251 | L"SampleGrad",
252 | L"SampleLevel",
253 | };
254 |
255 | #undef MAKE_SUFFIX_1D
256 | #undef MAKE_SUFFIX_2D_1
257 | #undef MAKE_SUFFIX_2D_2
258 | #undef MAKE_SUFFIX_2D_3
259 | #undef MAKE_SUFFIX_2D_4
260 | #undef DECLARE_TYPE_1D
261 | #undef DECLARE_TYPE_2D
262 | #undef DECLARE_SEMANTIC
263 |
264 | #endif // _KEYWORDS_INCLUDED_HPP_
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 | #include "d3d_app.hpp"
3 |
4 | const int width = 1280;
5 | const int height = 768;
6 |
7 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShow)
8 | {
9 | D3DApp *app = D3DApp::GetApp();
10 | if (app->Initialize(hInstance, width, height)) {
11 | app->Run();
12 | }
13 | app->Destroy();
14 | }
15 |
--------------------------------------------------------------------------------
/src/post_process.cpp:
--------------------------------------------------------------------------------
1 | #include "common.hpp"
2 | #include "post_process.hpp"
3 | #include "d3d_app.hpp"
4 |
5 | #include
6 |
7 | //////////////////////////////////////////////////////////////////////////
8 | // constructor / destructor
9 | //////////////////////////////////////////////////////////////////////////
10 | PostProcess::PostProcess(bool blend_enable /* = false */)
11 | : m_vertex_buffer(NULL)
12 | , m_index_buffer(NULL)
13 | , m_vertex_shader(NULL)
14 | , m_pixel_shader(NULL)
15 | , m_vertex_layout(NULL)
16 | , m_raster_state(NULL)
17 | , m_blend_state(NULL)
18 | , m_sampler_state(NULL)
19 | , m_depth_stencil_state(NULL)
20 | {
21 | InitVertexBuffer();
22 | InitIndexBuffer();
23 | InitVertexShader();
24 |
25 | InitRasterState();
26 | InitBlendState(blend_enable);
27 | InitSamplerState();
28 |
29 | LoadPixelShaderFromFile(TEXT("pp_common.hlsl"), TEXT("ps_main"));
30 | }
31 |
32 | PostProcess::~PostProcess()
33 | {
34 | SAFE_RELEASE(m_vertex_buffer);
35 | SAFE_RELEASE(m_index_buffer);
36 | SAFE_RELEASE(m_vertex_shader);
37 | SAFE_RELEASE(m_pixel_shader);
38 | SAFE_RELEASE(m_vertex_layout);
39 | SAFE_RELEASE(m_raster_state);
40 | SAFE_RELEASE(m_blend_state);
41 | SAFE_RELEASE(m_sampler_state);
42 | SAFE_RELEASE(m_depth_stencil_state);
43 | }
44 |
45 | //////////////////////////////////////////////////////////////////////////
46 | // public interfaces
47 | //////////////////////////////////////////////////////////////////////////
48 | void PostProcess::Apply() const
49 | {
50 | UINT stride = sizeof(Vertex);
51 | UINT offset = 0;
52 | D3DApp::GetD3D11DeviceContext()->IASetVertexBuffers(0, 1, &m_vertex_buffer, &stride, &offset);
53 | D3DApp::GetD3D11DeviceContext()->IASetIndexBuffer(m_index_buffer, DXGI_FORMAT_R32_UINT, 0);
54 |
55 | D3DApp::GetD3D11DeviceContext()->IASetInputLayout(m_vertex_layout);
56 | D3DApp::GetD3D11DeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
57 |
58 | ID3D11RenderTargetView* rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {NULL};
59 | for each(auto &it in m_output_pins) {rtvs[it.first] = it.second;}
60 | D3DApp::GetD3D11DeviceContext()->OMSetRenderTargets(ARRAYSIZE(rtvs), rtvs, NULL);
61 |
62 | ID3D11ShaderResourceView* srvs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {NULL};
63 | for each(auto &it in m_input_pins)
64 | {
65 | srvs[it.first] = it.second;
66 | }
67 | D3DApp::GetD3D11DeviceContext()->PSSetShaderResources(0, ARRAYSIZE(srvs), srvs);
68 | D3DApp::GetD3D11DeviceContext()->PSSetSamplers(0, 1, &m_sampler_state);
69 |
70 | D3DApp::GetD3D11DeviceContext()->RSSetState(m_raster_state);
71 | D3DApp::GetD3D11DeviceContext()->OMSetBlendState(m_blend_state, NULL, 0xFFFFFFFF);
72 | D3DApp::GetD3D11DeviceContext()->OMSetDepthStencilState(m_depth_stencil_state, 0);
73 |
74 | D3DApp::GetD3D11DeviceContext()->VSSetShader(m_vertex_shader, NULL, 0);
75 | D3DApp::GetD3D11DeviceContext()->GSSetShader(NULL, NULL, 0);
76 | D3DApp::GetD3D11DeviceContext()->PSSetShader(m_pixel_shader, NULL, 0);
77 | D3DApp::GetD3D11DeviceContext()->DrawIndexed(6, 0, 0);
78 | }
79 |
80 | void PostProcess::InputPin(int slot, ID3D11ShaderResourceView* srv)
81 | {
82 | m_input_pins[slot] = srv;
83 | }
84 |
85 | void PostProcess::OutputPin(int slot, ID3D11RenderTargetView* rtv)
86 | {
87 | m_output_pins[slot] = rtv;
88 | }
89 |
90 | void PostProcess::SetParameters(int slot, ID3D11Buffer* cbuffer)
91 | {
92 | D3DApp::GetD3D11DeviceContext()->PSSetConstantBuffers(slot, 1, &cbuffer);
93 | }
94 |
95 | bool PostProcess::LoadPixelShaderFromFile(const tstring& file_name, const tstring& entry_point)
96 | {
97 | tstring file_path = TEXT("fx/") + file_name;
98 | ID3DBlob* error_buffer = NULL;
99 | ID3DBlob* pixel_shader_buffer = NULL;
100 | ID3D11PixelShader* pixel_shader = NULL;
101 |
102 | HRESULT hr = D3DX11CompileFromFile(
103 | file_path.c_str(),
104 | NULL,
105 | NULL,
106 | to_string(entry_point).c_str(),
107 | "ps_4_0",
108 | D3D10_SHADER_DEBUG,
109 | 0,
110 | NULL,
111 | &pixel_shader_buffer,
112 | &error_buffer,
113 | NULL);
114 |
115 | if (FAILED(hr))
116 | {
117 | if (error_buffer != NULL)
118 | {
119 | std::string error_message = static_cast(error_buffer->GetBufferPointer());
120 | m_error_message = to_tstring(error_message);
121 | }
122 | SAFE_RELEASE(pixel_shader_buffer);
123 | SAFE_RELEASE(error_buffer);
124 | return false;
125 | }
126 |
127 | hr = D3DApp::GetD3D11Device()->CreatePixelShader(
128 | pixel_shader_buffer->GetBufferPointer(),
129 | pixel_shader_buffer->GetBufferSize(),
130 | NULL,
131 | &pixel_shader);
132 |
133 | if (FAILED(hr))
134 | {
135 | m_error_message = TEXT("create pixel shader failed.");
136 | SAFE_RELEASE(pixel_shader_buffer);
137 | SAFE_RELEASE(error_buffer);
138 | return false;
139 | }
140 |
141 | SAFE_RELEASE(m_pixel_shader);
142 | m_pixel_shader = pixel_shader;
143 | SAFE_RELEASE(pixel_shader_buffer);
144 | SAFE_RELEASE(error_buffer);
145 | return true;
146 | }
147 |
148 | bool PostProcess::LoadPixelShaderFromMemory(const tstring& shader_content, const tstring& entry_point)
149 | {
150 | ID3DBlob* error_buffer = NULL;
151 | ID3DBlob* pixel_shader_buffer = NULL;
152 | ID3D11PixelShader* pixel_shader = NULL;
153 |
154 | std::string shader_content_str = to_string(shader_content);
155 | HRESULT hr = D3DX11CompileFromMemory(
156 | shader_content_str.c_str(),
157 | shader_content_str.length(),
158 | NULL,
159 | NULL,
160 | NULL,
161 | to_string(entry_point).c_str(),
162 | "ps_4_0",
163 | D3D10_SHADER_DEBUG,
164 | 0,
165 | NULL,
166 | &pixel_shader_buffer,
167 | &error_buffer,
168 | NULL);
169 |
170 | if (FAILED(hr))
171 | {
172 | if (error_buffer != NULL)
173 | {
174 | std::string error_message = static_cast(error_buffer->GetBufferPointer());
175 | m_error_message = to_tstring(error_message);
176 | }
177 | SAFE_RELEASE(pixel_shader_buffer);
178 | SAFE_RELEASE(error_buffer);
179 | return false;
180 | }
181 |
182 | hr = D3DApp::GetD3D11Device()->CreatePixelShader(
183 | pixel_shader_buffer->GetBufferPointer(),
184 | pixel_shader_buffer->GetBufferSize(),
185 | NULL,
186 | &pixel_shader);
187 |
188 | if (FAILED(hr))
189 | {
190 | m_error_message = TEXT("create pixel shader failed.");
191 | SAFE_RELEASE(pixel_shader_buffer);
192 | SAFE_RELEASE(error_buffer);
193 | return false;
194 | }
195 |
196 | SAFE_RELEASE(m_pixel_shader);
197 | m_pixel_shader = pixel_shader;
198 | SAFE_RELEASE(pixel_shader_buffer);
199 | SAFE_RELEASE(error_buffer);
200 | return true;
201 | }
202 |
203 | tstring PostProcess::GetErrorMessage() const
204 | {
205 | return m_error_message;
206 | }
207 |
208 | //////////////////////////////////////////////////////////////////////////
209 | // private subroutines
210 | //////////////////////////////////////////////////////////////////////////
211 | void PostProcess::InitVertexBuffer()
212 | {
213 | Vertex vertices[] = {
214 | {float3(-1.0f, -1.0f, 0.0f), float2(0.0f, 1.0f)},
215 | {float3(-1.0f, 1.0f, 0.0f), float2(0.0f, 0.0f)},
216 | {float3( 1.0f, 1.0f, 0.0f), float2(1.0f, 0.0f)},
217 | {float3( 1.0f, -1.0f, 0.0f), float2(1.0f, 1.0f)},
218 | };
219 |
220 | D3D11_BUFFER_DESC vertex_buffer_desc;
221 | ZeroMemory(&vertex_buffer_desc, sizeof(vertex_buffer_desc));
222 | vertex_buffer_desc.Usage = D3D11_USAGE_DEFAULT;1,
223 | vertex_buffer_desc.ByteWidth = sizeof(vertices);
224 | vertex_buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
225 | vertex_buffer_desc.CPUAccessFlags = 0;
226 | vertex_buffer_desc.MiscFlags = 0;
227 |
228 | D3D11_SUBRESOURCE_DATA vertices_data;
229 | ZeroMemory(&vertices_data, sizeof(vertices_data));
230 | vertices_data.pSysMem = vertices;
231 | D3DApp::GetD3D11Device()->CreateBuffer(&vertex_buffer_desc, &vertices_data, &m_vertex_buffer);
232 | }
233 |
234 | void PostProcess::InitIndexBuffer()
235 | {
236 | unsigned int indices[] = {
237 | 0, 1, 2,
238 | 0, 2, 3,
239 | };
240 |
241 | D3D11_BUFFER_DESC index_buffer_desc;
242 | ZeroMemory(&index_buffer_desc, sizeof(index_buffer_desc));
243 | index_buffer_desc.Usage = D3D11_USAGE_DEFAULT;
244 | index_buffer_desc.ByteWidth = sizeof(indices);
245 | index_buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
246 | index_buffer_desc.CPUAccessFlags = 0;
247 | index_buffer_desc.MiscFlags = 0;
248 |
249 | D3D11_SUBRESOURCE_DATA indices_data;
250 | ZeroMemory(&indices_data, sizeof(indices_data));
251 | indices_data.pSysMem = indices;
252 | D3DApp::GetD3D11Device()->CreateBuffer(&index_buffer_desc, &indices_data, &m_index_buffer);
253 | }
254 |
255 | void PostProcess::InitVertexShader()
256 | {
257 | ID3DBlob *vertex_shader_buffer = NULL;
258 | D3DX11CompileFromFile(
259 | TEXT("fx/pp_common.hlsl"),
260 | NULL,
261 | NULL,
262 | "vs_main",
263 | "vs_4_0",
264 | 0,
265 | 0,
266 | NULL,
267 | &vertex_shader_buffer,
268 | NULL,
269 | NULL);
270 |
271 | D3DApp::GetD3D11Device()->CreateVertexShader(
272 | vertex_shader_buffer->GetBufferPointer(),
273 | vertex_shader_buffer->GetBufferSize(),
274 | NULL,
275 | &m_vertex_shader);
276 |
277 | // create vertex layout
278 | D3D11_INPUT_ELEMENT_DESC layout[] = {
279 | {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
280 | {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
281 | };
282 | UINT num_elements = ARRAYSIZE(layout);
283 | D3DApp::GetD3D11Device()->CreateInputLayout(
284 | layout,
285 | num_elements,
286 | vertex_shader_buffer->GetBufferPointer(),
287 | vertex_shader_buffer->GetBufferSize(),
288 | &m_vertex_layout);
289 |
290 | SAFE_RELEASE(vertex_shader_buffer);
291 | }
292 |
293 | void PostProcess::InitRasterState()
294 | {
295 | CD3D11_RASTERIZER_DESC raster_state_desc(D3D11_DEFAULT);
296 | raster_state_desc.CullMode = D3D11_CULL_NONE;
297 | raster_state_desc.DepthClipEnable = false;
298 | D3DApp::GetD3D11Device()->CreateRasterizerState(&raster_state_desc, &m_raster_state);
299 | }
300 |
301 | void PostProcess::InitBlendState(bool blend_enable)
302 | {
303 | D3D11_BLEND_DESC blend_desc;
304 | D3D11_RENDER_TARGET_BLEND_DESC target_blend_desc;
305 | target_blend_desc.BlendEnable = blend_enable;
306 | target_blend_desc.SrcBlend = D3D11_BLEND_SRC_ALPHA;
307 | target_blend_desc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
308 | target_blend_desc.BlendOp = D3D11_BLEND_OP_ADD;
309 | target_blend_desc.SrcBlendAlpha = D3D11_BLEND_ONE;
310 | target_blend_desc.DestBlendAlpha = D3D11_BLEND_ZERO;
311 | target_blend_desc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
312 | target_blend_desc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
313 |
314 | blend_desc.AlphaToCoverageEnable = false;
315 | blend_desc.IndependentBlendEnable = false;
316 | blend_desc.RenderTarget[0] = target_blend_desc;
317 | D3DApp::GetD3D11Device()->CreateBlendState(&blend_desc, &m_blend_state);
318 | }
319 |
320 | void PostProcess::InitSamplerState()
321 | {
322 | CD3D11_SAMPLER_DESC sampler_desc(D3D11_DEFAULT);
323 | sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
324 | sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
325 | sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
326 | D3DApp::GetD3D11Device()->CreateSamplerState(&sampler_desc, &m_sampler_state);
327 | }
328 |
329 | void PostProcess::InitDepthStencilState()
330 | {
331 | CD3D11_DEPTH_STENCIL_DESC ds_desc(D3D11_DEFAULT);
332 | ds_desc.DepthEnable = FALSE;
333 | D3DApp::GetD3D11Device()->CreateDepthStencilState(&ds_desc, &m_depth_stencil_state);
334 | }
335 |
--------------------------------------------------------------------------------
/src/post_process.hpp:
--------------------------------------------------------------------------------
1 | #ifndef _POST_PROCESS_INCLUDED_HPP_
2 | #define _POST_PROCESS_INCLUDED_HPP_
3 |
4 | #include