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
|
/*
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 { R x, y, z; } sgVec3;
typedef struct sgVec4 { R x, y, z, w; } 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 sgBgra { uint8_t b, g, r, a; } sgBgra;
typedef struct sgRgba { uint8_t r, g, b, a; } sgRgba;
// TODO: Should we use real-valued colours?
typedef sgRgba sgPixel;
// TODO: Expose a macro to control the desired surface format.
typedef sgBgra sgScreenPixel;
typedef uint16_t sgTextureId;
typedef enum sgTextureFilter {
sgNearest,
sgBilinear
} sgTextureFilter;
typedef struct sgImage {
int width;
int height;
sgPixel* 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.
sgPixel* 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, sgPixel colour);
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*, sgVec3 ambient);
// TODO: Implement directional lights.
void sgDepth(swgfx*);
void sgNormals(swgfx*);
void sgGamma (swgfx*, sgPixel*, int width, int height);
void sgGammaInv(swgfx*, sgPixel*, int width, int height);
sgCounters sgGetCounters(const swgfx*);
|