diff --git a/src/Graphics.h b/src/Graphics.h index 710c09405..a5fa3e606 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -25,14 +25,14 @@ typedef enum MatrixType_ { #define SIZEOF_VERTEX_TEXTURED 24 #if defined CC_BUILD_PSP -/* 3 floats for position (XYZ), 4 bytes for colour. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* 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 @@ -45,9 +45,9 @@ CC_VAR extern struct _GfxData { float _unused; /* Whether context graphics has been lost (all creation/render calls fail) */ cc_bool LostContext; - /* Whether some textures are created with mipmaps. */ + /* Whether some textures are created with mipmaps */ cc_bool Mipmaps; - /* Whether managed textures are actually supported. */ + /* 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 */ @@ -77,58 +77,58 @@ void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count); /* Creates a new texture. (and also generates mipmaps if mipmaps) */ /* Supported flags: TEXTURE_FLAG_MANAGED, TEXTURE_FLAG_DYNAMIC */ /* 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. */ +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); /* 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. */ +/* Sets the currently active texture */ CC_API void Gfx_BindTexture(GfxResourceID texId); -/* Deletes the given texture, then sets it to 0. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* Returns whether fog blending is enabled */ CC_API cc_bool Gfx_GetFog(void); -/* Sets whether fog blending is enabled. */ +/* Sets whether fog blending is enabled */ CC_API void Gfx_SetFog(cc_bool enabled); -/* Sets the colour of the blended fog. */ +/* Sets the colour of the blended fog */ CC_API void Gfx_SetFogCol(PackedCol col); -/* Sets thickness of fog for FOG_EXP/FOG_EXP2 modes. */ +/* 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. */ +/* Sets extent/end of fog for FOG_LINEAR mode */ CC_API void Gfx_SetFogEnd(float value); -/* Sets in what way fog is blended. */ +/* Sets in what way fog is blended */ CC_API void Gfx_SetFogMode(FogFunc func); -/* Sets whether backface culling is performed. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* Sets whether blending between the alpha components of texture and vertex colour is performed */ CC_API void Gfx_SetAlphaArgBlend(cc_bool enabled); -/* Clears the colour and depth buffer to default. */ +/* Clears the colour and depth buffer to default */ CC_API void Gfx_Clear(void); -/* Sets the colour that the colour buffer is cleared to. */ +/* Sets the colour that the colour buffer is cleared to */ CC_API void Gfx_ClearCol(PackedCol col); -/* Sets whether pixels may be discard based on z/depth. */ +/* Sets whether pixels may be discard based on z/depth */ CC_API void Gfx_SetDepthTest(cc_bool enabled); -/* Sets whether R/G/B/A of pixels are actually written to the colour buffer channels. */ +/* Sets whether R/G/B/A of pixels are actually written to the colour buffer channels */ CC_API void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a); -/* Sets whether z/depth of pixels is actually written to the depth buffer. */ +/* Sets whether z/depth of pixels is actually written to the depth buffer */ CC_API void Gfx_SetDepthWrite(cc_bool enabled); /* Sets whether the game should only write output to depth buffer */ /* NOTE: Implicitly calls Gfx_SetColWriteMask */ @@ -136,25 +136,25 @@ CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly); /* 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. */ +/* 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. */ +/* Sets the currently active index buffer */ CC_API void Gfx_BindIb(GfxResourceID ib); -/* Deletes the given index buffer, then sets it to 0. */ +/* Deletes the given index buffer, then sets it to 0 */ CC_API void Gfx_DeleteIb(GfxResourceID* ib); -/* Creates a new vertex buffer. */ +/* Creates a new vertex buffer */ CC_API GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count); -/* Sets the currently active vertex buffer. */ +/* Sets the currently active vertex buffer */ CC_API void Gfx_BindVb(GfxResourceID vb); -/* Deletes the given vertex buffer, then sets it to 0. */ +/* 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. */ +/* 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. */ +/* 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.. */ +/* 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); @@ -166,39 +166,34 @@ void Gfx_BindVb_Textured(GfxResourceID vb); #define Gfx_BindVb_Textured Gfx_BindVb #endif -/* Creates a new dynamic vertex buffer, whose contents can be updated later. */ +/* Creates a new dynamic vertex buffer, whose contents can be updated later */ CC_API GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices); -#ifndef CC_BUILD_GL11 -/* Static and dynamic vertex buffers are drawn in the same way */ -#define Gfx_BindDynamicVb Gfx_BindVb -#define Gfx_DeleteDynamicVb Gfx_DeleteVb -#else -/* OpenGL 1.1 draws static vertex buffers completely differently. */ -void Gfx_BindDynamicVb(GfxResourceID vb); -void Gfx_DeleteDynamicVb(GfxResourceID* vb); -#endif -/* Acquires temp memory for changing the contents of a dynamic vertex buffer. */ +/* 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. */ +/* Binds then submits the changed contents of a dynamic vertex buffer */ CC_API void Gfx_UnlockDynamicVb(GfxResourceID vb); -/* Sets the format of the rendered vertices. */ +/* Sets the format of the rendered vertices */ CC_API void Gfx_SetVertexFormat(VertexFormat fmt); -/* Updates the data of a dynamic vertex buffer. */ +/* Updates the data of a dynamic vertex buffer */ CC_API void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount); -/* Renders vertices from the currently bound vertex buffer as lines. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* 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); @@ -210,56 +205,56 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f /* 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. */ +/* 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. */ +/* 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. */ +/* Sets up state for rendering a new frame */ void Gfx_BeginFrame(void); -/* Finishes rendering a frame, and swaps it with the back buffer. */ +/* 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. */ +/* 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); -/* Updates state when the window's dimensions have changed. */ -/* NOTE: This may require recreating the context depending on the backend. */ +/* Updates state when the window's dimensions have changed */ +/* NOTE: This may require recreating the context depending on the backend */ void Gfx_OnWindowResize(void); -/* 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. */ +/* 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); -/* Raises ContextLost event and updates state for lost contexts. */ +/* Raises ContextLost event and updates state for lost contexts */ void Gfx_LoseContext(const char* reason); -/* Raises ContextRecreated event and restores internal state. */ +/* Raises ContextRecreated event and restores internal state */ void Gfx_RecreateContext(void); -/* Attempts to restore a lost context. */ +/* Attempts to restore a lost context */ cc_bool Gfx_TryRestoreContext(void); -/* Binds and draws the specified subset of the vertices in the current dynamic vertex buffer. */ -/* NOTE: This replaces the dynamic vertex buffer's data first with the given vertices before drawing. */ +/* Binds and draws the specified subset of the vertices in the current dynamic vertex buffer */ +/* NOTE: This replaces the dynamic vertex buffer's data first with the given vertices before drawing */ void Gfx_UpdateDynamicVb_IndexedTris(GfxResourceID vb, void* vertices, int vCount); -/* Renders a 2D flat coloured rectangle. */ +/* 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. */ +/* 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. */ +/* Renders a 2D coloured texture */ void Gfx_Draw2DTexture(const struct Texture* tex, PackedCol color); -/* Fills out the vertices for rendering a 2D coloured texture. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* 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. */ +/* 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 */ @@ -272,8 +267,8 @@ void Gfx_RestoreAlphaState(cc_uint8 draw); /* 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. */ +/* Binds then renders the given texture */ void Texture_Render(const struct Texture* tex); -/* Binds then renders the given texture. */ +/* Binds then renders the given texture */ void Texture_RenderShaded(const struct Texture* tex, PackedCol shadeColor); #endif diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 8d020abdc..1684acb01 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -371,6 +371,47 @@ void Gfx_UnlockVb(GfxResourceID vb) { tmp = NULL; } + +/*########################################################################################################################* +*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* +*#########################################################################################################################*/ +GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { + // TODO pass true instead + return CreateVertexBuffer(fmt, maxVertices, true); +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { + ID3D11Buffer* buffer = (ID3D11Buffer*)(*vb); + if (buffer) ID3D11Buffer_Release(buffer); + *vb = NULL; +} + +static D3D11_MAPPED_SUBRESOURCE mapDesc; +void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { + ID3D11Buffer* buffer = (ID3D11Buffer*)vb; + mapDesc.pData = NULL; + + HRESULT hr = ID3D11DeviceContext_Map(context, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapDesc); + if (hr) Logger_Abort2(hr, "Failed to lock dynamic VB"); + return mapDesc.pData; +} + +void Gfx_UnlockDynamicVb(GfxResourceID vb) { + ID3D11Buffer* buffer = (ID3D11Buffer*)vb; + ID3D11DeviceContext_Unmap(context, buffer, 0); + Gfx_BindDynamicVb(vb); +} + +void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { + void* data = Gfx_LockDynamicVb(vb, gfx_format, vCount); + Mem_Copy(data, vertices, vCount * gfx_stride); + Gfx_UnlockDynamicVb(vb); +} + + +/*########################################################################################################################* +*-----------------------------------------------------Vertex rendering----------------------------------------------------* +*#########################################################################################################################*/ void Gfx_SetVertexFormat(VertexFormat fmt) { if (fmt == gfx_format) return; gfx_format = fmt; @@ -400,37 +441,6 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { } -/*########################################################################################################################* -*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* -*#########################################################################################################################*/ -GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { - // TODO pass true instead - return CreateVertexBuffer(fmt, maxVertices, true); -} - -static D3D11_MAPPED_SUBRESOURCE mapDesc; -void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { - ID3D11Buffer* buffer = (ID3D11Buffer*)vb; - mapDesc.pData = NULL; - - HRESULT hr = ID3D11DeviceContext_Map(context, buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapDesc); - if (hr) Logger_Abort2(hr, "Failed to lock dynamic VB"); - return mapDesc.pData; -} - -void Gfx_UnlockDynamicVb(GfxResourceID vb) { - ID3D11Buffer* buffer = (ID3D11Buffer*)vb; - ID3D11DeviceContext_Unmap(context, buffer, 0); - Gfx_BindVb(vb); -} - -void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { - void* data = Gfx_LockDynamicVb(vb, gfx_format, vCount); - Mem_Copy(data, vertices, vCount * gfx_stride); - Gfx_UnlockDynamicVb(vb); -} - - /*########################################################################################################################* *---------------------------------------------------------Matrices--------------------------------------------------------* *#########################################################################################################################*/ @@ -517,6 +527,12 @@ void Gfx_BindVb(GfxResourceID vb) { ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset); } +void Gfx_BindDynamicVb(GfxResourceID vb) { + ID3D11Buffer* buffer = (ID3D11Buffer*)vb; + static UINT32 offset[] = { 0 }; + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset); +} + //######################################################################################################################## //--------------------------------------------------------Vertex shader--------------------------------------------------- diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index 436f75b21..a4f3ab2a0 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -631,13 +631,14 @@ GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { return D3D9_AllocVertexBuffer(fmt, count, D3DUSAGE_WRITEONLY); } +void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); } + void Gfx_BindVb(GfxResourceID vb) { IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb; cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_stride); if (res) Logger_Abort2(res, "D3D9_BindVb"); } -void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); } void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { return D3D9_LockVb(vb, fmt, count, 0); } @@ -649,6 +650,44 @@ void Gfx_UnlockVb(GfxResourceID vb) { } +/*########################################################################################################################* +*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* +*#########################################################################################################################*/ +GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { + if (Gfx.LostContext) return 0; + return D3D9_AllocVertexBuffer(fmt, maxVertices, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { D3D9_FreeResource(vb); } + +void Gfx_BindDynamicVb(GfxResourceID vb) { + IDirect3DVertexBuffer9* vbuffer = (IDirect3DVertexBuffer9*)vb; + cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, vbuffer, 0, gfx_stride); + if (res) Logger_Abort2(res, "D3D9_BindDynamicVb"); +} + +void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { + return D3D9_LockVb(vb, fmt, count, D3DLOCK_DISCARD); +} + +void Gfx_UnlockDynamicVb(GfxResourceID vb) { + Gfx_UnlockVb(vb); + Gfx_BindDynamicVb(vb); /* TODO: Inline this? */ +} + +void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { + int size = vCount * gfx_stride; + IDirect3DVertexBuffer9* buffer = (IDirect3DVertexBuffer9*)vb; + D3D9_SetVbData(buffer, vertices, size, D3DLOCK_DISCARD); + + cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, gfx_stride); + if (res) Logger_Abort2(res, "D3D9_SetDynamicVbData - Bind"); +} + + +/*########################################################################################################################* +*-----------------------------------------------------Vertex rendering----------------------------------------------------* +*#########################################################################################################################*/ void Gfx_SetVertexFormat(VertexFormat fmt) { cc_result res; if (fmt == gfx_format) return; @@ -689,33 +728,6 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { } -/*########################################################################################################################* -*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* -*#########################################################################################################################*/ -GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { - if (Gfx.LostContext) return 0; - return D3D9_AllocVertexBuffer(fmt, maxVertices, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); -} - -void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { - return D3D9_LockVb(vb, fmt, count, D3DLOCK_DISCARD); -} - -void Gfx_UnlockDynamicVb(GfxResourceID vb) { - Gfx_UnlockVb(vb); - Gfx_BindVb(vb); /* TODO: Inline this? */ -} - -void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { - int size = vCount * gfx_stride; - IDirect3DVertexBuffer9* buffer = (IDirect3DVertexBuffer9*)vb; - D3D9_SetVbData(buffer, vertices, size, D3DLOCK_DISCARD); - - cc_result res = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, gfx_stride); - if (res) Logger_Abort2(res, "D3D9_SetDynamicVbData - Bind"); -} - - /*########################################################################################################################* *---------------------------------------------------------Matrices--------------------------------------------------------* *#########################################################################################################################*/ diff --git a/src/Graphics_GL1.c b/src/Graphics_GL1.c index 1bdb88471..94c7c8ded 100644 --- a/src/Graphics_GL1.c +++ b/src/Graphics_GL1.c @@ -249,12 +249,13 @@ GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { return id; } -void Gfx_BindVb(GfxResourceID vb) { _glBindBuffer(GL_ARRAY_BUFFER, vb); } +void Gfx_BindVb(GfxResourceID vb) { + _glBindBuffer(GL_ARRAY_BUFFER, vb); +} void Gfx_DeleteVb(GfxResourceID* vb) { GfxResourceID id = *vb; - if (!id) return; - _delBuffer(id); + if (id) _delBuffer(id); *vb = 0; } @@ -330,6 +331,16 @@ GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { return id; } +void Gfx_BindDynamicVb(GfxResourceID vb) { + _glBindBuffer(GL_ARRAY_BUFFER, vb); +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { + GfxResourceID id = *vb; + if (id) _delBuffer(id); + *vb = 0; +} + void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { return FastAllocTempMem(count * strideSizes[fmt]); } @@ -370,6 +381,97 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { #endif +/*########################################################################################################################* +*----------------------------------------------------------Drawing--------------------------------------------------------* +*#########################################################################################################################*/ +#ifdef CC_BUILD_GL11 + /* point to client side dynamic array */ + #define VB_PTR ((cc_uint8*)dynamicListData) + #define IB_PTR gl_indices +#else + /* no client side array, use vertex buffer object */ + #define VB_PTR 0 + #define IB_PTR NULL +#endif + +static void GL_SetupVbColoured(void) { + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 12)); +} + +static void GL_SetupVbTextured(void) { + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 12)); + _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 16)); +} + +static void GL_SetupVbColoured_Range(int startVertex) { + cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED; + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset + 12)); +} + +static void GL_SetupVbTextured_Range(int startVertex) { + cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12)); + _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16)); +} + +void Gfx_SetVertexFormat(VertexFormat fmt) { + if (fmt == gfx_format) return; + gfx_format = fmt; + gfx_stride = strideSizes[fmt]; + + if (fmt == VERTEX_FORMAT_TEXTURED) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_TEXTURE_2D); + + gfx_setupVBFunc = GL_SetupVbTextured; + gfx_setupVBRangeFunc = GL_SetupVbTextured_Range; + } else { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + + gfx_setupVBFunc = GL_SetupVbColoured; + gfx_setupVBRangeFunc = GL_SetupVbColoured_Range; + } +} + +void Gfx_DrawVb_Lines(int verticesCount) { + gfx_setupVBFunc(); + glDrawArrays(GL_LINES, 0, verticesCount); +} + +void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) { +#ifdef CC_BUILD_GL11 + if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } +#endif + gfx_setupVBRangeFunc(startVertex); + _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); +} + +void Gfx_DrawVb_IndexedTris(int verticesCount) { +#ifdef CC_BUILD_GL11 + if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } +#endif + gfx_setupVBFunc(); + _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); +} + +#ifdef CC_BUILD_GL11 +void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { glCallList(activeList); } +#else +void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { + cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12)); + _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16)); + _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); +} +#endif /* !CC_BUILD_GL11 */ + + /*########################################################################################################################* *---------------------------------------------------------Textures--------------------------------------------------------* *#########################################################################################################################*/ @@ -612,95 +714,4 @@ static void GLBackend_Init(void) { } } #endif - - -/*########################################################################################################################* -*----------------------------------------------------------Drawing--------------------------------------------------------* -*#########################################################################################################################*/ -#ifdef CC_BUILD_GL11 -/* point to client side dynamic array */ -#define VB_PTR ((cc_uint8*)dynamicListData) -#define IB_PTR gl_indices -#else -/* no client side array, use vertex buffer object */ -#define VB_PTR 0 -#define IB_PTR NULL -#endif - -static void GL_SetupVbColoured(void) { - _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 0)); - _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + 12)); -} - -static void GL_SetupVbTextured(void) { - _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 0)); - _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 12)); - _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + 16)); -} - -static void GL_SetupVbColoured_Range(int startVertex) { - cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED; - _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset)); - _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset + 12)); -} - -static void GL_SetupVbTextured_Range(int startVertex) { - cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; - _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset)); - _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12)); - _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16)); -} - -void Gfx_SetVertexFormat(VertexFormat fmt) { - if (fmt == gfx_format) return; - gfx_format = fmt; - gfx_stride = strideSizes[fmt]; - - if (fmt == VERTEX_FORMAT_TEXTURED) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnable(GL_TEXTURE_2D); - - gfx_setupVBFunc = GL_SetupVbTextured; - gfx_setupVBRangeFunc = GL_SetupVbTextured_Range; - } else { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_TEXTURE_2D); - - gfx_setupVBFunc = GL_SetupVbColoured; - gfx_setupVBRangeFunc = GL_SetupVbColoured_Range; - } -} - -void Gfx_DrawVb_Lines(int verticesCount) { - gfx_setupVBFunc(); - glDrawArrays(GL_LINES, 0, verticesCount); -} - -void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) { -#ifdef CC_BUILD_GL11 - if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } -#endif - gfx_setupVBRangeFunc(startVertex); - _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); -} - -void Gfx_DrawVb_IndexedTris(int verticesCount) { -#ifdef CC_BUILD_GL11 - if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } -#endif - gfx_setupVBFunc(); - _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); -} - -#ifdef CC_BUILD_GL11 -void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { glCallList(activeList); } -#else -void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { - cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; - _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset)); - _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 12)); - _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset + 16)); - _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); -} -#endif /* !CC_BUILD_GL11 */ #endif diff --git a/src/Graphics_GL2.c b/src/Graphics_GL2.c index 9b5e8455c..7bf785b7b 100644 --- a/src/Graphics_GL2.c +++ b/src/Graphics_GL2.c @@ -129,12 +129,13 @@ GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { return GL_GenAndBind(GL_ARRAY_BUFFER); } -void Gfx_BindVb(GfxResourceID vb) { glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); } +void Gfx_BindVb(GfxResourceID vb) { + glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); +} void Gfx_DeleteVb(GfxResourceID* vb) { GLuint id = (GLuint)(*vb); - if (!id) return; - glDeleteBuffers(1, &id); + if (id) glDeleteBuffers(1, &id); *vb = 0; } @@ -161,6 +162,16 @@ GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { return id; } +void Gfx_BindDynamicVb(GfxResourceID vb) { + glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { + GLuint id = (GLuint)(*vb); + if (id) glDeleteBuffers(1, &id); + *vb = 0; +} + void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { return FastAllocTempMem(count * strideSizes[fmt]); } diff --git a/src/_GLShared.h b/src/_GLShared.h index 68c7b6a6b..fda94d846 100644 --- a/src/_GLShared.h +++ b/src/_GLShared.h @@ -163,8 +163,7 @@ void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* par void Gfx_DeleteTexture(GfxResourceID* texId) { GLuint id = (GLuint)(*texId); - if (!id) return; - glDeleteTextures(1, &id); + if (id) glDeleteTextures(1, &id); *texId = 0; }