diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-05-12 15:49:50 +0200 |
---|---|---|
committer | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2017-05-12 15:49:50 +0200 |
commit | e62817b8252974b8a98393275874ee303840bf13 (patch) | |
tree | 4565935f06e369f4a84410b0c098958e07a750c7 /graphics | |
parent | 2017-05-10 (diff) | |
download | AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar.gz AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar.bz2 AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar.lz AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar.xz AltCraft-e62817b8252974b8a98393275874ee303840bf13.tar.zst AltCraft-e62817b8252974b8a98393275874ee303840bf13.zip |
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/AssetManager.cpp | 39 | ||||
-rw-r--r-- | graphics/AssetManager.hpp | 13 | ||||
-rw-r--r-- | graphics/Camera3D.cpp | 79 | ||||
-rw-r--r-- | graphics/Camera3D.hpp | 66 | ||||
-rw-r--r-- | graphics/Display.cpp | 267 | ||||
-rw-r--r-- | graphics/Display.hpp | 40 | ||||
-rw-r--r-- | graphics/Shader.cpp | 102 | ||||
-rw-r--r-- | graphics/Shader.hpp | 72 | ||||
-rw-r--r-- | graphics/Texture.cpp | 39 | ||||
-rw-r--r-- | graphics/Texture.hpp | 12 | ||||
-rw-r--r-- | graphics/simpleFS.fs | 8 | ||||
-rw-r--r-- | graphics/simpleVS.vs | 8 |
12 files changed, 540 insertions, 205 deletions
diff --git a/graphics/AssetManager.cpp b/graphics/AssetManager.cpp index 3f68617..62dac64 100644 --- a/graphics/AssetManager.cpp +++ b/graphics/AssetManager.cpp @@ -1,6 +1,9 @@ #include "AssetManager.hpp" -const std::string pathToIndexFile = "./assets/indexes/1.11.json"; +const std::string pathToAssets = "./assets/"; +const std::string pathToObjects = pathToAssets + "objects/"; +const std::string pathToIndexFile = pathToAssets + "indexes/1.11.json"; +const std::string pathToAssetsMc = "./assetsMc/"; const std::map<Asset::AssetType, std::string> assetTypeFileExtensions{ std::make_pair(Asset::AssetType::Texture, ".png"), @@ -37,30 +40,46 @@ AssetManager::~AssetManager() { } Asset &AssetManager::GetAsset(std::string AssetName) { - Asset &asset = instance().assets[AssetName]; - if (!asset.isParsed()) + if (instance().assets.find(AssetName) == instance().assets.end() || !instance().assets[AssetName].isParsed()) LoadAsset(AssetName); - return asset; + return instance().assets[AssetName]; } void AssetManager::LoadAsset(std::string AssetName) { - if (instance().assets[AssetName].isParsed()) + if (instance().assets.find(AssetName) != instance().assets.end() && instance().assets[AssetName].isParsed()) return; + std::string AssetFileName = GetPathToAsset(AssetName); 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); + asset.data.texture = new Texture(AssetFileName,GL_CLAMP_TO_BORDER,GL_NEAREST); + //asset.data.texture.loadFromFile((asset.name + assetTypeFileExtensions.at(asset.type))); } } +std::string AssetManager::GetPathToAsset(std::string AssetName) { + if (instance().assets.find(AssetName) != instance().assets.end()){ + auto it = instance().assets.find(AssetName); + return pathToObjects + std::string(instance().assets[AssetName].hash.c_str(), 2) + "/" + + instance().assets[AssetName].hash; + } + + instance().assets[AssetName].hash=""; + instance().assets[AssetName].type=Asset::AssetType::Texture; + instance().assets[AssetName].name=AssetName; + instance().assets[AssetName].size=0; + return pathToAssetsMc + "" + instance().assets[AssetName].name + + assetTypeFileExtensions.at(instance().assets[AssetName].type); +} + bool Asset::isParsed() { switch (type) { case Unknown: return false; break; case Texture: - return this->data.texture.imageData != nullptr; + return this->data.texture != nullptr; break; case Sound: return false; @@ -79,7 +98,7 @@ Asset::~Asset() { case Unknown: break; case Texture: - SOIL_free_image_data(this->data.texture.imageData); + delete this->data.texture; break; case Sound: break; diff --git a/graphics/AssetManager.hpp b/graphics/AssetManager.hpp index 81be7c4..b2ff570 100644 --- a/graphics/AssetManager.hpp +++ b/graphics/AssetManager.hpp @@ -2,19 +2,15 @@ #include <fstream> #include <string> -#include <SOIL.h> #include <map> #include "../json.hpp" +#include "Texture.hpp" struct Asset { std::string name = ""; std::string hash = ""; union AssetData{ - struct TextureData{ - int width; - int height; - unsigned char *imageData; - } texture; + Texture *texture; } data; size_t size = 0; enum AssetType { @@ -38,12 +34,15 @@ class AssetManager { AssetManager &operator=(const AssetManager &); std::map<std::string, Asset> assets; -public: + static AssetManager &instance() { static AssetManager assetManager; return assetManager; } + static std::string GetPathToAsset(std::string AssetName); +public: + static Asset &GetAsset(std::string AssetName); static void LoadAsset(std::string AssetName); diff --git a/graphics/Camera3D.cpp b/graphics/Camera3D.cpp new file mode 100644 index 0000000..eb740e4 --- /dev/null +++ b/graphics/Camera3D.cpp @@ -0,0 +1,79 @@ +#include "Camera3D.hpp" + +Camera3D::Camera3D(glm::vec3 position, glm::vec3 up, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), + MovementSpeed(SPEED), + MouseSensitivity(SENSITIVTY), + Zoom(ZOOM) { + this->Position = position; + this->WorldUp = up; + this->Yaw = yaw; + this->Pitch = pitch; + this->updateCameraVectors(); +} + +Camera3D::Camera3D(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, + GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), + Zoom(ZOOM) { + this->Position = glm::vec3(posX, posY, posZ); + this->WorldUp = glm::vec3(upX, upY, upZ); + this->Yaw = yaw; + this->Pitch = pitch; + this->updateCameraVectors(); +} + +glm::mat4 Camera3D::GetViewMatrix() { + return glm::lookAt(this->Position, this->Position + this->Front, this->Up); +} + +void Camera3D::ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime) { + GLfloat velocity = this->MovementSpeed * deltaTime; + if (direction == FORWARD) + this->Position += this->Front * velocity; + if (direction == BACKWARD) + this->Position -= this->Front * velocity; + if (direction == LEFT) + this->Position -= this->Right * velocity; + if (direction == RIGHT) + this->Position += this->Right * velocity; +} + +void Camera3D::ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch) { + xoffset *= this->MouseSensitivity; + yoffset *= this->MouseSensitivity; + + this->Yaw += xoffset; + this->Pitch += yoffset; + + // Make sure that when pitch is out of bounds, screen doesn't get flipped + if (constrainPitch) { + if (this->Pitch > 89.0f) + this->Pitch = 89.0f; + if (this->Pitch < -89.0f) + this->Pitch = -89.0f; + } + + // Update Front, Right and Up Vectors using the updated Eular angles + this->updateCameraVectors(); +} + +void Camera3D::ProcessMouseScroll(GLfloat yoffset) { + if (this->Zoom >= 1.0f && this->Zoom <= 45.0f) + this->Zoom -= yoffset/5.0f; + if (this->Zoom <= 1.0f) + this->Zoom = 1.0f; + if (this->Zoom >= 45.0f) + this->Zoom = 45.0f; +} + +void Camera3D::updateCameraVectors() { + // Calculate the new Front vector + glm::vec3 front; + front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); + front.y = sin(glm::radians(this->Pitch)); + front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); + this->Front = glm::normalize(front); + // Also re-calculate the Right and Up vector + this->Right = glm::normalize(glm::cross(this->Front, + this->WorldUp)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. + this->Up = glm::normalize(glm::cross(this->Right, this->Front)); +} diff --git a/graphics/Camera3D.hpp b/graphics/Camera3D.hpp new file mode 100644 index 0000000..084462f --- /dev/null +++ b/graphics/Camera3D.hpp @@ -0,0 +1,66 @@ +#pragma once + +// Std. Includes +#include <vector> + +// GL Includes +#include <GL/glew.h> +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> + + +// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods +enum Camera_Movement { + FORWARD, + BACKWARD, + LEFT, + RIGHT +}; + +// Default camera values +const GLfloat YAW = -90.0f; +const GLfloat PITCH = 0.0f; +const GLfloat SPEED = 3.0f; +const GLfloat SENSITIVTY = 0.2f; +const GLfloat ZOOM = 45.0f; + +// An abstract camera class that processes input and calculates the corresponding Eular Angles, Vectors and Matrices for use in OpenGL +class Camera3D { +public: + // Camera3D Attributes + glm::vec3 Position; + glm::vec3 Front; + glm::vec3 Up; + glm::vec3 Right; + glm::vec3 WorldUp; + // Eular Angles + GLfloat Yaw; + GLfloat Pitch; + // Camera3D options + GLfloat MovementSpeed; + GLfloat MouseSensitivity; + GLfloat Zoom; + + // Constructor with vectors + explicit Camera3D(glm::vec3 position = glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), + GLfloat yaw = YAW, GLfloat pitch = PITCH); + + // Constructor with scalar values + Camera3D(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch); + + // Returns the view matrix calculated using Eular Angles and the LookAt Matrix + glm::mat4 GetViewMatrix(); + + // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems) + void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime); + + // Processes input received from a mouse input system. Expects the offset value in both the x and y direction. + void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true); + + // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis + void ProcessMouseScroll(GLfloat yoffset); + +private: + // Calculates the front vector from the Camera3D's (updated) Eular Angles + void updateCameraVectors(); +};
\ No newline at end of file diff --git a/graphics/Display.cpp b/graphics/Display.cpp index 01dd903..380a8ec 100644 --- a/graphics/Display.cpp +++ b/graphics/Display.cpp @@ -1,103 +1,222 @@ -#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 +#include "AssetManager.hpp" + +Display::Display(unsigned int winWidth, unsigned int winHeight, const char *winTitle, World *worldPtr) : world( + worldPtr) { + 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); + window->setVerticalSyncEnabled(true); + window->setMouseCursorVisible(false); + sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window); + + //Glew glewExperimental = GL_TRUE; - GLenum glewStatus = glewInit(); - if (glewStatus != GLEW_OK) { - std::cerr << "Can't initialize GLEW: " << glewGetErrorString(glewStatus) << std::endl; - throw 518; + if (glewInit() != GLEW_OK) { + std::cout << "Failed to initialize GLEW" << std::endl; + throw 3; } - int width, height; - glfwGetFramebufferSize(window, &width, &height); - glViewport(0, 0, width, height); -} - -Display::~Display() { - instance = nullptr; - glfwTerminate(); + glViewport(0, 0, width(), height()); + glEnable(GL_DEPTH_TEST); } bool Display::IsClosed() { - return false; + return !window->isOpen(); } -void Display::SetPlayerPos(float x, float y) { +void Display::SetPlayerPos(double playerX, double playerY, double playerZ) { + const int ChunkDistance = 2; + PositionI playerPos((int) playerX, (int) playerZ, (int) playerY); + for (auto &it:world->m_sections) { + PositionI delta = it.first-playerPos; + } } void Display::MainLoop() { - Shader vertexShader("./graphics/simpleVS.vs"); - Shader fragmentShader("./graphics/simpleFS.fs", false); - ShaderProgram program; - program.Attach(vertexShader); - program.Attach(fragmentShader); - program.Link(); + Shader shader("./shaders/simple.vs", "./shaders/simple.fs"); + Texture &texture1 = *(AssetManager::GetAsset("minecraft/textures/blocks/brick").data.texture); + Texture &texture2 = *(AssetManager::GetAsset("minecraft/textures/blocks/beacon").data.texture); GLfloat vertices[] = { - -0.5f, -0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - 0.0f, 0.5f, 0.0f + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; - GLuint VBO; + GLuint indices[] = { + 0, 1, 2, + 0, 2, 3 + }; + GLuint VBO, VAO, EBO; 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; + glGenBuffers(1, &EBO); 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 + { + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *) (3 * sizeof(GLfloat))); + glEnableVertexAttribArray(2); + } glBindVertexArray(0); - while (!glfwWindowShouldClose(window)) { - glfwPollEvents(); - + shader.Use(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture1.texture); + glUniform1i(glGetUniformLocation(shader.Program, "texture1"), 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture2.texture); + glUniform1i(glGetUniformLocation(shader.Program, "texture2"), 1); + + glm::vec3 cubePositions[] = { + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(2.0f, 5.0f, -15.0f), + glm::vec3(-1.5f, -2.2f, -2.5f), + glm::vec3(-3.8f, -2.0f, -12.3f), + glm::vec3(2.4f, -0.4f, -3.5f), + glm::vec3(-1.7f, 3.0f, -7.5f), + glm::vec3(1.3f, -2.0f, -2.5f), + glm::vec3(1.5f, 2.0f, -2.5f), + glm::vec3(1.5f, 0.2f, -1.5f), + glm::vec3(-1.3f, 1.0f, -1.5f) + }; + Camera3D camera; + bool captureMouse = true; + + bool isRunning = true; + while (isRunning) { + static sf::Clock clock, clock1; + float deltaTime = clock.getElapsedTime().asSeconds(); + float absTime = clock1.getElapsedTime().asSeconds(); + clock.restart(); + sf::Event event; + while (window->pollEvent(event)) { + switch (event.type) { + case sf::Event::Closed: + window->close(); + isRunning = false; + break; + case sf::Event::Resized: + glViewport(0, 0, width(), height()); + break; + case sf::Event::KeyPressed: + switch (event.key.code) { + case sf::Keyboard::Escape: + isRunning = false; + break; + case sf::Keyboard::T: + captureMouse = !captureMouse; + window->setMouseCursorVisible(!captureMouse); + sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), + *window); + break; + case sf::Keyboard::R: + shader.Reload(); + break; + default: + break; + } + case sf::Event::MouseWheelScrolled: + camera.ProcessMouseScroll(event.mouseWheelScroll.delta); + break; + default: + break; + } + } + if (captureMouse) { + 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); + int deltaX = (mousePos - center).x, deltaY = (center - mousePos).y; + camera.ProcessMouseMovement(deltaX, deltaY); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) + camera.ProcessKeyboard(Camera_Movement::FORWARD, deltaTime); + if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) + camera.ProcessKeyboard(Camera_Movement::BACKWARD, deltaTime); + if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) + camera.ProcessKeyboard(Camera_Movement::LEFT, deltaTime); + if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) + camera.ProcessKeyboard(Camera_Movement::RIGHT, deltaTime); + + + //Render code glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + shader.Use(); + + GLint modelLoc = glGetUniformLocation(shader.Program, "model"); + GLint projectionLoc = glGetUniformLocation(shader.Program, "projection"); + GLint viewLoc = glGetUniformLocation(shader.Program, "view"); + glm::mat4 projection = glm::perspective(camera.Zoom, (float) width() / (float) height(), 0.1f, 1000.0f); + glm::mat4 view = camera.GetViewMatrix(); + glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); + glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - glUseProgram((GLuint) program); glBindVertexArray(VAO); - glDrawArrays(GL_TRIANGLES, 0, 3); + for (GLuint i = 0; i < 10; i++) { + glm::mat4 model; + model = glm::translate(model, cubePositions[i]); + + GLfloat angle = 20.0f * (i); + model = glm::rotate(model, glm::radians(angle * absTime), glm::vec3(1.0f, 0.3f, 0.5f)); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); + + glDrawArrays(GL_TRIANGLES, 0, 36); + } glBindVertexArray(0); - glfwSwapBuffers(window); + //End of render code + + window->display(); } -} -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 index d6737ba..c656f2f 100644 --- a/graphics/Display.hpp +++ b/graphics/Display.hpp @@ -1,30 +1,32 @@ #pragma once -#include <condition_variable> -#include <GL/glew.h> -#include <GLFW/glfw3.h> +#include <SFML/Window.hpp> #include "../World.hpp" - -template <class T> -class CallbackHandler { - -}; +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> +#include "Shader.hpp" +#include "Texture.hpp" +#include "Camera3D.hpp" 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); + sf::Window *window; + World* world; + std::vector<Section*> toRender; public: - Display(int w, int h, std::string title, World *worldPtr); + Display(unsigned int winWidth, unsigned int winHeight, const char winTitle[9], World *worldPtr); + + bool IsClosed(); - ~Display(); + void SetPlayerPos(double playerX, double playerY, double playerZ); void MainLoop(); - bool IsClosed(); - - void SetPlayerPos(float x, float y); -}; + unsigned int width() { + return window->getSize().x; + } + unsigned int height() { + return window->getSize().y; + } +};
\ No newline at end of file diff --git a/graphics/Shader.cpp b/graphics/Shader.cpp index 2b72917..c84e169 100644 --- a/graphics/Shader.cpp +++ b/graphics/Shader.cpp @@ -1,36 +1,90 @@ -#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; +Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath) { + vertex = vertexPath; + fragment = fragmentPath; + // 1. Получаем исходный код шейдера из filePath + std::string vertexCode; + std::string fragmentCode; + std::ifstream vShaderFile; + std::ifstream fShaderFile; + // Удостоверимся, что ifstream объекты могут выкидывать исключения + vShaderFile.exceptions(std::ifstream::failbit); + fShaderFile.exceptions(std::ifstream::failbit); + try { + // Открываем файлы + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + // Считываем данные в потоки + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + // Закрываем файлы + vShaderFile.close(); + fShaderFile.close(); + // Преобразовываем потоки в массив GLchar + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); } - 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); + catch (std::ifstream::failure e) { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; + } + const GLchar *vShaderCode = vertexCode.c_str(); + const GLchar *fShaderCode = fragmentCode.c_str(); + + + // 2. Сборка шейдеров + GLuint vertex, fragment; GLint success; GLchar infoLog[512]; - glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); - if(!success) - { - glGetShaderInfoLog(shaderId, 512, NULL, infoLog); + + // Вершинный шейдер + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + // Если есть ошибки - вывести их + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; - throw 518; + }; + + // Вершинный шейдер + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + // Если есть ошибки - вывести их + glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragment, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + }; + + // Шейдерная программа + this->Program = glCreateProgram(); + glAttachShader(this->Program, vertex); + glAttachShader(this->Program, fragment); + glLinkProgram(this->Program); + //Если есть ошибки - вывести их + glGetProgramiv(this->Program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(this->Program, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } -} -Shader::~Shader() { - glDeleteShader(shaderId); + // Удаляем шейдеры, поскольку они уже в программу и нам больше не нужны. + glDeleteShader(vertex); + glDeleteShader(fragment); } -void Shader::bind() { +void Shader::Use() { + glUseProgram(this->Program); +} +void Shader::Reload() { + const GLchar *vertexPath = vertex; + const GLchar *fragmentPath = fragment; + this->~Shader(); + new(this) Shader(vertexPath, fragmentPath); + std::cout<<"Shader is realoded!"<<std::endl; } diff --git a/graphics/Shader.hpp b/graphics/Shader.hpp index 83e06e1..8178d2a 100644 --- a/graphics/Shader.hpp +++ b/graphics/Shader.hpp @@ -1,60 +1,22 @@ -#pragma once - #include <string> +#include <fstream> +#include <sstream> +#include <iostream> -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; - } +#include <GL/glew.h> -}; - -class ShaderProgram { - GLuint shaderProgram; +class Shader +{ +private: + const GLchar *vertex; + const GLchar *fragment; 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; - } - + // Идентификатор программы + GLuint Program; + // Конструктор считывает и собирает шейдер + Shader(const GLchar* vertexPath, const GLchar* fragmentPath); + // Использование программы + void Use(); + + void Reload(); };
\ No newline at end of file diff --git a/graphics/Texture.cpp b/graphics/Texture.cpp new file mode 100644 index 0000000..0104530 --- /dev/null +++ b/graphics/Texture.cpp @@ -0,0 +1,39 @@ +#include <iostream> +#include <SFML/Graphics.hpp> +#include "Texture.hpp" + +Texture::Texture(std::string filename, GLenum textureWrapping, GLenum textureFiltering) { + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + //Texture options + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textureWrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textureWrapping); + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,textureFiltering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + //Image load + sf::Image image; + if (!image.loadFromFile(filename)) { + std::cout << "Can't open image " << filename << std::endl; + throw 201; + } + if (image.getPixelsPtr()==nullptr){ + std::cout<<"Image data is corrupted!"<<std::endl; + throw 202; + } + image.flipVertically(); + + + //Creating texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) image.getPixelsPtr()); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + +} + +Texture::~Texture() { + glDeleteTextures(1, &texture); +} diff --git a/graphics/Texture.hpp b/graphics/Texture.hpp new file mode 100644 index 0000000..8e3f1af --- /dev/null +++ b/graphics/Texture.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include <GL/glew.h> + +class Texture { + Texture(Texture&); + Texture&operator=(Texture&); +public: + GLuint texture; + Texture(std::string filename, GLenum textureWrapping = GL_CLAMP_TO_BORDER, GLenum textureFiltering = GL_NEAREST); + ~Texture(); +};
\ No newline at end of file diff --git a/graphics/simpleFS.fs b/graphics/simpleFS.fs deleted file mode 100644 index 03b3fe0..0000000 --- a/graphics/simpleFS.fs +++ /dev/null @@ -1,8 +0,0 @@ -#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 deleted file mode 100644 index deae931..0000000 --- a/graphics/simpleVS.vs +++ /dev/null @@ -1,8 +0,0 @@ -#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 |