From f9420ede25de199a85b14ba3f4389e3752369730 Mon Sep 17 00:00:00 2001 From: Laura Hermanns Date: Thu, 4 Jul 2024 15:14:35 -0400 Subject: [PATCH] [C99] Added "Offscreen" example written in C. This example demonstrates how to render into a texture without ever creating a swap-chain. --- .gitignore | 1 + examples/C99/CMakeLists.txt | 2 + examples/C99/ExampleBase/ExampleBase.c | 81 ++++-- examples/C99/ExampleBase/ExampleBase.h | 17 ++ examples/C99/Offscreen/Offscreen.c | 330 +++++++++++++++++++++++++ examples/C99/Offscreen/Offscreen.frag | 11 + examples/C99/Offscreen/Offscreen.png | Bin 0 -> 49604 bytes examples/C99/Offscreen/Offscreen.vert | 13 + examples/C99/README.md | 6 + 9 files changed, 444 insertions(+), 17 deletions(-) create mode 100644 examples/C99/Offscreen/Offscreen.c create mode 100644 examples/C99/Offscreen/Offscreen.frag create mode 100644 examples/C99/Offscreen/Offscreen.png create mode 100644 examples/C99/Offscreen/Offscreen.vert diff --git a/.gitignore b/.gitignore index 442d4fbb0d..4eb4f1974d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ build*/ # Runtime output files for testing Screenshot.* Capture.* +*.Results.png # Output files from individual tests (Testbed is handled separately) tests/Output diff --git a/examples/C99/CMakeLists.txt b/examples/C99/CMakeLists.txt index bf20cd66ef..57584d24fb 100644 --- a/examples/C99/CMakeLists.txt +++ b/examples/C99/CMakeLists.txt @@ -16,6 +16,7 @@ project(LLGL_ExamplesC99) find_source_files(FilesExampleBaseC99 C "${EXAMPLE_C99_PROJECTS_DIR}/ExampleBase") find_project_source_files( FilesExampleC99_HelloTriangle "${EXAMPLE_C99_PROJECTS_DIR}/HelloTriangle" ) +find_project_source_files( FilesExampleC99_Offscreen "${EXAMPLE_C99_PROJECTS_DIR}/Offscreen" ) find_project_source_files( FilesExampleC99_Texturing "${EXAMPLE_C99_PROJECTS_DIR}/Texturing" ) @@ -53,6 +54,7 @@ if(LLGL_BUILD_EXAMPLES AND LLGL_BUILD_WRAPPER_C99) # C99 wrapper examples add_llgl_example_project(Example_C99_HelloTriangle C "${FilesExampleC99_HelloTriangle}" "${EXAMPLE_C99_PROJECT_LIBS}") + add_llgl_example_project(Example_C99_Offscreen C "${FilesExampleC99_Offscreen}" "${EXAMPLE_C99_PROJECT_LIBS}") add_llgl_example_project(Example_C99_Texturing C "${FilesExampleC99_Texturing}" "${EXAMPLE_C99_PROJECT_LIBS}") endif() diff --git a/examples/C99/ExampleBase/ExampleBase.c b/examples/C99/ExampleBase/ExampleBase.c index 9737987229..26bb663c7d 100644 --- a/examples/C99/ExampleBase/ExampleBase.c +++ b/examples/C99/ExampleBase/ExampleBase.c @@ -100,15 +100,6 @@ static void mouse_motion_event(LLGLWindow sender, const LLGLOffset2D* motion) * Global functions */ -struct ExampleConfig -{ - const char* rendererModule; - uint32_t windowSize[2]; - uint32_t samples; - bool vsync; - bool debugger; -}; - static struct ExampleConfig g_Config = { .rendererModule = "OpenGL", @@ -116,6 +107,7 @@ static struct ExampleConfig g_Config = .samples = 8, .vsync = true, .debugger = false, + .noDepthStencil = false }; static void update_viewport() @@ -138,6 +130,33 @@ static float aspect_ratio() return (float)swapChainResolution.width / (float)swapChainResolution.height; } +void example_config(const ExampleConfig* config) +{ + if (config != NULL) + { + if (config->rendererModule != NULL) + g_Config.rendererModule = config->rendererModule; + if (config->windowSize[0] != 0) + g_Config.windowSize[0] = config->windowSize[0]; + if (config->windowSize[1] != 0) + g_Config.windowSize[1] = config->windowSize[1]; + g_Config.samples = config->samples; + g_Config.vsync = config->vsync; + g_Config.debugger = config->debugger; + g_Config.noDepthStencil = config->noDepthStencil; + } + else + { + g_Config.rendererModule = "OpenGL"; + g_Config.windowSize[0] = 800; + g_Config.windowSize[1] = 600; + g_Config.samples = 8; + g_Config.vsync = true; + g_Config.debugger = false; + g_Config.noDepthStencil = false; + } +} + int example_init(const wchar_t* title) { // Register standard output as log callback @@ -155,10 +174,10 @@ int example_init(const wchar_t* title) LLGLSwapChainDescriptor swapChainDesc = { .resolution = { g_Config.windowSize[0], g_Config.windowSize[1] }, - .colorBits = 32, // 32 bits for color information - .depthBits = 24, // 24 bits for depth comparison - .stencilBits = 8, // 8 bits for stencil patterns - .samples = g_Config.samples, // check if LLGL adapts sample count that is too high + .colorBits = 32, // 32 bits for color information + .depthBits = (g_Config.noDepthStencil ? 0 : 24), // 24 bits for depth comparison + .stencilBits = (g_Config.noDepthStencil ? 0 : 8), // 8 bits for stencil patterns + .samples = g_Config.samples, // check if LLGL adapts sample count that is too high }; g_swapChain = llglCreateSwapChain(&swapChainDesc); @@ -249,10 +268,38 @@ bool example_poll_events() void perspective_projection(float outProjection[4][4], float aspectRatio, float nearPlane, float farPlane, float fieldOfView) { const int rendererID = llglGetRendererID(); - if (rendererID == LLGL_RENDERERID_OPENGL || rendererID == LLGL_RENDERERID_VULKAN) - build_perspective_projection(outProjection, aspectRatio, nearPlane, farPlane, fieldOfView, /*isUnitCube:*/ true); - else - build_perspective_projection(outProjection, aspectRatio, nearPlane, farPlane, fieldOfView, /*isUnitCube:*/ false); + const bool isUnitCube = (rendererID == LLGL_RENDERERID_OPENGL || rendererID == LLGL_RENDERERID_VULKAN); + build_perspective_projection(outProjection, aspectRatio, nearPlane, farPlane, fieldOfView, isUnitCube); +} + +static void build_orthogonal_projection(float m[4][4], float width, float height, float nearPlane, float farPlane, bool isUnitCube) +{ + m[0][0] = 2.0f / width; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + + m[1][0] = 0.0f; + m[1][1] = 2.0f / height; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = (isUnitCube ? 2.0f/(farPlane - nearPlane) : 1.0f/(farPlane - nearPlane)); + m[3][2] = 0.0f; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[2][3] = (isUnitCube ? -(farPlane + nearPlane)/(farPlane - nearPlane) : -nearPlane/(farPlane - nearPlane)); + m[3][3] = 1.0f; +} + +void orthogonal_projection(float outProjection[4][4], float width, float height, float nearPlane, float farPlane) +{ + const int rendererID = llglGetRendererID(); + const bool isUnitCube = (rendererID == LLGL_RENDERERID_OPENGL || rendererID == LLGL_RENDERERID_VULKAN); + build_orthogonal_projection(outProjection, width, height, nearPlane, farPlane, isUnitCube); } void get_textured_cube(const TexturedVertex** outVertices, size_t* outVertexCount, const uint32_t** outIndices, size_t* outIndexCount) diff --git a/examples/C99/ExampleBase/ExampleBase.h b/examples/C99/ExampleBase/ExampleBase.h index 58444b5c64..0f3fa9031b 100644 --- a/examples/C99/ExampleBase/ExampleBase.h +++ b/examples/C99/ExampleBase/ExampleBase.h @@ -26,6 +26,17 @@ * Structures */ +typedef struct ExampleConfig +{ + const char* rendererModule; + uint32_t windowSize[2]; + uint32_t samples; + bool vsync; + bool debugger; + bool noDepthStencil; +} +ExampleConfig; + typedef struct TexturedVertex { float position[3]; @@ -91,6 +102,9 @@ extern float g_projection[4][4]; * Global functions */ +// Configures the example setup. If used, it must be called before example_init(). If this is NULL, the defualt configuration will be used. +void example_config(const ExampleConfig* config); + // Initializes the example with the specified title and returns a non-zero error code if initialization failed. int example_init(const wchar_t* title); @@ -103,6 +117,9 @@ bool example_poll_events(); // Builds a perspective projection matrix. void perspective_projection(float outProjection[4][4], float aspectRatio, float nearPlane, float farPlane, float fieldOfView); +// Builds an orthogonal projection matrix. +void orthogonal_projection(float outProjection[4][4], float width, float height, float nearPlane, float farPlane); + // Returns the pointers the vertex and index data of a textured cube. void get_textured_cube(const TexturedVertex** outVertices, size_t* outVertexCount, const uint32_t** outIndices, size_t* outIndexCount); diff --git a/examples/C99/Offscreen/Offscreen.c b/examples/C99/Offscreen/Offscreen.c new file mode 100644 index 0000000000..afaaf052cb --- /dev/null +++ b/examples/C99/Offscreen/Offscreen.c @@ -0,0 +1,330 @@ +/* + * Offscreen.c + * + * Copyright (c) 2015 Lukas Hermanns. All rights reserved. + * Licensed under the terms of the BSD 3-Clause license (see LICENSE.txt). + */ + +/* +This example demonstates how to render offscreen, i.e. into a render-target without showing anything on the screen. +The rendered result will be written to a PNG file called "Offscreen.Results.png" in the same directory as this source file. +This image should look identical to the "Offscreen.png" image. +*/ + +#include +#include // printf() +#include // malloc()/free() +#include // sinf()/cosf() + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "../../../external/stb/stb_image_write.h" // stbi_write_png() + +#define FRAME_WIDTH 512 +#define FRAME_HEIGHT 512 +#define ENABLE_MULTISAMPLING 1 + +#ifndef M_PI +#define M_PI 3.141592654f +#endif + + +static const float g_colorWheel[6][3] = +{ + { 1.0f, 0.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 1.0f }, +}; + +// Linear interpolation between a and b +float Lerp(float a, float b, float t) +{ + return a*(1.0f - t) + b*t; +} + +float LerpColorWheel(float t, int component) +{ + const int colorIndex = (int)(t*6.0f); + const float colorIndexRemainder = t*6.0f - (float)colorIndex; + return Lerp( + g_colorWheel[(colorIndex )%6][component], + g_colorWheel[(colorIndex + 1)%6][component], + colorIndexRemainder + ); +} + +int main(int argc, char* argv[]) +{ + // Load render system module + const char* rendererModule = "OpenGL"; + if (llglLoadRenderSystem(rendererModule) == 0) + { + fprintf(stderr, "Failed to load render system: %s\n", rendererModule); + return 1; + } + + // Print information about the selected renderer + LLGLRendererInfo info = {}; + llglGetRendererInfo(&info); + printf( + "Renderer: %s\n" + "Device: %s\n" + "Vendor: %s\n" + "Shading Language: %s\n", + info.rendererName, info.deviceName, info.vendorName, info.shadingLanguageName + ); + + // Vertex data structure + typedef struct Vertex + { + float position[2]; + float color[3]; + } + Vertex; + + // Generate vertices for strip geometry + const uint32_t numSegments = 64; + const uint32_t numVertices = (numSegments + 1)*2; + const size_t vertexBufferSize = sizeof(Vertex)*numVertices; + + Vertex* vertices = (Vertex*)malloc(vertexBufferSize); + if (vertices == NULL) + { + fprintf(stderr, "Failed to allocate %zu bytes for vertex buffer\n", vertexBufferSize); + return 1; + } + + const float invFrameScaleX = 1.0f / (float)numSegments; + const float invFrameScaleY = 1.0f / (float)numSegments; + + const float ringOuterRadius = 0.8f; + const float ringInnerRadius = 0.5f; + + for (size_t i = 0; i <= numSegments; ++i) + { + float u = (float)i * invFrameScaleX; + + float angle = u*M_PI*2.0f; + + float x0 = sinf(angle)*ringOuterRadius; + float y0 = cosf(angle)*ringOuterRadius; + + float x1 = sinf(angle)*ringInnerRadius; + float y1 = cosf(angle)*ringInnerRadius; + + float r = LerpColorWheel(u, 0); + float g = LerpColorWheel(u, 1); + float b = LerpColorWheel(u, 2); + + // Left-top vertex + vertices[i*2 ].position[0] = x0; + vertices[i*2 ].position[1] = y0; + vertices[i*2 ].color[0] = r; + vertices[i*2 ].color[1] = g; + vertices[i*2 ].color[2] = b; + + // Left-bottom vertex + vertices[i*2 + 1].position[0] = x1; + vertices[i*2 + 1].position[1] = y1; + vertices[i*2 + 1].color[0] = r; + vertices[i*2 + 1].color[1] = g; + vertices[i*2 + 1].color[2] = b; + } + + // Vertex format with 2D floating-point vector for position and 4D byte vector for color + LLGLVertexAttribute vertexAttributes[2] = + { + { .name = "position", .format = LLGLFormatRG32Float, .location = 0, .offset = offsetof(Vertex, position), .stride = sizeof(Vertex) }, + { .name = "color", .format = LLGLFormatRGB32Float, .location = 1, .offset = offsetof(Vertex, color ), .stride = sizeof(Vertex) }, + }; + + // Create vertex buffer + LLGLBufferDescriptor vertexBufferDesc = + { + .debugName = "VertexBuffer", + .size = vertexBufferSize, // Size (in bytes) of the vertex buffer + .bindFlags = LLGLBindVertexBuffer, // Enables the buffer to be bound to a vertex buffer slot + .numVertexAttribs = 2, + .vertexAttribs = vertexAttributes, // Vertex format layout + }; + LLGLBuffer vertexBuffer = llglCreateBuffer(&vertexBufferDesc, vertices); + + // Free temporariy resources + free(vertices); + + // Create shaders + LLGLShaderDescriptor vertShaderDesc = + { + .debugName = "VertexShader", + .type = LLGLShaderTypeVertex, + .source = "Offscreen.vert", + .sourceType = LLGLShaderSourceTypeCodeFile, + .flags = LLGLShaderCompilePatchClippingOrigin + }; + LLGLShaderDescriptor fragShaderDesc = + { + .debugName = "FragmentShader", + .type = LLGLShaderTypeFragment, + .source = "Offscreen.frag", + .sourceType = LLGLShaderSourceTypeCodeFile + }; + + // Specify vertex attributes for vertex shader + vertShaderDesc.vertex.numInputAttribs = 2; + vertShaderDesc.vertex.inputAttribs = vertexAttributes; + + LLGLShader shaders[2] = + { + llglCreateShader(&vertShaderDesc), + llglCreateShader(&fragShaderDesc), + }; + + for (int i = 0; i < 2; ++i) + { + LLGLReport shaderReport = llglGetShaderReport(shaders[i]); + if (llglHasReportErrors(shaderReport)) + { + fprintf(stderr, "%s\n", llglGetReportText(shaderReport)); + return 1; + } + } + + // Create texture to render into and read results from + LLGLTextureDescriptor textureDesc = + { + .debugName = "Offscreen.Texture", + .type = LLGLTextureTypeTexture2D, + .format = LLGLFormatRGBA8UNorm, + .extent = { FRAME_WIDTH, FRAME_HEIGHT, 1}, + .bindFlags = LLGLBindColorAttachment | LLGLBindCopySrc, + .mipLevels = 1, + .miscFlags = LLGLMiscNoInitialData, + }; + LLGLTexture texture = llglCreateTexture(&textureDesc, NULL); + + // Create offscreen render target to render into + LLGLRenderTargetDescriptor renderTargetDesc = + { + .debugName = "Offscreen.RenderTarget", + .renderPass = NULL, + .resolution = { FRAME_WIDTH, FRAME_HEIGHT }, + #if ENABLE_MULTISAMPLING + .samples = 8, + .colorAttachments[0] = { .format = LLGLFormatRGBA8UNorm }, // Let LLGL create an internal multi-sample texture with RGBA8UNorm format + .resolveAttachments[0] = { .texture = texture }, // Resolve multi-sampled texture into our output texture + #else + .colorAttachments[0] = { .texture = texture }, // Render directly into our output texture + #endif + }; + LLGLRenderTarget renderTarget = llglCreateRenderTarget(&renderTargetDesc); + + // Create graphics pipeline + LLGLGraphicsPipelineDescriptor pipelineDesc = + { + .vertexShader = shaders[0], + .fragmentShader = shaders[1], + .renderPass = llglGetRenderTargetRenderPass(renderTarget), + .primitiveTopology = LLGLPrimitiveTopologyTriangleStrip, + #if ENABLE_MULTISAMPLING + .rasterizer.multiSampleEnabled = true, + #endif + .blend.targets[0].colorMask = LLGLColorMaskAll, + }; + LLGLPipelineState pipeline = llglCreateGraphicsPipelineState(&pipelineDesc); + + // Link shader program and check for errors + LLGLReport pipelineReport = llglGetPipelineStateReport(pipeline); + if (llglHasReportErrors(pipelineReport)) + { + fprintf(stderr, "%s\n", llglGetReportText(pipelineReport)); + return 1; + } + + // Create command buffer to submit subsequent graphics commands to the GPU + LLGLCommandBufferDescriptor cmdBufferDesc = + { + .flags = LLGLCommandBufferImmediateSubmit, + .numNativeBuffers = 2, + }; + LLGLCommandBuffer cmdBuffer = llglCreateCommandBuffer(&cmdBufferDesc); + + // Initialize frame constants + const LLGLViewport viewport = + { + .x = 0.0f, + .y = 0.0f, + .width = (float)FRAME_WIDTH, + .height = (float)FRAME_HEIGHT, + .minDepth = 0.0f, + .maxDepth = 1.0f + }; + + const LLGLClearValue clearColor = + { + .color = { 0.1f, 0.1f, 0.2f, 1.0f }, + }; + + // Render single frame into offscreen render target + llglBegin(cmdBuffer); + { + // Set viewport and scissor rectangle + llglSetViewport(&viewport); + + // Set vertex buffer + llglSetVertexBuffer(vertexBuffer); + + // Set the swap-chain as the initial render target + llglBeginRenderPass(renderTarget); + { + // Clear color buffer + llglClear(LLGLClearColor, &clearColor); + + // Set graphics pipeline + llglSetPipelineState(pipeline); + + // Draw triangle with 3 vertices + llglDraw(numVertices, 0); + } + llglEndRenderPass(); + } + llglEnd(); + + // Read results from entire texture we just rendered into + const size_t imageRowStride = sizeof(uint32_t)*FRAME_WIDTH; + const size_t imageSize = imageRowStride * FRAME_HEIGHT; + + void* imageData = malloc(imageSize); + + LLGLMutableImageView dstImageView = + { + .format = LLGLImageFormatRGBA, + .dataType = LLGLDataTypeUInt8, + .data = imageData, + .dataSize = imageSize, + }; + LLGLTextureRegion dstRegion = + { + .subresource = { .numMipLevels = 1, .numArrayLayers = 1 }, + .offset = { 0, 0, 0 }, + .extent = textureDesc.extent, + }; + llglReadTexture(texture, &dstRegion, &dstImageView); + + // Save results to disk + const char* outputFilename = "Offscreen.Results.png"; + if (stbi_write_png(outputFilename, FRAME_WIDTH, FRAME_HEIGHT, 4, imageData, (int)imageRowStride) == 0) + { + fprintf(stderr, "Failed to save image to disk: %s\n", outputFilename); + return 1; + } + + // Free temporary resources + free(imageData); + + // Clean up + llglUnloadRenderSystem(); + + return 0; +} diff --git a/examples/C99/Offscreen/Offscreen.frag b/examples/C99/Offscreen/Offscreen.frag new file mode 100644 index 0000000000..9627899e17 --- /dev/null +++ b/examples/C99/Offscreen/Offscreen.frag @@ -0,0 +1,11 @@ +// GLSL shader version 3.30 (for OpenGL 3.3) +#version 330 + +in vec4 vColor; + +out vec4 outColor; + +void main() +{ + outColor = vColor; +} diff --git a/examples/C99/Offscreen/Offscreen.png b/examples/C99/Offscreen/Offscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..7d06be26a460d9c18a5b16d94e7b1cbcf816f1d6 GIT binary patch literal 49604 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 YH_Zd;ZY=FAhQQDEZ9BKtI+M@*FU{UOG5`Po literal 0 HcmV?d00001 diff --git a/examples/C99/Offscreen/Offscreen.vert b/examples/C99/Offscreen/Offscreen.vert new file mode 100644 index 0000000000..c695326b4f --- /dev/null +++ b/examples/C99/Offscreen/Offscreen.vert @@ -0,0 +1,13 @@ +// GLSL shader version 3.30 (for OpenGL 3.3) +#version 330 + +in vec2 position; +in vec3 color; + +out vec4 vColor; + +void main() +{ + gl_Position = vec4(position, 0, 1); + vColor = vec4(color, 1); +} diff --git a/examples/C99/README.md b/examples/C99/README.md index 6738c3c0b7..c11f59f910 100644 --- a/examples/C99/README.md +++ b/examples/C99/README.md @@ -18,3 +18,9 @@ Texturing example with loading an image from file (using STB lib), indexed-drawi

+### [Offscreen](Offscreen) + +Offscreen example renders into a texture and outputs the result onto disk instead of the screen. + +

+