Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Last active March 31, 2024 22:42
Show Gist options
  • Save pervognsen/c25a039fcf8c256141ef0778a1b32a88 to your computer and use it in GitHub Desktop.
Save pervognsen/c25a039fcf8c256141ef0778a1b32a88 to your computer and use it in GitHub Desktop.
gob.h
// My investigations on the C standard compliance of Gob and related techniques:
// https://gist.github.com/pervognsen/5249a405fe7d76ded1cf08ed50fa9176
#pragma once
#include <stdint.h>
#pragma pack(push, 8)
#if __cplusplus >= 201103L || (__cplusplus && _MSC_VER >= 1900)
#define GOB_DISALLOW_COPYING(type) type(const type&) = delete;
#else
#define GOB_DISALLOW_COPYING(type)
#endif
#define GOB_FOURCC(code) ((code[0]) | (code[1] << 8) | (code[2] << 16) | (code[3] << 24))
typedef int32_t Gob_Offset;
struct Gob_Reference {
Gob_Offset offset;
GOB_DISALLOW_COPYING(Gob_Reference)
};
#define GOB_POINTER(reference) \
((void *)((char *)&(reference) + (reference).offset))
#define GOB_DECLARE_REFERENCE_TYPE(type) \
union type##Reference { \
Gob_Offset offset; \
Gob_Offset offset_##type; \
GOB_DISALLOW_COPYING(type##Reference) \
};
#define GOB_GET_POINTER_FROM_REFERENCE(type, reference) \
((type *)((char *)&(reference) + (reference).offset_##type))
#define GOB_SET_REFERENCE_FROM_POINTER(reference, pointer) \
(reference).offset = (Gob_Offset)((char *)(pointer) - (char *)&(reference))
#define GOB_GET_SIZE(type, array, count) \
(sizeof(type) - sizeof(((type *)0)->array[0]) + sizeof(((type *)0)->array[0]) * (count))
GOB_DECLARE_REFERENCE_TYPE(Gob_DescriptorTable)
GOB_DECLARE_REFERENCE_TYPE(Gob_String)
GOB_DECLARE_REFERENCE_TYPE(Gob_Buffer)
GOB_DECLARE_REFERENCE_TYPE(Gob_Node)
GOB_DECLARE_REFERENCE_TYPE(Gob_Mesh)
GOB_DECLARE_REFERENCE_TYPE(Gob_Material)
GOB_DECLARE_REFERENCE_TYPE(Gob_Light)
enum {
GOB_SIGNATURE = GOB_FOURCC("GOB ")
};
struct Gob_Header {
uint32_t signature;
Gob_DescriptorTableReference descriptor_table;
};
typedef uint32_t Gob_Type;
enum {
GOB_TYPE_BUFFER = GOB_FOURCC("BUFF"),
GOB_TYPE_MESH = GOB_FOURCC("MESH"),
GOB_TYPE_NODE = GOB_FOURCC("NODE"),
GOB_TYPE_MATERIAL = GOB_FOURCC("MATE"),
GOB_TYPE_LIGHT = GOB_FOURCC("LIGH"),
GOB_TYPE_SCENE = GOB_FOURCC("SCEN")
};
struct Gob_Descriptor {
Gob_Type type;
Gob_Reference reference;
};
struct Gob_DescriptorTable {
uint32_t descriptors_count;
Gob_Descriptor descriptors[1];
};
struct Gob_Buffer {
uint32_t size;
char data[1];
};
struct Gob_BufferRange {
Gob_BufferReference buffer;
uint32_t start;
uint32_t stride;
};
typedef char *Gob_String;
struct Gob_Float2 {
float x;
float y;
};
struct Gob_Float3 {
float x;
float y;
float z;
};
struct Gob_Float4 {
float x;
float y;
float z;
float w;
};
struct Gob_Transform {
Gob_Float3 translation;
Gob_Float3 scale;
Gob_Float4 rotation;
};
typedef uint8_t Gob_NodeKind;
enum {
GOB_TRANSFORM_NODE,
GOB_MESH_NODE,
GOB_LIGHT_NODE
};
struct Gob_Node {
Gob_NodeKind kind;
union {
Gob_MeshReference mesh;
Gob_LightReference light;
};
Gob_StringReference name;
Gob_Transform transform;
uint32_t children_count;
Gob_NodeReference children[1];
};
struct Gob_Material {
// ...
};
struct Gob_IndexBuffer {
uint8_t index_size;
Gob_BufferReference buffer;
};
typedef uint8_t Gob_MeshTopology;
enum {
GOB_TRIANGLE_LIST,
GOB_TRIANGLE_STRIP
};
struct Gob_MeshSection {
uint32_t index_start;
uint32_t index_count;
Gob_MaterialReference material;
};
struct Gob_Mesh {
Gob_MeshTopology topology;
Gob_BufferRange positions;
Gob_BufferRange normals;
Gob_BufferRange tangents;
Gob_BufferRange bitangents;
Gob_IndexBuffer indices;
uint32_t sections_count;
Gob_MeshSection sections[1];
};
typedef uint8_t Gob_LightKind;
enum {
GOB_POINT_LIGHT,
GOB_DIRECTIONAL_LIGHT,
GOB_SPOT_LIGHT
};
struct Gob_Light {
Gob_LightKind kind;
union {
Gob_Float3 point;
Gob_Float3 direction;
};
Gob_Float3 color;
};
struct Gob_Scene {
Gob_NodeReference root;
};
#define GOB_BUFFER(reference) GOB_GET_POINTER_FROM_REFERENCE(Gob_Buffer, reference)
#define GOB_BUFFER_DATA(reference) (GOB_BUFFER(reference)->data)
#define GOB_DESCRIPTOR_TABLE(reference) GOB_GET_POINTER_FROM_REFERENCE(Gob_DescriptorTable, reference)
#define GOB_NODE(reference) GOB_GET_POINTER_FROM_REFERENCE(Gob_Node, reference)
#define GOB_MESH(reference) GOB_GET_POINTER_FROM_REFERENCE(Gob_Mesh, reference)
#pragma pack(pop)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment