Browse Source

Initial commit

master
Riyyi 3 years ago
commit
57c16ef187
  1. 1
      .gitignore
  2. 12
      .gitmodules
  3. 63
      CMakeLists.txt
  4. 50
      README.org
  5. BIN
      data/font/DejaVuSans.ttf
  6. BIN
      data/font/DejaVuSansMono.ttf
  7. BIN
      data/gfx/awesome-face.png
  8. 9
      data/glsl/color.frag
  9. 16
      data/glsl/color.vert
  10. 14
      data/glsl/font.frag
  11. 12
      data/glsl/font.vert
  12. 13
      data/glsl/simple.frag
  13. 16
      data/glsl/simple.vert
  14. 1
      deps/freetype
  15. 282
      deps/glad/include/KHR/khrplatform.h
  16. 3201
      deps/glad/include/glad/glad.h
  17. 1639
      deps/glad/src/glad.c
  18. 1
      deps/glfw
  19. 1
      deps/glm
  20. 1
      deps/stb
  21. 38
      include/camera.h
  22. 42
      include/cube.h
  23. 43
      include/cubecolor.h
  24. 31
      include/entity.h
  25. 42
      include/font.h
  26. 66
      include/gamestate.h
  27. 53
      include/input.h
  28. 46
      include/object.h
  29. 44
      include/shader.h
  30. 33
      include/state/maingame.h
  31. 42
      include/text.h
  32. 28
      include/texture.h
  33. 69
      include/window.h
  34. 111
      src/camera.cpp
  35. 188
      src/cube.cpp
  36. 197
      src/cubecolor.cpp
  37. 21
      src/entity.cpp
  38. 86
      src/font.cpp
  39. 120
      src/input.cpp
  40. 70
      src/main.cpp
  41. 95
      src/object.cpp
  42. 162
      src/shader.cpp
  43. 100
      src/state/maingame.cpp
  44. 117
      src/text.cpp
  45. 105
      src/texture.cpp
  46. 215
      src/window.cpp

1
.gitignore vendored

@ -0,0 +1 @@
build/

12
.gitmodules vendored

@ -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

63
CMakeLists.txt

@ -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)

50
README.org

@ -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]]

BIN
data/font/DejaVuSans.ttf

Binary file not shown.

BIN
data/font/DejaVuSansMono.ttf

Binary file not shown.

BIN
data/gfx/awesome-face.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

9
data/glsl/color.frag

@ -0,0 +1,9 @@
#version 130
out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = vec4(color, 1.0f);
}

16
data/glsl/color.vert

@ -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;
}

14
data/glsl/font.frag

@ -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;
}

12
data/glsl/font.vert

@ -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;
}

13
data/glsl/simple.frag

@ -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;
}

16
data/glsl/simple.vert

@ -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;
}

1
deps/freetype vendored

@ -0,0 +1 @@
Subproject commit fbbcf50367403a6316a013b51690071198962920

282
deps/glad/include/KHR/khrplatform.h vendored

@ -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_ */

3201
deps/glad/include/glad/glad.h vendored

File diff suppressed because it is too large Load Diff

1639
deps/glad/src/glad.c vendored

File diff suppressed because it is too large Load Diff

1
deps/glfw vendored

@ -0,0 +1 @@
Subproject commit 2c7f3ce91b4f22773855c43d6480824ed4ac9907

1
deps/glm vendored

@ -0,0 +1 @@
Subproject commit 6347f62261da5be4e27a256e28aef6abc0ba884d

1
deps/stb vendored

@ -0,0 +1 @@
Subproject commit b42009b3b9d4ca35bc703f5310eedc74f584be58

38
include/camera.h

@ -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

42
include/cube.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

43
include/cubecolor.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

31
include/entity.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

42
include/font.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

66
include/gamestate.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

53
include/input.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

46
include/object.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

44
include/shader.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

33
include/state/maingame.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

42
include/text.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

28
include/texture.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

69
include/window.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

111
src/camera.cpp

@ -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;
}

188
src/cube.cpp

@ -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);