mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-28 14:42:23 +00:00
- allow reallocation of light buffer if more lights are needed.
- added a light preprocessing pass to the renderer so that a non-persistent buffer can be used with minimal mapping/unmapping. This only gets used if necessary because it adds some overhead to the renderer.
This commit is contained in:
parent
38796e7714
commit
00d7707aef
11 changed files with 323 additions and 169 deletions
|
@ -45,15 +45,20 @@
|
||||||
#include "gl/system/gl_interface.h"
|
#include "gl/system/gl_interface.h"
|
||||||
#include "gl/utility//gl_clock.h"
|
#include "gl/utility//gl_clock.h"
|
||||||
|
|
||||||
static const int BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB.
|
static const int INITIAL_BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB.
|
||||||
|
|
||||||
|
float *mMap;
|
||||||
|
|
||||||
FLightBuffer::FLightBuffer()
|
FLightBuffer::FLightBuffer()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
mBufferSize = INITIAL_BUFFER_SIZE;
|
||||||
|
mByteSize = mBufferSize * sizeof(float);
|
||||||
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
||||||
{
|
{
|
||||||
mBufferType = GL_SHADER_STORAGE_BUFFER;
|
mBufferType = GL_SHADER_STORAGE_BUFFER;
|
||||||
mBlockAlign = -1;
|
mBlockAlign = -1;
|
||||||
mBlockSize = BUFFER_SIZE;
|
mBlockSize = mBufferSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -64,12 +69,17 @@ FLightBuffer::FLightBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenBuffers(1, &mBufferId);
|
glGenBuffers(1, &mBufferId);
|
||||||
glBindBuffer(mBufferType, mBufferId);
|
|
||||||
unsigned int bytesize = BUFFER_SIZE * 4 * sizeof(float);
|
|
||||||
glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
|
||||||
void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
|
||||||
mBufferPointer = (float*)map;
|
|
||||||
glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId);
|
glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId);
|
||||||
|
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
||||||
|
{
|
||||||
|
glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
mBufferPointer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
mLastMappedIndex = UINT_MAX;
|
mLastMappedIndex = UINT_MAX;
|
||||||
|
@ -84,7 +94,8 @@ FLightBuffer::~FLightBuffer()
|
||||||
void FLightBuffer::Clear()
|
void FLightBuffer::Clear()
|
||||||
{
|
{
|
||||||
mIndex = 0;
|
mIndex = 0;
|
||||||
mBufferArray.Clear();
|
mIndices.Clear();
|
||||||
|
mUploadIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FLightBuffer::UploadLights(FDynLightData &data)
|
int FLightBuffer::UploadLights(FDynLightData &data)
|
||||||
|
@ -120,13 +131,45 @@ int FLightBuffer::UploadLights(FDynLightData &data)
|
||||||
|
|
||||||
if (totalsize <= 1) return -1;
|
if (totalsize <= 1) return -1;
|
||||||
|
|
||||||
if (mIndex + totalsize > BUFFER_SIZE)
|
if (mIndex + totalsize > mBufferSize)
|
||||||
{
|
{
|
||||||
return -1; // we ran out of space. All following lights will be ignored
|
// reallocate the buffer with twice the size
|
||||||
|
unsigned int newbuffer;
|
||||||
|
|
||||||
|
// first unmap the old buffer
|
||||||
|
glBindBuffer(mBufferType, mBufferId);
|
||||||
|
glUnmapBuffer(mBufferType);
|
||||||
|
|
||||||
|
// create and bind the new buffer, bind the old one to a copy target (too bad that DSA is not yet supported well enough to omit this crap.)
|
||||||
|
glGenBuffers(1, &newbuffer);
|
||||||
|
glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, newbuffer);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, mBufferId);
|
||||||
|
|
||||||
|
// create the new buffer's storage (twice as large as the old one)
|
||||||
|
mBufferSize *= 2;
|
||||||
|
mByteSize *= 2;
|
||||||
|
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
||||||
|
{
|
||||||
|
glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy contents and delete the old buffer.
|
||||||
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, mBufferType, 0, 0, mByteSize/2);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||||
|
glDeleteBuffers(1, &mBufferId);
|
||||||
|
mBufferId = newbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
float *copyptr;
|
float *copyptr;
|
||||||
|
|
||||||
|
assert(mBufferPointer != NULL);
|
||||||
|
if (mBufferPointer == NULL) return -1;
|
||||||
copyptr = mBufferPointer + mIndex * 4;
|
copyptr = mBufferPointer + mIndex * 4;
|
||||||
|
|
||||||
float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 };
|
float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 };
|
||||||
|
@ -142,9 +185,23 @@ int FLightBuffer::UploadLights(FDynLightData &data)
|
||||||
return bufferindex;
|
return bufferindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FLightBuffer::Begin()
|
||||||
|
{
|
||||||
|
if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||||
|
{
|
||||||
|
glBindBuffer(mBufferType, mBufferId);
|
||||||
|
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FLightBuffer::Finish()
|
void FLightBuffer::Finish()
|
||||||
{
|
{
|
||||||
Clear();
|
if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||||
|
{
|
||||||
|
glBindBuffer(mBufferType, mBufferId);
|
||||||
|
glUnmapBuffer(mBufferType);
|
||||||
|
mBufferPointer = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FLightBuffer::BindUBO(unsigned int index)
|
int FLightBuffer::BindUBO(unsigned int index)
|
||||||
|
|
|
@ -6,15 +6,18 @@ struct FDynLightData;
|
||||||
|
|
||||||
class FLightBuffer
|
class FLightBuffer
|
||||||
{
|
{
|
||||||
TArray<float> mBufferArray;
|
TArray<int> mIndices;
|
||||||
unsigned int mBufferId;
|
unsigned int mBufferId;
|
||||||
float * mBufferPointer;
|
float * mBufferPointer;
|
||||||
|
|
||||||
unsigned int mBufferType;
|
unsigned int mBufferType;
|
||||||
unsigned int mIndex;
|
unsigned int mIndex;
|
||||||
|
unsigned int mUploadIndex;
|
||||||
unsigned int mLastMappedIndex;
|
unsigned int mLastMappedIndex;
|
||||||
unsigned int mBlockAlign;
|
unsigned int mBlockAlign;
|
||||||
unsigned int mBlockSize;
|
unsigned int mBlockSize;
|
||||||
|
unsigned int mBufferSize;
|
||||||
|
unsigned int mByteSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -22,10 +25,14 @@ public:
|
||||||
~FLightBuffer();
|
~FLightBuffer();
|
||||||
void Clear();
|
void Clear();
|
||||||
int UploadLights(FDynLightData &data);
|
int UploadLights(FDynLightData &data);
|
||||||
|
void Begin();
|
||||||
void Finish();
|
void Finish();
|
||||||
int BindUBO(unsigned int index);
|
int BindUBO(unsigned int index);
|
||||||
unsigned int GetBlockSize() const { return mBlockSize; }
|
unsigned int GetBlockSize() const { return mBlockSize; }
|
||||||
unsigned int GetBufferType() const { return mBufferType; }
|
unsigned int GetBufferType() const { return mBufferType; }
|
||||||
|
unsigned int GetIndexPtr() const { return mIndices.Size(); }
|
||||||
|
void StoreIndex(int index) { mIndices.Push(index); }
|
||||||
|
int GetIndex(int i) const { return mIndices[i]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -110,7 +110,7 @@ void FGLRenderer::Initialize()
|
||||||
mVBO = new FFlatVertexBuffer;
|
mVBO = new FFlatVertexBuffer;
|
||||||
mSkyVBO = new FSkyVertexBuffer;
|
mSkyVBO = new FSkyVertexBuffer;
|
||||||
mModelVBO = new FModelVertexBuffer;
|
mModelVBO = new FModelVertexBuffer;
|
||||||
mLights = new FLightBuffer;
|
mLights = new FLightBuffer();
|
||||||
gl_RenderState.SetVertexBuffer(mVBO);
|
gl_RenderState.SetVertexBuffer(mVBO);
|
||||||
mFBID = 0;
|
mFBID = 0;
|
||||||
SetupLevel();
|
SetupLevel();
|
||||||
|
|
|
@ -692,7 +692,7 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLDrawList::DoDraw(int pass, int i)
|
void GLDrawList::DoDraw(int pass, int i, bool trans)
|
||||||
{
|
{
|
||||||
switch(drawitems[i].rendertype)
|
switch(drawitems[i].rendertype)
|
||||||
{
|
{
|
||||||
|
@ -700,7 +700,7 @@ void GLDrawList::DoDraw(int pass, int i)
|
||||||
{
|
{
|
||||||
GLFlat * f=&flats[drawitems[i].index];
|
GLFlat * f=&flats[drawitems[i].index];
|
||||||
RenderFlat.Clock();
|
RenderFlat.Clock();
|
||||||
f->Draw(pass);
|
f->Draw(pass, trans);
|
||||||
RenderFlat.Unclock();
|
RenderFlat.Unclock();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -739,13 +739,13 @@ void GLDrawList::DoDrawSorted(SortNode * head)
|
||||||
{
|
{
|
||||||
DoDrawSorted(head->left);
|
DoDrawSorted(head->left);
|
||||||
}
|
}
|
||||||
DoDraw(GLPASS_TRANSLUCENT, head->itemindex);
|
DoDraw(GLPASS_TRANSLUCENT, head->itemindex, true);
|
||||||
if (head->equal)
|
if (head->equal)
|
||||||
{
|
{
|
||||||
SortNode * ehead=head->equal;
|
SortNode * ehead=head->equal;
|
||||||
while (ehead)
|
while (ehead)
|
||||||
{
|
{
|
||||||
DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex);
|
DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
||||||
ehead=ehead->equal;
|
ehead=ehead->equal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,7 +779,7 @@ void GLDrawList::Draw(int pass)
|
||||||
{
|
{
|
||||||
for(unsigned i=0;i<drawitems.Size();i++)
|
for(unsigned i=0;i<drawitems.Size();i++)
|
||||||
{
|
{
|
||||||
DoDraw(pass, i);
|
DoDraw(pass, i, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,9 @@ enum DrawListType
|
||||||
|
|
||||||
enum Drawpasses
|
enum Drawpasses
|
||||||
{
|
{
|
||||||
GLPASS_PLAIN, // Main pass without dynamic lights
|
|
||||||
GLPASS_ALL, // Main pass with dynamic lights
|
GLPASS_ALL, // Main pass with dynamic lights
|
||||||
|
GLPASS_LIGHTSONLY, // only collect dynamic lights
|
||||||
|
GLPASS_PLAIN, // Main pass without dynamic lights
|
||||||
GLPASS_DECALS, // Draws a decal
|
GLPASS_DECALS, // Draws a decal
|
||||||
GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer)
|
GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer)
|
||||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
GLPASS_TRANSLUCENT, // Draws translucent objects
|
||||||
|
@ -120,7 +121,7 @@ public:
|
||||||
SortNode * SortSpriteList(SortNode * head);
|
SortNode * SortSpriteList(SortNode * head);
|
||||||
SortNode * DoSort(SortNode * head);
|
SortNode * DoSort(SortNode * head);
|
||||||
|
|
||||||
void DoDraw(int pass, int index);
|
void DoDraw(int pass, int index, bool trans);
|
||||||
void DoDrawSorted(SortNode * node);
|
void DoDrawSorted(SortNode * node);
|
||||||
void DrawSorted();
|
void DrawSorted();
|
||||||
void Draw(int pass);
|
void Draw(int pass);
|
||||||
|
|
|
@ -112,10 +112,17 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
extern FDynLightData lightdata;
|
extern FDynLightData lightdata;
|
||||||
|
|
||||||
bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
|
||||||
{
|
{
|
||||||
Plane p;
|
Plane p;
|
||||||
|
|
||||||
|
if (dli != NULL && *dli != -1)
|
||||||
|
{
|
||||||
|
gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli));
|
||||||
|
(*dli)++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lightdata.Clear();
|
lightdata.Clear();
|
||||||
FLightNode * node = sub->lighthead;
|
FLightNode * node = sub->lighthead;
|
||||||
while (node)
|
while (node)
|
||||||
|
@ -143,9 +150,15 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
||||||
node = node->nextLight;
|
node = node->nextLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
int d = GLRenderer->mLights->UploadLights(lightdata);
|
||||||
gl_RenderState.ApplyLightIndex(dynlightindex);
|
if (pass == GLPASS_LIGHTSONLY)
|
||||||
return false;
|
{
|
||||||
|
GLRenderer->mLights->StoreIndex(d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_RenderState.ApplyLightIndex(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -197,15 +210,59 @@ void GLFlat::DrawSubsector(subsector_t * sub)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void GLFlat::DrawSubsectors(int pass, bool istrans)
|
void GLFlat::ProcessLights(bool istrans)
|
||||||
{
|
{
|
||||||
bool lightsapplied = false;
|
dynlightindex = GLRenderer->mLights->GetIndexPtr();
|
||||||
|
|
||||||
|
if (sub)
|
||||||
|
{
|
||||||
|
// This represents a single subsector
|
||||||
|
SetupSubsectorLights(GLPASS_LIGHTSONLY, sub);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw the subsectors belonging to this sector
|
||||||
|
for (int i=0; i<sector->subsectorcount; i++)
|
||||||
|
{
|
||||||
|
subsector_t * sub = sector->subsectors[i];
|
||||||
|
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||||
|
{
|
||||||
|
SetupSubsectorLights(GLPASS_LIGHTSONLY, 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);
|
||||||
|
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
SetupSubsectorLights(GLPASS_LIGHTSONLY, node->sub);
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans)
|
||||||
|
{
|
||||||
|
int dli = dynlightindex;
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
if (sub)
|
if (sub)
|
||||||
{
|
{
|
||||||
// This represents a single subsector
|
// This represents a single subsector
|
||||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||||
DrawSubsector(sub);
|
DrawSubsector(sub);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -216,10 +273,10 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||||
for (int i=0; i<sector->subsectorcount; i++)
|
for (int i=0; i<sector->subsectorcount; i++)
|
||||||
{
|
{
|
||||||
subsector_t * sub = sector->subsectors[i];
|
subsector_t * sub = sector->subsectors[i];
|
||||||
// This is just a quick hack to make translucent 3D floors and portals work.
|
|
||||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||||
drawcalls.Clock();
|
drawcalls.Clock();
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
|
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
|
||||||
drawcalls.Unclock();
|
drawcalls.Unclock();
|
||||||
|
@ -237,7 +294,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||||
subsector_t * sub = sector->subsectors[i];
|
subsector_t * sub = sector->subsectors[i];
|
||||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||||
DrawSubsector(sub);
|
DrawSubsector(sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +309,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub);
|
if (processlights) SetupSubsectorLights(GLPASS_ALL, node->sub, &dli);
|
||||||
DrawSubsector(node->sub);
|
DrawSubsector(node->sub);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +323,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLFlat::Draw(int pass)
|
void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIGHTSONLY
|
||||||
{
|
{
|
||||||
int rel = getExtraLight();
|
int rel = getExtraLight();
|
||||||
|
|
||||||
|
@ -286,10 +343,17 @@ void GLFlat::Draw(int pass)
|
||||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||||
gltexture->Bind();
|
gltexture->Bind();
|
||||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||||
DrawSubsectors(pass, false);
|
DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false);
|
||||||
gl_RenderState.EnableTextureMatrix(false);
|
gl_RenderState.EnableTextureMatrix(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GLPASS_LIGHTSONLY:
|
||||||
|
if (!trans || gltexture)
|
||||||
|
{
|
||||||
|
ProcessLights(trans);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GLPASS_TRANSLUCENT:
|
case GLPASS_TRANSLUCENT:
|
||||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
||||||
|
@ -298,14 +362,14 @@ void GLFlat::Draw(int pass)
|
||||||
if (!gltexture)
|
if (!gltexture)
|
||||||
{
|
{
|
||||||
gl_RenderState.EnableTexture(false);
|
gl_RenderState.EnableTexture(false);
|
||||||
DrawSubsectors(pass, true);
|
DrawSubsectors(pass, false, true);
|
||||||
gl_RenderState.EnableTexture(true);
|
gl_RenderState.EnableTexture(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gltexture->Bind();
|
gltexture->Bind();
|
||||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||||
DrawSubsectors(pass, true);
|
DrawSubsectors(pass, true, true);
|
||||||
gl_RenderState.EnableTextureMatrix(false);
|
gl_RenderState.EnableTextureMatrix(false);
|
||||||
}
|
}
|
||||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
|
@ -340,20 +340,31 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
gl_RenderState.EnableFog(true);
|
gl_RenderState.EnableFog(true);
|
||||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||||
|
|
||||||
// First draw all single-pass stuff
|
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort();
|
||||||
|
|
||||||
|
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
||||||
|
// so that we don't have to do repeated map/unmap calls on the buffer.
|
||||||
|
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||||
|
{
|
||||||
|
GLRenderer->mLights->Begin();
|
||||||
|
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKED].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY);
|
||||||
|
GLRenderer->mLights->Finish();
|
||||||
|
}
|
||||||
|
|
||||||
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
|
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||||
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL); // just in case
|
|
||||||
GLRenderer->mLights->Finish();
|
|
||||||
|
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights)
|
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||||
{
|
{
|
||||||
pass = GLPASS_ALL;
|
pass = GLPASS_ALL;
|
||||||
}
|
}
|
||||||
|
@ -364,7 +375,6 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
|
|
||||||
gl_RenderState.EnableTexture(gl_texture);
|
gl_RenderState.EnableTexture(gl_texture);
|
||||||
gl_RenderState.EnableBrightmap(true);
|
gl_RenderState.EnableBrightmap(true);
|
||||||
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
|
|
||||||
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,15 +385,13 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
gl_RenderState.SetTextureMode(TM_MASK);
|
gl_RenderState.SetTextureMode(TM_MASK);
|
||||||
}
|
}
|
||||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
|
|
||||||
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
|
||||||
|
|
||||||
// this list is empty most of the time so only waste time on it when in use.
|
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
||||||
if (gl_drawinfo->drawlists[GLDL_MASKEDOFS].Size() > 0)
|
if (gl_drawinfo->drawlists[GLDL_MASKEDOFS].Size() > 0)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort();
|
|
||||||
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(pass);
|
gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(pass);
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(0, 0);
|
glPolygonOffset(0, 0);
|
||||||
|
@ -393,7 +401,7 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
|
|
||||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
// Draw decals (not a real pass)
|
// Part 4: Draw decals (not a real pass)
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
|
@ -413,8 +421,8 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
// so they don't interfere with overlapping mid textures.
|
// so they don't interfere with overlapping mid textures.
|
||||||
glPolygonOffset(1.0f, 128.0f);
|
glPolygonOffset(1.0f, 128.0f);
|
||||||
|
|
||||||
// flood all the gaps with the back sector's flat texture
|
// Part 5: flood all the gaps with the back sector's flat texture
|
||||||
// This will always be drawn like GLDL_PLAIN or GLDL_FOG, depending on the fog settings
|
// This will always be drawn like GLDL_PLAIN, depending on the fog settings
|
||||||
|
|
||||||
glDepthMask(false); // don't write to Z-buffer!
|
glDepthMask(false); // don't write to Z-buffer!
|
||||||
gl_RenderState.EnableFog(true);
|
gl_RenderState.EnableFog(true);
|
||||||
|
@ -782,6 +790,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
||||||
SetCameraPos(viewx, viewy, viewz, viewangle);
|
SetCameraPos(viewx, viewy, viewz, viewangle);
|
||||||
SetViewMatrix(false, false);
|
SetViewMatrix(false, false);
|
||||||
gl_RenderState.ApplyMatrices();
|
gl_RenderState.ApplyMatrices();
|
||||||
|
GLRenderer->mLights->Clear();
|
||||||
|
|
||||||
clipper.Clear();
|
clipper.Clear();
|
||||||
angle_t a1 = FrustumAngle();
|
angle_t a1 = FrustumAngle();
|
||||||
|
|
|
@ -112,7 +112,7 @@ CVAR(Bool, gl_nolayer, false, 0)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLSprite::Draw(int pass)
|
void GLSprite::Draw(int pass)
|
||||||
{
|
{
|
||||||
if (pass == GLPASS_DECALS) return;
|
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -279,16 +279,17 @@ public:
|
||||||
|
|
||||||
int dynlightindex;
|
int dynlightindex;
|
||||||
|
|
||||||
bool SetupSubsectorLights(bool lightsapplied, subsector_t * sub);
|
void SetupSubsectorLights(int pass, subsector_t * sub, int *dli = NULL);
|
||||||
void DrawSubsector(subsector_t * sub);
|
void DrawSubsector(subsector_t * sub);
|
||||||
void DrawSubsectorLights(subsector_t * sub, int pass);
|
void DrawSubsectorLights(subsector_t * sub, int pass);
|
||||||
void DrawSubsectors(int pass, bool istrans);
|
void DrawSubsectors(int pass, bool processlights, bool istrans);
|
||||||
|
void ProcessLights(bool istrans);
|
||||||
|
|
||||||
void PutFlat(bool fog = false);
|
void PutFlat(bool fog = false);
|
||||||
void Process(sector_t * model, int whichplane, bool notexture);
|
void Process(sector_t * model, int whichplane, bool notexture);
|
||||||
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
|
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
|
||||||
void ProcessSector(sector_t * frontsector);
|
void ProcessSector(sector_t * frontsector);
|
||||||
void Draw(int pass);
|
void Draw(int pass, bool trans);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1408,7 +1408,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg,sector_t * frontsector,sector_t * backse
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
{
|
{
|
||||||
vertex_t * v1, * v2;
|
vertex_t * v1, *v2;
|
||||||
fixed_t fch1;
|
fixed_t fch1;
|
||||||
fixed_t ffh1;
|
fixed_t ffh1;
|
||||||
fixed_t fch2;
|
fixed_t fch2;
|
||||||
|
@ -1437,24 +1437,24 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
{
|
{
|
||||||
// Need these for aligning the textures
|
// Need these for aligning the textures
|
||||||
realfront = §ors[frontsector->sectornum];
|
realfront = §ors[frontsector->sectornum];
|
||||||
realback = backsector? §ors[backsector->sectornum] : NULL;
|
realback = backsector ? §ors[backsector->sectornum] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg->sidedef == seg->linedef->sidedef[0])
|
if (seg->sidedef == seg->linedef->sidedef[0])
|
||||||
{
|
{
|
||||||
v1=seg->linedef->v1;
|
v1 = seg->linedef->v1;
|
||||||
v2=seg->linedef->v2;
|
v2 = seg->linedef->v2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v1=seg->linedef->v2;
|
v1 = seg->linedef->v2;
|
||||||
v2=seg->linedef->v1;
|
v2 = seg->linedef->v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||||
{
|
{
|
||||||
glseg.fracleft=0;
|
glseg.fracleft = 0;
|
||||||
glseg.fracright=1;
|
glseg.fracright = 1;
|
||||||
if (gl_seamless)
|
if (gl_seamless)
|
||||||
{
|
{
|
||||||
if (v1->dirty) gl_RecalcVertexHeights(v1);
|
if (v1->dirty) gl_RecalcVertexHeights(v1);
|
||||||
|
@ -1463,29 +1463,29 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
}
|
}
|
||||||
else // polyobjects must be rendered per seg.
|
else // polyobjects must be rendered per seg.
|
||||||
{
|
{
|
||||||
if (abs(v1->x-v2->x) > abs(v1->y-v2->y))
|
if (abs(v1->x - v2->x) > abs(v1->y - v2->y))
|
||||||
{
|
{
|
||||||
glseg.fracleft = float(seg->v1->x - v1->x)/float(v2->x-v1->x);
|
glseg.fracleft = float(seg->v1->x - v1->x) / float(v2->x - v1->x);
|
||||||
glseg.fracright = float(seg->v2->x - v1->x)/float(v2->x-v1->x);
|
glseg.fracright = float(seg->v2->x - v1->x) / float(v2->x - v1->x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glseg.fracleft = float(seg->v1->y - v1->y)/float(v2->y-v1->y);
|
glseg.fracleft = float(seg->v1->y - v1->y) / float(v2->y - v1->y);
|
||||||
glseg.fracright = float(seg->v2->y - v1->y)/float(v2->y-v1->y);
|
glseg.fracright = float(seg->v2->y - v1->y) / float(v2->y - v1->y);
|
||||||
}
|
}
|
||||||
v1=seg->v1;
|
v1 = seg->v1;
|
||||||
v2=seg->v2;
|
v2 = seg->v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vertexes[0]=v1;
|
vertexes[0] = v1;
|
||||||
vertexes[1]=v2;
|
vertexes[1] = v2;
|
||||||
|
|
||||||
glseg.x1= FIXED2FLOAT(v1->x);
|
glseg.x1 = FIXED2FLOAT(v1->x);
|
||||||
glseg.y1= FIXED2FLOAT(v1->y);
|
glseg.y1 = FIXED2FLOAT(v1->y);
|
||||||
glseg.x2= FIXED2FLOAT(v2->x);
|
glseg.x2 = FIXED2FLOAT(v2->x);
|
||||||
glseg.y2= FIXED2FLOAT(v2->y);
|
glseg.y2 = FIXED2FLOAT(v2->y);
|
||||||
Colormap=frontsector->ColorMap;
|
Colormap = frontsector->ColorMap;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
dynlightindex = UINT_MAX;
|
dynlightindex = UINT_MAX;
|
||||||
|
|
||||||
|
@ -1506,22 +1506,22 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
rellight = rel;
|
rellight = rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha=1.0f;
|
alpha = 1.0f;
|
||||||
RenderStyle=STYLE_Normal;
|
RenderStyle = STYLE_Normal;
|
||||||
gltexture=NULL;
|
gltexture = NULL;
|
||||||
|
|
||||||
topflat=frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because
|
topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because
|
||||||
bottomflat=frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy.
|
bottomflat = frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy.
|
||||||
topplane = frontsector->ceilingplane;
|
topplane = frontsector->ceilingplane;
|
||||||
bottomplane = frontsector->floorplane;
|
bottomplane = frontsector->floorplane;
|
||||||
|
|
||||||
// Save a little time (up to 0.3 ms per frame ;) )
|
// Save a little time (up to 0.3 ms per frame ;) )
|
||||||
if (frontsector->floorplane.a | frontsector->floorplane.b)
|
if (frontsector->floorplane.a | frontsector->floorplane.b)
|
||||||
{
|
{
|
||||||
ffh1=frontsector->floorplane.ZatPoint(v1);
|
ffh1 = frontsector->floorplane.ZatPoint(v1);
|
||||||
ffh2=frontsector->floorplane.ZatPoint(v2);
|
ffh2 = frontsector->floorplane.ZatPoint(v2);
|
||||||
zfloor[0]=FIXED2FLOAT(ffh1);
|
zfloor[0] = FIXED2FLOAT(ffh1);
|
||||||
zfloor[1]=FIXED2FLOAT(ffh2);
|
zfloor[1] = FIXED2FLOAT(ffh2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1531,10 +1531,10 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
|
|
||||||
if (frontsector->ceilingplane.a | frontsector->ceilingplane.b)
|
if (frontsector->ceilingplane.a | frontsector->ceilingplane.b)
|
||||||
{
|
{
|
||||||
fch1=frontsector->ceilingplane.ZatPoint(v1);
|
fch1 = frontsector->ceilingplane.ZatPoint(v1);
|
||||||
fch2=frontsector->ceilingplane.ZatPoint(v2);
|
fch2 = frontsector->ceilingplane.ZatPoint(v2);
|
||||||
zceil[0]= FIXED2FLOAT(fch1);
|
zceil[0] = FIXED2FLOAT(fch1);
|
||||||
zceil[1]= FIXED2FLOAT(fch2);
|
zceil[1] = FIXED2FLOAT(fch2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1543,27 +1543,27 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (seg->linedef->special==Line_Horizon)
|
if (seg->linedef->special == Line_Horizon)
|
||||||
{
|
{
|
||||||
SkyNormal(frontsector,v1,v2);
|
SkyNormal(frontsector, v1, v2);
|
||||||
DoHorizon(seg,frontsector, v1,v2);
|
DoHorizon(seg, frontsector, v1, v2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return;
|
//return;
|
||||||
// [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag
|
// [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag
|
||||||
if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED|ML_3DMIDTEX))) // one sided
|
if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED | ML_3DMIDTEX))) // one sided
|
||||||
{
|
{
|
||||||
// sector's sky
|
// sector's sky
|
||||||
SkyNormal(frontsector,v1,v2);
|
SkyNormal(frontsector, v1, v2);
|
||||||
|
|
||||||
// normal texture
|
// normal texture
|
||||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true);
|
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true);
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
DoTexture(RENDERWALL_M1S,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
DoTexture(RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||||
realfront->GetPlaneTexZ(sector_t::ceiling),realfront->GetPlaneTexZ(sector_t::floor), // must come from the original!
|
realfront->GetPlaneTexZ(sector_t::ceiling), realfront->GetPlaneTexZ(sector_t::floor), // must come from the original!
|
||||||
fch1,fch2,ffh1,ffh2,0);
|
fch1, fch2, ffh1, ffh2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // two sided
|
else // two sided
|
||||||
|
@ -1576,8 +1576,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
|
|
||||||
if (backsector->floorplane.a | backsector->floorplane.b)
|
if (backsector->floorplane.a | backsector->floorplane.b)
|
||||||
{
|
{
|
||||||
bfh1=backsector->floorplane.ZatPoint(v1);
|
bfh1 = backsector->floorplane.ZatPoint(v1);
|
||||||
bfh2=backsector->floorplane.ZatPoint(v2);
|
bfh2 = backsector->floorplane.ZatPoint(v2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1586,51 +1586,51 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
|
|
||||||
if (backsector->ceilingplane.a | backsector->ceilingplane.b)
|
if (backsector->ceilingplane.a | backsector->ceilingplane.b)
|
||||||
{
|
{
|
||||||
bch1=backsector->ceilingplane.ZatPoint(v1);
|
bch1 = backsector->ceilingplane.ZatPoint(v1);
|
||||||
bch2=backsector->ceilingplane.ZatPoint(v2);
|
bch2 = backsector->ceilingplane.ZatPoint(v2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bch1 = bch2 = backsector->ceilingplane.d;
|
bch1 = bch2 = backsector->ceilingplane.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkyTop(seg,frontsector,backsector,v1,v2);
|
SkyTop(seg, frontsector, backsector, v1, v2);
|
||||||
SkyBottom(seg,frontsector,backsector,v1,v2);
|
SkyBottom(seg, frontsector, backsector, v1, v2);
|
||||||
|
|
||||||
// upper texture
|
// upper texture
|
||||||
if (frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || backsector->GetTexture(sector_t::ceiling)!=skyflatnum)
|
if (frontsector->GetTexture(sector_t::ceiling) != skyflatnum || backsector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||||
{
|
{
|
||||||
fixed_t bch1a=bch1, bch2a=bch2;
|
fixed_t bch1a = bch1, bch2a = bch2;
|
||||||
if (frontsector->GetTexture(sector_t::floor)!=skyflatnum || backsector->GetTexture(sector_t::floor)!=skyflatnum)
|
if (frontsector->GetTexture(sector_t::floor) != skyflatnum || backsector->GetTexture(sector_t::floor) != skyflatnum)
|
||||||
{
|
{
|
||||||
// the back sector's floor obstructs part of this wall
|
// the back sector's floor obstructs part of this wall
|
||||||
if (ffh1>bch1 && ffh2>bch2)
|
if (ffh1 > bch1 && ffh2 > bch2)
|
||||||
{
|
{
|
||||||
bch2a=ffh2;
|
bch2a = ffh2;
|
||||||
bch1a=ffh1;
|
bch1a = ffh1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bch1a<fch1 || bch2a<fch2)
|
if (bch1a < fch1 || bch2a < fch2)
|
||||||
{
|
{
|
||||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
|
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0,
|
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
|
||||||
realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling),
|
realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling),
|
||||||
fch1,fch2,bch1a,bch2a,0);
|
fch1, fch2, bch1a, bch2a, 0);
|
||||||
}
|
}
|
||||||
else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b |
|
else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b |
|
||||||
backsector->ceilingplane.a | backsector->ceilingplane.b) &&
|
backsector->ceilingplane.a | backsector->ceilingplane.b) &&
|
||||||
frontsector->GetTexture(sector_t::ceiling)!=skyflatnum &&
|
frontsector->GetTexture(sector_t::ceiling) != skyflatnum &&
|
||||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum)
|
backsector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||||
{
|
{
|
||||||
gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), true);
|
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), true);
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0,
|
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
|
||||||
realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling),
|
realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling),
|
||||||
fch1,fch2,bch1a,bch2a,0);
|
fch1, fch2, bch1a, bch2a, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||||
|
@ -1650,7 +1650,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
{
|
{
|
||||||
tex = tex->GetRawTexture();
|
tex = tex->GetRawTexture();
|
||||||
}
|
}
|
||||||
gltexture=FMaterial::ValidateTexture(tex);
|
gltexture = FMaterial::ValidateTexture(tex);
|
||||||
}
|
}
|
||||||
else gltexture = NULL;
|
else gltexture = NULL;
|
||||||
|
|
||||||
|
@ -1662,46 +1662,46 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
|
|
||||||
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||||
{
|
{
|
||||||
DoFFloorBlocks(seg,frontsector,backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
DoFFloorBlocks(seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bottom texture */
|
/* bottom texture */
|
||||||
// the back sector's ceiling obstructs part of this wall (specially important for sky sectors)
|
// the back sector's ceiling obstructs part of this wall (specially important for sky sectors)
|
||||||
if (fch1<bfh1 && fch2<bfh2)
|
if (fch1<bfh1 && fch2<bfh2)
|
||||||
{
|
{
|
||||||
bfh1=fch1;
|
bfh1 = fch1;
|
||||||
bfh2=fch2;
|
bfh2 = fch2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bfh1>ffh1 || bfh2>ffh2)
|
if (bfh1>ffh1 || bfh2>ffh2)
|
||||||
{
|
{
|
||||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
|
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||||
realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor),
|
realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor),
|
||||||
bfh1,bfh2,ffh1,ffh2,
|
bfh1, bfh2, ffh1, ffh2,
|
||||||
frontsector->GetTexture(sector_t::ceiling)==skyflatnum && backsector->GetTexture(sector_t::ceiling)==skyflatnum ?
|
frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||||
realfront->GetPlaneTexZ(sector_t::floor)-realback->GetPlaneTexZ(sector_t::ceiling) :
|
realfront->GetPlaneTexZ(sector_t::floor) - realback->GetPlaneTexZ(sector_t::ceiling) :
|
||||||
realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling));
|
realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||||
}
|
}
|
||||||
else if ((frontsector->floorplane.a | frontsector->floorplane.b |
|
else if ((frontsector->floorplane.a | frontsector->floorplane.b |
|
||||||
backsector->floorplane.a | backsector->floorplane.b) &&
|
backsector->floorplane.a | backsector->floorplane.b) &&
|
||||||
frontsector->GetTexture(sector_t::floor)!=skyflatnum &&
|
frontsector->GetTexture(sector_t::floor) != skyflatnum &&
|
||||||
backsector->GetTexture(sector_t::floor)!=skyflatnum)
|
backsector->GetTexture(sector_t::floor) != skyflatnum)
|
||||||
{
|
{
|
||||||
// render it anyway with the sector's floor texture. With a background sky
|
// render it anyway with the sector's floor texture. With a background sky
|
||||||
// there are ugly holes otherwise and slopes are simply not precise enough
|
// there are ugly holes otherwise and slopes are simply not precise enough
|
||||||
// to mach in any case.
|
// to mach in any case.
|
||||||
gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
|
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||||
realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor),
|
realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor),
|
||||||
bfh1,bfh2,ffh1,ffh2, realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling));
|
bfh1, bfh2, ffh1, ffh2, realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (backsector->GetTexture(sector_t::floor)!=skyflatnum &&
|
else if (backsector->GetTexture(sector_t::floor) != skyflatnum &&
|
||||||
!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||||
{
|
{
|
||||||
gl_drawinfo->AddLowerMissingTexture(seg->sidedef, sub, bfh1);
|
gl_drawinfo->AddLowerMissingTexture(seg->sidedef, sub, bfh1);
|
||||||
|
@ -1717,19 +1717,19 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
{
|
{
|
||||||
if (frontsector->GetTexture(sector_t::floor)==skyflatnum) return;
|
if (frontsector->GetTexture(sector_t::floor) == skyflatnum) return;
|
||||||
|
|
||||||
fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor);
|
fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor);
|
||||||
fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor);
|
fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor);
|
||||||
if (bfh>ffh)
|
if (bfh > ffh)
|
||||||
{
|
{
|
||||||
this->seg = seg;
|
this->seg = seg;
|
||||||
this->sub = NULL;
|
this->sub = NULL;
|
||||||
|
|
||||||
vertex_t * v1=seg->v1;
|
vertex_t * v1 = seg->v1;
|
||||||
vertex_t * v2=seg->v2;
|
vertex_t * v2 = seg->v2;
|
||||||
vertexes[0]=v1;
|
vertexes[0] = v1;
|
||||||
vertexes[1]=v2;
|
vertexes[1] = v2;
|
||||||
|
|
||||||
glseg.x1 = FIXED2FLOAT(v1->x);
|
glseg.x1 = FIXED2FLOAT(v1->x);
|
||||||
glseg.y1 = FIXED2FLOAT(v1->y);
|
glseg.y1 = FIXED2FLOAT(v1->y);
|
||||||
|
@ -1761,7 +1761,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
|
||||||
if (gltexture)
|
if (gltexture)
|
||||||
{
|
{
|
||||||
FTexCoordInfo tci;
|
FTexCoordInfo tci;
|
||||||
type=RENDERWALL_BOTTOM;
|
type = RENDERWALL_BOTTOM;
|
||||||
gltexture->GetTexCoordInfo(&tci, FRACUNIT, FRACUNIT);
|
gltexture->GetTexCoordInfo(&tci, FRACUNIT, FRACUNIT);
|
||||||
SetWallCoordinates(seg, &tci, FIXED2FLOAT(bfh), bfh, bfh, ffh, ffh, 0);
|
SetWallCoordinates(seg, &tci, FIXED2FLOAT(bfh), bfh, bfh, ffh, ffh, 0);
|
||||||
PutWall(false);
|
PutWall(false);
|
||||||
|
|
|
@ -70,8 +70,19 @@ EXTERN_CVAR(Bool, gl_seamless)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
FDynLightData lightdata;
|
FDynLightData lightdata;
|
||||||
|
|
||||||
|
|
||||||
void GLWall::SetupLights()
|
void GLWall::SetupLights()
|
||||||
{
|
{
|
||||||
|
// check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.)
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case RENDERWALL_FOGBOUNDARY:
|
||||||
|
case RENDERWALL_MIRRORSURFACE:
|
||||||
|
case RENDERWALL_COLOR:
|
||||||
|
case RENDERWALL_COLORLAYER:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2};
|
float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2};
|
||||||
Plane p;
|
Plane p;
|
||||||
|
|
||||||
|
@ -357,7 +368,7 @@ void GLWall::Draw(int pass)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (type == RENDERWALL_COLORLAYER)
|
if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(-1.0f, -128.0f);
|
glPolygonOffset(-1.0f, -128.0f);
|
||||||
|
@ -365,10 +376,14 @@ void GLWall::Draw(int pass)
|
||||||
|
|
||||||
switch (pass)
|
switch (pass)
|
||||||
{
|
{
|
||||||
case GLPASS_ALL: // Single-pass rendering
|
case GLPASS_LIGHTSONLY:
|
||||||
|
SetupLights();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GLPASS_ALL:
|
||||||
SetupLights();
|
SetupLights();
|
||||||
// fall through
|
// fall through
|
||||||
case GLPASS_PLAIN: // Single-pass rendering
|
case GLPASS_PLAIN:
|
||||||
rel = rellight + getExtraLight();
|
rel = rellight + getExtraLight();
|
||||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
|
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||||
|
@ -409,7 +424,7 @@ void GLWall::Draw(int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == RENDERWALL_COLORLAYER)
|
if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY)
|
||||||
{
|
{
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
glPolygonOffset(0, 0);
|
glPolygonOffset(0, 0);
|
||||||
|
|
Loading…
Reference in a new issue