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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
|
#ifndef CC_GFXAPI_H
#define CC_GFXAPI_H
#include "Vectors.h"
#include "PackedCol.h"
/*
Abstracts a 3D graphics rendering API
Copyright 2014-2023 ClassiCube | Licensed under BSD-3
*/
struct Bitmap;
struct Stream;
struct IGameComponent;
extern struct IGameComponent Gfx_Component;
typedef enum VertexFormat_ {
VERTEX_FORMAT_COLOURED, VERTEX_FORMAT_TEXTURED
} VertexFormat;
typedef enum FogFunc_ {
FOG_LINEAR, FOG_EXP, FOG_EXP2
} FogFunc;
typedef enum MatrixType_ {
MATRIX_PROJECTION, MATRIX_VIEW
} MatrixType;
#define SIZEOF_VERTEX_COLOURED 16
#define SIZEOF_VERTEX_TEXTURED 24
#if defined CC_BUILD_PSP
/* 3 floats for position (XYZ), 4 bytes for colour */
struct VertexColoured { PackedCol Col; float x, y, z; };
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour */
struct VertexTextured { float U, V; PackedCol Col; float x, y, z; };
#else
/* 3 floats for position (XYZ), 4 bytes for colour */
struct VertexColoured { float x, y, z; PackedCol Col; };
/* 3 floats for position (XYZ), 2 floats for texture coordinates (UV), 4 bytes for colour */
struct VertexTextured { float x, y, z; PackedCol Col; float U, V; };
#endif
void Gfx_Create(void);
void Gfx_Free(void);
CC_VAR extern struct _GfxData {
/* Maximum dimensions in pixels that a texture can be created up to */
/* NOTE: usually 1024 to 16384 */
int MaxTexWidth, MaxTexHeight;
/* Maximum total size in pixels a texture can consist of */
/* NOTE: Not all graphics backends specify a value for this */
int MaxTexSize;
/* Whether context graphics has been lost (all creation/render calls fail) */
cc_bool LostContext;
/* Whether some textures are created with mipmaps */
cc_bool Mipmaps;
/* Whether managed textures are actually supported */
/* If not, you must free/create them just like normal textures */
cc_bool ManagedTextures;
/* Whether graphics context has been created */
cc_bool Created;
struct Matrix View, Projection;
/* Whether the graphics backend supports non power of two textures */
cc_bool SupportsNonPowTwoTextures;
/* Maximum total size in pixels a low resolution texture can consist of */
/* NOTE: Not all graphics backends specify a value for this */
int MaxLowResTexSize;
/* Minimum dimensions in pixels that a texture must be */
/* NOTE: Most graphics backends do not use this */
int MinTexWidth, MinTexHeight;
cc_bool ReducedPerfMode;
cc_uint8 ReducedPerfModeCooldown;
} Gfx;
extern GfxResourceID Gfx_defaultIb;
extern const cc_string Gfx_LowPerfMessage;
#define ICOUNT(verticesCount) (((verticesCount) >> 2) * 6)
#define GFX_MAX_INDICES (65536 / 4 * 6)
#define GFX_MAX_VERTICES 65536
typedef enum GfxBuffers_ {
GFX_BUFFER_COLOR = 1,
GFX_BUFFER_DEPTH = 2
} GfxBuffers;
/* Texture should persist across gfx context loss (if backend supports ManagedTextures) */
#define TEXTURE_FLAG_MANAGED 0x01
/* Texture should allow updating via Gfx_UpdateTexture */
#define TEXTURE_FLAG_DYNAMIC 0x02
/* Texture is deliberately (and not accidentally) being created with non power of two dimensions */
#define TEXTURE_FLAG_NONPOW2 0x04
/* Texture can fallback to 16 bpp when necessary (most backends don't do this) */
#define TEXTURE_FLAG_LOWRES 0x08
void Gfx_RecreateTexture(GfxResourceID* tex, struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count);
cc_bool Gfx_CheckTextureSize(int width, int height, cc_uint8 flags);
/* Creates a new texture. (and also generates mipmaps if mipmaps) */
/* See TEXTURE_FLAG values for supported flags */
/* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures
use mipmapping may be either a per-texture or global state depending on the backend */
CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
GfxResourceID Gfx_CreateTexture2(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps);
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
CC_API void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps);
/* Updates a region of the given texture. (and mipmapped regions if mipmaps) */
/* NOTE: rowWidth is in pixels (so for normal bitmaps, rowWidth equals width) */ /* OBSOLETE */
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps);
/* Sets the currently active texture */
CC_API void Gfx_BindTexture(GfxResourceID texId);
/* Deletes the given texture, then sets it to 0 */
CC_API void Gfx_DeleteTexture(GfxResourceID* texId);
/* NOTE: Completely useless now, and does nothing in all graphics backends */
/* (used to set whether texture colour is used when rendering vertices) */
CC_API void Gfx_SetTexturing(cc_bool enabled);
/* Turns on mipmapping. (if Gfx_Mipmaps is enabled) */
/* NOTE: You must have created textures with mipmaps true for this to work */
CC_API void Gfx_EnableMipmaps(void);
/* Turns off mipmapping. (if Gfx_Mipmaps is enabled) */
/* NOTE: You must have created textures with mipmaps true for this to work */
CC_API void Gfx_DisableMipmaps(void);
/* Returns whether fog blending is enabled */
CC_API cc_bool Gfx_GetFog(void);
/* Sets whether fog blending is enabled */
CC_API void Gfx_SetFog(cc_bool enabled);
/* Sets the colour of the blended fog */
CC_API void Gfx_SetFogCol(PackedCol col);
/* Sets thickness of fog for FOG_EXP/FOG_EXP2 modes */
CC_API void Gfx_SetFogDensity(float value);
/* Sets extent/end of fog for FOG_LINEAR mode */
CC_API void Gfx_SetFogEnd(float value);
/* Sets in what way fog is blended */
CC_API void Gfx_SetFogMode(FogFunc func);
/* Sets whether backface culling is performed */
CC_API void Gfx_SetFaceCulling(cc_bool enabled);
/* Sets whether pixels with an alpha of less than 128 are discarded */
CC_API void Gfx_SetAlphaTest(cc_bool enabled);
/* Sets whether existing and new pixels are blended together */
CC_API void Gfx_SetAlphaBlending(cc_bool enabled);
/* Sets whether blending between the alpha components of texture and vertex colour is performed */
CC_API void Gfx_SetAlphaArgBlend(cc_bool enabled);
/* Clears the given rendering buffer(s) to default. */
/* buffers can be either GFX_BUFFER_COLOR or GFX_BUFFER_DEPTH, or both */
CC_API void Gfx_ClearBuffers(GfxBuffers buffers);
/* Sets the colour that the colour buffer is cleared to */
CC_API void Gfx_ClearColor(PackedCol color);
/* Sets whether pixels may be discard based on z/depth */
CC_API void Gfx_SetDepthTest(cc_bool enabled);
/* Sets whether z/depth of pixels is actually written to the depth buffer */
CC_API void Gfx_SetDepthWrite(cc_bool enabled);
/* Sets whether R/G/B/A of pixels are actually written to the colour buffer channels */
CC_API void Gfx_SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a);
/* Sets whether the game should only write output to depth buffer */
/* NOTE: Implicitly calls Gfx_SetColorWrite */
CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly);
/* Anaglyph 3D rendering support */
void Gfx_Set3DLeft( struct Matrix* proj, struct Matrix* view);
void Gfx_Set3DRight(struct Matrix* proj, struct Matrix* view);
void Gfx_End3D( struct Matrix* proj, struct Matrix* view);
/* Callback function to initialise/fill out the contents of an index buffer */
typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj);
/* Creates a new index buffer and fills out its contents */
CC_API GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj);
/* Sets the currently active index buffer */
CC_API void Gfx_BindIb(GfxResourceID ib);
/* Deletes the given index buffer, then sets it to 0 */
CC_API void Gfx_DeleteIb(GfxResourceID* ib);
/* Creates a new vertex buffer */
CC_API GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count);
/* Sets the currently active vertex buffer */
CC_API void Gfx_BindVb(GfxResourceID vb);
/* Deletes the given vertex buffer, then sets it to 0 */
CC_API void Gfx_DeleteVb(GfxResourceID* vb);
/* Acquires temp memory for changing the contents of a vertex buffer */
CC_API void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count);
/* Submits the changed contents of a vertex buffer */
CC_API void Gfx_UnlockVb(GfxResourceID vb);
/* TODO: How to make LockDynamicVb work with OpenGL 1.1 Builder stupidity. */
#ifdef CC_BUILD_GL11
/* Special case of Gfx_Create/LockVb for building chunks in Builder.c */
GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count);
#endif
#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL2
/* Special case Gfx_BindVb for use with Gfx_DrawIndexedTris_T2fC4b */
void Gfx_BindVb_Textured(GfxResourceID vb);
#else
#define Gfx_BindVb_Textured Gfx_BindVb
#endif
/* Creates a new dynamic vertex buffer, whose contents can be updated later */
CC_API GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices);
/* Sets the active vertex buffer to the given dynamic vertex buffer */
CC_API void Gfx_BindDynamicVb(GfxResourceID vb);
/* Deletes the given dynamic vertex buffer, then sets it to 0 */
CC_API void Gfx_DeleteDynamicVb(GfxResourceID* vb);
/* Acquires temp memory for changing the contents of a dynamic vertex buffer */
CC_API void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count);
/* Binds then submits the changed contents of a dynamic vertex buffer */
CC_API void Gfx_UnlockDynamicVb(GfxResourceID vb);
/* Updates the data of a dynamic vertex buffer */
CC_API void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount);
/* Sets the format of the rendered vertices */
CC_API void Gfx_SetVertexFormat(VertexFormat fmt);
/* Renders vertices from the currently bound vertex buffer as lines */
CC_API void Gfx_DrawVb_Lines(int verticesCount);
/* Renders vertices from the currently bound vertex and index buffer as triangles */
/* NOTE: Offsets each index by startVertex */
CC_API void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex);
/* Renders vertices from the currently bound vertex and index buffer as triangles */
CC_API void Gfx_DrawVb_IndexedTris(int verticesCount);
/* Special case Gfx_DrawVb_IndexedTris_Range for map renderer */
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex);
/* Loads the given matrix over the currently active matrix */
CC_API void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix);
/* Loads the identity matrix over the currently active matrix */
CC_API void Gfx_LoadIdentityMatrix(MatrixType type);
CC_API void Gfx_EnableTextureOffset(float x, float y);
CC_API void Gfx_DisableTextureOffset(void);
/* Calculates an orthographic projection matrix suitable with this backend. (usually for 2D) */
void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar);
/* Calculates a perspective projection matrix suitable with this backend. (usually for 3D) */
void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar);
/* NOTE: Projection matrix calculation is here because it can depend the graphics backend */
/* (e.g. OpenGL uses a Z clip space range of [-1, 1], whereas Direct3D9 uses [0, 1]) */
/* Outputs a .png screenshot of the backbuffer */
cc_result Gfx_TakeScreenshot(struct Stream* output);
/* Warns in chat if the backend has problems with the user's GPU */
/* Returns whether legacy rendering mode for borders/sky/clouds is needed */
cc_bool Gfx_WarnIfNecessary(void);
/* Sets up state for rendering a new frame */
void Gfx_BeginFrame(void);
/* Finishes rendering a frame, and swaps it with the back buffer */
void Gfx_EndFrame(void);
/* Sets whether to synchronise with monitor refresh to avoid tearing, and maximum frame rate */
/* NOTE: VSync setting may be unsupported or just ignored */
void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMillis);
/* Gets information about the user's GPU and current backend state */
/* Backend state may include depth buffer bits, free memory, etc */
/* NOTE: Each line is separated by \n */
void Gfx_GetApiInfo(cc_string* info);
/* Updates state when the window's dimensions have changed */
/* NOTE: This may require recreating the context depending on the backend */
void Gfx_OnWindowResize(void);
void Gfx_SetViewport(int x, int y, int w, int h);
enum Screen3DS { TOP_SCREEN, BOTTOM_SCREEN };
#ifdef CC_BUILD_DUALSCREEN
/* Selects which screen on the 3DS to render to */
void Gfx_3DS_SetRenderScreen(enum Screen3DS screen);
#else
static inline
void Gfx_3DS_SetRenderScreen(enum Screen3DS screen) { }
#endif
/* Raises ContextLost event and updates state for lost contexts */
void Gfx_LoseContext(const char* reason);
/* Raises ContextRecreated event and restores internal state */
void Gfx_RecreateContext(void);
/* Attempts to restore a lost context */
cc_bool Gfx_TryRestoreContext(void);
/* Renders a 2D flat coloured rectangle */
void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol color);
/* Renders a 2D flat vertical gradient rectangle */
void Gfx_Draw2DGradient(int x, int y, int width, int height, PackedCol top, PackedCol bottom);
/* Renders a 2D coloured texture */
void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color);
/* Fills out the vertices for rendering a 2D coloured texture */
void Gfx_Make2DQuad(const struct Texture* tex, PackedCol color, struct VertexTextured** vertices);
/* Switches state to be suitable for drawing 2D graphics */
/* NOTE: This means turning off fog/depth test, changing matrices, etc.*/
void Gfx_Begin2D(int width, int height);
/* Switches state to be suitable for drawing 3D graphics */
/* NOTE: This means restoring fog/depth test, restoring matrices, etc */
void Gfx_End2D(void);
/* Sets appropriate alpha test/blending for given block draw type */
void Gfx_SetupAlphaState(cc_uint8 draw);
/* Undoes changes to alpha test/blending state by Gfx_SetupAlphaState */
void Gfx_RestoreAlphaState(cc_uint8 draw);
/* Statically initialises the position and dimensions of this texture */
#define Tex_Rect(x,y, width,height) x,y,width,height
/* Statically initialises the texture coordinate corners of this texture */
#define Tex_UV(u1,v1, u2,v2) { u1,v1,u2,v2 }
/* Sets the position and dimensions of this texture */
#define Tex_SetRect(tex, xVal,yVal, wVal, hVal) tex.x = xVal; tex.y = yVal; tex.width = wVal; tex.height = hVal;
/* Sets texture coordinate corners of this texture */
/* Useful to only draw a sub-region of the texture's pixels */
#define Tex_SetUV(tex, U1,V1, U2,V2) tex.uv.u1 = U1; tex.uv.v1 = V1; tex.uv.u2 = U2; tex.uv.v2 = V2;
/* Binds then renders the given texture */
void Texture_Render(const struct Texture* tex);
/* Binds then renders the given texture */
void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor);
#endif
|