summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmniscient <omniscient.oce@gmail.com>2024-06-09 11:42:17 +1000
committerOmniscient <omniscient.oce@gmail.com>2024-06-09 11:42:17 +1000
commit64830ce51a185091f54c2b42b365110d89d44f1b (patch)
tree644c4a4425c2003a649cf02af33af488cb56a148
parent859ea7e23d2bbbc4b32b43727ae50aebe399e720 (diff)
triangle on opengl works again. happy days
-rw-r--r--assets/shaders/cube.frag3
-rw-r--r--assets/shaders/cube.vert3
-rw-r--r--assets/shaders/triangle.frag2
-rw-r--r--examples/triangle/ex_triangle.c31
-rw-r--r--src/renderer/backends/backend_vulkan.c8
-rw-r--r--src/renderer/backends/backend_vulkan.h2
-rw-r--r--src/renderer/backends/metal/backend_metal.h42
-rw-r--r--src/renderer/backends/opengl/backend_opengl.c204
-rw-r--r--src/renderer/backends/opengl/backend_opengl.h9
-rw-r--r--src/renderer/backends/opengl/opengl_helpers.h43
-rw-r--r--src/renderer/ral.c7
-rw-r--r--src/renderer/ral.h9
-rw-r--r--src/renderer/ral_types.h6
-rw-r--r--src/renderer/render_types.h1
-rw-r--r--xmake.lua6
15 files changed, 192 insertions, 184 deletions
diff --git a/assets/shaders/cube.frag b/assets/shaders/cube.frag
index 88ba822..796f1c8 100644
--- a/assets/shaders/cube.frag
+++ b/assets/shaders/cube.frag
@@ -8,5 +8,6 @@ layout(binding = 1) uniform sampler2D texSampler;
layout(location = 0) out vec4 outColor;
void main() {
- outColor = texture(texSampler, fragTexCoord); // vec4(fragTexCoord, 0.0);
+ // outColor = texture(texSampler, fragTexCoord); // vec4(fragTexCoord, 0.0);
+ outColor = vec4(1.0);
}
diff --git a/assets/shaders/cube.vert b/assets/shaders/cube.vert
index 2f1d76d..57475e7 100644
--- a/assets/shaders/cube.vert
+++ b/assets/shaders/cube.vert
@@ -1,6 +1,6 @@
#version 430
-layout(binding = 0) uniform UniformBufferObject {
+layout(binding = 0) uniform Matrices {
mat4 model;
mat4 view;
mat4 proj;
@@ -15,6 +15,7 @@ layout(location = 1) out vec2 fragTexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
+ // gl_Position = vec4(inPosition, 1.0);
fragColor = abs(inNormal);
fragTexCoord = inTexCoords;
}
diff --git a/assets/shaders/triangle.frag b/assets/shaders/triangle.frag
index c3ff328..ad6de8e 100644
--- a/assets/shaders/triangle.frag
+++ b/assets/shaders/triangle.frag
@@ -1,4 +1,4 @@
-#version 450
+#version 430
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
diff --git a/examples/triangle/ex_triangle.c b/examples/triangle/ex_triangle.c
index d9954e6..cd401c7 100644
--- a/examples/triangle/ex_triangle.c
+++ b/examples/triangle/ex_triangle.c
@@ -4,6 +4,7 @@
#include "buf.h"
#include "camera.h"
#include "core.h"
+#include "defines.h"
#include "file.h"
#include "log.h"
#include "maths.h"
@@ -73,8 +74,8 @@ int main() {
gpu_pipeline* gfx_pipeline = gpu_graphics_pipeline_create(pipeline_description);
// Load triangle vertex and index data
- buffer_handle triangle_vert_buf =
- gpu_buffer_create(4 * sizeof(vertex), CEL_BUFFER_VERTEX, CEL_BUFFER_FLAG_GPU, vertices);
+ buffer_handle triangle_vert_buf = gpu_buffer_create(4 * sizeof(custom_vertex), CEL_BUFFER_VERTEX,
+ CEL_BUFFER_FLAG_GPU, vertices);
buffer_handle triangle_index_buf =
gpu_buffer_create(sizeof(indices), CEL_BUFFER_INDEX, CEL_BUFFER_FLAG_GPU, indices);
@@ -87,24 +88,24 @@ int main() {
continue;
}
gpu_cmd_encoder* enc = gpu_get_default_cmd_encoder();
- // // Begin recording
+ // // Begin recording
gpu_cmd_encoder_begin(*enc);
gpu_cmd_encoder_begin_render(enc, renderpass);
- // encode_bind_pipeline(enc, PIPELINE_GRAPHICS, gfx_pipeline);
- // encode_set_default_settings(enc);
+ encode_bind_pipeline(enc, PIPELINE_GRAPHICS, gfx_pipeline);
+ encode_set_default_settings(enc);
- // // Record draw calls
- // encode_set_vertex_buffer(enc, triangle_vert_buf);
- // encode_set_index_buffer(enc, triangle_index_buf);
- // encode_draw_indexed(enc, 6);
+ // // Record draw calls
+ encode_set_vertex_buffer(enc, triangle_vert_buf);
+ encode_set_index_buffer(enc, triangle_index_buf);
+ encode_draw_indexed(enc, 6);
- // // End recording
- // gpu_cmd_encoder_end_render(enc);
+ // // End recording
+ // gpu_cmd_encoder_end_render(enc);
- // gpu_cmd_buffer buf = gpu_cmd_encoder_finish(enc); // Command buffer is no longer recording
- // and is ready to submit
- // // Submit
- // gpu_queue_submit(&buf);
+ // gpu_cmd_buffer buf = gpu_cmd_encoder_finish(enc); // Command buffer is no longer recording
+ // and is ready to submit
+ // // Submit
+ // gpu_queue_submit(&buf);
gpu_backend_end_frame();
}
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c
index 112e38b..8801230 100644
--- a/src/renderer/backends/backend_vulkan.c
+++ b/src/renderer/backends/backend_vulkan.c
@@ -1,7 +1,10 @@
+#include "defines.h"
#if defined(CEL_REND_BACKEND_VULKAN)
-#include <assert.h>
+#define GLFW_INCLUDE_VULKAN
#include <glfw3.h>
+
+#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
@@ -19,7 +22,6 @@
#include "str.h"
#include "vulkan_helpers.h"
-#include "defines.h"
#include "file.h"
#include "log.h"
#include "ral.h"
@@ -1637,7 +1639,7 @@ texture_handle gpu_texture_create(texture_desc desc, bool create_view, const voi
&texture->sampler);
if (res != VK_SUCCESS) {
ERROR("Error creating texture sampler for image %s", texture->debug_label);
- return;
+ exit(1);
}
return handle;
diff --git a/src/renderer/backends/backend_vulkan.h b/src/renderer/backends/backend_vulkan.h
index 21a80ba..6ca0bb5 100644
--- a/src/renderer/backends/backend_vulkan.h
+++ b/src/renderer/backends/backend_vulkan.h
@@ -1,10 +1,10 @@
#pragma once
+#include "defines.h"
#if defined(CEL_REND_BACKEND_VULKAN)
#include <vulkan/vk_platform.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
-#include "defines.h"
#include "mem.h"
#include "ral.h"
#include "ral_types.h"
diff --git a/src/renderer/backends/metal/backend_metal.h b/src/renderer/backends/metal/backend_metal.h
index 59b21d6..9561bb6 100644
--- a/src/renderer/backends/metal/backend_metal.h
+++ b/src/renderer/backends/metal/backend_metal.h
@@ -1,70 +1,70 @@
#pragma once
-#define CEL_REND_BACKEND_METAL
+// #define CEL_REND_BACKEND_METAL
#if defined(CEL_REND_BACKEND_METAL)
#include "defines.h"
#include "maths_types.h"
#ifdef __OBJC__
+#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
#import <QuartzCore/CAMetalLayer.h>
-#import <Foundation/Foundation.h>
#else
typedef void* id;
#endif
typedef struct gpu_swapchain {
u32x2 dimensions;
- #ifdef __OBJC__
+#ifdef __OBJC__
CAMetalLayer* swapchain;
- #else
+#else
void* swapchain;
- #endif
+#endif
} gpu_swapchain;
typedef struct gpu_device {
- /** @brief `device` gives us access to our GPU */
- #ifdef __OBJC__
+/** @brief `device` gives us access to our GPU */
+#ifdef __OBJC__
id<MTLDevice> id;
- #else
+#else
void* id;
- #endif
+#endif
} gpu_device;
typedef struct gpu_pipeline_layout {
void* pad;
} gpu_pipeline_layout;
typedef struct gpu_pipeline {
- #ifdef __OBJC__
+#ifdef __OBJC__
id<MTLRenderPipelineState> pipeline_state;
- #else
+#else
void* pipeline_state;
- #endif
+#endif
} gpu_pipeline;
typedef struct gpu_renderpass {
- #ifdef __OBJC__
+#ifdef __OBJC__
MTLRenderPassDescriptor* rpass_descriptor;
- #else
+#else
void* rpass_descriptor;
- #endif
+#endif
} gpu_renderpass;
typedef struct gpu_cmd_encoder {
- #ifdef __OBJC__
+#ifdef __OBJC__
id<MTLCommandBuffer> cmd_buffer;
id<MTLRenderCommandEncoder> render_encoder;
- #else
+#else
void* cmd_buffer;
void* render_encoder;
- #endif
+#endif
} gpu_cmd_encoder;
typedef struct gpu_cmd_buffer {
void* pad;
} gpu_cmd_buffer;
typedef struct gpu_buffer {
- #ifdef __OBJC__
+#ifdef __OBJC__
id<MTLBuffer> id;
- #else
+#else
void* id;
- #endif
+#endif
u64 size;
} gpu_buffer;
typedef struct gpu_texture {
diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/renderer/backends/opengl/backend_opengl.c
index 96415f1..073f343 100644
--- a/src/renderer/backends/opengl/backend_opengl.c
+++ b/src/renderer/backends/opengl/backend_opengl.c
@@ -2,8 +2,9 @@
#include "colours.h"
#include "opengl_helpers.h"
#include "ral_types.h"
-// #define CEL_REND_BACKEND_OPENGL
+#define CEL_REND_BACKEND_OPENGL 1
#if defined(CEL_REND_BACKEND_OPENGL)
+#include <assert.h>
#include <stdlib.h>
#include "camera.h"
@@ -29,8 +30,6 @@ static opengl_context context;
struct GLFWwindow;
-size_t vertex_attrib_size(vertex_attrib_type attr);
-
bool gpu_backend_init(const char* window_name, struct GLFWwindow* window) {
INFO("loading OpenGL backend");
@@ -62,7 +61,7 @@ bool gpu_backend_init(const char* window_name, struct GLFWwindow* window) {
void gpu_backend_shutdown() {}
-bool gpu_device_create(gpu_device* out_device) {}
+bool gpu_device_create(gpu_device* out_device) { /* No-op in OpenGL */ }
void gpu_device_destroy() {}
// --- Render Pipeline
@@ -73,23 +72,8 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
u32 shader_id = shader_create_separate(description.vs.filepath.buf, description.fs.filepath.buf);
pipeline->shader_id = shader_id;
- // Vertex
- u32 vao;
- glGenVertexArrays(1, &vao);
- pipeline->vao = vao;
-
- // Attributes
- u32 attr_count = description.vertex_desc.attributes_count;
- printf("N attributes %d\n", attr_count);
- u64 offset = 0;
- size_t vertex_size = description.vertex_desc.stride;
- for (u32 i = 0; i < description.vertex_desc.attributes_count; i++) {
- opengl_vertex_attr format = format_from_vertex_attr(description.vertex_desc.attributes[i]);
- glVertexAttribPointer(i, format.count, format.data_type, GL_FALSE, vertex_size, (void*)offset);
- size_t this_offset = format.count * vertex_attrib_size(description.vertex_desc.attributes[i]);
- printf("offset total %lld this attr %ld\n", offset, this_offset);
- offset += this_offset;
- }
+ // Vertex format
+ pipeline->vertex_desc = description.vertex_desc;
// Allocate uniform buffers if needed
printf("data layouts %d\n", description.data_layouts_count);
@@ -98,6 +82,20 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
TRACE("Got shader data layout %d's bindings! . found %d", layout_i, sdl.bindings_count);
for (u32 binding_j = 0; binding_j < sdl.bindings_count; binding_j++) {
+ u32 binding_id = binding_j;
+ assert(binding_id < MAX_PIPELINE_UNIFORM_BUFFERS);
+ shader_binding binding = sdl.bindings[binding_j];
+ if (binding.type == SHADER_BINDING_BYTES) {
+ buffer_handle ubo_handle =
+ gpu_buffer_create(binding.data.bytes.size, CEL_BUFFER_UNIFORM, CEL_BUFFER_FLAG_GPU,
+ NULL); // no data right now
+ pipeline->uniform_bindings[binding_id] = ubo_handle;
+ gpu_buffer* ubo_buf = BUFFER_GET(ubo_handle);
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, binding_j, ubo_buf->id.ubo);
+
+ // Now we want to store a handle associated with the shader for this
+ }
}
}
@@ -139,7 +137,10 @@ void gpu_queue_submit(gpu_cmd_buffer* buffer) {}
void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset,
buffer_handle dst, u64 dst_offset, u64 copy_size) {}
/** @brief Upload CPU-side data as array of bytes to a GPU buffer */
-void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size) {}
+void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size) {
+ // TODO: finish implementing this
+ gpu_buffer* buf = BUFFER_GET(gpu_buf);
+}
/** @brief Copy data from buffer to buffer using a one time submit command buffer and a wait */
void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst,
@@ -149,43 +150,77 @@ void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst) {}
// --- Render commands
void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline) {
+ encoder->pipeline = pipeline;
// In OpenGL this is more or less equivalent to just setting the shader
glUseProgram(pipeline->shader_id);
- glBindVertexArray(pipeline->vao);
}
void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
shader_data_layout sdl = data->shader_data_get_layout(data->data);
- size_t binding_count = sdl.bindings_count;
for (u32 i = 0; i < sdl.bindings_count; i++) {
shader_binding binding = sdl.bindings[i];
+ print_shader_binding(binding);
+
+ if (binding.type == SHADER_BINDING_BYTES) {
+ buffer_handle b = encoder->pipeline->uniform_bindings[i];
+ gpu_buffer* ubo_buf = BUFFER_GET(b);
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, data->data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
}
}
void encode_set_default_settings(gpu_cmd_encoder* encoder) {}
-void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
-void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
-void encode_draw(gpu_cmd_encoder* encoder) {}
-void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) {}
+void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
+ gpu_buffer* buffer = BUFFER_GET(buf);
+ if (buffer->vao == 0) { // if no VAO for this vertex buffer, create it
+ buffer->vao = opengl_bindcreate_vao(buffer, encoder->pipeline->vertex_desc);
+ }
+ glBindVertexArray(buffer->vao);
+}
+void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
+ gpu_buffer* buffer = BUFFER_GET(buf);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->id.ibo);
+}
+void encode_draw(gpu_cmd_encoder* encoder, u64 count) { glDrawArrays(GL_TRIANGLES, 0, count); }
+void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) {
+ glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0);
+}
void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {}
// --- Buffers
buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags,
const void* data) {
+ // "allocating" the cpu-side buffer struct
+ buffer_handle handle;
+ gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle);
+ buffer->size = size;
+ buffer->vao = 0; // When we create a new buffer, there will be no VAO.
+
+ // Opengl buffer
GLuint gl_buffer_id;
glGenBuffers(1, &gl_buffer_id);
GLenum gl_buf_type;
+ GLenum gl_buf_usage = GL_STATIC_DRAW;
switch (buf_type) {
case CEL_BUFFER_UNIFORM:
+ DEBUG("Creating Uniform buffer");
gl_buf_type = GL_UNIFORM_BUFFER;
+ gl_buf_usage = GL_DYNAMIC_DRAW;
+ buffer->id.ubo = gl_buffer_id;
break;
case CEL_BUFFER_DEFAULT:
case CEL_BUFFER_VERTEX:
+ DEBUG("Creating Vertex buffer");
gl_buf_type = GL_ARRAY_BUFFER;
+ buffer->id.vbo = gl_buffer_id;
break;
case CEL_BUFFER_INDEX:
+ DEBUG("Creating Index buffer");
gl_buf_type = GL_ELEMENT_ARRAY_BUFFER;
+ buffer->id.ibo = gl_buffer_id;
break;
default:
WARN("Unimplemented gpu_buffer_type provided %s", buffer_type_names[buf_type]);
@@ -194,27 +229,22 @@ buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_f
// bind buffer
glBindBuffer(gl_buf_type, gl_buffer_id);
- // "allocating" the cpu-side buffer struct
- buffer_handle handle;
- gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle);
- buffer->size = size;
-
if (data) {
TRACE("Upload data (%d bytes) as part of buffer creation", size);
- glBufferData(gl_buf_type, buffer->size, data, GL_STATIC_DRAW);
+ glBufferData(gl_buf_type, buffer->size, data, gl_buf_usage);
+ } else {
+ TRACE("Allocating the correct size anyway");
+ glBufferData(gl_buf_type, buffer->size, NULL, gl_buf_usage);
}
+ glBindBuffer(gl_buf_type, 0);
+
return handle;
}
void gpu_buffer_destroy(buffer_handle buffer) {}
void gpu_buffer_upload(const void* data) {}
-// Textures
-/** @brief Create a new GPU texture resource.
- * @param create_view creates a texture view (with same dimensions) at the same time
- * @param data if not NULL then the data stored at the pointer will be uploaded to the GPU texture
- * @note automatically creates a sampler for you */
texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {}
void gpu_texture_destroy(texture_handle) {}
void gpu_texture_upload(texture_handle texture, const void* data) {}
@@ -279,48 +309,16 @@ u32 shader_create_separate(const char* vert_shader, const char* frag_shader) {
return shader_prog;
}
-// /** @brief Internal backend state */
-// typedef struct opengl_state {
-// } opengl_state;
-
-// bool gfx_backend_init(renderer *ren) {
-// INFO("loading OpenGL backend");
-
-// // glfwInit(); // Already handled in `renderer_init`
-// 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);
-
-// // glad: load all OpenGL function pointers
-// if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
-// ERROR("Failed to initialise GLAD \n");
-
-// return false;
-// }
-
-// glEnable(GL_DEPTH_TEST);
-
-// opengl_state *internal = malloc(sizeof(opengl_state));
-// ren->backend_context = (void *)internal;
-
-// return true;
-// }
-
-// void gfx_backend_draw_frame(renderer *ren, camera *cam, mat4 model, texture *tex) {}
-
-// void gfx_backend_shutdown(renderer *ren) {}
-
-void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value) {
+inline void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value) {
glUniform3fv(glGetUniformLocation(program_id, uniform_name), 1, &value->x);
}
-void uniform_f32(u32 program_id, const char* uniform_name, f32 value) {
+inline void uniform_f32(u32 program_id, const char* uniform_name, f32 value) {
glUniform1f(glGetUniformLocation(program_id, uniform_name), value);
}
-void uniform_i32(u32 program_id, const char* uniform_name, i32 value) {
+inline void uniform_i32(u32 program_id, const char* uniform_name, i32 value) {
glUniform1i(glGetUniformLocation(program_id, uniform_name), value);
}
-void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value) {
+inline void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value) {
glUniformMatrix4fv(glGetUniformLocation(program_id, uniform_name), 1, GL_FALSE, value->data);
}
@@ -377,60 +375,4 @@ void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value) {
// u32 gl_primitive = to_gl_prim_topology(primitive);
// glDrawArrays(gl_primitive, start_index, count);
// }
-
-// shader shader_create_separate(const char *vert_shader, const char *frag_shader) {
-// INFO("Load shaders at %s and %s", vert_shader, frag_shader);
-// int success;
-// char info_log[512];
-
-// u32 vertex = glCreateShader(GL_VERTEX_SHADER);
-// const char *vertex_shader_src = string_from_file(vert_shader);
-// if (vertex_shader_src == NULL) {
-// ERROR("EXIT: couldnt load shader");
-// exit(-1);
-// }
-// glShaderSource(vertex, 1, &vertex_shader_src, NULL);
-// glCompileShader(vertex);
-// glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
-// if (!success) {
-// glGetShaderInfoLog(vertex, 512, NULL, info_log);
-// printf("%s\n", info_log);
-// ERROR("EXIT: vertex shader compilation failed");
-// exit(-1);
-// }
-
-// // fragment shader
-// u32 fragment = glCreateShader(GL_FRAGMENT_SHADER);
-// const char *fragment_shader_src = string_from_file(frag_shader);
-// if (fragment_shader_src == NULL) {
-// ERROR("EXIT: couldnt load shader");
-// exit(-1);
-// }
-// glShaderSource(fragment, 1, &fragment_shader_src, NULL);
-// glCompileShader(fragment);
-// glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
-// if (!success) {
-// glGetShaderInfoLog(fragment, 512, NULL, info_log);
-// printf("%s\n", info_log);
-// ERROR("EXIT: fragment shader compilation failed");
-// exit(-1);
-// }
-
-// u32 shader_prog;
-// shader_prog = glCreateProgram();
-
-// glAttachShader(shader_prog, vertex);
-// glAttachShader(shader_prog, fragment);
-// glLinkProgram(shader_prog);
-// glDeleteShader(vertex);
-// glDeleteShader(fragment);
-// free((char *)vertex_shader_src);
-// free((char *)fragment_shader_src);
-
-// shader s = { .program_id = shader_prog };
-// return s;
-// }
-
-// void set_shader(shader s) { glUseProgram(s.program_id); }
-
#endif
diff --git a/src/renderer/backends/opengl/backend_opengl.h b/src/renderer/backends/opengl/backend_opengl.h
index a9835c1..91de38d 100644
--- a/src/renderer/backends/opengl/backend_opengl.h
+++ b/src/renderer/backends/opengl/backend_opengl.h
@@ -4,6 +4,9 @@
#include "defines.h"
#include "maths_types.h"
+#include "ral_types.h"
+
+#define MAX_PIPELINE_UNIFORM_BUFFERS 32
typedef struct gpu_swapchain {
u32x2 dimensions;
@@ -15,13 +18,14 @@ typedef struct gpu_pipeline_layout {
} gpu_pipeline_layout;
typedef struct gpu_pipeline {
u32 shader_id;
- u32 vao;
+ vertex_description vertex_desc;
+ buffer_handle uniform_bindings[MAX_PIPELINE_UNIFORM_BUFFERS];
} gpu_pipeline;
typedef struct gpu_renderpass {
void *pad
} gpu_renderpass;
typedef struct gpu_cmd_encoder {
- void *pad
+ gpu_pipeline *pipeline;
} gpu_cmd_encoder; // Recording
typedef struct gpu_cmd_buffer {
void *pad
@@ -31,6 +35,7 @@ typedef struct gpu_buffer {
union {
u32 vbo;
u32 ibo;
+ u32 ubo;
} id;
u32 vao; // Optional
u64 size;
diff --git a/src/renderer/backends/opengl/opengl_helpers.h b/src/renderer/backends/opengl/opengl_helpers.h
index 44d40cb..405a8f1 100644
--- a/src/renderer/backends/opengl/opengl_helpers.h
+++ b/src/renderer/backends/opengl/opengl_helpers.h
@@ -1,4 +1,10 @@
+#if defined(CEL_REND_BACKEND_OPENGL)
#pragma once
+#include "backend_opengl.h"
+#include "log.h"
+#include "ral.h"
+#include "ral_types.h"
+
#include <glad/glad.h>
#include <glfw3.h>
#include "ral_types.h"
@@ -6,7 +12,8 @@ typedef struct opengl_vertex_attr {
u32 count;
GLenum data_type;
} opengl_vertex_attr;
-opengl_vertex_attr format_from_vertex_attr(vertex_attrib_type attr) {
+
+static opengl_vertex_attr format_from_vertex_attr(vertex_attrib_type attr) {
switch (attr) {
case ATTR_F32:
return (opengl_vertex_attr){ .count = 1, .data_type = GL_FLOAT };
@@ -31,6 +38,36 @@ opengl_vertex_attr format_from_vertex_attr(vertex_attrib_type attr) {
case ATTR_U32x4:
// return VK_FORMAT_R32G32B32A32_UINT;
case ATTR_I32x4:
- return (opengl_vertex_attr){ .count = 4, .data_type = GL_INT };
+ return (opengl_vertex_attr){ .count = 4, .data_type = GL_INT };
+ }
+}
+
+static u32 opengl_bindcreate_vao(gpu_buffer* buf, vertex_description desc) {
+ // 1. Bind the buffer
+ glBindBuffer(GL_ARRAY_BUFFER, buf->id.vbo);
+ // 2. Create new VAO
+ u32 vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ // Attributes
+ u32 attr_count = desc.attributes_count;
+ printf("N attributes %d\n", attr_count);
+ u64 offset = 0;
+ size_t vertex_size = desc.stride;
+ for (u32 i = 0; i < desc.attributes_count; i++) {
+ opengl_vertex_attr format = format_from_vertex_attr(desc.attributes[i]);
+ glVertexAttribPointer(i, format.count, format.data_type, GL_FALSE, vertex_size, (void*)offset);
+ TRACE(" %d %d %d %d %d %s", i, format.count, format.data_type, vertex_size, offset,
+ desc.attr_names[i]);
+ glEnableVertexAttribArray(i); // nth index
+ size_t this_offset = vertex_attrib_size(desc.attributes[i]);
+ printf("offset total %lld this attr %ld\n", offset, this_offset);
+ offset += this_offset;
}
-} \ No newline at end of file
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ return vao;
+}
+
+#endif
diff --git a/src/renderer/ral.c b/src/renderer/ral.c
index fe12b4f..123c932 100644
--- a/src/renderer/ral.c
+++ b/src/renderer/ral.c
@@ -68,4 +68,9 @@ void resource_pools_init(arena* a, struct resource_pools* res_pools) {
res_pools->textures = tex_pool;
// context.resource_pools = res_pools;
-} \ No newline at end of file
+}
+
+void print_shader_binding(shader_binding b) {
+ printf("Binding name: %s type %s vis %d stores data %d\n", b.label,
+ shader_binding_type_name[b.type], b.vis, b.stores_data);
+}
diff --git a/src/renderer/ral.h b/src/renderer/ral.h
index 3415b04..067847b 100644
--- a/src/renderer/ral.h
+++ b/src/renderer/ral.h
@@ -44,6 +44,10 @@ TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
TYPED_POOL(gpu_pipeline, pipeline);
TYPED_POOL(gpu_renderpass, renderpass);
+// --- Handy macros
+#define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
+#define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
+
// --- Pools
typedef struct gpu_backend_pools {
pipeline_pool pipelines;
@@ -69,7 +73,7 @@ typedef struct shader_desc {
str8 filepath; // Where it came from
str8 code; // Either GLSL or SPIRV bytecode
bool is_spirv;
- bool is_combined_vert_frag; // Contains both vertex and fragment stages
+ bool is_combined_vert_frag; // Contains both vertex and fragment stages
} shader_desc;
struct graphics_pipeline_desc {
@@ -149,7 +153,7 @@ void encode_set_default_settings(gpu_cmd_encoder* encoder);
void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
void encode_set_bind_group(); // TODO
-void encode_draw(gpu_cmd_encoder* encoder);
+void encode_draw(gpu_cmd_encoder* encoder, u64 count);
void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count);
void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
@@ -182,3 +186,4 @@ void gpu_temp_draw(size_t n_verts);
// --- Helpers
vertex_description static_3d_vertex_description();
+size_t vertex_attrib_size(vertex_attrib_type attr);
diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h
index 415796c..f1f7809 100644
--- a/src/renderer/ral_types.h
+++ b/src/renderer/ral_types.h
@@ -201,6 +201,10 @@ typedef enum shader_binding_type {
SHADER_BINDING_COUNT
} shader_binding_type;
+static const char* shader_binding_type_name[] = { "BUFFER", "BUFFER ARRAY", "TEXTURE",
+ "TEXTURE ARRAY", "SAMPLER", "BYTES",
+ "COUNT" };
+
// pub trait ShaderBindable: Clone + Copy {
// fn bind_to(&self, context: &mut PipelineContext, index: u32);
// }
@@ -228,6 +232,8 @@ typedef struct shader_binding {
#define MAX_LAYOUT_BINDINGS 8
+void print_shader_binding(shader_binding b);
+
/** @brief A list of bindings that describe what data a shader / pipeline expects
@note This roughly correlates to a descriptor set layout in Vulkan
*/
diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h
index a2c35fe..349f65a 100644
--- a/src/renderer/render_types.h
+++ b/src/renderer/render_types.h
@@ -10,6 +10,7 @@
*/
#pragma once
+#include "defines.h"
#include "ral.h"
#include "ral_types.h"
#if defined(CEL_PLATFORM_WINDOWS)
diff --git a/xmake.lua b/xmake.lua
index 86a673a..6af1402 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -20,7 +20,7 @@ end
-- Platform defines and system packages
if is_plat("linux") then
add_defines("CEL_PLATFORM_LINUX")
- add_syslinks("dl", "X11", "pthread")
+ add_syslinks("dl", "X11", "pthread", "vulkan")
elseif is_plat("windows") then
add_defines("CEL_PLATFORM_WINDOWS")
add_syslinks("user32", "gdi32", "kernel32", "shell32")
@@ -63,7 +63,6 @@ local core_sources = {
"src/renderer/*.c",
"src/renderer/backends/*.c",
"src/renderer/backends/opengl/*.c",
- "src/renderer/backends/metal/*.m",
"src/resources/*.c",
"src/std/*.c",
"src/std/containers/*.c",
@@ -133,6 +132,9 @@ target("core_config")
add_linkdirs("$(env VULKAN_SDK)/Lib", {public = true})
add_links("vulkan-1")
end
+ if is_plat("macosx") then
+ add_files("src/renderer/backends/metal/*.m")
+ end
set_default(false) -- prevents standalone building of this target
target("core_static")