diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..610cd3d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.0) +project(Reassembly2) +set (CMAKE_CXX_STANDARD 11) +include(ExternalProject) + +#For YCM (YouCompleteME) +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + +#Modified FindSDL2 +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${Reassembly2_SOURCE_DIR}/cmake") + +MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} ) + +set(Reassembly2_BUILD_DIR "${Reassembly2}/build") + +find_package(SDL2 REQUIRED) +find_package(SDL2_image REQUIRED) +MESSAGE( STATUS "SDL2_LIBRARY: " ${SDL2_LIBRARY} ) +MESSAGE( STATUS "SDL2_INCLUDE_DIR: " ${SDL2_INCLUDE_DIR} ) + +MESSAGE( STATUS "SDL2IMAGE_LIBRARY: " ${SDL2IMAGE_LIBRARY}) +MESSAGE( STATUS "SDL2IMAGE_INCLUDE_DIR: " ${SDL2IMAGE_INCLUDE_DIR}) + +find_package(GLEW REQUIRED) +MESSAGE( STATUS "GLEW_LIBRARY: " ${GLEW_LIBRARY}) +MESSAGE( STATUS "GLEW_INLCUDE_DIR: " ${GLEW_INLCUDE_DIR}) + +find_package(OpenGL REQUIRED) +MESSAGE( STATUS "OPENGL_LIBRARY: " ${OPENGL_LIBRARY}) +MESSAGE( STATUS "OPENGL_INCLUDE_DIR: " ${OPENGL_INCLUDE_DIR}) + +find_package(Freetype REQUIRED) +MESSAGE( STATUS "FREETYPE_LIBRARY: " ${FREETYPE_LIBRARY}) +MESSAGE( STATUS "FREETYPE_INCLUDE_DIR: " ${FREETYPE_INCLUDE_DIR}) +set(FREETYPE_INCLUDE_DIR "/usr/include/freetype2") +MESSAGE( STATUS "Override FREETYPE_INCLUDE_DIR: " ${FREETYPE_INCLUDE_DIR}) + +find_package(GLM REQUIRED) +MESSAGE( STATUS "GLM_INCLUDE_DIR: " ${GLM_INCLUDE_DIR}) + +include_directories(${SDL2_INCLUDE_DIR} ${SDL2IMAGE_INCLUDE_DIR} + ${GLEW_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIR} + ${GLM_INCLUDE_DIR} ) +file(GLOB_RECURSE Reassembly2_SOURCE_FILES ${Reassembly2_SOURCE_DIR}/src/*.cpp) +add_executable(Reassembly2 ${Reassembly2_SOURCE_FILES}) +target_link_libraries(Reassembly2 ${SDL2_LIBRARY} ${SDL2IMAGE_LIBRARY} + ${GLEW_LIBRARY} ${OPENGL_LIBRARY} ${FREETYPE_LIBRARY}) diff --git a/cmake/FindGLM.cmake b/cmake/FindGLM.cmake new file mode 100644 index 0000000..e2d45a8 --- /dev/null +++ b/cmake/FindGLM.cmake @@ -0,0 +1,52 @@ +# +# Find GLM +# +# Try to find GLM : OpenGL Mathematics. +# This module defines +# - GLM_INCLUDE_DIRS +# - GLM_FOUND +# +# The following variables can be set as arguments for the module. +# - GLM_ROOT_DIR : Root library directory of GLM +# +# References: +# - https://github.com/Groovounet/glm/blob/master/util/FindGLM.cmake +# - https://bitbucket.org/alfonse/gltut/src/28636298c1c0/glm-0.9.0.7/FindGLM.cmake +# + +# Additional modules +include(FindPackageHandleStandardArgs) + +if (WIN32) + # Find include files + find_path( + GLM_INCLUDE_DIR + NAMES glm/glm.hpp + PATHS + $ENV{PROGRAMFILES}/include + ${GLM_ROOT_DIR}/include + DOC "The directory where glm/glm.hpp resides") +else() + # Find include files + find_path( + GLM_INCLUDE_DIR + NAMES glm/glm.hpp + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + ${GLM_ROOT_DIR}/include + DOC "The directory where glm/glm.hpp resides") +endif() + +# Handle REQUIRD argument, define *_FOUND variable +find_package_handle_standard_args(GLM DEFAULT_MSG GLM_INCLUDE_DIR) + +# Define GLM_INCLUDE_DIRS +if (GLM_FOUND) + set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR}) +endif() + +# Hide some variables +mark_as_advanced(GLM_INCLUDE_DIR) diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake new file mode 100644 index 0000000..e9db3e2 --- /dev/null +++ b/cmake/FindSDL2.cmake @@ -0,0 +1,256 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2 is an environment variable that would +# correspond to the ./configure --prefix=$SDL2 +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. +# +# Note that on windows this will only search for the 32bit libraries, to search +# for 64bit change x86/i686-w64 to x64/x86_64-w64 + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2014 Kitware, Inc. +# Copyright 2000-2011 Insight Software Consortium +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2} + ${SDL2} + PATH_SUFFIXES include/SDL2 include SDL2 + i686-w64-mingw32/include/SDL2 + x86_64-w64-mingw32/include/SDL2 + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +# Lookup the 64 bit libs on x64 +IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 + HINTS + $ENV{SDL2} + ${SDL2} + PATH_SUFFIXES lib64 lib + lib/x64 + /usr/lib64 + x86_64-w64-mingw32/lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) +# On 32bit build find the 32bit libs +ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 + HINTS + $ENV{SDL2} + ${SDL2} + PATH_SUFFIXES lib + lib/x86 + /usr/lib32 + i686-w64-mingw32/lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) +ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + # Lookup the 64 bit libs on x64 + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2} + ${SDL2} + PATH_SUFFIXES lib64 lib + lib/x64 + x86_64-w64-mingw32/lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + # On 32bit build find the 32bit libs + ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2} + ${SDL2} + PATH_SUFFIXES lib + lib/x86 + i686-w64-mingw32/lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") + IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/cmake/FindSDL2_image.cmake b/cmake/FindSDL2_image.cmake new file mode 100644 index 0000000..1d87508 --- /dev/null +++ b/cmake/FindSDL2_image.cmake @@ -0,0 +1,67 @@ +# Locate the SDL2_image library. This CMake module is a modified version +# of the original FindSDL_image.cmake file +# ########################################################################### +# Locate SDL_image library +# This module defines +# SDL2IMAGE_LIBRARY, the name of the library to link against +# SDLIMAGE_FOUND, if false, do not try to link to SDL +# SDL2IMAGE_INCLUDE_DIR, where to find SDL/SDL.h +# +# $SDLDIR is an environment variable that would +# correspond to the ./configure --prefix=$SDLDIR +# used in building SDL. +# +# Created by Eric Wing. This was influenced by the FindSDL.cmake +# module, but with modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). + +#============================================================================= +# Copyright 2005-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2IMAGE_INCLUDE_DIR SDL_image.h + HINTS + $ENV{SDL2IMAGEDIR} + $ENV{SDL2DIR} + PATH_SUFFIXES include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw/include/SDL2 # Fink + /opt/local/include/SDL2 # DarwinPorts + /opt/csw/include/SDL2 # Blastwave + /opt/include/SDL2 +) + +FIND_LIBRARY(SDL2IMAGE_LIBRARY + NAMES SDL2_image + HINTS + $ENV{SDL2IMAGEDIR} + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt +) + +SET(SDL2IMAGE_FOUND "NO") +IF(SDL2IMAGE_LIBRARY AND SDL2IMAGE_INCLUDE_DIR) + SET(SDL2IMAGE_FOUND "YES") +ENDIF(SDL2IMAGE_LIBRARY AND SDL2IMAGE_INCLUDE_DIR) diff --git a/src/Assets.cpp b/src/Assets.cpp new file mode 100755 index 0000000..b79dd77 --- /dev/null +++ b/src/Assets.cpp @@ -0,0 +1,102 @@ +#include "Assets.h" + +#include +#include +#include + +#include + +#include "Utility.h" + + +Shader Assets::loadShader(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile, std::string name) { + shaders[name] = loadShaderFromFile(vShaderFile, fShaderFile, gShaderFile); + return shaders[name]; +} +Shader Assets::getShader(std::string name) { + return shaders[name]; +} +Texture2D Assets::loadTexture(const GLchar *file, GLboolean alpha, std::string name) { + textures[name] = loadTextureFromFile(file,alpha); + return textures[name]; +} +Texture2D Assets::getTexture(std::string name) { + return textures[name]; +} + +Texture2D Assets::loadTextureFromFile(const GLchar *file, GLboolean alpha) { + Texture2D texture; + if(alpha) { + texture.Internal_Format = GL_RGBA; + texture.Image_Format = GL_RGBA; + } + + SDL_Surface *loadedSurface; + loadedSurface = IMG_Load( file ); + + if(loadedSurface == NULL) { + std::cout << "Unable to load Image " << file << " SDL_Image Error: " << IMG_GetError() << std::endl; + SDL_FreeSurface(loadedSurface); + return texture; + } + texture.Generate(loadedSurface->w, loadedSurface->h, (unsigned char *) loadedSurface->pixels); + + Utility::checkOpenGLError(); + + SDL_FreeSurface(loadedSurface); + return texture; +} + +Shader Assets::loadShaderFromFile(const GLchar *vShaderFile,const GLchar *fShaderFile, const GLchar *gShaderFile) { + // 1. Retrieve the vertex/fragment source code from filePath + std::string vertexCode; + std::string fragmentCode; + std::string geometryCode; + try + { + // Open files + std::ifstream vertexShaderFile(vShaderFile); + std::ifstream fragmentShaderFile(fShaderFile); + std::stringstream vShaderStream, fShaderStream; + // Read file's buffer contents into streams + vShaderStream << vertexShaderFile.rdbuf(); + fShaderStream << fragmentShaderFile.rdbuf(); + // close file handlers + vertexShaderFile.close(); + fragmentShaderFile.close(); + // Convert stream into string + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + // If geometry shader path is present, also load a geometry shader + if (gShaderFile != nullptr) + { + std::ifstream geometryShaderFile(gShaderFile); + std::stringstream gShaderStream; + gShaderStream << geometryShaderFile.rdbuf(); + geometryShaderFile.close(); + geometryCode = gShaderStream.str(); + } + } + catch (std::exception e) + { + std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl; + } + const GLchar *vShaderCode = vertexCode.c_str(); + const GLchar *fShaderCode = fragmentCode.c_str(); + const GLchar *gShaderCode = geometryCode.c_str(); + // 2. Now create shader object from source code + Shader shader; + shader.Compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr); + return shader; +} + +Assets::~Assets() { + std::cout << "Deleting Assets" << std::endl; + for(auto iter : shaders) { + glDeleteProgram(iter.second.ID); + } + for(auto iter : textures) { + glDeleteTextures(1, &iter.second.ID); + } +} + diff --git a/src/Assets.h b/src/Assets.h new file mode 100755 index 0000000..3760725 --- /dev/null +++ b/src/Assets.h @@ -0,0 +1,32 @@ +#ifndef ASSETS_H +#define ASSETS_H + +#include +#include + +#include + +#include "Texture.h" +#include "Shader.h" + +class Assets { + private: + std::map textures; + std::map shaders; + + Texture2D loadTextureFromFile(const GLchar *file, GLboolean alpha); + Shader loadShaderFromFile(const GLchar *vShaderFile,const GLchar *fShaderFile, const GLchar *gShaderFile=nullptr); + + public: + Assets() {} + ~Assets(); + + Shader loadShader(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile, std::string name); + Shader getShader(std::string name); + Texture2D loadTexture(const GLchar *file, GLboolean alpha, std::string name); + Texture2D getTexture(std::string name); + + +}; + +#endif diff --git a/src/BitmapFont.cpp b/src/BitmapFont.cpp new file mode 100644 index 0000000..ad46c8b --- /dev/null +++ b/src/BitmapFont.cpp @@ -0,0 +1,116 @@ +#include "BitmapFont.h" + +#include +#include FT_FREETYPE_H +#include + +#include + +BitmapFont::BitmapFont(std::string fontLocation) { + FT_Library ft; + if(FT_Init_FreeType(&ft)) { + std::cout << "ERROR::FreeType: Could not init FreeType Library" << std::endl; + } + FT_Face face; + if(FT_New_Face(ft, fontLocation.c_str(), 0, &face)){ + std::cout << "ERROR::FreeType: Failed to load font" << std::endl; + } + FT_Set_Pixel_Sizes(face, 0, 48); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //Disable byte-alignment restriction + for(GLubyte c = 0; c < 128; c++) { + //Map bitmaps to chars + if(FT_Load_Char(face, c, FT_LOAD_RENDER)) { + std::cout << "ERROR::FreeType: Could not load Glyph: " << c << std::endl; + continue; + } + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RED, + face->glyph->bitmap.width, + face->glyph->bitmap.rows, + 0, + GL_RED, + GL_UNSIGNED_BYTE, + face->glyph->bitmap.buffer + ); + // Set texture options + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + Character character = { + texture, + glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), + glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), + face->glyph->advance.x + }; + characters.insert(std::pair(c, character)); + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); //Reset byte-alignment restriction + FT_Done_Face(face); + FT_Done_FreeType(ft); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + projection = glm::ortho(0.0f,800.0f,0.0f,600.0f); + + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void BitmapFont::drawText(Shader &s, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color) { + s.Use(); + s.SetVector3f("textColor", color, true); + s.SetMatrix4("projection",projection,true); + + glActiveTexture(GL_TEXTURE0); + glBindVertexArray(VAO); + + // Iterate through all characters + std::string::const_iterator c; + for (c = text.begin(); c != text.end(); c++) + { + Character ch = characters[*c]; + + GLfloat xpos = x + ch.bearing.x * scale; + GLfloat ypos = y - (ch.size.y - ch.bearing.y) * scale; + + GLfloat w = ch.size.x * scale; + GLfloat h = ch.size.y * scale; + // Update VBO for each character + GLfloat vertices[6][4] = { + { xpos, ypos + h, 0.0, 0.0 }, + { xpos, ypos, 0.0, 1.0 }, + { xpos + w, ypos, 1.0, 1.0 }, + + { xpos, ypos + h, 0.0, 0.0 }, + { xpos + w, ypos, 1.0, 1.0 }, + { xpos + w, ypos + h, 1.0, 0.0 } + }; + // Render glyph texture over quad + glBindTexture(GL_TEXTURE_2D, ch.texID); + // Update content of VBO memory + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // Be sure to use glBufferSubData and not glBufferData + + glBindBuffer(GL_ARRAY_BUFFER, 0); + // Render quad + glDrawArrays(GL_TRIANGLES, 0, 6); + // Now advance cursors for next glyph (note that advance is number of 1/64 pixels) + x += (ch.advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels)) + } + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/src/BitmapFont.h b/src/BitmapFont.h new file mode 100644 index 0000000..d9f801a --- /dev/null +++ b/src/BitmapFont.h @@ -0,0 +1,29 @@ +#ifndef BITMAPFONT_H +#define BITMAPFONT_H + +#include +#include +#include +#include + +#include "Shader.h" + +struct Character { + GLuint texID; + glm::ivec2 size; + glm::ivec2 bearing; + GLuint advance; +}; + +class BitmapFont { + public: + BitmapFont(std::string fontLocation); + void drawText(Shader &s, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color); + + private: + std::map characters; + GLuint VAO, VBO; + glm::mat4 projection; +}; + +#endif diff --git a/src/Command.h b/src/Command.h new file mode 100644 index 0000000..7f103e3 --- /dev/null +++ b/src/Command.h @@ -0,0 +1,11 @@ +#ifndef COMMAND_H +#define COMMAND_H + +class Command { + public: + virtual ~Command() {} + virtual void execute() = 0; +}; + + +#endif diff --git a/src/DarkRP2D.cpp b/src/DarkRP2D.cpp deleted file mode 100644 index 00bcba7..0000000 --- a/src/DarkRP2D.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include - -#include "DarkRP2D.h" -#include "utility/Utility.h" -#include "entities/components/Position.h" - -#include "entities/MovementSystem.h" -#include "entities/RenderSystem.h" -#include "entities/DestructSystem.h" - -void DarkRP2D::create(SDL_Renderer *gRenderer, InputHandler *inputHandler) { - this->gRenderer = gRenderer; - this->inputHandler = inputHandler; - //Load PNG texture - gTexture = utility::loadTexture( "assets/police_officer.png", gRenderer); - ex = new entityx::EntityX(); - ex->systems.add(); - ex->systems.add(); - ex->systems.add(); - ex->systems.configure(); - - entityx::Entity entity = ex->entities.create(); - entity.assign(); - entity.destroy(); -} - - unsigned int ups = 0; - unsigned int fps = 0; - unsigned int acc = 0; - void DarkRP2D::loop(unsigned int deltaTime) { - accumulator += deltaTime; - acc += deltaTime; - - Command *command = inputHandler->handleInput(); - if (command) { - command->execute(); - } - - skippedFrames = 0; - while (accumulator >= MS_PER_UPDATE && skippedFrames <= MAX_FRAMESKIP) { - accumulator -= MS_PER_UPDATE; - update(MS_PER_UPDATE/1000.0f); //Converted to Sec for normalization - ups++; - skippedFrames++; - } - - if(acc >= 1000) { - std::cout << "Updates per second: " << ups << " Frames per Second: " << fps << std::endl; - acc -= 1000; - ups = 0; - fps = 0; - } - fps++; - render(MS_PER_UPDATE/1000.0f); - } - - void DarkRP2D::update(double deltaInSec) { - ex->systems.update(deltaInSec); - ex->systems.update(deltaInSec); - } - - void DarkRP2D::render(double deltaInSec) { - //Clear screen - SDL_RenderClear( gRenderer ); - ex->systems.update(deltaInSec); - - SDL_Rect textureRect; //create a rect - textureRect.x = 0; //controls the rect's x coordinate - textureRect.y = 0; // controls the rect's y coordinte - textureRect.w = 64; // controls the width of the rect - textureRect.h = 64; // controls the height of the rect - - //Render texture to screen - SDL_RenderCopy( gRenderer, gTexture, NULL, &textureRect ); - - //Update screen - SDL_RenderPresent( gRenderer ); - } - - void DarkRP2D::resize(int width, int height) { - - } - - DarkRP2D::~DarkRP2D() { - //Free loaded image - SDL_DestroyTexture( gTexture ); - delete ex; - - gTexture = NULL; - } diff --git a/src/DarkRP2D.h b/src/DarkRP2D.h deleted file mode 100644 index 6435c6e..0000000 --- a/src/DarkRP2D.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef DARKRP2D_H -#define DARKRP2D_H - -#include -#include - -#include "input/InputHandler.h" - -class DarkRP2D { -private: - unsigned int accumulator = 0; - int skippedFrames = 0; - //test texture - SDL_Texture *gTexture = NULL; - InputHandler *inputHandler; - -public: - static const int UPDATES_PER_SECOND = 60; - static const unsigned int MS_PER_UPDATE = 17; // 1 / UPDATES_PER_SECOND ~ 16,777777777 - static const int MAX_FRAMESKIP = 5; - - SDL_Renderer *gRenderer = NULL; - entityx::EntityX *ex = NULL; - - DarkRP2D() {} - ~DarkRP2D(); - void create(SDL_Renderer *gRenderer, InputHandler *inputHandler); - void loop(unsigned int deltaTime); - void update(double deltaInSec); - void render(double deltaInSec); - void resize(int width, int height); -}; - -#endif // DARKRP2D_H diff --git a/src/DesktopLauncher.cpp b/src/DesktopLauncher.cpp old mode 100644 new mode 100755 index 329c19d..3d3ee51 --- a/src/DesktopLauncher.cpp +++ b/src/DesktopLauncher.cpp @@ -1,165 +1,87 @@ #include +#include +#include +#include +#include -#include -#include "DarkRP2D.h" -#include "input/InputHandler.h" +#include "Reassembly2.h" -#define GAME_NAME "DarkRP2D" +using namespace std; -const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600; +const int SCREEN_WIDTH = 800; +const int SCREEN_HEIGHT = 600; +static SDL_Window* gWindow = NULL; +static SDL_GLContext glcontext; -SDL_Window* gWindow = NULL; //The window we'll be rendering to -SDL_Surface* gScreenSurface = NULL; //The surface contained by the window -SDL_Renderer* gRenderer = NULL; -DarkRP2D* darkRP2D = NULL; -InputHandler* inputHandler = NULL; - -void PrintEvent(const SDL_Event *event) { - if (event->type == SDL_WINDOWEVENT) { - switch (event->window.event) { - case SDL_WINDOWEVENT_SHOWN: - SDL_Log("Window %d shown", event->window.windowID); - break; - case SDL_WINDOWEVENT_HIDDEN: - SDL_Log("Window %d hidden", event->window.windowID); - break; - case SDL_WINDOWEVENT_EXPOSED: - SDL_Log("Window %d exposed", event->window.windowID); - break; - case SDL_WINDOWEVENT_MOVED: - SDL_Log("Window %d moved to %d,%d", - event->window.windowID, event->window.data1, - event->window.data2); - break; - case SDL_WINDOWEVENT_RESIZED: - SDL_Log("Window %d resized to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - SDL_Log("Window %d size changed to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); - break; - case SDL_WINDOWEVENT_MINIMIZED: - SDL_Log("Window %d minimized", event->window.windowID); - break; - case SDL_WINDOWEVENT_MAXIMIZED: - SDL_Log("Window %d maximized", event->window.windowID); - break; - case SDL_WINDOWEVENT_RESTORED: - SDL_Log("Window %d restored", event->window.windowID); - break; - case SDL_WINDOWEVENT_ENTER: - SDL_Log("Mouse entered window %d", - event->window.windowID); - break; - case SDL_WINDOWEVENT_LEAVE: - SDL_Log("Mouse left window %d", event->window.windowID); - break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - SDL_Log("Window %d gained keyboard focus", - event->window.windowID); - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - SDL_Log("Window %d lost keyboard focus", - event->window.windowID); - break; - case SDL_WINDOWEVENT_CLOSE: - SDL_Log("Window %d closed", event->window.windowID); - break; -#if SDL_VERSION_ATLEAST(2, 0, 5) - case SDL_WINDOWEVENT_TAKE_FOCUS: - SDL_Log("Window %d is offered a focus", event->window.windowID); - break; - case SDL_WINDOWEVENT_HIT_TEST: - SDL_Log("Window %d has a special hit test", event->window.windowID); - break; -#endif - default: - SDL_Log("Window %d got unknown event %d", - event->window.windowID, event->window.event); - break; - } - } -} - -bool init() { - bool success = true; - //Initialize SDL - if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { - printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() ); - success = false; - } else { - //Create window - gWindow = SDL_CreateWindow( GAME_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); - if( gWindow == NULL ) { - printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); - success = false; - } else { - //Get window surface - gScreenSurface = SDL_GetWindowSurface( gWindow ); - if( gScreenSurface == NULL ) - { - printf( "ScreenSurface could not be fetched! SDL Error: %s\n", SDL_GetError() ); - success = false; - } - //Create renderer for window - gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED ); - if( gRenderer == NULL ) - { - printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() ); - success = false; - } - } - } - inputHandler = new InputHandler(); - darkRP2D = new DarkRP2D(); - darkRP2D->create(gRenderer, inputHandler); - - return success; -} - -void close() { - delete darkRP2D; - delete inputHandler; - SDL_DestroyRenderer( gRenderer ); - SDL_FreeSurface( gScreenSurface ); - SDL_DestroyWindow( gWindow ); - SDL_Quit(); -} +void dispose(); +bool initSDL(); int main(int argc, char *argv[]) { - //Initialization flag - bool success = true; - success = init(); - SDL_SetWindowResizable(gWindow, SDL_TRUE); - //Main loop flag - bool running = true; - //Event handler - SDL_Event e; - //Main GameClass + //Init SDL_Window, SDL_Surface, SDL_Renderer + if(!initSDL()) { + dispose(); + return 1; + } - unsigned int lastTime = SDL_GetTicks(), currentTime, elapsedTime; - //While application is running - while( running ) { - currentTime = SDL_GetTicks(); - elapsedTime = currentTime - lastTime; - //Handle events on queue - while( SDL_PollEvent( &e ) != 0 ) { - //User requests quit - if( e.type == SDL_QUIT ) { - running = false; - } else if ((e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) && e.key.repeat == 0) { - inputHandler->inputEvent(&e); - } - PrintEvent(&e); - } - darkRP2D->loop(elapsedTime); - lastTime = currentTime; - } + //While application is running + bool quit = false; + SDL_Event e; + Reassembly2 resA(gWindow); + resA.create(); + unsigned int lastTime = SDL_GetTicks(), currentTime, elapsedTime; + while( !quit ) { + currentTime = SDL_GetTicks(); + elapsedTime = currentTime - lastTime; + lastTime = currentTime; + if(SDL_PollEvent(&e) != 0) { + if(e.type == SDL_QUIT) { + quit = true; + break; + } + resA.loop(&e,elapsedTime); + } else { + resA.loop(NULL,elapsedTime); + } - close(); + } - return !success; + dispose(); + return 0; +} + +bool initSDL() { + //Init SDL + if(SDL_Init(SDL_INIT_VIDEO) < 0 ) { + cout << "SDL could not initialize! SDL_Error: " << SDL_GetError() << endl; + return false; + } + //Init Window + gWindow = SDL_CreateWindow( "SDL TEST", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL); + if( gWindow == NULL) { + cout << "Window could not be created! SDL_Error: " << SDL_GetError() << endl; + return false; + } + //Mask deprectated functions + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + //Init OpenGL Renderer + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + glcontext = SDL_GL_CreateContext(gWindow); + if(glcontext == NULL) { + cout << "Could not create OpenGL Context: " << SDL_GetError() << endl; + return false; + } + //Init GLEW + glewExperimental = GL_TRUE; + GLenum err = glewInit(); + if(GLEW_OK != err) { + cout << "Init of Glew failed: " << glewGetErrorString(err) << endl; + return false; + } + return true; +} + +void dispose() { + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow( gWindow ); + SDL_Quit(); } diff --git a/src/GameObject.cpp b/src/GameObject.cpp new file mode 100644 index 0000000..068b133 --- /dev/null +++ b/src/GameObject.cpp @@ -0,0 +1,37 @@ +#include "GameObject.h" + +#include +#include + +GameObject::GameObject() { + //Create VBO + glGenBuffers(1, &VBO); + float vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + glBindBuffer(GL_ARRAY_BUFFER,VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW); + //Create VAO + glGenBuffers(1, &VAO); + glBindVertexArray(VAO); + //Set attriPointer and enable + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0); + glEnableVertexAttribArray(0); + + //Cleanup + glBindBuffer(GL_ARRAY_BUFFER,0); + glBindVertexArray(0); +} + +GameObject::~GameObject() { + std::cout << "Deleting GameObject" << std::endl; + glDeleteBuffers(1,&VBO); + glDeleteBuffers(1,&VAO); +} + +void GameObject::draw() { + glBindVertexArray(this->VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); +} diff --git a/src/GameObject.h b/src/GameObject.h new file mode 100644 index 0000000..84a241e --- /dev/null +++ b/src/GameObject.h @@ -0,0 +1,17 @@ +#ifndef GAMEOBJECT_H +#define GAMEOBJECT_H + +class GameObject { + private: + unsigned int VBO; + unsigned int VAO; + + public: + GameObject(); + ~GameObject(); + + void draw(); + +}; + +#endif diff --git a/src/InputHandler.cpp b/src/InputHandler.cpp new file mode 100644 index 0000000..65582e3 --- /dev/null +++ b/src/InputHandler.cpp @@ -0,0 +1,27 @@ +#include "InputHandler.h" + +#include + +InputHandler::InputHandler() { + +} + +InputHandler::~InputHandler() { + //Free all Commands +} + +void InputHandler::handleInput(SDL_Event *event) { + if(event == NULL) { + return; + } + switch (event->type) { + case SDL_KEYDOWN: + std::cout << "The Key " << SDL_GetKeyName(event->key.keysym.sym) << " has been pressed!" << std::endl; + + break; + case SDL_KEYUP: + std::cout << "The Key " << SDL_GetKeyName(event->key.keysym.sym) << " has been released!" << std::endl; + break; + default: break; + } +} diff --git a/src/InputHandler.h b/src/InputHandler.h new file mode 100644 index 0000000..d6ea3ff --- /dev/null +++ b/src/InputHandler.h @@ -0,0 +1,19 @@ +#ifndef INPUTHANDLER_H +#define INPUTHANDLER_H +#include + +#include "Command.h" + +class InputHandler { + public: + void handleInput(SDL_Event *event); + ~InputHandler(); + InputHandler(); + + private: + Command* W; + Command* A; + Command* S; + Command* D; +}; +#endif diff --git a/src/Reassembly2.cpp b/src/Reassembly2.cpp new file mode 100755 index 0000000..c92c9f2 --- /dev/null +++ b/src/Reassembly2.cpp @@ -0,0 +1,83 @@ +#include "Reassembly2.h" + +#include +#include + +Reassembly2::~Reassembly2() { + std::cout << "Game got destroyed!" << std::endl; + delete assets; + delete obj; + delete inputHandler; + for(unsigned int i = 0; iloadTexture("bucket.png",false,"bucket"); + assets->loadTexture("drop.png",false,"drop"); + assets->loadShader("vert.shader","frag.shader",nullptr,"defaultShader"); + assets->loadShader("bitmapvert.shader","bitmapfrag.shader",nullptr,"bitmapShader"); + + obj = new GameObject(); + inputHandler = new InputHandler(); + font = new BitmapFont("arial.ttf"); + + glClearColor(1.f,1.f,1.f,1.f); + spawnRainDrop(); +} + +void Reassembly2::loop(SDL_Event *event, unsigned int delta) { + static unsigned int accumulator = 0, ups = 0, fps = 0, acc = 0; + accumulator += delta; + acc += delta; + + while(accumulator >= 17) { + accumulator -= 17; + update(event, delta); + ups++; + } + + if(acc >= 1000) { + std::cout << "Updates per second: " << ups << " Frames per Second: " << fps << std::endl; + acc -= 1000; + ups = 0; + fps = 0; + } + render(delta); + fps++; +} + +void Reassembly2::update(SDL_Event *event, unsigned int delta) { + inputHandler->handleInput(event); +} + +void Reassembly2::render(unsigned int delta) { + glClear(GL_COLOR_BUFFER_BIT); + + //Drawing + Shader defaultShader = assets->getShader("defaultShader"); + defaultShader.Use(); + //Draw Triangle + obj->draw(); + + //texttest + Shader bitmapShader = assets->getShader("bitmapShader"); + font->drawText(bitmapShader, "Hallo du noob", 25.0f, 25.0f, 1.f, glm::vec3(0.5f,0.8f,0.2f)); + + SDL_GL_SwapWindow(gWindow); +} + +void Reassembly2::resize(int width, int height){ +} + +void Reassembly2::spawnRainDrop() { + SDL_Rect *rainDrop = new SDL_Rect; + rainDrop->x = 100; + rainDrop->y = 100; + rainDrop->w = 64; + rainDrop->h= 64; + rainDrops.push_back(rainDrop); +} diff --git a/src/Reassembly2.h b/src/Reassembly2.h new file mode 100755 index 0000000..670294b --- /dev/null +++ b/src/Reassembly2.h @@ -0,0 +1,35 @@ +#ifndef REASSEMBLY2_H +#define REASSEMBLY2_H + +class Reassembly2; +#include +#include +#include "Assets.h" +#include "GameObject.h" +#include "InputHandler.h" +#include "BitmapFont.h" + +class Reassembly2 { + private: + SDL_Window* gWindow; + std::vector rainDrops; + Assets *assets; + GameObject *obj; + InputHandler *inputHandler; + BitmapFont *font; + + void spawnRainDrop(); + + public: + + Reassembly2(SDL_Window *gWindow) : gWindow(gWindow) {} + ~Reassembly2(); + void create (); + void loop(SDL_Event *event, unsigned int delta); + void update(SDL_Event *event, unsigned int delta); + void render(unsigned int delta); + void resize(int width, int height); + +}; + +#endif diff --git a/src/Shader.cpp b/src/Shader.cpp new file mode 100644 index 0000000..e018e07 --- /dev/null +++ b/src/Shader.cpp @@ -0,0 +1,117 @@ +#include "Shader.h" + +#include + +Shader &Shader::Use() { + glUseProgram(this->ID); + return *this; +} + +void Shader::Compile(const GLchar* vertexSource, const GLchar* fragmentSource, const GLchar* geometrySource) { + GLuint sVertex, sFragment, gShader; + // Vertex Shader + sVertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(sVertex, 1, &vertexSource, NULL); + glCompileShader(sVertex); + checkCompileErrors(sVertex, "VERTEX"); + // Fragment Shader + sFragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(sFragment, 1, &fragmentSource, NULL); + glCompileShader(sFragment); + checkCompileErrors(sFragment, "FRAGMENT"); + // If geometry shader source code is given, also compile geometry shader + if (geometrySource != nullptr) + { + gShader = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(gShader, 1, &geometrySource, NULL); + glCompileShader(gShader); + checkCompileErrors(gShader, "GEOMETRY"); + } + // Shader Program + this->ID = glCreateProgram(); + glAttachShader(this->ID, sVertex); + glAttachShader(this->ID, sFragment); + if (geometrySource != nullptr) + glAttachShader(this->ID, gShader); + glLinkProgram(this->ID); + checkCompileErrors(this->ID, "PROGRAM"); + // Delete the shaders as they're linked into our program now and no longer necessery + glDeleteShader(sVertex); + glDeleteShader(sFragment); + if (geometrySource != nullptr) + glDeleteShader(gShader); +} + +void Shader::SetFloat(const GLchar *name, GLfloat value, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform1f(glGetUniformLocation(this->ID, name), value); +} +void Shader::SetInteger(const GLchar *name, GLint value, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform1i(glGetUniformLocation(this->ID, name), value); +} +void Shader::SetVector2f(const GLchar *name, GLfloat x, GLfloat y, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform2f(glGetUniformLocation(this->ID, name), x, y); +} +void Shader::SetVector2f(const GLchar *name, const glm::vec2 &value, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform2f(glGetUniformLocation(this->ID, name), value.x, value.y); +} +void Shader::SetVector3f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform3f(glGetUniformLocation(this->ID, name), x, y, z); +} +void Shader::SetVector3f(const GLchar *name, const glm::vec3 &value, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform3f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z); +} +void Shader::SetVector4f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform4f(glGetUniformLocation(this->ID, name), x, y, z, w); +} +void Shader::SetVector4f(const GLchar *name, const glm::vec4 &value, GLboolean useShader) { + if (useShader) + this->Use(); + glUniform4f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z, value.w); +} +void Shader::SetMatrix4(const GLchar *name, const glm::mat4 &matrix, GLboolean useShader) { + if (useShader) + this->Use(); + glUniformMatrix4fv(glGetUniformLocation(this->ID, name), 1, GL_FALSE, glm::value_ptr(matrix)); +} + + +void Shader::checkCompileErrors(GLuint object, std::string type) { + GLint success; + GLchar infoLog[1024]; + if (type != "PROGRAM") + { + glGetShaderiv(object, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(object, 1024, NULL, infoLog); + std::cout << "| Shader Error at Compile-time: Type: " << type << "\n" + << infoLog << "\n -- --------------------------------------------------- -- " + << std::endl; + } + } + else + { + glGetProgramiv(object, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(object, 1024, NULL, infoLog); + std::cout << "| ERROR::Shader: Link-time error: Type: " << type << "\n" + << infoLog << "\n -- --------------------------------------------------- -- " + << std::endl; + } + } +} diff --git a/src/Shader.h b/src/Shader.h new file mode 100644 index 0000000..acccffd --- /dev/null +++ b/src/Shader.h @@ -0,0 +1,40 @@ +#ifndef SHADER_H +#define SHADER_H + +#include + +#include +#include +#include + + +// General purpsoe shader object. Compiles from file, generates +// compile/link-time error messages and hosts several utility +// functions for easy management. +class Shader +{ +public: + // State + GLuint ID; + // Constructor + Shader() { } + // Sets the current shader as active + Shader &Use(); + // Compiles the shader from given source code + void Compile(const GLchar *vertexSource, const GLchar *fragmentSource, const GLchar *geometrySource = nullptr); // Note: geometry source code is optional + // Utility functions + void SetFloat (const GLchar *name, GLfloat value, GLboolean useShader = false); + void SetInteger (const GLchar *name, GLint value, GLboolean useShader = false); + void SetVector2f (const GLchar *name, GLfloat x, GLfloat y, GLboolean useShader = false); + void SetVector2f (const GLchar *name, const glm::vec2 &value, GLboolean useShader = false); + void SetVector3f (const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLboolean useShader = false); + void SetVector3f (const GLchar *name, const glm::vec3 &value, GLboolean useShader = false); + void SetVector4f (const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLboolean useShader = false); + void SetVector4f (const GLchar *name, const glm::vec4 &value, GLboolean useShader = false); + void SetMatrix4 (const GLchar *name, const glm::mat4 &matrix, GLboolean useShader = false); +private: + // Checks if compilation or linking failed and if so, print the error logs + void checkCompileErrors(GLuint object, std::string type); +}; + +#endif diff --git a/src/Texture.cpp b/src/Texture.cpp new file mode 100644 index 0000000..1b0480b --- /dev/null +++ b/src/Texture.cpp @@ -0,0 +1,29 @@ +#include + +#include "Texture.h" + + +Texture2D::Texture2D() + : Width(0), Height(0), Internal_Format(GL_RGB), Image_Format(GL_RGB), Wrap_S(GL_REPEAT), Wrap_T(GL_REPEAT), Filter_Min(GL_LINEAR), Filter_Max(GL_LINEAR) +{ + glGenTextures(1, &this->ID); +} + +void Texture2D::Generate(GLuint width, GLuint height, unsigned char* data) { + this->Width = width; + this->Height = height; + // Create Texture + glBindTexture(GL_TEXTURE_2D, this->ID); + glTexImage2D(GL_TEXTURE_2D, 0, this->Internal_Format, width, height, 0, this->Image_Format, GL_UNSIGNED_BYTE, data); + // Set Texture wrap and filter modes + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, this->Wrap_S); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, this->Wrap_T); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this->Filter_Min); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this->Filter_Max); + // Unbind texture + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Texture2D::Bind() const { + glBindTexture(GL_TEXTURE_2D, this->ID); +} diff --git a/src/Texture.h b/src/Texture.h new file mode 100644 index 0000000..2d277b9 --- /dev/null +++ b/src/Texture.h @@ -0,0 +1,31 @@ +#ifndef TEXTURE_H +#define TEXTURE_H + +#include + +// Texture2D is able to store and configure a texture in OpenGL. +// It also hosts utility functions for easy management. +class Texture2D +{ +public: + // Holds the ID of the texture object, used for all texture operations to reference to this particlar texture + GLuint ID; + // Texture image dimensions + GLuint Width, Height; // Width and height of loaded image in pixels + // Texture Format + GLuint Internal_Format; // Format of texture object + GLuint Image_Format; // Format of loaded image + // Texture configuration + GLuint Wrap_S; // Wrapping mode on S axis + GLuint Wrap_T; // Wrapping mode on T axis + GLuint Filter_Min; // Filtering mode if texture pixels < screen pixels + GLuint Filter_Max; // Filtering mode if texture pixels > screen pixels + // Constructor (sets default texture modes) + Texture2D(); + // Generates texture from image data + void Generate(GLuint width, GLuint height, unsigned char* data); + // Binds the texture as the current active GL_TEXTURE_2D texture object + void Bind() const; +}; + +#endif diff --git a/src/Utility.h b/src/Utility.h new file mode 100644 index 0000000..7fd24e3 --- /dev/null +++ b/src/Utility.h @@ -0,0 +1,13 @@ +#ifndef UTILITY_H +#define UTILITY_H + + +namespace Utility{ + inline void checkOpenGLError() { + GLenum err; + if((err = glGetError()) != GL_NO_ERROR) { + std::cout << "OpenGL Error: " << err << std::endl; + } + } +} +#endif diff --git a/src/entities/DestructSystem.cpp b/src/entities/DestructSystem.cpp deleted file mode 100644 index 86b591d..0000000 --- a/src/entities/DestructSystem.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "DestructSystem.h" -#include "components/Texture.h" - -#include - -void DestructSystem::configure(entityx::EventManager &event_manager) { - event_manager.subscribe(*this); -} - -void DestructSystem::update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt){} - - -void DestructSystem::receive(const entityx::EntityDestroyedEvent &destroyedEvent) { - /*entityx::ComponentHandle texture = destroyedEvent.entity.component(); - if (texture) { - // Do stuff with texture - }*/ - std::cout << "!!!!!!!!!!!!!!!!!!!Entity destroyed!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; -} diff --git a/src/entities/DestructSystem.h b/src/entities/DestructSystem.h deleted file mode 100644 index 05da5f1..0000000 --- a/src/entities/DestructSystem.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef DESTRUCTSYSTEM_H -#define DESTRUCTSYSTEM_H - -#include - -class DestructSystem : public entityx::System, public entityx::Receiver { -public: - void configure(entityx::EventManager &event_manager); - void update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt); - void receive(const entityx::EntityDestroyedEvent &destroyedEvent); -}; - -#endif //DESTRUCTSYSTEM_H diff --git a/src/entities/MovementSystem.cpp b/src/entities/MovementSystem.cpp deleted file mode 100644 index 21e0967..0000000 --- a/src/entities/MovementSystem.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "MovementSystem.h" - -#include - -void MovementSystem::update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt) { - //std::cout << "Moving delta: " << dt << std::endl; -} diff --git a/src/entities/MovementSystem.h b/src/entities/MovementSystem.h deleted file mode 100644 index d9e4086..0000000 --- a/src/entities/MovementSystem.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MOVEMENTSYSTEM_H -#define MOVEMENTSYSTEM_H - -#include - -class MovementSystem : public entityx::System { -public: - void update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt) override; -}; - -#endif //MOVEMENTSYSTEM_H diff --git a/src/entities/RenderSystem.cpp b/src/entities/RenderSystem.cpp deleted file mode 100644 index 7bad130..0000000 --- a/src/entities/RenderSystem.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "RenderSystem.h" - -#include - -void RenderSystem::update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt) { - //std::cout << "Rendering delta: " << dt << std::endl; -} diff --git a/src/entities/RenderSystem.h b/src/entities/RenderSystem.h deleted file mode 100644 index a7325e6..0000000 --- a/src/entities/RenderSystem.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef RENDERSYSTEM_H -#define RENDERSYSTEM_H - -#include - -class RenderSystem : public entityx::System { -public: - void update(entityx::EntityManager &entities, entityx::EventManager &events, entityx::TimeDelta dt) override; -}; - -#endif //RENDERSYSTEM_H diff --git a/src/entities/components/Position.h b/src/entities/components/Position.h deleted file mode 100644 index 3a23154..0000000 --- a/src/entities/components/Position.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef POSITION_H -#define POSITION_H - -struct Position { - Position(float x = 0.0f, float y = 0.0f) : x(x), y(y) {} - - float x, y; -}; - -#endif //POSITION_H diff --git a/src/entities/components/Texture.h b/src/entities/components/Texture.h deleted file mode 100644 index f5f19b8..0000000 --- a/src/entities/components/Texture.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TEXTURE_H -#define TEXTURE_H - -#include - -struct Texture { - Texture(SDL_Texture *gTexture) : texture(gTexture) {} - SDL_Texture *texture; -}; - -#endif //TEXTURE_H diff --git a/src/input/InputHandler.cpp b/src/input/InputHandler.cpp deleted file mode 100644 index 175da30..0000000 --- a/src/input/InputHandler.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include - -#include "InputHandler.h" - -InputHandler::InputHandler() { - Command* com = new TestCommand(); - buttonW = com; - buttonA = com; - buttonS = com; - buttonD = com; -} - -Command* InputHandler::handleInput() { - if(cur == commandStream.size()) { - return NULL; - } - return commandStream[cur++]; -} - -void InputHandler::inputEvent(SDL_Event *e) { - switch(e->key.keysym.sym) { - case SDLK_w: - commandStream.push_back(buttonW); - break; - - case SDLK_a: - commandStream.push_back(buttonA); - break; - - case SDLK_s: - commandStream.push_back(buttonS); - break; - - case SDLK_d: - commandStream.push_back(buttonD); - break; - default: - break; - } - -} - -InputHandler::~InputHandler() { - delete buttonW; - /*delete buttonA; - delete buttonS; - delete buttonD;*/ -} diff --git a/src/input/InputHandler.h b/src/input/InputHandler.h deleted file mode 100644 index 74fa497..0000000 --- a/src/input/InputHandler.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef INPUTHANDLER_H -#define INPUTHANDLER_H - -#include -#include -#include "commands/TestCommand.h" - - -class InputHandler { -private: - Command* buttonW = NULL; - Command* buttonA = NULL; - Command* buttonS = NULL; - Command* buttonD = NULL; - - unsigned int cur = 0; - std::vector commandStream; - -public: - InputHandler(); - ~InputHandler(); - //Called when an KeyDown or KeyUP event happened - void inputEvent(SDL_Event *e); - //Called by the main GameLoop to get the newest Command - Command* handleInput(); -}; - -#endif // INPUTHANDLER_H diff --git a/src/input/commands/Command.h b/src/input/commands/Command.h deleted file mode 100644 index c32385a..0000000 --- a/src/input/commands/Command.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef COMMAND_H -#define COMMAND_H - -class Command { -public: - virtual ~Command() {} - virtual void execute() = 0; - -}; - -#endif // COMMAND_H diff --git a/src/input/commands/TestCommand.cpp b/src/input/commands/TestCommand.cpp deleted file mode 100644 index ff5ec2c..0000000 --- a/src/input/commands/TestCommand.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include "TestCommand.h" - -void TestCommand::execute() { - std::cout << "Test Command launched!" << std::endl; -} diff --git a/src/input/commands/TestCommand.h b/src/input/commands/TestCommand.h deleted file mode 100644 index 8b680fe..0000000 --- a/src/input/commands/TestCommand.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TESTCOMMAND_H -#define TESTCOMMAND_H - -#include "Command.h" - -class TestCommand : public Command { -public: - void execute() override; -}; - -#endif //TESTCOMMAND_H diff --git a/src/input/commands/moveCommands/DownCommand.cpp b/src/input/commands/moveCommands/DownCommand.cpp deleted file mode 100644 index 95340a1..0000000 --- a/src/input/commands/moveCommands/DownCommand.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "DownCommand.h" - -void DownCommand::execute() { - -} diff --git a/src/input/commands/moveCommands/DownCommand.h b/src/input/commands/moveCommands/DownCommand.h deleted file mode 100644 index fa832d2..0000000 --- a/src/input/commands/moveCommands/DownCommand.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef DOWNCOMMAND_H -#define DOWNCOMMAND_H - -#include "../Command.h" - -class DownCommand : public Command { -public: - DownCommand(); - void execute() override; -}; - -#endif //DOWNCOMMAND_H diff --git a/src/input/commands/moveCommands/LeftCommand.h b/src/input/commands/moveCommands/LeftCommand.h deleted file mode 100644 index 9cfd822..0000000 --- a/src/input/commands/moveCommands/LeftCommand.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef LEFTCOMMAND_H -#define LEFTCOMMAND_H - -#include "../Command.h" - -#endif //LEFTCOMMAND_H diff --git a/src/input/commands/moveCommands/RightCommand.h b/src/input/commands/moveCommands/RightCommand.h deleted file mode 100644 index 5835d94..0000000 --- a/src/input/commands/moveCommands/RightCommand.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef RIGHTCOMMAND_H -#define RIGHTCOMMAND_H - -#include "../Command.h" - -#endif //RIGHTCOMMAND_H diff --git a/src/input/commands/moveCommands/UpCommand.h b/src/input/commands/moveCommands/UpCommand.h deleted file mode 100644 index 5835d94..0000000 --- a/src/input/commands/moveCommands/UpCommand.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef RIGHTCOMMAND_H -#define RIGHTCOMMAND_H - -#include "../Command.h" - -#endif //RIGHTCOMMAND_H diff --git a/src/utility/Utility.h b/src/utility/Utility.h deleted file mode 100644 index fcf7a96..0000000 --- a/src/utility/Utility.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UTILITY_H -#define UTILITY_H - -#include -#include -#include - -namespace utility { - SDL_Texture* loadTexture( std::string path, SDL_Renderer* gRenderer ); -} - -#endif // UTILITY_H diff --git a/src/utility/Utitlity.cpp b/src/utility/Utitlity.cpp deleted file mode 100644 index d8adb5b..0000000 --- a/src/utility/Utitlity.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "utility.h" - -namespace utility { - - SDL_Texture* loadTexture( std::string path, SDL_Renderer* gRenderer ) { - //The final texture - SDL_Texture* newTexture = NULL; - - //Load image at specified path - SDL_Surface* loadedSurface = IMG_Load( path.c_str() ); - if( loadedSurface == NULL ) { - printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() ); - } - else { - //Create texture from surface pixels - newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface ); - if( newTexture == NULL ) { - printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() ); - } - //Get rid of old loaded surface - SDL_FreeSurface( loadedSurface ); - } - return newTexture; - } - -} diff --git a/src/utility/utility.h b/src/utility/utility.h deleted file mode 100644 index fcf7a96..0000000 --- a/src/utility/utility.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UTILITY_H -#define UTILITY_H - -#include -#include -#include - -namespace utility { - SDL_Texture* loadTexture( std::string path, SDL_Renderer* gRenderer ); -} - -#endif // UTILITY_H diff --git a/src/utility/utitlity.cpp b/src/utility/utitlity.cpp deleted file mode 100644 index d8adb5b..0000000 --- a/src/utility/utitlity.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "utility.h" - -namespace utility { - - SDL_Texture* loadTexture( std::string path, SDL_Renderer* gRenderer ) { - //The final texture - SDL_Texture* newTexture = NULL; - - //Load image at specified path - SDL_Surface* loadedSurface = IMG_Load( path.c_str() ); - if( loadedSurface == NULL ) { - printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() ); - } - else { - //Create texture from surface pixels - newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface ); - if( newTexture == NULL ) { - printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() ); - } - //Get rid of old loaded surface - SDL_FreeSurface( loadedSurface ); - } - return newTexture; - } - -}