diff --git a/projects/apis/opengl/loader/opengl_device_loader.c b/projects/apis/opengl/loader/opengl_device_loader.c new file mode 100644 index 0000000..41778c0 --- /dev/null +++ b/projects/apis/opengl/loader/opengl_device_loader.c @@ -0,0 +1,49 @@ +#include "opengl_loader.h" +#include "device/opengl_output_device.h" +#include "presentation_queue/opengl_presentation_queue.h" + +gnDeviceFunctions loadOpenGLDeviceFunctions() { + return (gnDeviceFunctions){ + ._gnCreatePresentationQueue = createOpenGLPresentationQueue, + ._gnPresentationQueueGetImage = getOpenGLPresentationQueueImage, + ._gnDestroyPresentationQueue = destroyOpenGLPresentationQueue, + + ._gnCreateShaderModule = NULL, + ._gnDestroyShaderModule = NULL, + + ._gnCreateRenderPassDescriptor = NULL, + ._gnDestroyRenderPassDescriptor = NULL, + + ._gnCreateGraphicsPipeline = NULL, + ._gnDestroyGraphicsPipeline = NULL, + + ._gnCreateFramebuffer = NULL, + ._gnDestroyFramebuffer = NULL, + + ._gnCreateCommandPool = NULL, + ._gnDestroyCommandPool = NULL, + + ._gnCreateBuffer = NULL, + ._gnBufferData = NULL, + ._gnBufferSubData = NULL, + ._gnMapBuffer = NULL, + ._gnDestroyBuffer = NULL, + + ._gnCreateUniformPool = NULL, + ._gnUniformPoolAllocateUniforms = NULL, + ._gnDestroyUniformPool = NULL, + + ._gnUpdateBufferUniform = NULL, + ._gnUpdateStorageUniform = NULL, + ._gnUpdateImageUniform = NULL, + + ._gnCreateTexture = NULL, + ._gnTextureData = NULL, + ._gnDestroyTexture = NULL, + + ._gnSubmit = NULL, + ._gnPresent = NULL, + + ._gnWaitForDevice = waitForOpenGLDevice + }; +} diff --git a/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.c b/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.c new file mode 100644 index 0000000..36cff07 --- /dev/null +++ b/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.c @@ -0,0 +1,43 @@ +#include "opengl_presentation_queue.h" +#include "surface/opengl_surface.h" +#include "textures/opengl_texture.h" + +gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo) { + presentationQueue->presentationQueue = malloc(sizeof(struct gnPlatformPresentationQueue_t)); + + uint32_t convertedFormat = glGryphnFormatToOpenGLFormat(presentationInfo.format.format); + + presentationQueue->imageCount = presentationInfo.minImageCount; + presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); + presentationQueue->presentationQueue->textures = GLuintArrayListCreate(); + presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate(); + for (int i = 0; i < presentationInfo.minImageCount; i++) { + presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t)); + presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); + glGenTextures(1, &presentationQueue->images[i]->texture->id); + + glTexImage2D( + GL_TEXTURE_2D, + 0, + glGryphnFormatToOpenGLInternalFormat(presentationInfo.format.format), + presentationInfo.imageSize.x, presentationInfo.imageSize.y, + 0, + glGryphnFormatToOpenGLFormat(presentationInfo.format.format), + GL_UNSIGNED_BYTE, + NULL + ); + + GLuintArrayListAdd(&presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->id); + uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, i); + } + return GN_SUCCESS; +} +gnReturnCode getOpenGLPresentationQueueImage(gnPresentationQueue presentationQueue, uint32_t* imageIndex) { + while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} + *imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0]; + uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures); + return GN_SUCCESS; +} +void destroyOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue) { + free(presentationQueue->presentationQueue); +} diff --git a/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.h b/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.h new file mode 100644 index 0000000..f9352b0 --- /dev/null +++ b/projects/apis/opengl/src/presentation_queue/opengl_presentation_queue.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include "presentation_queue/gryphn_presentation_queue.h" + +GN_ARRAY_LIST(GLuint); + +typedef struct gnPlatformPresentationQueue_t { + GLuintArrayList textures; + uint32_tArrayList avaliableTextures; +} gnPlatformPresentationQueue_t; + +gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo); +gnReturnCode getOpenGLPresentationQueueImage(gnPresentationQueue presentationQueue, uint32_t* imageIndex); +void destroyOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue); diff --git a/projects/apis/opengl/src/surface/opengl_surface.c b/projects/apis/opengl/src/surface/opengl_surface.c index 1f21a6d..0bc0f64 100644 --- a/projects/apis/opengl/src/surface/opengl_surface.c +++ b/projects/apis/opengl/src/surface/opengl_surface.c @@ -1,4 +1,5 @@ #include +#include "GL/glext.h" #include "opengl_surface.h" #ifdef GN_PLATFORM_LINUX @@ -65,3 +66,28 @@ gnSurfaceDetails genOpenGLSurfaceDetails( void destroyOpenGLSurface(gnWindowSurface surface) { free(surface->windowSurface); } + +GLint glGryphnFormatToOpenGLFormat(gnImageFormat format) { + switch (format) { + case GN_FORMAT_NONE: return GL_NONE; + case GN_FORMAT_BGRA8: return GL_BGRA; + case GN_FORMAT_RGBA8_SRGB: return GL_SRGB_ALPHA; + case GN_FORMAT_D32S8_UINT: return GL_DEPTH_STENCIL; + case GN_FORMAT_D24S8_UINT: return GL_DEPTH_STENCIL; + + // unsupprted formats + case GN_FORMAT_BGRA8_SRGB: return GL_NONE; + } +} +GLint glGryphnFormatToOpenGLInternalFormat(gnImageFormat format) { + switch (format) { + case GN_FORMAT_NONE: return GL_NONE; + case GN_FORMAT_BGRA8: return GL_BGRA8_EXT; + case GN_FORMAT_RGBA8_SRGB: return GL_SRGB8_ALPHA8; + case GN_FORMAT_D32S8_UINT: return GL_DEPTH32F_STENCIL8; + case GN_FORMAT_D24S8_UINT: return GL_DEPTH24_STENCIL8; + + // unsupprted formats + case GN_FORMAT_BGRA8_SRGB: return GL_NONE; + } +} diff --git a/projects/apis/opengl/src/surface/opengl_surface.h b/projects/apis/opengl/src/surface/opengl_surface.h index 2c18df4..c9f048f 100644 --- a/projects/apis/opengl/src/surface/opengl_surface.h +++ b/projects/apis/opengl/src/surface/opengl_surface.h @@ -17,3 +17,6 @@ gnReturnCode createGLXContext(gnWindowSurfaceHandle windowSurface, gnInstanceHan gnUInt2 getWindowSize(gnPlatformWindowSurface* surface); gnSurfaceDetails genOpenGLSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device); void destroyOpenGLSurface(gnWindowSurface surface); + +GLint glGryphnFormatToOpenGLFormat(gnImageFormat format); +GLint glGryphnFormatToOpenGLInternalFormat(gnImageFormat format); diff --git a/projects/apis/opengl/src/textures/opengl_texture.h b/projects/apis/opengl/src/textures/opengl_texture.h new file mode 100644 index 0000000..8cc3256 --- /dev/null +++ b/projects/apis/opengl/src/textures/opengl_texture.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include "textures/gryphn_texture.h" + +typedef struct gnPlatformTexture_t { + GLuint id; +} gnPlatformTexture; diff --git a/projects/loader/src/gryphn_loader.c b/projects/loader/src/gryphn_loader.c index 118fd82..7bbf73c 100644 --- a/projects/loader/src/gryphn_loader.c +++ b/projects/loader/src/gryphn_loader.c @@ -44,7 +44,9 @@ gnDeviceFunctions loadAPIDeviceFunctions(gnRenderingAPI api) { case GN_RENDERINGAPI_SOFTWARE: return (gnDeviceFunctions){ NULL }; case GN_RENDERINGAPI_DIRECTX11: return (gnDeviceFunctions){ NULL }; case GN_RENDERINGAPI_DIRECTX12: return (gnDeviceFunctions){ NULL }; - case GN_RENDERINGAPI_OPENGL: return (gnDeviceFunctions){ NULL }; +#ifdef GN_API_OPENGL + case GN_RENDERINGAPI_OPENGL: return loadOpenGLDeviceFunctions(); +#endif #ifdef GN_API_METAL case GN_RENDERINGAPI_METAL: return loadMetalDeviceFunctions(); #endif