From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_camera_view_8cpp_source.html | 922 +++++++++++++++++++++++++ 1 file changed, 922 insertions(+) create mode 100644 Doc/doxygen/html/_camera_view_8cpp_source.html (limited to 'Doc/doxygen/html/_camera_view_8cpp_source.html') diff --git a/Doc/doxygen/html/_camera_view_8cpp_source.html b/Doc/doxygen/html/_camera_view_8cpp_source.html new file mode 100644 index 0000000..40312c6 --- /dev/null +++ b/Doc/doxygen/html/_camera_view_8cpp_source.html @@ -0,0 +1,922 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/CameraView.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
CameraView.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: CameraView.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  3D Projection Camera View class
+
13  uses abstract PolyRender class to draw the triangles
+
14 */
+
15 
+
16 #include "MemDebug.h"
+
17 #include "CameraView.h"
+
18 #include "Color.h"
+
19 #include "Window.h"
+
20 #include "Scene.h"
+
21 #include "Light.h"
+
22 #include "Solid.h"
+
23 #include "Shadow.h"
+
24 #include "Sprite.h"
+
25 #include "Video.h"
+
26 #include "Bitmap.h"
+
27 #include "Screen.h"
+
28 #include "Game.h"
+
29 
+
30 // +--------------------------------------------------------------------+
+
31 
+
32 void Print(const char* fmt, ...);
+
33 
+
34 // +--------------------------------------------------------------------+
+
35 
+
36 static Camera emergency_cam;
+
37 static Scene emergency_scene;
+
38 
+
39 // +--------------------------------------------------------------------+
+
40 
+ +
42 : View(c), video(0), camera(cam), projector(c, cam), scene(s),
+
43 lens_flare_enable(0), halo_bitmap(0), infinite(0),
+
44 projection_type(Video::PROJECTION_PERSPECTIVE)
+
45 {
+
46  elem_bitmap[0] = 0;
+
47  elem_bitmap[1] = 0;
+
48  elem_bitmap[2] = 0;
+
49 
+
50  if (!camera)
+
51  camera = &emergency_cam;
+
52 
+
53  if (!scene)
+
54  scene = &emergency_scene;
+
55 
+
56  Rect r = window->GetRect();
+
57  width = r.w;
+
58  height = r.h;
+
59 }
+
60 
+ +
62 {
+
63 }
+
64 
+
65 // +--------------------------------------------------------------------+
+
66 
+
67 void
+ +
69 {
+
70  if (cam)
+
71  camera = cam;
+
72  else
+
73  camera = &emergency_cam;
+
74 
+ +
76 }
+
77 
+
78 void
+ +
80 {
+
81  if (s)
+
82  scene = s;
+
83  else
+
84  scene = &emergency_scene;
+
85 }
+
86 
+
87 void
+ +
89 {
+ +
91 }
+
92 
+
93 double
+ +
95 {
+
96  return projector.GetFieldOfView();
+
97 }
+
98 
+
99 void
+ +
101 {
+ +
103  projection_type = pt;
+
104 }
+
105 
+
106 DWORD
+ +
108 {
+
109  return projection_type;
+
110 }
+
111 
+
112 void
+ +
114 {
+
115  Rect r = window->GetRect();
+ +
117 
+
118  width = r.w;
+
119  height = r.h;
+
120 }
+
121 
+
122 
+
123 // +--------------------------------------------------------------------+
+
124 // Enable or disable lens flare effect, and provide bitmaps for rendering
+
125 // +--------------------------------------------------------------------+
+
126 
+
127 void
+
128 CameraView::LensFlare(int on, double dim)
+
129 {
+
130  lens_flare_enable = on;
+
131  lens_flare_dim = dim;
+
132 }
+
133 
+
134 void
+ +
136 {
+
137  if (halo)
+
138  halo_bitmap = halo;
+
139 
+
140  if (e1)
+
141  elem_bitmap[0] = e1;
+
142 
+
143  if (e2)
+
144  elem_bitmap[1] = e2;
+
145 
+
146  if (e3)
+
147  elem_bitmap[2] = e3;
+
148 }
+
149 
+
150 // +--------------------------------------------------------------------+
+
151 
+
152 int
+ +
154 {
+
155  int old = infinite;
+
156  infinite = i;
+ +
158  return old;
+
159 }
+
160 
+
161 // +--------------------------------------------------------------------+
+
162 // Compute the Depth of a Graphic
+
163 // +--------------------------------------------------------------------+
+
164 
+
165 void
+ +
167 {
+
168  if (infinite) {
+
169  g->SetDepth(1.0e20f);
+
170  return;
+
171  }
+
172 
+
173  // Translate into a viewpoint-relative coordinate
+
174  Vec3 loc = g->Location() - camera->Pos();
+
175 
+
176  // Rotate into the view orientation
+
177  float z = (float) (loc * camera->vpn());
+
178  g->SetDepth(z);
+
179 }
+
180 
+
181 // +--------------------------------------------------------------------+
+
182 
+
183 void
+ +
185 {
+
186  // disabled:
+
187  if (camera == &emergency_cam)
+
188  return;
+
189 
+
190  // prologue:
+ +
192  if (!video)
+
193  return;
+
194 
+
195  int cw = window->Width();
+
196  int ch = window->Height();
+
197 
+
198  cvrt = camera->vrt();
+
199  cvup = camera->vup();
+
200  cvpn = camera->vpn();
+
201 
+
202  TranslateScene();
+ +
204 
+
205  Rect old_rect;
+
206  video->GetWindowRect(old_rect);
+
207 
+ + +
210  video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type);
+
211 
+
212  // project and render:
+ +
214  RenderScene();
+ +
216  RenderSprites();
+
217  RenderLensFlare();
+
218 
+ +
220 
+
221  video->SetWindowRect(old_rect);
+
222 }
+
223 
+
224 // +--------------------------------------------------------------------+
+
225 // Translate all objects and lights to camera relative coordinates:
+
226 // +--------------------------------------------------------------------+
+
227 
+
228 void
+ +
230 {
+
231  camera_loc = camera->Pos();
+
232 
+
233  ListIter<Graphic> g_iter = scene->Graphics();
+
234  while (++g_iter) {
+
235  Graphic* graphic = g_iter.value();
+
236 
+
237  if (!graphic->IsInfinite())
+
238  graphic->TranslateBy(camera_loc);
+
239  }
+
240 
+
241  g_iter.attach(scene->Foreground());
+
242  while (++g_iter) {
+
243  Graphic* graphic = g_iter.value();
+
244  graphic->TranslateBy(camera_loc);
+
245  }
+
246 
+
247  g_iter.attach(scene->Sprites());
+
248  while (++g_iter) {
+
249  Graphic* graphic = g_iter.value();
+
250 
+
251  if (!graphic->IsInfinite())
+
252  graphic->TranslateBy(camera_loc);
+
253  }
+
254 
+
255  ListIter<Light> l_iter = scene->Lights();
+
256  while (++l_iter) {
+
257  Light* light = l_iter.value();
+
258  light->TranslateBy(camera_loc);
+
259  }
+
260 
+
261  camera->MoveTo(0,0,0);
+
262 }
+
263 
+
264 // +--------------------------------------------------------------------+
+
265 // Translate all objects and lights back to original positions:
+
266 // +--------------------------------------------------------------------+
+
267 
+
268 void
+ +
270 {
+
271  Point reloc = -camera_loc;
+
272 
+
273  ListIter<Graphic> g_iter = scene->Graphics();
+
274  while (++g_iter) {
+
275  Graphic* graphic = g_iter.value();
+
276 
+
277  if (!graphic->IsInfinite())
+
278  graphic->TranslateBy(reloc);
+
279  }
+
280 
+
281  g_iter.attach(scene->Foreground());
+
282  while (++g_iter) {
+
283  Graphic* graphic = g_iter.value();
+
284  graphic->TranslateBy(reloc);
+
285  }
+
286 
+
287  g_iter.attach(scene->Sprites());
+
288  while (++g_iter) {
+
289  Graphic* graphic = g_iter.value();
+
290 
+
291  if (!graphic->IsInfinite())
+
292  graphic->TranslateBy(reloc);
+
293  }
+
294 
+
295  ListIter<Light> l_iter = scene->Lights();
+
296  while (++l_iter) {
+
297  Light* light = l_iter.value();
+
298  light->TranslateBy(reloc);
+
299  }
+
300 
+ +
302 }
+
303 
+
304 // +--------------------------------------------------------------------+
+
305 // Mark visible objects
+
306 // +--------------------------------------------------------------------+
+
307 
+
308 void
+ +
310 {
+ +
312  graphics.clear();
+
313 
+
314  ListIter<Graphic> graphic_iter = scene->Graphics();
+
315  while (++graphic_iter) {
+
316  Graphic* graphic = graphic_iter.value();
+
317 
+
318  if (graphic->Hidden())
+
319  continue;
+
320 
+
321  if (graphic->CheckVisibility(projector)) {
+
322  graphic->Update();
+
323  graphics.append(graphic);
+
324  }
+
325  else {
+
326  graphic->ProjectScreenRect(0);
+
327  }
+
328  }
+
329 }
+
330 
+
331 void
+ +
333 {
+
334  if (flags < Graphic::RENDER_FIRST_LIGHT) {
+ +
336  }
+
337 
+
338  if (graphic->IsVisible()) {
+
339  Vec3 eye = camera->Pos();
+
340 
+
341  ListIter<Light> light_iter = scene->Lights();
+
342 
+
343  while (++light_iter) {
+
344  Light* light = light_iter.value();
+
345  bool bright_enough = light->Type() == Light::LIGHT_DIRECTIONAL ||
+
346  light->Intensity() >= 1e9;
+
347 
+
348  if (!bright_enough) {
+
349  Point test = graphic->Location() - light->Location();
+
350  if (test.length() < light->Intensity()*10)
+
351  bright_enough = true;
+
352  }
+
353 
+
354  // turn off lights that won't be used this pass:
+
355  if (light->CastsShadow()) {
+
356  if ((flags & Graphic::RENDER_ADD_LIGHT) == 0)
+
357  bright_enough = false;
+
358  }
+
359  else {
+
360  if ((flags & Graphic::RENDER_FIRST_LIGHT) == 0)
+
361  bright_enough = false;
+
362  }
+
363 
+
364  double obs_radius = graphic->Radius();
+
365  if (obs_radius < 100)
+
366  obs_radius = 100;
+
367 
+
368  light->SetActive(bright_enough);
+
369  }
+
370  }
+
371 }
+
372 
+
373 // +--------------------------------------------------------------------+
+
374 
+
375 void
+ +
377 {
+
378  if (scene->Background().isEmpty()) return;
+
379 
+ + + + + +
385 
+
386  // solid items:
+ +
388  while (++iter) {
+
389  Graphic* g = iter.value();
+
390 
+
391  if (!g->Hidden())
+ +
393  }
+
394 
+
395  // blended items:
+
396  iter.reset();
+
397  while (++iter) {
+
398  Graphic* g = iter.value();
+
399 
+
400  if (!g->Hidden())
+ +
402  }
+
403 
+
404  // glowing items:
+
405  iter.reset();
+
406  while (++iter) {
+
407  Graphic* g = iter.value();
+
408 
+
409  if (!g->Hidden())
+ +
411  }
+
412 }
+
413 
+
414 // +--------------------------------------------------------------------+
+
415 
+
416 void
+ +
418 {
+
419  bool foregroundVisible = false;
+
420 
+ +
422  while (++iter && !foregroundVisible) {
+
423  Graphic* g = iter.value();
+
424  if (g && !g->Hidden())
+
425  foregroundVisible = true;
+
426  }
+
427 
+
428  if (!foregroundVisible)
+
429  return;
+
430 
+ + + + + +
436  video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type);
+
437 
+ +
439  // solid items, ambient and non-shadow lights:
+
440  iter.reset();
+
441  while (++iter) {
+
442  Graphic* g = iter.value();
+ +
444  }
+
445 
+ + +
448 
+
449  // solid items, shadow lights:
+
450  iter.reset();
+
451  while (++iter) {
+
452  Graphic* g = iter.value();
+ +
454  }
+
455  }
+
456 
+
457  else {
+
458  // solid items:
+
459  iter.reset();
+
460  while (++iter) {
+
461  Graphic* g = iter.value();
+ +
463  }
+
464  }
+
465 
+ + + + + +
471 
+
472  // blended items:
+
473  iter.reset();
+
474  while (++iter) {
+
475  Graphic* g = iter.value();
+ + +
478  }
+
479 
+
480  // glowing items:
+
481  iter.reset();
+
482  while (++iter) {
+
483  Graphic* g = iter.value();
+ + +
486  }
+
487 }
+
488 
+
489 // +--------------------------------------------------------------------+
+
490 
+
491 void
+ +
493 {
+
494  if (scene->Sprites().isEmpty()) return;
+
495 
+ + + + + +
501 
+
502  // compute depth:
+
503  ListIter<Graphic> iter = scene->Sprites();
+
504  while (++iter) {
+
505  Graphic* g = iter.value();
+
506  if (g && g->IsVisible() && !g->Hidden()) {
+
507  FindDepth(g);
+
508  }
+
509  }
+
510 
+
511  // sort the list:
+
512  scene->Sprites().sort();
+
513 
+
514  // blended items:
+
515  iter.reset();
+
516  while (++iter) {
+
517  Graphic* g = iter.value();
+ +
519  }
+
520 
+
521  // glowing items:
+
522  iter.reset();
+
523  while (++iter) {
+
524  Graphic* g = iter.value();
+ +
526  }
+
527 }
+
528 
+
529 // +--------------------------------------------------------------------+
+
530 // Render the whole scene, sorted back to front
+
531 // +--------------------------------------------------------------------+
+
532 
+
533 void
+ +
535 {
+
536  if (graphics.isEmpty()) return;
+
537 
+
538  int i = 0;
+
539  int ngraphics = graphics.size();
+
540 
+
541  // compute depth:
+ +
543  while (++iter) {
+
544  Graphic* g = iter.value();
+
545  if (g && !g->Hidden()) {
+
546  FindDepth(g);
+
547 
+
548  if (g->IsSolid()) {
+
549  Solid* solid = (Solid*) g;
+
550 
+
551  solid->SelectDetail(&projector);
+
552 
+
553  if (video->IsShadowEnabled()) {
+ +
555  solid->UpdateShadows(scene->Lights());
+
556  }
+
557  }
+
558  }
+
559  }
+
560 
+
561  // sort the list:
+
562  graphics.sort();
+
563 
+
564  Graphic* g = graphics.last();
+
565  if (g->Depth() > 5e6) {
+
566  RenderSceneObjects(true);
+ +
568  }
+
569 
+
570  RenderSceneObjects(false);
+
571 }
+
572 
+
573 void
+ +
575 {
+ +
577 
+ + + + + +
583 
+
584  if (distant)
+
585  video->SetProjection((float) GetFieldOfView(), 5.0e6f, 1.0e12f, projection_type);
+
586  else
+
587  video->SetProjection((float) GetFieldOfView(), 1.0f, 1.0e6f, projection_type);
+
588 
+ +
590  // solid items, ambient and non-shadow lights:
+
591  iter.reset();
+
592  while (++iter) {
+
593  Graphic* g = iter.value();
+
594 
+
595  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+ +
597  }
+
598  }
+
599 
+
600  // send shadows to stencil buffer:
+
601  if (video->IsShadowEnabled()) {
+
602  iter.reset();
+
603  while (++iter) {
+
604  Graphic* g = iter.value();
+
605  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+
606  if (g->IsSolid()) {
+
607  Solid* solid = (Solid*) g;
+
608 
+
609  ListIter<Shadow> shadow_iter = solid->GetShadows();
+
610  while (++shadow_iter) {
+
611  Shadow* shadow = shadow_iter.value();
+
612  shadow->Render(video);
+
613  }
+
614  }
+
615  }
+
616  }
+
617  }
+
618 
+ + + +
622 
+
623  // solid items, shadow lights:
+
624  iter.reset();
+
625  while (++iter) {
+
626  Graphic* g = iter.value();
+
627 
+
628  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+ +
630  }
+
631  }
+
632  }
+
633 
+
634  else {
+
635  // solid items:
+
636  iter.reset();
+
637  while (++iter) {
+
638  Graphic* g = iter.value();
+
639 
+
640  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+ +
642  }
+
643  }
+
644  }
+
645 
+ + + + + +
651 
+
652  // blended items:
+
653  iter.reset();
+
654  while (++iter) {
+
655  Graphic* g = iter.value();
+
656 
+
657  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+ + +
660  }
+
661  }
+
662 
+
663  // glowing items:
+
664  iter.reset();
+
665  while (++iter) {
+
666  Graphic* g = iter.value();
+
667 
+
668  if (distant && g->Depth() > 5e6 || !distant && g->Depth() < 5e6) {
+ + +
671  }
+
672  }
+
673 }
+
674 
+
675 void
+
676 CameraView::Render(Graphic* g, DWORD flags)
+
677 {
+
678  if (g && g->IsVisible() && !g->Hidden()) {
+
679  if (g->IsSolid()) {
+
680  MarkVisibleLights(g, flags);
+ +
682  }
+
683 
+
684  g->Render(video, flags);
+
685  }
+
686 }
+
687 
+
688 // +--------------------------------------------------------------------+
+
689 // Draw the lens flare effect, if enabled and light source visible
+
690 // +--------------------------------------------------------------------+
+
691 
+
692 void
+ +
694 {
+
695  if (!lens_flare_enable || lens_flare_dim < 0.01)
+
696  return;
+
697 
+
698  if (!halo_bitmap)
+
699  return;
+
700 
+ + + +
704 
+
705  Vec3 flare_pos;
+
706  Vec3 sun_pos;
+
707  Vec3 center((float)width/2.0f, (float)height/2.0f, 1.0f);
+
708  int flare_visible = 0;
+
709 
+
710  ListIter<Light> light_iter = scene->Lights();
+
711  while (++light_iter) {
+
712  Light* light = light_iter.value();
+
713 
+
714  if (!light->IsActive())
+
715  continue;
+
716 
+
717  if (light->Type() == Light::LIGHT_DIRECTIONAL && light->Intensity() < 1)
+
718  continue;
+
719 
+
720  double distance = (light->Location()-camera->Pos()).length();
+
721 
+
722  // only do lens flare for the sun:
+
723  if (distance > 1e9) {
+
724  if (projector.IsVisible(light->Location(), 1.0f)) {
+
725  // FOUND IT: TRANSFORM/PROJECT FLARE LOCATION
+
726  Point sun_pos = light->Location();
+
727 
+
728  if (light->CastsShadow() && scene->IsLightObscured(camera->Pos(), sun_pos, -1))
+
729  continue;
+
730 
+
731  projector.Transform(sun_pos);
+
732 
+
733  if (sun_pos.z < 100)
+
734  continue;
+
735 
+
736  projector.Project(sun_pos, false);
+
737 
+
738  int x = (int) (sun_pos.x);
+
739  int y = (int) (sun_pos.y);
+
740  int w = (int) (window->Width() / 4.0);
+
741  int h = w;
+
742 
+
743  // halo:
+ +
745 
+
746  // lens elements:
+
747  if (elem_bitmap[0]) {
+
748  Point vector = center - sun_pos;
+
749  float vlen = (float) vector.length();
+
750  vector.Normalize();
+
751 
+
752  static int nelem = 12;
+
753  static int elem_indx[] = { 0, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 2 };
+
754  static float elem_dist[] = { -0.2f, 0.5f, 0.55f, 0.62f, 1.23f, 1.33f, 1.35f, 0.8f, 0.9f, 1.4f, 1.7f, 1.8f };
+
755  static float elem_size[] = { 0.3f, 0.2f, 0.4f, 0.3f, 0.4f, 0.2f, 0.6f, 0.1f, 0.1f, 1.6f, 1.0f, 0.2f };
+
756 
+
757  for (int elem = 0; elem < nelem; elem++) {
+
758  Bitmap* img = elem_bitmap[elem_indx[elem]];
+
759 
+
760  /***
+
761  if (elem == 10)
+
762  shade *= 0.5;
+
763  ***/
+
764 
+
765  if (img == 0)
+
766  img = elem_bitmap[0];
+
767 
+
768  flare_pos = sun_pos + (vector * elem_dist[elem] * vlen);
+
769  x = (int) (flare_pos.x);
+
770  y = (int) (flare_pos.y);
+
771  w = (int) (window->Width() / 8.0 * elem_size[elem]);
+
772  h = w;
+
773 
+
774  window->DrawBitmap(x-w,y-h,x+w,y+h, img, Video::BLEND_ADDITIVE);
+
775  }
+
776  }
+
777  }
+
778  }
+
779  }
+
780 }
+
781 
+
782 // +--------------------------------------------------------------------+
+
783 // Rotate and translate a plane in world space to view space.
+
784 // +--------------------------------------------------------------------+
+
785 
+
786 void
+ +
788 {
+
789  // Determine the distance from the viewpoint
+
790  Vec3 tnormal = plane.normal;
+
791 
+
792  if (!infinite)
+
793  plane.distance -= (float) (camera->Pos() * tnormal);
+
794 
+
795  // Rotate the normal into view orientation
+
796  plane.normal.x = tnormal * cvrt;
+
797  plane.normal.y = tnormal * cvup;
+
798  plane.normal.z = tnormal * cvpn;
+
799 }
+
800 
+
801 void
+ +
803 {
+
804  projector.SetDepthScale(scale);
+
805 }
+
+
+ + + + -- cgit v1.1