From 469a84c10ba60fba4a513c1b1a0eea600cd7b22f Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Wed, 10 May 2017 18:44:51 +0500 Subject: 2017-05-10 --- CMakeLists.txt | 53 ++++++-- Display.cpp | 288 ------------------------------------------- Display.hpp | 45 ------- Game.cpp | 4 +- Game.hpp | 2 +- cmake_modules/FindGLFW.cmake | 258 ++++++++++++++++++++++++++++++++++++++ cmake_modules/FindSOIL.cmake | 28 +++++ graphics/AssetManager.cpp | 91 ++++++++++++++ graphics/AssetManager.hpp | 51 ++++++++ graphics/Display.cpp | 103 ++++++++++++++++ graphics/Display.hpp | 30 +++++ graphics/Shader.cpp | 36 ++++++ graphics/Shader.hpp | 60 +++++++++ graphics/simpleFS.fs | 8 ++ graphics/simpleVS.vs | 8 ++ main.cpp | 1 + 16 files changed, 719 insertions(+), 347 deletions(-) delete mode 100644 Display.cpp delete mode 100644 Display.hpp create mode 100644 cmake_modules/FindGLFW.cmake create mode 100644 cmake_modules/FindSOIL.cmake create mode 100644 graphics/AssetManager.cpp create mode 100644 graphics/AssetManager.hpp create mode 100644 graphics/Display.cpp create mode 100644 graphics/Display.hpp create mode 100644 graphics/Shader.cpp create mode 100644 graphics/Shader.hpp create mode 100644 graphics/simpleFS.fs create mode 100644 graphics/simpleVS.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 811443d..2ea7965 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,33 +1,64 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.0) project(AltCraft) - set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors -w -Werror") -set(CMAKE_CXX_FLASG "${CMAKE_CXX_FLAGS} -g -O0") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -pg") - set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules) +if (CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors -w -Werror") + set(CMAKE_CXX_FLASG "${CMAKE_CXX_FLAGS} -g -O0") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -pg") + set(PLATFORM_LIBRARIES "pthread") +endif () + #Setup SFML find_package(SFML 2 COMPONENTS system network graphics window REQUIRED) include_directories(${SFML_INCLUDE_DIR}) if (NOT SFML_FOUND) - message(ERROR "SFML not found!") + message(FATAL_ERROR "SFML not found!") endif () #Setup Zlib find_package(ZLIB REQUIRED) include_directories(${ZLIB_INCLUDE_DIR}) if (NOT ZLIB_FOUND) - message(ERROR "Zlib not found!") + message(FATAL_ERROR "Zlib not found!") +endif () + +#Setup SOIL +find_package(SOIL REQUIRED) +include_directories(${SOIL_INCLUDE_DIRS}) +if (NOT SOIL_FOUND) + message(FATAL_ERROR "SOIL not found!") endif () +#Setup GLFW3 +find_package(GLFW REQUIRED) +include_directories(${GLFW_INCLUDE_DIRS}) +if (NOT GLFW_FOUND) + message(FATAL_ERROR "GLFW3 not found!") +endif () + +#Setup GLEW +find_package(GLEW REQUIRED) +include_directories(${GLEW_INCLUDE_DIRS}) +if (NOT GLEW_FOUND) + message(FATAL_ERROR "GLEW not found!") +endif () + +#Setup OpenGL +find_package(OpenGL REQUIRED) +include_directories(${OPENGL_INCLUDE_DIRS}) +if (NOT OPENGL_FOUND) + message(FATAL_ERROR "OpenGL not found!") +endif () set(SOURCE_FILES main.cpp Field.hpp utility.cpp Packet.hpp FieldParser.hpp Network.hpp Network.cpp NetworkClient.cpp NetworkClient.hpp json.hpp PacketBuilder.cpp PacketBuilder.hpp Packet.cpp FieldParser.cpp Field.cpp PacketParser.cpp PacketParser.hpp PositionF.cpp PositionF.hpp PositionI.cpp PositionI.hpp Game.cpp - Game.hpp World.cpp World.hpp Block.cpp Block.hpp Display.cpp Display.hpp Section.cpp Section.hpp Nbt.hpp) + Game.hpp World.cpp World.hpp Block.cpp Block.hpp Section.cpp Section.hpp Nbt.hpp graphics/AssetManager.cpp + graphics/AssetManager.hpp graphics/Display.cpp graphics/Display.hpp graphics/Shader.cpp graphics/Shader.hpp) add_executable(AltCraft ${SOURCE_FILES}) -target_link_libraries(AltCraft ${SFML_LIBRARIES} ${ZLIB_LIBRARIES} pthread) \ No newline at end of file +target_link_libraries(AltCraft ${PLATFORM_LIBRARIES} ${SFML_LIBRARIES} ${ZLIB_LIBRARIES} ${SOIL_LIBRARY} + ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES}) diff --git a/Display.cpp b/Display.cpp deleted file mode 100644 index 7c3e59e..0000000 --- a/Display.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include -#include "Display.hpp" - -Display::Display(int w, int h, std::string title, World *world, std::condition_variable &gameStartWaiter) - : gameStartWaiter(gameStartWaiter) { - window = new sf::RenderWindow(sf::VideoMode(w, h), title); - window->setActive(true); - window->clear(sf::Color::Black); - window->display(); - this->world = world; - window->setFramerateLimit(60); -} - -Display::~Display() { - delete window; -} - -void Display::Update() { - pollEvents(); - - /*{ - std::chrono::steady_clock clock; - static auto timeOfPreviousUpdate(clock.now()); - std::chrono::duration delta = clock.now() - timeOfPreviousUpdate; - if (delta.count() > 0.5) { - timeOfPreviousUpdate = clock.now();*/ - window->setTitle( - std::string("Render layer: " + std::to_string(renderLayer) + "\t" + - //" BlockID: " + std::to_string(currentId) + - " Mouse pos" + std::to_string(mousePos.x) + " " + std::to_string(mousePos.y) + - " FPS: " + std::to_string(1.0 / frameTime)));/* - } - }*/ - - window->clear(sf::Color::Black); - if (isGameStarted) - renderWorld(); - window->display(); -} - -void Display::renderWorld() { - //currentId = 0; - for (auto sectionIt = world->m_sections.begin(); sectionIt != world->m_sections.end(); ++sectionIt) { - if (sectionIt->first.GetY() != renderLayer / 16) - continue; - Section §ion = sectionIt->second; - sf::Image &image = GetSectionTexture(sectionIt->first); - sf::Texture texture; - texture.create(16, 16); - texture.update(image); - sf::Sprite sprite(texture); - sprite.setPosition(sectionIt->first.GetX() * 16, sectionIt->first.GetZ() * 16); - window->draw(sprite); - // sf::Texture &texture = GetSectionTexture(sectionIt->first); - /*for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - int y = renderLayer - sectionIt->first.GetY() * 16; - int absoluteX = sectionIt->first.GetX() * 16 + x; - int absoluteZ = sectionIt->first.GetZ() * 16 + z; - - - Block &block = section.GetBlock(PositionI(x, z, y)); - sf::RectangleShape shape(sf::Vector2f(1, 1)); - - shape.setPosition(absoluteX, absoluteZ); - shape.setFillColor(sf::Color::Magenta); - if (mousePos.x > shape.getPosition().x && mousePos.y > shape.getPosition().y) { - if (mousePos.x < shape.getPosition().x + 1 && mousePos.y < shape.getPosition().y + 1) { - currentId = block.id; - if (isClicked) { - std::cout << "Clicked it " << absoluteX << " " << absoluteZ << std::endl; - isClicked = false; - } - } - } - switch (block.id) { - case 0: - shape.setFillColor(sf::Color::Transparent); - break; - case 7: - shape.setFillColor(sf::Color::Yellow); - break; - case 1: - shape.setFillColor(sf::Color::White); - break; - case 11: - shape.setFillColor(sf::Color::Red); - break; - case 10: - shape.setFillColor(sf::Color::Red); - break; - case 3: - shape.setFillColor(sf::Color(139, 69, 69)); - break; - case 13: - shape.setFillColor(sf::Color(220, 220, 220)); - break; - case 9: - shape.setFillColor(sf::Color::Blue); - break; - case 8: - shape.setFillColor(sf::Color::Blue); - break; - case 2: - shape.setFillColor(sf::Color::Green); - break; - default: - //std::cout << "Unknown id is " << sectionIt.second.GetId() << std::endl; - break; - } - sf::Color darkness(0, 0, 0, ((15 - block.light) / 15.0f) * 255); - shape.setFillColor(shape.getFillColor() + darkness); - window->draw(shape); - } - } - sf::Vector2f p1 = sf::Vector2f(sectionIt->first.GetX() * 16, sectionIt->first.GetZ() * 16); - sf::Vector2f p2 = sf::Vector2f(sectionIt->first.GetX() * 16 + 16, sectionIt->first.GetZ() * 16); - sf::Vector2f p3 = sf::Vector2f(sectionIt->first.GetX() * 16 + 16, sectionIt->first.GetZ() * 16 + 16); - sf::Vector2f p4 = sf::Vector2f(sectionIt->first.GetX() * 16, sectionIt->first.GetZ() * 16 + 16); - sf::Vertex line1[] = { - sf::Vertex(p1), - sf::Vertex(p2), - }; - sf::Vertex line2[] = { - sf::Vertex(p2), - sf::Vertex(p3), - }; - sf::Vertex line3[] = { - sf::Vertex(p3), - sf::Vertex(p4), - }; - sf::Vertex line4[] = { - sf::Vertex(p4), - sf::Vertex(p1), - }; - window->draw(line1, 2, sf::Lines); - window->draw(line2, 2, sf::Lines); - window->draw(line3, 2, sf::Lines); - window->draw(line4, 2, sf::Lines);*/ - } -} - -void Display::pollEvents() { - sf::Event e; - while (window->pollEvent(e)) { - switch (e.type) { - case sf::Event::Closed: - window->close(); - break; - case sf::Event::MouseMoved: - mousePos = window->mapPixelToCoords(sf::Vector2i(e.mouseMove.x, e.mouseMove.y)); - break; - case sf::Event::KeyPressed: - if (e.key.code == sf::Keyboard::Z) { - if (renderLayer > 0) - renderLayer--; - } else if (e.key.code == sf::Keyboard::X) { - if (renderLayer < 256) - renderLayer++; - } else if (e.key.code == sf::Keyboard::Up) { - sf::View view = window->getView(); - view.move(0, -coeff); - window->setView(view); - } else if (e.key.code == sf::Keyboard::Down) { - sf::View view = window->getView(); - view.move(0, coeff); - window->setView(view); - } else if (e.key.code == sf::Keyboard::Right) { - sf::View view = window->getView(); - view.move(coeff, 0); - window->setView(view); - } else if (e.key.code == sf::Keyboard::Left) { - sf::View view = window->getView(); - view.move(-coeff, 0); - window->setView(view); - } else if (e.key.code == sf::Keyboard::A) { - sf::View view = window->getView(); - //view.setSize(view.getSize().x + coeff2, view.getSize().y + coeff2); - view.zoom(1.1); - window->setView(view); - } else if (e.key.code == sf::Keyboard::S) { - sf::View view = window->getView(); - view.zoom(0.9); - //view.setSize(view.getSize().x - coeff2, view.getSize().y - coeff2); - window->setView(view); - } else if (e.key.code == sf::Keyboard::K) { - std::cout << "Allocated memory is freed" << std::endl; - sectionTextures.clear(); - } - break; - case sf::Event::MouseButtonPressed: - isClicked = true; - break; - } - } -} - - -bool Display::IsClosed() { - return !window->isOpen(); -} - -void Display::SetPlayerPos(float x, float z) { - x = -55; - z = 196; - isGameStarted = true; - float div = 5; - float X = window->getSize().x / div, Z = window->getSize().y / div; - sf::View view(sf::Vector2f(x, z), sf::Vector2f(X, Z)); - window->setView(view); -} - -void Display::MainLoop() { - /*std::unique_lock gameStartLocker(gameStartMutex); - gameStartWaiter.wait(gameStartLocker); - while (!isGameStarted) { - std::cout << "Catch spirious wakeup" << std::endl; - gameStartWaiter.wait(gameStartLocker); - } - std::cout << "Graphics subsystem initialized" << std::endl;*/ - while (!IsClosed()) { - Update(); - { - std::chrono::steady_clock clock; - static auto timeOfPreviousUpdate(clock.now()); - std::chrono::duration delta = clock.now() - timeOfPreviousUpdate; - timeOfPreviousUpdate = clock.now(); - frameTime = delta.count(); - } - } -} - -sf::Image &Display::GetSectionTexture(PositionI pos) { - if (sectionTextures.find(pos) != sectionTextures.end() && - sectionTextures[pos][renderLayer - pos.GetY() * 16].getSize() != sf::Vector2u(0, 0)) - return sectionTextures[pos][renderLayer - pos.GetY() * 16]; - - auto sectionIt = world->m_sections.find(pos); - Section §ion = sectionIt->second; - sf::Image image; - image.create(16, 16); - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - int y = renderLayer - sectionIt->first.GetY() * 16; - sf::Color color = sf::Color::Magenta; - switch (section.GetBlock(PositionI(x, z, y)).id) { - case 0: - color = sf::Color::Transparent; - break; - case 7: - color = sf::Color::Yellow; - break; - case 1: - color = sf::Color::White; - break; - case 11: - color = sf::Color::Red; - break; - case 10: - color = sf::Color::Red; - break; - case 3: - color = sf::Color(139, 69, 69); - break; - case 13: - color = sf::Color(220, 220, 220); - break; - case 9: - color = sf::Color::Blue; - break; - case 8: - color = sf::Color::Blue; - break; - case 2: - color = sf::Color::Green; - break; - default: - break; - } - image.setPixel(x, z, color); - } - } - /*sf::Texture texture; - texture.create(16, 16); - texture.update(image);*/ - sectionTextures[pos][renderLayer - pos.GetY() * 16] = image; - return sectionTextures[pos][renderLayer - pos.GetY() * 16]; -} \ No newline at end of file diff --git a/Display.hpp b/Display.hpp deleted file mode 100644 index 3d54482..0000000 --- a/Display.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "World.hpp" - -class Display { - sf::RenderWindow *window; - std::map> sectionTextures; - //std::map> sectionTextures; - World *world; - bool isGameStarted = false; - std::condition_variable &gameStartWaiter; - std::mutex gameStartMutex; - - //utility methods - void pollEvents(); - - void renderWorld(); - - void Update(); - - sf::Image &GetSectionTexture(PositionI pos); - - //gameState vars - sf::Vector2f mousePos; - int renderLayer = 70; - //int currentId = 0; - bool isClicked = false; - int coeff = 10; - double frameTime = 0; -public: - Display(int w, int h, std::string title, World *world, std::condition_variable &gameStartWaiter); - - ~Display(); - - bool IsClosed(); - - void SetPlayerPos(float x, float z); - - void MainLoop(); -}; - diff --git a/Game.cpp b/Game.cpp index c3adaae..fcb8582 100644 --- a/Game.cpp +++ b/Game.cpp @@ -4,7 +4,7 @@ #include "json.hpp" Game::Game() { - m_display = new Display(1280, 720, "AltCraft", &m_world, gameStartWaiter); + m_display = new Display(1280, 720, "AltCraft", &m_world); m_nc = new NetworkClient("127.0.0.1", 25565, "HelloOne"); Packet &response = *m_nc->GetPacket(); if (response.GetId() != 0x02) { @@ -21,6 +21,7 @@ Game::Game() { Game::~Game() { std::cout << "Stopping game thread..." << std::endl; + m_exit=true; m_gameThread.join(); std::cout << "Stopping graphics..." << std::endl; delete m_display; @@ -29,7 +30,6 @@ Game::~Game() { } void Game::MainLoop() { - //std::thread(std::this_thread::get_id()).swap(m_display->GetThreadHandler()); while (!m_exit) { ParsePackets(); if (m_display->IsClosed()) diff --git a/Game.hpp b/Game.hpp index 1a2edce..b9096a5 100644 --- a/Game.hpp +++ b/Game.hpp @@ -3,7 +3,7 @@ #include "PositionI.hpp" #include "NetworkClient.hpp" #include "World.hpp" -#include "Display.hpp" +#include "graphics/Display.hpp" class Game { public: diff --git a/cmake_modules/FindGLFW.cmake b/cmake_modules/FindGLFW.cmake new file mode 100644 index 0000000..0640709 --- /dev/null +++ b/cmake_modules/FindGLFW.cmake @@ -0,0 +1,258 @@ +# +# Copyright 2013 Pixar +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +# Try to find GLFW library and include path. +# Once done this will define +# +# GLFW_FOUND +# GLFW_INCLUDE_DIR +# GLFW_LIBRARIES +# + +find_path( GLFW_INCLUDE_DIR + NAMES + GLFW/glfw3.h + HINTS + "${GLFW_LOCATION}/include" + "$ENV{GLFW_LOCATION}/include" + PATHS + "$ENV{PROGRAMFILES}/GLFW/include" + "${OPENGL_INCLUDE_DIR}" + /usr/openwin/share/include + /usr/openwin/include + /usr/X11R6/include + /usr/include/X11 + /opt/graphics/OpenGL/include + /opt/graphics/OpenGL/contrib/libglfw + /usr/local/include + /usr/include/GL + /usr/include + DOC + "The directory where GLFW/glfw3.h resides" + ) + +# +# XXX: Do we still need to search for GL/glfw.h? +# +find_path( GLFW_INCLUDE_DIR + NAMES + GL/glfw.h + HINTS + "${GLFW_LOCATION}/include" + "$ENV{GLFW_LOCATION}/include" + PATHS + "$ENV{PROGRAMFILES}/GLFW/include" + "${OPENGL_INCLUDE_DIR}" + /usr/openwin/share/include + /usr/openwin/include + /usr/X11R6/include + /usr/include/X11 + /opt/graphics/OpenGL/include + /opt/graphics/OpenGL/contrib/libglfw + /usr/local/include + /usr/include/GL + /usr/include + DOC + "The directory where GL/glfw.h resides" + ) + +if (WIN32) + if(CYGWIN) + find_library( GLFW_glfw_LIBRARY + NAMES + glfw32 + HINTS + "${GLFW_LOCATION}/lib" + "${GLFW_LOCATION}/lib/x64" + "$ENV{GLFW_LOCATION}/lib" + PATHS + "${OPENGL_LIBRARY_DIR}" + /usr/lib + /usr/lib/w32api + /usr/local/lib + /usr/X11R6/lib + DOC + "The GLFW library" + ) + else() + find_library( GLFW_glfw_LIBRARY + NAMES + glfw32 + glfw32s + glfw + glfw3 + HINTS + "${GLFW_LOCATION}/lib" + "${GLFW_LOCATION}/lib/x64" + "${GLFW_LOCATION}/lib-msvc110" + "${GLFW_LOCATION}/lib-vc2012" + "$ENV{GLFW_LOCATION}/lib" + "$ENV{GLFW_LOCATION}/lib/x64" + "$ENV{GLFW_LOCATION}/lib-msvc110" + "$ENV{GLFW_LOCATION}/lib-vc2012" + PATHS + "$ENV{PROGRAMFILES}/GLFW/lib" + "${OPENGL_LIBRARY_DIR}" + DOC + "The GLFW library" + ) + endif() +else () + if (APPLE) + find_library( GLFW_glfw_LIBRARY glfw + NAMES + glfw + glfw3 + HINTS + "${GLFW_LOCATION}/lib" + "${GLFW_LOCATION}/lib/cocoa" + "$ENV{GLFW_LOCATION}/lib" + "$ENV{GLFW_LOCATION}/lib/cocoa" + PATHS + /usr/local/lib + ) + set(GLFW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") + set(GLFW_corevideo_LIBRARY "-framework CoreVideo" CACHE STRING "CoreVideo framework for OSX") + set(GLFW_iokit_LIBRARY "-framework IOKit" CACHE STRING "IOKit framework for OSX") + else () + # (*)NIX + + find_package(Threads REQUIRED) + + find_package(X11 REQUIRED) + + if(NOT X11_Xrandr_FOUND) + message(FATAL_ERROR "Xrandr library not found - required for GLFW") + endif() + + if(NOT X11_xf86vmode_FOUND) + message(FATAL_ERROR "xf86vmode library not found - required for GLFW") + endif() + + if(NOT X11_Xcursor_FOUND) + message(FATAL_ERROR "Xcursor library not found - required for GLFW") + endif() + + if(NOT X11_Xinerama_FOUND) + message(FATAL_ERROR "Xinerama library not found - required for GLFW") + endif() + + if(NOT X11_Xi_FOUND) + message(FATAL_ERROR "Xi library not found - required for GLFW") + endif() + + list(APPEND GLFW_x11_LIBRARY "${X11_Xrandr_LIB}" "${X11_Xxf86vm_LIB}" "${X11_Xcursor_LIB}" "${X11_Xinerama_LIB}" "${X11_Xi_LIB}" "${X11_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}" -lrt -ldl) + + find_library( GLFW_glfw_LIBRARY + NAMES + glfw + glfw3 + HINTS + "${GLFW_LOCATION}/lib" + "$ENV{GLFW_LOCATION}/lib" + "${GLFW_LOCATION}/lib/x11" + "$ENV{GLFW_LOCATION}/lib/x11" + PATHS + /usr/lib64 + /usr/lib + /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} + /usr/local/lib64 + /usr/local/lib + /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE} + /usr/openwin/lib + /usr/X11R6/lib + DOC + "The GLFW library" + ) + endif (APPLE) +endif (WIN32) + +set( GLFW_FOUND "NO" ) + +if(GLFW_INCLUDE_DIR) + + if(GLFW_glfw_LIBRARY) + set( GLFW_LIBRARIES "${GLFW_glfw_LIBRARY}" + "${GLFW_x11_LIBRARY}" + "${GLFW_cocoa_LIBRARY}" + "${GLFW_iokit_LIBRARY}" + "${GLFW_corevideo_LIBRARY}" ) + set( GLFW_FOUND "YES" ) + set (GLFW_LIBRARY "${GLFW_LIBRARIES}") + set (GLFW_INCLUDE_PATH "${GLFW_INCLUDE_DIR}") + endif(GLFW_glfw_LIBRARY) + + + # Tease the GLFW_VERSION numbers from the lib headers + function(parseVersion FILENAME VARNAME) + + set(PATTERN "^#define ${VARNAME}.*$") + + file(STRINGS "${GLFW_INCLUDE_DIR}/${FILENAME}" TMP REGEX ${PATTERN}) + + string(REGEX MATCHALL "[0-9]+" TMP ${TMP}) + + set(${VARNAME} ${TMP} PARENT_SCOPE) + + endfunction() + + + if(EXISTS "${GLFW_INCLUDE_DIR}/GL/glfw.h") + + parseVersion(GL/glfw.h GLFW_VERSION_MAJOR) + parseVersion(GL/glfw.h GLFW_VERSION_MINOR) + parseVersion(GL/glfw.h GLFW_VERSION_REVISION) + + elseif(EXISTS "${GLFW_INCLUDE_DIR}/GLFW/glfw3.h") + + parseVersion(GLFW/glfw3.h GLFW_VERSION_MAJOR) + parseVersion(GLFW/glfw3.h GLFW_VERSION_MINOR) + parseVersion(GLFW/glfw3.h GLFW_VERSION_REVISION) + + endif() + + if(${GLFW_VERSION_MAJOR} OR ${GLFW_VERSION_MINOR} OR ${GLFW_VERSION_REVISION}) + set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}.${GLFW_VERSION_REVISION}") + set(GLFW_VERSION_STRING "${GLFW_VERSION}") + mark_as_advanced(GLFW_VERSION) + endif() + +endif(GLFW_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(GLFW + REQUIRED_VARS + GLFW_INCLUDE_DIR + GLFW_LIBRARIES + VERSION_VAR + GLFW_VERSION + ) + +mark_as_advanced( + GLFW_INCLUDE_DIR + GLFW_LIBRARIES + GLFW_glfw_LIBRARY + GLFW_cocoa_LIBRARY +) \ No newline at end of file diff --git a/cmake_modules/FindSOIL.cmake b/cmake_modules/FindSOIL.cmake new file mode 100644 index 0000000..60eba06 --- /dev/null +++ b/cmake_modules/FindSOIL.cmake @@ -0,0 +1,28 @@ +# Find SOIL +# Find the SOIL includes and library +# +# SOIL_INCLUDE_DIRS - where to find SOIL.h, etc. +# SOIL_LIBRARIES - List of libraries when using SOIL. +# SOIL_FOUND - True if SOIL found. +# +# Based on the FindZLIB.cmake module. + +IF (SOIL_INCLUDE_DIR) + # Already in cache, be silent + SET(SOIL_FIND_QUIETLY TRUE) +ENDIF (SOIL_INCLUDE_DIR) + +FIND_PATH(SOIL_INCLUDE_DIR SOIL.h PATH_SUFFIXES include/SOIL include) + +SET(SOIL_NAMES SOIL Soil soil) +FIND_LIBRARY(SOIL_LIBRARY NAMES ${SOIL_NAMES} ) +MARK_AS_ADVANCED( SOIL_LIBRARY SOIL_INCLUDE_DIR ) + +# Per-recommendation +SET(SOIL_INCLUDE_DIRS "${SOIL_INCLUDE_DIR}") +SET(SOIL_LIBRARIES "${SOIL_LIBRARY}") + +# handle the QUIETLY and REQUIRED arguments and set SOIL_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOIL DEFAULT_MSG SOIL_LIBRARIES SOIL_INCLUDE_DIRS) \ No newline at end of file diff --git a/graphics/AssetManager.cpp b/graphics/AssetManager.cpp new file mode 100644 index 0000000..3f68617 --- /dev/null +++ b/graphics/AssetManager.cpp @@ -0,0 +1,91 @@ +#include "AssetManager.hpp" + +const std::string pathToIndexFile = "./assets/indexes/1.11.json"; + +const std::map assetTypeFileExtensions{ + std::make_pair(Asset::AssetType::Texture, ".png"), + std::make_pair(Asset::AssetType::Lang, ".lang"), + std::make_pair(Asset::AssetType::Sound, ".ogg"), +}; + +AssetManager::AssetManager() { + std::ifstream indexFile(pathToIndexFile); + if (!indexFile) { + std::cerr << "Can't open file " << pathToIndexFile << std::endl; + } + nlohmann::json json = nlohmann::json::parse(indexFile)["objects"]; + for (auto it = json.begin(); it != json.end(); ++it) { + size_t fileNameExtensionPos = -1; + std::string name = it.key(); + Asset::AssetType type = Asset::Unknown; + for (auto &it:assetTypeFileExtensions) { + if ((fileNameExtensionPos = name.find(it.second)) != std::string::npos) { + type = it.first; + name = name.substr(0, fileNameExtensionPos); + break; + } + } + std::string hash = it.value()["hash"].get(); + size_t size = it.value()["size"].get(); + Asset asset{name, hash, Asset::AssetData(), size, type}; + this->assets[name] = asset; + } +} + +AssetManager::~AssetManager() { + +} + +Asset &AssetManager::GetAsset(std::string AssetName) { + Asset &asset = instance().assets[AssetName]; + if (!asset.isParsed()) + LoadAsset(AssetName); + return asset; +} + +void AssetManager::LoadAsset(std::string AssetName) { + if (instance().assets[AssetName].isParsed()) + return; + Asset &asset = instance().assets[AssetName]; + if (asset.type == Asset::Texture) { + asset.data.texture.imageData = SOIL_load_image((asset.name + assetTypeFileExtensions.at(asset.type)).c_str(), + &asset.data.texture.width, &asset.data.texture.height, 0, + SOIL_LOAD_RGBA); + } +} + +bool Asset::isParsed() { + switch (type) { + case Unknown: + return false; + break; + case Texture: + return this->data.texture.imageData != nullptr; + break; + case Sound: + return false; + break; + case Model: + return false; + break; + case Lang: + return false; + break; + } +} + +Asset::~Asset() { + switch (type) { + case Unknown: + break; + case Texture: + SOIL_free_image_data(this->data.texture.imageData); + break; + case Sound: + break; + case Model: + break; + case Lang: + break; + } +} diff --git a/graphics/AssetManager.hpp b/graphics/AssetManager.hpp new file mode 100644 index 0000000..81be7c4 --- /dev/null +++ b/graphics/AssetManager.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include "../json.hpp" + +struct Asset { + std::string name = ""; + std::string hash = ""; + union AssetData{ + struct TextureData{ + int width; + int height; + unsigned char *imageData; + } texture; + } data; + size_t size = 0; + enum AssetType { + Unknown, + Texture, + Sound, + Model, + Lang, + } type = Unknown; + bool isParsed(); + ~Asset(); +}; + +class AssetManager { + AssetManager(); + + ~AssetManager(); + + AssetManager(const AssetManager &); + + AssetManager &operator=(const AssetManager &); + + std::map assets; +public: + static AssetManager &instance() { + static AssetManager assetManager; + return assetManager; + } + + static Asset &GetAsset(std::string AssetName); + + static void LoadAsset(std::string AssetName); +}; + diff --git a/graphics/Display.cpp b/graphics/Display.cpp new file mode 100644 index 0000000..01dd903 --- /dev/null +++ b/graphics/Display.cpp @@ -0,0 +1,103 @@ +#include +#include "Display.hpp" +#include "Shader.hpp" + +Display *Display::instance = nullptr; + +Display::Display(int w, int h, std::string title, World *worldPtr) { + if (instance != nullptr) + throw 516; + instance = this; + world = worldPtr; + //GLFW + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + window = glfwCreateWindow(w, h, title.c_str(), nullptr, nullptr); + if (window == nullptr) { + std::cerr << "Can't create GLFW window" << std::endl; + glfwTerminate(); + throw 517; + } + glfwMakeContextCurrent(window); + glfwSetKeyCallback(window, &Display::callback_key); + //GLEW + glewExperimental = GL_TRUE; + GLenum glewStatus = glewInit(); + if (glewStatus != GLEW_OK) { + std::cerr << "Can't initialize GLEW: " << glewGetErrorString(glewStatus) << std::endl; + throw 518; + } + int width, height; + glfwGetFramebufferSize(window, &width, &height); + glViewport(0, 0, width, height); +} + +Display::~Display() { + instance = nullptr; + glfwTerminate(); +} + +bool Display::IsClosed() { + return false; +} + +void Display::SetPlayerPos(float x, float y) { + +} + +void Display::MainLoop() { + Shader vertexShader("./graphics/simpleVS.vs"); + Shader fragmentShader("./graphics/simpleFS.fs", false); + ShaderProgram program; + program.Attach(vertexShader); + program.Attach(fragmentShader); + program.Link(); + + GLfloat vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + GLuint VBO; + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(VBO, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); + glEnableVertexAttribArray(0); + + GLuint VAO; + glGenVertexArrays(1, &VAO); + + glBindVertexArray(VAO); + // 2. Копируем наш массив вершин в буфер для OpenGL + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + // 3. Устанавливаем указатели на вершинные атрибуты + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0); + glEnableVertexAttribArray(0); + //4. Отвязываем VAO + glBindVertexArray(0); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram((GLuint) program); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); + + glfwSwapBuffers(window); + } +} + +void Display::callback_key(GLFWwindow *window, int key, int scancode, int action, int mode) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(instance->window, GL_TRUE); +} diff --git a/graphics/Display.hpp b/graphics/Display.hpp new file mode 100644 index 0000000..d6737ba --- /dev/null +++ b/graphics/Display.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include "../World.hpp" + +template +class CallbackHandler { + +}; + +class Display { + World *world; + GLFWwindow *window; + static Display *instance; + //glfw callbacks + static void callback_key(GLFWwindow *window, int key, int scancode, int action, int mode); +public: + Display(int w, int h, std::string title, World *worldPtr); + + ~Display(); + + void MainLoop(); + + bool IsClosed(); + + void SetPlayerPos(float x, float y); +}; + diff --git a/graphics/Shader.cpp b/graphics/Shader.cpp new file mode 100644 index 0000000..2b72917 --- /dev/null +++ b/graphics/Shader.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include "Shader.hpp" + +Shader::Shader(std::string fileName, bool vertex) { + this->isVertex = vertex; + std::ifstream in(fileName); + if (!in){ + std::cout<<"Can't open shader source at "<(in)), + std::istreambuf_iterator()); + shaderId = glCreateShader(isVertex?GL_VERTEX_SHADER:GL_FRAGMENT_SHADER); + const char* shaderSrc = shaderSource.c_str(); + glShaderSource(shaderId, 1, &shaderSrc, NULL); + glCompileShader(shaderId); + GLint success; + GLchar infoLog[512]; + glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); + if(!success) + { + glGetShaderInfoLog(shaderId, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + throw 518; + } +} + +Shader::~Shader() { + glDeleteShader(shaderId); +} + +void Shader::bind() { + +} diff --git a/graphics/Shader.hpp b/graphics/Shader.hpp new file mode 100644 index 0000000..83e06e1 --- /dev/null +++ b/graphics/Shader.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include + +class Shader { + std::string shaderSource; + GLuint shaderId; + bool isVertex = true; + + Shader(const Shader &); + +public: + Shader(std::string fileName, bool vertex = true); + + ~Shader(); + + void bind(); + + GLuint GetId() { + return shaderId; + } + +}; + +class ShaderProgram { + GLuint shaderProgram; +public: + ShaderProgram() { + shaderProgram = glCreateProgram(); + } + + ~ShaderProgram() { + glDeleteProgram(shaderProgram); + } + + void Attach(Shader &shader) { + glAttachShader(shaderProgram, shader.GetId()); + } + + void Link() { + glLinkProgram(shaderProgram); + GLint success; + GLchar infoLog[512]; + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + std::cout << "Shader program linking failed: " << infoLog << std::endl; + } + glUseProgram(shaderProgram); + } + + GLuint GetId() { + return shaderProgram; + } + + explicit operator GLuint() const { + return shaderProgram; + } + +}; \ No newline at end of file diff --git a/graphics/simpleFS.fs b/graphics/simpleFS.fs new file mode 100644 index 0000000..03b3fe0 --- /dev/null +++ b/graphics/simpleFS.fs @@ -0,0 +1,8 @@ +#version 330 core + +out vec4 color; + +void main() +{ + color = vec4(1.0f, 0.5f, 0.2f, 1.0f); +} \ No newline at end of file diff --git a/graphics/simpleVS.vs b/graphics/simpleVS.vs new file mode 100644 index 0000000..deae931 --- /dev/null +++ b/graphics/simpleVS.vs @@ -0,0 +1,8 @@ +#version 330 core + +layout (location = 0) in vec3 position; + +void main() +{ + gl_Position = vec4(position.x, position.y, position.z, 1.0); +} \ No newline at end of file diff --git a/main.cpp b/main.cpp index b51bb81..74007c3 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include #include "Game.hpp" +#include "graphics/AssetManager.hpp" int main() { try { -- cgit v1.2.3