summaryrefslogtreecommitdiff
path: root/src/renderer/backends/opengl/backend_opengl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/backends/opengl/backend_opengl.c')
-rw-r--r--src/renderer/backends/opengl/backend_opengl.c204
1 files changed, 73 insertions, 131 deletions
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