summaryrefslogblamecommitdiffstats
path: root/src/Render.cpp
blob: 7e880684a0e8a4665781f0c324155d5dc3be17a6 (plain) (tree)
1
2
3
4
5
6
7
8






                           
                                                                                                                                    























                                                                                                                  

                                         














                                                                                              

                                                          



                                   

                                     
                                                                             
                                                      


                            
                                             
                                                       
 
                    




                                            
 












                                                                                           

                                                               


                                                               








                                                               
                                                                                                                        































                                                                                                                   


                                                                                                                


                                                      














                                                                                                              


                                                                                                                  


                              


                                      
                







                                                                                             
                                                                                                                                        









                                                                                                        
                               
 
                                                                                                
                                                                           
                                                  



                                                                                          
                                                       
                                                          


                                                                                              








                                                                                                   
 






                                                                                          
                                                        
       
        





                                                          

                                                          





                                                                                                                        

                               
                                                           
 
#include "Render.hpp"

#include "Utility.hpp"
#include "Shader.hpp"
#include "AssetManager.hpp"
#include "Event.hpp"

Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(0)) {
	InitSfml(windowWidth, windowHeight, windowTitle);
	glCheckError();
	InitGlew();
	glCheckError();
	PrepareToRendering();
	glCheckError();
}

Render::~Render() {
	delete window;
}

void Render::InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle) {
	LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\"";
	sf::ContextSettings contextSetting;
	contextSetting.majorVersion = 3;
	contextSetting.minorVersion = 3;
	contextSetting.attributeFlags = contextSetting.Core;
	contextSetting.depthBits = 24;
	window = new sf::Window(sf::VideoMode(WinWidth, WinHeight), WinTitle, sf::Style::Default, contextSetting);
	glCheckError();
	window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2,
	                                 sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2));
	SetMouseCapture(false);
    renderState.WindowWidth = WinWidth;
    renderState.WindowHeight = WinHeight;
}

void Render::InitGlew() {
	LOG(INFO) << "Initializing GLEW";
	glewExperimental = GL_TRUE;
	GLenum glewStatus = glewInit();
	glCheckError();
	if (glewStatus != GLEW_OK) {
		LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus);
	}
	glViewport(0, 0, window->getSize().x, window->getSize().y);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glFrontFace(GL_CCW);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glCheckError();
}

void Render::PrepareToRendering() {
	//TextureAtlas texture
	glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, AssetManager::Instance().GetTextureAtlas());
    AssetManager::Instance().GetTextureAtlasIndexes();
}

void Render::RenderFrame() {
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (renderWorld)
        world->Render(renderState);

    if (world) {
        world->Update(timer.RemainTimeMs());
    }

	window->display();
}

