Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
build/
|
||||||
+12
@@ -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)
|
||||||
+50
@@ -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.
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;
|
||||||
|
}
|
||||||
+1
Submodule deps/freetype added at fbbcf50367
Vendored
+282
@@ -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_ */
|
||||||
Vendored
+3201
File diff suppressed because it is too large
Load Diff
Vendored
+1639
File diff suppressed because it is too large
Load Diff
+1
Submodule deps/glfw added at 2c7f3ce91b
+1
Submodule deps/glm added at 6347f62261
+1
Submodule deps/stb added at b42009b3b9
@@ -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
|
||||||
+111
@@ -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
@@ -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;
|
||||||
+120
@@ -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;
|
||||||
|
}
|
||||||
+162
@@ -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();
|
||||||
|
}
|
||||||
+117
@@ -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;
|
||||||
|
}
|
||||||
+105
@@ -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;
|
||||||
|
}
|
||||||
+215
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user