summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt53
-rw-r--r--Display.cpp288
-rw-r--r--Display.hpp45
-rw-r--r--Game.cpp4
-rw-r--r--Game.hpp2
-rw-r--r--cmake_modules/FindGLFW.cmake258
-rw-r--r--cmake_modules/FindSOIL.cmake28
-rw-r--r--graphics/AssetManager.cpp91
-rw-r--r--graphics/AssetManager.hpp51
-rw-r--r--graphics/Display.cpp103
-rw-r--r--graphics/Display.hpp30
-rw-r--r--graphics/Shader.cpp36
-rw-r--r--graphics/Shader.hpp60
-rw-r--r--graphics/simpleFS.fs8
-rw-r--r--graphics/simpleVS.vs8
-rw-r--r--main.cpp1
16 files changed, 719 insertions, 347 deletions
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 <iostream>
-#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<double> 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 &section = 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<std::mutex> 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<double> 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 &section = 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 <SFML/Graphics.hpp>
-#include <thread>
-#include <mutex>
-#include <condition_variable>
-#include "World.hpp"
-
-class Display {
- sf::RenderWindow *window;
- std::map<PositionI, std::array<sf::Image,16>> sectionTextures;
- //std::map<PositionI, std::array<sf::Texture,16>> 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<Asset::AssetType, std::string> 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<std::string>();
+ size_t size = it.value()["size"].get<int>();
+ 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 <fstream>
+#include <string>
+#include <SOIL.h>
+#include <map>
+#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<std::string, Asset> 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 <iostream>
+#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 <condition_variable>
+#include <GL/glew.h>
+#include <GLFW/glfw3.h>
+#include "../World.hpp"
+
+template <class T>
+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 <GL/glew.h>
+#include <iostream>
+#include <fstream>
+#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 "<<fileName<<std::endl;
+ throw 519;
+ }
+ shaderSource = std::string((std::istreambuf_iterator<char>(in)),
+ std::istreambuf_iterator<char>());
+ 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 <string>
+
+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 <iostream>
#include "Game.hpp"
+#include "graphics/AssetManager.hpp"
int main() {
try {