raSystem  1.0 bata
raWater.cpp
Go to the documentation of this file.
1 #include "..\include\raMain.h"
2 
3 namespace System
4 {
5  raWater::raWater(raSmartPointer<raDirectX> dx, int width, int depth, raMaterial* pMaterial):
6  raVisual(dx)
7  {
8  m_DrawOder = 2;
9 
10  m_numMaterials = 1;
11  m_pMaterials = new raMaterial*[1];
12  m_pMaterials[0] = pMaterial;
13 
14  //Keine Subsets
15 
16  m_width = width;
17  m_depth = depth;
18 
19  m_nVertices = m_width * m_depth;
20  m_nIndices = 6 * (m_width - 1) * (m_depth - 1);
21 
22  m_curBuffNo = 0;
23 
24  for(int i = 0; i < 3;i++)
25  {
26  m_pVertices[i] = NULL;
27  }
28 
29  m_pNormals = NULL;
30  m_pTexcoords = NULL;
31 
32  m_pIndices = NULL;
33  m_pIB = NULL;
34  for(int n = 0; n < 3; n++)
35  {
36  m_pVB[n] = NULL;
37  }
38 
39  m_lastTimeStamp = 0;
40  m_lastAnimationTimeStamp = 0;
41  m_lastFrameTime = 0;
42  }
43 
45  {
46  for(int i = 0; i < 3; i++)
47  {
48  SAFE_DELETE_ARRAY(m_pVertices[i]);
49  }
50  SAFE_DELETE_ARRAY(m_pNormals);
51  SAFE_DELETE_ARRAY(m_pIndices);
52  }
53 
55  {
56  //Postion, Normale und Texcoords jetzt jeweils aus einem anderen Slot
57  //Die Offsets sind alle 0
58  D3D11_INPUT_ELEMENT_DESC layout[] =
59  {
60  { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,
61  0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
62  { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT,
63  1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
64  { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,
65  2, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
66  };
67 
68  UINT numElements = 3;
69 
70  // Create the input layout
71  D3DX11_PASS_DESC PassDesc;
73  pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
74  m_dx->GetDevice()->CreateInputLayout(layout, numElements,
75  PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize,
77 
78  return true;
79  }
80 
82  {
83  for(int i = 0; i < 3; i++)
84  {
85  m_pVertices[i] =
86  new raVector3[m_nVertices];
87  }
88  m_pNormals =
89  new raVector3[m_nVertices];
90  m_pTexcoords =
91  new raVector2[m_nVertices];
92 
93  SetupVertices();
94 
95  D3D11_BUFFER_DESC bufferDesc[3];
96  D3D11_SUBRESOURCE_DATA InitData[3];
97 
98  for(int n = 0; n < 3; n++)
99  {
100  bufferDesc[n].Usage = D3D11_USAGE_DEFAULT;
101  bufferDesc[n].BindFlags = D3D11_BIND_VERTEX_BUFFER;
102  bufferDesc[n].CPUAccessFlags = 0;
103  bufferDesc[n].MiscFlags = 0;
104 
105  InitData[n].SysMemPitch = 0;
106  InitData[n].SysMemSlicePitch = 0;
107  }
108 
109  bufferDesc[0].ByteWidth = m_nVertices * sizeof(D3DXVECTOR3);
110  InitData[0].pSysMem = m_pVertices[0];
111  m_dx->GetDevice()->CreateBuffer(&bufferDesc[0], &InitData[0], &m_pVB[0]);
112 
113  bufferDesc[1].ByteWidth = m_nVertices * sizeof(D3DXVECTOR3);
114  InitData[1].pSysMem = m_pNormals;
115  m_dx->GetDevice()->CreateBuffer(&bufferDesc[1], &InitData[1], &m_pVB[1]);
116 
117  bufferDesc[2].ByteWidth = m_nVertices * sizeof(D3DXVECTOR2);
118  InitData[2].pSysMem = m_pTexcoords;
119  m_dx->GetDevice()->CreateBuffer(&bufferDesc[2], &InitData[2], &m_pVB[2]);
120 
121  // m_pVertices und m_pNormals werden noch gebraucht
122  SAFE_DELETE_ARRAY(m_pTexcoords);
123  }
124 
126  {
127  int n = 0;
128  for (int z = 0; z < m_depth; z++)
129  {
130  for (int x = 0; x < m_width; x++)
131  {
132  for (int b = 0; b < 3; b++)
133  {
134  m_pVertices[b][n].x = (float) x - m_width / 2;
135  m_pVertices[b][n].y = 0.0f;
136  m_pVertices[b][n].z = (float) z - m_depth / 2;
137  }
138  m_pTexcoords[n].x = x / (m_width - 1.0f);
139  m_pTexcoords[n].y = z / (m_depth - 1.0f);
140  //m_pTexcoords[n].y = 1.0f - z / (m_depth - 1.0f);
141 
142  m_pNormals[n].x = 0.0f;
143  m_pNormals[n].y = 1.0f;
144  m_pNormals[n].z = 0.0f;
145 
146  n+=1;
147  }
148  }
149  }
150 
152  {
153  SetupIndices();
154 
155  D3D11_BUFFER_DESC bufferDesc;
156  bufferDesc.ByteWidth = m_nIndices * sizeof(UINT16);
157  bufferDesc.Usage = D3D11_USAGE_DEFAULT;
158  bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
159  bufferDesc.CPUAccessFlags = 0;
160  bufferDesc.MiscFlags = 0;
161 
162  D3D11_SUBRESOURCE_DATA InitData;
163  InitData.pSysMem = m_pIndices;
164  m_dx->GetDevice()->CreateBuffer( &bufferDesc, &InitData, &m_pIB);
165  }
166 
168  {
169  m_pIndices = new UINT16[m_nIndices];
170 
171  int n = 0;
172  for(int z = 0; z < m_depth - 1; z++)
173  {
174  for(int x = 0; x < m_width - 1; x++)
175  {
176  m_pIndices[n + 0] = (UINT16) (z * m_width + x);
177  m_pIndices[n + 1] = (UINT16) ((z + 1) * m_width + x);
178  m_pIndices[n + 2] = (UINT16) (z * m_width + (x + 1));
179  m_pIndices[n + 3] = (UINT16) ((z + 1) * m_width + x);
180  m_pIndices[n + 4] = (UINT16) ((z + 1) * m_width + (x + 1));
181  m_pIndices[n + 5] = (UINT16) (z * m_width + (x + 1));
182 
183  n+=6;
184  }
185  }
186  }
187 
188  bool raWater::RenderMesh(LPCSTR techniqueName)
189  {
190  raMaterial* pMaterial = m_pMaterials[0];
191  ID3DX11EffectTechnique* pTechnique = pMaterial->GetEffectTechnique(techniqueName);
192 
193  pMaterial->Setup();
194 
195  m_dx->GetImmediateContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
196 
197  UINT Strides[3];
198  UINT Offsets[3];
199 
200  Offsets[0] = 0;
201  Offsets[1] = 0;
202  Offsets[2] = 0;
203 
204  Strides[0] = sizeof(D3DXVECTOR3);
205  Strides[1] = sizeof(D3DXVECTOR3);
206  Strides[2] = sizeof(D3DXVECTOR2);
207 
208  m_dx->GetImmediateContext()->IASetVertexBuffers(0, 3, m_pVB, Strides, Offsets);
209 
210  m_dx->GetImmediateContext()->IASetIndexBuffer(m_pIB, DXGI_FORMAT_R16_UINT, 0);
211 
212  D3DX11_TECHNIQUE_DESC techDesc;
213  pTechnique->GetDesc( &techDesc );
214 
215  for(UINT p = 0; p < techDesc.Passes; ++p )
216  {
217  pTechnique->GetPassByIndex(p)->Apply(0, m_dx->GetImmediateContext());
218  m_dx->GetImmediateContext()->DrawIndexed(m_nIndices, 0, 0);
219  }
220  return true;
221  }
222 
223  bool raWater::Update(float fTime, float fElapsedTime)
224  {
225  const float C = 0.3f; // ripple speed
226  const float D = 0.4f; // distance
227  const float U = 0.05f; // viscosity
228  const float T = 0.13f; // time
229 
230  m_lastFrameTime = fElapsedTime;
231  m_lastTimeStamp += fElapsedTime;
232 
233  while (m_lastAnimationTimeStamp <= m_lastTimeStamp)
234  {
235  m_curBuffNo = (m_curBuffNo + 1) % 3;
236 
237  double TERM1 = (4.0f - 8.0f * C * C * T * T / (D * D)) / (U * T + 2);
238  double TERM2 = (U * T - 2.0f) / (U * T + 2.0f);
239  double TERM3 = (2.0f * C * C * T * T / (D * D)) / (U * T + 2);
240  for(int z = 1; z < m_depth - 1; z++)
241  {
242  // Randwerte bleiben unbeeinflusst
243  int row = z * m_width;
244  int rowup = (z - 1) * m_width;
245  int rowdown = (z + 1) * m_width;
246  for(int x = 1; x < m_width - 1; x++)
247  {
248  m_pVertices[m_curBuffNo][row + x].y = (float)(
249  TERM1 * (float)m_pVertices[(m_curBuffNo + 2) % 3][row+x].y
250  + TERM2 * (float)m_pVertices[(m_curBuffNo + 1) % 3][row+x].y
251  + TERM3 * ((float)m_pVertices[(m_curBuffNo + 2) % 3][row+x-1].y
252  + (float)m_pVertices[(m_curBuffNo + 2) % 3][row+x+1].y
253  + (float)m_pVertices[(m_curBuffNo + 2) % 3][rowup+x].y
254  + (float)m_pVertices[(m_curBuffNo + 2) % 3][rowdown+x].y));
255  }
256  }
257 
258  m_lastAnimationTimeStamp += (1.0f / ANIMATIONS_PER_SECOND);
259  }
260 
261  CalculateNormals();
262 
263  m_dx->GetImmediateContext()->UpdateSubresource(m_pVB[0], 0, NULL,
264  m_pVertices[m_curBuffNo], 0, 0);
265  m_dx->GetImmediateContext()->UpdateSubresource(m_pVB[1], 0, NULL,
266  m_pNormals, 0, 0);
267 
268  return true;
269  }
270 
271  void raWater::CalculateNormals()
272  {
273  int x, z;
274  raVector3* buf = m_pVertices[m_curBuffNo];
275 
276  D3DXVECTOR3* pNormals = new D3DXVECTOR3[m_nVertices];
277  for(UINT n = 0; n < m_nVertices; n++)
278  {
279  pNormals[n] = D3DXVECTOR3(0, 0, 0);
280  }
281 
282  int n = 0;
283  for(UINT i = 0; i < m_nIndices / 3; i++)
284  {
285  UINT16 i0 = m_pIndices[n++];
286  UINT16 i1 = m_pIndices[n++];
287  UINT16 i2 = m_pIndices[n++];
288  D3DXVECTOR3 v0 = buf[i0];
289  D3DXVECTOR3 v1 = buf[i1];
290  D3DXVECTOR3 v2 = buf[i2];
291  D3DXVECTOR3 diff1 = v2 - v1 ;
292  D3DXVECTOR3 diff2 = v0 - v1 ;
293  D3DXVECTOR3 fn;
294  D3DXVec3Cross(&fn, &diff1, &diff2);
295  pNormals[(int)i0] += fn ;
296  pNormals[(int)i1] += fn;
297  pNormals[(int)i2] += fn;
298  }
299 
300  n = 0;
301  for(z = 0;z < m_depth;z++)
302  {
303  for(x = 0;x < m_width;x++)
304  {
305  D3DXVec3Normalize((D3DXVECTOR3*)&m_pNormals[n], &pNormals[n]);
306  n += 1;
307  }
308  }
309  delete[] pNormals;
310  }
311 
312  void raWater::push(float x, float y, float depth)
313  {
314  x += m_width /2;
315  y += m_depth /2;
316  depth = depth * m_lastFrameTime * ANIMATIONS_PER_SECOND ;
317  _PREP(depth, x, y, 0, 0);
318  _PREP(depth, x, y, 0, 1);
319  _PREP(depth, x, y, 1, 0);
320  _PREP(depth, x, y, 1, 1);
321  }
322 
323  void raWater::pushX(float depth)
324  {
325  for (int x = 0; x < m_width; x++)
326  {
327  _PREP(depth, (float)x, 1, 0, 0);
328  }
329  }
330 
331  void raWater::pushZ(float depth)
332  {
333  for (int z = 0; z < m_depth; z++)
334  {
335  _PREP(raGetRandFloat(-abs(depth), abs(depth)), 1, (float) z, 0, 0);
336  //_PREP(depth * sin (4 * 2 * D3DX_PI * z / (m_depth - 1)), 1, (float)z, 0, 0);
337  }
338  }
339 
340  void raWater::_PREP(float depth, float x, float z, int addx, int addz)
341  {
342  int vertex = (int)(z + addz) * m_width + (int)(x + addx);
343  float diffz = (float)(z - floor(z + addz));
344  float diffx = (float)(x - floor(x + addx));
345  float dist = (float)(sqrt(diffz * diffz + diffx * diffx));
346  float power = 1 - dist;
347  if (power < 0) power = 0;
348  m_pVertices[m_curBuffNo][vertex].y += depth * power;
349  }
350 };
raFloat y
Definition: raVector3.h:13
raFloat x
Definition: raVector3.h:12
UINT m_DrawOder
Definition: raVisual.h:95
ID3D11DeviceContext * GetImmediateContext(void)
Definition: raDirectX.h:31
#define SAFE_DELETE_ARRAY(p)
Definition: d3dxGlobal.h:25
raFloat x
Definition: raVector2.h:10
unsigned short UINT16
Definition: d3dx11dbg.h:35
virtual bool RenderMesh(LPCSTR techniqueName="")
Definition: raWater.cpp:188
void pushZ(float deth)
Definition: raWater.cpp:331
interface ID3DX11EffectTechnique ID3DX11EffectTechnique
ID3D11Device * GetDevice(void)
Definition: raDirectX.h:29
virtual bool Update(float fTime, float fRunTime)
Definition: raWater.cpp:223
raFloat z
Definition: raVector3.h:14
virtual void SetupIndices()
Definition: raWater.cpp:167
SIZE_T IAInputSignatureSize
virtual bool CreateVertexLayout()
Definition: raWater.cpp:54
virtual void Setup()
Definition: raMaterial.cpp:160
~raWater(void)
Definition: raWater.cpp:44
virtual void CreateVertexBuffer()
Definition: raWater.cpp:81
ID3D11InputLayout * m_pVertexLayout
Definition: raVisual.h:100
raWater(raSmartPointer< raDirectX > dx, int width, int depth, raMaterial *mat)
Definition: raWater.cpp:5
raFloat y
Definition: raVector2.h:11
raMaterial ** m_pMaterials
Definition: raVisual.h:97
virtual void SetupVertices()
Definition: raWater.cpp:125
void _PREP(float depth, float x, float y, int addx, int addy)
Definition: raWater.cpp:340
virtual void CreateIndexBuffer()
Definition: raWater.cpp:151
RAPI float raGetRandFloat(float min, float max)
Definition: raUtility.cpp:195
void push(float x, float y, float depth)
Definition: raWater.cpp:312
raSmartPointer< raDirectX > m_dx
Definition: raVisual.h:99
DWORD m_numMaterials
Definition: raVisual.h:96
ID3DX11EffectTechnique * GetEffectTechnique(LPCSTR techniqueName="")
Definition: raMaterial.h:31
void pushX(float depth)
Definition: raWater.cpp:323