Compare commits

...

10 Commits

30 changed files with 26321 additions and 119 deletions

3
.gitignore vendored
View File

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

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

41
compile
View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

34
src/light.h Normal file
View 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)
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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