JOSP is to begin
This commit is contained in:
commit
e16bb83b7f
|
@ -0,0 +1,12 @@
|
||||||
|
[submodule "deps/bullet3"]
|
||||||
|
path = deps/bullet3
|
||||||
|
url = https://github.com/bulletphysics/bullet3.git
|
||||||
|
[submodule "deps/glfw"]
|
||||||
|
path = deps/glfw
|
||||||
|
url = https://github.com/glfw/glfw.git
|
||||||
|
[submodule "deps/glm"]
|
||||||
|
path = deps/glm
|
||||||
|
url = https://github.com/g-truc/glm.git
|
||||||
|
[submodule "deps/stb"]
|
||||||
|
path = deps/stb
|
||||||
|
url = https://github.com/nothings/stb.git
|
|
@ -0,0 +1,35 @@
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(jungle)
|
||||||
|
|
||||||
|
add_subdirectory(./deps/glfw/)
|
||||||
|
add_subdirectory(./deps/bullet3/)
|
||||||
|
add_subdirectory(./deps/glm)
|
||||||
|
|
||||||
|
##jungle target##
|
||||||
|
#add_executable(opengl_test ./src/main.cpp ./src/callbacks.cpp ./src/settings.cpp ./src/window_init.cpp ./deps/glad/src/glad.c)
|
||||||
|
#glfw dep
|
||||||
|
#add_dependencies(opengl_test glfw)
|
||||||
|
#target_include_directories(opengl_test PRIVATE ./deps/glfw/include/ ./deps/glad/include/ ./inc)
|
||||||
|
#target_link_libraries(opengl_test glfw)
|
||||||
|
#bullet dep
|
||||||
|
#add_dependencies(opengl_test BulletDynamics BulletCollision LinearMath)
|
||||||
|
#target_include_directories(opengl_test PRIVATE ./deps/bullet3/src/)
|
||||||
|
#target_link_libraries(opengl_test BulletDynamics BulletCollision LinearMath)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##test target##
|
||||||
|
add_executable(jungle ./test/main.cpp ./deps/glad/src/glad.c)
|
||||||
|
target_include_directories(jungle PRIVATE ./test/)
|
||||||
|
#glfw dep
|
||||||
|
add_dependencies(jungle glfw)
|
||||||
|
target_include_directories(jungle PRIVATE ./deps/glfw/include/ ./deps/glad/include/ ./inc)
|
||||||
|
target_link_libraries(jungle glfw)
|
||||||
|
#bullet dep
|
||||||
|
add_dependencies(jungle BulletDynamics BulletCollision LinearMath)
|
||||||
|
target_include_directories(jungle PRIVATE ./deps/bullet3/src/)
|
||||||
|
target_link_libraries(jungle BulletDynamics BulletCollision LinearMath)
|
||||||
|
#glm dep
|
||||||
|
add_dependencies(jungle glm)
|
||||||
|
target_include_directories(jungle PRIVATE ./deps/glm/)
|
||||||
|
target_link_libraries(jungle glm)
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit e9c461b0ace140d5c73972760781d94b7b5eee53
|
|
@ -0,0 +1,311 @@
|
||||||
|
#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;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# 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
|
||||||
|
/*
|
||||||
|
* To support platform where unsigned long cannot be used interchangeably with
|
||||||
|
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||||
|
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||||
|
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||||
|
* unsigned long long or similar (this results in different C++ name mangling).
|
||||||
|
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||||
|
* platforms where the size of a pointer is larger than the size of long.
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||||
|
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||||
|
#define KHRONOS_USE_INTPTR_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 KHRONOS_USE_INTPTR_T
|
||||||
|
typedef intptr_t khronos_intptr_t;
|
||||||
|
typedef uintptr_t khronos_uintptr_t;
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 228e58262e18f2ee61799bd86d0be718b1e31f9f
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 45008b225e28eb700fa0f7d3ff69b7c1db94fadf
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ae721c50eaf761660b4f90cc590453cdb0c2acd0
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 TexCoord;
|
||||||
|
|
||||||
|
// texture samplers
|
||||||
|
uniform sampler2D texture1;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 pixel = texture(texture1, TexCoord);
|
||||||
|
if(pixel.a == 0){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
FragColor = pixel;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
out vec2 TexCoord;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform ivec2 index;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = projection * view * model * vec4(aPos, 1.0f);
|
||||||
|
TexCoord = vec2((aTexCoord.x + index.x)/16, (aTexCoord.y + index.y)/16);
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
|
@ -0,0 +1,135 @@
|
||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
|
||||||
|
enum Camera_Movement
|
||||||
|
{
|
||||||
|
FORWARD,
|
||||||
|
BACKWARD,
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
UP,
|
||||||
|
DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
// Default camera values
|
||||||
|
const float YAW = -90.0f;
|
||||||
|
const float PITCH = 0.0f;
|
||||||
|
const float SPEED = 4.5f;
|
||||||
|
const float SENSITIVITY = 0.1f;
|
||||||
|
const float ZOOM = 45.0f;
|
||||||
|
|
||||||
|
// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// camera Attributes
|
||||||
|
glm::vec3 Position;
|
||||||
|
glm::vec3 Front;
|
||||||
|
glm::vec3 Up;
|
||||||
|
glm::vec3 Right;
|
||||||
|
glm::vec3 WorldUp;
|
||||||
|
// euler Angles
|
||||||
|
float Yaw;
|
||||||
|
float Pitch;
|
||||||
|
// camera options
|
||||||
|
float MovementSpeed;
|
||||||
|
float MouseSensitivity;
|
||||||
|
float Zoom;
|
||||||
|
|
||||||
|
// constructor with vectors
|
||||||
|
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
|
||||||
|
{
|
||||||
|
Position = position;
|
||||||
|
WorldUp = up;
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
// constructor with scalar values
|
||||||
|
Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
|
||||||
|
{
|
||||||
|
Position = glm::vec3(posX, posY, posZ);
|
||||||
|
WorldUp = glm::vec3(upX, upY, upZ);
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the view matrix calculated using Euler Angles and the LookAt Matrix
|
||||||
|
glm::mat4 GetViewMatrix()
|
||||||
|
{
|
||||||
|
return glm::lookAt(Position, Position + Front, Up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
|
||||||
|
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
|
||||||
|
{
|
||||||
|
float velocity = MovementSpeed * deltaTime;
|
||||||
|
if (direction == FORWARD)
|
||||||
|
Position += Front * velocity;
|
||||||
|
if (direction == BACKWARD)
|
||||||
|
Position -= Front * velocity;
|
||||||
|
if (direction == LEFT)
|
||||||
|
Position -= Right * velocity;
|
||||||
|
if (direction == RIGHT)
|
||||||
|
Position += Right * velocity;
|
||||||
|
|
||||||
|
if (direction == UP)
|
||||||
|
Position.y += velocity;
|
||||||
|
if (direction == DOWN)
|
||||||
|
Position.y -= velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
|
||||||
|
void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
|
||||||
|
{
|
||||||
|
xoffset *= MouseSensitivity;
|
||||||
|
yoffset *= MouseSensitivity;
|
||||||
|
|
||||||
|
Yaw += xoffset;
|
||||||
|
Pitch += yoffset;
|
||||||
|
|
||||||
|
// make sure that when pitch is out of bounds, screen doesn't get flipped
|
||||||
|
if (constrainPitch)
|
||||||
|
{
|
||||||
|
if (Pitch > 89.0f)
|
||||||
|
Pitch = 89.0f;
|
||||||
|
if (Pitch < -89.0f)
|
||||||
|
Pitch = -89.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Front, Right and Up Vectors using the updated Euler angles
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
|
||||||
|
void ProcessMouseScroll(float yoffset)
|
||||||
|
{
|
||||||
|
Zoom -= (float)yoffset;
|
||||||
|
if (Zoom < 1.0f)
|
||||||
|
Zoom = 1.0f;
|
||||||
|
if (Zoom > 45.0f)
|
||||||
|
Zoom = 45.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// calculates the front vector from the Camera's (updated) Euler Angles
|
||||||
|
void updateCameraVectors()
|
||||||
|
{
|
||||||
|
// calculate the new Front vector
|
||||||
|
glm::vec3 front;
|
||||||
|
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||||
|
front.y = sin(glm::radians(Pitch));
|
||||||
|
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||||
|
Front = glm::normalize(front);
|
||||||
|
// also re-calculate the Right and Up vector
|
||||||
|
Right = glm::normalize(glm::cross(Front, WorldUp)); // normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
||||||
|
Up = glm::normalize(glm::cross(Right, Front));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -0,0 +1,393 @@
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "shader_m.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
|
||||||
|
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
|
||||||
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
|
||||||
|
void processInput(GLFWwindow *window);
|
||||||
|
|
||||||
|
// settings
|
||||||
|
const unsigned int SCR_WIDTH = 854;
|
||||||
|
const unsigned int SCR_HEIGHT = 480;
|
||||||
|
|
||||||
|
// camera
|
||||||
|
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
|
||||||
|
float lastX = SCR_WIDTH / 2.0f;
|
||||||
|
float lastY = SCR_HEIGHT / 2.0f;
|
||||||
|
bool firstMouse = true;
|
||||||
|
|
||||||
|
// timing
|
||||||
|
float deltaTime = 0.0f; // time between current frame and last frame
|
||||||
|
float lastFrame = 0.0f;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// std::cout << "debug";
|
||||||
|
// glfw: initialize and configure
|
||||||
|
// ------------------------------
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
// glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glfw window creation
|
||||||
|
// --------------------
|
||||||
|
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Jungle", NULL, NULL);
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to create GLFW window" << std::endl;
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
|
||||||
|
// tell GLFW to capture our mouse
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
|
||||||
|
// glad: load all OpenGL function pointers
|
||||||
|
// ---------------------------------------
|
||||||
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure global opengl state
|
||||||
|
// -----------------------------
|
||||||
|
// glEnable(GL_BLEND);
|
||||||
|
// glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
|
||||||
|
// glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// build and compile our shader zprogram
|
||||||
|
// ------------------------------------
|
||||||
|
Shader ourShader("demo.vs", "demo.fs");
|
||||||
|
|
||||||
|
// set up vertex data (and buffer(s)) and configure vertex attributes
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
float vertices[] = {
|
||||||
|
// back
|
||||||
|
-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,
|
||||||
|
|
||||||
|
// front
|
||||||
|
-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,
|
||||||
|
|
||||||
|
// left
|
||||||
|
-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,
|
||||||
|
|
||||||
|
// right
|
||||||
|
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,
|
||||||
|
|
||||||
|
// down
|
||||||
|
-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,
|
||||||
|
|
||||||
|
// up
|
||||||
|
-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};
|
||||||
|
// world space positions of our cubes
|
||||||
|
glm::ivec3 cubePositions[] = {
|
||||||
|
glm::ivec3(0, 0, 0),
|
||||||
|
glm::ivec3(2, 5, -15),
|
||||||
|
glm::ivec3(-1, -2, -2),
|
||||||
|
glm::ivec3(-3, -2, -12),
|
||||||
|
glm::ivec3(2, -0, -3),
|
||||||
|
glm::ivec3(-1, 3, -7),
|
||||||
|
glm::ivec3(1, -2, -2),
|
||||||
|
glm::ivec3(1, 2, -2),
|
||||||
|
glm::ivec3(1, 0, -1),
|
||||||
|
glm::ivec3(-1, 1, -1)};
|
||||||
|
|
||||||
|
glm::ivec2 cubeTextures[] = {
|
||||||
|
glm::ivec2(1, 14),
|
||||||
|
glm::ivec2(8, 3),
|
||||||
|
glm::ivec2(0, 4),
|
||||||
|
glm::ivec2(1, 12),
|
||||||
|
glm::ivec2(1, 6),
|
||||||
|
|
||||||
|
glm::ivec2(0, 6),
|
||||||
|
glm::ivec2(1, 2),
|
||||||
|
glm::ivec2(0, 14),
|
||||||
|
glm::ivec2(3, 12),
|
||||||
|
glm::ivec2(1, 12)};
|
||||||
|
|
||||||
|
unsigned int VBO, VAO;
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// position attribute
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
// texture coord attribute
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// load and create a texture
|
||||||
|
// -------------------------
|
||||||
|
unsigned int texture1; //, texture2;
|
||||||
|
// texture 1
|
||||||
|
// ---------
|
||||||
|
glGenTextures(1, &texture1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
// set the texture wrapping parameters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
// set texture filtering parameters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// load image, create texture and generate mipmaps
|
||||||
|
int width, height, nrChannels;
|
||||||
|
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
|
||||||
|
unsigned char *data = stbi_load("./terrain.png", &width, &height, &nrChannels, STBI_rgb_alpha);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
// glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Failed to load texture" << std::endl;
|
||||||
|
}
|
||||||
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
// texture 2
|
||||||
|
// ---------
|
||||||
|
// glGenTextures(1, &texture2);
|
||||||
|
// glBindTexture(GL_TEXTURE_2D, texture2);
|
||||||
|
// set the texture wrapping parameters
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
// set texture filtering parameters
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
// load image, create texture and generate mipmaps
|
||||||
|
// data = stbi_load("./resources/textures/awesomeface.png", &width, &height, &nrChannels, 0);
|
||||||
|
// if (data)
|
||||||
|
//{
|
||||||
|
// // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
|
||||||
|
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
// glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
//}
|
||||||
|
// else
|
||||||
|
//{
|
||||||
|
// std::cout << "Failed to load texture" << std::endl;
|
||||||
|
//}
|
||||||
|
// stbi_image_free(data);
|
||||||
|
|
||||||
|
// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
ourShader.use();
|
||||||
|
ourShader.setInt("texture1", 0);
|
||||||
|
// ourShader.setInt("texture2", 1);
|
||||||
|
|
||||||
|
// bind textures on corresponding texture units
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
// glActiveTexture(GL_TEXTURE1);
|
||||||
|
// glBindTexture(GL_TEXTURE_2D, texture2);
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
// render loop
|
||||||
|
// -----------
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
// per-frame time logic
|
||||||
|
// --------------------
|
||||||
|
float currentFrame = static_cast<float>(glfwGetTime());
|
||||||
|
deltaTime = currentFrame - lastFrame;
|
||||||
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
|
// input
|
||||||
|
// -----
|
||||||
|
processInput(window);
|
||||||
|
|
||||||
|
// render
|
||||||
|
// ------
|
||||||
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// activate shader
|
||||||
|
ourShader.use();
|
||||||
|
|
||||||
|
// pass projection matrix to shader (note that in this case it could change every frame)
|
||||||
|
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
||||||
|
ourShader.setMat4("projection", projection);
|
||||||
|
|
||||||
|
// camera/view transformation
|
||||||
|
glm::mat4 view = camera.GetViewMatrix();
|
||||||
|
ourShader.setMat4("view", view);
|
||||||
|
|
||||||
|
// glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// glDepthMask(GL_TRUE);
|
||||||
|
// render opaque objects first
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
ourShader.setIVec2("index", cubeTextures[i]);
|
||||||
|
|
||||||
|
// calculate the model matrix for each object and pass it to shader before drawing
|
||||||
|
glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
|
||||||
|
model = glm::translate(model, glm::vec3(cubePositions[i]));
|
||||||
|
ourShader.setMat4("model", model);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
}
|
||||||
|
// glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
|
// render transparent objects with blending enabled
|
||||||
|
// glEnable(GL_BLEND);
|
||||||
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
// for (unsigned int i = 5; i < 10; i++)
|
||||||
|
// {
|
||||||
|
// ourShader.setIVec2("index", cubeTextures[i]);
|
||||||
|
|
||||||
|
// // calculate the model matrix for each object and pass it to shader before drawing
|
||||||
|
// glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
|
||||||
|
// model = glm::translate(model, glm::vec3(cubePositions[i]));
|
||||||
|
// ourShader.setMat4("model", model);
|
||||||
|
// glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
// }
|
||||||
|
// glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
// glDisable(GL_DEPTH_TEST);
|
||||||
|
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// optional: de-allocate all resources once they've outlived their purpose:
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
glDeleteBuffers(1, &VBO);
|
||||||
|
|
||||||
|
// glfw: terminate, clearing all previously allocated GLFW resources.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
|
||||||
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
|
void processInput(GLFWwindow *window)
|
||||||
|
{
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(LEFT, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(RIGHT, deltaTime);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(UP, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(DOWN, deltaTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
|
||||||
|
{
|
||||||
|
// make sure the viewport matches the new window dimensions; note that width and
|
||||||
|
// height will be significantly larger than specified on retina displays.
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the mouse moves, this callback is called
|
||||||
|
// -------------------------------------------------------
|
||||||
|
void mouse_callback(GLFWwindow *window, double xposIn, double yposIn)
|
||||||
|
{
|
||||||
|
float xpos = static_cast<float>(xposIn);
|
||||||
|
float ypos = static_cast<float>(yposIn);
|
||||||
|
|
||||||
|
if (firstMouse)
|
||||||
|
{
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
firstMouse = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float xoffset = xpos - lastX;
|
||||||
|
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
||||||
|
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
|
||||||
|
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
|
||||||
|
{
|
||||||
|
camera.ProcessMouseScroll(static_cast<float>(yoffset));
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned int ID;
|
||||||
|
// constructor generates the shader on the fly
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
|
{
|
||||||
|
// 1. retrieve the vertex/fragment source code from filePath
|
||||||
|
std::string vertexCode;
|
||||||
|
std::string fragmentCode;
|
||||||
|
std::ifstream vShaderFile;
|
||||||
|
std::ifstream fShaderFile;
|
||||||
|
// ensure ifstream objects can throw exceptions:
|
||||||
|
vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// open files
|
||||||
|
vShaderFile.open(vertexPath);
|
||||||
|
fShaderFile.open(fragmentPath);
|
||||||
|
std::stringstream vShaderStream, fShaderStream;
|
||||||
|
// read file's buffer contents into streams
|
||||||
|
vShaderStream << vShaderFile.rdbuf();
|
||||||
|
fShaderStream << fShaderFile.rdbuf();
|
||||||
|
// close file handlers
|
||||||
|
vShaderFile.close();
|
||||||
|
fShaderFile.close();
|
||||||
|
// convert stream into string
|
||||||
|
vertexCode = vShaderStream.str();
|
||||||
|
fragmentCode = fShaderStream.str();
|
||||||
|
}
|
||||||
|
catch (std::ifstream::failure& e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
const char* vShaderCode = vertexCode.c_str();
|
||||||
|
const char * fShaderCode = fragmentCode.c_str();
|
||||||
|
// 2. compile shaders
|
||||||
|
unsigned int vertex, fragment;
|
||||||
|
// vertex shader
|
||||||
|
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||||
|
glCompileShader(vertex);
|
||||||
|
checkCompileErrors(vertex, "VERTEX");
|
||||||
|
// fragment Shader
|
||||||
|
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||||
|
glCompileShader(fragment);
|
||||||
|
checkCompileErrors(fragment, "FRAGMENT");
|
||||||
|
// shader Program
|
||||||
|
ID = glCreateProgram();
|
||||||
|
glAttachShader(ID, vertex);
|
||||||
|
glAttachShader(ID, fragment);
|
||||||
|
glLinkProgram(ID);
|
||||||
|
checkCompileErrors(ID, "PROGRAM");
|
||||||
|
// delete the shaders as they're linked into our program now and no longer necessary
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
|
||||||
|
}
|
||||||
|
// activate the shader
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void use() const
|
||||||
|
{
|
||||||
|
glUseProgram(ID);
|
||||||
|
}
|
||||||
|
// utility uniform functions
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setBool(const std::string &name, bool value) const
|
||||||
|
{
|
||||||
|
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setInt(const std::string &name, int value) const
|
||||||
|
{
|
||||||
|
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
void setIVec2(const std::string &name, int x, int y) const
|
||||||
|
{
|
||||||
|
glUniform2i(glGetUniformLocation(ID, name.c_str()), x, y);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
void setIVec2(const std::string &name, const glm::ivec2 &value) const
|
||||||
|
{
|
||||||
|
glUniform2iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setFloat(const std::string &name, float value) const
|
||||||
|
{
|
||||||
|
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setVec2(const std::string &name, const glm::vec2 &value) const
|
||||||
|
{
|
||||||
|
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
void setVec2(const std::string &name, float x, float y) const
|
||||||
|
{
|
||||||
|
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setVec3(const std::string &name, const glm::vec3 &value) const
|
||||||
|
{
|
||||||
|
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
void setVec3(const std::string &name, float x, float y, float z) const
|
||||||
|
{
|
||||||
|
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setVec4(const std::string &name, const glm::vec4 &value) const
|
||||||
|
{
|
||||||
|
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
void setVec4(const std::string &name, float x, float y, float z, float w) const
|
||||||
|
{
|
||||||
|
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setMat2(const std::string &name, const glm::mat2 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setMat3(const std::string &name, const glm::mat3 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setMat4(const std::string &name, const glm::mat4 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// utility function for checking shader compilation/linking errors.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void checkCompileErrors(GLuint shader, std::string type)
|
||||||
|
{
|
||||||
|
GLint success;
|
||||||
|
GLchar infoLog[1024];
|
||||||
|
if (type != "PROGRAM")
|
||||||
|
{
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue