1 /*
2  Copyright (c) 2013 yvt
3 
4  This file is part of OpenSpades.
5 
6  OpenSpades is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OpenSpades is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OpenSpades.  If not, see <http://www.gnu.org/licenses/>.
18 
19  */
20 
21 #pragma once
22 
23 #include <vector>
24 #include <atomic>
25 
26 #include <Core/Debug.h>
27 #include <Core/Math.h>
28 #include "IGLDevice.h"
29 
30 namespace spades {
31 	namespace client {
32 		class GameMap;
33 	}
34 	namespace draw {
35 		class GLRenderer;
36 		class IGLDevice;
37 		class GLAmbientShadowRenderer {
38 
39 			class UpdateDispatch;
40 			enum { NumRays = 16, ChunkSize = 16, ChunkSizeBits = 4 };
41 			GLRenderer *renderer;
42 			IGLDevice *device;
43 			client::GameMap *map;
44 			Vector3 rays[NumRays];
45 
46 			struct Chunk {
47 				int cx, cy, cz;
48 				float data[ChunkSize][ChunkSize][ChunkSize];
49 				bool dirty = true;
50 				int dirtyMinX = 0, dirtyMaxX = ChunkSize - 1;
51 				int dirtyMinY = 0, dirtyMaxY = ChunkSize - 1;
52 				int dirtyMinZ = 0, dirtyMaxZ = ChunkSize - 1;
53 
54 				std::atomic<bool> transferDone {true};
55 			};
56 
57 			IGLDevice::UInteger texture;
58 
59 			int w, h, d;
60 			int chunkW, chunkH, chunkD;
61 
62 			std::vector<Chunk> chunks;
63 
GetChunk(int cx,int cy,int cz)64 			inline Chunk &GetChunk(int cx, int cy, int cz) {
65 				SPAssert(cx >= 0);
66 				SPAssert(cx < chunkW);
67 				SPAssert(cy >= 0);
68 				SPAssert(cy < chunkH);
69 				SPAssert(cz >= 0);
70 				SPAssert(cz < chunkD);
71 				return chunks[(cx + cy * chunkW) * chunkD + cz];
72 			}
73 
GetChunkWrapped(int cx,int cy,int cz)74 			inline Chunk &GetChunkWrapped(int cx, int cy, int cz) {
75 				// FIXME: support for non-POT dimensions?
76 				return GetChunk(cx & (chunkW - 1), cy & (chunkH - 1), cz);
77 			}
78 
79 			void Invalidate(int minX, int minY, int minZ, int maxX, int maxY, int maxZ);
80 
81 			void UpdateChunk(int cx, int cy, int cz);
82 			void UpdateDirtyChunks();
83 			int GetNumDirtyChunks();
84 
85 			UpdateDispatch *dispatch;
86 
87 		public:
88 			GLAmbientShadowRenderer(GLRenderer *renderer, client::GameMap *map);
89 			~GLAmbientShadowRenderer();
90 
91 			float Evaluate(IntVector3);
92 
93 			void GameMapChanged(int x, int y, int z, client::GameMap *);
94 
95 			void Update();
96 
GetTexture()97 			IGLDevice::UInteger GetTexture() { return texture; }
98 		};
99 	}
100 }
101