From 7f6ec430de361dc93f73fdd481a7fea8a9f45391 Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Tue, 19 Aug 2025 16:31:19 -0400 Subject: [PATCH] finish the most basic rendering pipeline --- .../opengl/loader/opengl_commands_loader.c | 10 +-- .../apis/opengl/src/buffer/opengl_buffer.c | 8 ++- .../commands/buffers/opengl_command_buffer.c | 9 +++ .../commands/buffers/opengl_command_buffer.h | 2 + .../src/commands/commands/opengl_commands.cpp | 63 ++++++++++++++----- .../src/commands/commands/opengl_commands.h | 2 +- .../opengl_graphics_pipeline.c | 37 +++++++++++ .../opengl_graphics_pipeline.h | 3 + .../apis/opengl/src/present/opengl_present.c | 2 + 9 files changed, 113 insertions(+), 23 deletions(-) diff --git a/projects/apis/opengl/loader/opengl_commands_loader.c b/projects/apis/opengl/loader/opengl_commands_loader.c index 88b6d31..33f2945 100644 --- a/projects/apis/opengl/loader/opengl_commands_loader.c +++ b/projects/apis/opengl/loader/opengl_commands_loader.c @@ -14,11 +14,11 @@ gnCommandFunctions loadOpenGLCommandFunctions() { ._gnCommandBeginRenderPass = openglBeginRenderPass, ._gnCommandEndRenderPass = openglEndRenderPass, - ._gnCommandBindGraphicsPipeline = NULL, - ._gnCommandSetViewport = NULL, - ._gnCommandSetScissor = NULL, - ._gnCommandBindUniform = NULL, - ._gnCommandPushConstant = NULL, + ._gnCommandBindGraphicsPipeline = openglBindGraphicsPipeline, + ._gnCommandSetViewport = openglSetViewport, + ._gnCommandSetScissor = openglSetScissor, + ._gnCommandBindUniform = openglBindUniform, + ._gnCommandPushConstant = openglPushConstant, ._gnCommandBindBuffer = openglBindBuffer, ._gnCommandDraw = openglDraw, diff --git a/projects/apis/opengl/src/buffer/opengl_buffer.c b/projects/apis/opengl/src/buffer/opengl_buffer.c index c70d3ee..d63633b 100644 --- a/projects/apis/opengl/src/buffer/opengl_buffer.c +++ b/projects/apis/opengl/src/buffer/opengl_buffer.c @@ -14,14 +14,16 @@ gnReturnCode openglCreateBuffer(gnBufferHandle buffer, gnDevice device, gnBuffer glCreateBuffers(1, &buffer->buffer->id); buffer->buffer->type = gnBufferTypeToGLEnum(info.type); buffer->buffer->usage = (info.usage == GN_DYNAMIC_DRAW) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; - glNamedBufferData(buffer->buffer->id, info.size, NULL, buffer->buffer->usage); + glNamedBufferStorage(buffer->buffer->id, info.size, NULL, GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT); return GN_SUCCESS; } void openglBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { - glNamedBufferData(buffer->buffer->id, dataSize, data, buffer->buffer->usage); + openglBufferSubData(buffer, 0, dataSize, data); } +#include "stdio.h" void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) { - glNamedBufferSubData(buffer->buffer->id, offset, dataSize, data); + glBindBuffer(buffer->buffer->type, buffer->buffer->id); + glBufferSubData(buffer->buffer->type, 0, dataSize, data); } void* openglMapBuffer(gnBufferHandle buffer) { return glMapNamedBuffer(buffer->buffer->id, GL_READ_WRITE); diff --git a/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.c b/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.c index a0bea22..e257cf8 100644 --- a/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.c +++ b/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.c @@ -9,6 +9,15 @@ gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* comm pool->commandPool->canBeReallocated[c] = GN_FALSE; commandBuffers[i]->commandBuffer = &pool->commandPool->commandBuffers[c]; commandBuffers[i]->commandBuffer->commmandRunner = openglCreateCommandRunner(); + + // glGenBuffers(1, &commandBuffers[i]->commandBuffer->vertexBuffer); + // glBindBuffer(GL_ARRAY_BUFFER, commandBuffers[i]->commandBuffer->vertexBuffer); + // glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); + + // gl + + // glGenBuffers(1, &commandBuffers[i]->commandBuffer->indexBuffer); + wasAbleToAllocate = GN_TRUE; break; } diff --git a/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.h b/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.h index 94b9375..a62f427 100644 --- a/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.h +++ b/projects/apis/opengl/src/commands/buffers/opengl_command_buffer.h @@ -1,10 +1,12 @@ #pragma once +#include "glad/glad.h" #include "core/src/command/command_buffer/gryphn_command_buffer.h" #include "commands/commands/opengl_command_runner.h" typedef struct gnPlatformCommandBuffer_t { int index; openglCommandRunner commmandRunner; + gnGraphicsPipeline boundGraphicsPipeline; } gnPlatformCommandBuffer; gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPoolHandle pool); diff --git a/projects/apis/opengl/src/commands/commands/opengl_commands.cpp b/projects/apis/opengl/src/commands/commands/opengl_commands.cpp index 6231a00..b51191f 100644 --- a/projects/apis/opengl/src/commands/commands/opengl_commands.cpp +++ b/projects/apis/opengl/src/commands/commands/opengl_commands.cpp @@ -5,6 +5,7 @@ #include "framebuffer/opengl_framebuffer.h" #include #include "buffer/opengl_buffer.h" +#include "graphics_pipeline/opengl_graphics_pipeline.h" GN_CPP_FUNCTION void openglBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { gnClearValue* values = (gnClearValue*)malloc(sizeof(gnClearValue*) * passInfo.clearValueCount); @@ -13,7 +14,7 @@ GN_CPP_FUNCTION void openglBeginRenderPass(gnCommandBuffer buffer, gnRenderPassI openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([passInfo, values]{ glBindFramebuffer(GL_FRAMEBUFFER, passInfo.framebuffer->framebuffer->framebuffers[0]); glClearColor(values[0].r, values[0].g, values[0].b, values[0].a); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glViewport(passInfo.offset.x, passInfo.offset.y, passInfo.size.x, passInfo.size.y); free(values); @@ -24,23 +25,57 @@ GN_CPP_FUNCTION void openglEndRenderPass(gnCommandBuffer buffer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); })); } -GN_CPP_FUNCTION void openglBindGraphicsPipeline(gnCommandBuffer buffer, gnGraphicsPipeline graphicsPipeline); -GN_CPP_FUNCTION void openglSetViewport(gnCommandBuffer buffer, gnViewport viewport); -GN_CPP_FUNCTION void openglSetScissor(gnCommandBuffer buffer, gnScissor scissor); -GN_CPP_FUNCTION void openglBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { - openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([&]{ - glBindBuffer(gnBufferTypeToGLEnum(type), bufferToBind->buffer->id); +GN_CPP_FUNCTION void openglBindGraphicsPipeline(gnCommandBuffer commandBuffer, gnGraphicsPipeline graphicsPipeline) { + gnGraphicsPipeline pipeline = graphicsPipeline; + gnCommandBuffer buffer = commandBuffer; + openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([buffer, pipeline]{ + buffer->commandBuffer->boundGraphicsPipeline = pipeline; + + glBindVertexArray(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject); + glUseProgram(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->program); })); } -GN_CPP_FUNCTION void openglDraw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance) { - openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([&]{ +GN_CPP_FUNCTION void openglSetViewport(gnCommandBuffer buffer, gnViewport viewport) { + +} +GN_CPP_FUNCTION void openglSetScissor(gnCommandBuffer buffer, gnScissor scissor) { + +} +GN_CPP_FUNCTION void openglBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { + gnBufferType bType = type; + gnCommandBufferHandle bBuffer = buffer; + gnBufferHandle bBufferToBind = bufferToBind; + + openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([bType, bBuffer, bBufferToBind]{ + if (bType == GN_VERTEX_BUFFER) { + glVertexArrayVertexBuffer( + bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, 0, + bBufferToBind->buffer->id, 0, + bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->stride + ); + } else if (bType == GN_INDEX_BUFFER) { + glVertexArrayElementBuffer(bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, bBufferToBind->buffer->id); + } + })); +} +GN_CPP_FUNCTION void openglDraw(gnCommandBuffer buffer, int sVertexCount, int sFirstVertex, int sInstanceCount, int sFirstInstance) { + int vertexCount = sVertexCount, firstVertex = sFirstVertex, instanceCount = sInstanceCount, firstInstance = sFirstInstance; + openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([vertexCount, firstVertex, instanceCount, firstInstance]{ glDrawArraysInstancedBaseInstance(GL_TRIANGLES, firstVertex, vertexCount, instanceCount, firstInstance); })); } -GN_CPP_FUNCTION void openglDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance) { - openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([&]{ - glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * firstIndex), instanceCount, vertexOffset, firstInstance); +// #include "stdio.h" +GN_CPP_FUNCTION void openglDrawIndexed(gnCommandBufferHandle sBuffer, gnIndexType sType, int sIndexCount, int sFirstIndex, int sVertexOffset, int sInstanceCount, int sFirstInstance) { + gnCommandBuffer buffer = sBuffer; + gnIndexType type = sType; + int indexCount = sIndexCount, firstIndex = sFirstIndex, vertexOffset = sVertexOffset, instanceCount = sInstanceCount, firstInstance = sFirstInstance; + openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function([buffer, type, indexCount, firstIndex, instanceCount, vertexOffset, firstInstance]{ + glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, indexCount, (type == GN_UINT16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * firstIndex), instanceCount, vertexOffset, firstInstance); })); } -GN_CPP_FUNCTION void openglBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets); -GN_CPP_FUNCTION void openglBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); +GN_CPP_FUNCTION void openglBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets) { + +} +GN_CPP_FUNCTION void openglPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) { + +} diff --git a/projects/apis/opengl/src/commands/commands/opengl_commands.h b/projects/apis/opengl/src/commands/commands/opengl_commands.h index 801f5df..b0f4e6f 100644 --- a/projects/apis/opengl/src/commands/commands/opengl_commands.h +++ b/projects/apis/opengl/src/commands/commands/opengl_commands.h @@ -11,4 +11,4 @@ GN_CPP_FUNCTION void openglBindBuffer(gnCommandBufferHandle buffer, gnBufferHand GN_CPP_FUNCTION void openglDraw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance); GN_CPP_FUNCTION void openglDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance); GN_CPP_FUNCTION void openglBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets); -GN_CPP_FUNCTION void openglBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); +GN_CPP_FUNCTION void openglPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); diff --git a/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.c b/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.c index a17e0ff..d4cb61a 100644 --- a/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.c +++ b/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.c @@ -1,5 +1,8 @@ #include "opengl_graphics_pipeline.h" #include "shaders/opengl_shader_module.h" +#include "core/src/instance/gryphn_instance.h" + +#include "stdio.h" gnReturnCode openglCreateGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) { graphicsPipeline->graphicsPipeline = malloc(sizeof(gnPlatformGraphicsPipeline)); @@ -7,6 +10,40 @@ gnReturnCode openglCreateGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, g for (int i = 0; i < info.shaderModuleCount; i++) glAttachShader(graphicsPipeline->graphicsPipeline->program, info.shaderModules[i]->shaderModule->id); glLinkProgram(graphicsPipeline->graphicsPipeline->program); + GLint linked; + glGetProgramiv(graphicsPipeline->graphicsPipeline->program, GL_LINK_STATUS, &linked); + if (!linked) { + GLchar infoLog[512]; + glGetProgramInfoLog(graphicsPipeline->graphicsPipeline->program, 512, NULL, infoLog); + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString(infoLog) + }); + } else { + gnDebuggerSetVerboseMessage(&device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Successfully linked program") + }); + } + + glCreateVertexArrays(1, &graphicsPipeline->graphicsPipeline->vertexArrayObject); + + glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0, 3, GL_FLOAT, GL_FALSE, 0); + glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0, 0); + + // Attribute 1: texcoord (2 floats) + glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*3); + glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1, 0); + + // Attribute 2: color (3 floats) + glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2, 3, GL_FLOAT, GL_FALSE, sizeof(float)*5); + glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2, 0); + + graphicsPipeline->graphicsPipeline->stride = (sizeof(float) * 8); + + // Enable them + glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0); + glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1); + glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2); + return GN_SUCCESS; } void openglDestroyGraphicsPipeline(gnGraphicsPipeline graphicsPipeline) { diff --git a/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.h b/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.h index 388aadf..99ac614 100644 --- a/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.h +++ b/projects/apis/opengl/src/graphics_pipeline/opengl_graphics_pipeline.h @@ -4,6 +4,9 @@ typedef struct gnPlatformGraphicsPipeline_t { GLuint program; + + GLuint vertexArrayObject; + GLsizei stride; } gnPlatformGraphicsPipeline; gnReturnCode openglCreateGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info); diff --git a/projects/apis/opengl/src/present/opengl_present.c b/projects/apis/opengl/src/present/opengl_present.c index f336522..594f03a 100644 --- a/projects/apis/opengl/src/present/opengl_present.c +++ b/projects/apis/opengl/src/present/opengl_present.c @@ -7,6 +7,8 @@ gnReturnCode openglPresent(gnOutputDeviceHandle device, gnPresentInfo info) { for (uint32_t i =0 ; i < info.presentationQueueCount; i++) { uint32_tArrayListAdd(info.presentationQueues[i]->presentationQueue->avaliableTextures, info.imageIndices[i]); + glBindVertexArray(0); + glUseProgram(device->outputDevice->shaderProgram); glBindBuffer(GL_ARRAY_BUFFER, device->outputDevice->buffer); glBindTexture(GL_TEXTURE_2D, GLuintArrayListAt(info.presentationQueues[i]->presentationQueue->textures, info.imageIndices[i]));