Compare commits
10 Commits
5adc6e80e6
...
799f21dfc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
799f21dfc1 | ||
|
|
3c398f0308 | ||
| 3c413c70b9 | |||
| 62a4b739dd | |||
| c6ae576289 | |||
| 908232c31e | |||
| d398f3a1d9 | |||
| af612fbfe9 | |||
| 860ea04cfb | |||
| c746f1d8eb |
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
build/
|
build/
|
||||||
cmake-build-*/
|
cmake-build-*/
|
||||||
out/
|
out/
|
||||||
|
.cache/
|
||||||
|
|
||||||
# CMake generated files
|
# CMake generated files
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
|
|||||||
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.19)
|
|||||||
project(OpenGLTest CXX)
|
project(OpenGLTest CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
@ -11,6 +12,7 @@ find_package(glfw3 REQUIRED)
|
|||||||
file(GLOB SOURCES src/*.h src/*.cpp)
|
file(GLOB SOURCES src/*.h src/*.cpp)
|
||||||
add_executable(opengl_test ${SOURCES})
|
add_executable(opengl_test ${SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(opengl_test PUBLIC include)
|
||||||
target_link_libraries(opengl_test
|
target_link_libraries(opengl_test
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
GLEW::GLEW
|
GLEW::GLEW
|
||||||
|
|||||||
BIN
assets/krita/clay_texture_1k.kra
Normal file
BIN
assets/krita/clay_texture_1k.kra
Normal file
Binary file not shown.
BIN
assets/krita/plaster_texture_1k.kra
Normal file
BIN
assets/krita/plaster_texture_1k.kra
Normal file
Binary file not shown.
BIN
assets/krita/plaster_texture_1k.png
Normal file
BIN
assets/krita/plaster_texture_1k.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
41
compile
41
compile
@ -1,13 +1,44 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ "$1" = "--clean" ]; then
|
RUN_AFTER_BUILD=0
|
||||||
echo "Cleaning build directory..."
|
CMAKE_ARGS=""
|
||||||
rm -rf build/*
|
BINARY_NAME="opengl_test"
|
||||||
fi
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--clean)
|
||||||
|
echo "Cleaning build directory..."
|
||||||
|
rm -rf build/*
|
||||||
|
;;
|
||||||
|
--debug)
|
||||||
|
echo "Enabling debug build..."
|
||||||
|
CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug"
|
||||||
|
;;
|
||||||
|
--run)
|
||||||
|
RUN_AFTER_BUILD=1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown argument: $arg"
|
||||||
|
echo "Usage: $0 [--clean] [--debug] [--run]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
|
||||||
(
|
(
|
||||||
cd build || exit 1
|
cd build || exit 1
|
||||||
cmake ..
|
cmake .. $CMAKE_ARGS
|
||||||
make
|
make
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if [ "$RUN_AFTER_BUILD" -eq 1 ]; then
|
||||||
|
if [ -x "build/$BINARY_NAME" ]; then
|
||||||
|
echo "Running ./$BINARY_NAME..."
|
||||||
|
"./build/$BINARY_NAME"
|
||||||
|
else
|
||||||
|
echo "Error: Binary 'build/$BINARY_NAME' not found or not executable."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|||||||
311
include/KHR/khrplatform.h
Normal file
311
include/KHR/khrplatform.h
Normal file
@ -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_ */
|
||||||
15914
include/glad/glad.h
Normal file
15914
include/glad/glad.h
Normal file
File diff suppressed because one or more lines are too long
@ -1,12 +1,129 @@
|
|||||||
#version 330
|
#version 460 core
|
||||||
|
|
||||||
in vec4 vertex_color;
|
in vec4 vertex_color;
|
||||||
in vec2 texture_coord;
|
in vec2 texture_coord;
|
||||||
|
in vec3 normal;
|
||||||
|
in vec3 frag_pos;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
// Must match the same as in math.h
|
||||||
|
const int MAX_POINT_LIGHTS = 3;
|
||||||
|
const int MAX_SPOT_LIGHTS = 3;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
vec3 color;
|
||||||
|
float ambient_intensity;
|
||||||
|
float diffuse_intensity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Directional_Light {
|
||||||
|
Light light;
|
||||||
|
vec3 direction;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Point_Light {
|
||||||
|
Light light;
|
||||||
|
vec3 position;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float exponent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Spot_Light {
|
||||||
|
Point_Light point_light;
|
||||||
|
|
||||||
|
vec3 direction;
|
||||||
|
float edge;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
float shininess;
|
||||||
|
float specular_intensity;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uniform Directional_Light sun;
|
||||||
|
uniform Point_Light point_lights[MAX_POINT_LIGHTS];
|
||||||
|
uniform Spot_Light spot_lights[MAX_SPOT_LIGHTS];
|
||||||
|
|
||||||
|
uniform int point_light_count;
|
||||||
|
uniform int spot_light_count;
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
uniform Material material;
|
||||||
|
uniform vec3 eye_position;
|
||||||
|
|
||||||
|
vec4 calculate_light_by_direction(Light light, vec3 direction) {
|
||||||
|
vec4 ambient_color = vec4(light.color, 1.0f) * light.ambient_intensity;
|
||||||
|
|
||||||
|
float diffuse_factor = max(dot(normalize(normal), normalize(direction)), 0.0f);
|
||||||
|
vec4 diffuse_color = vec4(light.color * light.diffuse_intensity * diffuse_factor, 1.0f);
|
||||||
|
|
||||||
|
vec4 specular_color = vec4(0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (diffuse_factor > 0.0f) {
|
||||||
|
vec3 frag_to_eye = normalize(eye_position - frag_pos);
|
||||||
|
vec3 reflected_vertex = normalize(reflect(direction, normalize(normal)));
|
||||||
|
float specular_factor = dot(frag_to_eye, reflected_vertex);
|
||||||
|
|
||||||
|
if (specular_factor > 0.0f) {
|
||||||
|
specular_factor = pow(specular_factor, material.shininess);
|
||||||
|
specular_color = vec4(light.color * material.specular_intensity * specular_factor, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ambient_color + diffuse_color + specular_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 calculate_point_light(Point_Light point_light) {
|
||||||
|
vec3 direction = frag_pos - point_light.position;
|
||||||
|
float distance = length(direction);
|
||||||
|
direction = normalize(direction);
|
||||||
|
|
||||||
|
vec4 light_color = calculate_light_by_direction(point_light.light, direction);
|
||||||
|
float attentuation = point_light.exponent * distance * distance + point_light.linear * distance + point_light.constant;
|
||||||
|
|
||||||
|
return (light_color / attentuation);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 calculate_point_lights() {
|
||||||
|
vec4 final_color = vec4(0, 0, 0, 0);
|
||||||
|
|
||||||
|
for (int i=0; i<point_light_count; i++) {
|
||||||
|
final_color += calculate_point_light(point_lights[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 calculate_spot_light(Spot_Light spot_light) {
|
||||||
|
vec3 ray_direction = normalize(frag_pos - spot_light.point_light.position);
|
||||||
|
float spot_light_factor = dot(ray_direction, spot_light.direction);
|
||||||
|
|
||||||
|
if (spot_light_factor > spot_light.edge) {
|
||||||
|
vec4 light_color = calculate_point_light(spot_light.point_light);
|
||||||
|
|
||||||
|
return light_color * (1.0f - (1.0f - spot_light_factor)*(1.0f/(1.0f - spot_light.edge)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 calculate_spot_lights() {
|
||||||
|
vec4 final_color = vec4(0, 0, 0, 0);
|
||||||
|
|
||||||
|
for (int i=0; i<spot_light_count; i++) {
|
||||||
|
final_color += calculate_spot_light(spot_lights[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = texture(tex, texture_coord);
|
vec4 final_color = calculate_light_by_direction(sun.light, sun.direction);
|
||||||
|
|
||||||
|
final_color += calculate_point_lights();
|
||||||
|
final_color += calculate_spot_lights();
|
||||||
|
|
||||||
|
color = texture(tex, texture_coord) * final_color;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
#version 330
|
#version 460 core
|
||||||
|
|
||||||
layout (location = 0) in vec3 pos;
|
layout (location = 0) in vec3 pos;
|
||||||
layout (location = 1) in vec2 tex;
|
layout (location = 1) in vec2 tex;
|
||||||
|
layout (location = 2) in vec3 norm;
|
||||||
|
|
||||||
out vec4 vertex_color;
|
out vec4 vertex_color;
|
||||||
out vec2 texture_coord;
|
out vec2 texture_coord;
|
||||||
|
out vec3 normal;
|
||||||
|
out vec3 frag_pos;
|
||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
@ -14,4 +17,6 @@ void main() {
|
|||||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||||
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||||
texture_coord = tex;
|
texture_coord = tex;
|
||||||
|
normal = mat3(transpose(inverse(model))) * norm;
|
||||||
|
frag_pos = (model * vec4(pos, 1.0)).xyz;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
Camera::Camera(Vector3 position, Vector3 world_up, f32 yaw, f32 pitch, f32 movement_speed, f32 rotation_speed) : position(position), world_up(world_up), yaw(yaw), pitch(pitch), movement_speed(movement_speed), rotation_speed(rotation_speed) {
|
|
||||||
update_camera(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_camera(Camera *camera) {
|
void update_camera(Camera *camera) {
|
||||||
Vector3 new_front = Vector3(
|
Vector3 new_front = Vector3(
|
||||||
cos(glm::radians(camera->yaw)) * cos(glm::radians(camera->pitch)),
|
cos(glm::radians(camera->yaw)) * cos(glm::radians(camera->pitch)),
|
||||||
|
|||||||
19
src/camera.h
19
src/camera.h
@ -7,19 +7,16 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
struct Camera {
|
struct Camera {
|
||||||
Vector3 position;
|
Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
Vector3 front = Vector3(0.0f, 0.0f, -1.0f);
|
Vector3 front = Vector3(0.0f, 0.0f, -1.0f);
|
||||||
Vector3 up;
|
Vector3 up = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
Vector3 right;
|
Vector3 right = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
Vector3 world_up;
|
Vector3 world_up = Vector3(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
f32 yaw;
|
f32 yaw = 90.0f;
|
||||||
f32 pitch;
|
f32 pitch = 0.0f;
|
||||||
f32 movement_speed;
|
f32 movement_speed = 5.0f;
|
||||||
f32 rotation_speed;
|
f32 rotation_speed = 1.0f;
|
||||||
|
|
||||||
Camera(Vector3 position, Vector3 up, f32 yaw, f32 pitch, f32 movement_speed, f32 rotation_speed);
|
|
||||||
~Camera() = default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void update_camera(Camera *camera);
|
void update_camera(Camera *camera);
|
||||||
|
|||||||
36
src/colors.h
Normal file
36
src/colors.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
namespace Color {
|
||||||
|
constexpr Vector3 WHITE {1.0f, 1.0f, 1.0f};
|
||||||
|
constexpr Vector3 BLACK {0.0f, 0.0f, 0.0f};
|
||||||
|
constexpr Vector3 GRAY {0.5f, 0.5f, 0.5f};
|
||||||
|
constexpr Vector3 LIGHT_GRAY {0.75f, 0.75f, 0.75f};
|
||||||
|
constexpr Vector3 DARK_GRAY {0.25f, 0.25f, 0.25f};
|
||||||
|
|
||||||
|
constexpr Vector3 RED {1.0f, 0.0f, 0.0f};
|
||||||
|
constexpr Vector3 GREEN {0.0f, 1.0f, 0.0f};
|
||||||
|
constexpr Vector3 BLUE {0.0f, 0.0f, 1.0f};
|
||||||
|
|
||||||
|
constexpr Vector3 CYAN {0.0f, 1.0f, 1.0f};
|
||||||
|
constexpr Vector3 MAGENTA {1.0f, 0.0f, 1.0f};
|
||||||
|
constexpr Vector3 YELLOW {1.0f, 1.0f, 0.0f};
|
||||||
|
|
||||||
|
constexpr Vector3 ORANGE {1.0f, 0.5f, 0.0f};
|
||||||
|
constexpr Vector3 PURPLE {0.5f, 0.0f, 0.5f};
|
||||||
|
constexpr Vector3 PINK {1.0f, 0.0f, 0.5f};
|
||||||
|
constexpr Vector3 BROWN {0.6f, 0.3f, 0.0f};
|
||||||
|
|
||||||
|
constexpr Vector3 LIME {0.5f, 1.0f, 0.0f};
|
||||||
|
constexpr Vector3 TEAL {0.0f, 0.5f, 0.5f};
|
||||||
|
constexpr Vector3 NAVY {0.0f, 0.0f, 0.5f};
|
||||||
|
constexpr Vector3 OLIVE {0.5f, 0.5f, 0.0f};
|
||||||
|
constexpr Vector3 MAROON {0.5f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
constexpr Vector3 GOLD {1.0f, 0.84f, 0.0f};
|
||||||
|
constexpr Vector3 SILVER {0.75f, 0.75f, 0.75f};
|
||||||
|
constexpr Vector3 SKY_BLUE {0.53f, 0.81f, 0.92f};
|
||||||
|
constexpr Vector3 TURQUOISE {0.25f, 0.88f, 0.82f};
|
||||||
|
constexpr Vector3 INDIGO {0.29f, 0.0f, 0.51f};
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
std::string read_entire_file(const char *path) {
|
string read_entire_file(const char *path) {
|
||||||
std::string content;
|
string content;
|
||||||
std::ifstream file_stream(path, std::ios::in);
|
std::ifstream file_stream(path, std::ios::in);
|
||||||
|
|
||||||
if (!file_stream.is_open()) {
|
if (!file_stream.is_open()) {
|
||||||
@ -9,7 +9,7 @@ std::string read_entire_file(const char *path) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = "";
|
string line = "";
|
||||||
while (!file_stream.eof())
|
while (!file_stream.eof())
|
||||||
{
|
{
|
||||||
std::getline(file_stream, line);
|
std::getline(file_stream, line);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
std::string read_entire_file(const char *path);
|
string read_entire_file(const char *path);
|
||||||
|
|||||||
9436
src/glad.c
Normal file
9436
src/glad.c
Normal file
File diff suppressed because one or more lines are too long
34
src/light.h
Normal file
34
src/light.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "math.h"
|
||||||
|
#include "colors.h"
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
Vector3 color = Color::WHITE;
|
||||||
|
f32 ambient_intensity = 1.0f;
|
||||||
|
f32 diffuse_intensity = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Directional_Light : public Light {
|
||||||
|
Vector3 direction = Vector3(0.0f, -1.0f, 0.0f); // Default to down
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Point_Light : public Light {
|
||||||
|
Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
f32 constant = 1.0f;
|
||||||
|
f32 linear = 0.0f;
|
||||||
|
f32 exponent = 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Spot_Light : public Light {
|
||||||
|
Vector3 direction = Vector3(0.0f, -1.0f, 0.0f);
|
||||||
|
Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
f32 constant = 1.0f;
|
||||||
|
f32 linear = 0.0f;
|
||||||
|
f32 exponent = 0.0f;
|
||||||
|
f32 edge = 0.0f;
|
||||||
|
f32 processed_edge = 0.0f; // Don't forget to glm::radians(edge)
|
||||||
|
};
|
||||||
|
|
||||||
187
src/main.cpp
187
src/main.cpp
@ -5,30 +5,57 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
#include "light.h"
|
||||||
|
#include "material.h"
|
||||||
|
#include "colors.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *vertex_shader_code = "shaders/shader.vert";
|
|
||||||
static const char *fragment_shader_code = "shaders/shader.frag";
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Mesh *meshes[10] = {nullptr};
|
Mesh *meshes[10] = {nullptr};
|
||||||
Shader shaders[10];
|
Shader shaders[10];
|
||||||
|
|
||||||
Window window(1024, 720);
|
Window window;
|
||||||
|
window.width = 1920;
|
||||||
|
window.height = 1080;
|
||||||
bool success = setup_window(&window);
|
bool success = setup_window(&window);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
printf("Failed to setup window");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Delta
|
// Delta
|
||||||
f32 dt = 0.0f;
|
f32 dt = 0.0f;
|
||||||
f32 last_dt = 0.f;
|
f32 last_dt = 0.f;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Create a floor
|
||||||
|
f32 vertices[] = {
|
||||||
|
// x y z u v nx ny nz
|
||||||
|
-10.0f, 0.0f, -10.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
|
||||||
|
10.0f, 0.0f, -10.0f, 10.0f, 0.0f, 0.0f, -1.0f, 0.0f,
|
||||||
|
-10.0f, 0.0f, 10.0f, 0.0f, 10.0f, 0.0f, -1.0f, 0.0f,
|
||||||
|
10.0f, 0.0f, 10.0f, 10.0f, 10.0f, 0.0f, -1.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 indices[] {
|
||||||
|
0, 2, 1,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
|
||||||
|
Mesh *floor = new Mesh();
|
||||||
|
create_mesh(floor, vertices, indices, 32, 6);
|
||||||
|
meshes[0] = floor;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Create a mesh
|
// Create a mesh
|
||||||
f32 vertices[] = {
|
f32 vertices[] = {
|
||||||
// x y z u v
|
// x y z u v nx ny nz
|
||||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
|
0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 indices[] = {
|
u32 indices[] = {
|
||||||
@ -38,33 +65,102 @@ int main() {
|
|||||||
0, 1, 2
|
0, 1, 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
calculate_normals_avg(vertices, 32, 8, indices, 12, 5);
|
||||||
|
|
||||||
Mesh *pyramid1 = new Mesh();
|
Mesh *pyramid1 = new Mesh();
|
||||||
create_mesh(pyramid1, vertices, indices, 20, 12);
|
create_mesh(pyramid1, vertices, indices, 32, 12);
|
||||||
meshes[0] = pyramid1;
|
meshes[1] = pyramid1;
|
||||||
|
|
||||||
Mesh *pyramid2 = new Mesh();
|
Mesh *pyramid2 = new Mesh();
|
||||||
create_mesh(pyramid2, vertices, indices, 20, 12);
|
create_mesh(pyramid2, vertices, indices, 32, 12);
|
||||||
meshes[1] = pyramid2;
|
meshes[2] = pyramid2;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Create a shader
|
// Create a shader
|
||||||
Shader *shader = new Shader();
|
Shader *shader = new Shader();
|
||||||
create_shader(shader, vertex_shader_code, fragment_shader_code);
|
create_shader(shader, (char*)"shaders/shader.vert", (char*)"shaders/shader.frag");
|
||||||
shaders[0] = *shader;
|
shaders[0] = *shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture clay_texture = Texture((char *)"assets/textures/clay_texture_1k.png");
|
Texture clay_texture;
|
||||||
|
clay_texture.file_path = (char *)"assets/textures/clay_texture_1k.png";
|
||||||
load_texture(&clay_texture);
|
load_texture(&clay_texture);
|
||||||
|
|
||||||
Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png");
|
Texture plaster_texture;
|
||||||
|
plaster_texture.file_path = (char *)"assets/textures/plaster_texture_1k.png";
|
||||||
load_texture(&plaster_texture);
|
load_texture(&plaster_texture);
|
||||||
|
|
||||||
Matrix4 projection = glm::perspective(
|
Material shiny_material;
|
||||||
45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f,
|
shiny_material.shininess = 256.0f;
|
||||||
100.0f);
|
shiny_material.specular_intensity = 4.0f;
|
||||||
|
|
||||||
Camera camera(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f, 5.0f, 1.0f);
|
Material dull_material;
|
||||||
|
dull_material.shininess = 4.0f;
|
||||||
|
dull_material.specular_intensity = 0.3f;
|
||||||
|
|
||||||
|
Directional_Light sun_light;
|
||||||
|
sun_light.color = Color::WHITE;
|
||||||
|
sun_light.ambient_intensity = 0.3f;
|
||||||
|
sun_light.diffuse_intensity = 0.3f;
|
||||||
|
sun_light.direction = Vector3(5.0f, -1.0, -5.0f);
|
||||||
|
|
||||||
|
Point_Light point_lights[MAX_POINT_LIGHTS];
|
||||||
|
u32 point_light_count = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Point_Light point_light;
|
||||||
|
point_light.color = Color::MAGENTA;
|
||||||
|
point_light.ambient_intensity = 0.0f;
|
||||||
|
point_light.diffuse_intensity = 0.3f;
|
||||||
|
point_light.position = Vector3(10.0f, 2.0f, 0.0f);
|
||||||
|
point_light.constant = 0.3f;
|
||||||
|
point_light.linear = 0.1f;
|
||||||
|
point_light.exponent = 0.1f;
|
||||||
|
|
||||||
|
point_lights[0] = point_light;
|
||||||
|
point_light_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Point_Light point_light;
|
||||||
|
point_light.color = Color::GREEN;
|
||||||
|
point_light.ambient_intensity = 0.0f;
|
||||||
|
point_light.diffuse_intensity = 0.3f;
|
||||||
|
point_light.position = Vector3(-10.0f, 2.0f, 0.0f);
|
||||||
|
point_light.constant = 0.3f;
|
||||||
|
point_light.linear = 0.1f;
|
||||||
|
point_light.exponent = 0.1f;
|
||||||
|
|
||||||
|
point_lights[1] = point_light;
|
||||||
|
point_light_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Spot_Light spot_lights[MAX_SPOT_LIGHTS];
|
||||||
|
u32 spot_light_count = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Spot_Light spot_light;
|
||||||
|
spot_light.color = Color::BLUE;
|
||||||
|
spot_light.direction = glm::normalize(Vector3(0.0f, -1.0f, 0.0f));
|
||||||
|
spot_light.ambient_intensity = 5.0f;
|
||||||
|
spot_light.diffuse_intensity = 2.0f;
|
||||||
|
spot_light.position = Vector3(0.0f, 10.0f, 0.0f);
|
||||||
|
spot_light.constant = 1.0f;
|
||||||
|
spot_light.linear = 0.0f;
|
||||||
|
spot_light.exponent = 0.0f;
|
||||||
|
spot_light.edge = 20.0f;
|
||||||
|
spot_light.processed_edge = cosf(glm::radians(20.0f));
|
||||||
|
|
||||||
|
spot_lights[0] = spot_light;
|
||||||
|
spot_light_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4 projection = glm::perspective(45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
Camera camera;
|
||||||
|
camera.position.y = 2.0f;
|
||||||
|
update_camera(&camera);
|
||||||
|
|
||||||
|
|
||||||
// Loop until window is closed
|
// Loop until window is closed
|
||||||
@ -74,9 +170,6 @@ int main() {
|
|||||||
dt = now - last_dt;
|
dt = now - last_dt;
|
||||||
last_dt = now;
|
last_dt = now;
|
||||||
|
|
||||||
// Get and handle user input events
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
key_control(&camera, window.ascii_keys, dt);
|
key_control(&camera, window.ascii_keys, dt);
|
||||||
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
||||||
|
|
||||||
@ -90,31 +183,46 @@ int main() {
|
|||||||
|
|
||||||
glUseProgram(shaders[0].id);
|
glUseProgram(shaders[0].id);
|
||||||
|
|
||||||
{
|
use_light(&shaders[0], &sun_light);
|
||||||
Matrix4 model(1.0f);
|
use_light(&shaders[0], point_lights, point_light_count);
|
||||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
use_light(&shaders[0], spot_lights, spot_light_count);
|
||||||
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
|
||||||
|
|
||||||
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
glUniformMatrix4fv(shaders[0].projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||||
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
Matrix4 view = calculate_view_matrix(&camera);
|
||||||
use_texture(&clay_texture);
|
glUniformMatrix4fv(shaders[0].view, 1, GL_FALSE, glm::value_ptr(view));
|
||||||
|
glUniform3f(shaders[0].eye_position, camera.position.x, camera.position.y, camera.position.z);
|
||||||
|
|
||||||
|
|
||||||
|
{ // Floor
|
||||||
|
Matrix4 model(1.0f);
|
||||||
|
model = glm::translate(model, Vector3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
glUniformMatrix4fv(shaders[0].model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
use_texture(&plaster_texture);
|
||||||
|
use_material(&dull_material, shaders[0].shininess, shaders[0].specular_intensity);
|
||||||
render_mesh(meshes[0]);
|
render_mesh(meshes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{ // Prism
|
||||||
Matrix4 model(1.0f);
|
Matrix4 model(1.0f);
|
||||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -3.5f));
|
model = glm::translate(model, Vector3(0.0f, 1.0f, 0.0f));
|
||||||
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
// model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||||
|
|
||||||
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
glUniformMatrix4fv(shaders[0].model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
use_texture(&clay_texture);
|
||||||
use_texture(&plaster_texture);
|
use_material(&shiny_material, shaders[0].shininess, shaders[0].specular_intensity);
|
||||||
render_mesh(meshes[1]);
|
render_mesh(meshes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4 view = calculate_view_matrix(&camera);
|
{ // Prism
|
||||||
glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view));
|
Matrix4 model(1.0f);
|
||||||
|
model = glm::translate(model, Vector3(2.0f, 1.0f, -4.0f));
|
||||||
|
|
||||||
|
glUniformMatrix4fv(shaders[0].model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
use_texture(&clay_texture);
|
||||||
|
use_material(&dull_material, shaders[0].shininess, shaders[0].specular_intensity);
|
||||||
|
render_mesh(meshes[2]);
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
@ -125,6 +233,9 @@ int main() {
|
|||||||
// that it now shows. We then can start drawing on the other
|
// that it now shows. We then can start drawing on the other
|
||||||
// buffer.
|
// buffer.
|
||||||
glfwSwapBuffers(window.gl_window);
|
glfwSwapBuffers(window.gl_window);
|
||||||
|
|
||||||
|
// Get and handle user input events
|
||||||
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
8
src/material.cpp
Normal file
8
src/material.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "material.h"
|
||||||
|
|
||||||
|
|
||||||
|
void use_material(Material *material, u32 shininess_location, u32 specular_intensity_location) {
|
||||||
|
glUniform1f(shininess_location, material->shininess);
|
||||||
|
glUniform1f(specular_intensity_location, material->specular_intensity);
|
||||||
|
}
|
||||||
|
|
||||||
14
src/material.h
Normal file
14
src/material.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
The kind of a thing
|
||||||
|
*/
|
||||||
|
struct Material {
|
||||||
|
f32 shininess = 2.0f;
|
||||||
|
f32 specular_intensity = 0.2f;
|
||||||
|
};
|
||||||
|
|
||||||
|
void use_material(Material *material, u32 shininess_location, u32 specular_intensity_location);
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
// #include <cstdint>
|
||||||
|
#include <string>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
@ -34,5 +35,8 @@ typedef double f64;
|
|||||||
|
|
||||||
using Matrix4 = glm::mat4;
|
using Matrix4 = glm::mat4;
|
||||||
using Vector3 = glm::vec3;
|
using Vector3 = glm::vec3;
|
||||||
|
using string = std::string;
|
||||||
|
|
||||||
const f32 RADIAN_FACTOR = 3.14159265f / 180.0f;
|
const f32 RADIAN_FACTOR = 3.14159265f / 180.0f;
|
||||||
|
const u32 MAX_POINT_LIGHTS = 3;
|
||||||
|
const u32 MAX_SPOT_LIGHTS = 3;
|
||||||
|
|||||||
55
src/mesh.cpp
55
src/mesh.cpp
@ -32,13 +32,16 @@ void create_mesh(
|
|||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices_count, vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices_count, vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
// Position vertices
|
// Position vertices
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, 0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, 0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, (void *)(sizeof(vertices[0]) * 3));
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 3));
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 5));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
// Unbinding
|
// Unbinding
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
@ -73,3 +76,51 @@ void clear_mesh(Mesh *mesh) {
|
|||||||
|
|
||||||
mesh->index_count = 0;
|
mesh->index_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void calculate_normals_avg(f32 *vertices, u32 vertices_count, u32 vertices_length, u32 *indices, u32 indices_count, u32 normal_offset) {
|
||||||
|
for (size_t i = 0; i< indices_count; i+=3) {
|
||||||
|
u32 in0 = indices[i] * vertices_length;
|
||||||
|
u32 in1 = indices[i+1] * vertices_length;
|
||||||
|
u32 in2 = indices[i+2] * vertices_length;
|
||||||
|
|
||||||
|
Vector3 v1;
|
||||||
|
v1.x = vertices[in1] - vertices[in0];
|
||||||
|
v1.y = vertices[in1+1] - vertices[in0+1];
|
||||||
|
v1.z = vertices[in1+2] - vertices[in0+2];
|
||||||
|
|
||||||
|
Vector3 v2;
|
||||||
|
v2.x = vertices[in2] - vertices[in0];
|
||||||
|
v2.y = vertices[in2+1] - vertices[in0+1];
|
||||||
|
v2.z = vertices[in2+2] - vertices[in0+2];
|
||||||
|
|
||||||
|
Vector3 normal = glm::cross(v1, v2);
|
||||||
|
normal = glm::normalize(normal);
|
||||||
|
|
||||||
|
in0 += normal_offset;
|
||||||
|
in1 += normal_offset;
|
||||||
|
in2 += normal_offset;
|
||||||
|
|
||||||
|
vertices[in0] += normal.x;
|
||||||
|
vertices[in0+1] += normal.y;
|
||||||
|
vertices[in0+2] += normal.z;
|
||||||
|
|
||||||
|
vertices[in1] += normal.x;
|
||||||
|
vertices[in1+1] += normal.y;
|
||||||
|
vertices[in1+2] += normal.z;
|
||||||
|
|
||||||
|
vertices[in2] += normal.x;
|
||||||
|
vertices[in2+1] += normal.y;
|
||||||
|
vertices[in2+2] += normal.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i=0; i<vertices_count/vertices_length; i++) {
|
||||||
|
u32 n_offset = i * vertices_length + normal_offset;
|
||||||
|
Vector3 vector(vertices[n_offset], vertices[n_offset+1], vertices[n_offset+2]);
|
||||||
|
vector = glm::normalize(vector);
|
||||||
|
|
||||||
|
vertices[n_offset] = vector.x;
|
||||||
|
vertices[n_offset+1] = vector.y;
|
||||||
|
vertices[n_offset+2] = vector.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,9 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
The shape of a thing
|
||||||
|
*/
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
u32 VAO, VBO, IBO;
|
u32 VAO, VBO, IBO;
|
||||||
u32 index_count;
|
u32 index_count;
|
||||||
@ -14,4 +17,5 @@ struct Mesh {
|
|||||||
void create_mesh(Mesh *mesh, f32 *vertices, u32 *indices, u32 vertices_count, u32 indices_count);
|
void create_mesh(Mesh *mesh, f32 *vertices, u32 *indices, u32 vertices_count, u32 indices_count);
|
||||||
void render_mesh(Mesh *mesh);
|
void render_mesh(Mesh *mesh);
|
||||||
void clear_mesh(Mesh *mesh);
|
void clear_mesh(Mesh *mesh);
|
||||||
|
void calculate_normals_avg(f32 *vertices, u32 vertices_count, u32 vertices_length, u32 *indices, u32 indices_count, u32 normal_offset);
|
||||||
|
|
||||||
|
|||||||
128
src/shader.cpp
128
src/shader.cpp
@ -1,18 +1,14 @@
|
|||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
Shader::Shader() {
|
|
||||||
id = 0;
|
|
||||||
uniform_projection = 0;
|
|
||||||
uniform_model = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader::~Shader() {
|
Shader::~Shader() {
|
||||||
clear_shader(this);
|
clear_shader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) {
|
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) {
|
||||||
std::string vertex_shader_code = read_entire_file(vertex_shader_path);
|
string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||||
std::string fragment_shader_code = read_entire_file(fragment_shader_path);
|
string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||||
|
|
||||||
|
|
||||||
shader->id = glCreateProgram();
|
shader->id = glCreateProgram();
|
||||||
@ -47,7 +43,7 @@ bool create_shader(Shader *shader, const char *vertex_shader_path, const char *f
|
|||||||
glGetProgramiv(shader->id, GL_LINK_STATUS, &result);
|
glGetProgramiv(shader->id, GL_LINK_STATUS, &result);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
glGetProgramInfoLog(shader->id, sizeof(errors), nullptr, errors);
|
||||||
printf("Error linking shader: '%s'\n", errors);
|
printf("Error linking shader: '%s'\n", errors);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -56,14 +52,71 @@ bool create_shader(Shader *shader, const char *vertex_shader_path, const char *f
|
|||||||
glGetProgramiv(shader->id, GL_VALIDATE_STATUS, &result);
|
glGetProgramiv(shader->id, GL_VALIDATE_STATUS, &result);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
glGetProgramInfoLog(shader->id, sizeof(errors), nullptr, errors);
|
||||||
printf("Error validating shader: '%s'\n", errors);
|
printf("Error validating shader: '%s'\n", errors);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
|
shader->projection = glGetUniformLocation(shader->id, "projection");
|
||||||
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
shader->model = glGetUniformLocation(shader->id, "model");
|
||||||
shader->uniform_view = glGetUniformLocation(shader->id, "view");
|
shader->view = glGetUniformLocation(shader->id, "view");
|
||||||
|
shader->eye_position = glGetUniformLocation(shader->id, "eye_position");
|
||||||
|
|
||||||
|
shader->directional_light.color = glGetUniformLocation(shader->id, "sun.light.color");
|
||||||
|
shader->directional_light.ambient_intensity = glGetUniformLocation(shader->id, "sun.light.ambient_intensity");
|
||||||
|
shader->directional_light.diffuse_intensity = glGetUniformLocation(shader->id, "sun.light.diffuse_intensity");
|
||||||
|
shader->directional_light.direction = glGetUniformLocation(shader->id, "sun.direction");
|
||||||
|
|
||||||
|
shader->shininess = glGetUniformLocation(shader->id, "material.shininess");
|
||||||
|
shader->specular_intensity = glGetUniformLocation(shader->id, "material.specular_intensity");
|
||||||
|
|
||||||
|
shader->point_light_count = glGetUniformLocation(shader->id, "point_light_count");
|
||||||
|
shader->spot_light_count = glGetUniformLocation(shader->id, "spot_light_count");
|
||||||
|
|
||||||
|
// Point lights
|
||||||
|
for (size_t i=0; i<MAX_POINT_LIGHTS; i++) {
|
||||||
|
char location_buffer[100] = {"\0"};
|
||||||
|
|
||||||
|
// Common
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].light.color", i);
|
||||||
|
shader->point_lights[i].color = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].light.ambient_intensity", i);
|
||||||
|
shader->point_lights[i].ambient_intensity = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].light.diffuse_intensity", i);
|
||||||
|
shader->point_lights[i].diffuse_intensity = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].position", i);
|
||||||
|
shader->point_lights[i].position = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].constant", i);
|
||||||
|
shader->point_lights[i].constant = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "point_lights[%zu].constant", i);
|
||||||
|
shader->point_lights[i].constant = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spot lights
|
||||||
|
for (size_t i=0; i<MAX_SPOT_LIGHTS; i++) {
|
||||||
|
char location_buffer[100] = {"\0"};
|
||||||
|
|
||||||
|
// Common
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.light.color", i);
|
||||||
|
shader->spot_lights[i].color = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.light.ambient_intensity", i);
|
||||||
|
shader->spot_lights[i].ambient_intensity = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.light.diffuse_intensity", i);
|
||||||
|
shader->spot_lights[i].diffuse_intensity = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.position", i);
|
||||||
|
shader->spot_lights[i].position = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.constant", i);
|
||||||
|
shader->spot_lights[i].constant = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].point_light.constant", i);
|
||||||
|
shader->spot_lights[i].constant = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].direction", i);
|
||||||
|
shader->spot_lights[i].direction = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
snprintf(location_buffer, sizeof(location_buffer), "spot_lights[%zu].edge", i);
|
||||||
|
shader->spot_lights[i].edge = glGetUniformLocation(shader->id, location_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -85,7 +138,7 @@ bool add_shader(Shader *shader, const char *shader_code, Shader_Type shader_type
|
|||||||
|
|
||||||
glGetShaderiv(_shader, GL_COMPILE_STATUS, &result);
|
glGetShaderiv(_shader, GL_COMPILE_STATUS, &result);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
glGetShaderInfoLog(_shader, sizeof(errors), NULL, errors);
|
glGetShaderInfoLog(_shader, sizeof(errors), nullptr, errors);
|
||||||
printf("Error compiling the %d shader->id: '%s'\n", shader_type, errors);
|
printf("Error compiling the %d shader->id: '%s'\n", shader_type, errors);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -101,7 +154,52 @@ void clear_shader(Shader *shader) {
|
|||||||
shader->id = 0;
|
shader->id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->uniform_model = 0;
|
shader->model = 0;
|
||||||
shader->uniform_projection = 0;
|
shader->projection = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void use_light(Shader *shader, Directional_Light *light) {
|
||||||
|
glUniform3f(shader->directional_light.color, light->color.x, light->color.y, light->color.z);
|
||||||
|
glUniform1f(shader->directional_light.ambient_intensity, light->ambient_intensity);
|
||||||
|
|
||||||
|
glUniform3f(shader->directional_light.direction, light->direction.x, light->direction.y, light->direction.z);
|
||||||
|
glUniform1f(shader->directional_light.diffuse_intensity, light->diffuse_intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void use_light(Shader *shader, Point_Light *point_lights, u32 point_light_count) {
|
||||||
|
if (point_light_count > MAX_POINT_LIGHTS) point_light_count = MAX_POINT_LIGHTS;
|
||||||
|
|
||||||
|
glUniform1i(shader->point_light_count, point_light_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < point_light_count; i++) {
|
||||||
|
glUniform3f(shader->point_lights[i].color, point_lights[i].color.x, point_lights[i].color.y, point_lights[i].color.z);
|
||||||
|
glUniform1f(shader->point_lights[i].ambient_intensity, point_lights[i].ambient_intensity);
|
||||||
|
glUniform1f(shader->point_lights[i].diffuse_intensity, point_lights[i].diffuse_intensity);
|
||||||
|
|
||||||
|
glUniform3f(shader->point_lights[i].position, point_lights[i].position.x, point_lights[i].position.y, point_lights[i].position.z);
|
||||||
|
glUniform1f(shader->point_lights[i].constant, point_lights[i].constant);
|
||||||
|
glUniform1f(shader->point_lights[i].linear, point_lights[i].linear);
|
||||||
|
glUniform1f(shader->point_lights[i].exponent, point_lights[i].exponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void use_light(Shader *shader, Spot_Light *spot_lights, u32 spot_light_count) {
|
||||||
|
if (spot_light_count > MAX_SPOT_LIGHTS) spot_light_count = MAX_SPOT_LIGHTS;
|
||||||
|
|
||||||
|
glUniform1i(shader->spot_light_count, spot_light_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < spot_light_count; i++) {
|
||||||
|
glUniform3f(shader->spot_lights[i].color, spot_lights[i].color.x, spot_lights[i].color.y, spot_lights[i].color.z);
|
||||||
|
glUniform1f(shader->spot_lights[i].ambient_intensity, spot_lights[i].ambient_intensity);
|
||||||
|
glUniform1f(shader->spot_lights[i].diffuse_intensity, spot_lights[i].diffuse_intensity);
|
||||||
|
|
||||||
|
glUniform3f(shader->spot_lights[i].position, spot_lights[i].position.x, spot_lights[i].position.y, spot_lights[i].position.z);
|
||||||
|
glUniform1f(shader->spot_lights[i].constant, spot_lights[i].constant);
|
||||||
|
glUniform1f(shader->spot_lights[i].linear, spot_lights[i].linear);
|
||||||
|
glUniform1f(shader->spot_lights[i].exponent, spot_lights[i].exponent);
|
||||||
|
|
||||||
|
glUniform3f(shader->spot_lights[i].direction, spot_lights[i].direction.x, spot_lights[i].direction.y, spot_lights[i].direction.z);
|
||||||
|
glUniform1f(shader->spot_lights[i].edge, spot_lights[i].processed_edge);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
60
src/shader.h
60
src/shader.h
@ -3,7 +3,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "file.h"
|
#include "light.h"
|
||||||
|
|
||||||
enum Shader_Type : u32 {
|
enum Shader_Type : u32 {
|
||||||
VERTEX = GL_VERTEX_SHADER,
|
VERTEX = GL_VERTEX_SHADER,
|
||||||
@ -11,15 +11,63 @@ enum Shader_Type : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
u32 id;
|
u32 id = 0;
|
||||||
u32 uniform_projection;
|
|
||||||
u32 uniform_model;
|
u32 projection = 0;
|
||||||
u32 uniform_view;
|
u32 model = 0;
|
||||||
|
u32 view = 0;
|
||||||
|
u32 eye_position = 0;
|
||||||
|
u32 shininess = 0;
|
||||||
|
u32 specular_intensity = 0;
|
||||||
|
u32 position = 0;
|
||||||
|
u32 constant = 0;
|
||||||
|
u32 linear = 0;
|
||||||
|
u32 exponent = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 color;
|
||||||
|
u32 ambient_intensity;
|
||||||
|
u32 diffuse_intensity;
|
||||||
|
|
||||||
|
u32 direction;
|
||||||
|
} directional_light;
|
||||||
|
|
||||||
|
u32 point_light_count = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 color;
|
||||||
|
u32 ambient_intensity;
|
||||||
|
u32 diffuse_intensity;
|
||||||
|
|
||||||
|
u32 position;
|
||||||
|
u32 constant;
|
||||||
|
u32 linear;
|
||||||
|
u32 exponent;
|
||||||
|
} point_lights[MAX_POINT_LIGHTS];
|
||||||
|
|
||||||
|
u32 spot_light_count = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 color;
|
||||||
|
u32 ambient_intensity;
|
||||||
|
u32 diffuse_intensity;
|
||||||
|
|
||||||
|
u32 position;
|
||||||
|
u32 constant;
|
||||||
|
u32 linear;
|
||||||
|
u32 exponent;
|
||||||
|
|
||||||
|
u32 direction;
|
||||||
|
u32 edge;
|
||||||
|
} spot_lights[MAX_SPOT_LIGHTS];
|
||||||
|
|
||||||
Shader();
|
|
||||||
~Shader();
|
~Shader();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path);
|
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path);
|
||||||
bool add_shader(Shader *shader, const char *shader_code, Shader_Type type);
|
bool add_shader(Shader *shader, const char *shader_code, Shader_Type type);
|
||||||
void clear_shader(Shader *shader);
|
void clear_shader(Shader *shader);
|
||||||
|
|
||||||
|
void use_light(Shader *shader, Directional_Light *light);
|
||||||
|
void use_light(Shader *shader, Point_Light *light, u32 point_light_count);
|
||||||
|
void use_light(Shader *shader, Spot_Light *light, u32 point_light_count);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
Texture::Texture(char *file_path) : file_path(file_path) {}
|
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
clear_texture(this);
|
clear_texture(this);
|
||||||
@ -44,6 +43,6 @@ void clear_texture(Texture *texture) {
|
|||||||
texture->width = 0;
|
texture->width = 0;
|
||||||
texture->height = 0;
|
texture->height = 0;
|
||||||
texture->bit_depth = 0;
|
texture->bit_depth = 0;
|
||||||
texture->file_path = NULL;
|
texture->file_path = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
#include <stb_image.h>
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "../lib/stb_image.h"
|
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int bit_depth = 0;
|
int bit_depth = 0;
|
||||||
char *file_path;
|
char *file_path = nullptr;
|
||||||
|
|
||||||
Texture(char *file_path);
|
|
||||||
~Texture();
|
~Texture();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,6 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Window::Window(u32 window_width, u32 window_height) {
|
|
||||||
width = window_width;
|
|
||||||
height = window_height;
|
|
||||||
x_change_position = 0.0f;
|
|
||||||
y_change_position = 0.0f;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 1024; i++) {
|
|
||||||
ascii_keys[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
glfwDestroyWindow(gl_window);
|
glfwDestroyWindow(gl_window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@ -36,7 +24,7 @@ bool setup_window(Window *window) {
|
|||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
|
||||||
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", NULL, NULL);
|
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", nullptr, nullptr);
|
||||||
|
|
||||||
if (!window->gl_window) {
|
if (!window->gl_window) {
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
|||||||
17
src/window.h
17
src/window.h
@ -9,19 +9,18 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
u32 width = 800, height = 600;
|
u32 width = 1024, height = 768;
|
||||||
s32 buffer_width, buffer_height;
|
s32 buffer_width = 0, buffer_height = 0;
|
||||||
GLFWwindow *gl_window = nullptr;
|
GLFWwindow *gl_window = nullptr;
|
||||||
bool ascii_keys[1024];
|
bool ascii_keys[1024] = {false};
|
||||||
|
|
||||||
// Camera coords
|
// Camera coords
|
||||||
f32 last_x_position;
|
f32 last_x_position = 0.0f;
|
||||||
f32 last_y_position;
|
f32 last_y_position = 0.0f;
|
||||||
f32 x_change_position;
|
f32 x_change_position = 0.0f;
|
||||||
f32 y_change_position;
|
f32 y_change_position = 0.0f;
|
||||||
bool first_mouse_movement;
|
bool first_mouse_movement = true;
|
||||||
|
|
||||||
Window(u32 window_width, u32 window_height);
|
|
||||||
~Window();
|
~Window();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user