Exemple #1
0
    void Node::MarkAsDirty(bool recursive, bool scaleChange)
    {
        dirty_ = true;
        SetUniformsNeedUpdate();
        OnDirty();

        if (scaleChange)
            OnScaleChange();

        if (recursive)
            for (auto child : children_)
                child->MarkAsDirty(recursive, scaleChange);
    }
Exemple #2
0
bool GDocApp<OptionsFmt>::SetDirty(bool Dirty)
{
	if (IsAttached() && (d->Dirty ^ Dirty))
	{
		// Changing...
		if (Dirty)
		{
			// Setting dirty
			d->Dirty = true;
			SetCurFile(d->CurFile);
		}
		else
		{
			// Clearing dirty
			int Result = LgiMsg(this,
								LgiLoadString(L_DOCAPP_SAVE_CHANGE, "Do you want to save your changes?"),
								d->AppName,
								MB_YESNOCANCEL);
			if (Result == IDYES)
			{
				if (!ValidStr(d->CurFile))
				{
					GMru::OnCommand(IDM_SAVEAS);
				}
				else
				{
					_SaveFile(d->CurFile);
				}
			}
			else if (Result == IDCANCEL)
			{
				return false;
			}

			d->Dirty = false;
			SetCurFile(d->CurFile);
		}

		OnDirty(d->Dirty);
	}

	return true;
}
Exemple #3
0
bool GDocApp<OptionsFmt>::_SaveFile(char *File)
{
	char RealPath[256];
	if (ResolveShortcut(File, RealPath, sizeof(RealPath)))
	{
		File = RealPath;
	}
	else
	{
		strcpy_s(RealPath, sizeof(RealPath), File);
	}

	bool Status = GMru::_SaveFile(RealPath);
	if (Status)
	{
		d->Dirty = false;
		SetCurFile(RealPath);
		OnDirty(d->Dirty);
	}

	return Status;
}
/**
*  @brief
*    Constructor of SPK_PLQuadRendererShaders
*/
SPK_PLQuadRendererShaders::SPK_PLQuadRendererShaders(PLRenderer::Renderer &cRenderer, const String &sShaderLanguage, float fScaleX, float fScaleY) : SPK_PLQuadRenderer(cRenderer, fScaleX, fScaleY),
	m_pEventHandlerDirty(new PLCore::EventHandler<PLRenderer::Program*>(&SPK_PLQuadRendererShaders::OnDirty, this)),
	m_sShaderLanguage(sShaderLanguage),
	m_pVertexShader(nullptr),
	m_pFragmentShader(nullptr),
	m_pProgram(nullptr),
	m_pPositionProgramAttribute(nullptr),
	m_pTexCoordProgramAttribute(nullptr),
	m_pColorProgramAttribute(nullptr),
	m_pObjectSpaceToClipSpaceMatrixProgramUniform(nullptr),
	m_pTextureMapProgramUniform(nullptr)
{
	// Get the shader language to use
	if (!m_sShaderLanguage.GetLength())
		m_sShaderLanguage = cRenderer.GetDefaultShaderLanguage();

	// Create the GPU program right now?
	if (!m_pProgram || m_pProgram->GetShaderLanguage() != m_sShaderLanguage) {
		// If there's an previous instance of the program, destroy it first
		if (m_pProgram) {
			delete m_pProgram;
			m_pProgram = nullptr;
		}
		if (m_pFragmentShader) {
			delete m_pFragmentShader;
			m_pFragmentShader = nullptr;
		}
		if (m_pVertexShader) {
			delete m_pVertexShader;
			m_pVertexShader = nullptr;
		}
		m_pPositionProgramAttribute						= nullptr;
		m_pTexCoordProgramAttribute						= nullptr;
		m_pColorProgramAttribute						= nullptr;
		m_pObjectSpaceToClipSpaceMatrixProgramUniform	= nullptr;
		m_pTextureMapProgramUniform						= nullptr;

		// Get the shader language instance
		PLRenderer::ShaderLanguage *pShaderLanguage = cRenderer.GetShaderLanguage(m_sShaderLanguage);
		if (pShaderLanguage) {
			// Shader source code
			String sVertexShaderSourceCode;
			String sFragmentShaderSourceCode;
			if (m_sShaderLanguage == "GLSL") {
				#include "SPK_PLQuadRendererShaders_GLSL.h"
				if (cRenderer.GetAPI() == "OpenGL ES 2.0") {
					// Get shader source codes
					sVertexShaderSourceCode   = "#version 100\n" + sSPK_PLQuadRendererShaders_GLSL_VS;
					sFragmentShaderSourceCode = "#version 100\n" + sSPK_PLQuadRendererShaders_GLSL_FS;
				} else {
					// Remove precision qualifiers so that we're able to use 110 (OpenGL 2.0 shaders) instead of 130 (OpenGL 3.0 shaders,
					// with this version we can keep the precision qualifiers) so that this shader requirements are as low as possible
					sVertexShaderSourceCode   = "#version 110\n" + Shader::RemovePrecisionQualifiersFromGLSL(sSPK_PLQuadRendererShaders_GLSL_VS);
					sFragmentShaderSourceCode = "#version 110\n" + Shader::RemovePrecisionQualifiersFromGLSL(sSPK_PLQuadRendererShaders_GLSL_FS);
				}
			} else if (m_sShaderLanguage == "Cg") {
				#include "SPK_PLQuadRendererShaders_Cg.h"
				sVertexShaderSourceCode   = sSPK_PLQuadRendererShaders_Cg_VS;
				sFragmentShaderSourceCode = sSPK_PLQuadRendererShaders_Cg_FS;
			}

			// Create a vertex shader instance
			m_pVertexShader = pShaderLanguage->CreateVertexShader(sVertexShaderSourceCode, "arbvp1");

			// Create a fragment shader instance
			m_pFragmentShader = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode, "arbfp1");

			// Create a program instance and assign the created vertex and fragment shaders to it
			m_pProgram = pShaderLanguage->CreateProgram(m_pVertexShader, m_pFragmentShader);
			if (m_pProgram) {
				// Add our nark which will inform us as soon as the program gets dirty
				m_pProgram->EventDirty.Connect(*m_pEventHandlerDirty);

				// Get attributes and uniforms
				OnDirty(m_pProgram);
			}
		}
	}
}
/**
*  @brief
*    Calculates the logarithmic average luminance
*/
void HDRAverageLuminance::CalculateAverageLuminance(const String &sShaderLanguage, TextureBufferRectangle &cOriginalTexture, const Color3 &cLuminanceConvert)
{
	// Get the internal texture format to use
	const TextureBuffer::EPixelFormat nInternalFormat = (cOriginalTexture.GetFormat() == TextureBuffer::R16G16B16A16F) ? TextureBuffer::L16F : TextureBuffer::L32F;

	// Get the shader language to use
	String sUsedShaderLanguage = sShaderLanguage;
	if (!sUsedShaderLanguage.GetLength())
		sUsedShaderLanguage = m_pRenderer->GetDefaultShaderLanguage();

	// Create the shaders and programs right now?
	if (!m_pVertexShader || m_pVertexShader->GetShaderLanguage() != sUsedShaderLanguage) {
		// If there's an previous instance of the program, destroy it first
		if (m_pDownsampleLogProgram) {
			delete m_pDownsampleLogProgram;
			m_pDownsampleLogProgram = nullptr;
		}
		if (m_pDownsampleLogFragmentShader) {
			delete m_pDownsampleLogFragmentShader;
			m_pDownsampleLogFragmentShader = nullptr;
		}
		if (m_pDownsampleProgram) {
			delete m_pDownsampleProgram;
			m_pDownsampleProgram = nullptr;
		}
		if (m_pDownsampleFragmentShader) {
			delete m_pDownsampleFragmentShader;
			m_pDownsampleFragmentShader = nullptr;
		}
		if (m_pDownsampleVertexShader) {
			delete m_pDownsampleVertexShader;
			m_pDownsampleVertexShader = nullptr;
		}
		if (m_pDownsampleExpProgram) {
			delete m_pDownsampleExpProgram;
			m_pDownsampleExpProgram = nullptr;
		}
		if (m_pDownsampleExpFragmentShader) {
			delete m_pDownsampleExpFragmentShader;
			m_pDownsampleExpFragmentShader = nullptr;
		}
		if (m_pVertexShader) {
			delete m_pVertexShader;
			m_pVertexShader = nullptr;
		}
		m_pDownsampleLogPositionProgramAttribute		= nullptr;
		m_pDownsampleLogTextureSizeProgramUniform		= nullptr;
		m_pDownsampleLogTextureProgramUniform			= nullptr;
		m_pDownsampleLogLuminanceConvertProgramUniform	= nullptr;
		m_pDownsampleLogEpsilonProgramUniform			= nullptr;
		m_pDownsamplePositionProgramAttribute			= nullptr;
		m_pDownsampleTextureSizeProgramUniform			= nullptr;
		m_pDownsampleSizeProgramUniform					= nullptr;
		m_pDownsampleTextureProgramUniform				= nullptr;
		m_pDownsampleExpPositionProgramAttribute		= nullptr;
		m_pDownsampleExpTextureSizeProgramUniform		= nullptr;
		m_pDownsampleExpTextureProgramUniform			= nullptr;

		// Get the shader language instance
		ShaderLanguage *pShaderLanguage = m_pRenderer->GetShaderLanguage(sUsedShaderLanguage);
		if (pShaderLanguage) {
			// Shader source code
			String sVertexShaderSourceCode;
			String sVertexShaderSourceCode_Downsample;
			String sFragmentShaderSourceCode_DownsampleLog;
			String sFragmentShaderSourceCode_Downsample;
			String sFragmentShaderSourceCode_DownsampleExp;
			if (sUsedShaderLanguage == "GLSL") {
				#include "HDRAverageLuminance_GLSL.h"
				sVertexShaderSourceCode					= sHDRAverageLuminance_GLSL_VS;
				sVertexShaderSourceCode_Downsample		= sHDRAverageLuminance_GLSL_VS_Downsample;
				sFragmentShaderSourceCode_DownsampleLog	= sHDRAverageLuminance_GLSL_FS_Common + sHDRAverageLuminance_GLSL_FS_DownsampleLog;
				sFragmentShaderSourceCode_Downsample	= sHDRAverageLuminance_GLSL_FS_Common + sHDRAverageLuminance_GLSL_FS_Downsample;
				sFragmentShaderSourceCode_DownsampleExp	= sHDRAverageLuminance_GLSL_FS_Common + sHDRAverageLuminance_GLSL_FS_DownsampleExp;
			} else if (sUsedShaderLanguage == "Cg") {
				#include "HDRAverageLuminance_Cg.h"
				sVertexShaderSourceCode					= sHDRAverageLuminance_Cg_VS;
				sVertexShaderSourceCode_Downsample		= sHDRAverageLuminance_Cg_VS_Downsample;
				sFragmentShaderSourceCode_DownsampleLog	= sHDRAverageLuminance_Cg_FS_Common + sHDRAverageLuminance_Cg_FS_DownsampleLog;
				sFragmentShaderSourceCode_Downsample	= sHDRAverageLuminance_Cg_FS_Common + sHDRAverageLuminance_Cg_FS_Downsample;
				sFragmentShaderSourceCode_DownsampleExp	= sHDRAverageLuminance_Cg_FS_Common + sHDRAverageLuminance_Cg_FS_DownsampleExp;
			}

			// Create a vertex shader instance
			m_pVertexShader           = pShaderLanguage->CreateVertexShader(sVertexShaderSourceCode);
			m_pDownsampleVertexShader = pShaderLanguage->CreateVertexShader(sVertexShaderSourceCode_Downsample);

			// Create a fragment shader instance
			m_pDownsampleLogFragmentShader = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode_DownsampleLog);
			m_pDownsampleFragmentShader    = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode_Downsample);
			m_pDownsampleExpFragmentShader = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode_DownsampleExp);

			// Create a program instance and assign the created vertex and fragment shaders to it
			m_pDownsampleLogProgram = pShaderLanguage->CreateProgram(m_pVertexShader, m_pDownsampleLogFragmentShader);
			if (m_pDownsampleLogProgram) {
				// Add our nark which will inform us as soon as the program gets dirty
				m_pDownsampleLogProgram->EventDirty.Connect(EventHandlerDirty);

				// Get attributes and uniforms
				OnDirty(m_pDownsampleLogProgram);
			}
			m_pDownsampleProgram = pShaderLanguage->CreateProgram(m_pDownsampleVertexShader, m_pDownsampleFragmentShader);
			if (m_pDownsampleProgram) {
				// Add our nark which will inform us as soon as the program gets dirty
				m_pDownsampleProgram->EventDirty.Connect(EventHandlerDirty);

				// Get attributes and uniforms
				OnDirty(m_pDownsampleProgram);
			}
			m_pDownsampleExpProgram = pShaderLanguage->CreateProgram(m_pVertexShader, m_pDownsampleExpFragmentShader);
			if (m_pDownsampleExpProgram) {
				// Add our nark which will inform us as soon as the program gets dirty
				m_pDownsampleExpProgram->EventDirty.Connect(EventHandlerDirty);

				// Get attributes and uniforms
				OnDirty(m_pDownsampleExpProgram);
			}
		}
	}

	// Create the fullscreen quad instance if required
	if (!m_pFullscreenQuad)
		m_pFullscreenQuad = new FullscreenQuad(*m_pRenderer);

	// Get the vertex buffer of the fullscreen quad
	VertexBuffer *pVertexBuffer = m_pFullscreenQuad->GetVertexBuffer();
	if (pVertexBuffer) {
		// First step: Downsample 2x2, calculate pixel luminance and log - I don't use a "bilinear filter" because this would mess up the incoming texel data "before" the log calculation was performed!
		if (m_pRenderer->SetProgram(m_pDownsampleLogProgram)) {
			// Get the size of the original HDR texture
			const Vector2i vRTSize = cOriginalTexture.GetSize()/2;
			if (vRTSize.x != 0 && vRTSize.y != 0) {
				// Render target size change?
				if (m_pDownsampleLogRenderTarget && (m_pDownsampleLogRenderTarget->GetSize() != vRTSize || m_pDownsampleLogRenderTarget->GetFormat() != nInternalFormat)) {
					// Destroy the downsample 2x2 log render target
					if (m_pDownsampleLogRenderTarget) {
						delete m_pDownsampleLogRenderTarget;
						m_pDownsampleLogRenderTarget = nullptr;
					}
				}

				// Create the downsample 2x2 log render target right now?
				if (!m_pDownsampleLogRenderTarget)
					m_pDownsampleLogRenderTarget = m_pRenderer->CreateSurfaceTextureBufferRectangle(vRTSize, nInternalFormat, SurfaceTextureBuffer::NoMultisampleAntialiasing);
			}
			
			// Make the downsample 2x2 log render target to the current render target
			m_pRenderer->SetRenderTarget(m_pDownsampleLogRenderTarget);

			// Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute"
			if (m_pDownsampleLogPositionProgramAttribute)
				m_pDownsampleLogPositionProgramAttribute->Set(pVertexBuffer, PLRenderer::VertexBuffer::Position);

			// Set the "TextureSize" fragment shader parameter
			if (m_pDownsampleLogTextureSizeProgramUniform)
				m_pDownsampleLogTextureSizeProgramUniform->Set(cOriginalTexture.GetSize());

			// Set the "Texture" fragment shader parameter
			if (m_pDownsampleLogTextureProgramUniform) {
				const int nTextureUnit = m_pDownsampleLogTextureProgramUniform->Set(&cOriginalTexture);
				if (nTextureUnit >= 0) {
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressU, TextureAddressing::Wrap);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressV, TextureAddressing::Wrap);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::None);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::None);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Set the "LuminanceConvert" fragment shader parameter
			if (m_pDownsampleLogLuminanceConvertProgramUniform)
				m_pDownsampleLogLuminanceConvertProgramUniform->Set(cLuminanceConvert);

			// Set the "Epsilon" fragment shader parameter
			if (m_pDownsampleLogEpsilonProgramUniform)
				m_pDownsampleLogEpsilonProgramUniform->Set(0.0001f);

			// Draw the fullscreen quad
			m_pFullscreenQuad->Draw();
		}

		Vector2i vFinalTextureSize;
		TextureBufferRectangle *pFinalTextureBufferRectangle = nullptr;

		// Second step: Reduce to <4>x<4>
		if (m_pDownsampleLogRenderTarget && m_pRenderer->SetProgram(m_pDownsampleProgram)) {
			const uint32 TextureScaleFactor = 2;

			// Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute"
			if (m_pDownsamplePositionProgramAttribute)
				m_pDownsamplePositionProgramAttribute->Set(pVertexBuffer, PLRenderer::VertexBuffer::Position);

			// Get the size of the original HDR texture
			const Vector2i vRTSize = m_pDownsampleLogRenderTarget->GetSize()/TextureScaleFactor;
			if (vRTSize.x != 0 && vRTSize.y != 0) {
				// Render target size change?
				if (m_pDownsampleRenderTarget && (m_pDownsampleRenderTarget->GetSize() != vRTSize || m_pDownsampleRenderTarget->GetFormat() != nInternalFormat)) {
					// Destroy the downsample 4x4 render target
					if (m_pDownsampleRenderTarget) {
						delete m_pDownsampleRenderTarget;
						m_pDownsampleRenderTarget = nullptr;
					}
				}

				// Create the downsample 4x4 render target right now?
				if (!m_pDownsampleRenderTarget)
					m_pDownsampleRenderTarget = m_pRenderer->CreateSurfaceTextureBufferRectangle(vRTSize, nInternalFormat, SurfaceTextureBuffer::NoMultisampleAntialiasing);
			}

			// Get the maximum size
			Vector2i vCurrentSize = m_pDownsampleLogRenderTarget->GetSize();
			uint32   nSize		  = Math::Max(vCurrentSize.x, vCurrentSize.y);

			// Downscale in multiple render passes, we render into m_pDownsampleRenderTarget and m_pDownsampleLogRenderTarget in a ping-pong way
			bool bRenderTarget = false;
			for (; nSize>TextureScaleFactor; nSize/=TextureScaleFactor, bRenderTarget=!bRenderTarget, vCurrentSize/=TextureScaleFactor) {
				// Get the render target we will render into
				SurfaceTextureBuffer *pRenderTargetTexture = bRenderTarget ? m_pDownsampleLogRenderTarget : m_pDownsampleRenderTarget;

				// Get the texture buffer we will downscale
				TextureBufferRectangle *pTextureBufferRectangle = static_cast<TextureBufferRectangle*>(bRenderTarget ? m_pDownsampleRenderTarget->GetTextureBuffer() : m_pDownsampleLogRenderTarget->GetTextureBuffer());

				// Set the current render target
				m_pRenderer->SetRenderTarget(pRenderTargetTexture);

				// Backup texture width
				vFinalTextureSize			 = vCurrentSize/TextureScaleFactor;
				pFinalTextureBufferRectangle = static_cast<TextureBufferRectangle*>(pRenderTargetTexture->GetTextureBuffer());

				// Set the "TextureSize" fragment shader parameter
				if (m_pDownsampleTextureSizeProgramUniform)
					m_pDownsampleTextureSizeProgramUniform->Set(vCurrentSize);

				// Set the "Size" fragment shader parameter
				if (m_pDownsampleSizeProgramUniform)
					m_pDownsampleSizeProgramUniform->Set(static_cast<float>(vFinalTextureSize.x)/pRenderTargetTexture->GetSize().x, static_cast<float>(vFinalTextureSize.y)/pRenderTargetTexture->GetSize().y);

				// Set the "Texture" fragment shader parameter
				if (m_pDownsampleTextureProgramUniform) {
					const int nTextureUnit = m_pDownsampleTextureProgramUniform->Set(pTextureBufferRectangle);
					if (nTextureUnit >= 0) {
						m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressU, TextureAddressing::Wrap);
						m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressV, TextureAddressing::Wrap);
						m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::None);	// [TODO] Use bilinear filter
						m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::None);	// [TODO] Use bilinear filter
						m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
					}
				}

				// Draw the fullscreen quad
				m_pFullscreenQuad->Draw();
			}
		}

		// Third step: Reduce <4>x<4> to <1>x<1> and calculate the exponent
		if (m_pRenderer->SetProgram(m_pDownsampleExpProgram)) {
			// Render format change?
			if (m_pAverageLuminanceTextureBuffer2D && m_pAverageLuminanceTextureBuffer2D->GetFormat() != nInternalFormat) {
				// Destroy the result render target
				if (m_pAverageLuminanceTextureBuffer2D) {
					delete m_pAverageLuminanceTextureBuffer2D;
					m_pAverageLuminanceTextureBuffer2D = nullptr;
				}
			}

			// Create the result render target right now?
			if (!m_pAverageLuminanceTextureBuffer2D)
				m_pAverageLuminanceTextureBuffer2D = m_pRenderer->CreateSurfaceTextureBuffer2D(Vector2i::One, nInternalFormat, SurfaceTextureBuffer::NoMultisampleAntialiasing);

			// Make the result render target to the current render target
			m_pRenderer->SetRenderTarget(m_pAverageLuminanceTextureBuffer2D);

			// Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute"
			if (m_pDownsampleExpPositionProgramAttribute)
				m_pDownsampleExpPositionProgramAttribute->Set(pVertexBuffer, PLRenderer::VertexBuffer::Position);

			// Set the "TextureSize" fragment shader parameter
			if (m_pDownsampleExpTextureSizeProgramUniform)
				m_pDownsampleExpTextureSizeProgramUniform->Set(vFinalTextureSize);

			// Set the "Texture" fragment shader parameter
			if (m_pDownsampleExpTextureProgramUniform) {
				const int nTextureUnit = m_pDownsampleExpTextureProgramUniform->Set(pFinalTextureBufferRectangle);
				if (nTextureUnit >= 0) {
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressU, TextureAddressing::Wrap);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::AddressV, TextureAddressing::Wrap);
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::None);	// [TODO] Use bilinear filter
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::None);	// [TODO] Use bilinear filter
					m_pRenderer->SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None);
				}
			}

			// Draw the fullscreen quad
			m_pFullscreenQuad->Draw();
		}
	}
}