Skip to content

Commit

Permalink
[C99] Added "Offscreen" example written in C.
Browse files Browse the repository at this point in the history
This example demonstrates how to render into a texture without ever creating a swap-chain.
  • Loading branch information
LukasBanana committed Jul 5, 2024
1 parent b50c4e9 commit f9420ed
Show file tree
Hide file tree
Showing 9 changed files with 444 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions examples/C99/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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" )


Expand Down Expand Up @@ -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()

Expand Down
81 changes: 64 additions & 17 deletions examples/C99/ExampleBase/ExampleBase.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,14 @@ 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",
.windowSize = { 800, 600 },
.samples = 8,
.vsync = true,
.debugger = false,
.noDepthStencil = false
};

static void update_viewport()
Expand All @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions examples/C99/ExampleBase/ExampleBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down
Loading

0 comments on commit f9420ed

Please sign in to comment.