Optimization du renderer.
This commit is contained in:
		| @@ -1,102 +1,105 @@ | ||||
| #include "world.h" | ||||
|  | ||||
| World::World(){} | ||||
| World::World() {} | ||||
|  | ||||
| World::~World(){} | ||||
| World::~World() {} | ||||
|  | ||||
| Array2d<Chunk*>& World::GetChunks() { return m_chunks; } | ||||
|  | ||||
| Chunk* World::ChunkAt(float x, float y, float z) const { | ||||
|     int cx = (int)x / CHUNK_SIZE_X; | ||||
|     int cz = (int)z / CHUNK_SIZE_Z; | ||||
| 	int cx = (int)x / CHUNK_SIZE_X; | ||||
| 	int cz = (int)z / CHUNK_SIZE_Z; | ||||
|  | ||||
|     if (x < 0 || y < 0 || z < 0 || | ||||
|         x >= WORLD_SIZE_X * CHUNK_SIZE_X ||  | ||||
|         z >= CHUNK_SIZE_Z * WORLD_SIZE_Y ||  | ||||
|         y > CHUNK_SIZE_Y) | ||||
|         return 0; | ||||
| 	if (x < 0 || y < 0 || z < 0 || | ||||
| 		x >= WORLD_SIZE_X * CHUNK_SIZE_X || | ||||
| 		z >= CHUNK_SIZE_Z * WORLD_SIZE_Y || | ||||
| 		y > CHUNK_SIZE_Y) | ||||
| 		return 0; | ||||
|  | ||||
|     return m_chunks.Get(cx, cz); | ||||
| 	return m_chunks.Get(cx, cz); | ||||
| } | ||||
|  | ||||
| Chunk* World::ChunkAt(const Vector3f& pos) const { return ChunkAt(pos.x, pos.y, pos.z); } | ||||
|  | ||||
| BlockType World::BlockAt(float x, float y, float z, BlockType defaultBlockType) const { | ||||
|     Chunk* c = ChunkAt(x, y, z); | ||||
| 	Chunk* c = ChunkAt(x, y, z); | ||||
|  | ||||
|     if (!c) | ||||
|         return defaultBlockType; | ||||
| 	if (!c) | ||||
| 		return defaultBlockType; | ||||
|  | ||||
|     int bx = (int)x % CHUNK_SIZE_X; | ||||
|     int by = (int)y % CHUNK_SIZE_Y; | ||||
|     int bz = (int)z % CHUNK_SIZE_Z; | ||||
| 	int bx = (int)x % CHUNK_SIZE_X; | ||||
| 	int by = (int)y % CHUNK_SIZE_Y; | ||||
| 	int bz = (int)z % CHUNK_SIZE_Z; | ||||
|  | ||||
|     return c->GetBlock(bx, by, bz); | ||||
| 	return c->GetBlock(bx, by, bz); | ||||
| } | ||||
|  | ||||
| BlockType World::BlockAt(const Vector3f& pos, BlockType defaultBlockType) const { | ||||
|     return BlockAt(pos.x, pos.y, pos.z, defaultBlockType); | ||||
| 	return BlockAt(pos.x, pos.y, pos.z, defaultBlockType); | ||||
| } | ||||
|  | ||||
| void World::TransposeWorld(Player& player) { | ||||
|     int x = 0; | ||||
|     int y = 0; | ||||
| 	int x = 0; | ||||
| 	int y = 0; | ||||
|  | ||||
|     if (player.GetPosition().x > (WORLD_SIZE_X * CHUNK_SIZE_X) * .66f) ++x; | ||||
|     else if (player.GetPosition().x < (WORLD_SIZE_X * CHUNK_SIZE_X) * .33f) --x; | ||||
|     if (player.GetPosition().z > (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .66f) ++y; | ||||
|     else if (player.GetPosition().z < (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .33f) --y; | ||||
| 	if (player.GetPosition().x > (WORLD_SIZE_X * CHUNK_SIZE_X) * .66f) ++x; | ||||
| 	else if (player.GetPosition().x < (WORLD_SIZE_X * CHUNK_SIZE_X) * .33f) --x; | ||||
| 	if (player.GetPosition().z > (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .66f) ++y; | ||||
| 	else if (player.GetPosition().z < (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .33f) --y; | ||||
|  | ||||
|     if (!x && !y) return; | ||||
| 	if (!x && !y) return; | ||||
|  | ||||
|     if (x != 0)  | ||||
|         for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)  | ||||
|             for (int ax = 0; ax < abs(x); ++ay) | ||||
|                 if (ChunkAt(x < 0 ? (WORLD_SIZE_X - 1 - ax) * WORLD_SIZE_X : ax, 1, ay * WORLD_SIZE_Y)) | ||||
|                     m_tbDeleted.push_back(std::move(m_chunks.Get(x < 0? WORLD_SIZE_X - 1 - ax: ax, ay))); | ||||
|     if (y != 0)  | ||||
|         for (int ax = 0; ax < WORLD_SIZE_X; ++ax) | ||||
|             for (int ay = 0; ay < abs(y); ++ay) | ||||
|                 if (ChunkAt(ax * WORLD_SIZE_X , 1, y < 0 ? (WORLD_SIZE_Y - 1 - ay) * WORLD_SIZE_Y : ay)) | ||||
|                     m_tbDeleted.push_back(std::move(m_chunks.Get(ax, y < 0 ? WORLD_SIZE_Y - 1 - ay: ay))); | ||||
|      | ||||
|     for (int ax = 0; ax < WORLD_SIZE_X; ++ax) | ||||
|         for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)  | ||||
|             if (ax + x < WORLD_SIZE_X && ax + x > 0 && | ||||
|                 ay + y < WORLD_SIZE_Y && ay + y > 0) | ||||
|                 m_chunks.Set(x > 0? ax: ax + x, y > 0? ay: ay + y,  | ||||
|                     m_chunks.Get(x < 0 ? ax : ax + x, y < 0 ? ay : ay + y)); | ||||
|     if (x != 0)  | ||||
|         for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) | ||||
|             for (int ax = 0; ax < abs(x); ++ay) | ||||
|                 m_chunks.Set(x > 0 ? WORLD_SIZE_X - 1 - ax : ax, ay, nullptr); | ||||
|     if (y != 0)  | ||||
|         for (int ax = 0; ax < WORLD_SIZE_X; ++ax) | ||||
|             for (int ay = 0; ay < abs(y); ++ay) | ||||
|                 m_chunks.Set(ax, y > 0 ? WORLD_SIZE_Y - 1 - ay : ay, nullptr); | ||||
|      | ||||
|     m_center[0] += x; m_center[1] += y; | ||||
|     player.Transpose(x, y); | ||||
| 	if (x > 0) { | ||||
| 		for (int ax = 0; ax < WORLD_SIZE_X; ++ax) | ||||
| 			for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) | ||||
| 				if (ax - x >= 0) | ||||
| 					m_chunks.Set(ax - x, ay, | ||||
| 						m_chunks.Remove(ax, ay)); | ||||
| 				else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); | ||||
| 	} | ||||
| 	else if (x < 0) { | ||||
| 		for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) | ||||
| 			for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay) | ||||
| 				if (ax - x < WORLD_SIZE_X) | ||||
| 					m_chunks.Set(ax - x, ay, | ||||
| 						m_chunks.Remove(ax, ay)); | ||||
| 				else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); | ||||
| 	} | ||||
|  | ||||
| 	if (y > 0) { | ||||
| 		for (int ax = 0; ax < WORLD_SIZE_X; ++ax) | ||||
| 			for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) | ||||
| 				if (ay - y >= 0) | ||||
| 					m_chunks.Set(ax, ay - y, | ||||
| 						m_chunks.Remove(ax, ay)); | ||||
| 				else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); | ||||
| 	} | ||||
| 	else if (y < 0) { | ||||
| 		for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) | ||||
| 			for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay) | ||||
| 				if (ay - y < WORLD_SIZE_Y) | ||||
| 					m_chunks.Set(ax, ay - y, | ||||
| 						m_chunks.Remove(ax, ay)); | ||||
| 				else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); | ||||
| 	} | ||||
|  | ||||
| 	m_center[0] += x; m_center[1] += y; | ||||
| 	player.Teleport(x, y); | ||||
| } | ||||
|  | ||||
| void World::CleanUpWorld(int& deleteframes, bool clear = false) { | ||||
| 	if (clear) m_tbDeleted.clear(); | ||||
|     if (!m_tbDeleted.empty() && !deleteframes) { | ||||
|         m_tbDeleted.pop_back(); | ||||
|         deleteframes = FRAMES_DELETE_CHUNKS; | ||||
|     } | ||||
| } | ||||
|  | ||||
| Chunk* World::RetrieveChunk(int x, int y) { | ||||
|     for (int index = 0; index < m_tbDeleted.size(); ++index) { | ||||
|         int cx, cy; | ||||
|         m_tbDeleted.at(index)->GetPosition(cx, cy); | ||||
|  | ||||
|         if (cx == x && cy == y)  | ||||
|             return std::move(m_tbDeleted.at(index)); | ||||
|     } | ||||
|  | ||||
|     return nullptr; | ||||
| 	if (clear) { | ||||
| 		while (m_tbDeleted.size() > 0) { | ||||
| 			delete m_tbDeleted.back(); | ||||
| 			m_tbDeleted.pop_back(); | ||||
| 		} | ||||
| 	} | ||||
| 	if (!m_tbDeleted.empty() && !deleteframes) { | ||||
| 		delete m_tbDeleted.back(); | ||||
| 		m_tbDeleted.pop_back(); | ||||
| 		deleteframes = FRAMES_DELETE_CHUNKS; | ||||
| 	} | ||||
| 	std::cout << "Chunk Write Buffer: " << m_tbDeleted.size() << std::endl; | ||||
| } | ||||
|  | ||||
| void World::GetScope(int& x, int& y) { | ||||
| @@ -106,25 +109,29 @@ void World::GetScope(int& x, int& y) { | ||||
|  | ||||
| void World::Update(int& rendercount, int& badhitcount, Player& player, Transformation& world, Shader& shader, TextureAtlas& atlas, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]) { | ||||
| 	atlas.Bind(); | ||||
| 	TransposeWorld(player); | ||||
| 	RenderWorld(rendercount, badhitcount, player, world, shader); | ||||
| 	TransposeWorld(player); | ||||
| 	UpdateWorld(player, perlin, blockinfo); | ||||
| 	shader.Disable(); | ||||
| } | ||||
|  | ||||
| bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { | ||||
|  | ||||
| 	if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z && | ||||
| 		chx >= 0 && chy >= 0) | ||||
| 		if (!ChunkAt(chx, 1, chy)) { | ||||
|  | ||||
| 			for (int index = 0; index < m_tbDeleted.size(); ++index) { // V<>rifie l'existence d'un chunk dans le buffer de suppression avec sa position. | ||||
| 				int x, y; | ||||
| 				m_tbDeleted.at(index)->GetPosition(x, y); | ||||
| 					if (chx / CHUNK_SIZE_X + m_center[0] == x &&  | ||||
|  | ||||
| 				if (&m_tbDeleted.at(index)) { | ||||
| 					m_tbDeleted.at(index)->GetPosition(x, y); | ||||
| 					if (chx / CHUNK_SIZE_X + m_center[0] == x && | ||||
| 						chy / CHUNK_SIZE_Z + m_center[1] == y) { | ||||
| 						GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, std::move(m_tbDeleted.at(index))); | ||||
| 						return true; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			std::ostringstream pos; // V<>rifie l'existence d'un fichier .chunk avec sa position. | ||||
| @@ -138,24 +145,20 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { | ||||
|  | ||||
| 				for (int x = 0; x < CHUNK_SIZE_X; ++x) | ||||
| 					for (int z = 0; z < CHUNK_SIZE_Z; ++z) { | ||||
| 						Vector3f noise; | ||||
| 						noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); | ||||
| 						noise.y = 0; | ||||
| 						noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); | ||||
| 						noise.Normalize(); | ||||
| 						float height = perlin.Get(noise.x, noise.z) * 3 - 32; | ||||
| 						for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y)  | ||||
| 						float xnoiz, ynoiz; | ||||
| 						xnoiz = (double)(x + (chx / CHUNK_SIZE_X + m_center[0]) * CHUNK_SIZE_X) / (double)INT16_MAX; | ||||
| 						ynoiz = (double)(z + (chy / CHUNK_SIZE_Z + m_center[1]) * CHUNK_SIZE_Z) / (double)INT16_MAX; | ||||
| 						float height = (perlin.Get(xnoiz, ynoiz)) * 10.f; | ||||
| 						for (int y = 0; y <= (int)height; ++y) | ||||
| 							chunk->SetBlock(x, y, z, BTYPE_METAL, this); | ||||
| 					} | ||||
|  | ||||
| 				for (int x = 0; x < CHUNK_SIZE_X; ++x) | ||||
| 					for (int z = 0; z < CHUNK_SIZE_Z; ++z) { | ||||
| 						Vector3f noise; | ||||
| 						noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); | ||||
| 						noise.y = 0; | ||||
| 						noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); | ||||
| 						noise.Normalize(); | ||||
| 						float height = perlin.Get(noise.x, noise.z) + 16; | ||||
| 						float xnoiz, ynoiz; | ||||
| 						xnoiz = (double)(x + (chx / CHUNK_SIZE_X + m_center[0]) * CHUNK_SIZE_X) / (double)INT16_MAX; | ||||
| 						ynoiz = (double)(z + (chy / CHUNK_SIZE_Z + m_center[1]) * CHUNK_SIZE_Z) / (double)INT16_MAX; | ||||
| 						float height = (perlin.Get(xnoiz, ynoiz) + 16.f); | ||||
| 						for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y) { | ||||
| 							if (chunk->GetBlock(x, y, z) == BTYPE_AIR) | ||||
| 								chunk->SetBlock(x, y, z, BTYPE_GRASS, this); | ||||
| @@ -164,25 +167,12 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { | ||||
|  | ||||
| 				for (int x = 0; x < CHUNK_SIZE_X; ++x) | ||||
| 					for (int z = 0; z < CHUNK_SIZE_Z; ++z) { | ||||
| 						for (int y = 0; y <= 10; ++y) { | ||||
| 						for (int y = 0; y < 15; ++y) { | ||||
| 							if (chunk->GetBlock(x, y, z) == BTYPE_AIR) | ||||
| 								chunk->SetBlock(x, y, z, BTYPE_ICE, this); | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 				for (int x = 0; x < CHUNK_SIZE_X; ++x) | ||||
| 					for (int z = 0; z < CHUNK_SIZE_Z; ++z) { | ||||
| 						for (int y = 0; y < CHUNK_SIZE_Y; ++y) { | ||||
| 							Vector3f noise; | ||||
| 							noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); | ||||
| 							noise.y = (x + z) * CHUNK_SIZE_Y + m_center[0]; | ||||
| 							noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); | ||||
| 							noise.Normalize(); | ||||
| 							float height = perlin.Get(noise.x, noise.y, noise.z); | ||||
| 							if (chunk->GetBlock(x, y, z) != BTYPE_AIR && height > 18) | ||||
| 								chunk->SetBlock(x, y, z, BTYPE_DIRT, this); | ||||
| 						} | ||||
| 					} | ||||
| 			} | ||||
| 			else { | ||||
| 				input.seekg(0, std::ios_base::end); | ||||
| @@ -197,7 +187,6 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { | ||||
|  | ||||
| 				delete[] data; | ||||
| 			} | ||||
| 			std::cout << "Chunk generated: " << chx / CHUNK_SIZE_X + m_center[0] << ", " << chy / CHUNK_SIZE_Z + m_center[1] << std::endl; | ||||
|  | ||||
| 			return true; | ||||
| 		} | ||||
| @@ -274,7 +263,7 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran | ||||
| 	shader.Use(); | ||||
| 	rendercount = 0; | ||||
| 	badhitcount = 0; | ||||
| 	static std::vector<Vector3i> renderManifest; | ||||
| 	//static std::vector<Vector3i> renderManifest; | ||||
| 	Vector3f angle; | ||||
| 	Vector3f cursor; | ||||
| 	Vector3f direct = player.GetDirection(); | ||||
| @@ -283,18 +272,61 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran | ||||
| 	direct.y = 0; | ||||
| 	direct.Normalize(); | ||||
| 	pos.y = 1; | ||||
| 	renderManifest.clear(); | ||||
| 	//renderManifest.clear(); | ||||
|  | ||||
| 	static Vector3i renderManifest[VIEW_DISTANCE * 4]; | ||||
|  | ||||
| 	for (int dist = VIEW_DISTANCE; dist >= 0; dist -= CHUNK_SIZE_X) { | ||||
| 		// Configuration du radar. | ||||
| 		angle.x = direct.z + direct.x; | ||||
| 		angle.y = 0; | ||||
| 		angle.z = direct.z - direct.x; | ||||
| 		angle.Normalize(); | ||||
| 		float sinus, cosinus; | ||||
| 		int echantillons; | ||||
|  | ||||
| 		float sinus = .01745240643; // sin(1 degr<67>) | ||||
| 		float cosinus = .99984769515; // cos(1 degr<67>) | ||||
| 		int echantillons = 90; | ||||
| 		if (dist > VIEW_DISTANCE * .375f) {  | ||||
| 			angle.x = direct.z + direct.x; | ||||
| 			angle.z = direct.z - direct.x; | ||||
| 			sinus = .01745240643; // sin(1 degr<67>) | ||||
| 			cosinus = .99984769515; // cos(1 degr<67>) | ||||
| 			echantillons = 90; | ||||
| 		} | ||||
| 		else if (dist > VIEW_DISTANCE * .5f) { | ||||
| 			angle.x = direct.z + direct.x; | ||||
| 			angle.z = direct.z - direct.x; | ||||
| 			sinus = .0261769483; | ||||
| 			cosinus = .99965732497; | ||||
| 			echantillons = 60; | ||||
| 		} | ||||
| 		else if (dist > VIEW_DISTANCE * .625f) { | ||||
| 			angle.x = direct.z + direct.x; | ||||
| 			angle.z = direct.z - direct.x; | ||||
| 			sinus = .0348994967; | ||||
| 			cosinus = .99939082701; | ||||
| 			echantillons = 45; | ||||
| 		} | ||||
| 		else /*if (dist > VIEW_DISTANCE * .75f)*/ {  | ||||
| 			angle.x = direct.z + direct.x; | ||||
| 			angle.z = direct.z - direct.x; | ||||
| 			sinus = .05233595624; | ||||
| 			cosinus = .99862953475; | ||||
| 			echantillons = 30; | ||||
| 		} | ||||
| 		//else if (dist > VIEW_DISTANCE * .875f) { // - CHUNK_SIZE_X * 28) { | ||||
| 		//	angle.x = direct.z; | ||||
| 		//	angle.z = -direct.x; | ||||
| 		//	sinus = .08715574274; | ||||
| 		//	cosinus = .996194698091; | ||||
| 		//	echantillons = 36; | ||||
| 		//	//echantillons = 0; | ||||
| 		//} | ||||
| 		//else { | ||||
| 		//	angle.x = direct.z; | ||||
| 		//	angle.z = -direct.x; | ||||
| 		//	sinus = .13052619222; | ||||
| 		//	cosinus = .99144486137; | ||||
| 		//	echantillons = 24; | ||||
| 		//} | ||||
|  | ||||
| 		angle.y = 0; | ||||
| 		angle.Normalize(); | ||||
|  | ||||
| 		for (int radar = 0; radar < echantillons; ++radar) { | ||||
| 			float x = angle.x; | ||||
| @@ -312,7 +344,7 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran | ||||
| 			if (ChunkAt(cursor)) { | ||||
| 				int chx, chy; | ||||
| 				ChunkAt(cursor)->GetPosition(chx, chy); | ||||
| 				for (int index = 0; index < renderManifest.size(); ++index) | ||||
| 				for (int index = 0; index < rendercount; ++index) | ||||
| 					if (renderManifest[index] == Vector3i(chx, 0, chy)) { | ||||
| 						valide = false; | ||||
| 						++badhitcount; | ||||
| @@ -326,8 +358,8 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran | ||||
| 					glBlendColor(0.f, 0.f, 0.f, blend); | ||||
| 					ChunkAt(cursor)->Render(); | ||||
| 					world.ApplyTranslation(-(chx - m_center[0]) * CHUNK_SIZE_X, 0, -(chy - m_center[1]) * CHUNK_SIZE_Z); | ||||
| 					renderManifest.push_back(Vector3i(chx, 0, chy)); | ||||
| 					++rendercount; | ||||
| 					renderManifest[++rendercount] = Vector3i(chx, 0, chy); | ||||
| 					//++rendercount; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user