1 /**************************************************************************
2 *
3 * Copyright 2010 Luca Barbieri
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 **************************************************************************/
26
27 #define _USE_MATH_DEFINES
28 #include "d3d11app.h"
29 #include "d3d11spikysphere.hlsl.vs.h"
30 #include "d3d11spikysphere.hlsl.hs.h"
31 #include "d3d11spikysphere.hlsl.ds.h"
32 #include "d3d11spikysphere.hlsl.ps.h"
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <float.h>
38 #include <D3DX10math.h>
39
40 struct cb_frame_t
41 {
42 D3DXMATRIX model;
43 D3DXMATRIX view_proj;
44 float disp_scale;
45 float disp_freq;
46 float tess_factor;
47 };
48
49 static float vertex_data[] =
50 {
51 1.0, 0.0, 0.0,
52 0.0, 1.0, 0.0,
53 0.0, 0.0, 1.0,
54
55 0.0, 1.0, 0.0,
56 -1.0, 0.0, 0.0,
57 0.0, 0.0, 1.0,
58
59 0.0, -1.0, 0.0,
60 1.0, 0.0, 0.0,
61 0.0, 0.0, 1.0,
62
63 -1.0, 0.0, 0.0,
64 0.0, -1.0, 0.0,
65 0.0, 0.0, 1.0,
66
67 0.0, 1.0, 0.0,
68 1.0, 0.0, 0.0,
69 0.0, 0.0, -1.0,
70
71 -1.0, 0.0, 0.0,
72 0.0, 1.0, 0.0,
73 0.0, 0.0, -1.0,
74
75 1.0, 0.0, 0.0,
76 0.0, -1.0, 0.0,
77 0.0, 0.0, -1.0,
78
79 0.0, -1.0, 0.0,
80 -1.0, 0.0, 0.0,
81 0.0, 0.0, -1.0,
82 };
83
84 struct d3d11spikysphere : public d3d11_application
85 {
86 ID3D11Device* dev;
87 ID3D11PixelShader* ps;
88 ID3D11DomainShader* ds;
89 ID3D11HullShader* hs;
90 ID3D11VertexShader* vs;
91 ID3D11InputLayout* layout;
92 ID3D11Buffer* vb;
93 ID3D11RenderTargetView* rtv;
94 ID3D11DepthStencilView* zsv;
95 ID3D11Buffer* cb_frame;
96
97 int cur_width;
98 int cur_height;
99
d3d11spikysphered3d11spikysphere100 d3d11spikysphere()
101 : cur_width(-1), cur_height(-1), zsv(0)
102 {}
103
initd3d11spikysphere104 bool init(ID3D11Device* dev, int argc, char** argv)
105 {
106 this->dev = dev;
107 ensure(dev->CreateVertexShader(g_vs, sizeof(g_vs), NULL, &vs));
108 ensure(dev->CreateHullShader(g_hs, sizeof(g_hs), NULL, &hs));
109 ensure(dev->CreateDomainShader(g_ds, sizeof(g_ds), NULL, &ds));
110 ensure(dev->CreatePixelShader(g_ps, sizeof(g_ps), NULL, &ps));
111
112 D3D11_INPUT_ELEMENT_DESC elements[1] =
113 {
114 {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,
115 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
116 };
117
118 ensure(dev->CreateInputLayout(elements, 1, g_vs, sizeof(g_vs), &layout));
119
120 D3D11_BUFFER_DESC bufferd;
121 bufferd.ByteWidth = sizeof(vertex_data);
122 bufferd.Usage = D3D11_USAGE_IMMUTABLE;
123 bufferd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
124 bufferd.CPUAccessFlags = 0;
125 bufferd.MiscFlags = 0;
126 bufferd.StructureByteStride = 0;
127
128 D3D11_SUBRESOURCE_DATA buffersd;
129 buffersd.pSysMem = vertex_data;
130
131 ensure(dev->CreateBuffer(&bufferd, &buffersd, &vb));
132
133 D3D11_BUFFER_DESC cbd;
134 cbd.ByteWidth = (sizeof(cb_frame_t) + 15) & ~15;
135 cbd.Usage = D3D11_USAGE_DYNAMIC;
136 cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
137 cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
138 cbd.MiscFlags = 0;
139 cbd.StructureByteStride = 0;
140
141 ensure(dev->CreateBuffer(&cbd, NULL, &cb_frame));
142 return true;
143 }
144
drawd3d11spikysphere145 void draw(ID3D11DeviceContext* ctx, ID3D11RenderTargetView* rtv, unsigned width, unsigned height, double time)
146 {
147 D3D11_VIEWPORT vp;
148 memset(&vp, 0, sizeof(vp));
149 vp.Width = (float)width;
150 vp.Height = (float)height;
151 vp.MaxDepth = 1.0f;
152
153 if(width != cur_width || height != cur_height)
154 {
155 if(zsv)
156 zsv->Release();
157 ID3D11Texture2D* zsbuf;
158 D3D11_TEXTURE2D_DESC zsbufd;
159 memset(&zsbufd, 0, sizeof(zsbufd));
160 zsbufd.Width = width;
161 zsbufd.Height = height;
162 zsbufd.Format = DXGI_FORMAT_D32_FLOAT;
163 zsbufd.ArraySize = 1;
164 zsbufd.MipLevels = 1;
165 zsbufd.SampleDesc.Count = 1;
166 zsbufd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
167 ensure(dev->CreateTexture2D(&zsbufd, 0, &zsbuf));
168 ensure(dev->CreateDepthStencilView(zsbuf, 0, &zsv));
169 zsbuf->Release();
170 }
171
172 float black[4] = {0, 0, 0, 0};
173
174 D3D11_MAPPED_SUBRESOURCE map;
175 ensure(ctx->Map(cb_frame, 0, D3D11_MAP_WRITE_DISCARD, 0, &map));
176 cb_frame_t* cb_frame_data = (cb_frame_t*)map.pData;
177 D3DXMatrixIdentity(&cb_frame_data->model);
178
179 D3DXMATRIX view;
180 D3DXVECTOR3 eye(2.0f * (float)sin(time), 0.0f, 2.0f * (float)cos(time));
181 D3DXVECTOR3 at(0, 0, 0);
182 D3DXVECTOR3 up(0, 1, 0);
183 D3DXMatrixLookAtLH(&view, &eye, &at, &up);
184 D3DXMATRIX proj;
185 D3DXMatrixPerspectiveLH(&proj, 1.1f, 1.1f, 1.0f, 3.0f);
186
187 cb_frame_data->view_proj = view * proj;
188 float min_tess_factor = 1.0f;
189 cb_frame_data->tess_factor = (1.0f - (float)cos(time)) * ((64.0f - min_tess_factor) / 2.0f) + min_tess_factor;
190 cb_frame_data->disp_scale = 0.9f;
191 //cb_frame_data->disp_scale = (sin(time) + 1.0) / 2.0;
192 cb_frame_data->disp_freq = 5.0f * (float)M_PI;
193 //cb_frame_data->disp_freq = (4.0 + 4.0 * cos(time / 5.0)) * PI;
194 ctx->Unmap(cb_frame, 0);
195
196 ctx->HSSetConstantBuffers(0, 1, &cb_frame);
197 ctx->DSSetConstantBuffers(0, 1, &cb_frame);
198
199 //ctx->OMSetBlendState(bs, black, ~0);
200 //ctx->OMSetDepthStencilState(dss, 0);
201 ctx->OMSetRenderTargets(1, &rtv, zsv);
202 //ctx->RSSetState(rs);
203 ctx->RSSetViewports(1, &vp);
204
205 ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
206 ctx->IASetInputLayout(layout);
207 unsigned stride = 3 * 4;
208 unsigned offset = 0;
209 ctx->IASetVertexBuffers(0, 1, &vb, &stride, &offset);
210
211 ctx->VSSetShader(vs, NULL, 0);
212 ctx->HSSetShader(hs, NULL, 0);
213 ctx->DSSetShader(ds, NULL, 0);
214 ctx->GSSetShader(NULL, NULL, 0);
215 ctx->PSSetShader(ps, NULL, 0);
216
217 ctx->ClearRenderTargetView(rtv, black);
218 ctx->ClearDepthStencilView(zsv, D3D11_CLEAR_DEPTH, 1.0f, 0);
219
220 ctx->Draw(3 * 8, 0);
221 }
222 };
223
d3d11_application_create()224 d3d11_application* d3d11_application_create()
225 {
226 return new d3d11spikysphere();
227 }
228