diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Graphics.h |
initial commit
Diffstat (limited to 'src/Graphics.h')
-rw-r--r-- | src/Graphics.h | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/src/Graphics.h b/src/Graphics.h new file mode 100644 index 0000000..ff9c204 --- /dev/null +++ b/src/Graphics.h @@ -0,0 +1,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 |