1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/*
Software rendering library.
Coordinate systems:
- The coordinate systems for image addressing and texture sampling are the same
except in scale.
Origin is in the top-left corner of the image.
Axes extend down and to the right.
- Image addressing:
(i,j) integer coordinates refer to the center of the pixel.
- Texture addressing:
(u,v) range in [0,1].
(0,0) is the center of the top-left pixel.
(1,1) is the center of the bottom-right pixel.
Multi-threading:
- Internal resources (swgfx context) are externally synchronized.
- External resources (colour buffer) are internally synchronized.
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#define SWGFX_PROFILING 1 // TODO: Move this to client project cmake.
constexpr size_t SWGFX_MAX_TEXTURES = 255;
typedef float R;
typedef struct sgVec2i { int x, y; } sgVec2i;
typedef struct sgVec2 { R x, y; } sgVec2;
typedef struct sgVec3 { union { struct { R r, g, b; }; struct { R x, y, z; }; }; } sgVec3;
typedef struct sgVec4 { union { struct { R r, g, b, a; }; struct { R x, y, z, w; }; struct { sgVec3 rgb; R _; }; }; } sgVec4;
typedef sgVec3 sgNormal;
typedef struct sgVert2i { sgVec2i pos; sgVec2 uv; } sgVert2i;
typedef struct sgVert2 { sgVec2 pos; sgVec2 uv; } sgVert2;
typedef struct sgVert3 { sgVec3 pos; sgVec2 uv; sgVec3 normal; } sgVert3;
typedef struct sgVert4 { sgVec4 pos; sgVec2 uv; sgVec3 normal; } sgVert4;
typedef struct sgQuadi { sgVert2i p0, p1; } sgQuadi;
typedef struct sgQuad { sgVert2 p0, p1; } sgQuad;
typedef struct sgTri2 { sgVert2 p0, p1, p2; } sgTri2;
typedef struct sgTri3 { sgVert3 p0, p1, p2; } sgTri3;
typedef struct sgTri4 { sgVert4 p0, p1, p2; } sgTri4;
typedef uint16_t sgIdx;
typedef struct sgVertIdx { sgIdx pos, uv, normal; } sgVertIdx;
typedef struct sgTriIdx { sgVertIdx v0, v1, v2; } sgTriIdx;
typedef struct sgRgba { uint8_t r, g, b, a; } sgRgba;
typedef struct sgBgra { uint8_t b, g, r, a; } sgBgra;
typedef sgVec3 sgColour3;
typedef sgVec4 sgColour4;
typedef sgRgba sgPixel;
// TODO: Expose a macro to control the desired surface format.
typedef sgBgra sgScreenPixel;
typedef uint16_t sgTextureId;
typedef sgRgba sgTexel;
typedef enum sgTextureFilter {
sgNearest,
sgBilinear
} sgTextureFilter;
typedef struct sgImage {
int width;
int height;
sgTexel* pixels;
} sgImage;
typedef struct swgfx swgfx;
#if SWGFX_PROFILING
typedef struct sgCounters {
uint64_t frames; // Frames drawn.
uint64_t triangles3; // 3D triangles processed.
uint64_t triangles2; // 2D triangles processed.
uint64_t pixels; // Pixels written.
} sgCounters;
#endif // SWGFX_PROFILING
size_t sgMem(int width, int height); // Get memory requirements.
swgfx* sgNew(int width, int height, void* mem);
void sgDel(swgfx**);
// TODO: Write client app first, then implement the functions below in the C file.
sgColour4* sgColourBuffer(swgfx*);
void sgPresent(swgfx*, sgVec2i dimensions, sgScreenPixel* screen);
void sgModelId (swgfx*);
void sgModel (swgfx*, sgVec3 position, sgVec3 right, sgVec3 up, sgVec3 forward);
void sgView (swgfx*, sgVec3 position, sgVec3 forward);
void sgOrtho (swgfx*, R left, R right, R top, R bottom, R near, R far);
void sgPerspective(swgfx*, R fovy, R aspect, R near, R far);
void sgViewport (swgfx*, int x0, int y0, int width, int height);
void sgTextureRegister(swgfx*, sgTextureId, const sgImage*, sgTextureFilter);
void sgTextureActivate(swgfx*, sgTextureId);
void sgClear(swgfx*);
void sgPixels(swgfx*, size_t count, const sgVec2i* positions, sgColour4);
void sgQuads (swgfx*, size_t count, const sgQuad*);
void sgQuadsi(swgfx*, size_t count, const sgQuadi*);
void sgTriangles2 (swgfx*, size_t count, const sgTri2*);
void sgTriangleStrip2(swgfx*, size_t count, const sgVec2*);
void sgTriangles (swgfx*, size_t count, const sgTri3*, const sgNormal*);
void sgTriangleStrip (swgfx*, size_t count, const sgVec3*, const sgNormal*);
void sgTrianglesIndexed(swgfx*, size_t numIndices, const sgIdx* indices, const sgVec3* positions, const sgVec2* texcoords, const sgVec3* normals);
void sgTrianglesIndexedNonUniform(swgfx*, size_t numTris, const sgTriIdx* tris, const sgVec3* positions, const sgVec2* texcoords, const sgVec3* normals);
void sgLighting(swgfx*);
void sgAmbient (swgfx*, sgColour3);
void sgDirectional(swgfx*, sgColour3, sgVec3 direction);
void sgDepth(swgfx*);
void sgNormals(swgfx*);
void sgGamma (sgTexel*, int width, int height);
void sgGammaInv(sgColour4*, int width, int height);
sgCounters sgGetCounters(const swgfx*);
|