Enabled MSAA
This commit is contained in:
parent
4fd3e9c437
commit
1de2691f33
|
@ -2,20 +2,22 @@
|
|||
#include <Common/Log.h>
|
||||
|
||||
CFramebuffer::CFramebuffer()
|
||||
: mInitialized(false)
|
||||
: mpRenderbuffer(nullptr)
|
||||
, mpTexture(nullptr)
|
||||
, mWidth(0)
|
||||
, mHeight(0)
|
||||
, mpRenderbuffer(nullptr)
|
||||
, mpTexture(nullptr)
|
||||
, mEnableMultisampling(false)
|
||||
, mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
CFramebuffer::CFramebuffer(u32 Width, u32 Height)
|
||||
: mInitialized(false)
|
||||
: mpRenderbuffer(nullptr)
|
||||
, mpTexture(nullptr)
|
||||
, mWidth(0)
|
||||
, mHeight(0)
|
||||
, mpRenderbuffer(nullptr)
|
||||
, mpTexture(nullptr)
|
||||
, mEnableMultisampling(false)
|
||||
, mInitialized(false)
|
||||
{
|
||||
Resize(Width, Height);
|
||||
}
|
||||
|
@ -44,30 +46,18 @@ void CFramebuffer::Init()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
|
||||
mpRenderbuffer = new CRenderbuffer(mWidth, mHeight);
|
||||
mpRenderbuffer->Bind();
|
||||
glFramebufferRenderbuffer(
|
||||
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mpRenderbuffer->BufferID()
|
||||
);
|
||||
|
||||
mpTexture = new CTexture(mWidth, mHeight);
|
||||
mpTexture->Bind(0);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpTexture->TextureID(), 0
|
||||
);
|
||||
|
||||
mStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (mStatus != GL_FRAMEBUFFER_COMPLETE)
|
||||
Log::Error("Framebuffer not complete");
|
||||
|
||||
mpRenderbuffer->SetMultisamplingEnabled(mEnableMultisampling);
|
||||
mpTexture->SetMultisamplingEnabled(mEnableMultisampling);
|
||||
InitBuffers();
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CFramebuffer::Bind()
|
||||
void CFramebuffer::Bind(GLenum Target /*= GL_FRAMEBUFFER*/)
|
||||
{
|
||||
if (!mInitialized) Init();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
glBindFramebuffer(Target, mFramebuffer);
|
||||
}
|
||||
|
||||
void CFramebuffer::Resize(u32 Width, u32 Height)
|
||||
|
@ -81,30 +71,51 @@ void CFramebuffer::Resize(u32 Width, u32 Height)
|
|||
{
|
||||
mpRenderbuffer->Resize(Width, Height);
|
||||
mpTexture->Resize(Width, Height);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
mpRenderbuffer->Bind();
|
||||
glFramebufferRenderbuffer(
|
||||
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mpRenderbuffer->BufferID()
|
||||
);
|
||||
|
||||
mpTexture->Bind(0);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpTexture->TextureID(), 0
|
||||
);
|
||||
InitBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CTexture* CFramebuffer::Texture()
|
||||
void CFramebuffer::SetMultisamplingEnabled(bool Enable)
|
||||
{
|
||||
return mpTexture;
|
||||
if (mEnableMultisampling != Enable)
|
||||
{
|
||||
mEnableMultisampling = Enable;
|
||||
|
||||
if (mInitialized)
|
||||
{
|
||||
mpRenderbuffer->SetMultisamplingEnabled(Enable);
|
||||
mpTexture->SetMultisamplingEnabled(Enable);
|
||||
InitBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************ PROTECTED ************
|
||||
void CFramebuffer::InitBuffers()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
|
||||
mpRenderbuffer->Bind();
|
||||
glFramebufferRenderbuffer(
|
||||
GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mpRenderbuffer->BufferID()
|
||||
);
|
||||
|
||||
mpTexture->Bind(0);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, (mEnableMultisampling ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D), mpTexture->TextureID(), 0
|
||||
);
|
||||
|
||||
mStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (mStatus != GL_FRAMEBUFFER_COMPLETE)
|
||||
Log::Error("Framebuffer not complete; error " + TString::HexString((u32) mStatus, 0));
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
void CFramebuffer::BindDefaultFramebuffer()
|
||||
void CFramebuffer::BindDefaultFramebuffer(GLenum Target /*= GL_FRAMEBUFFER*/)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, smDefaultFramebuffer);
|
||||
glBindFramebuffer(Target, smDefaultFramebuffer);
|
||||
}
|
||||
|
||||
GLint CFramebuffer::smDefaultFramebuffer;
|
||||
|
|
|
@ -11,6 +11,7 @@ class CFramebuffer
|
|||
CRenderbuffer *mpRenderbuffer;
|
||||
CTexture *mpTexture;
|
||||
u32 mWidth, mHeight;
|
||||
bool mEnableMultisampling;
|
||||
bool mInitialized;
|
||||
GLenum mStatus;
|
||||
|
||||
|
@ -22,11 +23,18 @@ public:
|
|||
CFramebuffer(u32 Width, u32 Height);
|
||||
~CFramebuffer();
|
||||
void Init();
|
||||
void Bind();
|
||||
void Bind(GLenum Target = GL_FRAMEBUFFER);
|
||||
void Resize(u32 Width, u32 Height);
|
||||
CTexture* Texture();
|
||||
static void BindDefaultFramebuffer();
|
||||
void SetMultisamplingEnabled(bool Enable);
|
||||
|
||||
// Accessors
|
||||
inline CTexture* Texture() const { return mpTexture; }
|
||||
|
||||
// Static
|
||||
static void BindDefaultFramebuffer(GLenum Target = GL_FRAMEBUFFER);
|
||||
|
||||
protected:
|
||||
void InitBuffers();
|
||||
};
|
||||
|
||||
#endif // CFRAMEBUFFER_H
|
||||
|
|
|
@ -8,20 +8,23 @@ class CRenderbuffer
|
|||
{
|
||||
GLuint mRenderbuffer;
|
||||
u32 mWidth, mHeight;
|
||||
bool mEnableMultisampling;
|
||||
bool mInitialized;
|
||||
|
||||
public:
|
||||
CRenderbuffer::CRenderbuffer()
|
||||
: mInitialized(false)
|
||||
, mWidth(0)
|
||||
: mWidth(0)
|
||||
, mHeight(0)
|
||||
, mEnableMultisampling(false)
|
||||
, mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
CRenderbuffer::CRenderbuffer(u32 Width, u32 Height)
|
||||
: mInitialized(false)
|
||||
, mWidth(Width)
|
||||
: mWidth(Width)
|
||||
, mHeight(Height)
|
||||
, mEnableMultisampling(false)
|
||||
, mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -33,10 +36,9 @@ public:
|
|||
|
||||
void CRenderbuffer::Init()
|
||||
{
|
||||
glGenRenderbuffers(1, &mRenderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||
mInitialized = true;
|
||||
glGenRenderbuffers(1, &mRenderbuffer);
|
||||
InitStorage();
|
||||
}
|
||||
|
||||
inline void CRenderbuffer::Resize(u32 Width, u32 Height)
|
||||
|
@ -45,10 +47,7 @@ public:
|
|||
mHeight = Height;
|
||||
|
||||
if (mInitialized)
|
||||
{
|
||||
Bind();
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||
}
|
||||
InitStorage();
|
||||
}
|
||||
|
||||
inline void CRenderbuffer::Bind()
|
||||
|
@ -66,6 +65,26 @@ public:
|
|||
{
|
||||
return mRenderbuffer;
|
||||
}
|
||||
|
||||
inline void SetMultisamplingEnabled(bool Enable)
|
||||
{
|
||||
if (mEnableMultisampling != Enable)
|
||||
{
|
||||
mEnableMultisampling = Enable;
|
||||
InitStorage();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void InitStorage()
|
||||
{
|
||||
Bind();
|
||||
|
||||
if (mEnableMultisampling)
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||
else
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRENDERBUFFER_H
|
||||
|
|
|
@ -176,6 +176,11 @@ void CRenderer::RenderBloom()
|
|||
CGraphics::SetIdentityMVP();
|
||||
CGraphics::UpdateMVPBlock();
|
||||
|
||||
mPostProcessFramebuffer.Resize(mViewportWidth, mViewportHeight);
|
||||
mSceneFramebuffer.Bind(GL_READ_FRAMEBUFFER);
|
||||
mPostProcessFramebuffer.Bind(GL_DRAW_FRAMEBUFFER);
|
||||
glBlitFramebuffer(0, 0, mViewportWidth, mViewportHeight, 0, 0, mViewportWidth, mViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Pass 1: Alpha-blend the scene texture on a black background
|
||||
mBloomFramebuffers[0].Resize(BloomWidth, BloomHeight);
|
||||
mBloomFramebuffers[0].Bind();
|
||||
|
@ -183,7 +188,7 @@ void CRenderer::RenderBloom()
|
|||
|
||||
CDrawUtil::UseTextureShader();
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
|
||||
mSceneFramebuffer.Texture()->Bind(0);
|
||||
mPostProcessFramebuffer.Texture()->Bind(0);
|
||||
CDrawUtil::DrawSquare();
|
||||
|
||||
// Pass 2: Horizontal blur
|
||||
|
@ -226,7 +231,7 @@ void CRenderer::RenderBloom()
|
|||
}
|
||||
|
||||
// Render result onto main scene framebuffer
|
||||
mSceneFramebuffer.Bind();
|
||||
mPostProcessFramebuffer.Bind();
|
||||
glViewport(0, 0, mViewportWidth, mViewportHeight);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
|
||||
|
@ -247,6 +252,11 @@ void CRenderer::RenderBloom()
|
|||
CDrawUtil::DrawSquare();
|
||||
}
|
||||
|
||||
// Copy framebuffer back into the scene framebuffer for more rendering
|
||||
mPostProcessFramebuffer.Bind(GL_READ_FRAMEBUFFER);
|
||||
mSceneFramebuffer.Bind(GL_DRAW_FRAMEBUFFER);
|
||||
glBlitFramebuffer(0, 0, mViewportWidth, mViewportHeight, 0, 0, mViewportWidth, mViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Clean up
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
@ -310,6 +320,7 @@ void CRenderer::BeginFrame()
|
|||
CGraphics::SetActiveContext(mContextIndex);
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mDefaultFramebuffer);
|
||||
|
||||
mSceneFramebuffer.SetMultisamplingEnabled(true);
|
||||
mSceneFramebuffer.Resize(mViewportWidth, mViewportHeight);
|
||||
mSceneFramebuffer.Bind();
|
||||
|
||||
|
@ -320,23 +331,11 @@ void CRenderer::BeginFrame()
|
|||
|
||||
void CRenderer::EndFrame()
|
||||
{
|
||||
// Render result to screen
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mDefaultFramebuffer);
|
||||
InitFramebuffer();
|
||||
// Copy result to the backbuffer
|
||||
mSceneFramebuffer.Bind(GL_READ_FRAMEBUFFER);
|
||||
CFramebuffer::BindDefaultFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||
glViewport(0, 0, mViewportWidth, mViewportHeight);
|
||||
|
||||
CGraphics::SetIdentityMVP();
|
||||
CGraphics::UpdateMVPBlock();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
CDrawUtil::UseTextureShader();
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
mSceneFramebuffer.Texture()->Bind(0);
|
||||
CDrawUtil::DrawSquare();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glBlitFramebuffer(0, 0, mViewportWidth, mViewportHeight, 0, 0, mViewportWidth, mViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
gDrawCount = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ private:
|
|||
float mBloomHScale, mBloomVScale;
|
||||
|
||||
CFramebuffer mSceneFramebuffer;
|
||||
CFramebuffer mPostProcessFramebuffer;
|
||||
CFramebuffer mBloomFramebuffers[3];
|
||||
GLint mDefaultFramebuffer;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ CTexture::CTexture(CResourceEntry *pEntry /*= 0*/)
|
|||
, mHeight(0)
|
||||
, mNumMipMaps(0)
|
||||
, mLinearSize(0)
|
||||
, mEnableMultisampling(false)
|
||||
, mBufferExists(false)
|
||||
, mpImgDataBuffer(nullptr)
|
||||
, mImgDataSize(0)
|
||||
|
@ -22,6 +23,7 @@ CTexture::CTexture(u32 Width, u32 Height)
|
|||
, mHeight((u16) Height)
|
||||
, mNumMipMaps(1)
|
||||
, mLinearSize(Width * Height * 4)
|
||||
, mEnableMultisampling(false)
|
||||
, mBufferExists(false)
|
||||
, mpImgDataBuffer(nullptr)
|
||||
, mImgDataSize(0)
|
||||
|
@ -36,8 +38,9 @@ CTexture::~CTexture()
|
|||
|
||||
bool CTexture::BufferGL()
|
||||
{
|
||||
GLenum BindTarget = (mEnableMultisampling ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D);
|
||||
glGenTextures(1, &mTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
glBindTexture(BindTarget, mTextureID);
|
||||
|
||||
GLenum GLFormat, GLType;
|
||||
bool IsCompressed = false;
|
||||
|
@ -81,9 +84,14 @@ bool CTexture::BufferGL()
|
|||
GLvoid *pData = (mBufferExists) ? (mpImgDataBuffer + MipOffset) : NULL;
|
||||
|
||||
if (!IsCompressed)
|
||||
glTexImage2D(GL_TEXTURE_2D, iMip, GLFormat, MipW, MipH, 0, GLFormat, GLType, pData);
|
||||
{
|
||||
if (mEnableMultisampling)
|
||||
glTexImage2DMultisample(BindTarget, 4, GLFormat, MipW, MipH, true);
|
||||
else
|
||||
glTexImage2D(BindTarget, iMip, GLFormat, MipW, MipH, 0, GLFormat, GLType, pData);
|
||||
}
|
||||
else
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, iMip, GLFormat, MipW, MipH, 0, MipSize, pData);
|
||||
glCompressedTexImage2D(BindTarget, iMip, GLFormat, MipW, MipH, 0, MipSize, pData);
|
||||
|
||||
MipW /= 2;
|
||||
MipH /= 2;
|
||||
|
@ -91,17 +99,17 @@ bool CTexture::BufferGL()
|
|||
MipSize /= 4;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mNumMipMaps - 1);
|
||||
glTexParameteri(BindTarget, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(BindTarget, GL_TEXTURE_MAX_LEVEL, mNumMipMaps - 1);
|
||||
|
||||
// Linear filtering on mipmaps:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(BindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(BindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
// Anisotropic filtering:
|
||||
float MaxAnisotropy;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &MaxAnisotropy);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MaxAnisotropy);
|
||||
glTexParameterf(BindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, MaxAnisotropy);
|
||||
|
||||
mGLBufferExists = true;
|
||||
return true;
|
||||
|
@ -114,7 +122,8 @@ void CTexture::Bind(u32 GLTextureUnit)
|
|||
if (!mGLBufferExists)
|
||||
BufferGL();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
GLenum BindTarget = (mEnableMultisampling ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D);
|
||||
glBindTexture(BindTarget, mTextureID);
|
||||
}
|
||||
|
||||
void CTexture::Resize(u32 Width, u32 Height)
|
||||
|
@ -323,13 +332,14 @@ void CTexture::CopyGLBuffer()
|
|||
u32 MipW = mWidth, MipH = mHeight, MipOffset = 0;
|
||||
float BytesPerPixel = FormatBPP(mTexelFormat) / 8.f;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
GLenum BindTarget = (mEnableMultisampling ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D);
|
||||
glBindTexture(BindTarget, mTextureID);
|
||||
|
||||
for (u32 iMip = 0; iMip < mNumMipMaps; iMip++)
|
||||
{
|
||||
void *pData = mpImgDataBuffer + MipOffset;
|
||||
|
||||
glGetTexImage(GL_TEXTURE_2D, iMip, GL_RGBA, GL_UNSIGNED_BYTE, pData);
|
||||
glGetTexImage(BindTarget, iMip, GL_RGBA, GL_UNSIGNED_BYTE, pData);
|
||||
|
||||
MipOffset += (u32) (MipW * MipH * BytesPerPixel);
|
||||
MipW /= 2;
|
||||
|
|
|
@ -21,9 +21,10 @@ class CTexture : public CResource
|
|||
u32 mNumMipMaps; // The number of mipmaps this texture has
|
||||
u32 mLinearSize; // The size of the top level mipmap, in bytes
|
||||
|
||||
bool mBufferExists; // Indicates whether image data buffer has valid data
|
||||
u8 *mpImgDataBuffer; // Pointer to image data buffer
|
||||
u32 mImgDataSize; // Size of image data buffer
|
||||
bool mEnableMultisampling; // Whether multisample should be enabled (if this texture is a render target).
|
||||
bool mBufferExists; // Indicates whether image data buffer has valid data
|
||||
u8 *mpImgDataBuffer; // Pointer to image data buffer
|
||||
u32 mImgDataSize; // Size of image data buffer
|
||||
|
||||
bool mGLBufferExists; // Indicates whether GL buffer has valid data
|
||||
GLuint mTextureID; // ID for texture GL buffer
|
||||
|
@ -39,7 +40,7 @@ public:
|
|||
float ReadTexelAlpha(const CVector2f& rkTexCoord);
|
||||
bool WriteDDS(IOutputStream& rOut);
|
||||
|
||||
// Getters
|
||||
// Accessors
|
||||
ETexelFormat TexelFormat() const { return mTexelFormat; }
|
||||
ETexelFormat SourceTexelFormat() const { return mSourceTexelFormat; }
|
||||
u32 Width() const { return (u32) mWidth; }
|
||||
|
@ -47,6 +48,14 @@ public:
|
|||
u32 NumMipMaps() const { return mNumMipMaps; }
|
||||
GLuint TextureID() const { return mTextureID; }
|
||||
|
||||
inline void SetMultisamplingEnabled(bool Enable)
|
||||
{
|
||||
if (mEnableMultisampling != Enable)
|
||||
DeleteBuffers();
|
||||
|
||||
mEnableMultisampling = Enable;
|
||||
}
|
||||
|
||||
// Static
|
||||
static u32 FormatBPP(ETexelFormat Format);
|
||||
|
||||
|
|
|
@ -32,12 +32,13 @@ void CBasicViewport::initializeGL()
|
|||
CGraphics::Initialize();
|
||||
|
||||
// Setting various GL flags
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(0xFFFF);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(0xFFFF);
|
||||
glPolygonOffset(1.f, 5.f);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
// Clear cached material
|
||||
CMaterial::KillCachedMaterial();
|
||||
|
|
Loading…
Reference in New Issue