Riyyi
4 years ago
commit
57c16ef187
46 changed files with 7496 additions and 0 deletions
@ -0,0 +1,12 @@
|
||||
[submodule "deps/freetype"] |
||||
path = deps/freetype |
||||
url = https://github.com/aseprite/freetype2 |
||||
[submodule "deps/glfw"] |
||||
path = deps/glfw |
||||
url = https://github.com/glfw/glfw |
||||
[submodule "deps/glm"] |
||||
path = deps/glm |
||||
url = https://github.com/g-truc/glm |
||||
[submodule "deps/stb"] |
||||
path = deps/stb |
||||
url = https://github.com/nothings/stb |
@ -0,0 +1,63 @@
|
||||
# User config between these lines |
||||
# ------------------------------------------ |
||||
|
||||
# Set project name |
||||
set(NAME "final") |
||||
|
||||
# ------------------------------------------ |
||||
|
||||
cmake_minimum_required(VERSION 3.1) |
||||
|
||||
# Check if the build should include debugging symbols |
||||
option(DEBUG "" ON) |
||||
if(NOT DEBUG) |
||||
# cmake -DDEBUG=off .. && make |
||||
message("--- Release ---") |
||||
set(CMAKE_BUILD_TYPE "Release") |
||||
|
||||
# -O3 = Optimizations that increase compilation time and performance |
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") |
||||
else() |
||||
# cmake -DDEBUG=on .. && make |
||||
message("--- Debug ---") |
||||
set(CMAKE_BUILD_TYPE "Debug") |
||||
|
||||
# -Og = Optimizations that do not interfere with debugging |
||||
# -Wall = All warnings about contructions that are easily avoidable |
||||
# -Wextra = Extra warning flags not covered by -Wall |
||||
# -pg = Generate profile information for analysis with gprof |
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -Wall -Wextra -pg") |
||||
# gprof final gmon.out > profile-data.txt |
||||
endif() |
||||
|
||||
project(${NAME}) |
||||
set(CMAKE_CXX_STANDARD 14) |
||||
|
||||
# Include all headers |
||||
include_directories( |
||||
"deps/glfw/include" |
||||
"deps/glad/include" |
||||
"deps/glm" |
||||
"deps/stb" |
||||
"deps/freetype/include" |
||||
"include" |
||||
) |
||||
|
||||
# Add source files |
||||
file(GLOB_RECURSE GLAD "deps/glad/*.c") |
||||
file(GLOB_RECURSE SOURCE "src/*.cpp") |
||||
set(SOURCES ${GLAD} ${SOURCE}) |
||||
|
||||
# GLFW |
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) |
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) |
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) |
||||
|
||||
# Add GLFW target to project |
||||
add_subdirectory(deps/glfw) |
||||
|
||||
# Add FreeType target to project |
||||
add_subdirectory(deps/freetype) |
||||
|
||||
add_executable(${NAME} ${SOURCES}) |
||||
target_link_libraries(${NAME} glfw freetype) |
@ -0,0 +1,50 @@
|
||||
#+TITLE: OpenGL Test |
||||
#+AUTHOR: Riyyi |
||||
#+LANGUAGE: en |
||||
#+OPTIONS: toc:nil |
||||
|
||||
OpenGL Test. |
||||
|
||||
* Download |
||||
|
||||
** Clone |
||||
|
||||
#+BEGIN_SRC shell-script |
||||
$ git clone "https://<git>.com/riyyi/opengl-test" |
||||
$ cd opengl-test |
||||
$ git submodule init |
||||
$ git submodule update |
||||
#+END_SRC |
||||
|
||||
** Update |
||||
|
||||
#+BEGIN_SRC shell-script |
||||
$ git pull |
||||
$ git submodule update --recursive |
||||
#+END_SRC |
||||
|
||||
* Build instructions |
||||
|
||||
#+BEGIN_SRC shell-script |
||||
$ mkdir build |
||||
$ cd build |
||||
$ cmake .. && make |
||||
#+END_SRC |
||||
|
||||
* Controls |
||||
|
||||
| Button | Action | |
||||
|------------+----------------| |
||||
| WASD | Move around | |
||||
| Space | Move upwards | |
||||
| Left Shift | Move downwards | |
||||
| Mouse | Look around | |
||||
| Escape | Quit | |
||||
|
||||
* Libraries |
||||
|
||||
- [[https://github.com/aseprite/freetype2][FreeType2]] |
||||
- [[https://github.com/Dav1dde/glad][glad]] |
||||
- [[https://github.com/glfw/glfw][GLFW]] |
||||
- [[https://github.com/g-truc/glm][GLM]] |
||||
- [[https://github.com/nothings/stb][stb]] |
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,9 @@
|
||||
#version 130 |
||||
out vec4 FragColor; |
||||
|
||||
in vec3 color; |
||||
|
||||
void main() |
||||
{ |
||||
FragColor = vec4(color, 1.0f); |
||||
} |
@ -0,0 +1,16 @@
|
||||
#version 130 |
||||
in vec3 aPos; |
||||
in vec3 aColor; |
||||
|
||||
out vec3 color; |
||||
|
||||
uniform mat4 model; |
||||
uniform mat4 view; |
||||
uniform mat4 projection; |
||||
|
||||
void main() |
||||
{ |
||||
// Vclip = Mprojection ⋅ Mview ⋅ Mmodel ⋅ Vlocal |
||||
gl_Position = projection * view * model * vec4(aPos, 1.0); |
||||
color = aColor; |
||||
} |
@ -0,0 +1,14 @@
|
||||
#version 130 |
||||
in vec2 textCoord; |
||||
|
||||
out vec4 fragColor; |
||||
|
||||
uniform vec3 color; |
||||
uniform sampler2D texture1; |
||||
|
||||
void main() |
||||
{ |
||||
// Sample sets the alpha channel to either 0 / 1 |
||||
vec4 sampled = vec4(1.0f, 1.0f, 1.0f, texture(texture1, textCoord).r); |
||||
fragColor = vec4(color, 1.0f) * sampled; |
||||
} |
@ -0,0 +1,12 @@
|
||||
#version 130 |
||||
in vec4 postex; // <vec2 position, vec2 texture> |
||||
|
||||
out vec2 textCoord; |
||||
|
||||
uniform mat4 projection; |
||||
|
||||
void main() |
||||
{ |
||||
gl_Position = projection * vec4(postex.xy, 0.0f, 1.0f); |
||||
textCoord = postex.zw; |
||||
} |
@ -0,0 +1,13 @@
|
||||
#version 130 |
||||
in vec2 textCoord; |
||||
|
||||
out vec4 FragColor; |
||||
|
||||
uniform vec4 color; |
||||
uniform sampler2D texture1; |
||||
|
||||
void main() |
||||
{ |
||||
// FragColor = color; |
||||
FragColor = texture(texture1, textCoord) * color; |
||||
} |
@ -0,0 +1,16 @@
|
||||
#version 130 |
||||
in vec3 aPos; |
||||
in vec2 aTextCoord; |
||||
|
||||
out vec2 textCoord; |
||||
|
||||
uniform mat4 model; |
||||
uniform mat4 view; |
||||
uniform mat4 projection; |
||||
|
||||
void main() |
||||
{ |
||||
// Vclip = Mprojection ⋅ Mview ⋅ Mmodel ⋅ Vlocal |
||||
gl_Position = projection * view * model * vec4(aPos, 1.0); |
||||
textCoord = aTextCoord; |
||||
} |
@ -0,0 +1,282 @@
|
||||
#ifndef __khrplatform_h_ |
||||
#define __khrplatform_h_ |
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc. |
||||
** |
||||
** Permission is hereby granted, free of charge, to any person obtaining a |
||||
** copy of this software and/or associated documentation files (the |
||||
** "Materials"), to deal in the Materials without restriction, including |
||||
** without limitation the rights to use, copy, modify, merge, publish, |
||||
** distribute, sublicense, and/or sell copies of the Materials, and to |
||||
** permit persons to whom the Materials are furnished to do so, subject to |
||||
** the following conditions: |
||||
** |
||||
** The above copyright notice and this permission notice shall be included |
||||
** in all copies or substantial portions of the Materials. |
||||
** |
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. |
||||
*/ |
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
* |
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL |
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID: |
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692 |
||||
* |
||||
* Adopters may modify this file to suit their platform. Adopters are |
||||
* encouraged to submit platform specific modifications to the Khronos |
||||
* group so that they can be included in future versions of this file. |
||||
* Please submit changes by filing pull requests or issues on |
||||
* the EGL Registry repository linked above. |
||||
* |
||||
* |
||||
* See the Implementer's Guidelines for information about where this file |
||||
* should be located on your system and for more details of its use: |
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
* |
||||
* This file should be included as |
||||
* #include <KHR/khrplatform.h> |
||||
* by Khronos client API header files that use its types and defines. |
||||
* |
||||
* The types in khrplatform.h should only be used to define API-specific types. |
||||
* |
||||
* Types defined in khrplatform.h: |
||||
* khronos_int8_t signed 8 bit |
||||
* khronos_uint8_t unsigned 8 bit |
||||
* khronos_int16_t signed 16 bit |
||||
* khronos_uint16_t unsigned 16 bit |
||||
* khronos_int32_t signed 32 bit |
||||
* khronos_uint32_t unsigned 32 bit |
||||
* khronos_int64_t signed 64 bit |
||||
* khronos_uint64_t unsigned 64 bit |
||||
* khronos_intptr_t signed same number of bits as a pointer |
||||
* khronos_uintptr_t unsigned same number of bits as a pointer |
||||
* khronos_ssize_t signed size |
||||
* khronos_usize_t unsigned size |
||||
* khronos_float_t signed 32 bit floating point |
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds |
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in |
||||
* nanoseconds |
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds |
||||
* khronos_boolean_enum_t enumerated boolean type. This should |
||||
* only be used as a base type when a client API's boolean type is |
||||
* an enum. Client APIs which use an integer or other type for |
||||
* booleans cannot use this as the base type for their boolean. |
||||
* |
||||
* Tokens defined in khrplatform.h: |
||||
* |
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. |
||||
* |
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. |
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. |
||||
* |
||||
* Calling convention macros defined in this file: |
||||
* KHRONOS_APICALL |
||||
* KHRONOS_APIENTRY |
||||
* KHRONOS_APIATTRIBUTES |
||||
* |
||||
* These may be used in function prototypes as: |
||||
* |
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname( |
||||
* int arg1, |
||||
* int arg2) KHRONOS_APIATTRIBUTES; |
||||
*/ |
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL |
||||
*------------------------------------------------------------------------- |
||||
* This precedes the return type of the function in the function prototype. |
||||
*/ |
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__) |
||||
# define KHRONOS_APICALL __declspec(dllimport) |
||||
#elif defined (__SYMBIAN32__) |
||||
# define KHRONOS_APICALL IMPORT_C |
||||
#elif defined(__ANDROID__) |
||||
# define KHRONOS_APICALL __attribute__((visibility("default"))) |
||||
#else |
||||
# define KHRONOS_APICALL |
||||
#endif |
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY |
||||
*------------------------------------------------------------------------- |
||||
* This follows the return type of the function and precedes the function |
||||
* name in the function prototype. |
||||
*/ |
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) |
||||
/* Win32 but not WinCE */ |
||||
# define KHRONOS_APIENTRY __stdcall |
||||
#else |
||||
# define KHRONOS_APIENTRY |
||||
#endif |
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES |
||||
*------------------------------------------------------------------------- |
||||
* This follows the closing parenthesis of the function prototype arguments. |
||||
*/ |
||||
#if defined (__ARMCC_2__) |
||||
#define KHRONOS_APIATTRIBUTES __softfp |
||||
#else |
||||
#define KHRONOS_APIATTRIBUTES |
||||
#endif |
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions |
||||
*-----------------------------------------------------------------------*/ |
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) |
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h> |
||||
*/ |
||||
#include <stdint.h> |
||||
typedef int32_t khronos_int32_t; |
||||
typedef uint32_t khronos_uint32_t; |
||||
typedef int64_t khronos_int64_t; |
||||
typedef uint64_t khronos_uint64_t; |
||||
#define KHRONOS_SUPPORT_INT64 1 |
||||
#define KHRONOS_SUPPORT_FLOAT 1 |
||||
|
||||
#elif defined(__VMS ) || defined(__sgi) |
||||
|
||||
/*
|
||||
* Using <inttypes.h> |
||||
*/ |
||||
#include <inttypes.h> |
||||
typedef int32_t khronos_int32_t; |
||||
typedef uint32_t khronos_uint32_t; |
||||
typedef int64_t khronos_int64_t; |
||||
typedef uint64_t khronos_uint64_t; |
||||
#define KHRONOS_SUPPORT_INT64 1 |
||||
#define KHRONOS_SUPPORT_FLOAT 1 |
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) |
||||
|
||||
/*
|
||||
* Win32 |
||||
*/ |
||||
typedef __int32 khronos_int32_t; |
||||
typedef unsigned __int32 khronos_uint32_t; |
||||
typedef __int64 khronos_int64_t; |
||||
typedef unsigned __int64 khronos_uint64_t; |
||||
#define KHRONOS_SUPPORT_INT64 1 |
||||
#define KHRONOS_SUPPORT_FLOAT 1 |
||||
|
||||
#elif defined(__sun__) || defined(__digital__) |
||||
|
||||
/*
|
||||
* Sun or Digital |
||||
*/ |
||||
typedef int khronos_int32_t; |
||||
typedef unsigned int khronos_uint32_t; |
||||
#if defined(__arch64__) || defined(_LP64) |
||||
typedef long int khronos_int64_t; |
||||
typedef unsigned long int khronos_uint64_t; |
||||
#else |
||||
typedef long long int khronos_int64_t; |
||||
typedef unsigned long long int khronos_uint64_t; |
||||
#endif /* __arch64__ */ |
||||
#define KHRONOS_SUPPORT_INT64 1 |
||||
#define KHRONOS_SUPPORT_FLOAT 1 |
||||
|
||||
#elif 0 |
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support |
||||
*/ |
||||
typedef int khronos_int32_t; |
||||
typedef unsigned int khronos_uint32_t; |
||||
#define KHRONOS_SUPPORT_INT64 0 |
||||
#define KHRONOS_SUPPORT_FLOAT 0 |
||||
|
||||
#else |
||||
|
||||
/*
|
||||
* Generic fallback |
||||
*/ |
||||
#include <stdint.h> |
||||
typedef int32_t khronos_int32_t; |
||||
typedef uint32_t khronos_uint32_t; |
||||
typedef int64_t khronos_int64_t; |
||||
typedef uint64_t khronos_uint64_t; |
||||
#define KHRONOS_SUPPORT_INT64 1 |
||||
#define KHRONOS_SUPPORT_FLOAT 1 |
||||
|
||||
#endif |
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms |
||||
*/ |
||||
typedef signed char khronos_int8_t; |
||||
typedef unsigned char khronos_uint8_t; |
||||
typedef signed short int khronos_int16_t; |
||||
typedef unsigned short int khronos_uint16_t; |
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64, |
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears |
||||
* to be the only LLP64 architecture in current use. |
||||
*/ |
||||
#ifdef _WIN64 |
||||
typedef signed long long int khronos_intptr_t; |
||||
typedef unsigned long long int khronos_uintptr_t; |
||||
typedef signed long long int khronos_ssize_t; |
||||
typedef unsigned long long int khronos_usize_t; |
||||
#else |
||||
typedef signed long int khronos_intptr_t; |
||||
typedef unsigned long int khronos_uintptr_t; |
||||
typedef signed long int khronos_ssize_t; |
||||
typedef unsigned long int khronos_usize_t; |
||||
#endif |
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT |
||||
/*
|
||||
* Float type |
||||
*/ |
||||
typedef float khronos_float_t; |
||||
#endif |
||||
|
||||
#if KHRONOS_SUPPORT_INT64 |
||||
/* Time types
|
||||
* |
||||
* These types can be used to represent a time interval in nanoseconds or |
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number |
||||
* of nanoseconds since some arbitrary system event (e.g. since the last |
||||
* time the system booted). The Unadjusted System Time is an unsigned |
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals |
||||
* may be either signed or unsigned. |
||||
*/ |
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t; |
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t; |
||||
#endif |
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits. |
||||
*/ |
||||
#ifndef KHRONOS_MAX_ENUM |
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF |
||||
#endif |
||||
|
||||
/*
|
||||
* Enumerated boolean type |
||||
* |
||||
* Values other than zero should be considered to be true. Therefore |
||||
* comparisons should not be made against KHRONOS_TRUE. |
||||
*/ |
||||
typedef enum { |
||||
KHRONOS_FALSE = 0, |
||||
KHRONOS_TRUE = 1, |
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM |
||||
} khronos_boolean_enum_t; |
||||
|
||||
#endif /* __khrplatform_h_ */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef CAMERA_H |
||||
#define CAMERA_H |
||||
|
||||
#define SPEED 2.5f |
||||
#define SENSITIVITY 0.25f |
||||
#define NEAR_PlANE 0.1f |
||||
#define FAR_PlANE 100.0f |
||||
|
||||
#include "object.h" |
||||
|
||||
class Camera : public Object { |
||||
public: |
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
float fov(); |
||||
void setFov(float fov); |
||||
glm::mat4 projection(); |
||||
|
||||
private: |
||||
float m_fov; |
||||
float m_pitch; |
||||
float m_yaw; |
||||
glm::vec3 m_up; |
||||
glm::mat4 m_projection; |
||||
}; |
||||
|
||||
#endif // CAMERA_H
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef CUBE_H |
||||
#define CUBE_H |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include "object.h" |
||||
|
||||
class Shader; |
||||
|
||||
class Cube : public Object { |
||||
public: |
||||
Cube(); |
||||
Cube(float r, float g, float b); |
||||
~Cube(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void setColor(float r, float g, float b); |
||||
|
||||
private: |
||||
unsigned int m_vao; |
||||
unsigned int m_vbo; |
||||
unsigned int m_vSize; |
||||
unsigned int m_texture; |
||||
glm::vec3 m_color; |
||||
Shader *m_shader; |
||||
}; |
||||
|
||||
#endif // CUBE_H
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef CUBE_COLOR_H |
||||
#define CUBE_COLOR_H |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include "object.h" |
||||
|
||||
class Shader; |
||||
|
||||
class CubeColor : public Object { |
||||
public: |
||||
CubeColor(); |
||||
CubeColor(float r, float g, float b, bool lineMode = false); |
||||
~CubeColor(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void setLineMode(bool lineMode); |
||||
void setColor(float r, float g, float b); |
||||
|
||||
private: |
||||
bool m_lineMode; |
||||
unsigned int m_vao; |
||||
unsigned int m_vbo; |
||||
unsigned int m_vSize; |
||||
glm::vec3 m_color; |
||||
Shader *m_shader; |
||||
}; |
||||
|
||||
#endif // CUBE_COLOR_H
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef ENTITY_H |
||||
#define ENTITY_H |
||||
|
||||
class Entity { |
||||
public: |
||||
Entity(); |
||||
virtual ~Entity(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
virtual void initialize() = 0; |
||||
virtual void update() = 0; |
||||
virtual void render() = 0; |
||||
virtual void destroy() = 0; |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
bool active() const; |
||||
void setActive(bool active); |
||||
|
||||
private: |
||||
bool m_active; |
||||
}; |
||||
|
||||
#endif // ENTITY_H
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef FONT_H |
||||
#define FONT_H |
||||
|
||||
#include <map> // map |
||||
#include <string> // string |
||||
#include <unordered_map> // unordered_map |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include <glm/glm.hpp> |
||||
|
||||
struct Character { |
||||
unsigned int texture; // ID
|
||||
glm::ivec2 size; // Width / height
|
||||
glm::ivec2 bearing; // Offset from baseline to left/top of glyph
|
||||
unsigned int advance; // Offset to advance to next glyph
|
||||
}; |
||||
|
||||
class FontManager { |
||||
public: |
||||
FT_Face loadFont(const std::string &path); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
Character character(const char character) const; |
||||
const std::map<const char, Character> &characterList() const; |
||||
|
||||
private: |
||||
std::unordered_map<std::string, FT_Face> m_fontList; |
||||
|
||||
std::map<const char, Character> m_characterList; |
||||
}; |
||||
|
||||
extern FontManager *g_fontManager; |
||||
|
||||
#endif // FONT_H
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef GAMESTATE_H |
||||
#define GAMESTATE_H |
||||
|
||||
#include <chrono> // time |
||||
#include <thread> // sleep_for |
||||
|
||||
#include "entity.h" |
||||
#include "window.h" |
||||
|
||||
class GameState : public Entity { |
||||
public: |
||||
static void sleep(int amount) { |
||||
// Sleep for amount ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(amount)); |
||||
} |
||||
}; |
||||
|
||||
class GameStateManager { |
||||
public: |
||||
GameStateManager() : m_state(nullptr) { |
||||
} |
||||
|
||||
~GameStateManager() { |
||||
if(m_state != nullptr) { |
||||
m_state->destroy(); |
||||
delete m_state; |
||||
} |
||||
} |
||||
|
||||
void setState(GameState* state) { |
||||
if(m_state != nullptr) { |
||||
m_state->destroy(); |
||||
delete m_state; |
||||
} |
||||
|
||||
m_state = state; |
||||
if(m_state != nullptr) { |
||||
m_state->initialize(); |
||||
} |
||||
} |
||||
|
||||
void update() { |
||||
if(m_state != nullptr) { |
||||
m_state->update(); |
||||
} |
||||
} |
||||
|
||||
void render() { |
||||
if(m_state != nullptr) { |
||||
m_state->render(); |
||||
} |
||||
} |
||||
|
||||
private: |
||||
GameState *m_state; |
||||
}; |
||||
|
||||
extern GameStateManager *g_gameStateManager; |
||||
|
||||
#endif // GAMESTATE_H
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef INPUT_H |
||||
#define INPUT_H |
||||
|
||||
#include <GLFW/glfw3.h> |
||||
|
||||
#include "entity.h" |
||||
|
||||
class InputManager : public Entity { |
||||
public: |
||||
InputManager(); |
||||
~InputManager(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
enum keyStates { |
||||
UP = 0, |
||||
PRESSED, |
||||
DOWN, |
||||
RELEASED, |
||||
}; |
||||
|
||||
char keyState(int key); |
||||
void setKeyState(int key, int scancode, int action, int mode); |
||||
float xOffset(); |
||||
float yOffset(); |
||||
void setMouse(double xpos, double ypos); |
||||
|
||||
private: |
||||
char m_previousKeyStates[GLFW_KEY_LAST]; |
||||
char m_currentKeyStates[GLFW_KEY_LAST]; |
||||
bool m_firstMouse; |
||||
float m_xLast; |
||||
float m_yLast; |
||||
float m_xOffset; |
||||
float m_yOffset; |
||||
}; |
||||
|
||||
extern InputManager *g_inputManager; |
||||
|
||||
#endif // INPUT_H
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef OBJECT_H |
||||
#define OBJECT_H |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include "entity.h" |
||||
|
||||
class Object : public Entity { |
||||
public: |
||||
Object(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
virtual void initialize(); |
||||
virtual void update(); |
||||
virtual void render(); |
||||
virtual void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
glm::vec3 position() const; |
||||
void setPosition(glm::vec3 position); |
||||
void setPosition(float x, float y, float z); |
||||
glm::vec3 rotation() const; |
||||
void setRotation(glm::vec3 rotation); |
||||
void setRotation(float x, float y, float z); |
||||
glm::vec3 scale() const; |
||||
void setScale(glm::vec3 scale); |
||||
void setScale(float x, float y, float z); |
||||
glm::mat4 model() const; |
||||
void setModel(glm::mat4 transform); |
||||
|
||||
private: |
||||
glm::vec3 m_position; |
||||
glm::vec3 m_rotation; |
||||
glm::vec3 m_scale; |
||||
glm::mat4 m_model; |
||||
}; |
||||
|
||||
#endif // OBJECT_H
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef SHADER_H |
||||
#define SHADER_H |
||||
|
||||
#define INFO_LOG_SIZE 512 |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include <string> |
||||
|
||||
class Shader { |
||||
public: |
||||
Shader(const std::string &vertexSource, const std::string &fragmentSource); |
||||
~Shader(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// Setup shader program
|
||||
std::string readFile(const std::string &path) const; |
||||
unsigned int compileShader(unsigned int type, const char *shaderSource) const; |
||||
unsigned int linkShader(unsigned int vertex, unsigned int fragment) const; |
||||
int checkStatus(unsigned int check, bool isProgram = false) const; |
||||
|
||||
// Use shader program
|
||||
void use() const; |
||||
void setFloat(const std::string &name, float f1, float f2, float f3, float f4) const; |
||||
void setFloat(const std::string &name, glm::vec3 v) const; |
||||
void setFloat(const std::string &name, glm::vec4 v) const; |
||||
void setFloat(const std::string &name, glm::mat4 m) const; |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
unsigned int program() const; |
||||
|
||||
private: |
||||
unsigned int m_program; |
||||
}; |
||||
|
||||
#endif // SHADER_H
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef MAINGAME_H |
||||
#define MAINGAME_H |
||||
|
||||
#define CUBE 6 |
||||
#define CUBE_SIZE 15 |
||||
|
||||
#include <array> |
||||
|
||||
#include "gamestate.h" |
||||
|
||||
class Object; |
||||
class Text; |
||||
|
||||
class MainGame : public GameState |
||||
{ |
||||
public: |
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
private: |
||||
std::array<Object *, CUBE_SIZE> m_object; |
||||
Text *m_text; |
||||
}; |
||||
|
||||
#endif // MAINGAME_H
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef TEXT_H |
||||
#define TEXT_H |
||||
|
||||
#include <iostream> |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include "object.h" |
||||
|
||||
class Shader; |
||||
|
||||
class Text : public Object { |
||||
public: |
||||
Text(); |
||||
~Text(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void setText(std::string text); |
||||
|
||||
private: |
||||
unsigned int m_vao; |
||||
unsigned int m_vbo; |
||||
glm::vec3 m_color; |
||||
Shader *m_shader; |
||||
std::string m_text; |
||||
}; |
||||
|
||||
#endif // TEXT_H
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef TEXTURE_H |
||||
#define TEXTURE_H |
||||
|
||||
#include <string> |
||||
#include <unordered_map> |
||||
|
||||
class TextureManager { |
||||
public: |
||||
unsigned int loadTexture(const std::string &path); |
||||
void deleteTexture(const unsigned int texture); |
||||
|
||||
unsigned int createTexture( |
||||
int format, unsigned int width, unsigned int height, const void *image, |
||||
int wrap, int filterMin, int filterMag, bool genMipmap = false); |
||||
|
||||
private: |
||||
std::unordered_map<std::string, unsigned int> m_textureList; |
||||
}; |
||||
|
||||
extern TextureManager *g_textureManager; |
||||
|
||||
#endif // TEXTURE_H
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
*/ |
||||
|
||||
#ifndef WINDOW_H |
||||
#define WINDOW_H |
||||
|
||||
#include "entity.h" |
||||
|
||||
class Camera; |
||||
class GLFWwindow; |
||||
class Shader; |
||||
|
||||
class Window : public Entity { |
||||
public: |
||||
// Window();
|
||||
Window(int width, int height); |
||||
~Window(); |
||||
|
||||
bool shouldClose(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void initialize(); |
||||
void update(); |
||||
void render(); |
||||
void destroy(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
int width(); |
||||
int height(); |
||||
float aspect(); |
||||
float currentTime(); |
||||
float deltaTime(); |
||||
|
||||
GLFWwindow *window(); |
||||
Shader *shader(); |
||||
Shader *shaderColor(); |
||||
Shader *shaderFont(); |
||||
Camera *camera(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
static void errorCallback(int error, const char *description); |
||||
static void keyCallback(GLFWwindow *window, int key, int scancode, |
||||
int action, int mode); |
||||
static void mouseCallback(GLFWwindow* window, double xpos, double ypos); |
||||
|
||||
private: |
||||
int m_width; |
||||
int m_height; |
||||
float m_aspect; |
||||
float m_currentTime; |
||||
float m_lastFrameTime; |
||||
float m_deltaTime; |
||||
|
||||
GLFWwindow *m_window; |
||||
Shader *m_shader; |
||||
Shader *m_shaderColor; |
||||
Shader *m_shaderFont; |
||||
Camera *m_camera; |
||||
}; |
||||
|
||||
extern Window *g_window; |
||||
|
||||
#endif // WINDOW_H
|
@ -0,0 +1,111 @@
|
||||
#include <glm/gtx/transform.hpp> // glm::lookAt, glm::perspective |
||||
#include <glm/ext/matrix_clip_space.hpp> // glm::perspective |
||||
|
||||
#include "camera.h" |
||||
#include "input.h" |
||||
#include "window.h" |
||||
|
||||
void Camera::initialize() |
||||
{ |
||||
setPosition(glm::vec3(0.0f, 0.0f, 3.0f)); |
||||
setRotation(glm::vec3(0.0f, 0.0f, -1.0f)); |
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f)); |
||||
setFov(90.0f); |
||||
m_pitch = 0.0f; |
||||
m_yaw = 0.0f; |
||||
// Up vector in world space
|
||||
m_up = glm::vec3(0.0f, 1.0f, 0.0f); |
||||
} |
||||
|
||||
void Camera::update() |
||||
{ |
||||
// Get mouse movement offset compared to last frame
|
||||
float xoffset = g_inputManager->xOffset() * SENSITIVITY; |
||||
float yoffset = g_inputManager->yOffset() * SENSITIVITY; |
||||
m_yaw += xoffset; |
||||
m_pitch += yoffset; |
||||
// Prevent gimbal lock
|
||||
if(m_pitch > 89.0f) m_pitch = 89.0f; |
||||
if(m_pitch < -89.0f) m_pitch = -89.0f; |
||||
|
||||
// Update camera rotation, by calculating direction vector via yaw and pitch
|
||||
setRotation( |
||||
cos(glm::radians(m_pitch)) * cos(glm::radians(m_yaw)), |
||||
sin(glm::radians(m_pitch)), |
||||
cos(glm::radians(m_pitch)) * sin(glm::radians(m_yaw))); |
||||
setRotation(glm::normalize(rotation())); |
||||
// The direction vector is based on
|
||||
// Camera direction (z): normalize(position - target)
|
||||
// Right axis (x): normalize(cross(up, direction))
|
||||
// Up axis (y): cross(direction, right)
|
||||
|
||||
// Source: https://learnopengl.com/img/getting-started/camera_axes.png
|
||||
|
||||
// Cross = combination of two vectors in 3D space,
|
||||
// where result is always perpendicular to both of the vectors
|
||||
|
||||
// Update camera position
|
||||
float cameraSpeed = SPEED * g_window->deltaTime(); |
||||
// WASD movement
|
||||
if (g_inputManager->keyState(GLFW_KEY_W) == InputManager::DOWN) { |
||||
setPosition(position() + cameraSpeed * rotation()); |
||||
} |
||||
if (g_inputManager->keyState(GLFW_KEY_S) == InputManager::DOWN) { |
||||
setPosition(position() - cameraSpeed * rotation()); |
||||
} |
||||
if (g_inputManager->keyState(GLFW_KEY_A) == InputManager::DOWN) { |
||||
setPosition(position() - |
||||
glm::normalize(glm::cross(rotation(), m_up)) * cameraSpeed); |
||||
} |
||||
if (g_inputManager->keyState(GLFW_KEY_D) == InputManager::DOWN) { |
||||
setPosition(position() + |
||||
glm::normalize(glm::cross(rotation(), m_up)) * cameraSpeed); |
||||
} |
||||
// Up / down movement
|
||||
if (g_inputManager->keyState(GLFW_KEY_SPACE) == InputManager::DOWN) { |
||||
setPosition(position().x, position().y + cameraSpeed, position().z); |
||||
} |
||||
if (g_inputManager->keyState(GLFW_KEY_LEFT_SHIFT) == InputManager::DOWN) { |
||||
setPosition(position().x, position().y - cameraSpeed, position().z); |
||||
} |
||||
|
||||
// Update camera matrix
|
||||
|
||||
// Local space -> World space: model matrix
|
||||
// Is done in Object::update()
|
||||
|
||||
// World space -> View space: view matrix
|
||||
setModel(glm::lookAt(position(), position() + rotation(), m_up)); |
||||
|
||||
// View space -> Clip space: projection matrix
|
||||
m_projection = glm::perspective(glm::radians(m_fov), g_window->aspect(), |
||||
NEAR_PlANE, FAR_PlANE); |
||||
|
||||
// Clip space -> Screen space: viewport transform
|
||||
// Is done in the fragment shader using the settings of glViewport
|
||||
|
||||
// Souce: https://learnopengl.com/img/getting-started/coordinate_systems.png
|
||||
} |
||||
|
||||
void Camera::render() |
||||
{ |
||||
} |
||||
|
||||
void Camera::destroy() |
||||
{ |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
float Camera::fov() { |
||||
return m_fov; |
||||
} |
||||
|
||||
void Camera::setFov(float fov) |
||||
{ |
||||
m_fov = fov; |
||||
} |
||||
|
||||
glm::mat4 Camera::projection() { |
||||
return m_projection; |
||||
} |
@ -0,0 +1,188 @@
|
||||
#include <cmath> // sin, fmod |
||||
#include <cstdio> // printf |
||||
|
||||
#include <glad/glad.h> |
||||
#include <GLFW/glfw3.h> |
||||
#include <glm/gtx/transform.hpp> // glm::translate, glm::rotate, glm::scale |
||||
|
||||
#include "camera.h" |
||||
#include "cube.h" |
||||
#include "shader.h" |
||||
#include "texture.h" |
||||
#include "window.h" |
||||
|
||||
Cube::Cube() : Object(), m_color(1.0f), m_shader(nullptr) |
||||
{ |
||||
initialize(); |
||||
} |
||||
|
||||
Cube::Cube(float r, float g, float b) : Cube() |
||||
{ |
||||
m_color = glm::vec3(r, g, b); |
||||
} |
||||
|
||||
Cube::~Cube() |
||||
{ |
||||
destroy(); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Cube::initialize() |
||||
{ |
||||
printf("Cube::initialize\n"); |
||||
|
||||
setPosition(glm::vec3(0.0f, 0.0f, 0.0f)); |
||||
setRotation(glm::vec3(0.0f, 0.0f, 0.0f)); |
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f)); |
||||
|
||||
// Vertex attribute pointer size
|
||||
int p1Size = 3; |
||||
int p2Size = 2; |
||||
// Vertex data
|
||||
float vertexData[] = { |
||||
// x y z tx ty
|
||||
-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, |
||||
}; |
||||
m_vSize = sizeof(vertexData) / sizeof(vertexData[0]) / (p1Size + p2Size); |
||||
m_shader = g_window->shader(); |
||||
|
||||
// Create objects
|
||||
glGenVertexArrays(1, &m_vao); |
||||
glGenBuffers(1, &m_vbo); |
||||
|
||||
// Bind vertex array object
|
||||
glBindVertexArray(m_vao); |
||||
|
||||
// Bind vertex buffer object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); |
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); |
||||
|
||||
int stride = (p1Size + p2Size) * sizeof(float); |
||||
//~ Set vertex shader attribute pointers
|
||||
unsigned int p1 = glGetAttribLocation(m_shader->program(), "aPos"); |
||||
glEnableVertexAttribArray(p1); |
||||
// Specify vertex data interpretation
|
||||
glVertexAttribPointer( |
||||
p1, // Index
|
||||
p1Size, // Size
|
||||
GL_FLOAT, // Data type
|
||||
GL_FALSE, // Normalize
|
||||
stride, // Stride, byte offset between vertex attributes
|
||||
(void*)0); // Pointer, byte offset
|
||||
|
||||
unsigned int p2 = glGetAttribLocation(m_shader->program(), "aTextCoord"); |
||||
glEnableVertexAttribArray(p2); |
||||
// Specify vertex data interpretation
|
||||
glVertexAttribPointer( |
||||
p2, |
||||
p2Size, |
||||
GL_FLOAT, |
||||
GL_FALSE, |
||||
stride, |
||||
(void*)(p1Size * sizeof(float))); |
||||
//~
|
||||
|
||||
// Unbind vertex array object
|
||||
glBindVertexArray(0); |
||||
|
||||
// Texture
|
||||
m_texture = g_textureManager->loadTexture("../data/gfx/awesome-face.png"); |
||||
} |
||||
|
||||
void Cube::update() |
||||
{ |
||||
float timeValue = glfwGetTime(); |
||||
float amount = std::fmod(timeValue * 50, 360); |
||||
setRotation(amount, amount, 0.0f); |
||||
|
||||
// Call parent update
|
||||
Object::update(); |
||||
} |
||||
|
||||
void Cube::render() |
||||
{ |
||||
// Render
|
||||
m_shader->use(); |
||||
m_shader->setFloat("color", glm::vec4(m_color, 1.0f)); |
||||
m_shader->setFloat("model", model()); |
||||
m_shader->setFloat("view", g_window->camera()->model()); |
||||
m_shader->setFloat("projection", g_window->camera()->projection()); |
||||
|
||||
glBindVertexArray(m_vao); |
||||
glBindTexture(GL_TEXTURE_2D, m_texture); |
||||
glDrawArrays(GL_TRIANGLES, 0, m_vSize); |
||||
glBindTexture(GL_TEXTURE_2D, 0); |
||||
glBindVertexArray(0); |
||||
} |
||||
|
||||
void Cube::destroy() |
||||
{ |
||||
// Clean resources
|
||||
glDeleteVertexArrays(1, &m_vao); |
||||
glDeleteBuffers(1, &m_vbo); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Cube::setColor(float r, float g, float b) |
||||
{ |
||||
m_color = glm::vec3(r, g, b); |
||||
} |
||||
|
||||
// @Todo
|
||||
// + Local postition flipped
|
||||
// + Shader textures
|
||||
// + World positions ?
|
||||
// + Cleanup and understand camera::update
|
||||
// + Cleanup cube more
|
||||
// ! Only set shader projection on camera fov update, remove projection getter
|
||||
|
||||
// - Object: model matrix (add translate to origin before rotation)
|
||||
// - Object: model matrix (rotations in radians here or in child (cube)?)
|
||||
// |- rotation around 2 axis ?
|
||||
// https://learnopengl.com/Getting-started/Coordinate-Systems
|
||||
// + Object setter overload, take 3 floats as well
|
||||
// - Object setter, single float position update (?)
|
||||
// - Cube init: check if glGetAttribLocation != UINT_MAX
|
||||
// - Text in window: FPS, Player position, player rotation
|
@ -0,0 +1,197 @@
|
||||
#include <cmath> // sin, fmod |
||||
#include <cstdio> // printf |
||||
|
||||
#include <glad/glad.h> |
||||
#include <GLFW/glfw3.h> |
||||
#include <glm/gtx/transform.hpp> // glm::translate, glm::rotate, glm::scale |
||||
|
||||
#include "camera.h" |
||||
#include "cubecolor.h" |
||||
#include "shader.h" |
||||
#include "window.h" |
||||
|
||||
CubeColor::CubeColor() : Object(), m_lineMode(false), m_color(1.0f), m_shader(nullptr) |
||||
{ |
||||
initialize(); |
||||
} |
||||
|
||||
CubeColor::CubeColor(float r, float g, float b, bool lineMode) |
||||
{ |
||||
setColor(r, g, b); |
||||
setLineMode(lineMode); |
||||
initialize(); |
||||
} |
||||
|
||||
CubeColor::~CubeColor() |
||||
{ |
||||
destroy(); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void CubeColor::initialize() |
||||
{ |
||||
printf("CubeColor::initialize\n"); |
||||
|
||||
setPosition(glm::vec3(0.0f, 0.0f, 0.0f)); |
||||
setRotation(glm::vec3(0.0f, 0.0f, 0.0f)); |
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f)); |
||||
|
||||
// Vertex attribute pointer size
|
||||
int p1Size = 3; |
||||
int p2Size = 3; |
||||
// Vertex data
|
||||
float vertexData[] = { |
||||
// x y z r g b
|
||||
// Front
|
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, |
||||
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, |
||||
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, |
||||
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, |
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
// Back
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, |
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, |
||||
// Right
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
||||
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, |
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, |
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
||||
// Left
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, |
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, |
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, |
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
// Bottom
|
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, |
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, |
||||
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
||||
// To
|
||||
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, |
||||
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, |
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, |
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
||||
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, |
||||
}; |
||||
m_vSize = sizeof(vertexData) / sizeof(vertexData[0]) / (p1Size + p2Size); |
||||
m_shader = g_window->shaderColor(); |
||||
|
||||
// If color besides glm::vec3(1.0f) has been set, overwrite rainbow pattern
|
||||
if (m_color != glm::vec3(1.0f)) { |
||||
// Loop through all 'rows'
|
||||
for (unsigned int i = p1Size; i < m_vSize * (p1Size + p2Size); i += p1Size + p2Size) { |
||||
vertexData[i] = m_color.r; |
||||
vertexData[i + 1] = m_color.g; |
||||
vertexData[i + 2] = m_color.b; |
||||
} |
||||
} |
||||
|
||||
// Create objects
|
||||
glGenVertexArrays(1, &m_vao); |
||||
glGenBuffers(1, &m_vbo); |
||||
|
||||
// Bind vertex array object
|
||||
glBindVertexArray(m_vao); |
||||
|
||||
// Bind vertex buffer object
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); |
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); |
||||
|
||||
int stride = (p1Size + p2Size) * sizeof(float); |
||||
//~ Set vertex shader attribute pointers
|
||||
unsigned int p1 = glGetAttribLocation(m_shader->program(), "aPos"); |
||||
glEnableVertexAttribArray(p1); |
||||
// Specify vertex data interpretation
|
||||
glVertexAttribPointer( |
||||
p1, // Index
|
||||
p1Size, // Size
|
||||
GL_FLOAT, // Data type
|
||||
GL_FALSE, // Normalize
|
||||
stride, // Stride, byte offset between vertex attributes
|
||||
(void*)0); // Pointer, byte offset
|
||||
|
||||
unsigned int p2 = glGetAttribLocation(m_shader->program(), "aColor"); |
||||
glEnableVertexAttribArray(p2); |
||||
// Specify vertex data interpretation
|
||||
glVertexAttribPointer( |
||||
p2, |
||||
p2Size, |
||||
GL_FLOAT, |
||||
GL_FALSE, |
||||
stride, |
||||
(void*)(p1Size * sizeof(float))); |
||||
//~
|
||||
|
||||
// Unbind vertex array object
|
||||
glBindVertexArray(0); |
||||
} |
||||
|
||||
void CubeColor::update() |
||||
{ |
||||
float timeValue = glfwGetTime(); |
||||
float loopValue = (std::sin(timeValue) / 2.0f) + 0.5f; |
||||
if (m_color == glm::vec3(1.0f)) { |
||||
setPosition(position().x, position().y, -loopValue * 6 + 6); |
||||
} |
||||
else if (m_lineMode) { |
||||
setScale(loopValue, loopValue, loopValue); |
||||
} |
||||
|
||||
// Call parent update
|
||||
Object::update(); |
||||
} |
||||
|
||||
void CubeColor::render() |
||||
{ |
||||
// Enable wireframe mode
|
||||
if (m_lineMode) { |
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
||||
} |
||||
|
||||
// Render
|
||||
m_shader->use(); |
||||
m_shader->setFloat("model", model()); |
||||
m_shader->setFloat("view", g_window->camera()->model()); |
||||
m_shader->setFloat("projection", g_window->camera()->projection()); |
||||
|
||||
glBindVertexArray(m_vao); |
||||
glDrawArrays(GL_TRIANGLES, 0, m_vSize); |
||||
glBindVertexArray(0); |
||||
|
||||
// Disable wireframe mode
|
||||
if (m_lineMode) { |
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
||||
} |
||||
} |
||||
|
||||
void CubeColor::destroy() |
||||
{ |
||||
// Clean resources
|
||||
glDeleteVertexArrays(1, &m_vao); |
||||
glDeleteBuffers(1, &m_vbo); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void CubeColor::setLineMode(bool lineMode) |
||||
{ |
||||
m_lineMode = lineMode; |
||||
} |
||||
|
||||
void CubeColor::setColor(float r, float g, float b) |
||||
{ |
||||
m_color = glm::vec3(r, g, b); |
||||
} |
@ -0,0 +1,21 @@
|
||||
#include "entity.h" |
||||
|
||||
Entity::Entity() : m_active(true) |
||||
{ |
||||
} |
||||
|
||||
Entity::~Entity() |
||||
{ |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
bool Entity::active() const |
||||
{ |
||||
return m_active; |
||||
} |
||||
|
||||
void Entity::setActive(bool active) |
||||
{ |
||||
m_active = active; |
||||
} |
@ -0,0 +1,86 @@
|
||||
#include <glad/glad.h> |
||||
|
||||
#include "font.h" |
||||
#include "texture.h" |
||||
|
||||
FT_Face FontManager::loadFont(const std::string &path) |
||||
{ |
||||
// Return previously loaded font
|
||||
auto iter = m_fontList.find(path); |
||||
if (iter != m_fontList.end()) { |
||||
return m_fontList[path]; |
||||
} |
||||
|
||||
// Init FreeType library
|
||||
FT_Library ft; |
||||
if (FT_Init_FreeType(&ft)) { |
||||
printf("FontManager::loadFont::ERROR::FREETYPE: Could not init FreeType Library\n"); |
||||
} |
||||
|
||||
// Load font
|
||||
FT_Face face; |
||||
if (FT_New_Face(ft, path.c_str(), 0, &face)) { |
||||
printf("FontManager::loadFont::FAILED\n%s\n", path.c_str()); |
||||
} |
||||
else { |
||||
// Define font size for this face
|
||||
FT_Set_Pixel_Sizes(face, 0, 24); // face, width, height, where width = dynamic
|
||||
|
||||
// Create character list of the first 128 ascii characters
|
||||
for (unsigned char c = 0; c < 128; c++) { |
||||
|
||||
// Creat 8-bit bitmap image of the character
|
||||
if (FT_Load_Char(face, c, FT_LOAD_RENDER)) { |
||||
printf("FontManager::loadFont::ERROR::FREETYTPE: Failed to load Glyph\n"); |
||||
continue; |
||||
} |
||||
|
||||
// Create texture
|
||||
unsigned int texture = g_textureManager->createTexture( |
||||
GL_RED, |
||||
face->glyph->bitmap.width, |
||||
face->glyph->bitmap.rows, |
||||
face->glyph->bitmap.buffer, |
||||
GL_CLAMP_TO_EDGE, |
||||
GL_LINEAR, |
||||
GL_LINEAR |
||||
); |
||||
|
||||
// Create character
|
||||
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 |
||||
}; |
||||
|
||||
// Construct and insert new element in the map
|
||||
m_characterList.emplace(c, character); |
||||
} |
||||
|
||||
// Construct and insert new element in the unordered_map
|
||||
m_fontList.emplace(path, face); |
||||
} |
||||
|
||||
// Clean resources
|
||||
FT_Done_Face(face); |
||||
FT_Done_FreeType(ft); |
||||
|
||||
return face; |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
Character FontManager::character(const char character) const |
||||
{ |
||||
return m_characterList.at(character); |
||||
} |
||||
|
||||
const std::map<const char, Character> &FontManager::characterList() const |
||||
{ |
||||
return m_characterList; |
||||
} |
||||
|
||||
// @Todo link fontList to characterList via:
|
||||
// <freetype/freetype.h>
|
||||
// typedef struct FT_FaceRec_* FT_Face;
|
@ -0,0 +1,120 @@
|
||||
#include <cstring> // memset, memcpy |
||||
|
||||
#include "input.h" |
||||
#include "window.h" |
||||
|
||||
InputManager::InputManager() |
||||
{ |
||||
initialize(); |
||||
} |
||||
|
||||
InputManager::~InputManager() |
||||
{ |
||||
destroy(); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void InputManager::initialize() |
||||
{ |
||||
// Set every key to release state
|
||||
memset(&m_previousKeyStates, GLFW_RELEASE, sizeof(char) * GLFW_KEY_LAST); |
||||
memset(&m_currentKeyStates, GLFW_RELEASE, sizeof(char) * GLFW_KEY_LAST); |
||||
|
||||
m_firstMouse = true; |
||||
// Set cursor in middle of the screen initially
|
||||
m_xLast = g_window->width() / 2; |
||||
m_yLast = g_window->height() / 2; |
||||
} |
||||
|
||||
void InputManager::update() |
||||
{ |
||||
} |
||||
|
||||
void InputManager::render() |
||||
{ |
||||
// Copy current key states to previous
|
||||
memcpy(&m_previousKeyStates, &m_currentKeyStates, sizeof(char) * GLFW_KEY_LAST); |
||||
|
||||
// Stop mouse movement
|
||||
m_xOffset = 0.0f; |
||||
m_yOffset = 0.0f; |
||||
} |
||||
|
||||
void InputManager::destroy() |
||||
{ |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
char InputManager::keyState(int key) |
||||
{ |
||||
if (m_previousKeyStates[key] == GLFW_RELEASE && |
||||
m_currentKeyStates[key] == GLFW_RELEASE) { |
||||
return InputManager::UP; |
||||
} |
||||
if (m_previousKeyStates[key] == GLFW_RELEASE && |
||||
m_currentKeyStates[key] == GLFW_PRESS) { |
||||
return InputManager::PRESSED; |
||||
} |
||||
if (m_previousKeyStates[key] == GLFW_PRESS && |
||||
m_currentKeyStates[key] == GLFW_PRESS) { |
||||
return InputManager::DOWN; |
||||
} |
||||
if (m_currentKeyStates[key] == GLFW_REPEAT) { |
||||
return InputManager::DOWN; |
||||
} |
||||
if (m_previousKeyStates[key] == GLFW_PRESS && |
||||
m_currentKeyStates[key] == GLFW_RELEASE) { |
||||
return InputManager::RELEASED; |
||||
} |
||||
|
||||
return InputManager::UP; |
||||
} |
||||
|
||||
void InputManager::setKeyState(int key, int scancode, int action, int mode) |
||||
{ |
||||
if (key != GLFW_KEY_UNKNOWN) { |
||||
m_currentKeyStates[key] = (char)action; |
||||
} |
||||
|
||||
// Suppress unused warning
|
||||
(void)scancode; |
||||
(void)mode; |
||||
} |
||||
|
||||
float InputManager::xOffset() |
||||
{ |
||||
return m_xOffset; |
||||
} |
||||
|
||||
float InputManager::yOffset() |
||||
{ |
||||
return m_yOffset; |
||||
} |
||||
|
||||
void InputManager::setMouse(double xpos, double ypos) |
||||
{ |
||||
// Prevent weird jump on first cursor window enter
|
||||
if(m_firstMouse) { |
||||
m_xLast = xpos; |
||||
m_yLast = ypos; |
||||
m_firstMouse = false; |
||||
} |
||||
|
||||
m_xOffset = xpos - m_xLast; |
||||
// Reversed since y-coordinates range from bottom to top
|
||||
m_yOffset = m_yLast - ypos; |
||||
m_xLast = xpos; |
||||
m_yLast = ypos; |
||||
} |
||||
|
||||
// @Todo
|
||||
// - Instead of copying the entire key array into the previous array each frame.
|
||||
// Have a pointer point to one of the arrays.
|
||||
// To read input, say: array that pointer points to now = current,
|
||||
// array that pointer does not point to now = previous.
|
||||
// At the end of the frame, point the pointer to the other array.
|
||||
// (?) How to get not point to array now easily? maybe two pointers that swap
|
||||
// - current pointer
|
||||
// - previous pointer
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Rick van Vonderen |
||||
* 0945444 |
||||
* TI2B |
||||
* |
||||
* https://www.glfw.org/docs/latest/build_guide.html#build_link_cmake_source
|
||||
* |
||||
* `m_` for member variables, |
||||
* `s_` for static variables, |
||||
* `g_` for global variables. |
||||
*/ |
||||
|
||||
#include <cstdio> // printf |
||||
|
||||
#include "font.h" |
||||
#include "gamestate.h" |
||||
#include "input.h" |
||||
#include "state/maingame.h" |
||||
#include "texture.h" |
||||
#include "window.h" |
||||
|
||||
// Define globals here
|
||||
GameStateManager *g_gameStateManager; |
||||
InputManager *g_inputManager; |
||||
TextureManager *g_textureManager; |
||||
FontManager *g_fontManager; |
||||
Window *g_window; |
||||
|
||||
#include <glm/gtx/transform.hpp> // glm::translate, glm::rotate, glm::scale |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
|
||||
#ifndef NDEBUG |
||||
printf("--- Debug mode ---\n"); |
||||
|
||||
// Supress unused warning
|
||||
(void)argc; |
||||
(void)argv; |
||||
#endif |
||||
|
||||
printf("--- Main ---\n"); |
||||
|
||||
g_window = new Window(1280, 720); |
||||
g_inputManager = new InputManager(); |
||||
g_textureManager = new TextureManager(); |
||||
g_fontManager = new FontManager(); |
||||
g_gameStateManager = new GameStateManager(); |
||||
g_gameStateManager->setState(new MainGame()); |
||||
|
||||
g_fontManager->loadFont("../data/font/DejaVuSansMono.ttf"); |
||||
|
||||
// Window loop
|
||||
while (!g_window->shouldClose()) { |
||||
g_window->update(); |
||||
g_inputManager->update(); |
||||
g_gameStateManager->update(); |
||||
g_gameStateManager->render(); |
||||
g_inputManager->render(); |
||||
g_window->render(); |
||||
} |
||||
|
||||
delete g_gameStateManager; |
||||
delete g_fontManager; |
||||
delete g_textureManager; |
||||
delete g_inputManager; |
||||
delete g_window; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,95 @@
|
||||
// #include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/gtx/transform.hpp> // glm::translate, glm::rotate, glm::scale |
||||
|
||||
#include "object.h" |
||||
|
||||
Object::Object() : Entity(), m_position(), m_rotation(), m_scale(), m_model() |
||||
{ |
||||
// printf("obj: %s\n", glm::to_string(position()).c_str());
|
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Object::initialize() |
||||
{ |
||||
} |
||||
|
||||
void Object::update() |
||||
{ |
||||
// Local space -> World space: model matrix
|
||||
m_model = glm::mat4(1.0f); |
||||
// Translate
|
||||
m_model = glm::translate(m_model, position()); |
||||
// Rotate
|
||||
m_model = glm::rotate(m_model, glm::radians(rotation().x), |
||||
glm::vec3(1.0, 0.0, 0.0)); |
||||
m_model = glm::rotate(m_model, glm::radians(rotation().y), |
||||
glm::vec3(0.0, 1.0, 0.0)); |
||||
m_model = glm::rotate(m_model, glm::radians(rotation().z), |
||||
glm::vec3(0.0, 0.0, 1.0)); |
||||
// Scale
|
||||
m_model = glm::scale(m_model, scale()); |
||||
} |
||||
|
||||
void Object::render() |
||||
{ |
||||
} |
||||
|
||||
void Object::destroy() |
||||
{ |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
glm::vec3 Object::position() const |
||||
{ |
||||
return m_position; |
||||
} |
||||
|
||||
void Object::setPosition(glm::vec3 position) |
||||
{ |
||||
m_position = position; |
||||
} |
||||
|
||||
void Object::setPosition(float x, float y, float z) |
||||
{ |
||||
m_position = glm::vec3(x, y, z); |
||||
} |
||||
|
||||
glm::vec3 Object::rotation() const |
||||
{ |
||||
return m_rotation; |
||||
} |
||||
|
||||
void Object::setRotation(glm::vec3 rotation) |
||||
{ |
||||
m_rotation = rotation; |
||||
} |
||||
|
||||
void Object::setRotation(float x, float y, float z) |
||||
{ |
||||
m_rotation = glm::vec3(x, y, z); |
||||
} |
||||
|
||||
glm::vec3 Object::scale() const |
||||
{ |
||||
return m_scale; |
||||
} |
||||
|
||||
void Object::setScale(glm::vec3 scale) |
||||
{ |
||||
m_scale = scale; |
||||
} |
||||
|
||||
void Object::setScale(float x, float y, float z) |
||||
{ |
||||
m_scale = glm::vec3(x, y, z); |
||||
} |
||||
|
||||
glm::mat4 Object::model() const { |
||||
return m_model; |
||||
} |
||||
|
||||
void Object::setModel(glm::mat4 model) { |
||||
m_model = model; |
||||
} |
@ -0,0 +1,162 @@
|
||||
#include <climits> // UINT_MAX |
||||
#include <cstdio> // printf |
||||
#include <fstream> // ifstream |
||||
#include <iostream> // ios |
||||
#include <memory> // make_unique |
||||
|
||||
#include <glad/glad.h> |
||||
#include <glm/gtc/type_ptr.hpp> // glm::value_ptr |
||||
|
||||
#include "shader.h" |
||||
|
||||
Shader::Shader(const std::string &vertexSource, const std::string &fragmentSource) : |
||||
m_program(0) |
||||
{ |
||||
std::string vertex = readFile(vertexSource); |
||||
std::string fragment = readFile(fragmentSource); |
||||
|
||||
unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, vertex.c_str()); |
||||
unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragment.c_str()); |
||||
if (vertexShader != UINT_MAX && fragmentShader != UINT_MAX) { |
||||
m_program = linkShader(vertexShader, fragmentShader); |
||||
} |
||||
} |
||||
|
||||
Shader::~Shader() |
||||
{ |
||||
if (m_program > 0) { |
||||
glDeleteProgram(m_program); |
||||
m_program = 0; |
||||
} |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
std::string Shader::readFile(const std::string &path) const |
||||
{ |
||||
// Create input stream object and open file
|
||||
std::ifstream file; |
||||
file.open(path.c_str(), std::ifstream::in); |
||||
|
||||
// Check if file exists
|
||||
if (!file.is_open()) { |
||||
printf("Shader::readFile::FAILED\n%s\n", path.c_str()); |
||||
return nullptr; |
||||
} |
||||
|
||||
// Get length of the file
|
||||
file.seekg(0, std::ios::end); |
||||
unsigned int length = file.tellg(); |
||||
file.seekg(0, std::ios::beg); |
||||
|
||||
// Allocate memory filled with zeros
|
||||
auto buffer = std::make_unique<char[]>(length + 1); |
||||
|
||||
file.read(buffer.get(), length); |
||||
file.close(); |
||||
|
||||
// Create string from the buffer
|
||||
std::string result = std::string(buffer.get(), length + 1); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
unsigned int Shader::compileShader(unsigned int type, const char *source) const |
||||
{ |
||||
// Create new shader
|
||||
unsigned int shader; |
||||
shader = glCreateShader(type); |
||||
// Attach shader source to shader object
|
||||
glShaderSource(shader, 1, &source, nullptr); |
||||
// Compile shader
|
||||
glCompileShader(shader); |
||||
// Check compilation status
|
||||
if (checkStatus(shader)) { |
||||
return shader; |
||||
} |
||||
|
||||
// On fail
|
||||
glDeleteShader(shader); |
||||
return UINT_MAX; |
||||
} |
||||
|
||||
unsigned int Shader::linkShader(unsigned int vertex, unsigned int fragment) const |
||||
{ |
||||
// Create new shader program
|
||||
unsigned int shaderProgram; |
||||
shaderProgram = glCreateProgram(); |
||||
// Attach both shaders to the shader program
|
||||
glAttachShader(shaderProgram, vertex); |
||||
glAttachShader(shaderProgram, fragment); |
||||
// Setup vertex attributes
|
||||
glBindAttribLocation(shaderProgram, 0, "aPos"); |
||||
// Link the shaders
|
||||
glLinkProgram(shaderProgram); |
||||
// Clear resources
|
||||
glDeleteShader(vertex); |
||||
glDeleteShader(fragment); |
||||
// Check linking status
|
||||
if (checkStatus(shaderProgram, true)) { |
||||
return shaderProgram; |
||||
} |
||||
|
||||
// On fail
|
||||
glDeleteProgram(shaderProgram); |
||||
return UINT_MAX; |
||||
} |
||||
|
||||
int Shader::checkStatus(unsigned int check, bool isProgram) const |
||||
{ |
||||
int success; |
||||
char infoLog[INFO_LOG_SIZE]; |
||||
|
||||
// Check shader or program
|
||||
!isProgram |
||||
? glGetShaderiv(check, GL_COMPILE_STATUS, &success) |
||||
: glGetProgramiv(check, GL_LINK_STATUS, &success); |
||||
|
||||
if (!success) { |
||||
// Check shader or program
|
||||
!isProgram |
||||
? glGetShaderInfoLog(check, INFO_LOG_SIZE, nullptr, infoLog) |
||||
: glGetProgramInfoLog(check, INFO_LOG_SIZE, nullptr, infoLog); |
||||
printf("Shader::checkStatus::FAILED\n%s\n", infoLog); |
||||
} |
||||
|
||||
return success; |
||||
} |
||||
|
||||
void Shader::use() const |
||||
{ |
||||
glUseProgram(m_program); |
||||
} |
||||
|
||||
void Shader::setFloat(const std::string &name, float f1, float f2, float f3, float f4) const |
||||
{ |
||||
// Set uniform vec4 data
|
||||
glUniform4f(glGetUniformLocation(m_program, name.c_str()), f1, f2, f3, f4); |
||||
} |
||||
|
||||
void Shader::setFloat(const std::string &name, glm::vec3 v) const { |
||||
// Set uniform vec3 data
|
||||
glUniform3f(glGetUniformLocation(m_program, name.c_str()), v.x, v.y, v.z); |
||||
} |
||||
|
||||
void Shader::setFloat(const std::string &name, glm::vec4 v) const { |
||||
// Set uniform vec4 data
|
||||
glUniform4f(glGetUniformLocation(m_program, name.c_str()), v.x, v.y, v.z, v.w); |
||||
// glUniform4fv(glGetUniformLocation(m_program, name.c_str()), 1, glm::value_ptr(v));
|
||||
} |
||||
|
||||
void Shader::setFloat(const std::string &name, glm::mat4 m) const { |
||||
// Set uniform mat4 data
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_program, name.c_str()), |
||||
1, GL_FALSE, glm::value_ptr(m)); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
unsigned int Shader::program() const |
||||
{ |
||||
return m_program; |
||||
} |
@ -0,0 +1,100 @@
|
||||
#include <cstdio> // printf |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
#include "cube.h" |
||||
#include "cubecolor.h" |
||||
#include "state/maingame.h" |
||||
#include "text.h" |
||||
|
||||
void MainGame::initialize() { |
||||
printf("MainGame::initialize\n"); |
||||
|
||||
glm::vec3 cubeColors[CUBE_SIZE] = { |
||||
// Textured cube
|
||||
glm::vec3( 0.6f, 0.2f, 0.2f), |
||||
glm::vec3( 0.2f, 0.6f, 0.2f), |
||||
glm::vec3( 0.2f, 0.2f, 0.6f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
// Colored cube
|
||||
glm::vec3( 0.6f, 0.2f, 0.2f), |
||||
glm::vec3( 0.2f, 0.6f, 0.2f), |
||||
glm::vec3( 0.2f, 0.2f, 0.6f), |
||||
glm::vec3( 0.6f, 0.2f, 0.2f), |
||||
glm::vec3( 0.2f, 0.6f, 0.2f), |
||||
glm::vec3( 0.2f, 0.2f, 0.6f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
glm::vec3( 1.0f, 1.0f, 1.0f), |
||||
}; |
||||
|
||||
glm::vec3 cubePositions[CUBE_SIZE] = { |
||||
// Textured cube
|
||||
glm::vec3( 0.0f, 0.0f, 0.0f), |
||||
glm::vec3( 2.0f, 0.0f, 0.0f), |
||||
glm::vec3( 4.0f, 0.0f, 0.0f), |
||||
glm::vec3( 0.0f, 2.0f, 0.0f), |
||||
glm::vec3( 2.0f, 2.0f, 0.0f), |
||||
glm::vec3( 4.0f, 2.0f, 0.0f), |
||||
// Colored cube
|
||||
glm::vec3( 0.0f, 0.0f, 6.0f), |
||||
glm::vec3( 2.0f, 0.0f, 6.0f), |
||||
glm::vec3( 4.0f, 0.0f, 6.0f), |
||||
glm::vec3( 0.0f, 2.0f, 6.0f), |
||||
glm::vec3( 2.0f, 2.0f, 6.0f), |
||||
glm::vec3( 4.0f, 2.0f, 6.0f), |
||||
glm::vec3( 0.0f, 4.0f, 6.0f), |
||||
glm::vec3( 2.0f, 4.0f, 6.0f), |
||||
glm::vec3( 4.0f, 4.0f, 6.0f), |
||||
}; |
||||
|
||||
bool cubeLine[CUBE_SIZE] = { |
||||
// Colored cube
|
||||
false, |
||||
false, |
||||
false, |
||||
true, |
||||
true, |
||||
true, |
||||
true, |
||||
}; |
||||
|
||||
for(int i = 0; i < CUBE; i++) { |
||||
m_object[i] = new Cube(cubeColors[i].x, cubeColors[i].y, cubeColors[i].z); |
||||
m_object[i]->setPosition(cubePositions[i]); |
||||
} |
||||
for(int i = CUBE; i < CUBE_SIZE; i++) { |
||||
m_object[i] = new CubeColor(cubeColors[i].x, cubeColors[i].y, cubeColors[i].z, |
||||
cubeLine[i - CUBE]); |
||||
m_object[i]->setPosition(cubePositions[i]); |
||||
} |
||||
|
||||
m_text = new Text(); |
||||
m_text->setText("Test"); |
||||
} |
||||
|
||||
void MainGame::update() { |
||||
for(int i = 0; i < CUBE_SIZE; i++) { |
||||
m_object[i]->update(); |
||||
} |
||||
|
||||
m_text->update(); |
||||
} |
||||
|
||||
void MainGame::render() { |
||||
for(int i = 0; i < CUBE_SIZE; i++) { |
||||
m_object[i]->render(); |
||||
} |
||||
|
||||
m_text->render(); |
||||
} |
||||
|
||||
void MainGame::destroy() { |
||||
for(int i = 0; i < CUBE_SIZE; i++) { |
||||
m_object[i]->destroy(); |
||||
} |
||||
|
||||
m_text->destroy(); |
||||
} |
@ -0,0 +1,117 @@
|
||||
#include <cstdio> // printf |
||||
// #include <iostream>
|
||||
|
||||
#include <glad/glad.h> |
||||
#include <glm/ext/matrix_clip_space.hpp> // glm::ortho |
||||
|
||||
#include "font.h" |
||||
#include "shader.h" |
||||
#include "text.h" |
||||
#include "texture.h" |
||||
#include "window.h" |
||||
|
||||
Text::Text() : Object(), m_color(1.0f), m_shader(nullptr), m_text("") |
||||
{ |
||||
initialize(); |
||||
} |
||||
|
||||
Text::~Text() |
||||
{ |
||||
destroy(); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Text::initialize() |
||||
{ |
||||
setScale(1.0f, 1.0f, 1.0f); |
||||
|
||||
m_shader = g_window->shaderFont(); |
||||
|
||||
// Generate buffer
|
||||
glGenVertexArrays(1, &m_vao); |
||||
glGenBuffers(1, &m_vbo); |
||||
glBindVertexArray(m_vao); |
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); |
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); |
||||
glEnableVertexAttribArray(0); |
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)0); |
||||
glBindBuffer(GL_ARRAY_BUFFER, 0); |
||||
glBindVertexArray(0); |
||||
} |
||||
|
||||
void Text::update() |
||||
{ |
||||
setPosition(50.0f, 50.0f, 0.0f); |
||||
} |
||||
|
||||
void Text::render() |
||||
{ |
||||
glEnable(GL_BLEND); |
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
||||
|
||||
// Render
|
||||
m_shader->use(); |
||||
m_shader->setFloat("color", m_color); |
||||
m_shader->setFloat("projection", glm::ortho( |
||||
0.0f, (float)g_window->width(), |
||||
0.0f, (float)g_window->height())); |
||||
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(m_vao); |
||||
|
||||
// Iterate through all characters
|
||||
std::string::const_iterator c; |
||||
for (c = m_text.begin(); c != m_text.end(); c++) |
||||
{ |
||||
Character ch = g_fontManager->character(*c); |
||||
// printf("ch: %u, %d %d, %d %d, %u\n",
|
||||
// ch.texture, ch.size.x, ch.size.y, ch.bearing.x, ch.bearing.y, ch.advance);
|
||||
|
||||
float xpos = position().x + ch.bearing.x * scale().x; |
||||
float ypos = position().y - (ch.size.y - ch.bearing.y) * scale().x; |
||||
// printf("xpos-ypos: %f, %f\n", xpos, ypos);
|
||||
|
||||
float w = ch.size.x * scale().x; |
||||
float h = ch.size.y * scale().x; |
||||
// printf("w-h: %f, %f\n", w, h);
|
||||
|
||||
// Update VBO for each character
|
||||
float 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.texture); |
||||
// Update content of VBO memory
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); |
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); |
||||
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)
|
||||
// Bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
setPosition(position().x + (ch.advance >> 6) * scale().x, position().y, position().z); |
||||
} |
||||
|
||||
// printf("\n");
|
||||
|
||||
glBindVertexArray(0); |
||||
glBindTexture(GL_TEXTURE_2D, 0); |
||||
} |
||||
|
||||
void Text::destroy() |
||||
{ |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Text::setText(std::string text) |
||||
{ |
||||
m_text = text; |
||||
} |
@ -0,0 +1,105 @@
|
||||
#include <climits> // UINT_MAX |
||||
|
||||
#include <glad/glad.h> |
||||
#define STB_IMAGE_IMPLEMENTATION |
||||
#include <stb_image.h> |
||||
|
||||
#include "texture.h" |
||||
|
||||
unsigned int TextureManager::loadTexture(const std::string &path) |
||||
{ |
||||
// Return previously loaded texture
|
||||
auto iter = m_textureList.find(path); |
||||
if (iter != m_textureList.end()) { |
||||
return m_textureList[path]; |
||||
} |
||||
|
||||
int width; |
||||
int height; |
||||
int channels; |
||||
// Load image data
|
||||
stbi_set_flip_vertically_on_load(true); |
||||
unsigned char *image = stbi_load(path.c_str(), &width, &height, &channels, STBI_default); |
||||
|
||||
unsigned int texture = UINT_MAX; |
||||
if (!image) { |
||||
printf("TextureManager::loadTexure::FAILED\n%s\n", path.c_str()); |
||||
} |
||||
else { |
||||
int format = 0; |
||||
if (channels == 3) { |
||||
format = GL_RGB; |
||||
} |
||||
else if (channels == 4) { |
||||
format = GL_RGBA; |
||||
} |
||||
|
||||
// Generate texture
|
||||
texture = createTexture( |
||||
format, |
||||
width, |
||||
height, |
||||
image, |
||||
GL_REPEAT, |
||||
GL_NEAREST, |
||||
GL_NEAREST, |
||||
true); |
||||
|
||||
// Construct and insert new element in the unordered_map
|
||||
m_textureList.emplace(path, texture); |
||||
} |
||||
|
||||
// Clean resources
|
||||
stbi_image_free(image); |
||||
|
||||
return texture; |
||||
} |
||||
|
||||
void TextureManager::deleteTexture(const unsigned int texture) |
||||
{ |
||||
glDeleteTextures(1, &texture); |
||||
} |
||||
|
||||
unsigned int TextureManager::createTexture( |
||||
int format, unsigned int width, unsigned int height, const void *image, |
||||
int wrap, int filterMin, int filterMag, bool genMipmap) |
||||
{ |
||||
unsigned int texture = UINT_MAX; |
||||
|
||||
// Create texture object
|
||||
glGenTextures(1, &texture); |
||||
|
||||
// Bind texture object
|
||||
glBindTexture(GL_TEXTURE_2D, texture); |
||||
|
||||
// Set unpacking of pixel data to byte-alignment,
|
||||
// this prevents alignment issues when using a single byte for color
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
||||
|
||||
// Generate texture
|
||||
glTexImage2D( |
||||
GL_TEXTURE_2D, // Texture target
|
||||
0, // Midmap level, base starts at level 0
|
||||
format, // Texture format
|
||||
width, height, // Image width/height
|
||||
0, // Always 0 (legacy)
|
||||
format, // Texture source format
|
||||
GL_UNSIGNED_BYTE, // Texture source datatype
|
||||
image); // Image data
|
||||
|
||||
// Set the texture wrapping / filtering options
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); // X
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); // Y
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMin); // Minify
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMag); // Magnify
|
||||
|
||||
if (genMipmap) { |
||||
// Automatically generate all mipmap levels
|
||||
glGenerateMipmap(GL_TEXTURE_2D); |
||||
} |
||||
|
||||
// Unbind texture object
|
||||
glBindTexture(GL_TEXTURE_2D, 0); |
||||
|
||||
return texture; |
||||
} |
@ -0,0 +1,215 @@
|
||||
#include <cstdio> // printf |
||||
|
||||
#include <glad/glad.h> |
||||
#include <GLFW/glfw3.h> |
||||
#include <glm/glm.hpp> |
||||
#include <stb_image.h> |
||||
|
||||
#include "camera.h" |
||||
#include "input.h" |
||||
#include "shader.h" |
||||
#include "window.h" |
||||
|
||||
// Window::Window() : Entity(), m_width(0), m_height(0)
|
||||
// {
|
||||
// }
|
||||
|
||||
Window::Window(int width, int height) : Entity(), m_width(width), m_height(height) |
||||
{ |
||||
this->initialize(); |
||||
} |
||||
|
||||
Window::~Window() |
||||
{ |
||||
this->destroy(); |
||||
} |
||||
|
||||
bool Window::shouldClose() |
||||
{ |
||||
return glfwWindowShouldClose(m_window); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Window::initialize() |
||||
{ |
||||
// Error callback function
|
||||
glfwSetErrorCallback(Window::errorCallback); |
||||
|
||||
// Init GLFW and set the required options
|
||||
glfwInit(); |
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); |
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); |
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); |
||||
|
||||
// Create a GLFWwindow object that can be used for GLFW's functions
|
||||
m_window = glfwCreateWindow(m_width, m_height, |
||||
"Lines", NULL, NULL); |
||||
glfwMakeContextCurrent(m_window); |
||||
if (m_window == NULL) { |
||||
printf("Failed to create GLFW window\n"); |
||||
glfwTerminate(); |
||||
} |
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { |
||||
printf("Failed to initialize OpenGL context\n"); |
||||
} |
||||
|
||||
// Associate the wrapper to the window
|
||||
glfwSetWindowUserPointer(m_window, this); |
||||
|
||||
// Keyboard callback function
|
||||
glfwSetKeyCallback(m_window, Window::keyCallback); |
||||
|
||||
// Capture cursor and hide it
|
||||
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); |
||||
|
||||
// Mouse callback function
|
||||
glfwSetCursorPosCallback(m_window, Window::mouseCallback); |
||||
|
||||
// Load shaders
|
||||
m_shader = new Shader("../data/glsl/simple.vert", "../data/glsl/simple.frag"); |
||||
m_shaderColor = new Shader("../data/glsl/color.vert", "../data/glsl/color.frag"); |
||||
m_shaderFont = new Shader("../data/glsl/font.vert", "../data/glsl/font.frag"); |
||||
|
||||
// Enable z-buffer / depth buffer
|
||||
glEnable(GL_DEPTH_TEST); |
||||
|
||||
m_lastFrameTime = 0.0f; |
||||
m_deltaTime = 0.0f; |
||||
|
||||
// Initialize camera
|
||||
m_camera = new Camera(); |
||||
m_camera->initialize(); |
||||
} |
||||
|
||||
void Window::update() |
||||
{ |
||||
// Clear buffers
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); |
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
||||
|
||||
// Check if any events have been activated (keypresses, mouse movement)
|
||||
glfwPollEvents(); |
||||
|
||||
// Reset the viewport to the new window size
|
||||
glfwGetFramebufferSize(m_window, &m_width, &m_height); |
||||
m_aspect = (float)m_width / (float)m_height; |
||||
glViewport(0, 0, m_width, m_height); |
||||
|
||||
// Calculate delta time
|
||||
m_currentTime = glfwGetTime(); |
||||
m_deltaTime = m_currentTime - m_lastFrameTime; |
||||
m_lastFrameTime = m_currentTime; |
||||
|
||||
m_camera->update(); |
||||
} |
||||
|
||||
void Window::render() |
||||
{ |
||||
m_camera->render(); |
||||
|
||||
// Swap the screen buffers
|
||||
glfwSwapBuffers(m_window); |
||||
} |
||||
|
||||
void Window::destroy() |
||||
{ |
||||
delete m_shader; |
||||
delete m_shaderColor; |
||||
delete m_shaderFont; |
||||
delete m_camera; |
||||
|
||||
// Clean GLFW allocated resources
|
||||
glfwDestroyWindow(m_window); |
||||
glfwTerminate(); |
||||
printf("Cleaned up GLFW resources..\n"); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
int Window::width() |
||||
{ |
||||
return m_width; |
||||
} |
||||
|
||||
int Window::height() |
||||
{ |
||||
return m_height; |
||||
} |
||||
|
||||
float Window::aspect() |
||||
{ |
||||
return m_aspect; |
||||
} |
||||
|
||||
float Window::currentTime() |
||||
{ |
||||
return m_currentTime; |
||||
} |
||||
|
||||
float Window::deltaTime() |
||||
{ |
||||
return m_deltaTime; |
||||
} |
||||
|
||||
GLFWwindow *Window::window() |
||||
{ |
||||
return m_window; |
||||
} |
||||
|
||||
Shader *Window::shader() |
||||
{ |
||||
return m_shader; |
||||
} |
||||
|
||||
Shader *Window::shaderColor() |
||||
{ |
||||
return m_shaderColor; |
||||
} |
||||
|
||||
Shader *Window::shaderFont() |
||||
{ |
||||
return m_shaderFont; |
||||
} |
||||
|
||||
Camera *Window::camera() |
||||
{ |
||||
return m_camera; |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Window::errorCallback(int error, const char* description) |
||||
{ |
||||
fputs(description, stderr); |
||||
|
||||
// Suppress unused warning
|
||||
(void)error; |
||||
} |
||||
|
||||
void Window::keyCallback(GLFWwindow* window, int key, int scancode, |
||||
int action, int mode) |
||||
{ |
||||
// printf("%d\n", key);
|
||||
|
||||
// Quit game
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) |
||||
glfwSetWindowShouldClose(window, GL_TRUE); |
||||
|
||||
// Mouse capture
|
||||
if (key == GLFW_KEY_LEFT_SUPER && action == GLFW_PRESS) |
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); |
||||
else |
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); |
||||
|
||||
g_inputManager->setKeyState(key, scancode, action, mode); |
||||
} |
||||
|
||||
void Window::mouseCallback(GLFWwindow* window, double xpos, double ypos) |
||||
{ |
||||
g_inputManager->setMouse(xpos, ypos); |
||||
|
||||
// Suppress unused warning
|
||||
(void)window; |
||||
} |
Loading…
Reference in new issue