Compare commits
10 Commits
5adc6e80e6
...
799f21dfc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
799f21dfc1 | ||
|
|
3c398f0308 | ||
| 3c413c70b9 | |||
| 62a4b739dd | |||
| c6ae576289 | |||
| 908232c31e | |||
| d398f3a1d9 | |||
| af612fbfe9 | |||
| 860ea04cfb | |||
| c746f1d8eb |
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
build/
|
||||
cmake-build-*/
|
||||
out/
|
||||
.cache/
|
||||
|
||||
# CMake generated files
|
||||
CMakeFiles/
|
||||
@ -19,4 +20,4 @@ Makefile
|
||||
# Other temporary files
|
||||
*.log
|
||||
*.tmp
|
||||
*.swp
|
||||
*.swp
|
||||
|
||||
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.19)
|
||||
project(OpenGLTest CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
@ -11,6 +12,7 @@ find_package(glfw3 REQUIRED)
|
||||
file(GLOB SOURCES src/*.h src/*.cpp)
|
||||
add_executable(opengl_test ${SOURCES})
|
||||
|
||||
target_include_directories(opengl_test PUBLIC include)
|
||||
target_link_libraries(opengl_test
|
||||
OpenGL::GL
|
||||
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
|
||||
|
||||
if [ "$1" = "--clean" ]; then
|
||||
echo "Cleaning build directory..."
|
||||
rm -rf build/*
|
||||
fi
|
||||
RUN_AFTER_BUILD=0
|
||||
CMAKE_ARGS=""
|
||||
BINARY_NAME="opengl_test"
|
||||
|
||||
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
|
||||
cmake ..
|
||||
cmake .. $CMAKE_ARGS
|
||||
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 vec2 texture_coord;
|
||||
in vec3 normal;
|
||||
in vec3 frag_pos;
|
||||
|
||||
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 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() {
|
||||
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 = 1) in vec2 tex;
|
||||
layout (location = 2) in vec3 norm;
|
||||
|
||||
out vec4 vertex_color;
|
||||
out vec2 texture_coord;
|
||||
out vec3 normal;
|
||||
out vec3 frag_pos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 model;
|
||||
@ -14,4 +17,6 @@ void main() {
|
||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||
texture_coord = tex;
|
||||
normal = mat3(transpose(inverse(model))) * norm;
|
||||
frag_pos = (model * vec4(pos, 1.0)).xyz;
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
#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) {
|
||||
Vector3 new_front = Vector3(
|
||||
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"
|
||||
|
||||
struct Camera {
|
||||
Vector3 position;
|
||||
Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
|
||||
Vector3 front = Vector3(0.0f, 0.0f, -1.0f);
|
||||
Vector3 up;
|
||||
Vector3 right;
|
||||
Vector3 world_up;
|
||||
Vector3 up = Vector3(0.0f, 0.0f, 0.0f);
|
||||
Vector3 right = Vector3(0.0f, 0.0f, 0.0f);
|
||||
Vector3 world_up = Vector3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
f32 yaw;
|
||||
f32 pitch;
|
||||
f32 movement_speed;
|
||||
f32 rotation_speed;
|
||||
|
||||
Camera(Vector3 position, Vector3 up, f32 yaw, f32 pitch, f32 movement_speed, f32 rotation_speed);
|
||||
~Camera() = default;
|
||||
f32 yaw = 90.0f;
|
||||
f32 pitch = 0.0f;
|
||||
f32 movement_speed = 5.0f;
|
||||
f32 rotation_speed = 1.0f;
|
||||
};
|
||||
|
||||
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"
|
||||
|
||||
std::string read_entire_file(const char *path) {
|
||||
std::string content;
|
||||
string read_entire_file(const char *path) {
|
||||
string content;
|
||||
std::ifstream file_stream(path, std::ios::in);
|
||||
|
||||
if (!file_stream.is_open()) {
|
||||
@ -9,7 +9,7 @@ std::string read_entire_file(const char *path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string line = "";
|
||||
string line = "";
|
||||
while (!file_stream.eof())
|
||||
{
|
||||
std::getline(file_stream, line);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#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 "camera.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() {
|
||||
Mesh *meshes[10] = {nullptr};
|
||||
Shader shaders[10];
|
||||
|
||||
Window window(1024, 720);
|
||||
Window window;
|
||||
window.width = 1920;
|
||||
window.height = 1080;
|
||||
bool success = setup_window(&window);
|
||||
|
||||
if (!success) {
|
||||
printf("Failed to setup window");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Delta
|
||||
f32 dt = 0.0f;
|
||||
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
|
||||
f32 vertices[] = {
|
||||
// x y z u v
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
// x y z u v nx ny nz
|
||||
-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, 0.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, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
u32 indices[] = {
|
||||
@ -38,33 +65,102 @@ int main() {
|
||||
0, 1, 2
|
||||
};
|
||||
|
||||
calculate_normals_avg(vertices, 32, 8, indices, 12, 5);
|
||||
|
||||
Mesh *pyramid1 = new Mesh();
|
||||
create_mesh(pyramid1, vertices, indices, 20, 12);
|
||||
meshes[0] = pyramid1;
|
||||
create_mesh(pyramid1, vertices, indices, 32, 12);
|
||||
meshes[1] = pyramid1;
|
||||
|
||||
Mesh *pyramid2 = new Mesh();
|
||||
create_mesh(pyramid2, vertices, indices, 20, 12);
|
||||
meshes[1] = pyramid2;
|
||||
create_mesh(pyramid2, vertices, indices, 32, 12);
|
||||
meshes[2] = pyramid2;
|
||||
}
|
||||
|
||||
{
|
||||
// Create a 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
Matrix4 projection = glm::perspective(
|
||||
45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f,
|
||||
100.0f);
|
||||
Material shiny_material;
|
||||
shiny_material.shininess = 256.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
|
||||
@ -74,9 +170,6 @@ int main() {
|
||||
dt = now - last_dt;
|
||||
last_dt = now;
|
||||
|
||||
// Get and handle user input events
|
||||
glfwPollEvents();
|
||||
|
||||
key_control(&camera, window.ascii_keys, dt);
|
||||
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
||||
|
||||
@ -90,31 +183,46 @@ int main() {
|
||||
|
||||
glUseProgram(shaders[0].id);
|
||||
|
||||
{
|
||||
Matrix4 model(1.0f);
|
||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
||||
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||
use_light(&shaders[0], &sun_light);
|
||||
use_light(&shaders[0], point_lights, point_light_count);
|
||||
use_light(&shaders[0], spot_lights, spot_light_count);
|
||||
|
||||
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
||||
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
use_texture(&clay_texture);
|
||||
glUniformMatrix4fv(shaders[0].projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
Matrix4 view = calculate_view_matrix(&camera);
|
||||
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]);
|
||||
}
|
||||
|
||||
{
|
||||
{ // Prism
|
||||
Matrix4 model(1.0f);
|
||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -3.5f));
|
||||
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||
model = glm::translate(model, Vector3(0.0f, 1.0f, 0.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].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
use_texture(&plaster_texture);
|
||||
glUniformMatrix4fv(shaders[0].model, 1, GL_FALSE, glm::value_ptr(model));
|
||||
use_texture(&clay_texture);
|
||||
use_material(&shiny_material, shaders[0].shininess, shaders[0].specular_intensity);
|
||||
render_mesh(meshes[1]);
|
||||
}
|
||||
|
||||
Matrix4 view = calculate_view_matrix(&camera);
|
||||
glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view));
|
||||
{ // Prism
|
||||
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);
|
||||
|
||||
@ -125,6 +233,9 @@ int main() {
|
||||
// that it now shows. We then can start drawing on the other
|
||||
// buffer.
|
||||
glfwSwapBuffers(window.gl_window);
|
||||
|
||||
// Get and handle user input events
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include <cstdint>
|
||||
// #include <cstdint>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@ -34,5 +35,8 @@ typedef double f64;
|
||||
|
||||
using Matrix4 = glm::mat4;
|
||||
using Vector3 = glm::vec3;
|
||||
using string = std::string;
|
||||
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// Unbinding
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@ -73,3 +76,51 @@ void clear_mesh(Mesh *mesh) {
|
||||
|
||||
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 <GL/glew.h>
|
||||
|
||||
/*
|
||||
The shape of a thing
|
||||
*/
|
||||
struct Mesh {
|
||||
u32 VAO, VBO, IBO;
|
||||
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 render_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 "file.h"
|
||||
|
||||
Shader::Shader() {
|
||||
id = 0;
|
||||
uniform_projection = 0;
|
||||
uniform_model = 0;
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
clear_shader(this);
|
||||
}
|
||||
|
||||
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);
|
||||
std::string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||
string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||
string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
if (!result) {
|
||||
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
||||
glGetProgramInfoLog(shader->id, sizeof(errors), nullptr, errors);
|
||||
printf("Error linking shader: '%s'\n", errors);
|
||||
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);
|
||||
|
||||
if (!result) {
|
||||
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
||||
glGetProgramInfoLog(shader->id, sizeof(errors), nullptr, errors);
|
||||
printf("Error validating shader: '%s'\n", errors);
|
||||
return false;
|
||||
}
|
||||
|
||||
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
|
||||
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
||||
shader->uniform_view = glGetUniformLocation(shader->id, "view");
|
||||
shader->projection = glGetUniformLocation(shader->id, "projection");
|
||||
shader->model = glGetUniformLocation(shader->id, "model");
|
||||
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;
|
||||
}
|
||||
@ -85,7 +138,7 @@ bool add_shader(Shader *shader, const char *shader_code, Shader_Type shader_type
|
||||
|
||||
glGetShaderiv(_shader, GL_COMPILE_STATUS, &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);
|
||||
return false;
|
||||
}
|
||||
@ -101,7 +154,52 @@ void clear_shader(Shader *shader) {
|
||||
shader->id = 0;
|
||||
}
|
||||
|
||||
shader->uniform_model = 0;
|
||||
shader->uniform_projection = 0;
|
||||
shader->model = 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/gl.h>
|
||||
#include "math.h"
|
||||
#include "file.h"
|
||||
#include "light.h"
|
||||
|
||||
enum Shader_Type : u32 {
|
||||
VERTEX = GL_VERTEX_SHADER,
|
||||
@ -11,15 +11,63 @@ enum Shader_Type : u32 {
|
||||
};
|
||||
|
||||
struct Shader {
|
||||
u32 id;
|
||||
u32 uniform_projection;
|
||||
u32 uniform_model;
|
||||
u32 uniform_view;
|
||||
u32 id = 0;
|
||||
|
||||
u32 projection = 0;
|
||||
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();
|
||||
};
|
||||
|
||||
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);
|
||||
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"
|
||||
|
||||
Texture::Texture(char *file_path) : file_path(file_path) {}
|
||||
|
||||
Texture::~Texture() {
|
||||
clear_texture(this);
|
||||
@ -44,6 +43,6 @@ void clear_texture(Texture *texture) {
|
||||
texture->width = 0;
|
||||
texture->height = 0;
|
||||
texture->bit_depth = 0;
|
||||
texture->file_path = NULL;
|
||||
texture->file_path = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <stb_image.h>
|
||||
#include "math.h"
|
||||
#include "../lib/stb_image.h"
|
||||
|
||||
struct Texture {
|
||||
u32 id = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int bit_depth = 0;
|
||||
char *file_path;
|
||||
char *file_path = nullptr;
|
||||
|
||||
Texture(char *file_path);
|
||||
~Texture();
|
||||
};
|
||||
|
||||
|
||||
@ -1,18 +1,6 @@
|
||||
#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() {
|
||||
glfwDestroyWindow(gl_window);
|
||||
glfwTerminate();
|
||||
@ -36,7 +24,7 @@ bool setup_window(Window *window) {
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
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) {
|
||||
const char *desc;
|
||||
|
||||
17
src/window.h
17
src/window.h
@ -9,19 +9,18 @@
|
||||
#include "math.h"
|
||||
|
||||
struct Window {
|
||||
u32 width = 800, height = 600;
|
||||
s32 buffer_width, buffer_height;
|
||||
u32 width = 1024, height = 768;
|
||||
s32 buffer_width = 0, buffer_height = 0;
|
||||
GLFWwindow *gl_window = nullptr;
|
||||
bool ascii_keys[1024];
|
||||
bool ascii_keys[1024] = {false};
|
||||
|
||||
// Camera coords
|
||||
f32 last_x_position;
|
||||
f32 last_y_position;
|
||||
f32 x_change_position;
|
||||
f32 y_change_position;
|
||||
bool first_mouse_movement;
|
||||
f32 last_x_position = 0.0f;
|
||||
f32 last_y_position = 0.0f;
|
||||
f32 x_change_position = 0.0f;
|
||||
f32 y_change_position = 0.0f;
|
||||
bool first_mouse_movement = true;
|
||||
|
||||
Window(u32 window_width, u32 window_height);
|
||||
~Window();
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user