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