From cef6ddca6ef9860fc4947098247bd41d65ca6cef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 08:09:40 +0200 Subject: [PATCH 1/9] - fixed: Rendering to a camera textures clobbered the main render target for the software renderer. --- src/swrenderer/scene/r_scene.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 1f406d424..7350090da 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -337,6 +337,7 @@ namespace swrenderer auto viewport = MainThread()->Viewport.get(); const bool savedviewactive = viewactive; + auto savedtarget = viewport->RenderTarget; viewwidth = width; viewport->RenderTarget = canvas; @@ -353,7 +354,7 @@ namespace swrenderer DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); - viewport->RenderTarget = nullptr; + viewport->RenderTarget = savedtarget; viewport->RenderingToCanvas = false; R_ExecuteSetViewSize(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow); From 870890d8cfd6698012a6463c03bb9263e4aa595b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 09:33:45 +0200 Subject: [PATCH 2/9] - r_clearcolor did not consider that the base palette's alpha is not set. --- src/swrenderer/scene/r_scene.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 7350090da..0780c83ce 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -107,11 +107,12 @@ namespace swrenderer } else { - uint32_t bgracolor = GPalette.BaseColors[clearcolor].d; + PalEntry bgracolor = GPalette.BaseColors[clearcolor]; + bgracolor.a = 255; int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight(); uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels(); for (int i = 0; i < size; i++) - dest[i] = bgracolor; + dest[i] = bgracolor.d; } } From ad021cc37435bb86739c537fc2fa4af08c73c71c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 10:26:56 +0200 Subject: [PATCH 3/9] - fixed: Hardware camera textures were given a dimension of (0, 0). --- src/gl/textures/gl_hwtexture.cpp | 14 +++++++------- src/gl/textures/gl_hwtexture.h | 5 ++--- src/gl/textures/gl_material.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 0ab9457fa..855ae362f 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -207,8 +207,6 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int } } // store the physical size. - texwidth = rw; - texheight = rh; int sourcetype; if (glTextureBytes > 0) @@ -467,14 +465,14 @@ void FHardwareTexture::UnbindAll() // //=========================================================================== -int FHardwareTexture::GetDepthBuffer() +int FHardwareTexture::GetDepthBuffer(int width, int height) { if (glDepthID == 0) { glGenRenderbuffers(1, &glDepthID); glBindRenderbuffer(GL_RENDERBUFFER, glDepthID); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, - GetTexDimension(texwidth), GetTexDimension(texheight)); + GetTexDimension(width), GetTexDimension(height)); glBindRenderbuffer(GL_RENDERBUFFER, 0); } return glDepthID; @@ -487,10 +485,12 @@ int FHardwareTexture::GetDepthBuffer() // //=========================================================================== -void FHardwareTexture::BindToFrameBuffer() +void FHardwareTexture::BindToFrameBuffer(int width, int height) { + width = GetTexDimension(width); + height = GetTexDimension(height); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height)); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height)); } diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 9dac63cbb..7ddcd27a4 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -60,7 +60,6 @@ public: private: - short texwidth = 0, texheight = 0; bool forcenocompression; TranslatedTexture glDefTex; @@ -71,7 +70,7 @@ private: TranslatedTexture * GetTexID(int translation); - int GetDepthBuffer(); + int GetDepthBuffer(int w, int h); void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data); public: @@ -81,7 +80,7 @@ public: static void Unbind(int texunit); static void UnbindAll(); - void BindToFrameBuffer(); + void BindToFrameBuffer(int w, int h); unsigned int Bind(int texunit, int translation, bool needmipmap); void AllocateBuffer(int w, int h, int texelsize); diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index be71fffd2..99a6f133a 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -207,6 +207,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla wt->GenTime[0] = screen->FrameTime; } } + else + { + w = tex->GetWidth(); + h = tex->GetHeight(); + } if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind")) { // could not create texture @@ -762,7 +767,7 @@ void FMaterial::BindToFrameBuffer() FHardwareTexture::Unbind(0); ClearLastTexture(); } - mBaseLayer->mHwTexture->BindToFrameBuffer(); + mBaseLayer->mHwTexture->BindToFrameBuffer(mWidth, mHeight); } //========================================================================== From e654a99d39891b2d01eff0301537c1f799022ef2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 10:40:11 +0200 Subject: [PATCH 4/9] - changed GLDebug to receive char pointers instead of FStrings. The most frequent call using this is the regular texture creation function where this results in a pointless allocation and destruction of a temporary string which is easily avoided. --- src/gl/renderer/gl_renderbuffers.cpp | 18 +++++++++--------- src/gl/renderer/gl_renderbuffers.h | 15 ++++++++------- src/gl/system/gl_debug.cpp | 8 ++++---- src/gl/system/gl_debug.h | 4 ++-- src/gl/textures/gl_hwtexture.cpp | 2 +- src/gl/textures/gl_hwtexture.h | 3 ++- src/gl/textures/gl_samplers.cpp | 2 +- 7 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index acc2d5c0d..0d594dbbb 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -428,8 +428,8 @@ void FGLRenderBuffers::CreateExposureLevels(int width, int height) FGLExposureTextureLevel level; level.Width = width; level.Height = height; - level.Texture = Create2DTexture(textureName, GL_R32F, level.Width, level.Height); - level.Framebuffer = CreateFrameBuffer(fbName, level.Texture); + level.Texture = Create2DTexture(textureName.GetChars(), GL_R32F, level.Width, level.Height); + level.Framebuffer = CreateFrameBuffer(fbName.GetChars(), level.Texture); ExposureLevels.Push(level); } while (width > 1 || height > 1); @@ -474,7 +474,7 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye) // //========================================================================== -GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data) +GLuint FGLRenderBuffers::Create2DTexture(const char *name, GLuint format, int width, int height, const void *data) { GLuint handle = 0; glGenTextures(1, &handle); @@ -508,7 +508,7 @@ GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int return handle; } -GLuint FGLRenderBuffers::Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations) +GLuint FGLRenderBuffers::Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations) { GLuint handle = 0; glGenTextures(1, &handle); @@ -525,7 +525,7 @@ GLuint FGLRenderBuffers::Create2DMultisampleTexture(const FString &name, GLuint // //========================================================================== -GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, int width, int height) +GLuint FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height) { GLuint handle = 0; glGenRenderbuffers(1, &handle); @@ -535,7 +535,7 @@ GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, return handle; } -GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, int width, int height, int samples) +GLuint FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples) { if (samples <= 1) return CreateRenderBuffer(name, format, width, height); @@ -554,7 +554,7 @@ GLuint FGLRenderBuffers::CreateRenderBuffer(const FString &name, GLuint format, // //========================================================================== -GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer) +GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer) { GLuint handle = 0; glGenFramebuffers(1, &handle); @@ -566,7 +566,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff return handle; } -GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) +GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) { GLuint handle = 0; glGenFramebuffers(1, &handle); @@ -582,7 +582,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff return handle; } -GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample) +GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample) { GLuint handle = 0; glGenFramebuffers(1, &handle); diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 1c8ea1690..84c0f63ec 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -97,13 +97,14 @@ private: void CreateEyeBuffers(int eye); void CreateShadowMap(); void CreateAmbientOcclusion(int width, int height); - GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr); - GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations); - GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height); - GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height, int samples); - GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer); - GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); - GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample); + + GLuint Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr); + GLuint Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations); + GLuint CreateRenderBuffer(const char *name, GLuint format, int width, int height); + GLuint CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples); + GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer); + GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); + GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample); bool CheckFrameBufferCompleteness(); void ClearFrameBuffer(bool stencil, bool depth); void DeleteTexture(GLuint &handle); diff --git a/src/gl/system/gl_debug.cpp b/src/gl/system/gl_debug.cpp index 1fca45f0c..7aa425349 100644 --- a/src/gl/system/gl_debug.cpp +++ b/src/gl/system/gl_debug.cpp @@ -101,19 +101,19 @@ void FGLDebug::Update() // //----------------------------------------------------------------------------- -void FGLDebug::LabelObject(GLenum type, GLuint handle, const FString &name) +void FGLDebug::LabelObject(GLenum type, GLuint handle, const char *name) { if (HasDebugApi() && gl_debug_level != 0) { - glObjectLabel(type, handle, (GLsizei)name.Len(), name.GetChars()); + glObjectLabel(type, handle, -1, name); } } -void FGLDebug::LabelObjectPtr(void *ptr, const FString &name) +void FGLDebug::LabelObjectPtr(void *ptr, const char *name) { if (HasDebugApi() && gl_debug_level != 0) { - glObjectPtrLabel(ptr, (GLsizei)name.Len(), name.GetChars()); + glObjectPtrLabel(ptr, -1, name); } } diff --git a/src/gl/system/gl_debug.h b/src/gl/system/gl_debug.h index 52645ec16..4b03d0835 100644 --- a/src/gl/system/gl_debug.h +++ b/src/gl/system/gl_debug.h @@ -11,8 +11,8 @@ class FGLDebug public: void Update(); - static void LabelObject(GLenum type, GLuint handle, const FString &name); - static void LabelObjectPtr(void *ptr, const FString &name); + static void LabelObject(GLenum type, GLuint handle, const char *name); + static void LabelObjectPtr(void *ptr, const char *name); static void PushGroup(const FString &name); static void PopGroup(); diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 855ae362f..551f628f0 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -160,7 +160,7 @@ void FHardwareTexture::Resize(int swidth, int sheight, int width, int height, un // //=========================================================================== -unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name) +unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) { int rh,rw; int texformat=TexFormat[gl_texture_format]; diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 7ddcd27a4..9b2fbf681 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -86,7 +86,8 @@ public: void AllocateBuffer(int w, int h, int texelsize); uint8_t *MapBuffer(); - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name) = delete; + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name); unsigned int GetTextureHandle(int translation); void Clean(bool all); diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp index 5ca9a8d0b..ef6d9f3f4 100644 --- a/src/gl/textures/gl_samplers.cpp +++ b/src/gl/textures/gl_samplers.cpp @@ -58,7 +58,7 @@ FSamplerManager::FSamplerManager() { FString name; name.Format("mSamplers[%d]", i); - FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name); + FGLDebug::LabelObject(GL_SAMPLER, mSamplers[i], name.GetChars()); } } From 83c513b6c9dd80efc236575fc265820ff4809787 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 14 Apr 2018 11:27:48 +0300 Subject: [PATCH 5/9] Added names for arguments in DStaticEventHandler class definition --- src/events.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/events.h b/src/events.h index 547ab4829..09638b43e 100755 --- a/src/events.h +++ b/src/events.h @@ -138,13 +138,13 @@ public: // void WorldLoaded(); void WorldUnloaded(); - void WorldThingSpawned(AActor*); - void WorldThingDied(AActor*, AActor*); - void WorldThingRevived(AActor*); - void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle); - void WorldThingDestroyed(AActor*); - void WorldLinePreActivated(line_t*, AActor*, bool*); - void WorldLineActivated(line_t*, AActor*); + void WorldThingSpawned(AActor* actor); + void WorldThingDied(AActor* actor, AActor* inflictor); + void WorldThingRevived(AActor* actor); + void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle); + void WorldThingDestroyed(AActor* actor); + void WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate); + void WorldLineActivated(line_t* line, AActor* actor); void WorldLightning(); void WorldTick(); From ba4cc1a6ca6c491b2bcc36433c82c59bed46ee8e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 14 Apr 2018 11:33:17 +0300 Subject: [PATCH 6/9] Added activation type to WorldLine(Pre)Activated events https://forum.zdoom.org/viewtopic.php?t=60232 --- src/events.cpp | 15 +++++++++------ src/events.h | 9 +++++---- src/p_spec.cpp | 4 ++-- wadsrc/static/zscript/events.txt | 1 + 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/events.cpp b/src/events.cpp index 17fc30bea..e9c76a7bb 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -404,16 +404,16 @@ void E_WorldThingDestroyed(AActor* actor) handler->WorldThingDestroyed(actor); } -void E_WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate) +void E_WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate) { for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) - handler->WorldLinePreActivated(line, actor, shouldactivate); + handler->WorldLinePreActivated(line, actor, activationType, shouldactivate); } -void E_WorldLineActivated(line_t* line, AActor* actor) +void E_WorldLineActivated(line_t* line, AActor* actor, int activationType) { for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) - handler->WorldLineActivated(line, actor); + handler->WorldLineActivated(line, actor, activationType); } void E_PlayerEntered(int num, bool fromhub) @@ -545,6 +545,7 @@ DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageType); DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageFlags); DEFINE_FIELD_X(WorldEvent, FWorldEvent, DamageAngle); DEFINE_FIELD_X(WorldEvent, FWorldEvent, ActivatedLine); +DEFINE_FIELD_X(WorldEvent, FWorldEvent, ActivationType); DEFINE_FIELD_X(WorldEvent, FWorldEvent, ShouldActivate); DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, PlayerNumber); @@ -795,7 +796,7 @@ void DStaticEventHandler::WorldThingDestroyed(AActor* actor) } } -void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate) +void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate) { IFVIRTUAL(DStaticEventHandler, WorldLinePreActivated) { @@ -805,6 +806,7 @@ void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, boo FWorldEvent e = E_SetupWorldEvent(); e.Thing = actor; e.ActivatedLine = line; + e.ActivationType = activationType; e.ShouldActivate = *shouldactivate; VMValue params[2] = { (DStaticEventHandler*)this, &e }; VMCall(func, params, 2, nullptr, 0); @@ -812,7 +814,7 @@ void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, boo } } -void DStaticEventHandler::WorldLineActivated(line_t* line, AActor* actor) +void DStaticEventHandler::WorldLineActivated(line_t* line, AActor* actor, int activationType) { IFVIRTUAL(DStaticEventHandler, WorldLineActivated) { @@ -822,6 +824,7 @@ void DStaticEventHandler::WorldLineActivated(line_t* line, AActor* actor) FWorldEvent e = E_SetupWorldEvent(); e.Thing = actor; e.ActivatedLine = line; + e.ActivationType = activationType; VMValue params[2] = { (DStaticEventHandler*)this, &e }; VMCall(func, params, 2, nullptr, 0); } diff --git a/src/events.h b/src/events.h index 09638b43e..072502501 100755 --- a/src/events.h +++ b/src/events.h @@ -41,9 +41,9 @@ void E_WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int d // called before AActor::Destroy of each actor. void E_WorldThingDestroyed(AActor* actor); // called in P_ActivateLine before executing special, set shouldactivate to false to prevent activation. -void E_WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate); +void E_WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate); // called in P_ActivateLine after successful special execution. -void E_WorldLineActivated(line_t* line, AActor* actor); +void E_WorldLineActivated(line_t* line, AActor* actor, int activationType); // same as ACS SCRIPT_Lightning void E_WorldLightning(); // this executes on every tick, before everything, only when in valid level and not paused @@ -143,8 +143,8 @@ public: void WorldThingRevived(AActor* actor); void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle); void WorldThingDestroyed(AActor* actor); - void WorldLinePreActivated(line_t* line, AActor* actor, bool* shouldactivate); - void WorldLineActivated(line_t* line, AActor* actor); + void WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate); + void WorldLineActivated(line_t* line, AActor* actor, int activationType); void WorldLightning(); void WorldTick(); @@ -203,6 +203,7 @@ struct FWorldEvent DAngle DamageAngle; // for line(pre)activated line_t* ActivatedLine = nullptr; + int ActivationType = 0; bool ShouldActivate = true; }; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 3185b6c20..e00d8a33a 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -191,7 +191,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe // [MK] Use WorldLinePreActivated to decide if activation should continue bool shouldactivate = true; - E_WorldLinePreActivated(line, mo, &shouldactivate); + E_WorldLinePreActivated(line, mo, activationType, &shouldactivate); if ( !shouldactivate ) return false; bool remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); @@ -206,7 +206,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe line->args[3], line->args[4]); // [MK] Fire up WorldLineActivated - if ( buttonSuccess ) E_WorldLineActivated(line, mo); + if ( buttonSuccess ) E_WorldLineActivated(line, mo, activationType); special = line->special; if (!repeat && buttonSuccess) diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index 1aa2e3b59..fc8b82721 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -27,6 +27,7 @@ struct WorldEvent native play version("2.4") native readonly double DamageAngle; // for line(pre)activated native readonly Line ActivatedLine; + native readonly int ActivationType; native bool ShouldActivate; } From 0affc119fdd9acd536c5081bf325195e7f4c8715 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 12:04:37 +0200 Subject: [PATCH 7/9] - moved hardware independent part of flat vertex data out of GL folder. --- src/CMakeLists.txt | 1 + src/gl/data/gl_vertexbuffer.cpp | 243 +------------------ src/gl/data/gl_vertexbuffer.h | 42 ++-- src/gl/scene/gl_drawinfo.cpp | 2 +- src/hwrenderer/data/flatvertices.cpp | 298 ++++++++++++++++++++++++ src/hwrenderer/data/flatvertices.h | 81 +++++++ src/textures/formats/rawpagetexture.cpp | 2 +- 7 files changed, 398 insertions(+), 271 deletions(-) create mode 100644 src/hwrenderer/data/flatvertices.cpp create mode 100644 src/hwrenderer/data/flatvertices.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3659bb1c0..e0d0e6896 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1082,6 +1082,7 @@ set (PCH_SOURCES gl/textures/gl_texture.cpp gl/textures/gl_material.cpp gl/textures/gl_samplers.cpp + hwrenderer/data/flatvertices.cpp hwrenderer/dynlights/hw_aabbtree.cpp menu/joystickmenu.cpp diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 8e9ab5c59..cb6a3a748 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -126,7 +126,7 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) //========================================================================== FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) -: FVertexBuffer(!gl.legacyMode) +: FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height) { switch (gl.buffermethod) { @@ -159,36 +159,6 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) } mIndex = mCurIndex = 0; mNumReserved = NUM_RESERVED; - vbo_shadowdata.Resize(mNumReserved); - - // the first quad is reserved for handling coordinates through uniforms. - vbo_shadowdata[0].Set(0, 0, 0, 0, 0); - vbo_shadowdata[1].Set(1, 0, 0, 0, 0); - vbo_shadowdata[2].Set(2, 0, 0, 0, 0); - vbo_shadowdata[3].Set(3, 0, 0, 0, 0); - - // and the second one for the fullscreen quad used for blend overlays. - vbo_shadowdata[4].Set(0, 0, 0, 0, 0); - vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); - vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); - vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); - - // and this is for the postprocessing copy operation - vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); - vbo_shadowdata[9].Set(-1.0f, 1.0f, 0, 0.0f, 1.f); - 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); if (gl.buffermethod == BM_DEFERRED) { @@ -216,11 +186,7 @@ FFlatVertexBuffer::~FFlatVertexBuffer() void FFlatVertexBuffer::OutputResized(int width, int height) { - vbo_shadowdata[4].Set(0, 0, 0, 0, 0); - vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); - vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); - vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); - + FFlatVertexGenerator::OutputResized(width, height); Map(); memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex)); Unmap(); @@ -272,173 +238,6 @@ void FFlatVertexBuffer::Unmap() } } -//========================================================================== -// -// Initialize a single vertex -// -//========================================================================== - -void FFlatVertex::SetFlatVertex(vertex_t *vt, const secplane_t & plane) -{ - x = vt->fX(); - y = vt->fY(); - z = plane.ZatPoint(vt); - u = vt->fX()/64.f; - v = -vt->fY()/64.f; -} - -//========================================================================== -// -// Find a 3D floor -// -//========================================================================== - -static F3DFloor *Find3DFloor(sector_t *target, sector_t *model) -{ - for(unsigned i=0; ie->XFloor.ffloors.Size(); i++) - { - F3DFloor *ffloor = target->e->XFloor.ffloors[i]; - if (ffloor->model == model && !(ffloor->flags & FF_THISINSIDE)) return ffloor; - } - return NULL; -} - -//========================================================================== -// -// Creates the vertices for one plane in one subsector -// -//========================================================================== - -int FFlatVertexBuffer::CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor) -{ - int idx = vbo_shadowdata.Reserve(sub->numlines); - for(unsigned int k=0; knumlines; k++, idx++) - { - vbo_shadowdata[idx].SetFlatVertex(sub->firstline[k].v1, plane); - if (sub->sector->transdoor && floor) vbo_shadowdata[idx].z -= 1.f; - } - return idx; -} - -//========================================================================== -// -// Creates the vertices for one plane in one subsector -// -//========================================================================== - -int FFlatVertexBuffer::CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor) -{ - int rt = vbo_shadowdata.Size(); - // First calculate the vertices for the sector itself - for(int j=0; jsubsectorcount; j++) - { - subsector_t *sub = sec->subsectors[j]; - CreateSubsectorVertices(sub, plane, floor); - } - return rt; -} - -//========================================================================== -// -// -// -//========================================================================== - -int FFlatVertexBuffer::CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor) -{ - // First calculate the vertices for the sector itself - sec->vboheight[h] = sec->GetPlaneTexZ(h); - sec->vboindex[h] = CreateSectorVertices(sec, plane, floor); - - // Next are all sectors using this one as heightsec - TArray &fakes = sec->e->FakeFloor.Sectors; - for (unsigned g=0; gvboindex[2+h] = CreateSectorVertices(fsec, plane, false); - } - - // and finally all attached 3D floors - TArray &xf = sec->e->XFloor.attached; - for (unsigned g=0; gflags & FF_RENDERPLANES) - { - bool dotop = (ffloor->top.model == sec) && (ffloor->top.isceiling == h); - bool dobottom = (ffloor->bottom.model == sec) && (ffloor->bottom.isceiling == h); - - if (dotop || dobottom) - { - if (dotop) ffloor->top.vindex = vbo_shadowdata.Size(); - if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size(); - - CreateSectorVertices(fsec, plane, false); - } - } - } - sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h]; - return sec->vboindex[h]; -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexBuffer::CreateFlatVBO() -{ - for (int h = sector_t::floor; h <= sector_t::ceiling; h++) - { - for(auto &sec : level.sectors) - { - CreateVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor); - } - } - - // We need to do a final check for Vavoom water and FF_FIX sectors. - // No new vertices are needed here. The planes come from the actual sector - for (auto &sec : level.sectors) - { - for(auto ff : sec.e->XFloor.ffloors) - { - if (ff->top.model == &sec) - { - ff->top.vindex = sec.vboindex[ff->top.isceiling]; - } - if (ff->bottom.model == &sec) - { - ff->bottom.vindex = sec.vboindex[ff->top.isceiling]; - } - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) -{ - int startvt = sec->vboindex[plane]; - int countvt = sec->vbocount[plane]; - secplane_t &splane = sec->GetSecPlane(plane); - FFlatVertex *vt = &vbo_shadowdata[startvt]; - FFlatVertex *mapvt = &map[startvt]; - for(int i=0; iz = splane.ZatPoint(vt->x, vt->y); - if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; - mapvt->z = vt->z; - } -} - //========================================================================== // // @@ -448,45 +247,9 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { vbo_shadowdata.Resize(mNumReserved); - CreateFlatVBO(); + FFlatVertexGenerator::CreateVertices(); mCurIndex = mIndex = vbo_shadowdata.Size(); Map(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); Unmap(); } - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexBuffer::CheckPlanes(sector_t *sector) -{ - if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) - { - UpdatePlaneVertices(sector, sector_t::ceiling); - sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); - } - if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) - { - UpdatePlaneVertices(sector, sector_t::floor); - sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor); - } -} - -//========================================================================== -// -// checks the validity of all planes attached to this sector -// and updates them if possible. -// -//========================================================================== - -void FFlatVertexBuffer::CheckUpdate(sector_t *sector) -{ - CheckPlanes(sector); - sector_t *hs = sector->GetHeightSec(); - if (hs != NULL) CheckPlanes(hs); - for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) - CheckPlanes(sector->e->XFloor.ffloors[i]->model); -} \ No newline at end of file diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index ea4c3481f..fc77c683f 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -27,6 +27,7 @@ #include "gl/utility/gl_clock.h" #include "gl/system/gl_interface.h" #include "r_data/models/models.h" +#include "hwrenderer/data/flatvertices.h" struct vertex_t; struct secplane_t; @@ -56,22 +57,6 @@ public: void EnableBufferArrays(int enable, int disable); }; -struct FFlatVertex -{ - float x,z,y; // world position - float u,v; // texture coordinates - - void SetFlatVertex(vertex_t *vt, const secplane_t &plane); - void Set(float xx, float zz, float yy, float uu, float vv) - { - x = xx; - z = zz; - y = yy; - u = uu; - v = vv; - } -}; - struct FSimpleVertex { float x, z, y; // world position @@ -104,14 +89,13 @@ public: void EnableColorArray(bool on); }; -class FFlatVertexBuffer : public FVertexBuffer +class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator { FFlatVertex *map; unsigned int mIndex; unsigned int mCurIndex; unsigned int mNumReserved; - void CheckPlanes(sector_t *sector); static const unsigned int BUFFER_SIZE = 2000000; static const unsigned int BUFFER_SIZE_TO_USE = 1999500; @@ -128,8 +112,6 @@ public: 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 - FFlatVertexBuffer(int width, int height); ~FFlatVertexBuffer(); @@ -138,7 +120,6 @@ public: void BindVBO(); void CreateVBO(); - void CheckUpdate(sector_t *sector); FFlatVertex *GetBuffer() { @@ -180,6 +161,17 @@ public: } #endif + + void CheckPlanes(sector_t *sector) + { + FFlatVertexGenerator::CheckPlanes(sector, map); + } + + void CheckUpdate(sector_t *sector) + { + FFlatVertexGenerator::CheckUpdate(sector, map); + } + void Reset() { mCurIndex = mIndex; @@ -187,14 +179,6 @@ public: 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); - int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); - void CreateFlatVBO(); - void UpdatePlaneVertices(sector_t *sec, int plane); - }; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index e36d4a487..91e11c328 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -623,7 +623,7 @@ SortNode * GLDrawList::SortSpriteList(SortNode * head) sortspritelist.Clear(); for(count=0,n=head;n;n=n->next) sortspritelist.Push(n); - std::sort(sortspritelist.begin(), sortspritelist.end(), [=](SortNode *a, SortNode *b) + std::stable_sort(sortspritelist.begin(), sortspritelist.end(), [=](SortNode *a, SortNode *b) { return CompareSprites(a, b) < 0; }); diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp new file mode 100644 index 000000000..6a3690ff6 --- /dev/null +++ b/src/hwrenderer/data/flatvertices.cpp @@ -0,0 +1,298 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2005-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** hw_flatvertices.cpp +** Creates flat vertex data for hardware rendering. +** +**/ + +#include "doomtype.h" +#include "p_local.h" +#include "r_state.h" +#include "m_argv.h" +#include "c_cvars.h" +#include "g_levellocals.h" +#include "flatvertices.h" + + +//========================================================================== +// +// +// +//========================================================================== + +FFlatVertexGenerator::FFlatVertexGenerator(int width, int height) +{ + vbo_shadowdata.Resize(NUM_RESERVED); + + // the first quad is reserved for handling coordinates through uniforms. + vbo_shadowdata[0].Set(0, 0, 0, 0, 0); + vbo_shadowdata[1].Set(1, 0, 0, 0, 0); + vbo_shadowdata[2].Set(2, 0, 0, 0, 0); + vbo_shadowdata[3].Set(3, 0, 0, 0, 0); + + // and the second one for the fullscreen quad used for blend overlays. + vbo_shadowdata[4].Set(0, 0, 0, 0, 0); + vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); + vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); + vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); + + // and this is for the postprocessing copy operation + vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); + vbo_shadowdata[9].Set(-1.0f, 1.0f, 0, 0.0f, 1.f); + 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); +} + +void FFlatVertexGenerator::OutputResized(int width, int height) +{ + vbo_shadowdata[4].Set(0, 0, 0, 0, 0); + vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); + vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); + vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); +} + +//========================================================================== +// +// Initialize a single vertex +// +//========================================================================== + +void FFlatVertex::SetFlatVertex(vertex_t *vt, const secplane_t & plane) +{ + x = vt->fX(); + y = vt->fY(); + z = plane.ZatPoint(vt); + u = vt->fX()/64.f; + v = -vt->fY()/64.f; +} + +//========================================================================== +// +// Find a 3D floor +// +//========================================================================== + +static F3DFloor *Find3DFloor(sector_t *target, sector_t *model) +{ + for(unsigned i=0; ie->XFloor.ffloors.Size(); i++) + { + F3DFloor *ffloor = target->e->XFloor.ffloors[i]; + if (ffloor->model == model && !(ffloor->flags & FF_THISINSIDE)) return ffloor; + } + return NULL; +} + +//========================================================================== +// +// Creates the vertices for one plane in one subsector +// +//========================================================================== + +int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor) +{ + int idx = vbo_shadowdata.Reserve(sub->numlines); + for(unsigned int k=0; knumlines; k++, idx++) + { + vbo_shadowdata[idx].SetFlatVertex(sub->firstline[k].v1, plane); + if (sub->sector->transdoor && floor) vbo_shadowdata[idx].z -= 1.f; + } + return idx; +} + +//========================================================================== +// +// Creates the vertices for one plane in one subsector +// +//========================================================================== + +int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor) +{ + int rt = vbo_shadowdata.Size(); + // First calculate the vertices for the sector itself + for(int j=0; jsubsectorcount; j++) + { + subsector_t *sub = sec->subsectors[j]; + CreateSubsectorVertices(sub, plane, floor); + } + return rt; +} + +//========================================================================== +// +// +// +//========================================================================== + +int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor) +{ + // First calculate the vertices for the sector itself + sec->vboheight[h] = sec->GetPlaneTexZ(h); + sec->vboindex[h] = CreateSectorVertices(sec, plane, floor); + + // Next are all sectors using this one as heightsec + TArray &fakes = sec->e->FakeFloor.Sectors; + for (unsigned g=0; gvboindex[2+h] = CreateSectorVertices(fsec, plane, false); + } + + // and finally all attached 3D floors + TArray &xf = sec->e->XFloor.attached; + for (unsigned g=0; gflags & FF_RENDERPLANES) + { + bool dotop = (ffloor->top.model == sec) && (ffloor->top.isceiling == h); + bool dobottom = (ffloor->bottom.model == sec) && (ffloor->bottom.isceiling == h); + + if (dotop || dobottom) + { + if (dotop) ffloor->top.vindex = vbo_shadowdata.Size(); + if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size(); + + CreateSectorVertices(fsec, plane, false); + } + } + } + sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h]; + return sec->vboindex[h]; +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FFlatVertexGenerator::CreateFlatVertices() +{ + for (int h = sector_t::floor; h <= sector_t::ceiling; h++) + { + for(auto &sec : level.sectors) + { + CreateVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor); + } + } + + // We need to do a final check for Vavoom water and FF_FIX sectors. + // No new vertices are needed here. The planes come from the actual sector + for (auto &sec : level.sectors) + { + for(auto ff : sec.e->XFloor.ffloors) + { + if (ff->top.model == &sec) + { + ff->top.vindex = sec.vboindex[ff->top.isceiling]; + } + if (ff->bottom.model == &sec) + { + ff->bottom.vindex = sec.vboindex[ff->top.isceiling]; + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map) +{ + int startvt = sec->vboindex[plane]; + int countvt = sec->vbocount[plane]; + secplane_t &splane = sec->GetSecPlane(plane); + FFlatVertex *vt = &vbo_shadowdata[startvt]; + FFlatVertex *mapvt = &map[startvt]; + for(int i=0; iz = splane.ZatPoint(vt->x, vt->y); + if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; + mapvt->z = vt->z; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FFlatVertexGenerator::CreateVertices() +{ + vbo_shadowdata.Resize(NUM_RESERVED); + CreateFlatVertices(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FFlatVertexGenerator::CheckPlanes(sector_t *sector, FFlatVertex *map) +{ + if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) + { + UpdatePlaneVertices(sector, sector_t::ceiling, map); + sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); + } + if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) + { + UpdatePlaneVertices(sector, sector_t::floor, map); + sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor); + } +} + +//========================================================================== +// +// checks the validity of all planes attached to this sector +// and updates them if possible. +// +//========================================================================== + +void FFlatVertexGenerator::CheckUpdate(sector_t *sector, FFlatVertex *map) +{ + CheckPlanes(sector, map); + sector_t *hs = sector->GetHeightSec(); + if (hs != NULL) CheckPlanes(hs, map); + for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) + CheckPlanes(sector->e->XFloor.ffloors[i]->model, map); +} diff --git a/src/hwrenderer/data/flatvertices.h b/src/hwrenderer/data/flatvertices.h new file mode 100644 index 000000000..9a45558b5 --- /dev/null +++ b/src/hwrenderer/data/flatvertices.h @@ -0,0 +1,81 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2005-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// + +#ifndef _HW__VERTEXBUFFER_H +#define _HW__VERTEXBUFFER_H + +#include "tarray.h" + +struct FFlatVertex +{ + float x, z, y; // world position + float u, v; // texture coordinates + + void SetFlatVertex(vertex_t *vt, const secplane_t &plane); + void Set(float xx, float zz, float yy, float uu, float vv) + { + x = xx; + z = zz; + y = yy; + u = uu; + v = vv; + } +}; + +class FFlatVertexGenerator +{ +protected: + TArray vbo_shadowdata; + + + void CheckPlanes(sector_t *sector); + +public: + enum + { + QUAD_INDEX = 0, + FULLSCREEN_INDEX = 4, + PRESENT_INDEX = 8, + STENCILTOP_INDEX = 12, + STENCILBOTTOM_INDEX = 16, + + NUM_RESERVED = 20 + }; + + FFlatVertexGenerator(int width, int height); + + void OutputResized(int width, int height); + +private: + int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); + int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); + int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); + void CreateFlatVertices(); + void UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map); +protected: + void CreateVertices(); + void CheckPlanes(sector_t *sector, FFlatVertex *map); + void CheckUpdate(sector_t *sector, FFlatVertex *map); + +}; + +#endif \ No newline at end of file diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index ffe0d7a22..9a311b10f 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -226,5 +226,5 @@ int FRawPageTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, } bmp->CopyPixelData(x, y, source, 320, 200, 1, 320, 0, paldata, inf); } - + return 0; } From 59a08ce0df35d14d9bc5d23a95964fc9bff99dc4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 12:24:04 +0200 Subject: [PATCH 8/9] - fixed a few warnings and changed the return type of FGLTexture::Bind, because no caller needs the hardware texture. --- src/gl/textures/gl_material.cpp | 11 +++++------ src/gl/textures/gl_material.h | 2 +- src/hwrenderer/data/flatvertices.cpp | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 99a6f133a..ed1c86e46 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -157,7 +157,7 @@ FHardwareTexture *FGLTexture::CreateHwTexture() // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, int flags) +bool FGLTexture::Bind(int texunit, int clampmode, int translation, int flags) { int usebright = false; @@ -216,7 +216,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla { // could not create texture delete[] buffer; - return NULL; + return false; } delete[] buffer; } @@ -225,9 +225,9 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (lastSampler != clampmode) lastSampler = GLRenderer->mSamplerManager->Bind(texunit, clampmode, lastSampler); lastTranslation = translation; - return hwtex; + return true; } - return NULL; + return false; } //=========================================================================== @@ -636,8 +636,7 @@ void FMaterial::Bind(int clampmode, int translation) // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = mExpanded? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY)? CTF_CheckHires : 0; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, flags); - if (gltexture != NULL) + if (mBaseLayer->Bind(0, clampmode, translation, flags)) { for(unsigned i=0;ifX(); - y = vt->fY(); - z = plane.ZatPoint(vt); - u = vt->fX()/64.f; - v = -vt->fY()/64.f; + x = (float)vt->fX(); + y = (float)vt->fY(); + z = (float)plane.ZatPoint(vt); + u = (float)vt->fX()/64.f; + v = -(float)vt->fY()/64.f; } //========================================================================== @@ -243,7 +243,7 @@ void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVe FFlatVertex *mapvt = &map[startvt]; for(int i=0; iz = splane.ZatPoint(vt->x, vt->y); + vt->z = (float)splane.ZatPoint(vt->x, vt->y); if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; mapvt->z = vt->z; } From 790182a2f433abf4ec636b6be8f2528499dfe526 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Apr 2018 20:20:43 +0200 Subject: [PATCH 9/9] - split GLWall::PutWall in two. --- src/gl/compatibility/gl_20.cpp | 20 +++---- src/gl/scene/gl_drawinfo.h | 3 ++ src/gl/scene/gl_wall.h | 11 ++-- src/gl/scene/gl_walls.cpp | 98 ++++++++++++++++++---------------- 4 files changed, 73 insertions(+), 59 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 28ceb6be6..ea32d58c2 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -534,32 +534,32 @@ static bool gl_CheckFog(FColormap *cm, int lightlevel) // //========================================================================== -bool GLWall::PutWallCompat(int passflag) +bool FDrawInfo::PutWallCompat(GLWall *wall, int passflag) { static int list_indices[2][2] = { { GLLDL_WALLS_PLAIN, GLLDL_WALLS_FOG },{ GLLDL_WALLS_MASKED, GLLDL_WALLS_FOGMASKED } }; // are lights possible? - if (mDrawer->FixedColormap != CM_DEFAULT || !gl_lights || seg->sidedef == nullptr || type == RENDERWALL_M2SNF || !gltexture) return false; + if (mDrawer->FixedColormap != CM_DEFAULT || !gl_lights || wall->seg->sidedef == nullptr || wall->type == RENDERWALL_M2SNF || !wall->gltexture) return false; // multipassing these is problematic. - if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S)) return false; + if ((wall->flags & GLWall::GLWF_SKYHACK && wall->type == RENDERWALL_M2S)) return false; // Any lights affecting this wall? - if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) + if (!(wall->seg->sidedef->Flags & WALLF_POLYOBJ)) { - if (seg->sidedef->lighthead == nullptr) return false; + if (wall->seg->sidedef->lighthead == nullptr) return false; } - else if (sub) + else if (wall->sub) { - if (sub->lighthead == nullptr) return false; + if (wall->sub->lighthead == nullptr) return false; } - bool foggy = gl_CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive; - bool masked = passflag == 2 && gltexture->isMasked(); + bool foggy = gl_CheckFog(&wall->Colormap, wall->lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive; + bool masked = passflag == 2 && wall->gltexture->isMasked(); int list = list_indices[masked][foggy]; - gl_drawinfo->dldrawlists[list].AddWall(this); + dldrawlists[list].AddWall(wall); return true; } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index eb2faaa52..0c2607632 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -236,6 +236,9 @@ struct FDrawInfo ~FDrawInfo(); void ClearBuffers(); + void AddWall(GLWall *wall); + bool PutWallCompat(GLWall *wall, int passflag); // Legacy GL only. + bool DoOneSectorUpper(subsector_t * subsec, float planez); bool DoOneSectorLower(subsector_t * subsec, float planez); bool DoFakeBridge(subsector_t * subsec, float planez); diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 7151b1809..a2fa33eca 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -106,10 +106,13 @@ struct GLSectorPlane } }; +class FDrawInfo; class GLWall { + friend class FDrawInfo; public: + static const char passflag[]; enum { @@ -120,6 +123,7 @@ public: GLWF_NOSPLITUPPER=16, GLWF_NOSPLITLOWER=32, GLWF_NOSPLIT=64, + GLWF_TRANSLUCENT = 128 }; enum @@ -142,19 +146,20 @@ public: friend class GLPortal; GLSceneDrawer *mDrawer; - GLSeg glseg; vertex_t * vertexes[2]; // required for polygon splitting + FMaterial *gltexture; + TArray *lightlist; + + GLSeg glseg; float ztop[2],zbottom[2]; texcoord tcs[4]; float alpha; - FMaterial *gltexture; FColormap Colormap; ERenderStyle RenderStyle; float ViewDistance; - TArray *lightlist; int lightlevel; uint8_t type; uint8_t flags; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index b7eb40393..919ce374c 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -46,6 +46,56 @@ #include "gl/shaders/gl_shader.h" +void FDrawInfo::AddWall(GLWall *wall) +{ + bool translucent = !!(wall->flags & GLWall::GLWF_TRANSLUCENT); + int list; + + if (translucent) // translucent walls + { + wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared(); + if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(true); + drawlists[GLDL_TRANSLUCENT].AddWall(wall); + } + else + { + if (gl.legacyMode) + { + if (PutWallCompat(wall, GLWall::passflag[wall->type])) return; + } + + bool masked; + + masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked()); + + if ((wall->flags & GLWall::GLWF_SKYHACK && wall->type == RENDERWALL_M2S)) + { + list = GLDL_MASKEDWALLSOFS; + } + else + { + list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; + } + if (gl.buffermethod == BM_DEFERRED) wall->MakeVertices(false); + drawlists[list].AddWall(wall); + + } +} + + +const char GLWall::passflag[] = { + 0, //RENDERWALL_NONE, + 1, //RENDERWALL_TOP, // unmasked + 1, //RENDERWALL_M1S, // unmasked + 2, //RENDERWALL_M2S, // depends on render and texture settings + 1, //RENDERWALL_BOTTOM, // unmasked + 3, //RENDERWALL_FOGBOUNDARY, // translucent + 1, //RENDERWALL_MIRRORSURFACE, // only created from PORTALTYPE_MIRROR + 2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary. + 3, //RENDERWALL_COLOR, // translucent + 2, //RENDERWALL_FFBLOCK // depends on render and texture settings +}; + //========================================================================== // // @@ -53,26 +103,11 @@ //========================================================================== void GLWall::PutWall(bool translucent) { - int list; - - static char passflag[] = { - 0, //RENDERWALL_NONE, - 1, //RENDERWALL_TOP, // unmasked - 1, //RENDERWALL_M1S, // unmasked - 2, //RENDERWALL_M2S, // depends on render and texture settings - 1, //RENDERWALL_BOTTOM, // unmasked - 3, //RENDERWALL_FOGBOUNDARY, // translucent - 1, //RENDERWALL_MIRRORSURFACE, // only created from PORTALTYPE_MIRROR - 2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary. - 3, //RENDERWALL_COLOR, // translucent - 2, //RENDERWALL_FFBLOCK // depends on render and texture settings - }; - - if (gltexture && gltexture->tex->GetTranslucency() && passflag[type] == 2) { translucent = true; } + if (translucent) flags |= GLWF_TRANSLUCENT; if (mDrawer->FixedColormap) { @@ -81,36 +116,7 @@ void GLWall::PutWall(bool translucent) Colormap.Clear(); } if (mDrawer->isFullbright(Colormap.LightColor, lightlevel)) flags &= ~GLWF_GLOW; - - if (translucent) // translucent walls - { - ViewDistance = (r_viewpoint.Pos - (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 - { - if (gl.legacyMode && !translucent) - { - if (PutWallCompat(passflag[type])) return; - } - - bool masked; - - masked = passflag[type] == 1 ? false : (gltexture && gltexture->isMasked()); - - if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S)) - { - list = GLDL_MASKEDWALLSOFS; - } - else - { - list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; - } - if (gl.buffermethod == BM_DEFERRED) MakeVertices(false); - gl_drawinfo->drawlists[list].AddWall(this); - - } + gl_drawinfo->AddWall(this); lightlist = NULL; vertcount = 0; // make sure that following parts of the same linedef do not get this one's vertex info. }