From 48430d9b1a648508f068b7714b68e6cb32a8bfba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 21:15:53 +0200 Subject: [PATCH 01/32] - don't assume that deserializing an actor will result in a valid pointer. This addresses a very strange crash I encounteded while travelling in a hub, and ended up with a NULL pointer after the 'Serialize' call which means that some code cleared the variable that is currently being deserialized. I was completely unable to find out what caused this because there is so much recursion going on in the deserializer. All actions on the deserialized actor are now being done with a local copy of that variable so that altering the actual one won't have any adverse effects. --- src/farchive.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/farchive.cpp b/src/farchive.cpp index 6697fd5b72..317abe702f 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1194,6 +1194,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype) const PClass *type; BYTE playerNum; DWORD index; + DObject *newobj; operator<< (objHead); @@ -1255,11 +1256,11 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype) case NEW_CLS_OBJ: type = ReadClass (wanttype); // Printf ("New class: %s (%u)\n", type->Name, m_File->Tell()); - obj = type->CreateNew (); + newobj = obj = type->CreateNew (); MapObject (obj); - obj->SerializeUserVars (*this); - obj->Serialize (*this); - obj->CheckIfSerialized (); + newobj->SerializeUserVars (*this); + newobj->Serialize (*this); + newobj->CheckIfSerialized (); break; case NEW_PLYR_OBJ: From 9ca6764556aa07e94d5928ae7a8ad7d0b5aaed82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 21:41:17 +0200 Subject: [PATCH 02/32] Revert "- removed STAT_INVENTORY." This reverts commit 5ff0abe5681a519f05c1339c6d01e3e970178a81. - use STAT_INVENTORY only for held items. Seems this was causing some strange issues with hubs, but for items placed in the world it still cannot be allowed to have them in a different statnum. --- src/g_level.cpp | 2 +- src/g_shared/a_pickups.cpp | 2 ++ src/statnums.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 349d8f5a6e..e47cbb4a55 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1280,7 +1280,7 @@ void G_FinishTravel () for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { - inv->ChangeStatNum (STAT_DEFAULT); + inv->ChangeStatNum (STAT_INVENTORY); inv->LinkToWorld (); inv->Travelled (); } diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index e41a91d2f9..c723662016 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -821,6 +821,7 @@ void AInventory::BecomeItem () } RemoveFromHash (); flags &= ~MF_SPECIAL; + ChangeStatNum(STAT_INVENTORY); SetState (FindState("Held")); } @@ -847,6 +848,7 @@ void AInventory::BecomePickup () } flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM; renderflags &= ~RF_INVISIBLE; + ChangeStatNum(STAT_DEFAULT); SetState (SpawnState); } diff --git a/src/statnums.h b/src/statnums.h index 45bb53e654..7f691e232a 100644 --- a/src/statnums.h +++ b/src/statnums.h @@ -53,7 +53,7 @@ enum STAT_BOSSTARGET, // A boss brain target STAT_LIGHTNING, // The lightning thinker STAT_DECALTHINKER, // An object that thinks for a decal - UNUSED_STAT_INVENTORY, // An inventory item (value kept for savegame compatibility.) + STAT_INVENTORY, // An inventory item STAT_LIGHT, // A sector light effect STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!! STAT_EARTHQUAKE, // Earthquake actors From 4ab8ca63cec13c2b8cf6b344b06f22d27ff36ee8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 22:23:31 +0200 Subject: [PATCH 03/32] - use more desctiptive names for the predefined vertex buffer indices. --- src/gl/compatibility/gl_20.cpp | 2 ++ src/gl/data/gl_vertexbuffer.h | 7 +++++++ src/gl/renderer/gl_postprocess.cpp | 2 +- src/gl/renderer/gl_quaddrawer.cpp | 2 +- src/gl/scene/gl_wall.h | 3 +++ src/gl/scene/gl_walls.cpp | 5 +++++ 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index fb4064d3bb..c1ba2d2db7 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -772,11 +772,13 @@ void GLWall::RenderLightsCompat(int pass) } if (PrepareLight(light, pass)) { + vertcount = 0; RenderWall(RWF_TEXTURED, NULL); } node = node->nextLight; } memcpy(tcs, save, sizeof(tcs)); + vertcount = 0; } //========================================================================== diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index c9abae0dad..5e6912a10c 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -83,6 +83,13 @@ class FFlatVertexBuffer : public FVertexBuffer static const unsigned int BUFFER_SIZE_TO_USE = 1999500; public: + enum + { + QUAD_INDEX = 0, + FULLSCREEN_INDEX = 4, + PRESENT_INDEX = 8 + }; + TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x FFlatVertexBuffer(int width, int height); diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index a9aec57c68..c1b39e5563 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -114,7 +114,7 @@ void FGLRenderer::RenderScreenQuad() { mVBO->BindVBO(); gl_RenderState.ResetVertexBuffer(); - glDrawArrays(GL_TRIANGLE_STRIP, 8, 4); + glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } //----------------------------------------------------------------------------- diff --git a/src/gl/renderer/gl_quaddrawer.cpp b/src/gl/renderer/gl_quaddrawer.cpp index 4dbd52a98f..eedac12e52 100644 --- a/src/gl/renderer/gl_quaddrawer.cpp +++ b/src/gl/renderer/gl_quaddrawer.cpp @@ -81,6 +81,6 @@ void FQuadDrawer::DoRender(int type) glUniformMatrix4fv(shader->vertexmatrix_index, 1, false, matV); glUniformMatrix4fv(shader->texcoordmatrix_index, 1, false, matT); glUniform1i(shader->quadmode_index, 1); - GLRenderer->mVBO->RenderArray(type, 0, 4); + GLRenderer->mVBO->RenderArray(type, FFlatVertexBuffer::QUAD_INDEX, 4); glUniform1i(shader->quadmode_index, 0); } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 674d7fffd1..59f21dc378 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -172,6 +172,9 @@ public: float zceil[2]; float zfloor[2]; + unsigned int vertindex; + unsigned int vertcount; + public: seg_t * seg; // this gives the easiest access to all other structs involved subsector_t * sub; // For polyobjects diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index d8cef97713..54ba8c731b 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1467,6 +1467,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) // note: we always have a valid sidedef and linedef reference when getting here. this->seg = seg; + vertindex = 0; + vertcount = 0; if ((seg->sidedef->Flags & WALLF_POLYOBJ) && seg->backsector) { @@ -1760,6 +1762,9 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * float ffh = frontsector->GetPlaneTexZ(sector_t::floor); float bfh = backsector->GetPlaneTexZ(sector_t::floor); + + vertindex = 0; + vertcount = 0; if (bfh > ffh) { this->seg = seg; From 8cf53f04e87151fbf317a1ad5f71d41dc0eb7abd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 22:54:08 +0200 Subject: [PATCH 04/32] - split off the vertex creation from RenderWall. --- src/gl/scene/gl_wall.h | 1 + src/gl/scene/gl_walls_draw.cpp | 57 ++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 59f21dc378..f8d8ef1bba 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -195,6 +195,7 @@ private: void SetupLights(); bool PrepareLight(ADynamicLight * light, int pass); + void MakeVertices(bool nosplit); void RenderWall(int textured, unsigned int *store = NULL); void RenderTextured(int rflags); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 5c0455fdb6..9f0d168a48 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -167,6 +167,36 @@ void GLWall::SetupLights() dynlightindex = GLRenderer->mLights->UploadLights(lightdata); } +//========================================================================== +// +// build the vertices for this wall +// +//========================================================================== + +void GLWall::MakeVertices(bool nosplit) +{ + if (vertcount == 0) + { + bool split = (gl_seamless && !nosplit && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + + ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); + ptr++; + if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); + ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); + ptr++; + if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr); + ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); + ptr++; + if (split && glseg.fracright == 1) SplitRightEdge(ptr); + ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); + ptr++; + if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr); + vertcount = GLRenderer->mVBO->GetCount(ptr, &vertindex); + } +} + //========================================================================== // @@ -177,31 +207,18 @@ void GLWall::SetupLights() void GLWall::RenderWall(int textured, unsigned int *store) { - bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); - if (!(textured & RWF_NORENDER)) { gl_RenderState.Apply(); gl_RenderState.ApplyLightIndex(dynlightindex); } - - // the rest of the code is identical for textured rendering and lights - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - unsigned int count, offset; - - ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); - ptr++; - if (split && glseg.fracleft == 0) SplitLeftEdge(ptr); - ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); - ptr++; - if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr); - ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); - ptr++; - if (split && glseg.fracright == 1) SplitRightEdge(ptr); - ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); - ptr++; - if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr); - count = GLRenderer->mVBO->GetCount(ptr, &offset); + + if (gl.buffermethod != BM_DEFERRED) + { + MakeVertices(!(textured&RWF_NOSPLIT)); + } + + unsigned int count = vertcount, offset = vertindex; if (!(textured & RWF_NORENDER)) { GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count); From 8f331f56e29116fbe45c46ce5dcedc7e465b3c9f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 23:02:43 +0200 Subject: [PATCH 05/32] - use MakeVertices directly in the portal code and remove all related code from RenderWall. --- src/gl/compatibility/gl_20.cpp | 2 +- src/gl/scene/gl_portal.cpp | 4 +++- src/gl/scene/gl_wall.h | 2 +- src/gl/scene/gl_walls_draw.cpp | 24 +++++------------------- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index c1ba2d2db7..f052564527 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -773,7 +773,7 @@ void GLWall::RenderLightsCompat(int pass) if (PrepareLight(light, pass)) { vertcount = 0; - RenderWall(RWF_TEXTURED, NULL); + RenderWall(RWF_TEXTURED); } node = node->nextLight; } diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 559c149763..bb71668053 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -152,7 +152,9 @@ void GLPortal::DrawPortalStencil() for (unsigned int i = 0; imVBO->RenderArray(GL_TRIANGLE_FAN, offset, count); - vertexcount += count; - } - if (store != NULL) - { - store[0] = offset; - store[1] = count; - } + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, vertindex, vertcount); + vertexcount += vertcount; } //========================================================================== From 4598c4138c98350d8059dc334105d9ed964df8f6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 23:13:49 +0200 Subject: [PATCH 06/32] - added vertex initialization for walls in the processing pass for core profile without persistent buffers. This is slower than doing it in the render pass so it's only active when actually needed - it's also slower than using a client array so this code only gets used when there is no choice but to work with a 3.x core profile context. --- src/gl/scene/gl_drawinfo.cpp | 2 ++ src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_walls.cpp | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 1d39369483..8424230943 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -325,6 +325,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) if (gl.glslversion < 1.3f) { GLWall * ws1; + ws->vertcount = 0; // invalidate current vertices. ws1=&walls[walls.Size()-1]; ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated! float newtexv = ws->tcs[GLWall::UPLFT].v + ((ws->tcs[GLWall::LOLFT].v - ws->tcs[GLWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]); @@ -467,6 +468,7 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0])); float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0])); + ws->vertcount = 0; // invalidate current vertices. GLWall w=*ws; AddWall(&w); ws1=&walls[walls.Size()-1]; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 24fd9a678f..ef82472e05 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -526,7 +526,7 @@ void gl_FillScreen() gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); // The fullscreen quad is stored at index 4 in the main vertex buffer. - glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); + glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); } //========================================================================== diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 54ba8c731b..3afde063cd 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -135,6 +135,7 @@ void GLWall::PutWall(bool translucent) if (translucent) // translucent walls { ViewDistance = (ViewPos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared(); + if (gl.buffermethod == BM_DEFERRED) MakeVertices(true); gl_drawinfo->drawlists[GLDL_TRANSLUCENT].AddWall(this); } else @@ -157,16 +158,19 @@ void GLWall::PutWall(bool translucent) { list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; } + if (gl.buffermethod == BM_DEFERRED) MakeVertices(false); gl_drawinfo->drawlists[list].AddWall(this); } lightlist = NULL; + vertcount = 0; // make sure that following parts of the same linedef do not get this one's vertex info. } void GLWall::PutPortal(int ptype) { GLPortal * portal; + if (gl.buffermethod == BM_DEFERRED) MakeVertices(false); switch (ptype) { // portals don't go into the draw list. @@ -237,6 +241,7 @@ void GLWall::PutPortal(int ptype) portal->AddLine(this); break; } + vertcount = 0; } //========================================================================== // From 76d7b52fcdbbb7d27f1e02606fb7988563ae58f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 23:20:23 +0200 Subject: [PATCH 07/32] - handle the case where a wall gets drawn with an unmapped buffer and no vertex data. This uses the quad drawer because it can only happen with translucent walls that got split during sorting. --- src/gl/scene/gl_walls_draw.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index a8ae5fc794..585ced1a8f 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -60,6 +60,7 @@ #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" +#include "gl/renderer/gl_quaddrawer.h" EXTERN_CVAR(Bool, gl_seamless) @@ -213,6 +214,20 @@ void GLWall::RenderWall(int textured) { MakeVertices(!(textured&RWF_NOSPLIT)); } + else if (vertcount == 0) + { + // in case we get here without valid vertex data and no ability to create them now, + // use the quad drawer as fallback (without edge splitting.) + // This can only happen in one special situation, when a translucent line got split during sorting. + FQuadDrawer qd; + qd.Set(0, glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); + qd.Set(1, glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); + qd.Set(2, glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); + qd.Set(3, glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); + qd.Render(GL_TRIANGLE_FAN); + vertexcount += 4; + return; + } GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, vertindex, vertcount); vertexcount += vertcount; } From b83c2056a8a1d36eb037f461ad17a11a42a444f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 00:01:51 +0200 Subject: [PATCH 08/32] - store the stencil caps in the reserved part of the main vertex buffer instead of constantly recreating them. --- src/gl/data/gl_vertexbuffer.cpp | 13 ++++++++++++- src/gl/data/gl_vertexbuffer.h | 6 +++++- src/gl/scene/gl_portal.cpp | 29 +++++++---------------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 05fd475c07..7e77849545 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -153,7 +153,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) map = new FFlatVertex[BUFFER_SIZE]; } mIndex = mCurIndex = 0; - mNumReserved = 12; + mNumReserved = NUM_RESERVED; vbo_shadowdata.Resize(mNumReserved); // the first quad is reserved for handling coordinates through uniforms. @@ -174,6 +174,17 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) vbo_shadowdata[10].Set(1.0f, -1.0f, 0, 1.f, 0.0f); vbo_shadowdata[11].Set(1.0f, 1.0f, 0, 1.f, 1.f); + // The next two are the stencil caps. + vbo_shadowdata[12].Set(-32767.0f, 32767.0f, -32767.0f, 0, 0); + vbo_shadowdata[13].Set(-32767.0f, 32767.0f, 32767.0f, 0, 0); + vbo_shadowdata[14].Set(32767.0f, 32767.0f, 32767.0f, 0, 0); + vbo_shadowdata[15].Set(32767.0f, 32767.0f, -32767.0f, 0, 0); + + vbo_shadowdata[16].Set(-32767.0f, -32767.0f, -32767.0f, 0, 0); + vbo_shadowdata[17].Set(-32767.0f, -32767.0f, 32767.0f, 0, 0); + vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0); + vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0); + } FFlatVertexBuffer::~FFlatVertexBuffer() diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 5e6912a10c..68f1013675 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -87,7 +87,11 @@ public: { QUAD_INDEX = 0, FULLSCREEN_INDEX = 4, - PRESENT_INDEX = 8 + PRESENT_INDEX = 8, + STENCILTOP_INDEX = 12, + STENCILBOTTOM_INDEX = 16, + + NUM_RESERVED = 20 }; TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index bb71668053..628e0f915c 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -147,40 +147,25 @@ void GLPortal::DrawPortalStencil() { if (mPrimIndices.Size() == 0) { - bool cap = NeedCap() && lines.Size() > 1; - mPrimIndices.Resize(2 * lines.Size() + 4 * cap); + mPrimIndices.Resize(2 * lines.Size()); - for (unsigned int i = 0; imVBO->GetBuffer(); - ptr[0].Set(-32767.0f, 32767.0f, -32767.0f, 0, 0); - ptr[1].Set(-32767.0f, 32767.0f, 32767.0f, 0, 0); - ptr[2].Set(32767.0f, 32767.0f, 32767.0f, 0, 0); - ptr[3].Set(32767.0f, 32767.0f, -32767.0f, 0, 0); - ptr += 4; - mPrimIndices[n + 1] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n]); - ptr[0].Set(-32767.0f, -32767.0f, -32767.0f, 0, 0); - ptr[1].Set(-32767.0f, -32767.0f, 32767.0f, 0, 0); - ptr[2].Set(32767.0f, -32767.0f, 32767.0f, 0, 0); - ptr[3].Set(32767.0f, -32767.0f, -32767.0f, 0, 0); - ptr += 4; - mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]); - } } gl_RenderState.Apply(); for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) { GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); } + if (NeedCap() && lines.Size() > 1) + { + glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); + glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); + } } From 6755cb2a25e274803d30a1b8b7867339933d68e1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 00:02:32 +0200 Subject: [PATCH 09/32] - use the quad drawer for skybox-flagged sectors. --- src/gl/scene/gl_flats.cpp | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 57861d1c13..3ce888089d 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -64,6 +64,7 @@ #include "gl/utility/gl_clock.h" #include "gl/utility/gl_convert.h" #include "gl/utility/gl_templates.h" +#include "gl/renderer/gl_quaddrawer.h" #ifdef _DEBUG CVAR(Int, gl_breaksec, -1, 0) @@ -318,7 +319,6 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) void GLFlat::DrawSkyboxSector(int pass, bool processlights) { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); float minx = FLT_MAX, miny = FLT_MAX; float maxx = -FLT_MAX, maxy = -FLT_MAX; @@ -345,36 +345,13 @@ void GLFlat::DrawSkyboxSector(int pass, bool processlights) static float vvals[] = { 1, 0, 0, 1 }; int rot = -xs_FloorToInt(plane.Angle / 90.f); + FQuadDrawer qd; - ptr->x = minx; - ptr->z = z; - ptr->y = miny; - ptr->u = uvals[rot & 3]; - ptr->v = vvals[rot & 3]; - ptr++; - - ptr->x = minx; - ptr->z = z; - ptr->y = maxy; - ptr->u = uvals[(rot + 1) & 3]; - ptr->v = vvals[(rot + 1) & 3]; - ptr++; - - ptr->x = maxx; - ptr->z = z; - ptr->y = maxy; - ptr->u = uvals[(rot + 2) & 3]; - ptr->v = vvals[(rot + 2) & 3]; - ptr++; - - ptr->x = maxx; - ptr->z = z; - ptr->y = miny; - ptr->u = uvals[(rot + 3) & 3]; - ptr->v = vvals[(rot + 3) & 3]; - ptr++; - - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + qd.Set(0, minx, z, miny, uvals[rot & 3], vvals[rot & 3]); + qd.Set(1, minx, z, maxy, uvals[(rot + 1) & 3], vvals[(rot + 1) & 3]); + qd.Set(2, maxx, z, maxy, uvals[(rot + 2) & 3], vvals[(rot + 2) & 3]); + qd.Set(3, maxx, z, miny, uvals[(rot + 3) & 3], vvals[(rot + 3) & 3]); + qd.Render(GL_TRIANGLE_FAN); flatvertices += 4; flatprimitives++; From f6544f3c4472062cfe43dbd2d04dc7d5a8f91f77 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 00:04:29 +0200 Subject: [PATCH 10/32] - removed unused GLFLat::sub and all codes depending on it a valid pointer. --- src/gl/compatibility/gl_20.cpp | 40 +++++------ src/gl/scene/gl_flats.cpp | 126 ++++++++++++++------------------- src/gl/scene/gl_wall.h | 1 - 3 files changed, 70 insertions(+), 97 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index f052564527..8e6682f17b 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -647,35 +647,27 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) void GLFlat::DrawLightsCompat(int pass) { gl_RenderState.Apply(); - if (sub) + // Draw the subsectors belonging to this sector + for (int i = 0; isubsectorcount; i++) { - // This represents a single subsector - DrawSubsectorLights(sub, pass); - } - else - { - // Draw the subsectors belonging to this sector - for (int i = 0; isubsectorcount; i++) + subsector_t * sub = sector->subsectors[i]; + if (gl_drawinfo->ss_renderflags[sub - subsectors] & renderflags) { - subsector_t * sub = sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub - subsectors] & renderflags) - { - DrawSubsectorLights(sub, pass); - } + DrawSubsectorLights(sub, pass); } + } - // Draw the subsectors assigned to it due to missing textures - if (!(renderflags&SSRF_RENDER3DPLANES)) + // Draw the subsectors assigned to it due to missing textures + if (!(renderflags&SSRF_RENDER3DPLANES)) + { + gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR) ? + gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : + gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); + + while (node) { - gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR) ? - gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); - - while (node) - { - DrawSubsectorLights(node->sub, pass); - node = node->next; - } + DrawSubsectorLights(node->sub, pass); + node = node->next; } } } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 3ce888089d..bd55a1a09d 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -204,35 +204,27 @@ void GLFlat::ProcessLights(bool istrans) { dynlightindex = GLRenderer->mLights->GetIndexPtr(); - if (sub) + // Draw the subsectors belonging to this sector + for (int i=0; isubsectorcount; i++) { - // This represents a single subsector - SetupSubsectorLights(GLPASS_LIGHTSONLY, sub); - } - else - { - // Draw the subsectors belonging to this sector - for (int i=0; isubsectorcount; i++) + subsector_t * sub = sector->subsectors[i]; + if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { - subsector_t * sub = sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) - { - SetupSubsectorLights(GLPASS_LIGHTSONLY, sub); - } + SetupSubsectorLights(GLPASS_LIGHTSONLY, sub); } + } - // Draw the subsectors assigned to it due to missing textures - if (!(renderflags&SSRF_RENDER3DPLANES)) + // Draw the subsectors assigned to it due to missing textures + if (!(renderflags&SSRF_RENDER3DPLANES)) + { + gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? + gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : + gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); + + while (node) { - gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? - gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); - - while (node) - { - SetupSubsectorLights(GLPASS_LIGHTSONLY, node->sub); - node = node->next; - } + SetupSubsectorLights(GLPASS_LIGHTSONLY, node->sub); + node = node->next; } } } @@ -249,60 +241,51 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) int dli = dynlightindex; gl_RenderState.Apply(); - if (sub) + if (vboindex >= 0) { - // This represents a single subsector - if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); - DrawSubsector(sub); - } - else - { - if (vboindex >= 0) + int index = vboindex; + for (int i=0; isubsectorcount; i++) { - int index = vboindex; - for (int i=0; isubsectorcount; i++) - { - subsector_t * sub = sector->subsectors[i]; + subsector_t * sub = sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) - { - if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); - drawcalls.Clock(); - glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - drawcalls.Unclock(); - flatvertices += sub->numlines; - flatprimitives++; - } - index += sub->numlines; - } - } - else - { - // Draw the subsectors belonging to this sector - for (int i=0; isubsectorcount; i++) - { - subsector_t * sub = sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) - { - if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); - DrawSubsector(sub); - } + if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) + { + if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); + drawcalls.Clock(); + glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); + drawcalls.Unclock(); + flatvertices += sub->numlines; + flatprimitives++; + } + index += sub->numlines; + } + } + else + { + // Draw the subsectors belonging to this sector + for (int i=0; isubsectorcount; i++) + { + subsector_t * sub = sector->subsectors[i]; + if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) + { + if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); + DrawSubsector(sub); } } + } - // Draw the subsectors assigned to it due to missing textures - if (!(renderflags&SSRF_RENDER3DPLANES)) - { - gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? - gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); + // Draw the subsectors assigned to it due to missing textures + if (!(renderflags&SSRF_RENDER3DPLANES)) + { + gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? + gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : + gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); - while (node) - { - if (processlights) SetupSubsectorLights(GLPASS_ALL, node->sub, &dli); - DrawSubsector(node->sub); - node = node->next; - } + while (node) + { + if (processlights) SetupSubsectorLights(GLPASS_ALL, node->sub, &dli); + DrawSubsector(node->sub); + node = node->next; } } } @@ -565,7 +548,6 @@ void GLFlat::ProcessSector(sector_t * frontsector) // Get the real sector for this one. sector = §ors[frontsector->sectornum]; extsector_t::xfloor &x = sector->e->XFloor; - this->sub = NULL; dynlightindex = -1; byte &srf = gl_drawinfo->sectorrenderflags[sector->sectornum]; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 60da861306..ae7014c7d6 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -288,7 +288,6 @@ public: friend struct GLDrawList; sector_t * sector; - subsector_t * sub; // only used for translucent planes float dz; // z offset for rendering hacks float z; // the z position of the flat (only valid for non-sloped planes) FMaterial *gltexture; From 960038bb81631f70d4afb55fb7c0a3beaffcbd79 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 26 Aug 2016 01:36:21 +0200 Subject: [PATCH 11/32] Clear global state tracking variables when the OpenGL context is (re)created --- src/gl/renderer/gl_renderstate.cpp | 25 +++++++++++++++++++++++++ src/gl/system/gl_framebuffer.cpp | 5 +++++ src/gl/textures/gl_hwtexture.h | 4 ++-- src/gl/textures/gl_material.cpp | 6 ++++++ src/gl/textures/gl_material.h | 1 + 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 83303d61e7..56b319f008 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -80,19 +80,44 @@ void FRenderState::Reset() mDstBlend = GL_ONE_MINUS_SRC_ALPHA; mAlphaThreshold = 0.5f; mBlendEquation = GL_FUNC_ADD; + mModelMatrixEnabled = false; + mTextureMatrixEnabled = false; mObjectColor = 0xffffffff; mVertexBuffer = mCurrentVertexBuffer = NULL; mColormapState = CM_DEFAULT; + mSoftLight = 0; + mLightParms[0] = mLightParms[1] = mLightParms[2] = 0.0f; mLightParms[3] = -1.f; mSpecialEffect = EFF_NONE; mClipHeight = 0.f; mClipHeightDirection = 0.f; + mShaderTimer = 0.0f; ClearClipSplit(); stSrcBlend = stDstBlend = -1; stBlendEquation = -1; stAlphaThreshold = -1.f; + stAlphaTest = 0; mLastDepthClamp = true; + mInterpolationFactor = 0.0f; + + mColor.Set(0.0f, 0.0f, 0.0f, 0.0f); + mCameraPos.Set(0.0f, 0.0f, 0.0f, 0.0f); + mGlowTop.Set(0.0f, 0.0f, 0.0f, 0.0f); + mGlowBottom.Set(0.0f, 0.0f, 0.0f, 0.0f); + mGlowTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f); + mGlowBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f); + mSplitTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f); + mSplitBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f); + mClipLine.Set(0.0f, 0.0f, 0.0f, 0.0f); + mDynColor.Set(0.0f, 0.0f, 0.0f, 0.0f); + mClipSplit[0] = mClipSplit[1] = 0.0f; + mEffectState = 0; + activeShader = nullptr; + mProjectionMatrix.loadIdentity(); + mViewMatrix.loadIdentity(); + mModelMatrix.loadIdentity(); + mTextureMatrix.loadIdentity(); } //========================================================================== diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 6d56c1b27f..ec8b3f599e 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -99,6 +99,11 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int // If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed! SetVSync(vid_vsync); + // Make sure all global variables tracking OpenGL context state are reset.. + FHardwareTexture::InitGlobalState(); + FMaterial::InitGlobalState(); + gl_RenderState.Reset(); + GLRenderer = new FGLRenderer(this); memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); UpdatePalette (); diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 9b7028f8cd..4c00af272c 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -48,11 +48,11 @@ private: public: static unsigned int lastbound[MAX_TEXTURES]; - static int lastactivetexture; - static int max_texturesize; static int GetTexDimension(int value); + static void InitGlobalState() { for (int i = 0; i < MAX_TEXTURES; i++) lastbound[i] = 0; } + private: short texwidth, texheight; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 8e0ab73e69..6ba1fe4b0c 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -669,6 +669,12 @@ static FMaterial *last; static int lastclamp; static int lasttrans; +void FMaterial::InitGlobalState() +{ + last = nullptr; + lastclamp = 0; + lasttrans = 0; +} void FMaterial::Bind(int clampmode, int translation) { diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index dea0d4cf57..d44a845f6f 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -263,6 +263,7 @@ public: static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans); static void ClearLastTexture(); + static void InitGlobalState(); }; #endif From b68bbaf617974d669d3cd13c69efcfdbdf4bd1fb Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 26 Aug 2016 01:40:28 +0200 Subject: [PATCH 12/32] Fix uninitialized memory access if a FShaderProgram is destroyed without being fully compiled and linked --- src/gl/shaders/gl_shaderprogram.cpp | 6 ++++++ src/gl/shaders/gl_shaderprogram.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/gl/shaders/gl_shaderprogram.cpp b/src/gl/shaders/gl_shaderprogram.cpp index 63ce092614..959315a9d1 100644 --- a/src/gl/shaders/gl_shaderprogram.cpp +++ b/src/gl/shaders/gl_shaderprogram.cpp @@ -52,6 +52,12 @@ #include "i_system.h" #include "doomerrors.h" +FShaderProgram::FShaderProgram() +{ + for (int i = 0; i < NumShaderTypes; i++) + mShaders[i] = 0; +} + //========================================================================== // // Free shader program resources diff --git a/src/gl/shaders/gl_shaderprogram.h b/src/gl/shaders/gl_shaderprogram.h index 16684ddff5..64a36db494 100644 --- a/src/gl/shaders/gl_shaderprogram.h +++ b/src/gl/shaders/gl_shaderprogram.h @@ -6,6 +6,7 @@ class FShaderProgram { public: + FShaderProgram(); ~FShaderProgram(); enum ShaderType @@ -30,6 +31,9 @@ public: static void PatchFragShader(FString &code); private: + FShaderProgram(const FShaderProgram &) = delete; + FShaderProgram &operator=(const FShaderProgram &) = delete; + static FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion); static void PatchCommon(FString &code); From 5f09d3b7ef7b8915d9e69b310fa2bf12fd5b4ce6 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 26 Aug 2016 01:46:39 +0200 Subject: [PATCH 13/32] Add FBufferedUniformSampler because sampler uniforms may default bind to other locations than zero --- src/gl/shaders/gl_bloomshader.h | 4 ++-- src/gl/shaders/gl_lensshader.h | 2 +- src/gl/shaders/gl_presentshader.h | 2 +- src/gl/shaders/gl_shader.h | 22 ++++++++++++++++++++++ src/gl/shaders/gl_tonemapshader.h | 4 ++-- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/gl/shaders/gl_bloomshader.h b/src/gl/shaders/gl_bloomshader.h index cbc740ab60..b20277a42d 100644 --- a/src/gl/shaders/gl_bloomshader.h +++ b/src/gl/shaders/gl_bloomshader.h @@ -8,7 +8,7 @@ class FBloomExtractShader public: void Bind(); - FBufferedUniform1i SceneTexture; + FBufferedUniformSampler SceneTexture; FBufferedUniform1f Exposure; FBufferedUniform2f Scale; FBufferedUniform2f Offset; @@ -22,7 +22,7 @@ class FBloomCombineShader public: void Bind(); - FBufferedUniform1i BloomTexture; + FBufferedUniformSampler BloomTexture; private: FShaderProgram mShader; diff --git a/src/gl/shaders/gl_lensshader.h b/src/gl/shaders/gl_lensshader.h index ef0810e4ea..7e9ef63926 100644 --- a/src/gl/shaders/gl_lensshader.h +++ b/src/gl/shaders/gl_lensshader.h @@ -8,7 +8,7 @@ class FLensShader public: void Bind(); - FBufferedUniform1i InputTexture; + FBufferedUniformSampler InputTexture; FBufferedUniform1f AspectRatio; FBufferedUniform1f Scale; FBufferedUniform4f LensDistortionCoefficient; diff --git a/src/gl/shaders/gl_presentshader.h b/src/gl/shaders/gl_presentshader.h index b54fa2e36e..6f4e899bb7 100644 --- a/src/gl/shaders/gl_presentshader.h +++ b/src/gl/shaders/gl_presentshader.h @@ -8,7 +8,7 @@ class FPresentShader public: void Bind(); - FBufferedUniform1i InputTexture; + FBufferedUniformSampler InputTexture; FBufferedUniform1f InvGamma; FBufferedUniform1f Contrast; FBufferedUniform1f Brightness; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 75e4b4e5e5..52ca59ec78 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -201,6 +201,28 @@ public: } }; +class FBufferedUniformSampler +{ + int mBuffer; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + mBuffer = -1; + } + + void Set(int newvalue) + { + if (newvalue != mBuffer) + { + mBuffer = newvalue; + glUniform1i(mIndex, newvalue); + } + } +}; + class FShader { diff --git a/src/gl/shaders/gl_tonemapshader.h b/src/gl/shaders/gl_tonemapshader.h index 9d427713fe..7ec24117b1 100644 --- a/src/gl/shaders/gl_tonemapshader.h +++ b/src/gl/shaders/gl_tonemapshader.h @@ -8,9 +8,9 @@ class FTonemapShader public: void Bind(); - FBufferedUniform1i SceneTexture; + FBufferedUniformSampler SceneTexture; FBufferedUniform1f Exposure; - FBufferedUniform1i PaletteLUT; + FBufferedUniformSampler PaletteLUT; static bool IsPaletteMode(); From abba548e40737f5621725e1d1edec02c13521b6e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 02:03:24 +0200 Subject: [PATCH 14/32] - render sector hacks through the quad renderer if the vertex buffer is not accessible. --- src/gl/scene/gl_flats.cpp | 50 +++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index bd55a1a09d..6058971274 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -47,6 +47,7 @@ #include "doomstat.h" #include "d_player.h" #include "portal.h" +#include "templates.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" @@ -176,18 +177,46 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli) void GLFlat::DrawSubsector(subsector_t * sub) { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - for (unsigned int k = 0; k < sub->numlines; k++) + if (gl.buffermethod != BM_DEFERRED) { - vertex_t *vt = sub->firstline[k].v1; - ptr->x = vt->fX(); - ptr->z = plane.plane.ZatPoint(vt) + dz; - ptr->y = vt->fY(); - ptr->u = vt->fX() / 64.f; - ptr->v = -vt->fY() / 64.f; - ptr++; + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (unsigned int k = 0; k < sub->numlines; k++) + { + vertex_t *vt = sub->firstline[k].v1; + ptr->x = vt->fX(); + ptr->z = plane.plane.ZatPoint(vt) + dz; + ptr->y = vt->fY(); + ptr->u = vt->fX() / 64.f; + ptr->v = -vt->fY() / 64.f; + ptr++; + } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + } + else + { + // if we cannot access the buffer, use the quad drawer as fallback by splitting the subsector into quads. + // Trying to get this into the vertex buffer in the processing pass is too costly and this is only used for render hacks. + FQuadDrawer qd; + unsigned int vi[4]; + + vi[0] = 0; + for (unsigned int i = 1; i < sub->numlines; i += 2) + { + if (i < sub->numlines - 3) + { + for (unsigned int j = 1; j < 4; j++) + { + vi[j] = MIN(i + j, sub->numlines - 1); + } + for (unsigned int x = 0; x < 4; x++) + { + vertex_t *vt = sub->firstline[vi[x]].v1; + qd.Set(x, vt->fX(), plane.plane.ZatPoint(vt) + dz, vt->fY(), vt->fX() / 64.f, -vt->fY() / 64.f); + } + qd.Render(GL_TRIANGLE_FAN); + } + } } - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); flatvertices += sub->numlines; flatprimitives++; @@ -263,6 +292,7 @@ void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) else { // Draw the subsectors belonging to this sector + // (can this case even happen?) for (int i=0; isubsectorcount; i++) { subsector_t * sub = sector->subsectors[i]; From 465792df0a0243c8ae4cc3925c056d85db319891 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 02:16:06 +0200 Subject: [PATCH 15/32] - make sure that after travelling has finished, no travelling thinkers are left in the list. Since this list is excluded from regular thinker cleaning, anything that may survive through the end of G_FinishTravel will endlessly multiply and severely break the following savegames or just simply crash on broken pointers. --- src/dthinker.h | 5 +++++ src/g_level.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/dthinker.h b/src/dthinker.h index 10a53309d6..855c3c9ad9 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -77,6 +77,11 @@ public: static void RunThinkers (int statnum); static void DestroyAllThinkers (); static void DestroyMostThinkers (); + static void DestroyThinkersInList(int statnum) + { + DestroyThinkersInList(Thinkers[STAT_TRAVELLING]); + DestroyThinkersInList(FreshThinkers[STAT_TRAVELLING]); + } static void SerializeAll (FArchive &arc, bool keepPlayers); static void MarkRoots(); diff --git a/src/g_level.cpp b/src/g_level.cpp index e47cbb4a55..60e9b06990 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1295,6 +1295,11 @@ void G_FinishTravel () } bglobal.FinishTravel (); + + // make sure that, after travelling has completed, no travelling thinkers are left. + // Since this list is excluded from regular thinker cleaning, anything that may survive through here + // will endlessly multiply and severely break the following savegames or just simply crash on broken pointers. + DThinker::DestroyThinkersInList(STAT_TRAVELLING); } //========================================================================== From 597e10116f5df541c4132124c6a4035b296eb18c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 08:30:47 +0200 Subject: [PATCH 16/32] - added missing framebuffer function to fudging block. --- src/gl/system/gl_interface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 30839e8f4b..a7b1be6487 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -307,6 +307,7 @@ void gl_LoadExtensions() FUDGE_FUNC(glDeleteRenderbuffers, EXT); FUDGE_FUNC(glRenderbufferStorage, EXT); FUDGE_FUNC(glBindRenderbuffer, EXT); + FUDGE_FUNC(glCheckFramebufferStatus, EXT); gl_PatchMenu(); } From 5303526c70138423b074d06cf794b584728f0405 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 08:34:27 +0200 Subject: [PATCH 17/32] - actually use the parameter... --- src/dthinker.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dthinker.h b/src/dthinker.h index 855c3c9ad9..ac5adc431b 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -79,8 +79,8 @@ public: static void DestroyMostThinkers (); static void DestroyThinkersInList(int statnum) { - DestroyThinkersInList(Thinkers[STAT_TRAVELLING]); - DestroyThinkersInList(FreshThinkers[STAT_TRAVELLING]); + DestroyThinkersInList(Thinkers[statnum]); + DestroyThinkersInList(FreshThinkers[statnum]); } static void SerializeAll (FArchive &arc, bool keepPlayers); static void MarkRoots(); From c9578ae72df9e8bf8826c7915cef68f666389c58 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Aug 2016 18:18:50 +0200 Subject: [PATCH 18/32] - create vertex buffer data for horizon portals in the constructor instead of in the draw function. This was the last remaining place where the vertex buffer was accessed in the render pass. --- src/gl/scene/gl_flats.cpp | 2 +- src/gl/scene/gl_portal.cpp | 119 ++++++++++++++++++++----------------- src/gl/scene/gl_portal.h | 9 +-- 3 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 6058971274..8b665648e6 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -200,7 +200,7 @@ void GLFlat::DrawSubsector(subsector_t * sub) unsigned int vi[4]; vi[0] = 0; - for (unsigned int i = 1; i < sub->numlines; i += 2) + for (unsigned int i = 1; i < sub->numlines-1; i += 2) { if (i < sub->numlines - 3) { diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 628e0f915c..4b8d8eb275 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -1070,6 +1070,66 @@ void GLLineToLinePortal::RenderAttached() // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- + +GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, bool local) + : GLPortal(local) +{ + origin = pt; + + // create the vertex data for this horizon portal. + GLSectorPlane * sp = &origin->plane; + const float vx = ViewPos.X; + const float vy = ViewPos.Y; + const float vz = ViewPos.Z; + const float z = sp->Texheight; + const float tz = (z - vz); + + // Draw to some far away boundary + // This is not drawn as larger strips because it causes visual glitches. + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (float x = -32768 + vx; x<32768 + vx; x += 4096) + { + for (float y = -32768 + vy; y<32768 + vy; y += 4096) + { + ptr->Set(x, z, y, x / 64, -y / 64); + ptr++; + ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64); + ptr++; + ptr->Set(x, z, y + 4096, x / 64, -y / 64 - 64); + ptr++; + ptr->Set(x + 4096, z, y + 4096, x / 64 + 64, -y / 64 - 64); + ptr++; + } + } + + // fill the gap between the polygon and the true horizon + // Since I can't draw into infinity there can always be a + // small gap + ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); + ptr++; + ptr->Set(-32768 + vx, z, 32768 + vy, -512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, 32768 + vy, -512.f, tz); + ptr++; + ptr->Set(32768 + vx, z, 32768 + vy, 512.f, 0); + ptr++; + ptr->Set(32768 + vx, vz, 32768 + vy, 512.f, tz); + ptr++; + ptr->Set(32768 + vx, z, -32768 + vy, -512.f, 0); + ptr++; + ptr->Set(32768 + vx, vz, -32768 + vy, -512.f, tz); + ptr++; + ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); + ptr++; + + vcount = GLRenderer->mVBO->GetCount(ptr, &voffset) - 10; + +} + //----------------------------------------------------------------------------- // // GLHorizonPortal::DrawContents @@ -1079,11 +1139,10 @@ void GLHorizonPortal::DrawContents() { PortalAll.Clock(); - GLSectorPlane * sp=&origin->plane; FMaterial * gltexture; PalEntry color; - float z; player_t * player=&players[consoleplayer]; + GLSectorPlane * sp = &origin->plane; gltexture=FMaterial::ValidateTexture(sp->texture, false, true); if (!gltexture) @@ -1095,9 +1154,6 @@ void GLHorizonPortal::DrawContents() gl_RenderState.SetCameraPos(ViewPos.X, ViewPos.Y, ViewPos.Z); - z=sp->Texheight; - - if (gltexture && gltexture->tex->isFullbright()) { // glowing textures are always drawn full bright without color @@ -1120,58 +1176,11 @@ void GLHorizonPortal::DrawContents() gl_RenderState.Apply(); - - float vx= ViewPos.X; - float vy= ViewPos.Y; - - // Draw to some far away boundary - // This is not drawn as larher strips because it causes visual glitches. - for(float x=-32768+vx; x<32768+vx; x+=4096) + for (unsigned i = 0; i < vcount; i += 4) { - for(float y=-32768+vy; y<32768+vy;y+=4096) - { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - ptr->Set(x, z, y, x / 64, -y / 64); - ptr++; - ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64); - ptr++; - ptr->Set(x, z, y + 4096, x / 64, -y / 64 - 64); - ptr++; - ptr->Set(x + 4096, z, y + 4096, x / 64 + 64, -y / 64 - 64); - ptr++; - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - } + glDrawArrays(GL_TRIANGLE_STRIP, voffset + i, 4); } - - float vz= ViewPos.Z; - float tz=(z-vz);///64.0f; - - // fill the gap between the polygon and the true horizon - // Since I can't draw into infinity there can always be a - // small gap - - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); - ptr++; - ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); - ptr++; - ptr->Set(-32768 + vx, z, 32768 + vy, -512.f, 0); - ptr++; - ptr->Set(-32768 + vx, vz, 32768 + vy, -512.f, tz); - ptr++; - ptr->Set(32768 + vx, z, 32768 + vy, 512.f, 0); - ptr++; - ptr->Set(32768 + vx, vz, 32768 + vy, 512.f, tz); - ptr++; - ptr->Set(32768 + vx, z, -32768 + vy, -512.f, 0); - ptr++; - ptr->Set(32768 + vx, vz, -32768 + vy, -512.f, tz); - ptr++; - ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); - ptr++; - ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); - ptr++; - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + glDrawArrays(GL_TRIANGLE_STRIP, voffset + vcount, 10); gl_RenderState.EnableTextureMatrix(false); PortalAll.Unclock(); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 7b9f896db4..fbd3a0c7f2 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -365,6 +365,8 @@ public: struct GLHorizonPortal : public GLPortal { GLHorizonInfo * origin; + unsigned int voffset; + unsigned int vcount; friend struct GLEEHorizonPortal; protected: @@ -376,12 +378,7 @@ protected: public: - GLHorizonPortal(GLHorizonInfo * pt, bool local = false) - : GLPortal(local) - { - origin=pt; - } - + GLHorizonPortal(GLHorizonInfo * pt, bool local = false); }; struct GLEEHorizonPortal : public GLPortal From b1a0108a961ec24ec7af922b60355947c453e31f Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 25 Aug 2016 19:58:50 +0200 Subject: [PATCH 19/32] Fix tonemap palette not being rebuilt on palette change --- src/gl/renderer/gl_postprocess.cpp | 6 ++++++ src/gl/renderer/gl_renderer.cpp | 1 + src/gl/renderer/gl_renderer.h | 1 + src/gl/system/gl_framebuffer.cpp | 3 +++ 4 files changed, 11 insertions(+) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index c1b39e5563..20f6f469f4 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -278,6 +278,12 @@ void FGLRenderer::BindTonemapPalette(int texunit) } } +void FGLRenderer::ClearTonemapPalette() +{ + delete mTonemapPalette; + mTonemapPalette = nullptr; +} + //----------------------------------------------------------------------------- // // Apply lens distortion and place the result in the HUD/2D texture diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index fba3a09eac..d154766d68 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -111,6 +111,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) gllight = glpart2 = glpart = mirrortexture = NULL; mLights = NULL; m2DDrawer = nullptr; + mTonemapPalette = nullptr; } void gl_LoadModels(); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index da2a11ed0e..4b663680f6 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -167,6 +167,7 @@ public: void BloomScene(); void TonemapScene(); void BindTonemapPalette(int texunit); + void ClearTonemapPalette(); void LensDistortScene(); void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma); void Flush() { CopyToBackbuffer(nullptr, true); } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ec8b3f599e..ae1fabaed9 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -310,6 +310,9 @@ void OpenGLFrameBuffer::UpdatePalette() bb>>=8; palette_brightness = (rr*77 + gg*143 + bb*35)/255; + + if (GLRenderer) + GLRenderer->ClearTonemapPalette(); } void OpenGLFrameBuffer::GetFlashedPalette (PalEntry pal[256]) From 6c5109ec9949bf60e94b893f6fbc594d836cad82 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 27 Aug 2016 06:24:36 +0200 Subject: [PATCH 20/32] Fix uninitialized mPipelineTexture and fix BindCurrentTexture using the wrong handle --- src/gl/renderer/gl_renderbuffers.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 9c9c76979c..9f27e63136 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -65,6 +65,12 @@ CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); FGLRenderBuffers::FGLRenderBuffers() { + for (int i = 0; i < NumPipelineTextures; i++) + { + mPipelineTexture[i] = 0; + mPipelineFB[i] = 0; + } + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&mOutputFB); glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); } @@ -477,7 +483,7 @@ void FGLRenderBuffers::BindSceneFB() void FGLRenderBuffers::BindCurrentTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); - glBindTexture(GL_TEXTURE_2D, mPipelineFB[mCurrentPipelineTexture]); + glBindTexture(GL_TEXTURE_2D, mPipelineTexture[mCurrentPipelineTexture]); } //========================================================================== From 716fbec8eedb8ed06b8a937ffac39b062cfbf817 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 27 Aug 2016 22:14:57 -0400 Subject: [PATCH 21/32] - Added support for building with FMOD Studio Low Level API (partially based off of Emile Belanger's/Beloko Games Android work) - Use with FMOD Studio 1.06.x. 1.07 and 1.08 compile but for some reason produce a lot of noise on vanilla Doom sounds. - Crashes when used with fluidsynth provided by Ubuntu 16.04, but a self compiled version of the library works just fine. - Reverbs are mostly untested, but implemented. - Debug waveform drawing is not implemented as it requires a non-trivial amount of work. - It will still show as FMOD Ex in the menus since I'm too lazy at the moment to make it a "separate" backend. --- output_sdl/CMakeLists.txt | 18 +- src/sound/fmod_wrap.h | 9 + src/sound/fmodsound.cpp | 359 ++++++++++++++++++++++++++++++++++---- src/sound/fmodsound.h | 9 + 4 files changed, 354 insertions(+), 41 deletions(-) diff --git a/output_sdl/CMakeLists.txt b/output_sdl/CMakeLists.txt index de42f6be6f..323d941494 100644 --- a/output_sdl/CMakeLists.txt +++ b/output_sdl/CMakeLists.txt @@ -1,11 +1,17 @@ cmake_minimum_required( VERSION 2.8.7 ) if( NOT NO_FMOD AND FMOD_INCLUDE_DIR ) - add_library( output_sdl MODULE output_sdl.c ) include_directories( ${FMOD_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ) - target_link_libraries( output_sdl ${SDL2_LIBRARY} ) + check_library_exists(${FMOD_LIBRARY} "FMOD_System_GetDriverCaps" "fmod.h" FMOD_IS_EX) - FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so ]; then ln -sf output_sdl/liboutput_sdl.so ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so; fi" ) - add_custom_command( TARGET output_sdl POST_BUILD - COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/link-make - COMMAND /bin/sh -c ${CMAKE_CURRENT_BINARY_DIR}/link-make ) + # Only usable with FMOD Ex + if( FMOD_IS_EX ) + include_directories( ${FMOD_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ) + add_library( output_sdl MODULE output_sdl.c ) + target_link_libraries( output_sdl ${SDL2_LIBRARY} ) + + FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so ]; then ln -sf output_sdl/liboutput_sdl.so ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so; fi" ) + add_custom_command( TARGET output_sdl POST_BUILD + COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/link-make + COMMAND /bin/sh -c ${CMAKE_CURRENT_BINARY_DIR}/link-make ) + endif() endif() diff --git a/src/sound/fmod_wrap.h b/src/sound/fmod_wrap.h index 6734ba85b3..02d6a56ae3 100644 --- a/src/sound/fmod_wrap.h +++ b/src/sound/fmod_wrap.h @@ -611,5 +611,14 @@ namespace FMOD } #endif + +// FMOD Ex vs FMOD Studio +#if FMOD_VERSION >= 0x00040000 && FMOD_VERSION <= 0x0004FFFF +#define FMOD_STUDIO 0 +#else +#define FMOD_STUDIO 1 +#define FMOD_SOFTWARE 0 +#endif + #endif #endif diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 1088818ced..465aade9b6 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -122,10 +122,14 @@ CUSTOM_CVAR (Int, snd_streambuffersize, 64, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } #ifndef NO_FMOD -#if FMOD_VERSION < 0x43400 +#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 #define FMOD_OPENSTATE_PLAYING FMOD_OPENSTATE_STREAMING #endif +#if !FMOD_STUDIO +#define setParameterFloat setParameter +#endif + // TYPES ------------------------------------------------------------------- struct FEnumList @@ -183,15 +187,28 @@ static const FEnumList OutputNames[] = { "WASAPI", FMOD_OUTPUTTYPE_WASAPI }, { "ASIO", FMOD_OUTPUTTYPE_ASIO }, +#if FMOD_STUDIO + //Android + + { "OPENSL", FMOD_OUTPUTTYPE_OPENSL }, + { "Android Audio Track", FMOD_OUTPUTTYPE_AUDIOTRACK }, +#endif + // Linux +#if !FMOD_STUDIO { "OSS", FMOD_OUTPUTTYPE_OSS }, +#endif { "ALSA", FMOD_OUTPUTTYPE_ALSA }, +#if !FMOD_STUDIO { "ESD", FMOD_OUTPUTTYPE_ESD }, -#if FMOD_VERSION >= 0x43400 +#endif +#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 { "PulseAudio", FMOD_OUTPUTTYPE_PULSEAUDIO }, { "Pulse", FMOD_OUTPUTTYPE_PULSEAUDIO }, #endif +#if !FMOD_STUDIO { "SDL", 666 }, +#endif // Mac { "Core Audio", FMOD_OUTPUTTYPE_COREAUDIO }, @@ -207,7 +224,7 @@ static const FEnumList SpeakerModeNames[] = { "Surround", FMOD_SPEAKERMODE_SURROUND }, { "5.1", FMOD_SPEAKERMODE_5POINT1 }, { "7.1", FMOD_SPEAKERMODE_7POINT1 }, -#if FMOD_VERSION < 0x44000 +#if !FMOD_STUDIO && FMOD_VERSION < 0x44000 { "Prologic", FMOD_SPEAKERMODE_PROLOGIC }, #endif { "1", FMOD_SPEAKERMODE_MONO }, @@ -222,7 +239,7 @@ static const FEnumList ResamplerNames[] = { "NoInterp", FMOD_DSP_RESAMPLER_NOINTERP }, { "Linear", FMOD_DSP_RESAMPLER_LINEAR }, // [BL] 64-bit version of FMOD Ex 4.26 crashes with these resamplers. -#if !(defined(_M_X64) || defined(__amd64__)) || !(FMOD_VERSION >= 0x42600 && FMOD_VERSION <= 0x426FF) +#if FMOD_STUDIO || !(defined(_M_X64) || defined(__amd64__)) || !(FMOD_VERSION >= 0x42600 && FMOD_VERSION <= 0x426FF) { "Cubic", FMOD_DSP_RESAMPLER_CUBIC }, { "Spline", FMOD_DSP_RESAMPLER_SPLINE }, #endif @@ -237,11 +254,13 @@ static const FEnumList SoundFormatNames[] = { "PCM-24", FMOD_SOUND_FORMAT_PCM24 }, { "PCM-32", FMOD_SOUND_FORMAT_PCM32 }, { "PCM-Float", FMOD_SOUND_FORMAT_PCMFLOAT }, +#if FMOD_STUDIO && FMOD_VERSION < 0x10700 { "GCADPCM", FMOD_SOUND_FORMAT_GCADPCM }, { "IMAADPCM", FMOD_SOUND_FORMAT_IMAADPCM }, { "VAG", FMOD_SOUND_FORMAT_VAG }, { "XMA", FMOD_SOUND_FORMAT_XMA }, { "MPEG", FMOD_SOUND_FORMAT_MPEG }, +#endif { NULL, 0 } }; @@ -356,10 +375,13 @@ public: Stream = stream; // As this interface is for music, make it super-high priority. +#if FMOD_STUDIO + if (FMOD_OK == stream->getDefaults(&frequency, NULL)) + stream->setDefaults(frequency, 1); +#else if (FMOD_OK == stream->getDefaults(&frequency, NULL, NULL, NULL)) - { stream->setDefaults(frequency, 1, 0, 0); - } +#endif } bool Play(bool looping, float volume) @@ -371,21 +393,33 @@ public: looping = false; } Stream->setMode((looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF) | FMOD_SOFTWARE | FMOD_2D); +#if FMOD_STUDIO + result = Owner->Sys->playSound(Stream,0, true, &Channel); +#else result = Owner->Sys->playSound(FMOD_CHANNEL_FREE, Stream, true, &Channel); +#endif if (result != FMOD_OK) { return false; } Channel->setChannelGroup(Owner->MusicGroup); +#if FMOD_STUDIO + Channel->setMixLevelsOutput(1, 1, 1, 1, 1, 1, 1, 1); +#else Channel->setSpeakerMix(1, 1, 1, 1, 1, 1, 1, 1); +#endif Channel->setVolume(volume); // Ensure reverb is disabled. +#if FMOD_STUDIO + Channel->setReverbProperties(0,0.f); +#else FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == Channel->getReverbProperties(&reverb)) { reverb.Room = -10000; Channel->setReverbProperties(&reverb); } +#endif Channel->setPaused(false); Ended = false; JustStarted = true; @@ -429,7 +463,7 @@ public: bool is; FMOD_OPENSTATE openstate = FMOD_OPENSTATE_MAX; bool starving; -#if FMOD_VERSION >= 0x43400 +#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 bool diskbusy; #endif @@ -437,7 +471,7 @@ public: { return true; } -#if FMOD_VERSION < 0x43400 +#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving)) #else if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving, &diskbusy)) @@ -526,7 +560,7 @@ public: unsigned int percentbuffered; unsigned int position; bool starving; -#if FMOD_VERSION >= 0x43400 +#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 bool diskbusy; #endif float volume; @@ -534,7 +568,7 @@ public: bool paused; bool isplaying; -#if FMOD_VERSION < 0x43400 +#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving)) #else if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving, &diskbusy)) @@ -710,7 +744,9 @@ bool FMODSoundRenderer::Init() } const char *wrongver = NULL; -#if FMOD_VERSION >= 0x43600 +#if FMOD_STUDIO + if (version < (FMOD_VERSION & 0xFFFF00)) +#elif FMOD_VERSION >= 0x43600 if (version < 0x43600) #else if (version < 0x42000) @@ -718,7 +754,7 @@ bool FMODSoundRenderer::Init() { wrongver = "an old"; } -#if FMOD_VERSION < 0x42700 +#if !FMOD_STUDIO && FMOD_VERSION < 0x42700 else if ((version & 0xFFFF00) > 0x42600) #else else if ((version & 0xFFFF00) > (FMOD_VERSION & 0xFFFF00)) @@ -744,7 +780,7 @@ bool FMODSoundRenderer::Init() Printf("Loaded FMOD version %x.%02x.%02x\n", version >> 16, (version >> 8) & 255, version & 255); ShowedBanner = true; } -#ifdef _WIN32 +#if defined(_WIN32) && !FMOD_STUDIO if (OSPlatform == os_WinNT4) { // The following was true as of FMOD 3. I don't know if it still @@ -781,7 +817,7 @@ bool FMODSoundRenderer::Init() } #endif -#if !defined _WIN32 && !defined __APPLE__ +#if !defined _WIN32 && !defined __APPLE__ && !FMOD_STUDIO // Try to load SDL output plugin result = Sys->setPluginPath(progdir); // Should we really look for it in the program directory? result = Sys->loadPlugin("liboutput_sdl.so", &OutputPlugin); @@ -812,7 +848,7 @@ bool FMODSoundRenderer::Init() } result = Sys->getNumDrivers(&driver); -#ifdef __unix__ +#if defined(__unix__) && !FMOD_STUDIO if (result == FMOD_OK) { // On Linux, FMOD defaults to OSS. If OSS is not present, it doesn't @@ -852,7 +888,11 @@ bool FMODSoundRenderer::Init() result = Sys->setDriver(driver); } result = Sys->getDriver(&driver); -#if FMOD_VERSION >= 0x43600 +#if FMOD_STUDIO + // We were built with an FMOD Studio that only returns the control panel frequency + result = Sys->getDriverInfo(driver, nullptr, 0, nullptr, &Driver_MinFrequency, &speakermode, nullptr); + Driver_MaxFrequency = Driver_MinFrequency; +#elif FMOD_VERSION >= 0x43600 // We were built with an FMOD that only returns the control panel frequency result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &speakermode); Driver_MaxFrequency = Driver_MinFrequency; @@ -865,7 +905,9 @@ bool FMODSoundRenderer::Init() Printf(TEXTCOLOR_BLUE"Could not ascertain driver capabilities. Some things may be weird. (Error %d)\n", result); // Fill in some default to pretend it worked. (But as long as we specify a valid driver, // can this call actually fail?) +#if !FMOD_STUDIO Driver_Caps = 0; +#endif Driver_MinFrequency = 4000; Driver_MaxFrequency = 48000; speakermode = FMOD_SPEAKERMODE_STEREO; @@ -877,11 +919,13 @@ bool FMODSoundRenderer::Init() { speakermode = FMOD_SPEAKERMODE(eval); } +#if !FMOD_STUDIO result = Sys->setSpeakerMode(speakermode); if (result != FMOD_OK) { Printf(TEXTCOLOR_BLUE"Could not set speaker mode to '%s'. (Error %d)\n", *snd_speakermode, result); } +#endif // Set software format eval = Enum_NumForName(SoundFormatNames, snd_output_format); @@ -902,7 +946,11 @@ bool FMODSoundRenderer::Init() samplerate = snd_samplerate; if (samplerate == 0 || snd_samplerate == 0) { // Creative's ASIO drivers report the only supported frequency as 0! +#if FMOD_STUDIO + if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL)) +#else if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL, NULL, NULL, NULL)) +#endif { samplerate = 48000; } @@ -911,12 +959,26 @@ bool FMODSoundRenderer::Init() { Printf(TEXTCOLOR_BLUE"Sample rate %d is unsupported. Trying %d.\n", *snd_samplerate, samplerate); } +#if FMOD_STUDIO + result = Sys->setSoftwareFormat(samplerate, speakermode, 0); +#else result = Sys->setSoftwareFormat(samplerate, format, 0, 0, resampler); +#endif if (result != FMOD_OK) { Printf(TEXTCOLOR_BLUE"Could not set mixing format. Defaults will be used. (Error %d)\n", result); } +#if FMOD_STUDIO + FMOD_ADVANCEDSETTINGS advSettings = {}; + advSettings.resamplerMethod = resampler; + result = Sys->setAdvancedSettings(&advSettings); + if (result != FMOD_OK) + { + Printf(TEXTCOLOR_BLUE"Could not set resampler method. Defaults will be used. (Error %d)\n", result); + } +#endif + // Set software channels according to snd_channels result = Sys->setSoftwareChannels(snd_channels + NUM_EXTRA_SOFTWARE_CHANNELS); if (result != FMOD_OK) @@ -924,6 +986,7 @@ bool FMODSoundRenderer::Init() Printf(TEXTCOLOR_BLUE"Failed to set the preferred number of channels. (Error %d)\n", result); } +#if !FMOD_STUDIO if (Driver_Caps & FMOD_CAPS_HARDWARE_EMULATED) { // The user has the 'Acceleration' slider set to off! // This is really bad for latency! @@ -931,7 +994,9 @@ bool FMODSoundRenderer::Init() Printf (TEXTCOLOR_BLUE"Please turn it back on if you want decent sound.\n"); result = Sys->setDSPBufferSize(1024, 10); // At 48khz, the latency between issuing an fmod command and hearing it will now be about 213ms. } - else if (snd_buffersize != 0 || snd_buffercount != 0) + else +#endif + if (snd_buffersize != 0 || snd_buffercount != 0) { int buffersize = snd_buffersize ? snd_buffersize : 1024; int buffercount = snd_buffercount ? snd_buffercount : 4; @@ -951,7 +1016,9 @@ bool FMODSoundRenderer::Init() if (snd_hrtf) { // These flags are the same thing, just with different names. -#ifdef FMOD_INIT_SOFTWARE_HRTF +#ifdef FMOD_INIT_CHANNEL_LOWPASS + initflags |= FMOD_INIT_CHANNEL_LOWPASS; +#elif defined(FMOD_INIT_SOFTWARE_HRTF) initflags |= FMOD_INIT_SOFTWARE_HRTF; #else initflags |= FMOD_INIT_HRTF_LOWPASS; @@ -959,7 +1026,11 @@ bool FMODSoundRenderer::Init() } if (snd_profile) { +#ifdef FMOD_INIT_PROFILE_ENABLE + initflags |= FMOD_INIT_PROFILE_ENABLE; +#else initflags |= FMOD_INIT_ENABLE_PROFILE; +#endif } for (;;) { @@ -970,14 +1041,23 @@ bool FMODSoundRenderer::Init() // 1. The speaker mode selected isn't supported by this soundcard. Force it to stereo. // 2. The output format is unsupported. Force it to 16-bit PCM. // 3. ??? +#if FMOD_STUDIO + result = Sys->getSoftwareFormat(nullptr, &speakermode, nullptr); +#else result = Sys->getSpeakerMode(&speakermode); +#endif if (result == FMOD_OK && speakermode != FMOD_SPEAKERMODE_STEREO && +#if FMOD_STUDIO + FMOD_OK == Sys->setSoftwareFormat(samplerate, FMOD_SPEAKERMODE_STEREO, 0)) +#else FMOD_OK == Sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO)) +#endif { Printf(TEXTCOLOR_RED" Buffer creation failed. Retrying with stereo output.\n"); continue; } +#if !FMOD_STUDIO result = Sys->getSoftwareFormat(&samplerate, &format, NULL, NULL, &resampler, NULL); if (result == FMOD_OK && format != FMOD_SOUND_FORMAT_PCM16 && @@ -986,11 +1066,21 @@ bool FMODSoundRenderer::Init() Printf(TEXTCOLOR_RED" Buffer creation failed. Retrying with PCM-16 output.\n"); continue; } +#endif } - else if (result == FMOD_ERR_NET_SOCKET_ERROR && (initflags & FMOD_INIT_ENABLE_PROFILE)) + else if (result == FMOD_ERR_NET_SOCKET_ERROR && +#ifdef FMOD_INIT_PROFILE_ENABLE + (initflags & FMOD_INIT_PROFILE_ENABLE)) +#else + (initflags & FMOD_INIT_ENABLE_PROFILE)) +#endif { Printf(TEXTCOLOR_RED" Could not create socket. Retrying without profiling.\n"); +#ifdef FMOD_INIT_PROFILE_ENABLE + initflags &= ~FMOD_INIT_PROFILE_ENABLE; +#else initflags &= ~FMOD_INIT_ENABLE_PROFILE; +#endif continue; } #ifdef _WIN32 @@ -1066,7 +1156,11 @@ bool FMODSoundRenderer::Init() { FMOD::DSP *sfx_head, *pausable_head; +#if FMOD_STUDIO + result = SfxGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &sfx_head); +#else result = SfxGroup->getDSPHead(&sfx_head); +#endif if (result == FMOD_OK) { result = sfx_head->getInput(0, &pausable_head, &SfxConnection); @@ -1103,8 +1197,8 @@ bool FMODSoundRenderer::Init() } result = WaterLP->addInput(pausable_head, NULL); WaterLP->setActive(false); - WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); - WaterLP->setParameter(FMOD_DSP_LOWPASS_RESONANCE, 2); + WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); + WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_RESONANCE, 2); if (WaterReverb != NULL) { @@ -1120,15 +1214,25 @@ bool FMODSoundRenderer::Init() // These parameters are entirely empirical and can probably // stand some improvement, but it sounds remarkably close // to the old reverb unit's output. - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_LFREFERENCE, 150); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_HFREFERENCE, 10000); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_ROOM, 0); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_ROOMHF, -5000); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_DRYLEVEL, 0); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_DECAYHFRATIO, 1); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_DECAYTIME, 0.25f); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_DENSITY, 100); - WaterReverb->setParameter(FMOD_DSP_SFXREVERB_DIFFUSION, 100); +#if FMOD_STUDIO + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY, 150); +#else + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_LFREFERENCE, 150); +#endif + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_HFREFERENCE, 10000); +#if !FMOD_STUDIO + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_ROOM, 0); + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_ROOMHF, -5000); +#endif + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DRYLEVEL, 0); +#if FMOD_STUDIO + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_HFDECAYRATIO, 100); +#else + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DECAYHFRATIO, 1); +#endif + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DECAYTIME, 0.25f); + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DENSITY, 100); + WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DIFFUSION, 100); WaterReverb->setActive(false); } } @@ -1154,7 +1258,11 @@ bool FMODSoundRenderer::Init() { FMOD::DSP *master_head; +#if FMOD_STUDIO + result = master_group->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &master_head); +#else result = master_group->getDSPHead(&master_head); +#endif if (result == FMOD_OK) { result = master_head->getOutput(0, &ChannelGroupTargetUnit, NULL); @@ -1174,7 +1282,11 @@ bool FMODSoundRenderer::Init() } } +#if FMOD_STUDIO + if (FMOD_OK != Sys->getSoftwareFormat(&OutputRate, NULL, NULL)) +#else if (FMOD_OK != Sys->getSoftwareFormat(&OutputRate, NULL, NULL, NULL, NULL, NULL)) +#endif { OutputRate = 48000; // Guess, but this should never happen. } @@ -1272,20 +1384,35 @@ void FMODSoundRenderer::PrintStatus() { Printf ("Output type: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(OutputNames, output)); } +#if FMOD_STUDIO + if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &speakermode, nullptr)) + { + Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); + Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); + } +#else if (FMOD_OK == Sys->getSpeakerMode(&speakermode)) { Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); } +#endif if (FMOD_OK == Sys->getDriver(&driver)) { char name[256]; +#if FMOD_STUDIO + if (FMOD_OK != Sys->getDriverInfo(driver, name, sizeof(name), nullptr, nullptr, nullptr, nullptr)) +#else if (FMOD_OK != Sys->getDriverInfo(driver, name, sizeof(name), NULL)) +#endif { strcpy(name, "Unknown"); } Printf ("Driver: " TEXTCOLOR_GREEN "%d" TEXTCOLOR_NORMAL " (" TEXTCOLOR_ORANGE "%s" TEXTCOLOR_NORMAL ")\n", driver, name); +#if !FMOD_STUDIO DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency); +#endif } +#if !FMOD_STUDIO if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) { Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); @@ -1293,6 +1420,7 @@ void FMODSoundRenderer::PrintStatus() Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: " TEXTCOLOR_GREEN "%d\n", numoutputchannels); Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(ResamplerNames, resampler)); } +#endif if (FMOD_OK == Sys->getDSPBufferSize(&bufferlength, &numbuffers)) { Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: " TEXTCOLOR_GREEN "%u samples x %d\n", bufferlength, numbuffers); @@ -1305,6 +1433,7 @@ void FMODSoundRenderer::PrintStatus() // //========================================================================== +#if !FMOD_STUDIO void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency) { Printf (TEXTCOLOR_OLIVE " Min. frequency: " TEXTCOLOR_GREEN "%d\n", minfrequency); @@ -1325,6 +1454,7 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max } if (caps & FMOD_CAPS_REVERB_LIMITED) Printf(TEXTCOLOR_OLIVE " Limited reverb\n"); } +#endif //========================================================================== // @@ -1342,7 +1472,11 @@ void FMODSoundRenderer::PrintDriversList() { for (i = 0; i < numdrivers; ++i) { +#if FMOD_STUDIO + if (FMOD_OK == Sys->getDriverInfo(i, name, sizeof(name), nullptr, nullptr, nullptr, nullptr)) +#else if (FMOD_OK == Sys->getDriverInfo(i, name, sizeof(name), NULL)) +#endif { Printf("%d. %s\n", i, name); } @@ -1365,7 +1499,7 @@ FString FMODSoundRenderer::GatherStats() channels = 0; total = update = geometry = stream = dsp = 0; Sys->getChannelsPlaying(&channels); -#if FMOD_VERSION >= 0x42501 +#if FMOD_STUDIO || FMOD_VERSION >= 0x42501 // We were built with an FMOD with the geometry parameter. if (ActiveFMODVersion >= 0x42501) { // And we are running with an FMOD that includes it. @@ -1612,7 +1746,11 @@ static void SetCustomLoopPts(FMOD::Sound *sound) // //========================================================================== +#if FMOD_STUDIO +static FMOD_RESULT F_CALLBACK open_reader_callback(const char *name, unsigned int *filesize, void **handle, void *userdata) +#else static FMOD_RESULT F_CALLBACK open_reader_callback(const char *name, int unicode, unsigned int *filesize, void **handle, void **userdata) +#endif { FileReader *reader = NULL; if(sscanf(name, "_FileReader_%p", &reader) != 1) @@ -1623,7 +1761,9 @@ static FMOD_RESULT F_CALLBACK open_reader_callback(const char *name, int unicode *filesize = reader->GetLength(); *handle = reader; +#if !FMOD_STUDIO *userdata = reader; +#endif return FMOD_OK; } @@ -1667,10 +1807,17 @@ SoundStream *FMODSoundRenderer::OpenStream(FileReader *reader, int flags) FString name; InitCreateSoundExInfo(&exinfo); +#if FMOD_STUDIO + exinfo.fileuseropen = open_reader_callback; + exinfo.fileuserclose = close_reader_callback; + exinfo.fileuserread = read_reader_callback; + exinfo.fileuserseek = seek_reader_callback; +#else exinfo.useropen = open_reader_callback; exinfo.userclose = close_reader_callback; exinfo.userread = read_reader_callback; exinfo.userseek = seek_reader_callback; +#endif mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM; if(flags & SoundStream::Loop) @@ -1775,7 +1922,11 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi FMOD::Channel *chan; float freq; +#if FMOD_STUDIO + if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&freq, NULL)) +#else if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&freq, NULL, NULL, NULL)) +#endif { freq = PITCH(freq, pitch); } @@ -1785,7 +1936,11 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi } GRolloff = NULL; // Do 2D sounds need rolloff? +#if FMOD_STUDIO + result = Sys->playSound((FMOD::Sound *)sfx.data, (flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx, true, &chan); +#else result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); +#endif if (FMOD_OK == result) { result = chan->getMode(&mode); @@ -1809,7 +1964,9 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi mode |= FMOD_LOOP_OFF; } chan->setMode(mode); +#if !FMOD_STUDIO chan->setChannelGroup((flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx); +#endif if (freq != 0) { chan->setFrequency(freq); @@ -1822,12 +1979,16 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi } if (flags & SNDF_NOREVERB) { +#if FMOD_STUDIO + chan->setReverbProperties(0,0.f); +#else FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; chan->setReverbProperties(&reverb); } +#endif } chan->setPaused(false); return CommonChannelSetup(chan, reuse_chan); @@ -1852,15 +2013,26 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * FMOD_MODE mode; FMOD::Channel *chan; float freq; - float def_freq, def_vol, def_pan; + float def_freq; +#if !FMOD_STUDIO + float def_vol, def_pan; +#endif int numchans; int def_priority; +#if FMOD_STUDIO + if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&def_freq, &def_priority)) +#else if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&def_freq, &def_vol, &def_pan, &def_priority)) +#endif { freq = PITCH(def_freq, pitch); // Change the sound's default priority before playing it. +#if FMOD_STUDIO + ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, clamp(def_priority - priority, 1, 256)); +#else ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, clamp(def_priority - priority, 1, 256)); +#endif } else { @@ -1876,12 +2048,20 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * // as long as the parameters are set properly. It will first try to kick out sounds // with the same priority level but has no problem with kicking out sounds at // higher priority levels if it needs to. +#if FMOD_STUDIO + result = Sys->playSound((FMOD::Sound *)sfx.data, (flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx, true, &chan); +#else result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); +#endif // Then set the priority back. if (def_priority >= 0) { +#if FMOD_STUDIO + ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_priority); +#else ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, def_priority); +#endif } if (FMOD_OK == result) @@ -1906,7 +2086,9 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * } mode = SetChanHeadSettings(listener, chan, pos, !!(flags & SNDF_AREA), mode); chan->setMode(mode); +#if !FMOD_STUDIO chan->setChannelGroup((flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx); +#endif if (mode & FMOD_3D) { @@ -1941,12 +2123,16 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * } if (flags & SNDF_NOREVERB) { +#if FMOD_STUDIO + chan->setReverbProperties(0,0.f); +#else FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; chan->setReverbProperties(&reverb); } +#endif } chan->setPaused(false); chan->getPriority(&def_priority); @@ -1970,7 +2156,14 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * void FMODSoundRenderer::MarkStartTime(FISoundChannel *chan) { +#if FMOD_STUDIO + unsigned long long int dsp_time; + ((FMOD::Channel *)chan->SysChannel)->getDSPClock(&dsp_time,NULL); + chan->StartTime.Lo = dsp_time & 0xFFFFFFFF; + chan->StartTime.Hi = dsp_time >> 32; +#else Sys->getDSPClock(&chan->StartTime.Hi, &chan->StartTime.Lo); +#endif } //========================================================================== @@ -1990,7 +2183,14 @@ bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel * { // Sound is being restarted, so seek it to the position // it would be in now if it had never been evicted. QWORD_UNION nowtime; +#if FMOD_STUDIO + unsigned long long int delay; + chan->getDelay(&delay,NULL,NULL); + nowtime.Lo = delay & 0xFFFFFFFF; + nowtime.Hi = delay >> 32; +#else chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &nowtime.Hi, &nowtime.Lo); +#endif // If abstime is set, the sound is being restored, and // the channel's start time is actually its seek position. @@ -2078,14 +2278,24 @@ FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(SoundListener *listener, FMOD:: { // Beyond interp_range: Normal 3D panning. level = 1; } +#if FMOD_STUDIO + if (chan->get3DLevel(&old_level) == FMOD_OK && old_level != level) + { // Only set it if it's different. + chan->set3DLevel(level); +#else if (chan->get3DPanLevel(&old_level) == FMOD_OK && old_level != level) { // Only set it if it's different. chan->set3DPanLevel(level); +#endif if (level < 1) { // Let the noise come from all speakers, not just the front ones. // A centered 3D sound does not play at full volume, so neither should the 2D-panned one. // This is sqrt(0.5), which is the result for a centered equal power panning. +#if FMOD_STUDIO + chan->setMixLevelsOutput(0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f); +#else chan->setSpeakerMix(0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f); +#endif } } return oldmode; @@ -2119,7 +2329,14 @@ FISoundChannel *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FISou else { schan = S_GetChannel(chan); +#if FMOD_STUDIO + unsigned long long int time; + chan->getDelay(&time,NULL,NULL); + schan->StartTime.Lo = time & 0xFFFFFFFF; + schan->StartTime.Hi = time >> 32; +#else chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &schan->StartTime.Hi, &schan->StartTime.Lo); +#endif } chan->setUserData(schan); chan->setCallback(ChannelCallback); @@ -2369,7 +2586,7 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener) if (LastWaterLP != snd_waterlp) { LastWaterLP = snd_waterlp; - WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); + WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); } WaterLP->setActive(true); if (WaterReverb != NULL && snd_waterreverb) @@ -2481,7 +2698,14 @@ void FMODSoundRenderer::Sync(bool sync) if (sync) { Sys->lockDSP(); +#if FMOD_STUDIO + unsigned long long int clock; + SfxGroup->getDSPClock(&clock,NULL); + DSPClock.Lo = clock & 0xFFFFFFFF; + DSPClock.Hi = clock >> 32; +#else Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo); +#endif } else { @@ -2499,7 +2723,14 @@ void FMODSoundRenderer::UpdateSounds() { // Any sounds played between now and the next call to this function // will start exactly one tic from now. +#if FMOD_STUDIO + unsigned long long int clock; + SfxGroup->getDSPClock(&clock,NULL); + DSPClock.Lo = clock & 0xFFFFFFFF; + DSPClock.Hi = clock >> 32; +#else Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo); +#endif DSPClock.AsOne += OutputRate / TICRATE; Sys->update(); } @@ -2673,18 +2904,34 @@ unsigned int FMODSoundRenderer::GetSampleLength(SoundHandle sfx) //========================================================================== FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelCallback +#if FMOD_STUDIO + (FMOD_CHANNELCONTROL *channel, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE type, void *data1, void *data2) +#else (FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *data1, void *data2) +#endif { +#if FMOD_STUDIO + FMOD::ChannelControl *chan = (FMOD::ChannelControl *)channel; +#else FMOD::Channel *chan = (FMOD::Channel *)channel; +#endif FISoundChannel *schan; if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL) { +#if FMOD_STUDIO + if (type == FMOD_CHANNELCONTROL_CALLBACK_END) +#else if (type == FMOD_CHANNEL_CALLBACKTYPE_END) +#endif { S_ChannelEnded(schan); } +#if FMOD_STUDIO + else if (type == FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE) +#else else if (type == FMOD_CHANNEL_CALLBACKTYPE_VIRTUALVOICE) +#endif { S_ChannelVirtualChanged(schan, data1 != 0); } @@ -2701,9 +2948,17 @@ FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelCallback // //========================================================================== +#if FMOD_STUDIO +float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNELCONTROL *channel, float distance) +#else float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNEL *channel, float distance) +#endif { +#if FMOD_STUDIO + FMOD::ChannelControl *chan = (FMOD::ChannelControl *)channel; +#else FMOD::Channel *chan = (FMOD::Channel *)channel; +#endif FISoundChannel *schan; if (GRolloff != NULL) @@ -2742,7 +2997,11 @@ void FMODSoundRenderer::DrawWaveDebug(int mode) const spk *labels; int labelcount; +#if FMOD_STUDIO + if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans)) +#else if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans, NULL, NULL, NULL)) +#endif { return; } @@ -2866,12 +3125,14 @@ int FMODSoundRenderer::DrawChannelGroupWaveData(FMOD::ChannelGroup *group, float int drawn = 0; int x = 16; +#if !FMOD_STUDIO while (FMOD_OK == group->getWaveData(wavearray, width, drawn)) { drawn++; DrawWave(wavearray, x, y, width, height); x += (width + 16) << int(skip); } +#endif if (drawn) { y += height + 16; @@ -2893,12 +3154,14 @@ int FMODSoundRenderer::DrawSystemWaveData(float *wavearray, int width, int heigh int drawn = 0; int x = 16; +#if !FMOD_STUDIO while (FMOD_OK == Sys->getWaveData(wavearray, width, drawn)) { drawn++; DrawWave(wavearray, x, y, width, height); x += (width + 16) << int(skip); } +#endif if (drawn) { y += height + 16; @@ -2970,12 +3233,15 @@ int FMODSoundRenderer::DrawChannelGroupSpectrum(FMOD::ChannelGroup *group, float { x += width + 16; } + // TODO: FMOD Studio: Grab from DSP +#if !FMOD_STUDIO while (FMOD_OK == group->getSpectrum(spectrumarray, SPECTRUM_SIZE, drawn, FMOD_DSP_FFT_WINDOW_TRIANGLE)) { drawn++; DrawSpectrum(spectrumarray, x, y, width, height); x += (width + 16) << int(skip); } +#endif if (drawn) { y += height + 16; @@ -3001,12 +3267,15 @@ int FMODSoundRenderer::DrawSystemSpectrum(float *spectrumarray, int width, int h { x += width + 16; } + // TODO: FMOD Studio: Grab from DSP +#if !FMOD_STUDIO while (FMOD_OK == Sys->getSpectrum(spectrumarray, SPECTRUM_SIZE, drawn, FMOD_DSP_FFT_WINDOW_TRIANGLE)) { drawn++; DrawSpectrum(spectrumarray, x, y, width, height); x += (width + 16) << int(skip); } +#endif if (drawn) { y += height + 16; @@ -3121,7 +3390,7 @@ short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizeby void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const { memset(exinfo, 0, sizeof(*exinfo)); -#if FMOD_VERSION >= 0x42600 && FMOD_VERSION < 0x43800 +#if !FMOD_STUDIO && FMOD_VERSION >= 0x42600 && FMOD_VERSION < 0x43800 if (ActiveFMODVersion < 0x42600) { // This parameter was added for 4.26.00, and trying to pass it to older @@ -3145,13 +3414,32 @@ void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) co FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES *props) { -#if FMOD_VERSION < 0x43600 +#if !FMOD_STUDIO && FMOD_VERSION < 0x43600 return Sys->setReverbProperties((const FMOD_REVERB_PROPERTIES *)props); #else // The reverb format changed when hardware mixing support was dropped, because // all EAX-only properties were removed from the structure. FMOD_REVERB_PROPERTIES fr; +#if FMOD_STUDIO + const float LateEarlyRatio = powf(10.f, (props->Reverb - props->Reflections)/2000.f); + const float EarlyAndLatePower = powf(10.f, props->Reflections/1000.f) + powf(10, props->Reverb/1000.f); + const float HFGain = powf(10.f, props->RoomHF/2000.f); + fr.DecayTime = props->DecayTime*1000.f; + fr.EarlyDelay = props->ReflectionsDelay*1000.f; + fr.LateDelay = props->ReverbDelay*1000.f; + fr.HFReference = props->HFReference; + fr.HFDecayRatio = clamp(props->DecayHFRatio*100.f, 0.f, 100.f); + fr.Diffusion = props->Diffusion; + fr.Density = props->Density; + fr.LowShelfFrequency = props->DecayLFRatio; + fr.LowShelfGain = clamp(props->RoomLF/100.f, -48.f, 12.f); + fr.HighCut = clamp(props->RoomLF < 0 ? props->HFReference/sqrtf((1.f-HFGain)/HFGain) : 20000.f, 20.f, 20000.f); + fr.EarlyLateMix = props->Reflections > -10000.f ? LateEarlyRatio/(LateEarlyRatio + 1)*100.f : 100.f; + fr.WetLevel = clamp(10*log10f(EarlyAndLatePower)+props->Room/100.f, -80.f, 20.f); + + return Sys->setReverbProperties(0, &fr); +#else fr.Instance = props->Instance; fr.Environment = props->Environment; fr.EnvDiffusion = props->EnvDiffusion; @@ -3175,6 +3463,7 @@ FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES return Sys->setReverbProperties(&fr); #endif +#endif } #endif // NO_FMOD diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 33b1f4bf71..e85a993c57 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -76,8 +76,13 @@ private: QWORD_UNION DSPClock; int OutputRate; +#if FMOD_STUDIO + static FMOD_RESULT F_CALLBACK ChannelCallback(FMOD_CHANNELCONTROL *channel, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE type, void *data1, void *data2); + static float F_CALLBACK RolloffCallback(FMOD_CHANNELCONTROL *channel, float distance); +#else static FMOD_RESULT F_CALLBACK ChannelCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *data1, void *data2); static float F_CALLBACK RolloffCallback(FMOD_CHANNEL *channel, float distance); +#endif bool HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, int flags, float freq) const; FISoundChannel *CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const; @@ -89,7 +94,9 @@ private: bool Init (); void Shutdown (); +#if !FMOD_STUDIO void DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency); +#endif int DrawChannelGroupOutput(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, int mode); int DrawSystemOutput(float *wavearray, int width, int height, int y, int mode); @@ -121,7 +128,9 @@ private: // Just for snd_status display int Driver_MinFrequency; int Driver_MaxFrequency; +#if !FMOD_STUDIO FMOD_CAPS Driver_Caps; +#endif friend class FMODStreamCapsule; }; From 9b91a1348766dd6a68186f32f21bd8efa0ba8ebe Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 28 Aug 2016 10:21:20 +0300 Subject: [PATCH 22/32] Restored legacy way to collect OpenGL extensions --- src/gl/system/gl_load.c | 56 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/src/gl/system/gl_load.c b/src/gl/system/gl_load.c index c686b60fc5..a32eb226fb 100644 --- a/src/gl/system/gl_load.c +++ b/src/gl/system/gl_load.c @@ -2447,11 +2447,49 @@ static void LoadExtByName(const char *extensionName) } } +/* BEGINNING OF MANUAL CHANGES, DO NOT REMOVE! */ -static void ProcExtsFromExtList(void) +static void ProcExtsFromExtString(const char *strExtList) +{ + size_t iExtListLen = strlen(strExtList); + const char *strExtListEnd = strExtList + iExtListLen; + const char *strCurrPos = strExtList; + char strWorkBuff[256]; + + while (*strCurrPos) + { + /*Get the extension at our position.*/ + int iStrLen = 0; + const char *strEndStr = strchr(strCurrPos, ' '); + int iStop = 0; + if (strEndStr == NULL) + { + strEndStr = strExtListEnd; + iStop = 1; + } + + iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos); + + if (iStrLen > 255) + return; + + strncpy(strWorkBuff, strCurrPos, iStrLen); + strWorkBuff[iStrLen] = '\0'; + + LoadExtByName(strWorkBuff); + + strCurrPos = strEndStr + 1; + if (iStop) break; + } +} + +static int ProcExtsFromExtList(void) { GLint iLoop; GLint iNumExtensions = 0; + + if (_ptrc_glGetStringi == NULL) return 0; + _ptrc_glGetIntegerv(GL_NUM_EXTENSIONS, &iNumExtensions); for(iLoop = 0; iLoop < iNumExtensions; iLoop++) @@ -2459,6 +2497,8 @@ static void ProcExtsFromExtList(void) const char *strExtensionName = (const char *)_ptrc_glGetStringi(GL_EXTENSIONS, iLoop); LoadExtByName(strExtensionName); } + + return iNumExtensions; } int ogl_LoadFunctions() @@ -2469,9 +2509,15 @@ int ogl_LoadFunctions() _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv"); if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED; _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi"); - if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED; - - ProcExtsFromExtList(); + + if (0 == ProcExtsFromExtList()) + { + _ptrc_glGetString = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGetString"); + if (!_ptrc_glGetString) return ogl_LOAD_FAILED; + + ProcExtsFromExtString((const char *)_ptrc_glGetString(GL_EXTENSIONS)); + } + numFailed = Load_Version_3_3(); if(numFailed == 0) @@ -2480,6 +2526,8 @@ int ogl_LoadFunctions() return ogl_LOAD_SUCCEEDED + numFailed; } +/* END OF MANUAL CHANGES, DO NOT REMOVE! */ + static int g_major_version = 0; static int g_minor_version = 0; From e04055dbb2e733b747fddbb90b46b39a4cc567e9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Aug 2016 09:55:04 +0200 Subject: [PATCH 23/32] - added multiple message levels for 'developer' CVAR so that the important stuff won't get drowned in pointless notification spam that's of no use to anyone. - made 'developer' CVAR persist across launches and added some menu entries for it. - added checks for 'developer' to ACS's CheckInventory function. --- src/b_game.cpp | 2 +- src/c_console.cpp | 4 +- src/compatibility.cpp | 2 +- src/d_dehacked.cpp | 54 +++++++++++------------ src/d_net.cpp | 2 +- src/dobjtype.cpp | 12 ++--- src/doomstat.cpp | 2 +- src/doomstat.h | 2 +- src/doomtype.h | 22 +++++---- src/farchive.cpp | 6 +-- src/g_shared/a_decals.cpp | 4 +- src/i_net.cpp | 2 +- src/p_acs.cpp | 22 ++++----- src/p_conversation.cpp | 6 +-- src/p_glnodes.cpp | 6 +-- src/p_maputl.cpp | 2 +- src/p_setup.cpp | 12 ++--- src/p_spec.cpp | 4 +- src/p_tick.cpp | 2 +- src/p_udmf.cpp | 2 +- src/p_user.cpp | 6 +-- src/posix/sdl/hardware.cpp | 8 ++-- src/r_segs.cpp | 4 +- src/r_things.cpp | 12 +++-- src/resourcefiles/file_wad.cpp | 6 +-- src/s_playlist.cpp | 6 +-- src/s_sound.cpp | 8 ++-- src/sc_man.cpp | 2 +- src/sound/fmodsound.cpp | 10 ++--- src/sound/i_sound.cpp | 4 +- src/sound/music_fluidsynth_mididevice.cpp | 4 +- src/sound/music_midi_timidity.cpp | 2 +- src/sound/music_xmi_midiout.cpp | 2 +- src/sound/oalsound.cpp | 26 +++++------ src/v_video.cpp | 5 ++- src/win32/win32video.cpp | 6 +-- wadsrc/static/language.enu | 5 +++ wadsrc/static/menudef.txt | 10 +++++ 38 files changed, 157 insertions(+), 139 deletions(-) diff --git a/src/b_game.cpp b/src/b_game.cpp index 9681aa7a80..9d6419787e 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -494,7 +494,7 @@ bool FCajunMaster::LoadBots () tmp = M_GetCajunPath(BOTFILENAME); if (tmp.IsEmpty()) { - DPrintf ("No " BOTFILENAME ", so no bots\n"); + DPrintf (DMSG_ERROR, "No " BOTFILENAME ", so no bots\n"); return false; } try diff --git a/src/c_console.cpp b/src/c_console.cpp index 9a9274aa16..850a29455d 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -612,12 +612,12 @@ int Printf (const char *format, ...) return count; } -int DPrintf (const char *format, ...) +int DPrintf (int level, const char *format, ...) { va_list argptr; int count; - if (developer) + if (developer >= level) { va_start (argptr, format); count = VPrintf (PRINT_HIGH, format, argptr); diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 5bb51129a4..24897ac270 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -399,7 +399,7 @@ void CheckCompatibility(MapData *map) flags = BCompatMap.CheckKey(md5); - if (developer) + if (developer >= DMSG_NOTIFY) { Printf("MD5 = "); for (size_t j = 0; j < sizeof(md5.Bytes); ++j) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 29a087facd..4beb5c25a5 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -450,7 +450,7 @@ int FindStyle (const char *namestr) { if (!stricmp(StyleNames[i].Name, namestr)) return StyleNames[i].Num; } - DPrintf("Unknown render style %s\n", namestr); + DPrintf(DMSG_ERROR, "Unknown render style %s\n", namestr); return -1; } @@ -861,7 +861,7 @@ static int PatchThing (int thingy) } else { - DPrintf ("Thing %d\n", thingy); + DPrintf (DMSG_SPAMMY, "Thing %d\n", thingy); if (thingy > 0) { type = InfoNames[thingy - 1]; @@ -1086,7 +1086,7 @@ static int PatchThing (int thingy) } if (i == BitNames.Size()) { - DPrintf("Unknown bit mnemonic %s\n", strval); + DPrintf(DMSG_ERROR, "Unknown bit mnemonic %s\n", strval); } } } @@ -1242,7 +1242,7 @@ static int PatchThing (int thingy) else info->renderflags &= ~RF_INVISIBLE; } - DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags.GetValue(), info->flags2.GetValue(), + DPrintf (DMSG_SPAMMY, "Bits: %d,%d (0x%08x,0x%08x)\n", info->flags.GetValue(), info->flags2.GetValue(), info->flags.GetValue(), info->flags2.GetValue()); } else if (stricmp (Line1, "ID #") == 0) @@ -1328,7 +1328,7 @@ static int PatchSound (int soundNum) { int result; - DPrintf ("Sound %d (no longer supported)\n", soundNum); + //DPrintf ("Sound %d (no longer supported)\n", soundNum); /* sfxinfo_t *info, dummy; int offset = 0; @@ -1385,7 +1385,7 @@ static int PatchFrame (int frameNum) info = FindState (frameNum); if (info) { - DPrintf ("Frame %d\n", frameNum); + DPrintf (DMSG_SPAMMY, "Frame %d\n", frameNum); if (frameNum == 47) { // Use original tics for S_DSGUNFLASH1 tics = 5; @@ -1487,7 +1487,7 @@ static int PatchSprite (int sprNum) if ((unsigned)sprNum < OrgSprNames.Size()) { - DPrintf ("Sprite %d\n", sprNum); + DPrintf (DMSG_SPAMMY, "Sprite %d\n", sprNum); } else { @@ -1534,7 +1534,7 @@ static int PatchAmmo (int ammoNum) if (ammoNum >= 0 && ammoNum < 4 && (unsigned)ammoNum <= AmmoNames.Size()) { - DPrintf ("Ammo %d.\n", ammoNum); + DPrintf (DMSG_SPAMMY, "Ammo %d.\n", ammoNum); ammoType = AmmoNames[ammoNum]; if (ammoType != NULL) { @@ -1617,7 +1617,7 @@ static int PatchWeapon (int weapNum) if (type != NULL) { info = (AWeapon *)GetDefaultByType (type); - DPrintf ("Weapon %d\n", weapNum); + DPrintf (DMSG_SPAMMY, "Weapon %d\n", weapNum); } } @@ -1757,7 +1757,7 @@ static int PatchPointer (int ptrNum) { if (CodePConv[ptrNum] == indexnum) break; } - DPrintf("Final ptrNum: %i\n", ptrNum); + DPrintf(DMSG_SPAMMY, "Final ptrNum: %i\n", ptrNum); } // End of hack. @@ -1765,7 +1765,7 @@ static int PatchPointer (int ptrNum) // Better to just use the size of the array rather than a hardcoded value. if (ptrNum >= 0 && (unsigned int) ptrNum < CodePConv.Size()) { - DPrintf ("Pointer %d\n", ptrNum); + DPrintf (DMSG_SPAMMY, "Pointer %d\n", ptrNum); } else { @@ -1789,7 +1789,7 @@ static int PatchPointer (int ptrNum) { SetPointer(state, Actions[index], CodePConv[ptrNum]); } - DPrintf("%s has a hacked state for pointer num %i with index %i\nLine1=%s, Line2=%s\n", + DPrintf(DMSG_SPAMMY, "%s has a hacked state for pointer num %i with index %i\nLine1=%s, Line2=%s\n", state->StaticFindStateOwner(state)->TypeName.GetChars(), ptrNum, index, Line1, Line2); } else @@ -1806,7 +1806,7 @@ static int PatchCheats (int dummy) { int result; - DPrintf ("Cheats (support removed by request)\n"); + DPrintf (DMSG_NOTIFY, "Dehacked cheats support removed by request\n"); while ((result = GetLine ()) == 1) { @@ -1836,7 +1836,7 @@ static int PatchMisc (int dummy) }; int result; - DPrintf ("Misc\n"); + DPrintf (DMSG_SPAMMY, "Misc\n"); while ((result = GetLine()) == 1) { @@ -2017,7 +2017,7 @@ static int PatchPars (int dummy) level_info_t *info; int result, par; - DPrintf ("[Pars]\n"); + DPrintf (DMSG_SPAMMY, "[Pars]\n"); while ( (result = GetLine()) ) { // Argh! .bex doesn't follow the same rules as .deh @@ -2058,7 +2058,7 @@ static int PatchPars (int dummy) } info->partime = par; - DPrintf ("Par for %s changed to %d\n", mapname, par); + DPrintf (DMSG_SPAMMY, "Par for %s changed to %d\n", mapname, par); } return result; } @@ -2067,7 +2067,7 @@ static int PatchCodePtrs (int dummy) { int result; - DPrintf ("[CodePtr]\n"); + DPrintf (DMSG_SPAMMY, "[CodePtr]\n"); while ((result = GetLine()) == 1) { @@ -2132,7 +2132,7 @@ static int PatchMusic (int dummy) { int result; - DPrintf ("[Music]\n"); + DPrintf (DMSG_SPAMMY, "[Music]\n"); while ((result = GetLine()) == 1) { @@ -2142,7 +2142,7 @@ static int PatchMusic (int dummy) keystring << "MUSIC_" << Line1; GStrings.SetString (keystring, newname); - DPrintf ("Music %s set to:\n%s\n", keystring.GetChars(), newname); + DPrintf (DMSG_SPAMMY, "Music %s set to:\n%s\n", keystring.GetChars(), newname); } return result; @@ -2198,7 +2198,7 @@ static int PatchText (int oldSize) goto donewithtext; } - DPrintf ("Searching for text:\n%s\n", oldStr); + DPrintf (DMSG_SPAMMY, "Searching for text:\n%s\n", oldStr); good = false; // Search through sprite names; they are always 4 chars @@ -2264,7 +2264,7 @@ static int PatchText (int oldSize) if (!good) { - DPrintf (" (Unmatched)\n"); + DPrintf (DMSG_SPAMMY, " (Unmatched)\n"); } donewithtext: @@ -2284,7 +2284,7 @@ static int PatchStrings (int dummy) { int result; - DPrintf ("[Strings]\n"); + DPrintf (DMSG_SPAMMY, "[Strings]\n"); while ((result = GetLine()) == 1) { @@ -2310,7 +2310,7 @@ static int PatchStrings (int dummy) const char *ll = Line1; if (!stricmp(ll, "GOTREDSKULL")) ll = "GOTREDSKUL"; GStrings.SetString (ll, holdstring); - DPrintf ("%s set to:\n%s\n", Line1, holdstring.GetChars()); + DPrintf (DMSG_SPAMMY, "%s set to:\n%s\n", Line1, holdstring.GetChars()); } return result; @@ -2350,7 +2350,7 @@ static int DoInclude (int dummy) else { data = Line2; - DPrintf ("Including %s\n", data); + DPrintf (DMSG_SPAMMY, "Including %s\n", data); savepatchname = PatchName; savepatchfile = PatchFile; savepatchpt = PatchPt; @@ -2384,7 +2384,7 @@ static int DoInclude (int dummy) delete[] path; } - DPrintf ("Done with include\n"); + DPrintf (DMSG_SPAMMY, "Done with include\n"); PatchName = savepatchname; PatchFile = savepatchfile; PatchPt = savepatchpt; @@ -2536,7 +2536,7 @@ static bool DoDehPatch() } else { - DPrintf ("Patch does not have DeHackEd signature. Assuming .bex\n"); + DPrintf (DMSG_WARNING, "Patch does not have DeHackEd signature. Assuming .bex\n"); dversion = 19; pversion = 6; PatchPt = PatchFile; @@ -3027,7 +3027,7 @@ void FinishDehPatch () subclass->Replacement = old_replacement; } - DPrintf ("%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars()); + DPrintf (DMSG_NOTIFY, "%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars()); } // Now that all Dehacked patches have been processed, it's okay to free StateMap. diff --git a/src/d_net.cpp b/src/d_net.cpp index eadd47d965..2611338679 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -231,7 +231,7 @@ static struct TicSpecial specialsize = MAX(specialsize * 2, needed + 30); - DPrintf ("Expanding special size to %zu\n", specialsize); + DPrintf (DMSG_NOTIFY, "Expanding special size to %zu\n", specialsize); for (i = 0; i < BACKUPTICS; i++) streams[i] = (BYTE *)M_Realloc (streams[i], specialsize); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index a7f07247f2..7a593c5fe3 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2134,7 +2134,7 @@ bool PArray::ReadValue(FArchive &ar, void *addr) const } if (i < ElementCount) { - DPrintf("Array on disk (%u) is bigger than in memory (%u)\n", + DPrintf(DMSG_WARNING, "Array on disk (%u) is bigger than in memory (%u)\n", count, ElementCount); for (; i < ElementCount; ++i) { @@ -2501,13 +2501,13 @@ bool PStruct::ReadFields(FArchive &ar, void *addr) const const PSymbol *sym = Symbols.FindSymbol(FName(label, true), true); if (sym == NULL) { - DPrintf("Cannot find field %s in %s\n", + DPrintf(DMSG_ERROR, "Cannot find field %s in %s\n", label, TypeName.GetChars()); SkipValue(ar); } else if (!sym->IsKindOf(RUNTIME_CLASS(PField))) { - DPrintf("Symbol %s in %s is not a field\n", + DPrintf(DMSG_ERROR, "Symbol %s in %s is not a field\n", label, TypeName.GetChars()); SkipValue(ar); } @@ -2806,7 +2806,7 @@ bool PClass::ReadValue(FArchive &ar, void *addr) const } else { - DPrintf("Unknown superclass %s of class %s\n", + DPrintf(DMSG_ERROR, "Unknown superclass %s of class %s\n", type->TypeName.GetChars(), TypeName.GetChars()); SkipValue(ar, VAL_Struct); } @@ -3243,7 +3243,7 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size) { I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars()); } - DPrintf("Defining placeholder class %s\n", name.GetChars()); + DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars()); notnew = true; } else @@ -3327,7 +3327,7 @@ PClass *PClass::FindClassTentative(FName name, bool fatal) return static_cast(found); } PClass *type = static_cast(GetClass()->CreateNew()); - DPrintf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars()); + DPrintf(DMSG_SPAMMY, "Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars()); type->TypeName = name; type->ParentClass = this; diff --git a/src/doomstat.cpp b/src/doomstat.cpp index d693aae1b9..87ca50a168 100644 --- a/src/doomstat.cpp +++ b/src/doomstat.cpp @@ -39,7 +39,7 @@ FStringTable GStrings; EGameSpeed GameSpeed = SPEED_Normal; // Show developer messages if true. -CVAR (Bool, developer, false, 0) +CVAR (Int, developer, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // [RH] Feature control cvars CVAR (Bool, var_friction, true, CVAR_SERVERINFO); diff --git a/src/doomstat.h b/src/doomstat.h index cfdca5e5a3..bbb323c7e3 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -204,7 +204,7 @@ extern int bodyqueslot; // ---- [RH] ---- -EXTERN_CVAR (Bool, developer) +EXTERN_CVAR (Int, developer) extern bool ToggleFullscreen; diff --git a/src/doomtype.h b/src/doomtype.h index 39c59751d3..34f750313b 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -147,7 +147,7 @@ int Printf (int printlevel, const char *, ...) GCCPRINTF(2,3); int Printf (const char *, ...) GCCPRINTF(1,2); // [RH] Same here: -int DPrintf (const char *, ...) GCCPRINTF(1,2); +int DPrintf (int level, const char *, ...) GCCPRINTF(2,3); extern "C" int mysnprintf(char *buffer, size_t count, const char *format, ...) GCCPRINTF(3,4); extern "C" int myvsnprintf(char *buffer, size_t count, const char *format, va_list argptr) GCCFORMAT(3); @@ -160,15 +160,19 @@ enum PRINT_MEDIUM, // death messages PRINT_HIGH, // critical messages PRINT_CHAT, // chat messages - PRINT_TEAMCHAT // chat messages from a teammate + PRINT_TEAMCHAT, // chat messages from a teammate + PRINT_LOG, // only to logfile + PRINT_BOLD = 200 // What Printf_Bold used +}; + +enum +{ + DMSG_OFF, // no developer messages. + DMSG_ERROR, // general notification messages + DMSG_WARNING, // warnings + DMSG_NOTIFY, // general notification messages + DMSG_SPAMMY, // for those who want to see everything, regardless of its usefulness. }; -#define PRINT_LOW 0 // pickup messages -#define PRINT_MEDIUM 1 // death messages -#define PRINT_HIGH 2 // critical messages -#define PRINT_CHAT 3 // chat messages -#define PRINT_TEAMCHAT 4 // chat messages from a teammate -#define PRINT_LOG 5 // only to logfile -#define PRINT_BOLD 200 // What Printf_Bold used struct PalEntry { diff --git a/src/farchive.cpp b/src/farchive.cpp index 317abe702f..de3e248a47 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -354,12 +354,12 @@ void FCompressedFile::Implode () // If the data could not be compressed, store it as-is. if (r != Z_OK || outlen >= len) { - DPrintf ("cfile could not be compressed\n"); + DPrintf (DMSG_SPAMMY, "cfile could not be compressed\n"); outlen = 0; } else { - DPrintf ("cfile shrank from %lu to %lu bytes\n", len, outlen); + DPrintf (DMSG_SPAMMY, "cfile shrank from %lu to %lu bytes\n", len, outlen); } } else @@ -717,7 +717,7 @@ void FArchive::Close () { m_File->Close (); m_File = NULL; - DPrintf ("Processed %u objects\n", ArchiveToObject.Size()); + DPrintf (DMSG_SPAMMY, "Processed %u objects\n", ArchiveToObject.Size()); } } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index c37c1065a5..94e92e7258 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -825,13 +825,13 @@ void ADecal::BeginPlay () // without effectively doing anything. if (NULL == ShootDecal(tpl, this, Sector, X(), Y(), Z(), Angles.Yaw + 180, 64., true)) { - DPrintf ("Could not find a wall to stick decal to at (%f,%f)\n", X(), Y()); + DPrintf (DMSG_WARNING, "Could not find a wall to stick decal to at (%f,%f)\n", X(), Y()); } } } else { - DPrintf ("Decal actor at (%f,%f) does not have a good template\n", X(), Y()); + DPrintf (DMSG_ERROR, "Decal actor at (%f,%f) does not have a good template\n", X(), Y()); } // This actor doesn't need to stick around anymore. Destroy(); diff --git a/src/i_net.cpp b/src/i_net.cpp index 5957846d2a..e03f50a6ba 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -322,7 +322,7 @@ void PacketGet (void) // Don't show the message for disconnect notifications. if (c != 2 || TransmitBuffer[0] != PRE_FAKE || TransmitBuffer[1] != PRE_DISCONNECT) { - DPrintf("Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port); + DPrintf(DMSG_WARNING, "Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port); } doomcom.remotenode = -1; return; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 0762b3e294..5f08f01526 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1331,12 +1331,12 @@ static int CheckInventory (AActor *activator, const char *type, bool max) if (info == NULL) { - Printf ("ACS: I don't know what '%s' is.\n", type); + DPrintf (DMSG_ERROR, "ACS: '%s': Unknown actor class.\n", type); return 0; } else if (!info->IsDescendantOf(RUNTIME_CLASS(AInventory))) { - Printf ("ACS: '%s' is not an inventory item.\n", type); + DPrintf(DMSG_ERROR, "ACS: '%s' is not an inventory item.\n", type); return 0; } @@ -2237,7 +2237,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) } } - DPrintf ("Loaded %d scripts, %d functions\n", NumScripts, NumFunctions); + DPrintf (DMSG_NOTIFY, "Loaded %d scripts, %d functions\n", NumScripts, NumFunctions); return true; } @@ -2824,7 +2824,7 @@ void FBehavior::StaticStartTypedScripts (WORD type, AActor *activator, bool alwa "Disconnect", "Return" }; - DPrintf("Starting all scripts of type %d (%s)\n", type, + DPrintf(DMSG_NOTIFY, "Starting all scripts of type %d (%s)\n", type, type < countof(TypeNames) ? TypeNames[type] : TypeNames[SCRIPT_Lightning - 1]); for (unsigned int i = 0; i < StaticModules.Size(); ++i) { @@ -6209,7 +6209,7 @@ int DLevelScript::RunScript () activeBehavior = savedActiveBehavior; // fall through case PCD_TERMINATE: - DPrintf ("%s finished\n", ScriptPresentation(script).GetChars()); + DPrintf (DMSG_NOTIFY, "%s finished\n", ScriptPresentation(script).GetChars()); state = SCRIPT_PleaseRemove; break; @@ -7646,7 +7646,7 @@ scriptwait: if (activationline != NULL) { activationline->special = 0; - DPrintf("Cleared line special on line %d\n", (int)(activationline - lines)); + DPrintf(DMSG_SPAMMY, "Cleared line special on line %d\n", (int)(activationline - lines)); } break; @@ -8285,7 +8285,7 @@ scriptwait: line->args[2] = STACK(3); line->args[3] = STACK(2); line->args[4] = STACK(1); - DPrintf("Set special on line %d (id %d) to %d(%d,%d,%d,%d,%d)\n", + DPrintf(DMSG_SPAMMY, "Set special on line %d (id %d) to %d(%d,%d,%d,%d,%d)\n", linenum, STACK(7), specnum, arg0, STACK(4), STACK(3), STACK(2), STACK(1)); } sp -= 7; @@ -9663,7 +9663,7 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr PutLast(); } - DPrintf("%s started.\n", ScriptPresentation(num).GetChars()); + DPrintf(DMSG_SPAMMY, "%s started.\n", ScriptPresentation(num).GetChars()); } static void SetScriptState (int script, DLevelScript::EScriptState state) @@ -9710,12 +9710,12 @@ void P_DoDeferedScripts () case acsdefered_t::defsuspend: SetScriptState (def->script, DLevelScript::SCRIPT_Suspended); - DPrintf ("Deferred suspend of %s\n", ScriptPresentation(def->script).GetChars()); + DPrintf (DMSG_SPAMMY, "Deferred suspend of %s\n", ScriptPresentation(def->script).GetChars()); break; case acsdefered_t::defterminate: SetScriptState (def->script, DLevelScript::SCRIPT_PleaseRemove); - DPrintf ("Deferred terminate of %s\n", ScriptPresentation(def->script).GetChars()); + DPrintf (DMSG_SPAMMY, "Deferred terminate of %s\n", ScriptPresentation(def->script).GetChars()); break; } delete def; @@ -9751,7 +9751,7 @@ static void addDefered (level_info_t *i, acsdefered_t::EType type, int script, c def->playernum = -1; } i->defered = def; - DPrintf ("%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->MapName.GetChars()); + DPrintf (DMSG_SPAMMY, "%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->MapName.GetChars()); } } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 64fe2cbab2..5456033688 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -253,7 +253,7 @@ static bool LoadScriptFile(int lumpnum, FileReader *lump, int numnodes, bool inc if ((type == 1 && !isbinary) || (type == 2 && isbinary)) { - DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); + DPrintf(DMSG_ERROR, "Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); return false; } @@ -273,7 +273,7 @@ static bool LoadScriptFile(int lumpnum, FileReader *lump, int numnodes, bool inc // is exactly 1516 bytes long. if (numnodes % 1516 != 0) { - DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); + DPrintf(DMSG_ERROR, "Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); return false; } numnodes /= 1516; @@ -283,7 +283,7 @@ static bool LoadScriptFile(int lumpnum, FileReader *lump, int numnodes, bool inc // And the teaser version has 1488-byte entries. if (numnodes % 1488 != 0) { - DPrintf("Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); + DPrintf(DMSG_ERROR, "Incorrect data format for %s.", Wads.GetLumpFullName(lumpnum)); return false; } numnodes /= 1488; diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 0fe4cd9c0b..39c8f8e0dc 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1013,7 +1013,7 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) subsectors, numsubsectors, vertexes, numvertexes); endTime = I_FPSTime (); - DPrintf ("BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); + DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); buildtime = endTime - startTime; } } @@ -1026,12 +1026,12 @@ bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime) #endif if (level.maptype != MAPTYPE_BUILD && gl_cachenodes && buildtime/1000.f >= gl_cachetime) { - DPrintf("Caching nodes\n"); + DPrintf(DMSG_NOTIFY, "Caching nodes\n"); CreateCachedNodes(map); } else { - DPrintf("Not caching nodes (time = %f)\n", buildtime/1000.f); + DPrintf(DMSG_NOTIFY, "Not caching nodes (time = %f)\n", buildtime/1000.f); } } diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 5fa8aa2f29..a3d4d0e9eb 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -361,7 +361,7 @@ bool AActor::FixMapthingPos() if (distance < radius) { - DPrintf("%s at (%f,%f) lies on %s line %td, distance = %f\n", + DPrintf(DMSG_NOTIFY, "%s at (%f,%f) lies on %s line %td, distance = %f\n", this->GetClass()->TypeName.GetChars(), X(), Y(), ldef->Delta().X == 0 ? "vertical" : ldef->Delta().Y == 0 ? "horizontal" : "diagonal", ldef - lines, distance); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 92636fb0cd..d8d95d2776 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1689,7 +1689,7 @@ static void SetMapThingUserData(AActor *actor, unsigned udi) if (var == NULL || (var->Flags & VARF_Native) || !var->Type->IsKindOf(RUNTIME_CLASS(PBasicType))) { - DPrintf("%s is not a user variable in class %s\n", varname.GetChars(), + DPrintf(DMSG_WARNING, "%s is not a user variable in class %s\n", varname.GetChars(), actor->GetClass()->TypeName.GetChars()); } else @@ -2477,7 +2477,7 @@ int P_DetermineTranslucency (int lumpnum) if (newcolor2.r == 255) // if black on white results in white it's either // fully transparent or additive { - if (developer) + if (developer >= DMSG_NOTIFY) { char lumpname[9]; lumpname[8] = 0; @@ -2488,7 +2488,7 @@ int P_DetermineTranslucency (int lumpnum) return -newcolor.r; } - if (developer) + if (developer >= DMSG_NOTIFY) { char lumpname[9]; lumpname[8] = 0; @@ -3028,7 +3028,7 @@ void P_LoadBlockMap (MapData * map) Args->CheckParm("-blockmap") ) { - DPrintf ("Generating BLOCKMAP\n"); + DPrintf (DMSG_SPAMMY, "Generating BLOCKMAP\n"); P_CreateBlockMap (); } else @@ -3060,7 +3060,7 @@ void P_LoadBlockMap (MapData * map) if (!P_VerifyBlockMap(count)) { - DPrintf ("Generating BLOCKMAP\n"); + DPrintf (DMSG_SPAMMY, "Generating BLOCKMAP\n"); P_CreateBlockMap(); } @@ -3957,7 +3957,7 @@ void P_SetupLevel (const char *lumpname, int position) subsectors, numsubsectors, vertexes, numvertexes); endTime = I_FPSTime (); - DPrintf ("BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); + DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, numsegs); oldvertextable = builder.GetOldVertexTable(); reloop = true; } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 67bb4de73c..4c3bdb488e 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -186,7 +186,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe line->special = 0; } // end of changed code - if (developer && buttonSuccess) + if (developer >= DMSG_SPAMMY && buttonSuccess) { Printf ("Line special %d activated on line %i\n", special, int(line - lines)); } @@ -358,7 +358,7 @@ bool P_PredictLine(line_t *line, AActor *mo, int side, int activationType) special = line->special; // end of changed code - if (developer && buttonSuccess) + if (developer >= DMSG_SPAMMY && buttonSuccess) { Printf("Line special %d predicted on line %i\n", special, int(line - lines)); } diff --git a/src/p_tick.cpp b/src/p_tick.cpp index 978c2c7ef6..332b7af81c 100644 --- a/src/p_tick.cpp +++ b/src/p_tick.cpp @@ -42,7 +42,7 @@ extern gamestate_t wipegamestate; // // P_CheckTickerPaused // -// Returns true if the ticker should be paused. In that cause, it also +// Returns true if the ticker should be paused. In that case, it also // pauses sound effects and possibly music. If the ticker should not be // paused, then it returns false but does not unpause anything. // diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 86116f8811..0b054247eb 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -147,7 +147,7 @@ extern TArray linemap; void UDMFParserBase::Skip() { - if (developer) sc.ScriptMessage("Ignoring unknown key \"%s\".", sc.String); + if (developer >= DMSG_WARNING) sc.ScriptMessage("Ignoring unknown UDMF key \"%s\".", sc.String); if(sc.CheckToken('{')) { int level = 1; diff --git a/src/p_user.cpp b/src/p_user.cpp index e4b6ec6bd9..b602432b33 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2441,7 +2441,7 @@ void P_PlayerThink (player_t *player) S_ChangeMusic("*"); } } - DPrintf("MUSINFO change for player %d to %d\n", (int)(player - players), player->MUSINFOactor->args[0]); + DPrintf(DMSG_NOTIFY, "MUSINFO change for player %d to %d\n", (int)(player - players), player->MUSINFOactor->args[0]); } } @@ -2828,9 +2828,9 @@ void P_PredictPlayer (player_t *player) DoLerp = (int)PredictionLast.pos.X != (int)player->mo->X() || (int)PredictionLast.pos.Y != (int)player->mo->Y(); // Aditional Debug information - if (developer && DoLerp) + if (developer >= DMSG_NOTIFY && DoLerp) { - DPrintf("Lerp! Ltic (%d) && Ptic (%d) | Lx (%f) && Px (%f) | Ly (%f) && Py (%f)\n", + DPrintf(DMSG_NOTIFY, "Lerp! Ltic (%d) && Ptic (%d) | Lx (%f) && Px (%f) | Ly (%f) && Py (%f)\n", PredictionLast.gametic, i, (PredictionLast.pos.X), (player->mo->X()), (PredictionLast.pos.Y), (player->mo->Y())); diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp index 6142eb1d8e..8bae3f900c 100644 --- a/src/posix/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -242,18 +242,18 @@ void I_SetFPSLimit(int limit) } if (limit == 0) { // no limit - DPrintf("FPS timer disabled\n"); + DPrintf(DMSG_NOTIFY, "FPS timer disabled\n"); } else { FPSLimitTimerEnabled = true; if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1) - Printf("Failed to create FPS limitter event\n"); + Printf(DMSG_WARNING, "Failed to create FPS limitter event\n"); itimerspec period = { {0, 0}, {0, 0} }; period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit; if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1) - Printf("Failed to set FPS limitter timer\n"); - DPrintf("FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000); + Printf(DMSG_WARNING, "Failed to set FPS limitter timer\n"); + DPrintf(DMSG_NOTIFY, "FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000); } } #else diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 4eb3cb440c..edb1949b62 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2341,7 +2341,7 @@ void R_CheckDrawSegs () firstdrawseg = drawsegs + firstofs; ds_p = drawsegs + MaxDrawSegs; MaxDrawSegs = newdrawsegs; - DPrintf ("MaxDrawSegs increased to %zu\n", MaxDrawSegs); + DPrintf (DMSG_NOTIFY, "MaxDrawSegs increased to %zu\n", MaxDrawSegs); } } @@ -2360,7 +2360,7 @@ ptrdiff_t R_NewOpening (ptrdiff_t len) maxopenings = maxopenings ? maxopenings*2 : 16384; while ((size_t)lastopening > maxopenings); openings = (short *)M_Realloc (openings, maxopenings * sizeof(*openings)); - DPrintf ("MaxOpenings increased to %zu\n", maxopenings); + DPrintf (DMSG_NOTIFY, "MaxOpenings increased to %zu\n", maxopenings); } return res; } diff --git a/src/r_things.cpp b/src/r_things.cpp index aad8fb501e..28b52129b2 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -222,7 +222,7 @@ vissprite_t *R_NewVisSprite (void) lastvissprite = &vissprites[MaxVisSprites]; firstvissprite = &vissprites[firstvisspritenum]; vissprite_p = &vissprites[prevvisspritenum]; - DPrintf ("MaxVisSprites increased to %d\n", MaxVisSprites); + DPrintf (DMSG_NOTIFY, "MaxVisSprites increased to %d\n", MaxVisSprites); // Allocate sprites from the new pile for (vissprite_t **p = vissprite_p; p < lastvissprite; ++p) @@ -832,13 +832,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor else { // decide which texture to use for the sprite -#ifdef RANGECHECK - if (spritenum >= (signed)sprites.Size () || spritenum < 0) + if ((unsigned)spritenum >= sprites.Size ()) { - DPrintf ("R_ProjectSprite: invalid sprite number %u\n", spritenum); + DPrintf (DMSG_ERROR, "R_ProjectSprite: invalid sprite number %u\n", spritenum); return; } -#endif spritedef_t *sprdef = &sprites[spritenum]; if (thing->frame >= sprdef->numframes) { @@ -1312,13 +1310,13 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double // decide which patch to use if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size()) { - DPrintf("R_DrawPSprite: invalid sprite number %i\n", pspr->GetSprite()); + DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite number %i\n", pspr->GetSprite()); return; } sprdef = &sprites[pspr->GetSprite()]; if (pspr->GetFrame() >= sprdef->numframes) { - DPrintf("R_DrawPSprite: invalid sprite frame %i : %i\n", pspr->GetSprite(), pspr->GetFrame()); + DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite frame %i : %i\n", pspr->GetSprite(), pspr->GetFrame()); return; } sprframe = &SpriteFrames[sprdef->spriteframes + pspr->GetFrame()]; diff --git a/src/resourcefiles/file_wad.cpp b/src/resourcefiles/file_wad.cpp index 0732d4c115..5965a5c8a6 100644 --- a/src/resourcefiles/file_wad.cpp +++ b/src/resourcefiles/file_wad.cpp @@ -471,7 +471,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - DPrintf("Marking %s as potential flat\n", Lumps[i].Name); + DPrintf(DMSG_NOTIFY, "Marking %s as potential flat\n", Lumps[i].Name); Lumps[i].Flags |= LUMPF_MAYBEFLAT; } } @@ -517,7 +517,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - DPrintf("Found %s block at (%d-%d)\n", startmarker, markers[start].index, end); + DPrintf(DMSG_NOTIFY, "Found %s block at (%d-%d)\n", startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) @@ -534,7 +534,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - DPrintf(" Skipped empty sprite %s (lump %d)\n", Lumps[j].Name, j); + DPrintf(DMSG_WARNING, " Skipped empty sprite %s (lump %d)\n", Lumps[j].Name, j); } else { diff --git a/src/s_playlist.cpp b/src/s_playlist.cpp index ec775e275f..e1b0fd5b61 100644 --- a/src/s_playlist.cpp +++ b/src/s_playlist.cpp @@ -182,7 +182,7 @@ int FPlayList::SetPosition (int position) { Position = position; } - DPrintf ("Playlist position set to %d\n", Position); + DPrintf (DMSG_NOTIFY, "Playlist position set to %d\n", Position); return Position; } @@ -197,7 +197,7 @@ int FPlayList::Advance () { Position = 0; } - DPrintf ("Playlist advanced to song %d\n", Position); + DPrintf (DMSG_NOTIFY, "Playlist advanced to song %d\n", Position); return Position; } @@ -207,7 +207,7 @@ int FPlayList::Backup () { Position = Songs.Size() - 1; } - DPrintf ("Playlist backed up to song %d\n", Position); + DPrintf (DMSG_NOTIFY, "Playlist backed up to song %d\n", Position); return Position; } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 321cbce1b8..2149f7814d 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -552,7 +552,7 @@ void S_UnloadSound (sfxinfo_t *sfx) GSnd->UnloadSound(sfx->data); sfx->data.Clear(); sfx->data3d.Clear(); - DPrintf("Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); + DPrintf(DMSG_NOTIFY, "Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); } } @@ -1327,7 +1327,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) { if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum) { - DPrintf ("Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i); + DPrintf (DMSG_NOTIFY, "Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i); sfx->link = i; // This is necessary to avoid using the rolloff settings of the linked sound if its // settings are different. @@ -1336,7 +1336,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) } } - DPrintf("Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); + DPrintf(DMSG_NOTIFY, "Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); int size = Wads.LumpLength(sfx->lumpnum); if (size > 0) @@ -1396,7 +1396,7 @@ static void S_LoadSound3D(sfxinfo_t *sfx) if(sfx->data3d.isValid()) return; - DPrintf("Loading monoized sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); + DPrintf(DMSG_NOTIFY, "Loading monoized sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); int size = Wads.LumpLength(sfx->lumpnum); if(size <= 0) return; diff --git a/src/sc_man.cpp b/src/sc_man.cpp index da106927e3..3f5530ff36 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -1044,7 +1044,7 @@ void FScriptPosition::Message (int severity, const char *message, ...) const { FString composed; - if ((severity == MSG_DEBUG || severity == MSG_DEBUGLOG) && !developer) return; + if ((severity == MSG_DEBUG || severity == MSG_DEBUGLOG) && developer < DMSG_NOTIFY) return; if (severity == MSG_OPTERROR) { severity = strictdecorate ? MSG_ERROR : MSG_WARNING; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 465aade9b6..2db5a98a10 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1994,7 +1994,7 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi return CommonChannelSetup(chan, reuse_chan); } - //DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); + //DPrintf (DMSG_WARNING, "Sound %s failed to play: %d\n", sfx->name.GetChars(), result); return NULL; } @@ -2142,7 +2142,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * } GRolloff = NULL; - //DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); + //DPrintf (DMSG_WARNING, "Sound %s failed to play: %d\n", sfx->name.GetChars(), result); return 0; } @@ -2566,7 +2566,7 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener) } if (env != PrevEnvironment || env->Modified) { - DPrintf ("Reverb Environment %s\n", env->Name); + DPrintf (DMSG_NOTIFY, "Reverb Environment %s\n", env->Name); const_cast(env)->Modified = false; SetSystemReverbProperties(&env->Properties); PrevEnvironment = env; @@ -2791,7 +2791,7 @@ std::pair FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int l result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); if (result != FMOD_OK) { - DPrintf("Failed to allocate sample: Error %d\n", result); + DPrintf(DMSG_ERROR, "Failed to allocate sample: Error %d\n", result); return std::make_pair(retval, true); } @@ -2829,7 +2829,7 @@ std::pair FMODSoundRenderer::LoadSound(BYTE *sfxdata, int leng result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); if (result != FMOD_OK) { - DPrintf("Failed to allocate sample: Error %d\n", result); + DPrintf(DMSG_ERROR, "Failed to allocate sample: Error %d\n", result); return std::make_pair(retval, true); } SetCustomLoopPts(sample); diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index f19e080c34..67f46b266f 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -417,7 +417,7 @@ short *SoundRenderer::DecodeSample(int outlen, const void *coded, int sizebytes, decoder->getInfo(&srate, &chans, &type); if(chans != ChannelConfig_Mono || type != SampleType_Int16) { - DPrintf("Sample is not 16-bit mono\n"); + DPrintf(DMSG_WARNING, "Sample is not 16-bit mono\n"); delete decoder; return samples; } @@ -553,7 +553,7 @@ std::pair SoundRenderer::LoadSoundVoc(BYTE *sfxdata, int lengt break; default: // Unknown block type okay = false; - DPrintf ("Unknown VOC block type %i\n", blocktype); + DPrintf (DMSG_ERROR, "Unknown VOC block type %i\n", blocktype); break; } // Move to next block diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index 0427ca438f..b3f7b7d458 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -498,12 +498,12 @@ int FluidSynthMIDIDevice::LoadPatchSets(const char *patches) } if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, path, count == 0)) { - DPrintf("Loaded patch set %s.\n", tok); + DPrintf(DMSG_NOTIFY, "Loaded patch set %s.\n", tok); count++; } else { - DPrintf("Failed to load patch set %s.\n", tok); + DPrintf(DMSG_ERROR, "Failed to load patch set %s.\n", tok); } tok = strtok(NULL, delim); } diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 30468839d4..ee9d322a40 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -376,7 +376,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity () return false; } - DPrintf ("cmd: \x1cG%s\n", CommandLine.GetChars()); + DPrintf (DMSG_NOTIFY, "cmd: \x1cG%s\n", CommandLine.GetChars()); #ifdef _WIN32 STARTUPINFO startup = { sizeof(startup), }; diff --git a/src/sound/music_xmi_midiout.cpp b/src/sound/music_xmi_midiout.cpp index 50b95a7762..a9cbcd2c60 100644 --- a/src/sound/music_xmi_midiout.cpp +++ b/src/sound/music_xmi_midiout.cpp @@ -143,7 +143,7 @@ XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args) memset(Songs, 0, sizeof(*Songs) * NumSongs); FindXMIDforms(MusHeader, SongLen, Songs); CurrSong = Songs; - DPrintf("XMI song count: %d\n", NumSongs); + DPrintf(DMSG_SPAMMY, "XMI song count: %d\n", NumSongs); } //========================================================================== diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 6dd204c866..21370d082e 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -747,8 +747,8 @@ OpenALSoundRenderer::OpenALSoundRenderer() ALCint major=0, minor=0; alcGetIntegerv(Device, ALC_MAJOR_VERSION, 1, &major); alcGetIntegerv(Device, ALC_MINOR_VERSION, 1, &minor); - DPrintf(" ALC Version: " TEXTCOLOR_BLUE"%d.%d\n", major, minor); - DPrintf(" ALC Extensions: " TEXTCOLOR_ORANGE"%s\n", alcGetString(Device, ALC_EXTENSIONS)); + DPrintf(DMSG_SPAMMY, " ALC Version: " TEXTCOLOR_BLUE"%d.%d\n", major, minor); + DPrintf(DMSG_SPAMMY, " ALC Extensions: " TEXTCOLOR_ORANGE"%s\n", alcGetString(Device, ALC_EXTENSIONS)); TArray attribs; if(*snd_samplerate > 0) @@ -778,10 +778,10 @@ OpenALSoundRenderer::OpenALSoundRenderer() } attribs.Clear(); - DPrintf(" Vendor: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_VENDOR)); - DPrintf(" Renderer: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_RENDERER)); - DPrintf(" Version: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_VERSION)); - DPrintf(" Extensions: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_EXTENSIONS)); + DPrintf(DMSG_SPAMMY, " Vendor: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_VENDOR)); + DPrintf(DMSG_SPAMMY, " Renderer: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_RENDERER)); + DPrintf(DMSG_SPAMMY, " Version: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_VERSION)); + DPrintf(DMSG_SPAMMY, " Extensions: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_EXTENSIONS)); ALC.EXT_EFX = !!alcIsExtensionPresent(Device, "ALC_EXT_EFX"); ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect"); @@ -864,7 +864,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() return; } FreeSfx = Sources; - DPrintf(" Allocated " TEXTCOLOR_BLUE"%u" TEXTCOLOR_NORMAL" sources\n", Sources.Size()); + DPrintf(DMSG_NOTIFY, " Allocated " TEXTCOLOR_BLUE"%u" TEXTCOLOR_NORMAL" sources\n", Sources.Size()); WasInWater = false; if(*snd_efx && ALC.EXT_EFX) @@ -913,10 +913,10 @@ OpenALSoundRenderer::OpenALSoundRenderer() { alEffecti(envReverb, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); if(alGetError() == AL_NO_ERROR) - DPrintf(" EAX Reverb found\n"); + DPrintf(DMSG_SPAMMY, " EAX Reverb found\n"); alEffecti(envReverb, AL_EFFECT_TYPE, AL_EFFECT_REVERB); if(alGetError() == AL_NO_ERROR) - DPrintf(" Standard Reverb found\n"); + DPrintf(DMSG_SPAMMY, " Standard Reverb found\n"); alDeleteEffects(1, &envReverb); getALError(); @@ -929,7 +929,7 @@ OpenALSoundRenderer::OpenALSoundRenderer() alFilteri(EnvFilters[0], AL_FILTER_TYPE, AL_FILTER_LOWPASS); alFilteri(EnvFilters[1], AL_FILTER_TYPE, AL_FILTER_LOWPASS); if(getALError() == AL_NO_ERROR) - DPrintf(" Lowpass found\n"); + DPrintf(DMSG_SPAMMY, " Lowpass found\n"); else { alDeleteFilters(2, EnvFilters); @@ -1194,7 +1194,7 @@ std::pair OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int loopend = length / (channels*bits/8); ALint loops[2] = { loopstart, loopend }; - DPrintf("Setting loop points %d -> %d\n", loops[0], loops[1]); + DPrintf(DMSG_NOTIFY, "Setting loop points %d -> %d\n", loops[0], loops[1]); alBufferiv(buffer, AL_LOOP_POINTS_SOFT, loops); getALError(); } @@ -1202,7 +1202,7 @@ std::pair OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int { static bool warned = false; if(!warned) - Printf("Loop points not supported!\n"); + Printf(DMSG_WARNING, "Loop points not supported!\n"); warned = true; } @@ -1867,7 +1867,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener) if(env != PrevEnvironment || env->Modified) { PrevEnvironment = env; - DPrintf("Reverb Environment %s\n", env->Name); + DPrintf(DMSG_NOTIFY, "Reverb Environment %s\n", env->Name); if(EnvSlot != 0) LoadReverb(env); diff --git a/src/v_video.cpp b/src/v_video.cpp index 01a73950b2..0ee065bbe9 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -907,11 +907,12 @@ void DFrameBuffer::DrawRateStuff () // Drawing it as a texture does and continues to show how // well the PalTex shader is working. static FPaletteTester palette; + int size = screen->GetHeight() < 800 ? 16 * 7 : 16 * 7 * 2; palette.SetTranslation(vid_showpalette); DrawTexture(&palette, 0, 0, - DTA_DestWidth, 16*7, - DTA_DestHeight, 16*7, + DTA_DestWidth, size, + DTA_DestHeight, size, DTA_Masked, false, TAG_DONE); } diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 29bb905fbe..8eb2349ec2 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -793,7 +793,7 @@ void I_SetFPSLimit(int limit) CloseHandle(FPSLimitEvent); FPSLimitEvent = NULL; } - DPrintf("FPS timer disabled\n"); + DPrintf(DMSG_NOTIFY, "FPS timer disabled\n"); } else { @@ -802,7 +802,7 @@ void I_SetFPSLimit(int limit) FPSLimitEvent = CreateEvent(NULL, FALSE, TRUE, NULL); if (FPSLimitEvent == NULL) { // Could not create event, so cannot use timer. - Printf("Failed to create FPS limitter event\n"); + Printf(DMSG_WARNING, "Failed to create FPS limitter event\n"); return; } } @@ -817,7 +817,7 @@ void I_SetFPSLimit(int limit) Printf("Failed to create FPS limitter timer\n"); return; } - DPrintf("FPS timer set to %u ms\n", period); + DPrintf(DMSG_NOTIFY, "FPS timer set to %u ms\n", period); } } diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index d80c048b7e..ed224cb575 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1957,6 +1957,7 @@ MSGMNU_TEAMMESSAGES = "Team Messages"; MSGMNU_CENTEREDMESSAGES = "Centered Messages"; MSGMNU_SCREENSHOTMESSAGES = "Screenshot messages"; MSGMNU_LONGSAVEMESSAGES = "Detailed save messages"; +MSGMNU_DEVELOPER = "Developer message mode"; // Scoreboard Options SCRBRDMNU_TITLE = "SCOREBOARD OPTIONS"; @@ -2287,6 +2288,10 @@ OPTVAL_SINC = "Sinc"; OPTVAL_NOTEONOFFONLY = "Note on/off only"; OPTVAL_FULLRAMPING = "Full ramping"; OPTVAL_ALLUNACKNOWLEDGED = "All unacknowledged"; +OPTVAL_ERRORS = "Errors"; +OPTVAL_WARNINGS = "Warnings"; +OPTVAL_NOTIFICATIONS = "Notifications"; +OPTVAL_EVERYTHING = "Everything"; // Colors C_BRICK = "\cabrick"; C_TAN = "\cbtan"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 077dc06087..203576e5d4 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1118,6 +1118,15 @@ OptionValue MessageLevels 2.0, "$OPTVAL_CRITICALMESSAGES" } +OptionValue DevMessageLevels +{ + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_ERRORS" + 2, "$OPTVAL_WARNINGS", + 3, "$OPTVAL_NOTIFICATIONS" + 4, "$OPTVAL_EVERYTHING" +} + OptionMenu MessageOptions { Title "$MSGMNU_TITLE" @@ -1126,6 +1135,7 @@ OptionMenu MessageOptions Option "$MSGMNU_SHOWSECRETS", "cl_showsecretmessage", "OnOff" Option "$MSGMNU_SCALETEXT", "con_scaletext", "ScaleValues" Option "$MSGMNU_MESSAGELEVEL", "msg", "MessageLevels" + Option "$MSGMNU_DEVELOPER", "developer", "DevMessageLevels" Option "$MSGMNU_CENTERMESSAGES", "con_centernotify", "OnOff" StaticText " " StaticText "$MSGMNU_MESSAGECOLORS", 1 From da5cf760b0941306b81774f8e130e17466353e56 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Aug 2016 10:10:32 +0200 Subject: [PATCH 24/32] - forgot to save this one... --- wadsrc/static/menudef.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 203576e5d4..ae8cfa0bb1 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1122,7 +1122,7 @@ OptionValue DevMessageLevels { 0, "$OPTVAL_OFF" 1, "$OPTVAL_ERRORS" - 2, "$OPTVAL_WARNINGS", + 2, "$OPTVAL_WARNINGS" 3, "$OPTVAL_NOTIFICATIONS" 4, "$OPTVAL_EVERYTHING" } From 03d055a5ec645beee5a953f78b5c6d6615686d52 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Aug 2016 10:11:09 +0200 Subject: [PATCH 25/32] - adjustments for message modes. --- src/gl/data/gl_setup.cpp | 2 +- src/gl/textures/gl_texture.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index f45995d907..73ceddb135 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -294,7 +294,7 @@ static void PrepareSectorData() seg[j].PartnerSeg!=NULL && subsectors[i].render_sector != seg[j].PartnerSeg->Subsector->render_sector) { - DPrintf("Found hack: (%f,%f) (%f,%f)\n", seg[j].v1->fX(), seg[j].v1->fY(), seg[j].v2->fX(), seg[j].v2->fY()); + DPrintf(DMSG_NOTIFY, "Found hack: (%f,%f) (%f,%f)\n", seg[j].v1->fX(), seg[j].v1->fY(), seg[j].v2->fX(), seg[j].v2->fY()); subsectors[i].hacked|=5; SpreadHackedFlag(&subsectors[i]); } diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index f1e6f0b0be..eb14862c6c 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -166,7 +166,7 @@ void gl_GenerateGlobalBrightmapFromColormap() for(int i=0;i<256;i++) { HasGlobalBrightmap |= GlobalBrightmap.Remap[i] == white; - if (GlobalBrightmap.Remap[i] == white) DPrintf("Marked color %d as fullbright\n",i); + if (GlobalBrightmap.Remap[i] == white) DPrintf(DMSG_NOTIFY, "Marked color %d as fullbright\n",i); } } @@ -290,7 +290,7 @@ void FTexture::CreateDefaultBrightmap() if (GlobalBrightmap.Remap[texbuf[i]] == white) { // Create a brightmap - DPrintf("brightmap created for texture '%s'\n", Name.GetChars()); + DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", Name.GetChars()); gl_info.Brightmap = new FBrightmapTexture(this); gl_info.bBrightmapChecked = 1; TexMan.AddTexture(gl_info.Brightmap); @@ -298,7 +298,7 @@ void FTexture::CreateDefaultBrightmap() } } // No bright pixels found - DPrintf("No bright pixels found in texture '%s'\n", Name.GetChars()); + DPrintf(DMSG_SPAMMY, "No bright pixels found in texture '%s'\n", Name.GetChars()); gl_info.bBrightmapChecked = 1; } else From 47714509d6345fa0589b3d7aa3d412fc327010f0 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 28 Aug 2016 11:12:06 +0300 Subject: [PATCH 26/32] Changed render buffers format back to RGBA16F Reverted a03b2ff48b305064c7689419e2cc297b5ccdc1aa to fix issues with nVidia graphics on macOS --- src/gl/renderer/gl_renderbuffers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 9f27e63136..9daec41dd7 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -274,7 +274,7 @@ void FGLRenderBuffers::CreateBloom(int width, int height) GLuint FGLRenderBuffers::GetHdrFormat() { - return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16; + return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16F; } //========================================================================== @@ -285,7 +285,7 @@ GLuint FGLRenderBuffers::GetHdrFormat() GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int width, int height) { - GLuint type = (format == GL_RGBA16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; + GLuint type = (format == GL_RGBA16F) ? GL_FLOAT : GL_UNSIGNED_BYTE; GLuint handle = 0; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); From bb066f6f07815fccd2c78394158e13b2b1e40338 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 28 Aug 2016 18:07:44 +0200 Subject: [PATCH 27/32] Fall back to gl_renderbuffers 0 if buffer creation fails --- src/gl/renderer/gl_renderbuffers.cpp | 44 +++++++++++++++++++++------- src/gl/renderer/gl_renderbuffers.h | 6 ++-- src/gl/renderer/gl_renderer.cpp | 3 +- src/gl/scene/gl_scene.cpp | 3 +- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 9daec41dd7..fd98522d87 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -147,10 +147,10 @@ void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle) // //========================================================================== -void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight) +bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight) { if (!IsEnabled()) - return; + return false; if (width <= 0 || height <= 0) I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height); @@ -189,6 +189,20 @@ void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei glActiveTexture(activeTex); glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (FailedCreate) + { + ClearScene(); + ClearPipeline(); + ClearBloom(); + mWidth = 0; + mHeight = 0; + mSamples = 0; + mBloomWidth = 0; + mBloomHeight = 0; + } + + return !FailedCreate; } //========================================================================== @@ -340,8 +354,8 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff glBindFramebuffer(GL_FRAMEBUFFER, handle); FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); - CheckFrameBufferCompleteness(); - ClearFrameBuffer(false, false); + if (CheckFrameBufferCompleteness()) + ClearFrameBuffer(false, false); return handle; } @@ -356,8 +370,8 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff else glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil); - CheckFrameBufferCompleteness(); - ClearFrameBuffer(true, true); + if (CheckFrameBufferCompleteness()) + ClearFrameBuffer(true, true); return handle; } @@ -373,8 +387,8 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil); - CheckFrameBufferCompleteness(); - ClearFrameBuffer(true, true); + if (CheckFrameBufferCompleteness()) + ClearFrameBuffer(true, true); return handle; } @@ -384,12 +398,15 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff // //========================================================================== -void FGLRenderBuffers::CheckFrameBufferCompleteness() +bool FGLRenderBuffers::CheckFrameBufferCompleteness() { GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (result == GL_FRAMEBUFFER_COMPLETE) - return; + return true; + FailedCreate = true; + +#if 0 FString error = "glCheckFramebufferStatus failed: "; switch (result) { @@ -404,6 +421,9 @@ void FGLRenderBuffers::CheckFrameBufferCompleteness() case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: error << "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break; } I_FatalError(error); +#endif + + return false; } //========================================================================== @@ -539,5 +559,7 @@ void FGLRenderBuffers::BindOutputFB() bool FGLRenderBuffers::IsEnabled() { - return gl_renderbuffers && gl.glslversion != 0; + return gl_renderbuffers && gl.glslversion != 0 && !FailedCreate; } + +bool FGLRenderBuffers::FailedCreate = false; diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 9c04eb546d..ee6d8de5ed 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -20,7 +20,7 @@ public: FGLRenderBuffers(); ~FGLRenderBuffers(); - void Setup(int width, int height, int sceneWidth, int sceneHeight); + bool Setup(int width, int height, int sceneWidth, int sceneHeight); void BindSceneFB(); void BlitSceneToTexture(); @@ -53,7 +53,7 @@ private: GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer); GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer); - void CheckFrameBufferCompleteness(); + bool CheckFrameBufferCompleteness(); void ClearFrameBuffer(bool stencil, bool depth); void DeleteTexture(GLuint &handle); void DeleteRenderBuffer(GLuint &handle); @@ -84,6 +84,8 @@ private: // Back buffer frame buffer GLuint mOutputFB = 0; + + static bool FailedCreate; }; #endif \ No newline at end of file diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index d154766d68..eb0eebaa12 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -289,9 +289,8 @@ void FGLRenderer::SetupLevel() void FGLRenderer::Begin2D() { - if (FGLRenderBuffers::IsEnabled()) + if (mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height)) { - mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height); if (mDrawingScene2D) mBuffers->BindSceneFB(); else diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index ef82472e05..250ec0c532 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -168,9 +168,8 @@ void FGLRenderer::Reset3DViewport() void FGLRenderer::Set3DViewport(bool mainview) { - if (mainview && FGLRenderBuffers::IsEnabled()) + if (mainview && mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height)) { - mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height); mBuffers->BindSceneFB(); } From 945d5b154a3f810d79bda16b14f9574e3e45118e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 28 Aug 2016 18:10:39 +0200 Subject: [PATCH 28/32] Remove gl_vid_multisample --- src/posix/cocoa/i_video.mm | 7 +------ src/posix/sdl/sdlglvideo.cpp | 11 +---------- src/win32/win32gliface.cpp | 11 +---------- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 8f8b7c1355..e2b59449d7 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -149,11 +149,6 @@ CUSTOM_CVAR(Int, vid_renderer, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINIT } } -CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} - EXTERN_CVAR(Bool, gl_smooth_rendered) @@ -1259,7 +1254,7 @@ void I_InitGraphics() val.Bool = !!Args->CheckParm("-devparm"); ticker.SetGenericRepDefault(val, CVAR_Bool); - Video = new CocoaVideo(gl_vid_multisample); + Video = new CocoaVideo(0); atterm(I_ShutdownGraphics); } diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index 0cd6b223b6..d8c00f2363 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -54,11 +54,6 @@ EXTERN_CVAR (Bool, cl_capfps) // PUBLIC DATA DEFINITIONS ------------------------------------------------- -CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL ) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} - CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { Printf("This won't take effect until " GAMENAME " is restarted.\n"); @@ -322,17 +317,13 @@ bool SDLGLVideo::InitHardware (bool allowsoftware, int multisample) SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen) : DFrameBuffer (width, height) { - static int localmultisample=-1; - - if (localmultisample<0) localmultisample=gl_vid_multisample; - int i; m_Lock=0; UpdatePending = false; - if (!static_cast(Video)->InitHardware(false, localmultisample)) + if (!static_cast(Video)->InitHardware(false, 0)) { vid_renderer = 0; return; diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index bec2a19cf1..23f1565925 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -40,11 +40,6 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; PFNWGLSWAPINTERVALEXTPROC vsyncfunc; -CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL ) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} - CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { Printf("This won't take effect until " GAMENAME " is restarted.\n"); @@ -911,10 +906,6 @@ IMPLEMENT_ABSTRACT_CLASS(Win32GLFrameBuffer) Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen) : BaseWinFB(width, height) { - static int localmultisample=-1; - - if (localmultisample<0) localmultisample=gl_vid_multisample; - m_Width = width; m_Height = height; m_Bits = bits; @@ -981,7 +972,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in I_RestoreWindowedPos(); } - if (!static_cast(Video)->InitHardware(Window, localmultisample)) + if (!static_cast(Video)->InitHardware(Window, 0)) { vid_renderer = 0; return; From 71387b1b42fff9f527758fbbc9680b2db1b70e15 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 29 Aug 2016 05:19:47 +0200 Subject: [PATCH 29/32] Fix wrong initial mClipSplit values. --- src/gl/renderer/gl_renderstate.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 56b319f008..86ea497ed0 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -111,7 +111,6 @@ void FRenderState::Reset() mSplitBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f); mClipLine.Set(0.0f, 0.0f, 0.0f, 0.0f); mDynColor.Set(0.0f, 0.0f, 0.0f, 0.0f); - mClipSplit[0] = mClipSplit[1] = 0.0f; mEffectState = 0; activeShader = nullptr; mProjectionMatrix.loadIdentity(); From e0e43ee7b335f8d69ca1868d18c5e5e4efabc076 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 29 Aug 2016 05:31:12 +0200 Subject: [PATCH 30/32] Fix mColor reset value --- src/gl/renderer/gl_renderstate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 86ea497ed0..7fda924281 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -101,7 +101,7 @@ void FRenderState::Reset() mLastDepthClamp = true; mInterpolationFactor = 0.0f; - mColor.Set(0.0f, 0.0f, 0.0f, 0.0f); + mColor.Set(1.0f, 1.0f, 1.0f, 1.0f); mCameraPos.Set(0.0f, 0.0f, 0.0f, 0.0f); mGlowTop.Set(0.0f, 0.0f, 0.0f, 0.0f); mGlowBottom.Set(0.0f, 0.0f, 0.0f, 0.0f); From 0f0dc2c852723f397583dc0a771726d38c9e1df0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Aug 2016 10:43:03 +0200 Subject: [PATCH 31/32] - implemented buffers for GL 3.x. These only get mapped during the data collection pass so the order of some things is different here. --- src/gl/data/gl_vertexbuffer.cpp | 63 ++++++++++++++++++++++++++---- src/gl/data/gl_vertexbuffer.h | 3 ++ src/gl/renderer/gl_postprocess.cpp | 2 +- src/gl/scene/gl_portal.cpp | 8 ++-- src/gl/scene/gl_scene.cpp | 4 +- src/gl/shaders/gl_shader.cpp | 2 +- src/gl/system/gl_interface.cpp | 8 +++- 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 7e77849545..31cb8d0b5c 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -126,6 +126,7 @@ void FSimpleVertexBuffer::EnableColorArray(bool on) void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); gl_RenderState.SetVertexBuffer(this); glBufferData(GL_ARRAY_BUFFER, count * sizeof(*verts), verts, GL_STREAM_DRAW); } @@ -139,18 +140,32 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) : FVertexBuffer(gl.buffermethod != BM_CLIENTARRAY) { - if (gl.buffermethod != BM_CLIENTARRAY) + switch (gl.buffermethod) + { + case BM_PERSISTENT: { unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + break; } - else + + case BM_DEFERRED: + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW); + map = nullptr; + break; + } + + case BM_CLIENTARRAY: { // The fallback path uses immediate mode rendering and does not set up an actual vertex buffer - vbo_shadowdata.Reserve(BUFFER_SIZE); map = new FFlatVertex[BUFFER_SIZE]; + break; + } } mIndex = mCurIndex = 0; mNumReserved = NUM_RESERVED; @@ -185,6 +200,13 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0); vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0); + if (gl.buffermethod == BM_DEFERRED) + { + Map(); + memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex)); + Unmap(); + } + } FFlatVertexBuffer::~FFlatVertexBuffer() @@ -195,7 +217,7 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); } - else + if (gl.buffermethod == BM_CLIENTARRAY) { delete[] map; } @@ -208,7 +230,7 @@ void FFlatVertexBuffer::BindVBO() glBindBuffer(GL_ARRAY_BUFFER, vbo_id); if (gl.glslversion > 0) { - if (vbo_id != 0) // set this up only if there is an actual buffer. + if (gl.buffermethod != BM_CLIENTARRAY) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); @@ -226,12 +248,37 @@ void FFlatVertexBuffer::BindVBO() } else { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(FFlatVertex), &map->x); + glTexCoordPointer(2, GL_FLOAT, sizeof(FFlatVertex), &map->u); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); } } +void FFlatVertexBuffer::Map() +{ + if (gl.buffermethod == BM_DEFERRED) + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); + map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT); + } +} + +void FFlatVertexBuffer::Unmap() +{ + if (gl.buffermethod == BM_DEFERRED) + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); + glUnmapBuffer(GL_ARRAY_BUFFER); + map = nullptr; + } +} + //========================================================================== // // Initialize a single vertex @@ -412,7 +459,9 @@ void FFlatVertexBuffer::CreateVBO() vbo_shadowdata.Resize(mNumReserved); CreateFlatVBO(); mCurIndex = mIndex = vbo_shadowdata.Size(); + Map(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + Unmap(); } //========================================================================== diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 68f1013675..88a1de2b89 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -149,6 +149,9 @@ public: mCurIndex = mIndex; } + void Map(); + void Unmap(); + private: int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 20f6f469f4..3a83f4caf5 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -114,7 +114,7 @@ void FGLRenderer::RenderScreenQuad() { mVBO->BindVBO(); gl_RenderState.ResetVertexBuffer(); - glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4b8d8eb275..cd3efb9e3b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -163,8 +163,8 @@ void GLPortal::DrawPortalStencil() } if (NeedCap() && lines.Size() > 1) { - glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); - glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); } } @@ -1178,9 +1178,9 @@ void GLHorizonPortal::DrawContents() for (unsigned i = 0; i < vcount; i += 4) { - glDrawArrays(GL_TRIANGLE_STRIP, voffset + i, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + i, 4); } - glDrawArrays(GL_TRIANGLE_STRIP, voffset + vcount, 10); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + vcount, 10); gl_RenderState.EnableTextureMatrix(false); PortalAll.Unclock(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 250ec0c532..08591283c0 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -284,6 +284,7 @@ void FGLRenderer::CreateScene() for(unsigned i=0;iglportal = NULL; gl_spriteindex=0; Bsp.Clock(); + GLRenderer->mVBO->Map(); R_SetView(); validcount++; // used for processing sidedefs only once by the renderer. gl_RenderBSPNode (nodes + numnodes - 1); @@ -295,6 +296,7 @@ void FGLRenderer::CreateScene() gl_drawinfo->HandleMissingTextures(); // Missing upper/lower textures gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks + GLRenderer->mVBO->Unmap(); ProcessAll.Unclock(); @@ -525,7 +527,7 @@ void gl_FillScreen() gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); // The fullscreen quad is stored at index 4 in the main vertex buffer. - glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); } //========================================================================== diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 67b9a2d6ae..8ac2b70933 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -125,7 +125,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; } } - //if (gl.buffermethod == BM_DEFERRED) + if (gl.buffermethod == BM_DEFERRED) { vp_comb << "#define USE_QUAD_DRAWER\n"; } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index a7b1be6487..9eb1d779e5 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -204,8 +204,12 @@ void gl_LoadExtensions() } else if (gl.version < 3.0f) { - //if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple. - //else gl.glslversion = 0; + if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple. + else + { + gl.buffermethod = BM_CLIENTARRAY; + gl.glslversion = 0; + } if (!CheckExtension("GL_EXT_packed_float")) gl.flags |= RFL_NO_RGBA16F; if (!CheckExtension("GL_EXT_packed_depth_stencil")) gl.flags |= RFL_NO_DEPTHSTENCIL; From 8f535997f86cdc4bc2dfdc182a33b97960fa4703 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Aug 2016 11:33:20 +0200 Subject: [PATCH 32/32] - enable core profile by default on GL 3.x. After doing some profiling it was very obvious that this has better performance than client arrays. Persistent buffers are still better, though, especially for handling dynamic lights. --- src/gl/data/gl_vertexbuffer.cpp | 4 ++- src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/system/gl_interface.cpp | 13 +------ src/win32/win32gliface.cpp | 60 +++++---------------------------- src/win32/win32gliface.h | 1 - 5 files changed, 14 insertions(+), 66 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 31cb8d0b5c..5833d31095 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -148,6 +148,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + DPrintf(DMSG_NOTIFY, "Using persistent buffer\n"); break; } @@ -157,13 +158,14 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW); map = nullptr; + DPrintf(DMSG_NOTIFY, "Using deferred buffer\n"); break; } case BM_CLIENTARRAY: { - // The fallback path uses immediate mode rendering and does not set up an actual vertex buffer map = new FFlatVertex[BUFFER_SIZE]; + DPrintf(DMSG_NOTIFY, "Using client array buffer\n"); break; } } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index eb0eebaa12..c8f2eb2249 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -130,7 +130,7 @@ void FGLRenderer::Initialize(int width, int height) m2DDrawer = new F2DDrawer; // Only needed for the core profile, because someone decided it was a good idea to remove the default VAO. - if (gl.version >= 4.0) + if (gl.buffermethod != BM_CLIENTARRAY) { glGenVertexArrays(1, &mVAOID); glBindVertexArray(mVAOID); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 9eb1d779e5..c54d964489 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -156,14 +156,6 @@ void gl_LoadExtensions() gl.version = strtod(version, NULL) + 0.01f; - bool iscore = false; - if (gl.version >= 3.2) - { - int v; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); - iscore = !!(v & GL_CONTEXT_CORE_PROFILE_BIT); - } - // Don't even start if it's lower than 2.0 or no framebuffers are available if ((gl.version < 2.0 || !CheckExtension("GL_EXT_framebuffer_object")) && gl.version < 3.0) { @@ -186,10 +178,7 @@ void gl_LoadExtensions() if (gl.version > 3.0f && (gl.version >= 3.3f || CheckExtension("GL_ARB_uniform_buffer_object"))) { gl.lightmethod = LM_DEFERRED; - if (iscore) - { - gl.buffermethod = BM_DEFERRED; - } + gl.buffermethod = BM_DEFERRED; } if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 23f1565925..494d942337 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -737,42 +737,6 @@ bool Win32GLVideo::SetupPixelFormat(int multisample) // //========================================================================== -// since we cannot use the extension loader here, before it gets initialized, -// we have to define the extended GL stuff we need, ourselves here. -// The headers generated by GLLoadGen only work if the loader gets initialized. -typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint); -#define GL_NUM_EXTENSIONS 0x821D - -bool Win32GLVideo::checkCoreUsability() -{ - const char *version = Args->CheckValue("-glversion"); - if (version != NULL) - { - if (strtod(version, NULL) < 4.0) return false; - } - if (Args->CheckParm("-noshader")) return false; - - // GL 4.4 implies GL_ARB_buffer_storage - if (strcmp((char*)glGetString(GL_VERSION), "4.4") >= 0) return true; - - // at this point the extension loader has not been initialized so we have to retrieve glGetStringi ourselves. - PFNGLGETSTRINGIPROC myglGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi"); - if (!myglGetStringi) return false; // this should not happen. - - const char *extension; - - int max = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &max); - - // step through all reported extensions and see if we got what we need... - for (int i = 0; i < max; i++) - { - extension = (const char*)myglGetStringi(GL_EXTENSIONS, i); - if (!strcmp(extension, "GL_ARB_buffer_storage")) return true; - } - return false; -} - bool Win32GLVideo::InitHardware (HWND Window, int multisample) { m_Window=Window; @@ -783,7 +747,14 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) return false; } - for (int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) + int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + const char *lm = Args->CheckValue("-buffermethod"); + if (lm != NULL) + { + if (!stricmp(lm, "clientarray")) prof = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + + for (; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) { m_hRC = NULL; if (myWglCreateContextAttribsARB != NULL) @@ -802,8 +773,6 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) 0 }; - //Printf("Trying to create an OpenGL %d.%d %s profile context\n", versions[i] / 10, versions[i] % 10, prof == WGL_CONTEXT_CORE_PROFILE_BIT_ARB ? "Core" : "Compatibility"); - m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); if (m_hRC != NULL) break; } @@ -811,7 +780,6 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) { - m_hRC = wglCreateContext(m_hDC); if (m_hRC == NULL) { @@ -823,17 +791,7 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) if (m_hRC != NULL) { wglMakeCurrent(m_hDC, m_hRC); - - // we can only use core profile contexts if GL_ARB_buffer_storage is supported or GL version is >= 4.4 - if (prof == WGL_CONTEXT_CORE_PROFILE_BIT_ARB && !checkCoreUsability()) - { - wglMakeCurrent(0, 0); - wglDeleteContext(m_hRC); - } - else - { - return true; - } + return true; } } // We get here if the driver doesn't support the modern context creation API which always means an old driver. diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index 00e6cba819..6320e29034 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -86,7 +86,6 @@ protected: void MakeModesList(); void AddMode(int x, int y, int bits, int baseHeight, int refreshHz); void FreeModes(); - bool checkCoreUsability(); public: int GetTrueHeight() { return m_trueHeight; }