diff --git a/src/Builder.c b/src/Builder.c index 35b9f0600..4871d2303 100644 --- a/src/Builder.c +++ b/src/Builder.c @@ -392,8 +392,7 @@ static cc_bool BuildChunk(int x1, int y1, int z1, struct ChunkInfo* info) { #ifndef CC_BUILD_GL11 /* add an extra element to fix crashing on some GPUs */ - info->Vb = Gfx_CreateVb( VERTEX_FORMAT_P3FT2FC4B, totalVerts + 1); - Builder_Vertices = Gfx_LockVb(info->Vb, VERTEX_FORMAT_P3FT2FC4B, totalVerts + 1); + Builder_Vertices = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FT2FC4B, totalVerts + 1, &info->Vb); #endif Builder_PostStretchTiles(); diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c index 30768fd50..f1d31703a 100644 --- a/src/EnvRenderer.c +++ b/src/EnvRenderer.c @@ -193,9 +193,7 @@ static void UpdateClouds(void) { z1 = -extent; z2 = World.Length + extent; clouds_vertices = CalcNumVertices(x2 - x1, z2 - z1); - clouds_vb = Gfx_CreateVb(VERTEX_FORMAT_P3FT2FC4B, clouds_vertices); - data = Gfx_LockVb(clouds_vb, VERTEX_FORMAT_P3FT2FC4B, clouds_vertices); - + data = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FT2FC4B, clouds_vertices, &clouds_vb); DrawCloudsY(x1, z1, x2, z2, Env.CloudsHeight, data); Gfx_UnlockVb(clouds_vb); } @@ -266,9 +264,7 @@ static void UpdateSky(void) { z1 = -extent; z2 = World.Length + extent; sky_vertices = CalcNumVertices(x2 - x1, z2 - z1); - sky_vb = Gfx_CreateVb( VERTEX_FORMAT_P3FC4B, sky_vertices); - data = Gfx_LockVb(sky_vb, VERTEX_FORMAT_P3FC4B, sky_vertices); - + data = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FC4B, sky_vertices, &sky_vb); height = max((World.Height + 2), Env.CloudsHeight) + 6; DrawSkyY(x1, z1, x2, z2, height, data); Gfx_UnlockVb(sky_vb); @@ -341,9 +337,7 @@ static void UpdateSkybox(void) { if (Gfx.LostContext) return; if (EnvRenderer_Minimal) return; - skybox_vb = Gfx_CreateVb( VERTEX_FORMAT_P3FT2FC4B, SKYBOX_COUNT); - data = Gfx_LockVb(skybox_vb, VERTEX_FORMAT_P3FT2FC4B, SKYBOX_COUNT); - + data = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FT2FC4B, SKYBOX_COUNT, &skybox_vb); Mem_Copy(data, vertices, sizeof(vertices)); for (i = 0; i < SKYBOX_COUNT; i++) { data[i].Col = Env.SkyboxCol; } Gfx_UnlockVb(skybox_vb); @@ -691,12 +685,10 @@ static void UpdateMapSides(void) { } y = Env_SidesHeight; - sides_vertices += CalcNumVertices(World.Width, World.Length); /* YQuads beneath map */ + sides_vertices += CalcNumVertices(World.Width, World.Length); /* YQuads beneath map */ sides_vertices += 2 * CalcNumVertices(World.Width, Math_AbsI(y)); /* ZQuads */ sides_vertices += 2 * CalcNumVertices(World.Length, Math_AbsI(y)); /* XQuads */ - - sides_vb = Gfx_CreateVb( VERTEX_FORMAT_P3FT2FC4B, sides_vertices); - data = Gfx_LockVb(sides_vb, VERTEX_FORMAT_P3FT2FC4B, sides_vertices); + data = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FT2FC4B, sides_vertices, &sides_vb); sides_fullBright = Blocks.FullBright[block]; col = sides_fullBright ? white : Env.ShadowCol; @@ -741,9 +733,7 @@ static void UpdateMapEdges(void) { r = rects[i]; edges_vertices += CalcNumVertices(r.Width, r.Height); /* YPlanes outside */ } - - edges_vb = Gfx_CreateVb( VERTEX_FORMAT_P3FT2FC4B, edges_vertices); - data = Gfx_LockVb(edges_vb, VERTEX_FORMAT_P3FT2FC4B, edges_vertices); + data = Gfx_CreateAndLockVb(VERTEX_FORMAT_P3FT2FC4B, edges_vertices, &edges_vb); edges_fullBright = Blocks.FullBright[block]; col = edges_fullBright ? white : Env.SunCol; diff --git a/src/Graphics.c b/src/Graphics.c index c8fcbc4a1..c710a3d82 100644 --- a/src/Graphics.c +++ b/src/Graphics.c @@ -88,6 +88,11 @@ void Gfx_UpdateDynamicVb_IndexedTris(GfxResourceID vb, void* vertices, int vCoun Gfx_DrawVb_IndexedTris(vCount); } +void* Gfx_CreateAndLockVb(VertexFormat fmt, int count, GfxResourceID* vb) { + *vb = Gfx_CreateVb(fmt, count); + return Gfx_LockVb(*vb, fmt, count); +} + void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol col) { VertexP3fC4b verts[4]; VertexP3fC4b* v = verts; @@ -736,13 +741,6 @@ static void* D3D9_LockVb(GfxResourceID vb, VertexFormat fmt, int count, int lock return dst; } -GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) { - IDirect3DVertexBuffer9* vbuffer; - vbuffer = D3D9_AllocVertexBuffer(fmt, count, D3DUSAGE_WRITEONLY); - D3D9_SetVbData(vbuffer, vertices, count * gfx_strideSizes[fmt], 0); - return vbuffer; -} - GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { return D3D9_AllocVertexBuffer(fmt, count, D3DUSAGE_WRITEONLY); } @@ -1070,6 +1068,17 @@ void Gfx_Free(void) { } #define gl_Toggle(cap) if (enabled) { glEnable(cap); } else { glDisable(cap); } +static void* tmpData; +static int tmpSize; + +static void* FastAllocTempMem(int size) { + if (size <= tmpSize) return tmpData; + Mem_Free(tmpData); + + tmpData = Mem_Alloc(size, 1, "Gfx_AllocTempMemory"); + tmpSize = size; + return tmpData; +} /*########################################################################################################################* @@ -1220,11 +1229,8 @@ void Gfx_DeleteIb(GfxResourceID* ib) { } *------------------------------------------------------Vertex buffers-----------------------------------------------------* *#########################################################################################################################*/ #ifndef CC_BUILD_GL11 -GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) { - GLuint id = GL_GenAndBind(GL_ARRAY_BUFFER); - cc_uint32 size = count * gfx_strideSizes[fmt]; - _glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - return id; +GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { + return GL_GenAndBind(GL_ARRAY_BUFFER); } void Gfx_BindVb(GfxResourceID vb) { _glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); } @@ -1235,6 +1241,14 @@ void Gfx_DeleteVb(GfxResourceID* vb) { _glDeleteBuffers(1, &id); *vb = 0; } + +void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { + return FastAllocTempMem(count * gfx_strideSizes[fmt]); +} + +void Gfx_UnlockVb(GfxResourceID vb) { + _glBufferData(GL_ARRAY_BUFFER, tmpSize, tmpData, GL_STATIC_DRAW); +} #else GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) { GLuint list = glGenLists(1); @@ -1280,18 +1294,13 @@ GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) { return id; } -static void* lockedData; -static int lockedSize; void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { - lockedSize = count * gfx_strideSizes[fmt]; - lockedData = Mem_Alloc(count, gfx_strideSizes[fmt], "Gfx_LockDynamicVb"); - return lockedData; - /* TODO: Reuse buffer instead of always allocating */ + return FastAllocTempMem(count * gfx_strideSizes[fmt]); } void Gfx_UnlockDynamicVb(GfxResourceID vb) { _glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vb); - _glBufferSubData(GL_ARRAY_BUFFER, 0, lockedSize, lockedData); + _glBufferSubData(GL_ARRAY_BUFFER, 0, tmpSize, tmpData); } void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { diff --git a/src/Graphics.h b/src/Graphics.h index dd6b9a12d..03fae133e 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -190,6 +190,8 @@ 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. */ void Gfx_UpdateDynamicVb_IndexedTris(GfxResourceID vb, void* vertices, int vCount); +/* Shorthand for Gfx_CreateVb followed by Gfx_LockVb */ +void* Gfx_CreateAndLockVb(VertexFormat fmt, int count, GfxResourceID* vb); /* Renders a 2D flat coloured rectangle. */ void Gfx_Draw2DFlat(int x, int y, int width, int height, PackedCol col);