absence_thelab

view src/3deng/lights.cpp @ 1:4d5933c261c3

todo and .hgignore
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Oct 2014 02:18:43 +0300
parents
children
line source
1 #include "lights.h"
2 #include <cmath>
4 Light::Light() {
5 intensity = 1.0f;
6 ambient_color = 0.0f;
7 diffuse_color = specular_color = 1.0f;
8 CastShadows = false;
9 }
11 void Light::SetIntensity(float intensity) {
12 this->intensity = intensity;
13 }
15 float Light::GetIntensity() const {
16 return intensity;
17 }
19 void Light::SetColor(const Color &color, PhongComponent comp) {
20 if(comp == (PhongComponent)-1) {
21 diffuse_color = specular_color = color;
22 } else {
23 switch(comp) {
24 case Ambient:
25 ambient_color = color;
26 break;
27 case Diffuse:
28 diffuse_color = color;
29 break;
30 case Specular:
31 specular_color = color;
32 break;
33 }
34 }
35 }
37 const Color &Light::GetColor(PhongComponent comp) const {
38 switch(comp) {
39 case Ambient:
40 return ambient_color;
41 case Diffuse:
42 return diffuse_color;
43 case Specular:
44 return specular_color;
45 }
46 }
48 void Light::SetShadowCasting(bool enable) {
49 CastShadows = enable;
50 }
52 bool Light::GetShadowCasting() const {
53 return CastShadows;
54 }
56 ////////// Directional Light ///////////
58 // Non-Applicable functions for this type of light
59 void DirLight::SetPosition(const Vector3 &pos) {}
60 void DirLight::SetRange(float range) {}
61 void DirLight::SetAttenuation(float att0, float att1, float att2) {}
62 Vector3 DirLight::GetPosition() const {return Direction;}
63 float DirLight::GetRange() const {return 0.0f;}
64 float DirLight::GetAttenuation(int degree) const {return 0.0f;}
65 void DirLight::ResetTransform() {}
66 void DirLight::ResetTranslation() {}
67 void DirLight::ResetRotation() {}
68 void DirLight::Transform(const Matrix4x4 &matrix) {}
69 void DirLight::Translate(float x, float y, float z) {}
70 void DirLight::Rotate(float x, float y, float z) {}
71 void DirLight::Rotate(const Vector3 &axis, float angle) {}
72 void DirLight::SetCone(float InnerCone, float OuterCone) {}
73 float DirLight::GetInnerCone() const {return 0.0f;}
74 float DirLight::GetOuterCone() const {return 0.0f;}
75 void DirLight::SetFalloff(float falloff) {}
76 float DirLight::GetFalloff() const {return 0.0f;}
77 void DirLight::ResetTargetTransform() {}
78 void DirLight::ResetTargetTranslation() {}
79 void DirLight::ResetTargetRotation() {}
80 void DirLight::TargetTransform(const Matrix4x4 &matrix) {}
81 void DirLight::TargetTranslate(float x, float y, float z) {}
82 void DirLight::TargetRotate(float x, float y, float z) {}
83 void DirLight::TargetRotate(const Vector3 &axis, float angle) {}
87 DirLight::DirLight() {
88 Direction = Vector3(0, -1, 0);
89 }
91 DirLight::DirLight(const Vector3 &dir) {
92 Direction = dir;
93 }
96 void DirLight::SetDirection(const Vector3 &dir) {
97 Direction = dir;
98 }
100 Vector3 DirLight::GetDirection() const {
101 Vector3 dir = Direction;
102 dir.Transform(DirRot);
103 return dir;
104 }
106 LightType DirLight::GetType() const {
107 return LTDir;
108 }
110 // direction transformations
111 void DirLight::ResetDirTransform() {
112 DirRot.ResetIdentity();
113 }
115 void DirLight::ResetDirRotation() {
116 DirRot.ResetIdentity();
117 }
119 void DirLight::TransformDir(const Matrix4x4 &matrix) {
120 DirRot *= matrix;
121 }
123 void DirLight::RotateDir(float x, float y, float z) {
124 DirRot.Rotate(x, y, z);
125 }
127 void DirLight::RotateDir(const Vector3 &axis, float angle) {
128 DirRot.Rotate(axis, angle);
129 }
132 void DirLight::SetLight(dword index, GraphicsContext *gc) const {
134 Vector3 dir = Direction;
135 dir.Transform(DirRot);
137 D3DLIGHT8 light;
138 memset(&light, 0, sizeof(D3DLIGHT8));
139 light.Ambient.r = ambient_color.r * intensity;
140 light.Diffuse.r = diffuse_color.r * intensity;
141 light.Specular.r = specular_color.r * intensity;
142 light.Ambient.g = ambient_color.g * intensity;
143 light.Diffuse.g = diffuse_color.g * intensity;
144 light.Specular.g = specular_color.g * intensity;
145 light.Ambient.b = ambient_color.b * intensity;
146 light.Diffuse.b = diffuse_color.b * intensity;
147 light.Specular.b = specular_color.b * intensity;
148 light.Direction = dir;
149 light.Type = (D3DLIGHTTYPE)LTDir;
151 gc->D3DDevice->SetLight(index, &light);
152 gc->D3DDevice->LightEnable(index, true);
153 }
155 Vertex DirLightVisVertices[] = {
156 Vertex(Vector3(0.0f, 0.0f, 0.1f), 0.0f, 0.0f, 0x00ff0000),
157 Vertex(Vector3(0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
158 Vertex(Vector3(-0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
159 Vertex(Vector3(0.0f, -0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff)
160 };
162 Index DirLightVisIndices[] = {
163 0, 1, 2,
164 0, 2, 3,
165 0, 3, 1,
166 1, 3, 2
167 };
170 void DirLight::Draw(GraphicsContext *gc, float size) {
172 Material mat(0.9f, 0.8f, 0.3f);
173 gc->SetMaterial(mat);
174 gc->SetTexture(0, 0);
175 gc->SetColorVertex(true);
176 gc->SetLighting(false);
177 gc->SetZBuffering(false);
179 Matrix4x4 WorldMat = (Matrix4x4)Base(Direction).CreateRotationMatrix() * DirRot;
180 gc->SetWorldMatrix(WorldMat);
182 Matrix4x4 ViewMat = gc->GetViewMatrix();
183 Matrix4x4 AugViewMat;
185 for(int i=0; i<4; i++) {
186 AugViewMat.SetRowVector(ViewMat.GetRowVector(i).Normalized(), i);
187 }
189 gc->SetViewMatrix(AugViewMat);
191 gc->Draw(DirLightVisVertices, DirLightVisIndices, 4, 12);
193 gc->SetViewMatrix(ViewMat);
195 gc->SetZBuffering(true);
196 gc->SetLighting(true);
197 gc->SetColorVertex(false);
199 }
201 /////////// Point Light //////////////
203 // Non-Applicable member functions
204 void PointLight::SetDirection(const Vector3 &dir) {}
205 Vector3 PointLight::GetDirection() const {return Position;}
206 void PointLight::ResetDirTransform() {}
207 void PointLight::ResetDirRotation() {}
208 void PointLight::TransformDir(const Matrix4x4 &matrix) {}
209 void PointLight::RotateDir(float x, float y, float z) {}
210 void PointLight::RotateDir(const Vector3 &axis, float angle) {}
211 void PointLight::SetCone(float InnerCone, float OuterCone) {}
212 float PointLight::GetInnerCone() const {return 0.0f;}
213 float PointLight::GetOuterCone() const {return 0.0f;}
214 void PointLight::SetFalloff(float falloff) {}
215 float PointLight::GetFalloff() const {return 0.0f;}
216 void PointLight::ResetTargetTransform() {}
217 void PointLight::ResetTargetTranslation() {}
218 void PointLight::ResetTargetRotation() {}
219 void PointLight::TargetTransform(const Matrix4x4 &matrix) {}
220 void PointLight::TargetTranslate(float x, float y, float z) {}
221 void PointLight::TargetRotate(float x, float y, float z) {}
222 void PointLight::TargetRotate(const Vector3 &axis, float angle) {}
226 PointLight::PointLight() {
227 Position = Vector3(0, 100, 0);
228 Range = 300.0f;
229 Attenuation[0] = 1.0f;
230 Attenuation[1] = 0.0f;
231 Attenuation[2] = 0.0f;
232 }
234 PointLight::PointLight(const Vector3 &pos, float range, float att0, float att1, float att2) {
235 Position = pos;
236 Range = range;
237 Attenuation[0] = att0;
238 Attenuation[1] = att1;
239 Attenuation[2] = att2;
240 }
242 Matrix4x4 PointLight::GetTransform() const {
243 return PosXForm * PosRot * PosTrans;
244 }
246 void PointLight::SetPosition(const Vector3 &pos) {
247 Position = pos;
248 }
250 void PointLight::SetRange(float range) {
251 Range = range;
252 }
254 void PointLight::SetAttenuation(float att0, float att1, float att2) {
255 Attenuation[0] = att0;
256 Attenuation[1] = att1;
257 Attenuation[2] = att2;
258 }
260 Vector3 PointLight::GetPosition() const {
261 Vector3 pos = Position;
262 pos.Transform(GetTransform());
263 return pos;
264 }
266 float PointLight::GetRange() const {
267 return Range;
268 }
270 float PointLight::GetAttenuation(int degree) const {
271 return Attenuation[degree];
272 }
274 LightType PointLight::GetType() const {
275 return LTPoint;
276 }
278 // position transformations
279 void PointLight::ResetTransform() {
280 PosRot.ResetIdentity();
281 PosTrans.ResetIdentity();
282 PosXForm.ResetIdentity();
283 }
285 void PointLight::ResetTranslation() {
286 PosTrans.ResetIdentity();
287 }
289 void PointLight::ResetRotation() {
290 PosRot.ResetIdentity();
291 }
293 void PointLight::Transform(const Matrix4x4 &matrix) {
294 PosXForm *= matrix;
295 }
297 void PointLight::Translate(float x, float y, float z) {
298 PosTrans.Translate(x, y, z);
299 }
301 void PointLight::Rotate(float x, float y, float z) {
302 PosRot.Rotate(x, y, z);
303 }
305 void PointLight::Rotate(const Vector3 &axis, float angle) {
306 PosRot.Rotate(axis, angle);
307 }
310 void PointLight::SetLight(dword index, GraphicsContext *gc) const {
312 Vector3 pos = Position;
313 pos.Transform(GetTransform());
315 D3DLIGHT8 light;
316 memset(&light, 0, sizeof(D3DLIGHT8));
317 light.Ambient.r = ambient_color.r * intensity;
318 light.Diffuse.r = diffuse_color.r * intensity;
319 light.Specular.r = specular_color.r * intensity;
320 light.Ambient.g = ambient_color.g * intensity;
321 light.Diffuse.g = diffuse_color.g * intensity;
322 light.Specular.g = specular_color.g * intensity;
323 light.Ambient.b = ambient_color.b * intensity;
324 light.Diffuse.b = diffuse_color.b * intensity;
325 light.Specular.b = specular_color.b * intensity;
326 light.Position = pos;
327 light.Range = Range;
328 light.Attenuation0 = Attenuation[0];
329 light.Attenuation1 = Attenuation[1];
330 light.Attenuation2 = Attenuation[2];
331 light.Type = (D3DLIGHTTYPE)LTPoint;
333 gc->D3DDevice->SetLight(index, &light);
334 gc->D3DDevice->LightEnable(index, true);
335 }
339 Index PointLightVisIndices[] = {0, 2, 1, 0, 3, 2};
341 void PointLight::Draw(GraphicsContext *gc, float size) {
343 dword color = (diffuse_color * intensity).GetPacked32();
345 float PtHalfSz = size / 2.0f;
346 Vertex PointLightVisVertices[] = {
347 Vertex(Vector3(-PtHalfSz, PtHalfSz, 0.0f), 0.0f, 0.0f, color),
348 Vertex(Vector3(PtHalfSz, PtHalfSz, 0.0f), 1.0f, 0.0f, color),
349 Vertex(Vector3(PtHalfSz, -PtHalfSz, 0.0f), 1.0f, 1.0f, color),
350 Vertex(Vector3(-PtHalfSz, -PtHalfSz, 0.0f), 0.0f, 1.0f, color)
351 };
353 Texture *tex = gc->texman->LoadTexture("STOCKTEX_BLOB");
354 gc->SetTexture(0, tex);
355 gc->SetTextureStageColor(0, TexBlendModulate, TexArgTexture, TexArgCurrent);
356 gc->SetTexture(1, 0);
358 gc->SetAlphaBlending(true);
359 gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
361 gc->SetColorVertex(true);
362 gc->SetLighting(false);
364 Matrix4x4 InvPos;
365 InvPos.Translate(Position.x, Position.y, Position.z);
366 gc->SetWorldMatrix(InvPos * GetTransform());
368 gc->SetZWrite(false);
369 gc->SetBillboarding(true);
370 gc->Draw(PointLightVisVertices, PointLightVisIndices, 4, 6);
371 gc->SetBillboarding(false);
372 gc->SetZWrite(true);
374 gc->SetAlphaBlending(false);
375 gc->SetLighting(true);
376 gc->SetColorVertex(false);
377 gc->SetTexture(0, 0);
378 }
381 ////////////// Spot Light ////////////////
382 void SpotLight::ResetTargetTransform() {}
383 void SpotLight::ResetTargetTranslation() {}
384 void SpotLight::ResetTargetRotation() {}
385 void SpotLight::TargetTransform(const Matrix4x4 &matrix) {}
386 void SpotLight::TargetTranslate(float x, float y, float z) {}
387 void SpotLight::TargetRotate(float x, float y, float z) {}
388 void SpotLight::TargetRotate(const Vector3 &axis, float angle) {}
390 SpotLight::SpotLight() {
391 Position = Vector3(0, 100, 0);
392 Direction = Vector3(0, -1, 0);
393 Falloff = 1.0f;
394 Phi = QuarterPi;
395 Theta = Phi - (Phi / 9.0f);
396 }
398 SpotLight::SpotLight(const Vector3 &pos, const Vector3 &dir, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
399 Position = pos;
400 Direction = dir;
401 SetCone(InnerCone, OuterCone);
402 Range = range;
403 Attenuation[0] = att0;
404 Attenuation[1] = att1;
405 Attenuation[2] = att2;
406 Falloff = 1.0f;
407 }
409 void SpotLight::SetDirection(const Vector3 &dir) {
410 Direction = dir;
411 }
413 Vector3 SpotLight::GetDirection() const {
414 Vector3 dir = Direction;
415 dir.Transform(DirRot);
416 return dir;
417 }
419 // direction transformations
420 void SpotLight::ResetDirTransform() {
421 DirRot.ResetIdentity();
422 }
424 void SpotLight::ResetDirRotation() {
425 DirRot.ResetIdentity();
426 }
428 void SpotLight::TransformDir(const Matrix4x4 &matrix) {
429 DirRot *= matrix;
430 }
432 void SpotLight::RotateDir(float x, float y, float z) {
433 DirRot.Rotate(x, y, z);
434 }
436 void SpotLight::RotateDir(const Vector3 &axis, float angle) {
437 DirRot.Rotate(axis, angle);
438 }
441 LightType SpotLight::GetType() const {
442 return LTSpot;
443 }
445 void SpotLight::SetCone(float InnerCone, float OuterCone) {
446 Theta = InnerCone;
447 Phi = OuterCone;
448 }
450 float SpotLight::GetInnerCone() const {
451 return Theta;
452 }
454 float SpotLight::GetOuterCone() const {
455 return Phi;
456 }
458 void SpotLight::SetFalloff(float falloff) {
459 Falloff = falloff;
460 }
462 float SpotLight::GetFalloff() const {
463 return Falloff;
464 }
467 void SpotLight::SetLight(dword index, GraphicsContext *gc) const {
469 Vector3 pos = Position;
470 pos.Transform(GetTransform());
472 Vector3 dir = Direction;
473 dir.Transform(DirRot);
475 D3DLIGHT8 light;
476 memset(&light, 0, sizeof(D3DLIGHT8));
477 light.Ambient.r = ambient_color.r * intensity;
478 light.Diffuse.r = diffuse_color.r * intensity;
479 light.Specular.r = specular_color.r * intensity;
480 light.Ambient.g = ambient_color.g * intensity;
481 light.Diffuse.g = diffuse_color.g * intensity;
482 light.Specular.g = specular_color.g * intensity;
483 light.Ambient.b = ambient_color.b * intensity;
484 light.Diffuse.b = diffuse_color.b * intensity;
485 light.Specular.b = specular_color.b * intensity;
486 light.Position = pos;
487 light.Direction = dir;
488 light.Range = Range;
489 light.Attenuation0 = Attenuation[0];
490 light.Attenuation1 = Attenuation[1];
491 light.Attenuation2 = Attenuation[2];
492 light.Falloff = Falloff;
493 light.Theta = Theta;
494 light.Phi = Phi;
495 light.Type = (D3DLIGHTTYPE)LTSpot;
497 gc->D3DDevice->SetLight(index, &light);
498 gc->D3DDevice->LightEnable(index, true);
499 }
501 void SpotLight::Draw(GraphicsContext *gc, float size) {
502 PointLight::Draw(gc, size);
503 }
505 //////////////// Target Spot Light ////////////////////
506 void TargetSpotLight::SetDirection(const Vector3 &dir) {}
507 Vector3 TargetSpotLight::GetDirection() const {return Vector3();}
508 void TargetSpotLight::ResetDirTransform() {}
509 void TargetSpotLight::ResetDirRotation() {}
510 void TargetSpotLight::TransformDir(const Matrix4x4 &matrix) {}
511 void TargetSpotLight::RotateDir(float x, float y, float z) {}
512 void TargetSpotLight::RotateDir(const Vector3 &axis, float angle) {}
514 TargetSpotLight::TargetSpotLight() {
515 Target = Vector3(0.0f, 0.0f, 0.0f);
516 }
518 TargetSpotLight::TargetSpotLight(const Vector3 &pos, const Vector3 &target, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
519 Position = pos;
520 Target = target;
521 SetCone(InnerCone, OuterCone);
522 Range = range;
523 Attenuation[0] = att0;
524 Attenuation[1] = att1;
525 Attenuation[2] = att2;
526 Falloff = 1.0f;
527 }
529 Matrix4x4 TargetSpotLight::GetTargetTransform() const {
530 return TargXForm * TargRot * TargTrans;
531 }
533 void TargetSpotLight::ResetTargetTransform() {
534 TargRot.ResetIdentity();
535 TargTrans.ResetIdentity();
536 TargXForm.ResetIdentity();
537 }
539 void TargetSpotLight::ResetTargetTranslation() {
540 TargTrans.ResetIdentity();
541 }
543 void TargetSpotLight::ResetTargetRotation() {
544 TargRot.ResetIdentity();
545 }
547 void TargetSpotLight::TargetTransform(const Matrix4x4 &matrix) {
548 TargXForm *= matrix;
549 }
551 void TargetSpotLight::TargetTranslate(float x, float y, float z) {
552 TargTrans.Translate(x, y, z);
553 }
555 void TargetSpotLight::TargetRotate(float x, float y, float z) {
556 TargRot.Rotate(x, y, z);
557 }
559 void TargetSpotLight::TargetRotate(const Vector3 &axis, float angle) {
560 TargRot.Rotate(axis, angle);
561 }
564 void TargetSpotLight::SetLight(dword index, GraphicsContext *gc) const {
565 Vector3 targ = Target;
566 targ.Transform(GetTargetTransform());
568 Vector3 pos = Position;
569 pos.Transform(GetTransform());
571 Vector3 *dir = const_cast<Vector3*>(&Direction);
572 *dir = (targ - pos).Normalized();
574 SpotLight::SetLight(index, gc);
575 }
577 void TargetSpotLight::Draw(GraphicsContext *gc, float size) {
578 Vector3 targ = Target;
579 targ.Transform(GetTargetTransform());
581 Vector3 pos = Position;
582 pos.Transform(GetTransform());
584 Direction = (targ - pos).Normalized();
585 SpotLight::Draw(gc, size);