diff options
Diffstat (limited to 'src/renderer/backends/opengl/backend_opengl.c')
-rw-r--r-- | src/renderer/backends/opengl/backend_opengl.c | 204 |
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 |