Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TerrainClouds.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2005. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: TerrainClouds.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12 */
13 
14 #include "MemDebug.h"
15 #include "TerrainClouds.h"
16 #include "Terrain.h"
17 #include "TerrainRegion.h"
18 
19 #include "Light.h"
20 #include "CameraView.h"
21 #include "Bitmap.h"
22 #include "DataLoader.h"
23 #include "Game.h"
24 #include "Fix.h"
25 #include "Scene.h"
26 
27 // +--------------------------------------------------------------------+
28 
30 : terrain(terr), type(t)
31 {
32  nverts = 0;
33  npolys = 0;
34  mverts = 0;
35  verts = 0;
36  polys = 0;
37 
38  loc = Point(0, 15000, 0);
39  radius = (float) (25000.0f);
40 
41  BuildClouds();
42 }
43 
44 // +--------------------------------------------------------------------+
45 
47 {
48  delete [] mverts;
49  delete verts;
50  delete [] polys;
51 }
52 
53 // +--------------------------------------------------------------------+
54 
55 static const double BANK_SIZE = 20000;
56 static const int CIRRUS_BANKS = 4;
57 static const int CUMULUS_BANKS = 4;
58 
59 void
61 {
62  if (type == 0) {
63  nbanks = CIRRUS_BANKS;
64  nverts = 4 * nbanks;
65  npolys = 2 * nbanks;
66  }
67  else {
68  nbanks = CUMULUS_BANKS;
69  nverts = 8 * nbanks;
70  npolys = 3 * nbanks;
71  }
72 
73  Bitmap* cloud_texture = terrain->CloudTexture(type);
74  Bitmap* shade_texture = terrain->ShadeTexture(type);
75 
76  strcpy_s(mtl_cloud.name, "cloud");
79  mtl_cloud.luminous = true;
81  mtl_cloud.tex_diffuse = cloud_texture;
82 
83  strcpy_s(mtl_shade.name, "shade");
86  mtl_shade.luminous = true;
88  mtl_shade.tex_diffuse = shade_texture;
89 
90  verts = new(__FILE__,__LINE__) VertexSet(nverts);
91  mverts = new(__FILE__,__LINE__) Vec3[nverts];
92  polys = new(__FILE__,__LINE__) Poly[npolys];
93 
94  verts->nverts = nverts;
95 
96  // initialize vertices
97  Vec3* pVert = mverts;
98  float* pTu = verts->tu;
99  float* pTv = verts->tv;
100 
101  int i, j, n;
102  double az = 0;
103  double r = 0;
104 
105  for (n = 0; n < nbanks; n++) {
106  double xloc = r * cos(az);
107  double yloc = r * sin(az);
108  double alt = rand() / 32.768;
109 
110  for (i = 0; i < 2; i++) {
111  for (j = 0; j < 2; j++) {
112  *pVert = Vec3((float) ((2*j-1) * BANK_SIZE + xloc),
113  (float) (alt),
114  (float) ((2*i-1) * BANK_SIZE + yloc));
115 
116  *pTu++ = (float) (-j);
117  *pTv++ = (float) ( i);
118 
119  float dist = pVert->length();
120  if (dist > radius)
121  radius = dist;
122 
123  pVert++;
124  }
125  }
126 
127  if (type > 0) {
128  for (i = 0; i < 2; i++) {
129  for (j = 0; j < 2; j++) {
130  *pVert = Vec3((float) ((2*j-1) * BANK_SIZE + xloc),
131  (float) (alt-100),
132  (float) ((2*i-1) * BANK_SIZE + yloc));
133 
134  *pTu++ = (float) (-j);
135  *pTv++ = (float) ( i);
136 
137  float dist = pVert->length();
138  if (dist > radius)
139  radius = dist;
140 
141  pVert++;
142  }
143  }
144  }
145 
146  az += (0.66 + rand()/32768.0) * 0.25 * PI;
147 
148  if (r < BANK_SIZE)
149  r += BANK_SIZE;
150  else if (r < 1.75*BANK_SIZE)
151  r += BANK_SIZE/4;
152  else
153  r += BANK_SIZE/8;
154  }
155 
156  // create the polys
157  for (i = 0; i < npolys; i++) {
158  Poly* p = polys + i;
159  p->nverts = 4;
160  p->vertex_set = verts;
161  p->material = (i<4*nbanks) ? &mtl_cloud : &mtl_shade;
162  p->visible = 1;
163  p->sortval = (i<4*nbanks) ? 1 : 2;
164  }
165 
166  // build main patch polys: (facing down)
167  Poly* p = polys;
168 
169  int stride = 4;
170  if (type > 0)
171  stride = 8;
172 
173  // clouds:
174  for (n = 0; n < nbanks; n++) {
175  p->verts[0] = 0 + n*stride;
176  p->verts[1] = 1 + n*stride;
177  p->verts[2] = 3 + n*stride;
178  p->verts[3] = 2 + n*stride;
179  p++;
180 
181  // reverse side: (facing up)
182  p->verts[0] = 0 + n*stride;
183  p->verts[3] = 1 + n*stride;
184  p->verts[2] = 3 + n*stride;
185  p->verts[1] = 2 + n*stride;
186  p++;
187  }
188 
189  // shades:
190  if (type > 0) {
191  for (n = 0; n < nbanks; n++) {
192  p->verts[0] = 4 + n*stride;
193  p->verts[1] = 5 + n*stride;
194  p->verts[2] = 7 + n*stride;
195  p->verts[3] = 6 + n*stride;
196  p++;
197  }
198  }
199 
200  // update the verts and colors of each poly:
201  for (i = 0; i < npolys; i++) {
202  Poly* p = polys + i;
203  WORD* v = p->verts;
204 
205  p->plane = Plane(mverts[v[0]],
206  mverts[v[1]],
207  mverts[v[2]]);
208  }
209 }
210 
211 // +--------------------------------------------------------------------+
212 
213 void
215 {
216  if (!nverts || !mverts || !verts)
217  return;
218 
219  for (int i = 0; i < nverts; ++i)
220  verts->loc[i] = mverts[i] + loc;
221 }
222 
223 // +--------------------------------------------------------------------+
224 
225 void
227 {
228  int i, n;
229 
230  if (terrain) {
231  DWORD cloud_color = terrain->GetRegion()->CloudColor().Value() | Color(0,0,0,255).Value();
232  DWORD shade_color = terrain->GetRegion()->ShadeColor().Value() | Color(0,0,0,255).Value();
233 
234  int stride = 4;
235  if (type > 0)
236  stride = 8;
237 
238  for (i = 0; i < nbanks; i++) {
239  for (n = 0; n < 4; n++) {
240  verts->diffuse[stride*i + n] = cloud_color;
241  verts->specular[stride*i + n] = 0xff000000;
242  }
243 
244  if (type > 0) {
245  for (; n < 8; n++) {
246  verts->diffuse[stride*i + n] = shade_color;
247  verts->specular[stride*i + n] = 0xff000000;
248  }
249  }
250  }
251  }
252 }
253 
254 // +--------------------------------------------------------------------+
255 
256 void
257 TerrainClouds::Render(Video* video, DWORD flags)
258 {
259  if ((flags & Graphic::RENDER_ALPHA) == 0)
260  return;
261 
262  if (video && life && polys && npolys && verts) {
263  if (scene)
265 
266  video->SetRenderState(Video::FOG_ENABLE, false);
267  video->DrawPolys(npolys, polys);
268  }
269 }