// Voxspatium Engine - Voxel Planets Engine // Copyright (C) 2018 Evert "Diamond" Prants // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "Application.h" #include "util/Log.h" #include "Shader.h" Application::Application() : m_width(1080), m_height(720) { } Application::~Application() { } void Application::initialize() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); return; } // Create our window centered at 1080x720 resolution m_window = SDL_CreateWindow( "Voxspatium Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_width, m_height, SDL_WINDOW_OPENGL ); if (!m_window) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); return; } // Set GL Attributes SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); m_glContext = SDL_GL_CreateContext(m_window); if(m_glContext == NULL) { printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); return; } SDL_GL_MakeCurrent(m_window, m_glContext); // Initialize GLEW glewInit(); // Create camera m_camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f); // Run the engine run(); } void Application::handleEvents() { /* Update the input manager */ Input::getInstance().flush(); /* Check for events */ SDL_Event e; while ( SDL_PollEvent(&e) ) { switch(e.type) { case SDL_QUIT: exit(); break; case SDL_KEYDOWN: Input::getInstance().pressKey(e.key.keysym.sym); break; case SDL_KEYUP: Input::getInstance().releaseKey(e.key.keysym.sym); break; case SDL_MOUSEMOTION: Input::getInstance().setMouseCoords(e.motion.x, e.motion.y); break; case SDL_MOUSEBUTTONDOWN: Input::getInstance().pressKey(e.button.button); break; case SDL_MOUSEBUTTONUP: Input::getInstance().releaseKey(e.button.button); break; case SDL_MOUSEWHEEL: Input::getInstance().setMouseWheel(e.wheel.y, e.wheel.x); break; } } glm::vec2 mousepos = Input::getInstance().getMouseCoords(); // Force mouse to the center of the screen SDL_SetWindowGrab(m_window, SDL_TRUE); SDL_WarpMouseInWindow(m_window, m_width/2, m_height/2); // Handle Camera Movement m_camera->processMouseMovement(-(m_width/2 - mousepos.x), m_height/2 - mousepos.y, GL_TRUE); // Handle Camera Movement Keys if(Input::getInstance().isKeyDown(SDLK_w)) m_camera->processKeyboard(Camera_Movement::FORWARD, 0.01f); if(Input::getInstance().isKeyDown(SDLK_s)) m_camera->processKeyboard(Camera_Movement::BACKWARD, 0.01f); if(Input::getInstance().isKeyDown(SDLK_d)) m_camera->processKeyboard(Camera_Movement::RIGHT, 0.01f); if(Input::getInstance().isKeyDown(SDLK_a)) m_camera->processKeyboard(Camera_Movement::LEFT, 0.01f); // Handle Camera Zoom m_camera->processMouseScroll((float) Input::getInstance().getMouseWheelVertical() / 10.0f); // Print mouse position on click if(Input::getInstance().isKeyPressed(SDL_BUTTON_LEFT)) std::cout << "mX: " << mousepos.x << " mY: " << mousepos.y << std::endl; // Exit game on Esc if(Input::getInstance().isKeyPressed(SDLK_ESCAPE)) exit(); } void Application::run() { m_run = true; m_now = SDL_GetPerformanceCounter(); m_last = 0; // TEST CODE SDL_ShowCursor(SDL_DISABLE); Input::getInstance().setMouseCoords(m_width/2, m_height/2); static const GLfloat vertices[] = { -1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 1.0f, // triangle 1 : begin -1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // triangle 1 : end 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // triangle 2 : begin -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, // triangle 2 : end 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, -1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,-1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f,-1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,-1.0f, 1.0f, 0.0f, 0.0f, 1.0f }; GLuint vertexArray, vertexBuffer; // Create VAO glGenVertexArrays(1, &vertexArray); glBindVertexArray(vertexArray); // Generate 1 buffer, put the resulting identifier in vertexBuffer glGenBuffers(1, &vertexBuffer); // The following commands will talk about our 'vertexBuffer' buffer glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // Give our vertices to OpenGL. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Create the shader and link them together Shader& skyboxShader = Shader::createShader("data/shaders/skybox.vert", "data/shaders/skybox.frag"); skyboxShader.linkShaders(); // Give the buffers to the shader skyboxShader.setBuffers(vertexArray, vertexBuffer, 0); // Set attribute arrays skyboxShader.setAttribute("position", 3, GL_FALSE, 6, 0, GL_FLOAT); skyboxShader.setAttribute("color", 3, GL_FALSE, 6, 3, GL_FLOAT); glEnable(GL_DEPTH_TEST); // END TEST CODE while(m_run) { m_last = m_now; m_now = SDL_GetPerformanceCounter(); handleEvents(); // Clear color buffer glClearColor(0.39f, 0.58f, 0.93f, 1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); deltaTime = ((m_now - m_last) / (double)SDL_GetPerformanceFrequency()); // TEST CODE glm::vec3 cameraPos = m_camera->getPosition(); glm::mat4 model = glm::scale(glm::translate(glm::mat4(1.0f), cameraPos), glm::vec3(50.0f, 50.0f, 50.0f)); skyboxShader.use(); skyboxShader.setUniform("modelMatrix", model); m_camera->shaderViewProjection(skyboxShader); // Load view and projection matrices glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles -> 6 squares // END TEST CODE update(deltaTime); render(); // Update window with OpenGL rendering SDL_GL_SwapWindow(m_window); } // After loop exits // Destroy window SDL_DestroyWindow(m_window); m_window = NULL; // Destroy context SDL_GL_DeleteContext(m_glContext); // Quit SDL subsystems SDL_Quit(); } void Application::update(GLfloat dtime) { } void Application::render() { }