1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
/**
* @brief
*/
#include "render.h"
#include <glfw3.h>
#include "camera.h"
#include "colours.h"
#include "core.h"
#include "log.h"
#include "maths.h"
#include "maths_types.h"
#include "pbr.h"
#include "ral_common.h"
#include "ral_impl.h"
#include "ral_types.h"
#include "render_scene.h"
#include "render_types.h"
#include "shadows.h"
extern Core g_core;
struct Renderer {
struct GLFWwindow* window;
RendererConfig config;
GPU_Device device;
GPU_Swapchain swapchain;
GPU_Renderpass* default_renderpass;
bool frame_aborted;
RenderScene scene;
PBR_Storage* pbr;
Shadow_Storage* shadows;
// Terrain_Storage terrain;
// Text_Storage text;
ResourcePools* resource_pools;
};
Renderer* get_renderer() { return g_core.renderer; }
bool Renderer_Init(RendererConfig config, Renderer* ren, GLFWwindow** out_window) {
INFO("Renderer init");
// init resource pools
DEBUG("Initialise GPU resource pools");
arena pool_arena = arena_create(malloc(1024 * 1024), 1024 * 1024);
ren->resource_pools = arena_alloc(&pool_arena, sizeof(struct ResourcePools));
ResourcePools_Init(&pool_arena, ren->resource_pools);
// GLFW window creation
// NOTE: all platforms use GLFW at the moment but thats subject to change
glfwInit();
#if defined(CEL_REND_BACKEND_OPENGL)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#elif defined(CEL_REND_BACKEND_VULKAN)
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
#endif
GLFWwindow* window =
glfwCreateWindow(config.scr_width, config.scr_height, config.window_name, NULL, NULL);
if (window == NULL) {
ERROR("Failed to create GLFW window\n");
glfwTerminate();
return false;
}
ren->window = window;
*out_window = window;
glfwMakeContextCurrent(ren->window);
// set the RAL backend up
if (!GPU_Backend_Init(config.window_name, window, ren->resource_pools)) {
return false;
}
GPU_Device_Create(&ren->device);
GPU_Swapchain_Create(&ren->swapchain);
// set up default scene
Camera default_cam =
Camera_Create(vec3(0.0, 2.0, 4.0), vec3_normalise(vec3(0.0, -2.0, -4.0)), VEC3_Y, 45.0);
SetCamera(default_cam);
DirectionalLight default_light = { /* TODO */ };
SetMainLight(default_light);
// create our renderpasses
ren->shadows = malloc(sizeof(Shadow_Storage));
Shadow_Init(ren->shadows, u32x2(512, 512));
return true;
}
void Renderer_Shutdown(Renderer* ren) { free(ren->shadows); }
size_t Renderer_GetMemReqs() { return sizeof(Renderer); }
void Render_FrameBegin(Renderer* ren) {
ren->frame_aborted = false;
if (!GPU_Backend_BeginFrame()) {
ren->frame_aborted = true;
WARN("Frame aborted");
return;
}
}
void Render_FrameEnd(Renderer* ren) {
if (ren->frame_aborted) {
return;
}
GPU_CmdEncoder* enc = GPU_GetDefaultEncoder();
GPU_Backend_EndFrame();
}
void Render_RenderEntities(RenderEnt* entities, size_t entity_count) {
Renderer* ren = get_renderer();
RenderScene scene = ren->scene;
// -- Shadows
f32 near_plane = 1.0, far_plane = 10.0;
Mat4 light_projection = mat4_orthographic(-10.0, 10.0, -10.0, 10.0, near_plane, far_plane);
Vec3 pos = vec3_negate(scene.sun.direction);
Mat4 light_view = mat4_look_at(pos, VEC3_ZERO, VEC3_Y);
Mat4 light_space_matrix = mat4_mult(light_view, light_projection);
Shadow_ShadowmapExecute(ren->shadows, light_space_matrix, entities, entity_count);
}
Mesh Mesh_Create(Geometry* geometry, bool free_on_upload) {
Mesh m = { 0 };
// Create and upload vertex buffer
size_t vert_bytes = geometry->vertices->len * sizeof(Vertex);
INFO("Creating vertex buffer with size %d (%d x %d)", vert_bytes, geometry->vertices->len,
sizeof(Vertex));
m.vertex_buffer =
GPU_BufferCreate(vert_bytes, BUFFER_VERTEX, BUFFER_FLAG_GPU, geometry->vertices->data);
// Create and upload index buffer
size_t index_bytes = geometry->indices->len * sizeof(u32);
INFO("Creating index buffer with size %d (len: %d)", index_bytes, geometry->indices->len);
m.index_buffer =
GPU_BufferCreate(index_bytes, BUFFER_INDEX, BUFFER_FLAG_GPU, geometry->indices->data);
m.is_uploaded = true;
m.geometry = geometry;
if (free_on_upload) {
Geometry_Destroy(geometry);
}
return m;
}
void Geometry_Destroy(Geometry* geometry) {
if (geometry->indices) {
u32_darray_free(geometry->indices);
}
if (geometry->vertices) {
Vertex_darray_free(geometry->vertices);
}
}
void SetCamera(Camera camera) { g_core.renderer->scene.camera = camera; }
void SetMainLight(DirectionalLight light) { g_core.renderer->scene.sun = light; }
|