Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
quadsquare_render.cpp
Go to the documentation of this file.
1 #include "quadsquare.h"
2 #include "aux_texture.h"
3 
5 
6 static void TerrainMakeActive( const TerrainTexture &text )
7 {
8  if (text.tex.t) {
10  text.tex.t->MakeActive();
11  } else {
13  }
14  GFXBlendMode( text.blendSrc, text.blendDst );
15  if (text.reflect)
17  else
20 }
21 
22 static void TerrainMakeClearActive( const TerrainTexture &text )
23 {
24  TerrainMakeActive( text );
26 }
27 
28 static void TerrainMakeDeactive( const TerrainTexture text )
29 {
30  if (text.tex.t) {}
31 }
32 
33 typedef std::vector< TextureIndex > vecTextureIndex;
34 typedef std::vector< TerrainTexture >vecTextureStar;
35 
40 int quadsquare::Render( const quadcornerdata &cd, const Vector &camvec )
41 {
42  quadsquare::camerapos = camvec;
43  vertices->LoadDrawState();
44  vertices->BeginDrawState( GFXFALSE );
45  int totsize = 0;
46  RenderAux( cd, GFX_PARTIALLY_VISIBLE );
47  vecTextureIndex::iterator i = indices.begin();
48  vecTextureStar::iterator k;
49  for (k = textures->begin(); k != textures->end(); i++, k++) {
50  TerrainMakeActive( *k );
51  unsigned int isize = (*i).q.size();
52  totsize += isize;
53  vertices->Draw( GFXTRI, isize, (*i).q.begin() );
54  TerrainMakeDeactive( *k );
55  }
56  vertices->EndDrawState();
57  i = indices.begin();
58  int j = 0;
59  for (k = textures->begin(); k != textures->end(); i++, j++, k++) {
60  if ( (*i).c.size() > 2 ) {
62  GFXPolygonOffset( 0, -j );
64  GFXColorVertex **cv = (&blendVertices->BeginMutate( 0 )->colors);
65  GFXColorVertex *tmp = *cv;
66  *cv = (*i).c.begin();
67  blendVertices->EndMutate( (*i).c.size() );
68  blendVertices->LoadDrawState();
69  blendVertices->BeginDrawState( GFXFALSE );
70  blendVertices->Draw( GFXTRI, (*i).c.size() );
71  blendVertices->EndDrawState( GFXFALSE );
72  cv = (&blendVertices->BeginMutate( 0 )->colors);
73  *cv = tmp;
74  blendVertices->EndMutate( 3 );
75  GFXColorMaterial( 0 );
76  GFXPolygonOffset( 0, 0 );
77  TerrainMakeDeactive( *k );
78  }
79  (*i).Clear();
80  }
81  return totsize;
82 }
83 
84 //#define DONOTDRAWBLENDEDQUADS
85 inline void RotateTriRight( unsigned int &aa,
86  unsigned short &ta,
87  unsigned int &bb,
88  unsigned short &tb,
89  unsigned int &cc,
90  unsigned short &tc )
91 {
92  unsigned int baki;
93  unsigned short baks;
94  baks = ta;
95  baki = aa;
96  aa = cc;
97  ta = tc;
98  cc = baki;
99  tc = baks;
100  baks = tb;
101  baki = bb;
102  tb = ta;
103  bb = aa;
104  aa = baki;
105  ta = baks;
106 }
107 
108 inline void RotateTriLeft( unsigned int &aa,
109  unsigned short &ta,
110  unsigned int &bb,
111  unsigned short &tb,
112  unsigned int &cc,
113  unsigned short &tc )
114 {
115  unsigned int baki;
116  unsigned short baks;
117  baks = ta;
118  baki = aa;
119  aa = bb;
120  ta = tb;
121  bb = baki;
122  tb = baks;
123  baks = tc;
124  baki = cc;
125  tc = ta;
126  cc = aa;
127  aa = baki;
128  ta = baks;
129 }
130 
131 void quadsquare::tri( unsigned int aa,
132  unsigned short ta,
133  unsigned int bb,
134  unsigned short tb,
135  unsigned int cc,
136  unsigned short tc )
137 {
138  assert( 0 ); //see below #if VERTEX_LIST functions... this whole contraption sorely needs a rewrite
139 #ifdef DONOTDRAWBLENDEDQUADS
140  if (ta == tb && tb == tc) {
141  indices[ta]->q.push_back( aa, bb, cc );
142  return;
143  } else {
144  return;
145  }
146 #endif
147  if ( !(ta == tb && tb == tc) ) {
148  if ( ( (*textures)[ta].blendDst == ZERO ) && ( (*textures)[tb].blendDst != ZERO ) )
149  RotateTriRight( aa, ta, bb, tb, cc, tc );
150  else if ( ( (*textures)[ta].blendDst == ZERO ) && ( (*textures)[tc].blendDst != ZERO ) )
151  RotateTriLeft( aa, ta, bb, tb, cc, tc );
152  GFXColorVertex cv[3];
153 #ifdef VERTEX_LIST
154  cv[0].SetVtx( *vertices->GetVertex( aa ) );
155  cv[1].SetVtx( *vertices->GetVertex( bb ) );
156  cv[2].SetVtx( *vertices->GetVertex( cc ) );
157 #endif
158  cv[0].SetColor( GFXColor( 1, 1, 1, 1 ) );
159  cv[1].SetColor( GFXColor( 1, 1, 1, 1 ) );
160  cv[2].SetColor( GFXColor( 1, 1, 1, 1 ) );
161  if (tb == tc) {
162  cv[0].a = 0;
163  cv[1].a = 1;
164  cv[2].a = 1;
165  indices[tb].c.push_back3( cv );
166  } else {
167  if (tb != ta) {
168  cv[0].a = 0;
169  cv[1].a = 1;
170  cv[2].a = 0;
171  indices[tb].c.push_back3( cv );
172  }
173  if (tc != ta) {
174  cv[0].a = 0;
175  cv[1].a = 0;
176  cv[2].a = 1;
177  indices[tc].c.push_back3( cv );
178  }
179  }
180  }
181  indices[ta].q.push_back( aa, bb, cc );
182 }
183 
184 unsigned short VertInfo::GetTex() const
185 {
186  return (Rem > 127) ? (Tex+1) : Tex;
187  //return Tex/texmultiply + (((Tex%texmultiply)>texmultiply/2)?1:0);
188 }
189 
190 void quadsquare::RenderAux( const quadcornerdata &cd, CLIPSTATE vis )
191 {
192 //Does the work of rendering this square. Uses the enabled vertices only.
193 //Recurses as necessary.
194  unsigned int whole = 2<<cd.Level;
196  //If this square is outside the frustum, then don't render it.
197  if (vis != GFX_TOTALLY_VISIBLE) {
198  Vector min, max;
199  min.i = cd.xorg;
200  min.j = MinY;
201  min.k = cd.zorg;
202  max.i = cd.xorg+whole;
203  max.j = MaxY;
204  max.k = cd.zorg+whole;
205  vis = nonlinear_trans->BoxInFrustum( min, max, quadsquare::camerapos );
206  if (vis == GFX_NOT_VISIBLE) {
208  //This square is completely outside the view frustum.
209  return;
210  }
211  }
212  int i;
213 
214  int flags = 0;
215  int mask = 1;
217  for (i = 0; i < 4; i++, mask <<= 1) {
218  if ( EnabledFlags&(16<<i) ) {
219  SetupCornerData( &q, cd, i );
220  Child[i]->RenderAux( q, vis );
221  } else {
222  flags |= mask;
223  }
224  }
226  if (flags == 0)
227  return;
228 //Local macro to make the triangle logic shorter & hopefully clearer.
229  //#define tri(aa,ta,bb,tb,cc,tc) (indices[ta].q.push_back (aa), indices[ta].q.push_back (bb), indices[ta].q.push_back (cc))
230 #define V0 (Vertex[0].vertindex)
231 #define T0 ( Vertex[0].GetTex() )
232 #define V1 (Vertex[1].vertindex)
233 #define T1 ( Vertex[1].GetTex() )
234 #define V2 (cd.Verts[0].vertindex)
235 #define T2 ( cd.Verts[0].GetTex() )
236 #define V3 (Vertex[2].vertindex)
237 #define T3 ( Vertex[2].GetTex() )
238 #define V4 (cd.Verts[1].vertindex)
239 #define T4 ( cd.Verts[1].GetTex() )
240 #define V5 (Vertex[3].vertindex)
241 #define T5 ( Vertex[3].GetTex() )
242 #define V6 (cd.Verts[2].vertindex)
243 #define T6 ( cd.Verts[2].GetTex() )
244 #define V7 (Vertex[4].vertindex)
245 #define T7 ( Vertex[4].GetTex() )
246 #define V8 (cd.Verts[3].vertindex)
247 #define T8 ( cd.Verts[3].GetTex() )
248  //Make the list of triangles to draw.
249  if ( (EnabledFlags&1) == 0 ) {tri( V0, T0, V8, T8, V2, T2 ); } else {
250  if (flags&8) tri( V0, T0, V8, T8, V1, T1 );
251  if (flags&1) tri( V0, T0, V1, T1, V2, T2 );
252  }
253  if ( (EnabledFlags&2) == 0 ) {tri( V0, T0, V2, T2, V4, T4 ); } else {
254  if (flags&1) tri( V0, T0, V2, T2, V3, T3 );
255  if (flags&2) tri( V0, T0, V3, T3, V4, T4 );
256  }
257  if ( (EnabledFlags&4) == 0 ) {tri( V0, T0, V4, T4, V6, T6 ); } else {
258  if (flags&2) tri( V0, T0, V4, T4, V5, T5 );
259  if (flags&4) tri( V0, T0, V5, T5, V6, T6 );
260  }
261  if ( (EnabledFlags&8) == 0 ) {tri( V0, T0, V6, T6, V8, T8 ); } else {
262  if (flags&4) tri( V0, T0, V6, T6, V7, T7 );
263  if (flags&8) tri( V0, T0, V7, T7, V8, T8 );
264  }
265 #undef V1
266 #undef V2
267 #undef V3
268 #undef V4
269 #undef V5
270 #undef V6
271 #undef V7
272 #undef V8
273 #undef T1
274 #undef T2
275 #undef T3
276 #undef T4
277 #undef T5
278 #undef t6
279 #undef T7
280 #undef T8
281 }
282 
283 void quadsquare::SetupCornerData( quadcornerdata *q, const quadcornerdata &cd, int ChildIndex )
284 {
285 //Fills the given structure with the appropriate corner values for the
286 //specified child block, given our own vertex data and our corner
287 //vertex data from cd.
288 //
289 //ChildIndex mapping:
290 //+-+-+
291 //|1|0|
292 //+-+-+
293 //|2|3|
294 //+-+-+
295 //
296 //Verts mapping:
297 //1-0
298 //| |
299 //2-3
300 //
301 //Vertex mapping:
302 //+-2-+
303 //| | |
304 //3-0-1
305 //| | |
306 //+-4-+
307  int half = 1<<cd.Level;
308  q->Parent = &cd;
309  q->Square = Child[ChildIndex];
310  q->Level = cd.Level-1;
311  q->ChildIndex = ChildIndex;
312  switch (ChildIndex)
313  {
314  default:
315  case 0:
316  q->xorg = cd.xorg+half;
317  q->zorg = cd.zorg;
318  q->Verts[0] = cd.Verts[0];
319  q->Verts[1] = Vertex[2];
320  q->Verts[2] = Vertex[0];
321  q->Verts[3] = Vertex[1];
322  break;
323  case 1:
324  q->xorg = cd.xorg;
325  q->zorg = cd.zorg;
326  q->Verts[0] = Vertex[2];
327  q->Verts[1] = cd.Verts[1];
328  q->Verts[2] = Vertex[3];
329  q->Verts[3] = Vertex[0];
330  break;
331  case 2:
332  q->xorg = cd.xorg;
333  q->zorg = cd.zorg+half;
334  q->Verts[0] = Vertex[0];
335  q->Verts[1] = Vertex[3];
336  q->Verts[2] = cd.Verts[2];
337  q->Verts[3] = Vertex[4];
338  break;
339  case 3:
340  q->xorg = cd.xorg+half;
341  q->zorg = cd.zorg+half;
342  q->Verts[0] = Vertex[1];
343  q->Verts[1] = Vertex[0];
344  q->Verts[2] = Vertex[4];
345  q->Verts[3] = cd.Verts[3];
346  break;
347  }
348 }
349