Merge branch 'SQC-15_paquets' into SQC-15_animation
This commit is contained in:
		| @@ -1024,6 +1024,82 @@ std::vector<char*> netprot::recvPacks(SOCKET sock, Buffer* buf, Buffer* outbuf) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::vector<char*> netprot::recvPacksFrom(SOCKET sock, Buffer* buf, sockaddr_in from, Buffer* outbuf) { | ||||||
|  | 	std::vector<char*> lsPck; | ||||||
|  | 	int len = buf->tmp ? buf->tmp - buf->ptr : 0, | ||||||
|  | 		end = 0; | ||||||
|  | 	char* cursor = buf->tmp ? buf->tmp : nullptr, | ||||||
|  | 		* next = buf->tmp ? buf->tmp + 1 : buf->ptr, | ||||||
|  | 		* last = buf->tmp ? buf->tmp : buf->ptr; | ||||||
|  | 	bool ended = true; | ||||||
|  | 	struct pollfd fds[1]; | ||||||
|  | 	sockaddr_in sockad = from; | ||||||
|  | 	addrlen_t socklen = sizeof(sockad); | ||||||
|  |  | ||||||
|  | 	fds[0].fd = sock; | ||||||
|  | 	fds[0].events = POLLIN; | ||||||
|  |  | ||||||
|  | 	while (true) { | ||||||
|  | 		if (!poll(fds, 1, 0)) { | ||||||
|  | 			if (ended) | ||||||
|  | 				buf->tmp = nullptr; | ||||||
|  | 			return lsPck; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		int bytes = recvfrom(sock, &buf->ptr[len], buf->len - len, 0, (sockaddr*)&sockad, &socklen); | ||||||
|  | 		if (bytes <= 0) { // si recv() retourne -1 ou 0; ça veut dire qu'il y a plus rien a lire qui n'a pas déjà été traité. | ||||||
|  | 			if (ended) | ||||||
|  | 				buf->tmp = nullptr; | ||||||
|  | 			return lsPck; | ||||||
|  | 		} | ||||||
|  | 		len += bytes; | ||||||
|  | 		end = len; | ||||||
|  |  | ||||||
|  | 		ended = false; | ||||||
|  |  | ||||||
|  | 		while (true) { | ||||||
|  | 			int cmp = 0; | ||||||
|  |  | ||||||
|  | 			if (cursor) | ||||||
|  | 				end -= (cursor - buf->ptr); | ||||||
|  |  | ||||||
|  | 			if (end < 0) | ||||||
|  | 				break; | ||||||
|  |  | ||||||
|  | 			cursor = (char*)memchr(next, '\r', end); | ||||||
|  |  | ||||||
|  | 			if (cursor) { | ||||||
|  | 				next = cursor; | ||||||
|  | 				cursor--; | ||||||
|  |  | ||||||
|  | 				cmp = memcmp(cursor, Footer, sizeof(uint32_t)); | ||||||
|  | 				if (cmp == 0) { | ||||||
|  | 					if (!outbuf) { | ||||||
|  | 						lsPck.push_back(last); | ||||||
|  | 						cursor += sizeof(uint32_t); | ||||||
|  | 						last = cursor; | ||||||
|  | 						next = cursor + 1; | ||||||
|  | 					} | ||||||
|  | 					else { | ||||||
|  | 						memcpy(&outbuf->ptr[cursor - last], last, cursor - last); | ||||||
|  | 						lsPck.push_back(&outbuf->ptr[cursor - last]); | ||||||
|  | 						cursor += sizeof(uint32_t); | ||||||
|  | 						last = cursor; | ||||||
|  | 						next = cursor + 1; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				if (!outbuf) | ||||||
|  | 					buf->tmp = last; | ||||||
|  | 				cursor = &buf->ptr[len]; | ||||||
|  | 				next = cursor + 1; | ||||||
|  | 				break; | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| template <> | template <> | ||||||
| void netprot::sendPack<netprot::Packet>(SOCKET sock, Packet* pack, Buffer* buf) { | void netprot::sendPack<netprot::Packet>(SOCKET sock, Packet* pack, Buffer* buf) { | ||||||
| 	switch (pack->type) { | 	switch (pack->type) { | ||||||
|   | |||||||
| @@ -177,6 +177,7 @@ namespace netprot { | |||||||
| 	template <class T> void sendPackTo(SOCKET sock, T* pack, Buffer* buf, sockaddr_in* sockad); | 	template <class T> void sendPackTo(SOCKET sock, T* pack, Buffer* buf, sockaddr_in* sockad); | ||||||
| 	 | 	 | ||||||
| 	std::vector<char*> recvPacks(SOCKET sock, Buffer* buf, Buffer* oufbuf = nullptr); | 	std::vector<char*> recvPacks(SOCKET sock, Buffer* buf, Buffer* oufbuf = nullptr); | ||||||
|  | 	std::vector<char*> recvPacksFrom(SOCKET sock, Buffer* buf, sockaddr_in from, Buffer* oufbuf = nullptr); | ||||||
|  |  | ||||||
| 	/* Templates */ | 	/* Templates */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -192,6 +192,8 @@ void Player::ApplyTransformation(Transformation& transformation, bool rel) const | |||||||
| 	if (rel) transformation.ApplyTranslation(-GetPOV()); | 	if (rel) transformation.ApplyTranslation(-GetPOV()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void Player::SetDirection(Vector3f dir) { m_direction = dir; } | ||||||
|  |  | ||||||
| Vector3f Player::GetPosition() const { return Vector3f(m_position.x + CHUNK_SIZE_X * WORLD_SIZE_X / 2, m_position.y, m_position.z + CHUNK_SIZE_Z * WORLD_SIZE_Y / 2); } | Vector3f Player::GetPosition() const { return Vector3f(m_position.x + CHUNK_SIZE_X * WORLD_SIZE_X / 2, m_position.y, m_position.z + CHUNK_SIZE_Z * WORLD_SIZE_Y / 2); } | ||||||
|  |  | ||||||
| Vector3f Player::GetVelocity() const { return m_velocity; } | Vector3f Player::GetVelocity() const { return m_velocity; } | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ public: | |||||||
| 	Sound ApplyPhysics(Vector3f input, World* world, float elapsedTime); | 	Sound ApplyPhysics(Vector3f input, World* world, float elapsedTime); | ||||||
| 	void ApplyTransformation(Transformation& transformation, bool rel = true) const; | 	void ApplyTransformation(Transformation& transformation, bool rel = true) const; | ||||||
|  |  | ||||||
|  | 	void SetDirection(Vector3f dir); | ||||||
| 	Vector3f GetPosition() const; | 	Vector3f GetPosition() const; | ||||||
| 	Vector3f GetDirection() const; | 	Vector3f GetDirection() const; | ||||||
| 	Vector3f GetVelocity() const; | 	Vector3f GetVelocity() const; | ||||||
|   | |||||||
| @@ -16,6 +16,9 @@ void World::SetSeed(uint64_t seed) { | |||||||
| 	m_seed = seed; | 	m_seed = seed; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Chunk* World::ChunkAt(float x, float y, float z) const { | Chunk* World::ChunkAt(float x, float y, float z) const { | ||||||
| 	int cx = (int)x / CHUNK_SIZE_X; | 	int cx = (int)x / CHUNK_SIZE_X; | ||||||
| 	int cz = (int)z / CHUNK_SIZE_Z; | 	int cz = (int)z / CHUNK_SIZE_Z; | ||||||
| @@ -31,6 +34,32 @@ Chunk* World::ChunkAt(float x, float y, float z) const { | |||||||
|  |  | ||||||
| Chunk* World::ChunkAt(const Vector3f& pos) const { return ChunkAt(pos.x, pos.y, pos.z); } | Chunk* World::ChunkAt(const Vector3f& pos) const { return ChunkAt(pos.x, pos.y, pos.z); } | ||||||
|  |  | ||||||
|  | void World::RemoveChunk(int nbReduit) | ||||||
|  | { | ||||||
|  | 	for (int x = 0; x < WORLD_SIZE_X; ++x) | ||||||
|  | 		for (int y = 0; y < WORLD_SIZE_Y; ++y) | ||||||
|  | 		{ | ||||||
|  | 			Chunk* chk = nullptr; | ||||||
|  | 			if (x < nbReduit) | ||||||
|  | 				chk = m_chunks.Remove(x, y); | ||||||
|  | 			if (y < nbReduit) | ||||||
|  | 				chk = m_chunks.Remove(x, y); | ||||||
|  | 			if (y > WORLD_SIZE_Y - nbReduit) | ||||||
|  | 				chk = m_chunks.Remove(x, y); | ||||||
|  | 			if (x > WORLD_SIZE_X - nbReduit) | ||||||
|  | 				chk = m_chunks.Remove(x, y); | ||||||
|  |  | ||||||
|  | 			// TODO: MakeDirty() les voisins pour qu'ils se redessinent. | ||||||
|  |  | ||||||
|  | 			if (!chk) | ||||||
|  | 				continue; | ||||||
|  |  | ||||||
|  | 			m_tbDeleted.emplace_back(chk); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| BlockType World::BlockAt(float x, float y, float z, BlockType defaultBlockType) const { | BlockType World::BlockAt(float x, float y, float z, BlockType defaultBlockType) const { | ||||||
| 	Chunk* c = ChunkAt(x, y, z); | 	Chunk* c = ChunkAt(x, y, z); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,6 +28,8 @@ public: | |||||||
| 	Chunk* ChunkAt(float x, float y, float z) const; | 	Chunk* ChunkAt(float x, float y, float z) const; | ||||||
| 	Chunk* ChunkAt(const Vector3f& pos) const; | 	Chunk* ChunkAt(const Vector3f& pos) const; | ||||||
|  |  | ||||||
|  | 	void RemoveChunk(int nbReduit); | ||||||
|  |  | ||||||
| 	BlockType BlockAt(float x, float y, float z, BlockType defaultBlockType = BTYPE_AIR) const; | 	BlockType BlockAt(float x, float y, float z, BlockType defaultBlockType = BTYPE_AIR) const; | ||||||
| 	BlockType BlockAt(const Vector3f& pos, BlockType defaultBlockType = BTYPE_AIR) const; | 	BlockType BlockAt(const Vector3f& pos, BlockType defaultBlockType = BTYPE_AIR) const; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,6 +47,70 @@ PlayerInfo* Connection::getInfo() const { return (PlayerInfo*)&m_playinfo; } | |||||||
|  |  | ||||||
| sockaddr_in* Connection::getAddr() const { return (sockaddr_in*)&m_addr; } | sockaddr_in* Connection::getAddr() const { return (sockaddr_in*)&m_addr; } | ||||||
|  |  | ||||||
|  | void Connection::getPacks(SOCKET sock) { | ||||||
|  | 	std::vector<char*> lsPck; | ||||||
|  | 	Input in; | ||||||
|  | 	while (true) { | ||||||
|  | 		lsPck = recvPacksFrom(sock, &m_buf, m_addr); | ||||||
|  |  | ||||||
|  | 		for (auto& pck : lsPck) { | ||||||
|  | 			uint32_t bsize = m_buf.len - (pck - m_buf.ptr); | ||||||
|  | 			switch (netprot::getType(pck, 1)) { | ||||||
|  | 				using enum netprot::PACKET_TYPE; | ||||||
|  | 			case INPUT: | ||||||
|  | 				if (Deserialize(&in, pck, &bsize)) | ||||||
|  | 					m_input_manifest[in.timestamp] = in; | ||||||
|  | 				break; | ||||||
|  | 			default: break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		lsPck.clear(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Connection::sendPacks(SOCKET sock, std::unordered_map<uint64_t, Connection*> conns) { | ||||||
|  | 	while (m_last_out < m_output_manifest.size()) { | ||||||
|  | 		Output out = m_output_manifest.at(m_last_out++); | ||||||
|  |  | ||||||
|  | 		for (auto& [key, conn] : conns) { | ||||||
|  | 			if (m_playinfo.id == conn->GetHash(true)) | ||||||
|  | 				continue; | ||||||
|  | 			sendPackTo<Output>(sock, &out, &m_bufout, conn->getAddr()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Connection::Run(World* world) { | ||||||
|  | 	Input in, last; | ||||||
|  | 	Output out; | ||||||
|  | 	float el; | ||||||
|  |  | ||||||
|  | 	if (m_input_manifest.size() < 2) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	while (m_last_in < m_input_manifest.size()) { | ||||||
|  | 		in = m_input_manifest.at(m_last_in + 1); | ||||||
|  | 		last = m_input_manifest.at(m_last_in); | ||||||
|  |  | ||||||
|  | 		el = (float)(in.timestamp - last.timestamp) / 1000.; | ||||||
|  | 		player.get()->SetDirection(in.direction); | ||||||
|  | 		player.get()->ApplyPhysics(player.get()->GetInput(in.keys.forward,  | ||||||
|  | 														  in.keys.backward,  | ||||||
|  | 														  in.keys.left,  | ||||||
|  | 														  in.keys.right,  | ||||||
|  | 														  in.keys.jump, false, el), world, el); | ||||||
|  |  | ||||||
|  | 		out.position = player.get()->GetPosition(); | ||||||
|  | 		out.direction = in.direction; | ||||||
|  | 		out.timestamp = in.timestamp; | ||||||
|  | 		out.id = m_playinfo.id; | ||||||
|  |  | ||||||
|  | 		m_output_manifest[out.timestamp] = out; | ||||||
|  |  | ||||||
|  | 		++m_last_in; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| void Connection::CleanInputManifest(Timestamp time) { | void Connection::CleanInputManifest(Timestamp time) { | ||||||
| 	auto wat = m_input_manifest.find(time); | 	auto wat = m_input_manifest.find(time); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| #include "../SQCSim-common/player.h" | #include "../SQCSim-common/player.h" | ||||||
| #include "../SQCSim-common/vector3.h" | #include "../SQCSim-common/vector3.h" | ||||||
| #include "../SQCSim-common/netprotocol.h" | #include "../SQCSim-common/netprotocol.h" | ||||||
|  | #include "../SQCSim-common/world.h" | ||||||
| #include "define.h" | #include "define.h" | ||||||
|  |  | ||||||
| using namespace netprot; | using namespace netprot; | ||||||
| @@ -32,6 +33,11 @@ public: | |||||||
| 	PlayerInfo* getInfo() const; | 	PlayerInfo* getInfo() const; | ||||||
| 	sockaddr_in* getAddr() const; | 	sockaddr_in* getAddr() const; | ||||||
|  |  | ||||||
|  | 	void getPacks(SOCKET sock); | ||||||
|  | 	void sendPacks(SOCKET sock, std::unordered_map<uint64_t, Connection*> conns); | ||||||
|  |  | ||||||
|  | 	void Run(World* world); | ||||||
|  |  | ||||||
| 	void CleanInputManifest(Timestamp time); | 	void CleanInputManifest(Timestamp time); | ||||||
| private: | private: | ||||||
| 	std::unordered_map<Timestamp, Input> m_input_manifest; | 	std::unordered_map<Timestamp, Input> m_input_manifest; | ||||||
| @@ -43,5 +49,11 @@ private: | |||||||
| 	LoginInfo m_loginfo; | 	LoginInfo m_loginfo; | ||||||
| 	PlayerInfo m_playinfo; | 	PlayerInfo m_playinfo; | ||||||
|  |  | ||||||
|  | 	Timestamp m_startsync; | ||||||
|  |  | ||||||
|  | 	uint64_t m_last_in = 0,  | ||||||
|  | 			 m_last_out = 0; | ||||||
|  | 	Buffer m_buf, | ||||||
|  | 		   m_bufout; | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -155,7 +155,7 @@ int Server::Ready() { | |||||||
| 				play.tid = log->tid; | 				play.tid = log->tid; | ||||||
|  |  | ||||||
| 				sendPack<GameInfo>(sock, &m_game, &m_buf); | 				sendPack<GameInfo>(sock, &m_game, &m_buf); | ||||||
| 				std::unique_ptr<Connection> conn = std::make_unique<Connection>(sock, sockad, *log, play); | 				Connection* conn = new Connection(sock, sockad, *log, play); | ||||||
|  |  | ||||||
| 				for (auto& [key, player] : m_players) { | 				for (auto& [key, player] : m_players) { | ||||||
| 					sendPack<PlayerInfo>(player->getSock(), &play, &m_buf); // Envoyer les infos de joueur distant aux joueurs d<>j<EFBFBD> connect<63>s		 | 					sendPack<PlayerInfo>(player->getSock(), &play, &m_buf); // Envoyer les infos de joueur distant aux joueurs d<>j<EFBFBD> connect<63>s		 | ||||||
| @@ -175,13 +175,16 @@ int Server::Ready() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void Server::Run() { | void Server::Run() { | ||||||
|  | 	bool endgame = false; | ||||||
| 	Input in; | 	Input in; | ||||||
| 	sockaddr_in sockad; | 	sockaddr_in sockad; | ||||||
| 	addrlen_t socklen = sizeof(sockad); | 	addrlen_t socklen = sizeof(sockad); | ||||||
| 	 | 	 | ||||||
| 	Log("Debut de la partie...", false, false); | 	Log("Debut de la partie...", false, false); | ||||||
|  |  | ||||||
| 	m_world = std::make_unique<World>(); | 	int players = m_players.size(); | ||||||
|  |  | ||||||
|  | 	m_world = new World(); | ||||||
| 	m_world->SetSeed(m_game.seed); | 	m_world->SetSeed(m_game.seed); | ||||||
| 	m_world->GetChunks().Reset(nullptr); | 	m_world->GetChunks().Reset(nullptr); | ||||||
| 	m_world->BuildWorld(); | 	m_world->BuildWorld(); | ||||||
| @@ -198,32 +201,41 @@ void Server::Run() { | |||||||
| 		sendPack<Sync>(conn->getSock(), &sync, &m_buf); | 		sendPack<Sync>(conn->getSock(), &sync, &m_buf); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	while (true) { | 	while (!endgame) { | ||||||
| 		if (recvfrom(m_sock_udp, m_buf.ptr, m_buf.len, 0, (sockaddr*)&sockad, &socklen) > 0) { | 		for (auto& [key, conn] : m_players) { | ||||||
| 			Packet pck = getPack(&m_buf); | 			conn->getPacks(m_sock_udp); | ||||||
| 			switch (pck.type) { | 			conn->Run(m_world); | ||||||
| 				using enum netprot::PACKET_TYPE; | 			conn->sendPacks(m_sock_udp, m_players); | ||||||
|             	case ERR:			std::puts("ERROR!");		break; | 		} | ||||||
|                 case INPUT:			std::puts("INPUT!");		break; |  | ||||||
|                 case OUTPUT:		std::puts("OUTPUT!");		break; |  | ||||||
| 				case SYNC:			std::puts("SYNC!");			break; |  | ||||||
|                 case TEAMINF:		std::puts("TEAMINF!");		break; |  | ||||||
|                 case SELFINF:		std::puts("SELFINF!");		break; |  | ||||||
|                 case PLAYINF:		std::puts("PLAYINF!");		break; |  | ||||||
|                 case LOGINF:		std::puts("LOGINF!");		break; |  | ||||||
|                 case CHUNKMOD:		std::puts("CHUNKMOD!");		break; |  | ||||||
|                 case PLAYERMOD:		std::puts("PLAYERMOD!");	break; |  | ||||||
|                 case PICKUPMOD:		std::puts("PICKUPMOD!");	break; |  | ||||||
|                 case GAMEINFO:		std::puts("GAMEINFO!");		break; |  | ||||||
|                 case ENDINFO:		std::puts("ENDINFO!");		break; |  | ||||||
|                 case CHAT:			std::puts("CHAT!");			break; |  | ||||||
|                 case ERRLOG:		std::puts("ERRLOG!");		break; |  | ||||||
| 				case LAST_PACK:									[[falltrough]]; |  | ||||||
| 				default:			std::puts("wtf?!");			break; |  | ||||||
|             } |  | ||||||
| 			netprot::emptyPack(pck); |  | ||||||
|         } |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	//while (true) { | ||||||
|  | 	//	if (recvfrom(m_sock_udp, m_buf.ptr, m_buf.len, 0, (sockaddr*)&sockad, &socklen) > 0) { | ||||||
|  | 	//		Packet pck = getPack(&m_buf); | ||||||
|  | 	//		switch (pck.type) { | ||||||
|  | 	//			using enum netprot::PACKET_TYPE; | ||||||
|  |  //           	case ERR:			std::puts("ERROR!");		break; | ||||||
|  |  //               case INPUT:			std::puts("INPUT!");		break; | ||||||
|  |  //               case OUTPUT:		std::puts("OUTPUT!");		break; | ||||||
|  | 	//			case SYNC:			std::puts("SYNC!");			break; | ||||||
|  |  //               case TEAMINF:		std::puts("TEAMINF!");		break; | ||||||
|  |  //               case SELFINF:		std::puts("SELFINF!");		break; | ||||||
|  |  //               case PLAYINF:		std::puts("PLAYINF!");		break; | ||||||
|  |  //               case LOGINF:		std::puts("LOGINF!");		break; | ||||||
|  |  //               case CHUNKMOD:		std::puts("CHUNKMOD!");		break; | ||||||
|  |  //               case PLAYERMOD:		std::puts("PLAYERMOD!");	break; | ||||||
|  |  //               case PICKUPMOD:		std::puts("PICKUPMOD!");	break; | ||||||
|  |  //               case GAMEINFO:		std::puts("GAMEINFO!");		break; | ||||||
|  |  //               case ENDINFO:		std::puts("ENDINFO!");		break; | ||||||
|  |  //               case CHAT:			std::puts("CHAT!");			break; | ||||||
|  |  //               case ERRLOG:		std::puts("ERRLOG!");		break; | ||||||
|  | 	//			case LAST_PACK:									[[falltrough]]; | ||||||
|  | 	//			default:			std::puts("wtf?!");			break; | ||||||
|  |  //           } | ||||||
|  | 	//		netprot::emptyPack(pck); | ||||||
|  |  //       } | ||||||
|  | 	//} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| inline std::string Server::LogTimestamp() { | inline std::string Server::LogTimestamp() { | ||||||
|   | |||||||
| @@ -36,12 +36,12 @@ private: | |||||||
|  |  | ||||||
| 	Buffer m_buf; | 	Buffer m_buf; | ||||||
|  |  | ||||||
| 	std::unordered_map<uint64_t, std::unique_ptr<Connection>> m_players; | 	std::unordered_map<uint64_t, Connection*> m_players; | ||||||
| 	std::unordered_map<Timestamp, Chat> m_chatlog; | 	std::unordered_map<Timestamp, Chat> m_chatlog; | ||||||
| 	std::vector<uint64_t> m_ids; | 	std::vector<uint64_t> m_ids; | ||||||
| 	GameInfo m_game; | 	GameInfo m_game; | ||||||
|  |  | ||||||
| 	std::unique_ptr<World> m_world = nullptr; | 	World* m_world = nullptr; | ||||||
| 	const bool m_manual_setup = SRV_MANUAL_SETUP; | 	const bool m_manual_setup = SRV_MANUAL_SETUP; | ||||||
|  |  | ||||||
| 	std::string LogTimestamp(); | 	std::string LogTimestamp(); | ||||||
|   | |||||||
| @@ -276,9 +276,46 @@ void Engine::DrawMenu() | |||||||
| 	ShowCursor(); | 	ShowCursor(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Engine::Init()  { | void Engine::DrawPause() | ||||||
|  | { | ||||||
|  | 	static const int sTitle = 400; | ||||||
|  | 	static const int sButton = 225; | ||||||
|  |  | ||||||
|  | 	glDisable(GL_LIGHTING); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	glDisable(GL_DEPTH_TEST); | ||||||
|  | 	glDisable(GL_STENCIL_TEST); | ||||||
|  | 	glMatrixMode(GL_PROJECTION); | ||||||
|  | 	glPushMatrix(); | ||||||
|  | 	glLoadIdentity(); | ||||||
|  | 	glOrtho(0, Width(), 0, Height(), -1, 1); | ||||||
|  | 	glMatrixMode(GL_MODELVIEW); | ||||||
|  | 	glPushMatrix(); | ||||||
|  |  | ||||||
|  | 	PauseBGTexture.Bind(); | ||||||
|  | 	glLoadIdentity(); | ||||||
|  | 	glBegin(GL_QUADS); | ||||||
|  | 	glTexCoord2f(0, 0); | ||||||
|  | 	glVertex2i(0, 0); | ||||||
|  | 	glTexCoord2f(1, 0); | ||||||
|  | 	glVertex2i(800, 0); | ||||||
|  | 	glTexCoord2f(1, 1); | ||||||
|  | 	glVertex2i(800, 600); | ||||||
|  | 	glTexCoord2f(0, 1); | ||||||
|  | 	glVertex2i(0, 600); | ||||||
|  | 	glEnd(); | ||||||
|  |  | ||||||
|  | 	glDisable(GL_BLEND); | ||||||
|  | 	glEnable(GL_DEPTH_TEST); | ||||||
|  | 	glMatrixMode(GL_PROJECTION); | ||||||
|  | 	glPopMatrix(); | ||||||
|  | 	glMatrixMode(GL_MODELVIEW); | ||||||
|  | 	glPopMatrix(); | ||||||
|  | 	ShowCursor(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Engine::Init() { | ||||||
|  |  | ||||||
| 	GLenum glewErr = glewInit(); | 	GLenum glewErr = glewInit(); | ||||||
| 	if (glewErr != GLEW_OK) { | 	if (glewErr != GLEW_OK) { | ||||||
| @@ -307,6 +344,10 @@ void Engine::Init()  { | |||||||
| 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||||
| 	glBlendEquation(GL_FUNC_SUBTRACT); | 	glBlendEquation(GL_FUNC_SUBTRACT); | ||||||
|  |  | ||||||
|  | 	if (m_istarted) | ||||||
|  | 		return; | ||||||
|  | 	else m_istarted = true; | ||||||
|  |  | ||||||
| 	//  | 	//  | ||||||
| 	// Objet de skybox avec sa propre texture et son propre shader! | 	// Objet de skybox avec sa propre texture et son propre shader! | ||||||
| 	m_skybox.Init(0.2f); | 	m_skybox.Init(0.2f); | ||||||
| @@ -396,15 +437,12 @@ void Engine::LoadResource() { | |||||||
|  |  | ||||||
| 	LoadTexture(MenuTitleTexture, TEXTURE_PATH "BrouillonbackgroundMenu.png"); | 	LoadTexture(MenuTitleTexture, TEXTURE_PATH "BrouillonbackgroundMenu.png"); | ||||||
| 	LoadTexture(MenuBGTexture, TEXTURE_PATH "BrouillonbackgroundMenu.png"); | 	LoadTexture(MenuBGTexture, TEXTURE_PATH "BrouillonbackgroundMenu.png"); | ||||||
|  | 	LoadTexture(PauseBGTexture, TEXTURE_PATH "BrouillonbackgroundMenu.png"); | ||||||
| 	LoadTexture(SplachScreenTexture, TEXTURE_PATH "sc2.png"); | 	LoadTexture(SplachScreenTexture, TEXTURE_PATH "sc2.png"); | ||||||
| 	LoadTexture(MenuQuitTexture, MENU_ITEM_PATH "BasicQuit.png"); | 	LoadTexture(MenuQuitTexture, MENU_ITEM_PATH "BasicQuit.png"); | ||||||
| 	LoadTexture(MenuOptionsTexture, MENU_ITEM_PATH "test.png"); | 	LoadTexture(MenuOptionsTexture, MENU_ITEM_PATH "test.png"); | ||||||
| 	LoadTexture(MenuStartTexture, MENU_ITEM_PATH "BasicPlay.png"); | 	LoadTexture(MenuStartTexture, MENU_ITEM_PATH "BasicPlay.png"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	TextureAtlas::TextureIndex texDirtIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal3.png"); | 	TextureAtlas::TextureIndex texDirtIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal3.png"); | ||||||
| 	TextureAtlas::TextureIndex texIceIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal2.png"); | 	TextureAtlas::TextureIndex texIceIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal2.png"); | ||||||
| 	TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png"); | 	TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png"); | ||||||
| @@ -895,7 +933,13 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { | |||||||
| 	glPushMatrix(); | 	glPushMatrix(); | ||||||
|  |  | ||||||
| 	int timer = GetCountdown(elapsedTime); | 	int timer = GetCountdown(elapsedTime); | ||||||
|  | 	for (int i = 1; i < WORLD_SIZE_X; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (timer <= COUNTDOWN - m_timerReductionChunk * i) { | ||||||
|  | 			m_world.RemoveChunk(m_nbReductionChunk * i); | ||||||
|  | 			m_renderer.RemoveChunk(m_nbReductionChunk * i); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if (m_keyK) { | 	if (m_keyK) { | ||||||
| 		SystemNotification(m_messageNotification); | 		SystemNotification(m_messageNotification); | ||||||
| 		m_keyK = false; | 		m_keyK = false; | ||||||
| @@ -960,12 +1004,13 @@ void Engine::PrintText(float x, float y, const std::string& t, float charSizeMul | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int Engine::GetFps(float elapsedTime) const { return 1 / elapsedTime; } | int Engine::GetFps(float elapsedTime) const { return 1 / elapsedTime; } | ||||||
|  |  | ||||||
| int Engine::GetCountdown(float elapsedTime) { | int Engine::GetCountdown(float elapsedTime) { | ||||||
| 	if (m_resetcountdown) | 	if (m_resetcountdown) | ||||||
| 	{ | 	{ | ||||||
|  | 		m_nbReductionChunk = 4; | ||||||
|  | 		m_timerReductionChunk = 30; | ||||||
| 		m_countdown = m_time + COUNTDOWN; | 		m_countdown = m_time + COUNTDOWN; | ||||||
| 		m_resetcountdown = false; | 		m_resetcountdown = false; | ||||||
| 	} | 	} | ||||||
| @@ -1001,7 +1046,6 @@ void Engine::Render(float elapsedTime) { | |||||||
|  |  | ||||||
| 		Transformation all; | 		Transformation all; | ||||||
| 		Transformation skybox; | 		Transformation skybox; | ||||||
| 		Transformation remotePlayer; |  | ||||||
| 		Vector3f vstep; | 		Vector3f vstep; | ||||||
|  |  | ||||||
| 		// Transformations initiales | 		// Transformations initiales | ||||||
| @@ -1032,16 +1076,15 @@ void Engine::Render(float elapsedTime) { | |||||||
| 			pollTime = 0; | 			pollTime = 0; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		RenderRemotePlayers(m_remotePlayer, pollTime); |  | ||||||
|  |  | ||||||
| 		m_player.ApplyTransformation(all); | 		m_player.ApplyTransformation(all); | ||||||
|  |  | ||||||
| 		m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation  | 		m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation  | ||||||
| 		// (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!). | 		// (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!). | ||||||
| 		 | 		 | ||||||
|  |  | ||||||
|  |  | ||||||
| 		 | 		 | ||||||
| 	 | 		//m_remotePlayer.ApplyTransformation(all); | ||||||
|  |  | ||||||
| 		if (m_mouseWU) bloc++; | 		if (m_mouseWU) bloc++; | ||||||
| 		else if (m_mouseWD) bloc--; | 		else if (m_mouseWD) bloc--; | ||||||
| @@ -1097,16 +1140,15 @@ void Engine::Render(float elapsedTime) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); | 		if (m_isSkybox) m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); | ||||||
| 		m_world.Update(m_bullets, m_player.GetPosition(), m_blockinfo); | 		m_world.Update(m_bullets, m_player.GetPosition(), m_blockinfo); | ||||||
| 		m_renderer.UpdateMesh(&m_world, m_player.GetPosition(), m_blockinfo); | 		m_renderer.UpdateMesh(&m_world, m_player.GetPosition(), m_blockinfo); | ||||||
|  |  | ||||||
|  | 		m_remotePlayer.Render(m_textureAtlas, m_shader01, elapsedTime); | ||||||
| 		if (m_isSkybox) m_skybox.Render(skybox); | 		if (m_isSkybox) m_skybox.Render(skybox); | ||||||
|  |  | ||||||
|  | 		if (m_isSkybox) DrawHud(elapsedTime, bloc); | ||||||
|  | 		if (m_isSkybox) DisplayPovGun(); | ||||||
| 		DrawHud(elapsedTime, bloc); |  | ||||||
| 		DisplayPovGun(); |  | ||||||
| 		ProcessNotificationQueue(); | 		ProcessNotificationQueue(); | ||||||
| 		if (m_damage) | 		if (m_damage) | ||||||
| 		{ | 		{ | ||||||
| @@ -1122,14 +1164,26 @@ void Engine::Render(float elapsedTime) { | |||||||
| 			fell = false; | 			fell = false; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (m_networkgame) { | 		if (m_networkgame) { // Pour se gerer le paquet. | ||||||
| 			using namespace std::chrono; | 			using namespace std::chrono; | ||||||
| 			using namespace netprot; | 			using namespace netprot; | ||||||
|  | 			Timestamp tstamp = duration_cast<milliseconds>(high_resolution_clock::now() - m_startTime).count(); | ||||||
| 			Input input; | 			Input input; | ||||||
|  | 			Sync sync; | ||||||
|  | 			uint64_t id = m_conn.getId(); | ||||||
|  | 			static std::vector<char*> lsPck; | ||||||
|  |  | ||||||
| 			input.sid = m_conn.getId(); | 			if (false) { // TODO: Faire un checkup pour chaque ~1000ms. | ||||||
|  | 				sync.sid = id; | ||||||
|  | 				sync.timestamp = tstamp; | ||||||
|  | 				sync.position = m_player.GetPosition(); | ||||||
|  | 				sync.hp = m_player.GetHP(); | ||||||
|  | 				// TODO: Garrocher ca quelque-part.  | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			input.sid = id; | ||||||
| 			input.direction = m_player.GetDirection(); | 			input.direction = m_player.GetDirection(); | ||||||
| 			input.timestamp = duration_cast<milliseconds>(high_resolution_clock::now() - m_startTime).count(); | 			input.timestamp = tstamp; | ||||||
| 			input.keys.forward = m_keyW; | 			input.keys.forward = m_keyW; | ||||||
| 			input.keys.backward = m_keyS; | 			input.keys.backward = m_keyS; | ||||||
| 			input.keys.left = m_keyA; | 			input.keys.left = m_keyA; | ||||||
| @@ -1138,13 +1192,38 @@ void Engine::Render(float elapsedTime) { | |||||||
| 			input.keys.block = m_mouseR; | 			input.keys.block = m_mouseR; | ||||||
| 			input.keys.shoot = m_mouseL; | 			input.keys.shoot = m_mouseL; | ||||||
|  |  | ||||||
| 			sendPackTo<Input>(m_conn.m_sock_udp, &input, &m_buf, &m_conn.m_srvsockaddr); | 			sendPackTo<Input>(m_conn.m_sock_udp, &input, &m_bufout, &m_conn.m_srvsockaddr); | ||||||
|  |  | ||||||
| 			// TODO: Faire la gestion de la réception de paquets. |  | ||||||
|  |  | ||||||
|  | 			lsPck = recvPacks(m_conn.m_sock_udp, &m_buf); | ||||||
|  | 			char* prevptr = nullptr; | ||||||
|  | 			for (auto& pck : lsPck) { // We could make a few threads out of this. | ||||||
|  | 				Sync sync; | ||||||
|  | 				Output out; | ||||||
|  | 				if (!prevptr) | ||||||
|  | 					prevptr = m_buf.ptr; | ||||||
|  | 				uint32_t bsize = m_buf.len - (pck - prevptr); | ||||||
|  | 				prevptr = pck; | ||||||
|  | 				switch (getType(pck, 1)) { | ||||||
|  | 					using enum PACKET_TYPE; | ||||||
|  | 				case SYNC: | ||||||
|  | 					if (Deserialize(&sync, pck, &bsize)) { | ||||||
|  | 						if (sync.sid != m_conn.getId()) | ||||||
|  | 							break; | ||||||
|  | 						// TODO: Vérifier si les positions concordent au sync local. | ||||||
|  | 					} | ||||||
|  | 					break; | ||||||
|  | 				case OUTPUT: | ||||||
|  | 					if (Deserialize(&out, pck, &bsize)) { | ||||||
|  | 						RemotePlayer* r = (RemotePlayer*)m_players[out.id]; | ||||||
|  | 						r->Feed(out); | ||||||
|  | 					} | ||||||
|  | 					break; | ||||||
|  | 				default: | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			lsPck.clear(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| 	else if (m_gamestate == GameState::MAIN_MENU || m_gamestate == GameState::OPTIONS) | 	else if (m_gamestate == GameState::MAIN_MENU || m_gamestate == GameState::OPTIONS) | ||||||
| 	{ | 	{ | ||||||
| @@ -1155,11 +1234,12 @@ void Engine::Render(float elapsedTime) { | |||||||
| 			DrawMenu(); | 			DrawMenu(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	else if (m_gamestate == GameState::PAUSE) | ||||||
|  | 	{ | ||||||
|  | 		DrawPause(); | ||||||
|  | 	} | ||||||
| 	else if (m_gamestate == GameState::QUIT) | 	else if (m_gamestate == GameState::QUIT) | ||||||
| 		Stop(); | 		Stop(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Engine::KeyPressEvent(unsigned char key) { | void Engine::KeyPressEvent(unsigned char key) { | ||||||
| @@ -1185,7 +1265,14 @@ void Engine::KeyPressEvent(unsigned char key) { | |||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case 36: // ESC - Quitter | 	case 36: // ESC - Quitter | ||||||
| 		m_gamestate = GameState::MAIN_MENU; | 		if (m_gamestate == GameState::PLAY) | ||||||
|  | 		{ | ||||||
|  | 			m_gamestate = GameState::PAUSE; | ||||||
|  | 		} | ||||||
|  | 		else if (m_gamestate == GameState::PAUSE) | ||||||
|  | 		{ | ||||||
|  | 			m_gamestate = GameState::PLAY; | ||||||
|  | 		} | ||||||
| 		//Stop(); | 		//Stop(); | ||||||
| 		break; | 		break; | ||||||
| 	case 57: // Space - Sauter | 	case 57: // Space - Sauter | ||||||
| @@ -1420,7 +1507,3 @@ bool Engine::LoadTexture(Texture& texture, const std::string& filename, bool use | |||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| void Engine::RenderRemotePlayers(RemotePlayer& remoteplayer, float elapsedTime) |  | ||||||
| { |  | ||||||
| 	remoteplayer.Render(m_textureAtlas, m_shader01, elapsedTime); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ public: | |||||||
|     Engine(); |     Engine(); | ||||||
|     virtual ~Engine(); |     virtual ~Engine(); | ||||||
|     virtual void DrawMenu(); |     virtual void DrawMenu(); | ||||||
|  |     virtual void DrawPause(); | ||||||
|     virtual void DrawSplachScreen(); |     virtual void DrawSplachScreen(); | ||||||
|     virtual void Init(); |     virtual void Init(); | ||||||
|     virtual void DeInit(); |     virtual void DeInit(); | ||||||
| @@ -94,17 +95,18 @@ private: | |||||||
|     Bullet* m_bullets[MAX_BULLETS]; |     Bullet* m_bullets[MAX_BULLETS]; | ||||||
|  |  | ||||||
|     std::unordered_map<uint64_t, Player*> m_players; |     std::unordered_map<uint64_t, Player*> m_players; | ||||||
|     netprot::Buffer m_buf; |     netprot::Buffer m_buf, m_bufout; | ||||||
|     std::chrono::high_resolution_clock::time_point m_startTime; |     std::chrono::high_resolution_clock::time_point m_startTime; | ||||||
|  |  | ||||||
|     //Menu |     //Menu | ||||||
|     enum class GameState: uint8_t { MAIN_MENU, OPTIONS, QUIT, NEWG, PLAY }; |     enum class GameState: uint8_t { MAIN_MENU, OPTIONS, QUIT, NEWG, PLAY, PAUSE }; | ||||||
|     GameState m_gamestate = GameState::MAIN_MENU; |     GameState m_gamestate = GameState::MAIN_MENU; | ||||||
|     Texture MenuTitleTexture; |     Texture MenuTitleTexture; | ||||||
|     Texture MenuBGTexture; |     Texture MenuBGTexture; | ||||||
|     Texture MenuStartTexture; |     Texture MenuStartTexture; | ||||||
|     Texture MenuQuitTexture; |     Texture MenuQuitTexture; | ||||||
|     Texture MenuOptionsTexture; |     Texture MenuOptionsTexture; | ||||||
|  |     Texture PauseBGTexture; | ||||||
|     Texture SplachScreenTexture; |     Texture SplachScreenTexture; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -118,6 +120,8 @@ private: | |||||||
|  |  | ||||||
|     int m_renderCount = 0; |     int m_renderCount = 0; | ||||||
|     int m_countdown = COUNTDOWN; |     int m_countdown = COUNTDOWN; | ||||||
|  |     int m_nbReductionChunk = 4; | ||||||
|  |     int m_timerReductionChunk = 30; | ||||||
|  |  | ||||||
|     bool m_damage = false; |     bool m_damage = false; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ Mesh::~Mesh() { | |||||||
| void Mesh::FlushMeshToVBO() { | void Mesh::FlushMeshToVBO() { | ||||||
|     m_vertexBuffer.SetMeshData(m_vd, m_vcount); |     m_vertexBuffer.SetMeshData(m_vd, m_vcount); | ||||||
|     m_vcount = 0; |     m_vcount = 0; | ||||||
|     //delete[] m_vd; |     delete[] m_vd; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Mesh::FlushVBO() { | void Mesh::FlushVBO() { | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ private: | |||||||
|     Chunk* m_chunk; // NE PAS D<>TRUIRE ICI. |     Chunk* m_chunk; // NE PAS D<>TRUIRE ICI. | ||||||
|  |  | ||||||
|     void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s, World* world); |     void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s, World* world); | ||||||
|  |     void RemoveChunk(int nbReduit); | ||||||
| public: | public: | ||||||
|     Mesh(Chunk* chunk); |     Mesh(Chunk* chunk); | ||||||
|     ~Mesh(); |     ~Mesh(); | ||||||
|   | |||||||
| @@ -52,6 +52,8 @@ protected: | |||||||
|     void HideCursor(); |     void HideCursor(); | ||||||
|     void ShowCrossCursor() const; |     void ShowCrossCursor() const; | ||||||
|  |  | ||||||
|  |     bool m_istarted = false; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     void InitWindow(int width, int height); |     void InitWindow(int width, int height); | ||||||
|     MOUSE_BUTTON ConvertMouseButton(sf::Mouse::Button button) const; |     MOUSE_BUTTON ConvertMouseButton(sf::Mouse::Button button) const; | ||||||
|   | |||||||
| @@ -71,101 +71,20 @@ void RemotePlayer::Feed(const netprot::Output out) { | |||||||
|  |  | ||||||
| void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, float elapsedTime) | void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, float elapsedTime) | ||||||
| { | { | ||||||
| 	m_texture_front.Bind(); |  | ||||||
| 	shader.Use(); | 	shader.Use(); | ||||||
|  | 	//m_texture_front.Bind(); | ||||||
|  |  | ||||||
| 	//float x = current.position.x; |  | ||||||
| 	//float y = current.position.y; |  | ||||||
| 	//float z = current.position.z; |  | ||||||
|  |  | ||||||
| 	float x = 128.0f; | 	float u, v, w, h; | ||||||
| 	float y = 21.0f; | 	atlas.Bind(); | ||||||
| 	float z = 128.0f; | 	atlas.TextureIndexToCoord(0, u, v, w, h); | ||||||
| 	 |  | ||||||
| 	float quadSize = 300.0f;  |  | ||||||
| 	glBegin(GL_QUADS); | 	glBegin(GL_QUADS); | ||||||
| 	glNormal3f(0, 0, 1); | 	glTexCoord2f(u, v); glVertex3f(0, 50., 0); | ||||||
|  | 	glTexCoord2f(u+w, v); glVertex3f(50., 50., 0); | ||||||
| 	// Face avant | 	glTexCoord2f(u+w, v+h); glVertex3f(50., 0, 0); | ||||||
| 	glTexCoord2f(0, 0); | 	glTexCoord2f(u, v+h); glVertex3f(0, 0, 0); | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	// Face arri<72>re |  | ||||||
| 	glTexCoord2f(0, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	// Face droite |  | ||||||
| 	glTexCoord2f(0, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	// Face gauche |  | ||||||
| 	glTexCoord2f(0, 0); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	// Face sup<75>rieure |  | ||||||
| 	glTexCoord2f(0, 0); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y + quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	// Face inf<6E>rieure |  | ||||||
| 	glTexCoord2f(0, 0); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 0); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z - quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(1, 1); |  | ||||||
| 	glVertex3f(x + quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glTexCoord2f(0, 1); |  | ||||||
| 	glVertex3f(x - quadSize / 2, y - quadSize / 2, z + quadSize / 2); |  | ||||||
|  |  | ||||||
| 	glEnd(); | 	glEnd(); | ||||||
|  | 	shader.Disable(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool RemotePlayer::LoadTexture(Texture& texture, const std::string& filename, bool useMipmaps, bool stopOnError) | bool RemotePlayer::LoadTexture(Texture& texture, const std::string& filename, bool useMipmaps, bool stopOnError) | ||||||
|   | |||||||
| @@ -7,6 +7,32 @@ Renderer::Renderer() { | |||||||
| Renderer::~Renderer() { | Renderer::~Renderer() { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void Renderer::RemoveChunk(int nbReduit) | ||||||
|  | { | ||||||
|  | 	for (int x = 0; x < WORLD_SIZE_X; ++x) | ||||||
|  | 		for (int y = 0; y < WORLD_SIZE_Y; ++y) | ||||||
|  | 		{ | ||||||
|  | 			Mesh* chk = nullptr; | ||||||
|  | 			if (x < nbReduit) | ||||||
|  | 				chk = m_meshes.Remove(x, y); | ||||||
|  | 			if (y < nbReduit) | ||||||
|  | 				chk = m_meshes.Remove(x, y); | ||||||
|  | 			if (y > WORLD_SIZE_Y - nbReduit) | ||||||
|  | 				chk = m_meshes.Remove(x, y); | ||||||
|  | 			if (x > WORLD_SIZE_X - nbReduit) | ||||||
|  | 				chk = m_meshes.Remove(x, y); | ||||||
|  |  | ||||||
|  | 			// TODO: MakeDirty() les voisins pour qu'ils se redessinent. | ||||||
|  |  | ||||||
|  | 			if (!chk) | ||||||
|  | 				continue; | ||||||
|  |  | ||||||
|  | 			delete chk; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| void Renderer::RenderWorld(World* origin, int& rendercount, const Vector3f& player_pos, const Vector3f& player_dir, Transformation& world, Shader& shader, TextureAtlas& atlas) const { | void Renderer::RenderWorld(World* origin, int& rendercount, const Vector3f& player_pos, const Vector3f& player_dir, Transformation& world, Shader& shader, TextureAtlas& atlas) const { | ||||||
| 	rendercount = 0; | 	rendercount = 0; | ||||||
| 	Vector3f angle; | 	Vector3f angle; | ||||||
|   | |||||||
| @@ -21,6 +21,8 @@ public: | |||||||
| 	Renderer(); | 	Renderer(); | ||||||
| 	~Renderer(); | 	~Renderer(); | ||||||
|  |  | ||||||
|  | 	void RemoveChunk(int nbReduit); | ||||||
|  |  | ||||||
| 	void UpdateMesh(World* origin, const Vector3f& player, BlockInfo* blockinfo[BTYPE_LAST]); | 	void UpdateMesh(World* origin, const Vector3f& player, BlockInfo* blockinfo[BTYPE_LAST]); | ||||||
|  |  | ||||||
| 	void RenderWorld(World* origin, int& rendercount, const Vector3f& player_pos, const Vector3f& player_dir, Transformation& world, Shader& shader, TextureAtlas& atlas) const; | 	void RenderWorld(World* origin, int& rendercount, const Vector3f& player_pos, const Vector3f& player_dir, Transformation& world, Shader& shader, TextureAtlas& atlas) const; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user