first commit
This commit is contained in:
commit
b31e7e35e5
47 changed files with 17107 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.a
|
||||
obj/
|
||||
bin/
|
||||
build/
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "vendor/glfw"]
|
||||
path = vendor/glfw
|
||||
url = https://github.com/TheCherno/glfw
|
18
Makefile
Normal file
18
Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
premake:
|
||||
./premake5 gmake2
|
||||
|
||||
gearlib-debug: premake
|
||||
make -C build config=debug
|
||||
|
||||
run: gearlib-debug
|
||||
cd examples && ../bin/Debug/test/test
|
||||
|
||||
gearlib-release: premake
|
||||
make -C build config=release
|
||||
|
||||
install: gearlib-release
|
||||
cp include/* /usr/local/include -r
|
||||
cp bin/Release/gearlib/libgearlib.a bin/Release/glfw/libglfw.a /usr/local/lib
|
||||
|
||||
clean:
|
||||
make -C build clean
|
BIN
examples/assets/cat.png
Normal file
BIN
examples/assets/cat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 123 KiB |
BIN
examples/assets/cuddle.png
Normal file
BIN
examples/assets/cuddle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 209 KiB |
BIN
examples/assets/parrots.png
Normal file
BIN
examples/assets/parrots.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 288 KiB |
13
examples/assets/quad.frag
Normal file
13
examples/assets/quad.frag
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 460 core
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
struct VertexOutput {
|
||||
vec4 Color;
|
||||
};
|
||||
|
||||
layout(location = 0) in VertexOutput Input;
|
||||
|
||||
void main() {
|
||||
color = Input.Color;
|
||||
}
|
21
examples/assets/quad.vert
Normal file
21
examples/assets/quad.vert
Normal file
|
@ -0,0 +1,21 @@
|
|||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Color;
|
||||
|
||||
struct VertexOutput {
|
||||
vec4 Color;
|
||||
};
|
||||
|
||||
layout(location = 0) out VertexOutput Output;
|
||||
|
||||
layout(std140, binding = 0) uniform Camera {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
void main() {
|
||||
Output.Color = a_Color;
|
||||
|
||||
gl_Position = projection * view * vec4(a_Position, 1.0);
|
||||
}
|
17
examples/assets/texture.frag
Normal file
17
examples/assets/texture.frag
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 460 core
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
struct VertexOutput {
|
||||
vec4 Tint;
|
||||
vec2 TexCoord;
|
||||
};
|
||||
|
||||
layout(location = 0) in VertexOutput Input;
|
||||
layout(location = 2) in flat float TexID;
|
||||
|
||||
layout(binding = 0) uniform sampler2D textures[32];
|
||||
|
||||
void main() {
|
||||
color = texture(textures[int(TexID)], Input.TexCoord) * Input.Tint;
|
||||
}
|
27
examples/assets/texture.vert
Normal file
27
examples/assets/texture.vert
Normal file
|
@ -0,0 +1,27 @@
|
|||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
layout(location = 1) in vec4 a_Tint;
|
||||
layout(location = 2) in vec2 a_TexCoord;
|
||||
layout(location = 3) in float a_TexID;
|
||||
|
||||
struct VertexOutput {
|
||||
vec4 Tint;
|
||||
vec2 TexCoord;
|
||||
};
|
||||
|
||||
layout(location = 0) out VertexOutput Output;
|
||||
layout(location = 2) out flat float TexID;
|
||||
|
||||
layout(std140, binding = 0) uniform Camera {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
void main() {
|
||||
Output.Tint = a_Tint;
|
||||
Output.TexCoord = a_TexCoord;
|
||||
TexID = a_TexID;
|
||||
|
||||
gl_Position = projection * view * vec4(a_Position, 1.0);
|
||||
}
|
39
examples/quad.cpp
Normal file
39
examples/quad.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "textures");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
setup_quads();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
double time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLUE));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
draw_quad(vec2(10, 10), vec2(500, 500), RED);
|
||||
|
||||
flush();
|
||||
|
||||
double end_time = glfwGetTime();
|
||||
double frame_time = end_time - time;
|
||||
time = end_time;
|
||||
|
||||
double fps = 1.0 / frame_time;
|
||||
printf("frame_time: %lf fps: %lf\n", frame_time, fps);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
44
examples/test.cpp
Normal file
44
examples/test.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "test");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
enable_debugging();
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
double time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLACK));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
for(int i = 0; i < 32; i++) {
|
||||
draw_texture(cat, vec2(rand() % 600, rand() % 600), vec2(500.0f, 500.0f), WHITE);
|
||||
}
|
||||
|
||||
flush();
|
||||
|
||||
double end_time = glfwGetTime();
|
||||
double frame_time = end_time - time;
|
||||
time = end_time;
|
||||
|
||||
double fps = 1.0 / frame_time;
|
||||
printf("frame_time: %lf fps: %lf\n", frame_time, fps);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
41
examples/textures.cpp
Normal file
41
examples/textures.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "textures");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
double time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLUE));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
draw_texture(cat, vec2(250.0f, 250.0f), vec2(500.0f, 500.0f), WHITE);
|
||||
|
||||
flush();
|
||||
|
||||
double end_time = glfwGetTime();
|
||||
double frame_time = end_time - time;
|
||||
time = end_time;
|
||||
|
||||
double fps = 1.0 / frame_time;
|
||||
printf("frame_time: %lf fps: %lf\n", frame_time, fps);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
21
include/gearlib.h
Normal file
21
include/gearlib.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef __GEARLIB_H__
|
||||
#define __GEARLIB_H__
|
||||
|
||||
#define MAX_VERTICES 2500
|
||||
|
||||
#include <gearlib/slibs.h>
|
||||
#include <gearlib/colors.h>
|
||||
#include <gearlib/raymath.h>
|
||||
#include <gearlib/init.h>
|
||||
#include <gearlib/shaders.h>
|
||||
#include <gearlib/events.h>
|
||||
#include <gearlib/debugging.h>
|
||||
#include <gearlib/vertex.h>
|
||||
#include <gearlib/renderer.h>
|
||||
#include <gearlib/camera.h>
|
||||
#include <gearlib/batch.h>
|
||||
#include <gearlib/quad.h>
|
||||
#include <gearlib/textures.h>
|
||||
#include <gearlib/uniform_buffer.h>
|
||||
|
||||
#endif
|
311
include/gearlib/KHR/khrplatform.h
Normal file
311
include/gearlib/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_ */
|
39
include/gearlib/batch.h
Normal file
39
include/gearlib/batch.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef __BATCH_H__
|
||||
#define __BATCH_H__
|
||||
|
||||
#include <gearlib.h>
|
||||
#include <vector>
|
||||
|
||||
typedef struct BatchStats {
|
||||
uint32_t draw_calls;
|
||||
uint32_t total_verts;
|
||||
} BatchStats;
|
||||
|
||||
typedef struct RenderBatch {
|
||||
uint32_t vbo, vao;
|
||||
|
||||
uint32_t shader;
|
||||
|
||||
void* vertices;
|
||||
void* vertex_ptr;
|
||||
size_t vertex_size;
|
||||
uint32_t vertex_count;
|
||||
uint32_t max_vertices;
|
||||
std::vector<VertexAttrib> layout;
|
||||
|
||||
BatchStats stats;
|
||||
|
||||
void* data;
|
||||
void (*flush_callback)(struct RenderBatch*);
|
||||
} RenderBatch;
|
||||
|
||||
extern std::vector<RenderBatch*> batches;
|
||||
|
||||
RenderBatch* create_batch(size_t vert_size, uint32_t max_verts);
|
||||
void flush();
|
||||
void flush_batch(RenderBatch* batch);
|
||||
void batch_add_attrib(RenderBatch* batch, VertexAttrib attr);
|
||||
void batch_bind_attribs(RenderBatch* batch);
|
||||
bool batch_needs_flush(RenderBatch* batch, uint32_t vertex_add);
|
||||
|
||||
#endif
|
23
include/gearlib/camera.h
Normal file
23
include/gearlib/camera.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef __CAMERA_H__
|
||||
#define __CAMERA_H__
|
||||
|
||||
enum CAMERA_PROJECTION {
|
||||
CAMERA_ORTHOGRAPHIC = 0,
|
||||
CAMERA_PERSPECTIVE
|
||||
};
|
||||
|
||||
typedef struct CameraMatrices {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
} CameraMatrices;
|
||||
|
||||
typedef struct Camera {
|
||||
vec3 position;
|
||||
int projection;
|
||||
struct CameraMatrices* m;
|
||||
} Camera;
|
||||
|
||||
Camera* create_camera(vec2 pos);
|
||||
void update_camera(Camera* camera, Window window);
|
||||
|
||||
#endif
|
12
include/gearlib/colors.h
Normal file
12
include/gearlib/colors.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef __COLORS_H__
|
||||
#define __COLORS_H__
|
||||
|
||||
#define WHITE vec4(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
#define BLACK vec4(0.0f, 0.0f, 0.0f, 1.0f)
|
||||
#define RED vec4(1.0f, 0.0f, 0.0f, 1.0f)
|
||||
#define GREEN vec4(0.0f, 1.0f, 0.0f, 1.0f)
|
||||
#define BLUE vec4(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
|
||||
#define BLANK vec4(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
|
||||
#endif
|
6
include/gearlib/debugging.h
Normal file
6
include/gearlib/debugging.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __DEBUGGING_H__
|
||||
#define __DEBUGGING_H__
|
||||
|
||||
void enable_debugging();
|
||||
|
||||
#endif
|
9
include/gearlib/events.h
Normal file
9
include/gearlib/events.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef __EVENTS_H__
|
||||
#define __EVENTS_H__
|
||||
|
||||
#include <gearlib.h>
|
||||
|
||||
void framebuffer_size_callback(Window window, int width, int height);
|
||||
void process_input(Window window);
|
||||
|
||||
#endif
|
3637
include/gearlib/glad/gl.h
Normal file
3637
include/gearlib/glad/gl.h
Normal file
File diff suppressed because it is too large
Load diff
11
include/gearlib/init.h
Normal file
11
include/gearlib/init.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef __INIT_H__
|
||||
#define __INIT_H__
|
||||
|
||||
#include <gearlib/opengl.h>
|
||||
|
||||
typedef GLFWwindow* Window;
|
||||
|
||||
void init_gl(int major, int minor);
|
||||
Window create_window(int width, int height, const char* title);
|
||||
|
||||
#endif
|
7
include/gearlib/opengl.h
Normal file
7
include/gearlib/opengl.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __OPENGL_H__
|
||||
#define __OPENGL_H__
|
||||
|
||||
#include <gearlib/glad/gl.h>
|
||||
#include <gearlib/GLFW/glfw3.h>
|
||||
|
||||
#endif
|
21
include/gearlib/quad.h
Normal file
21
include/gearlib/quad.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef __QUAD_H__
|
||||
#define __QUAD_H__
|
||||
|
||||
#include <gearlib.h>
|
||||
|
||||
void setup_quads();
|
||||
void draw_quad(vec2 pos, vec2 size, vec4 color);
|
||||
void draw_quad_trans(mat4 transform, vec4 color);
|
||||
void batch_draw_quad(RenderBatch* batch, mat4 transform, vec4 color);
|
||||
RenderBatch* create_quad_batch();
|
||||
|
||||
extern RenderBatch* quad_batch;
|
||||
|
||||
typedef struct {
|
||||
vec3 Position;
|
||||
vec4 Color;
|
||||
} QuadVertex;
|
||||
|
||||
extern vec3 quad_vertex_positions[6];
|
||||
|
||||
#endif
|
2546
include/gearlib/raymath.h
Normal file
2546
include/gearlib/raymath.h
Normal file
File diff suppressed because it is too large
Load diff
8
include/gearlib/renderer.h
Normal file
8
include/gearlib/renderer.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __RENDERER_H__
|
||||
#define __RENDERER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void renderer_draw(uint32_t vao, int count);
|
||||
|
||||
#endif
|
10
include/gearlib/shaders.h
Normal file
10
include/gearlib/shaders.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef __SHADERS_H__
|
||||
#define __SHADERS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t compile_shader(const char* path, int32_t type);
|
||||
uint32_t compile_shader_text(const char* name, const char* text, int32_t type);
|
||||
uint32_t load_shader_program(uint32_t shader, ...);
|
||||
|
||||
#endif
|
7985
include/gearlib/stb_image.h
Normal file
7985
include/gearlib/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
30
include/gearlib/textures.h
Normal file
30
include/gearlib/textures.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef __TEXTURES_H__
|
||||
#define __TEXTURES_H__
|
||||
|
||||
#include <gearlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t Texture;
|
||||
|
||||
void setup_textures();
|
||||
Texture load_texture(const char* path);
|
||||
void draw_texture(Texture id, vec2 pos, vec2 size, vec4 tint);
|
||||
void draw_texture_trans(Texture id, mat4 transform, vec4 tint);
|
||||
void batch_draw_texture(RenderBatch* batch, Texture id, mat4 transform, vec4 tint);
|
||||
RenderBatch* create_texture_quad_batch();
|
||||
|
||||
extern RenderBatch* texture_quad_batch;
|
||||
extern int max_textures;
|
||||
|
||||
typedef struct {
|
||||
vec3 Position;
|
||||
vec4 Tint;
|
||||
vec2 TexCoord;
|
||||
float TexID;
|
||||
} TextureQuadVertex;
|
||||
|
||||
typedef struct {
|
||||
float texture_index;
|
||||
} TextureQuadBatchData;
|
||||
|
||||
#endif
|
12
include/gearlib/uniform_buffer.h
Normal file
12
include/gearlib/uniform_buffer.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef __UNIFORM_BUFFER_H__
|
||||
#define __UNIFORM_BUFFER_H__
|
||||
|
||||
typedef struct UniformBuffer {
|
||||
size_t size;
|
||||
uint32_t ubo;
|
||||
} UniformBuffer;
|
||||
|
||||
UniformBuffer* create_uniform_buffer(size_t size);
|
||||
void set_uniform_data(UniformBuffer* buffer, void* data);
|
||||
|
||||
#endif
|
12
include/gearlib/vertex.h
Normal file
12
include/gearlib/vertex.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef __VERTEX_H__
|
||||
#define __VERTEX_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct VertexAttrib {
|
||||
int type;
|
||||
size_t size;
|
||||
int count;
|
||||
} VertexAttrib;
|
||||
|
||||
#endif
|
BIN
premake5
Executable file
BIN
premake5
Executable file
Binary file not shown.
BIN
premake5.exe
Normal file
BIN
premake5.exe
Normal file
Binary file not shown.
45
premake5.lua
Normal file
45
premake5.lua
Normal file
|
@ -0,0 +1,45 @@
|
|||
local includes = { "include", "include/gearlib" }
|
||||
|
||||
workspace "gearlib"
|
||||
configurations { "Debug", "Release" }
|
||||
location "build"
|
||||
|
||||
outputdir = "%{cfg.buildcfg}-%{cfg.system}"
|
||||
|
||||
include "vendor/glfw"
|
||||
|
||||
project "gearlib"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
targetdir "bin/%{cfg.buildcfg}/gearlib"
|
||||
|
||||
files { "include/**.h", "src/**.cpp", "src/**.c" }
|
||||
includedirs(includes)
|
||||
links { "GLFW", "m" }
|
||||
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Release"
|
||||
defines { "NDEBUG" }
|
||||
optimize "On"
|
||||
|
||||
project "test"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
targetdir "bin/%{cfg.buildcfg}/test"
|
||||
|
||||
files { "examples/test.cpp" }
|
||||
includedirs(includes)
|
||||
links { "GLFW", "gearlib", "m" }
|
||||
|
||||
debugdir "examples"
|
||||
|
||||
filter "configurations:Debug"
|
||||
defines { "DEBUG" }
|
||||
symbols "On"
|
||||
|
||||
filter "configurations:Release"
|
||||
defines { "NDEBUG" }
|
||||
optimize "On"
|
72
src/batch.cpp
Normal file
72
src/batch.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <gearlib.h>
|
||||
#include <vector>
|
||||
|
||||
std::vector<RenderBatch*> batches;
|
||||
|
||||
RenderBatch* create_batch(size_t vert_size, uint32_t max_verts) {
|
||||
RenderBatch* batch = new RenderBatch();
|
||||
batches.push_back(batch);
|
||||
|
||||
glCreateBuffers(1, &batch->vbo);
|
||||
glCreateVertexArrays(1, &batch->vao);
|
||||
|
||||
batch->vertex_size = vert_size;
|
||||
batch->max_vertices = max_verts;
|
||||
batch->vertices = calloc(vert_size, max_verts);
|
||||
batch->vertex_ptr = batch->vertices;
|
||||
glNamedBufferStorage(batch->vbo, vert_size * max_verts, NULL, GL_DYNAMIC_STORAGE_BIT);
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
void flush() {
|
||||
for(int i = 0; i < batches.size(); i++) {
|
||||
RenderBatch* batch = batches[i];
|
||||
|
||||
batch->stats.total_verts = 0;
|
||||
batch->stats.draw_calls = 0;
|
||||
|
||||
flush_batch(batch);
|
||||
}
|
||||
}
|
||||
|
||||
void flush_batch(RenderBatch* batch) {
|
||||
batch->stats.total_verts += batch->vertex_count;
|
||||
|
||||
glUseProgram(batch->shader);
|
||||
|
||||
if(batch->flush_callback != NULL)
|
||||
batch->flush_callback(batch);
|
||||
|
||||
glNamedBufferSubData(batch->vbo, 0, batch->vertex_size * batch->vertex_count, batch->vertices);
|
||||
renderer_draw(batch->vao, batch->vertex_count);
|
||||
batch->vertex_count = 0;
|
||||
batch->vertex_ptr = batch->vertices;
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
batch->stats.draw_calls++;
|
||||
}
|
||||
|
||||
void batch_add_attrib(RenderBatch* batch, VertexAttrib attr) {
|
||||
batch->layout.push_back(attr);
|
||||
}
|
||||
|
||||
void batch_bind_attribs(RenderBatch* batch) {
|
||||
size_t stride = 0;
|
||||
for(int i = 0; i < batch->layout.size(); i++) {
|
||||
VertexAttrib attr = batch->layout[i];
|
||||
|
||||
glEnableVertexArrayAttrib(batch->vao, i);
|
||||
glVertexArrayAttribFormat(batch->vao, i, attr.count, attr.type, GL_FALSE, stride);
|
||||
glVertexArrayAttribBinding(batch->vao, i, 0);
|
||||
|
||||
stride += attr.size * attr.count;
|
||||
}
|
||||
|
||||
glVertexArrayVertexBuffer(batch->vao, 0, batch->vbo, 0, stride);
|
||||
}
|
||||
|
||||
bool batch_needs_flush(RenderBatch* batch, uint32_t vertex_add) {
|
||||
return batch->vertex_size * (batch->vertex_count + vertex_add) >= batch->vertex_size * batch->max_vertices;
|
||||
}
|
28
src/camera.cpp
Normal file
28
src/camera.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <gearlib.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Camera* create_camera(vec2 pos) {
|
||||
Camera* camera = new Camera();
|
||||
camera->position = vec3(pos.x, pos.y, -3.0f);
|
||||
camera->m = new CameraMatrices();
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
void update_camera(Camera* camera, Window window) {
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
|
||||
assert(camera != NULL);
|
||||
|
||||
camera->m->view = mat4Transpose(mat4Translate(vec3_spread(camera->position)));
|
||||
|
||||
switch(camera->projection) {
|
||||
case CAMERA_ORTHOGRAPHIC:
|
||||
camera->m->projection = mat4Transpose(mat4Ortho(0.0f, width, height, 0.0f, 0.0f, 1000.0f));
|
||||
break;
|
||||
case CAMERA_PERSPECTIVE:
|
||||
camera->m->projection = mat4Transpose(mat4Perspective(45.0f * DEG2RAD, ((double)width / (double)height), 0.1f, 100.0f));
|
||||
break;
|
||||
}
|
||||
}
|
50
src/debugging.cpp
Normal file
50
src/debugging.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <debugging.h>
|
||||
#include <opengl.h>
|
||||
#include <iostream>
|
||||
|
||||
void message_callback(int32_t source, int32_t type, uint32_t id, int32_t severity, size_t length, char const* message, void const* user_param)
|
||||
{
|
||||
auto const src_str = [source]() {
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API: return "API";
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "WINDOW SYSTEM";
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER: return "SHADER COMPILER";
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY: return "THIRD PARTY";
|
||||
case GL_DEBUG_SOURCE_APPLICATION: return "APPLICATION";
|
||||
case GL_DEBUG_SOURCE_OTHER: return "OTHER";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}();
|
||||
|
||||
auto const type_str = [type]() {
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR: return "ERROR";
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "DEPRECATED_BEHAVIOR";
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "UNDEFINED_BEHAVIOR";
|
||||
case GL_DEBUG_TYPE_PORTABILITY: return "PORTABILITY";
|
||||
case GL_DEBUG_TYPE_PERFORMANCE: return "PERFORMANCE";
|
||||
case GL_DEBUG_TYPE_MARKER: return "MARKER";
|
||||
case GL_DEBUG_TYPE_OTHER: return "OTHER";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}();
|
||||
|
||||
auto const severity_str = [severity]() {
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION: return "NOTIFICATION";
|
||||
case GL_DEBUG_SEVERITY_LOW: return "LOW";
|
||||
case GL_DEBUG_SEVERITY_MEDIUM: return "MEDIUM";
|
||||
case GL_DEBUG_SEVERITY_HIGH: return "HIGH";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}();
|
||||
std::cout << src_str << ", " << type_str << ", " << severity_str << ", " << id << ": " << message << '\n';
|
||||
}
|
||||
|
||||
void enable_debugging() {
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE);
|
||||
glDebugMessageCallback((GLDEBUGPROC)message_callback, NULL);
|
||||
}
|
11
src/events.cpp
Normal file
11
src/events.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
void framebuffer_size_callback(Window window, int width, int height) {
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void process_input(Window window) {
|
||||
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
7
src/implementations.c
Normal file
7
src/implementations.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#define STBI_NO_SIMD
|
||||
#define STBI_FAILURE_USERMSG
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
#define RAYMATH_IMPLEMENTATION
|
||||
#include <raymath.h>
|
50
src/init.cpp
Normal file
50
src/init.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <gearlib.h>
|
||||
#include <opengl.h>
|
||||
|
||||
bool gl_initialized = false;
|
||||
|
||||
void init_gl(int major, int minor) {
|
||||
if(!glfwInit()) {
|
||||
printf("[GLFW] Failed to initialize\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("[GLFW] Initialized successfully\n");
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
printf("[OPENGL] Using OpenGL %d.%d\n", major, minor);
|
||||
|
||||
gl_initialized = true;
|
||||
}
|
||||
|
||||
Window create_window(int width, int height, const char* title) {
|
||||
if(!gl_initialized) init_gl(4, 6);
|
||||
|
||||
Window window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||
if(!window) {
|
||||
printf("[GLFW] Failed to create window\n");
|
||||
glfwTerminate();
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("[GLFW] Window created successfully\n");
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
if (!gladLoadGL((GLADloadfunc)glfwGetProcAddress)) {
|
||||
printf("[GLAD] Failed to initialize\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("[GLAD] Initialized successfully\n");
|
||||
}
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
return window;
|
||||
}
|
68
src/quad.cpp
Normal file
68
src/quad.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <gearlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
vec3 quad_vertex_positions[6] = {
|
||||
{ -0.5f, 0.5f, 0.0f },
|
||||
{ -0.5f, -0.5f, 0.0f },
|
||||
{ 0.5f, -0.5f, 0.0f },
|
||||
|
||||
{ -0.5f, 0.5f, 0.0f },
|
||||
{ 0.5f, -0.5f, 0.0f },
|
||||
{ 0.5f, 0.5f, 0.0f },
|
||||
};
|
||||
|
||||
RenderBatch* quad_batch = NULL;
|
||||
|
||||
void setup_quads() {
|
||||
quad_batch = create_quad_batch();
|
||||
}
|
||||
|
||||
void draw_quad(vec2 pos, vec2 size, vec4 color) {
|
||||
mat4 transform = mat4Multiply(
|
||||
mat4Scale(size.x, size.y, 1.0f),
|
||||
mat4Translate(pos.x, pos.y, 0.0f));
|
||||
|
||||
draw_quad_trans(transform, color);
|
||||
}
|
||||
|
||||
void draw_quad_trans(mat4 transform, vec4 color) {
|
||||
assert(quad_batch != NULL && "quad_batch is null, was setup_quads() called?");
|
||||
|
||||
batch_draw_quad(quad_batch, transform, color);
|
||||
}
|
||||
|
||||
void batch_draw_quad(RenderBatch* batch, mat4 transform, vec4 color) {
|
||||
uint32_t vertex_add = 6;
|
||||
|
||||
if(batch_needs_flush(batch, vertex_add))
|
||||
flush_batch(batch);
|
||||
|
||||
for(int i = 0; i < vertex_add; i++) {
|
||||
QuadVertex* vertex = (QuadVertex*)batch->vertex_ptr;
|
||||
|
||||
vertex->Position = vec3Transform(quad_vertex_positions[i], transform);
|
||||
vertex->Color = color;
|
||||
|
||||
batch->vertex_ptr = (QuadVertex*)batch->vertex_ptr + 1;
|
||||
batch->vertex_count++;
|
||||
}
|
||||
}
|
||||
|
||||
RenderBatch* create_quad_batch() {
|
||||
RenderBatch* quad_batch = create_batch(sizeof(QuadVertex), MAX_VERTICES);
|
||||
quad_batch->shader = load_shader_program(
|
||||
compile_shader("assets/quad.vert", GL_VERTEX_SHADER),
|
||||
compile_shader("assets/quad.frag", GL_FRAGMENT_SHADER), 0);
|
||||
|
||||
batch_add_attrib(quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 3
|
||||
}); // pos
|
||||
|
||||
batch_add_attrib(quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 4
|
||||
}); // color
|
||||
|
||||
batch_bind_attribs(quad_batch);
|
||||
|
||||
return quad_batch;
|
||||
}
|
8
src/renderer.cpp
Normal file
8
src/renderer.cpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include <gearlib.h>
|
||||
#include <opengl.h>
|
||||
|
||||
void renderer_draw(uint32_t vao, int count) {
|
||||
glBindVertexArray(vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, count);
|
||||
glBindVertexArray(0);
|
||||
}
|
76
src/shaders.cpp
Normal file
76
src/shaders.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include <shaders.h>
|
||||
#include <opengl.h>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
uint32_t compile_shader(const char* path, int32_t type) {
|
||||
std::ifstream file(path);
|
||||
std::string source((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
const char* source_cstr = source.c_str();
|
||||
|
||||
uint32_t id = compile_shader_text(path, source_cstr, type);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t compile_shader_text(const char* name, const char* text, int32_t type) {
|
||||
uint32_t id = glCreateShader(type);
|
||||
glShaderSource(id, 1, &text, NULL);
|
||||
glCompileShader(id);
|
||||
|
||||
int success;
|
||||
char info_log[512];
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
|
||||
if(!success) {
|
||||
glGetShaderInfoLog(id, 512, NULL, info_log);
|
||||
printf("[Shader %d, %s] Failed to compile: %s\n", id, name, info_log);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("[Shader %d, %s] Compiled successfully\n", id, name);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
uint32_t load_shader_program(uint32_t shader, ...) {
|
||||
std::vector<uint32_t> shaders;
|
||||
|
||||
va_list args;
|
||||
va_start(args, shader);
|
||||
while(shader != 0) {
|
||||
shaders.push_back(shader);
|
||||
shader = va_arg(args, uint32_t);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
uint32_t program = glCreateProgram();
|
||||
for(const auto& shader : shaders) {
|
||||
glAttachShader(program, shader);
|
||||
printf("[Shader %d] Attached to program %d\n", shader, program);
|
||||
}
|
||||
glLinkProgram(program);
|
||||
|
||||
int success;
|
||||
char info_log[512];
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||
if(!success) {
|
||||
glGetProgramInfoLog(program, 512, NULL, info_log);
|
||||
printf("[Program %d] Failed to link: %s\n", program, info_log);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("[Program %d] Linked successfully\n", program);
|
||||
}
|
||||
|
||||
for(const auto& shader : shaders) {
|
||||
glDeleteShader(shader);
|
||||
printf("[Shader %d] Deleted successfully\n", shader);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
128
src/textures.cpp
Normal file
128
src/textures.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include <textures.h>
|
||||
#include <stb_image.h>
|
||||
#include <opengl.h>
|
||||
#include <assert.h>
|
||||
|
||||
RenderBatch* texture_quad_batch = NULL;
|
||||
int max_textures;
|
||||
|
||||
void setup_textures() {
|
||||
texture_quad_batch = create_texture_quad_batch();
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_textures);
|
||||
if(max_textures > 32) max_textures = 32;
|
||||
}
|
||||
|
||||
uint32_t load_texture(const char* path) {
|
||||
uint32_t id;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &id);
|
||||
|
||||
uint8_t default_texture[] = {
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
255, 0, 255, 255, 0, 0, 0, 255 };
|
||||
|
||||
int width = 2, height = 2, channels;
|
||||
uint8_t* pixels = stbi_load(path, &width, &height, &channels, 4);
|
||||
if(pixels) {
|
||||
glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTextureParameteri(id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTextureStorage2D(id, 1, GL_RGBA8, width, height);
|
||||
glTextureSubImage2D(id, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
printf("[Texture %d, %s] Loaded successfully (%dx%d, %d channels)\n", id, path, width, height, channels);
|
||||
} else {
|
||||
glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTextureParameteri(id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTextureStorage2D(id, 1, GL_RGBA8, width, height);
|
||||
glTextureSubImage2D(id, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, default_texture);
|
||||
printf("[Texture %d, %s] Failed to load image data: %s\n", id, path, stbi_failure_reason());
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
vec2 texture_quad_texcoords[] = {
|
||||
{ 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
|
||||
{ 0.0f, 1.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f }
|
||||
};
|
||||
|
||||
void draw_texture(Texture id, vec2 pos, vec2 size, vec4 tint) {
|
||||
mat4 transform = mat4Multiply(
|
||||
mat4Scale(size.x, size.y, 1.0f),
|
||||
mat4Translate(pos.x, pos.y, 0.0f));
|
||||
|
||||
draw_texture_trans(id, transform, tint);
|
||||
}
|
||||
|
||||
void draw_texture_trans(Texture id, mat4 transform, vec4 tint) {
|
||||
assert(texture_quad_batch != NULL && "texture_quad_batch is null, was setup_textures() called?");
|
||||
batch_draw_texture(texture_quad_batch, id, transform, tint);
|
||||
}
|
||||
|
||||
void batch_draw_texture(RenderBatch* batch, Texture texture, mat4 transform, vec4 color) {
|
||||
TextureQuadBatchData* batch_data = (TextureQuadBatchData*)batch->data;
|
||||
uint32_t vertex_add = 6;
|
||||
|
||||
if(batch_needs_flush(batch, vertex_add) || batch_data->texture_index >= max_textures)
|
||||
flush_batch(batch);
|
||||
|
||||
uint32_t tex_id = batch_data->texture_index++;
|
||||
glBindTextureUnit(tex_id, texture);
|
||||
|
||||
for(int i = 0; i < vertex_add; i++) {
|
||||
TextureQuadVertex* vertex = (TextureQuadVertex*)batch->vertex_ptr;
|
||||
|
||||
vertex->Position = vec3Transform(quad_vertex_positions[i], transform);
|
||||
vertex->Tint = color;
|
||||
vertex->TexCoord = texture_quad_texcoords[i];
|
||||
vertex->TexID = tex_id;
|
||||
|
||||
batch->vertex_ptr = (TextureQuadVertex*)batch->vertex_ptr + 1;
|
||||
batch->vertex_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void texture_flush_callback(RenderBatch* batch) {
|
||||
TextureQuadBatchData* data = (TextureQuadBatchData*)batch->data;
|
||||
data->texture_index = 0;
|
||||
}
|
||||
|
||||
RenderBatch* create_texture_quad_batch() {
|
||||
RenderBatch* texture_quad_batch = create_batch(sizeof(TextureQuadVertex), MAX_VERTICES);
|
||||
texture_quad_batch->shader = load_shader_program(
|
||||
compile_shader("assets/texture.vert", GL_VERTEX_SHADER),
|
||||
compile_shader("assets/texture.frag", GL_FRAGMENT_SHADER), 0);
|
||||
|
||||
texture_quad_batch->data = new TextureQuadBatchData();
|
||||
texture_quad_batch->flush_callback = &texture_flush_callback;
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 3
|
||||
}); // pos
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 4
|
||||
}); // color
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 2
|
||||
}); // texcoord
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 1
|
||||
}); // texid
|
||||
|
||||
batch_bind_attribs(texture_quad_batch);
|
||||
|
||||
return texture_quad_batch;
|
||||
}
|
16
src/uniform_buffer.cpp
Normal file
16
src/uniform_buffer.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
UniformBuffer* create_uniform_buffer(size_t size) {
|
||||
UniformBuffer* buffer = (UniformBuffer*)calloc(sizeof(UniformBuffer), 1);
|
||||
buffer->size = size;
|
||||
|
||||
glCreateBuffers(1, &buffer->ubo);
|
||||
glNamedBufferStorage(buffer->ubo, buffer->size, NULL, GL_DYNAMIC_STORAGE_BIT);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer->ubo);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void set_uniform_data(UniformBuffer* buffer, void* data) {
|
||||
glNamedBufferSubData(buffer->ubo, 0, buffer->size, data);
|
||||
}
|
1
vendor/glfw
vendored
Submodule
1
vendor/glfw
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 026a148d7dd78d597de380c4e77ca0869f0ceaab
|
Loading…
Add table
Reference in a new issue