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 --- 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 ++++ 8 files changed, 387 insertions(+) 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 (limited to 'graphics') 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 -- cgit v1.2.3