void Render::HandleEvents() {
	sf::Event event;
	while (window->pollEvent(event)) {
		switch (event.type) {
			case sf::Event::Closed:
				LOG(INFO) << "Received close event by window closing";
				isRunning = false;
				break;
			case sf::Event::Resized:
				glViewport(0, 0, window->getSize().x, window->getSize().y);
                renderState.WindowWidth = window->getSize().x;
                renderState.WindowHeight = window->getSize().y;
				break;
			case sf::Event::KeyPressed:
				if (!window->hasFocus()) break;
                switch (event.key.code) {
                case sf::Keyboard::Escape:
                    LOG(INFO) << "Received close event by esc";
                    isRunning = false;
                    break;
                    case sf::Keyboard::T:
                        SetMouseCapture(!isMouseCaptured);
                        break;
                    case sf::Keyboard::U:
                        EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ "10.1.1.2", 25565 });
                        break;
                    case sf::Keyboard::I:
                        EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ "Manual disconnect" });
                        break;
                    case sf::Keyboard::K:
                        if (renderWorld) {
                            world->MaxRenderingDistance--;
                            if (world->MaxRenderingDistance <= 0)
                                world->MaxRenderingDistance = 1;
                            LOG(INFO) << "Decreased rendering distance: " << world->MaxRenderingDistance;
                            EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{});
                        }
                    break;
                    case sf::Keyboard::L:
                        if (renderWorld) {
                            world->MaxRenderingDistance++;
                            LOG(INFO) << "Increased rendering distance: " << world->MaxRenderingDistance;
                            EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{});
                        }
                        break;
                    case sf::Keyboard::W:
                        EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::W });
                        break;
                    case sf::Keyboard::A:
                        EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::A });
                        break;
                    case sf::Keyboard::S:
                        EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::S });
                        break;
                    case sf::Keyboard::D:
                        EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::D });
                        break;
                    case sf::Keyboard::Space:
                        EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ sf::Keyboard::Space });
                        break;
					default:
						break;
				}
            case sf::Event::KeyReleased:
                if (!window->hasFocus()) break;
                switch (event.key.code) {
                    case sf::Keyboard::W:
                        EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::W });
                        break;
                    case sf::Keyboard::A:
                        EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::A });
                        break;
                    case sf::Keyboard::S:
                        EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::S });
                        break;
                    case sf::Keyboard::D:
                        EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::D });
                        break;
                    case sf::Keyboard::Space:
                        EventAgregator::PushEvent(EventType::KeyReleased, KeyReleasedData{ sf::Keyboard::Space });
                        break;
                    default:
                        break;
                }
			default:
				break;
		}
	}	
}

void Render::HandleMouseCapture() {
	sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
	sf::Vector2i center = sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2);
	sf::Mouse::setPosition(center, *window);
	mouseXDelta = (mousePos - center).x, mouseYDelta = (center - mousePos).y;
	const float Sensetivity = 0.7f;
    EventAgregator::DirectEventCall(EventType::MouseMoved, MouseMovedData{ mouseXDelta * Sensetivity, mouseYDelta * Sensetivity});	
}

void Render::SetMouseCapture(bool IsCaptured) {
	window->setMouseCursorVisible(!isMouseCaptured);
	sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window);
	isMouseCaptured = IsCaptured;
	window->setMouseCursorVisible(!IsCaptured);
}

void Render::ExecuteRenderLoop() {
	EventListener listener;

	listener.RegisterHandler(EventType::ConnectionSuccessfull, [this](EventData eventData) {
		auto data = std::get<ConnectionSuccessfullData>(eventData);
		window->setTitle("Logging in...");
	});

	listener.RegisterHandler(EventType::PlayerConnected, [this](EventData eventData) {
		auto data = std::get<PlayerConnectedData>(eventData);
		window->setTitle("Loading terrain...");
        world = std::make_unique<RendererWorld>(data.ptr);
	});

	listener.RegisterHandler(EventType::RemoveLoadingScreen, [this](EventData eventData) {
		window->setTitle("Playing");
        renderWorld = true;
	});

    listener.RegisterHandler(EventType::ConnectionFailed, [this](EventData eventData) {
        window->setTitle("Connection failed: " + std::get<ConnectionFailedData>(eventData).reason);
        renderWorld = false;
        world.reset();
    });

    listener.RegisterHandler(EventType::Disconnected, [this](EventData eventData) {
        window->setTitle("Disconnected: " + std::get<DisconnectedData>(eventData).reason);
        renderWorld = false;
        world.reset();
    });

    listener.RegisterHandler(EventType::Connecting, [this](EventData eventData) {
        window->setTitle("Connecting to the server...");
    });
	
	while (isRunning) {
		HandleEvents();
		if (isMouseCaptured) HandleMouseCapture();
		glCheckError();

		RenderFrame();
		while (listener.IsEventsQueueIsNotEmpty())
			listener.HandleEvent();
        if (renderWorld) {
            world->renderDataMutex.lock();
            size_t size = world->renderData.size();
            world->renderDataMutex.unlock();
            window->setTitle("Size: " + std::to_string(size) + "  FPS: " + std::to_string(1.0 / timer.GetRealDeltaS()));
        }
		timer.Update();
	}
    EventAgregator::PushEvent(EventType::Exit, ExitData{});
}