예제 #1
0
NzString NzInputStream::ReadLine(unsigned int lineSize)
{
	NzString line;
	if (lineSize == 0) // Taille maximale indéterminée
	{
		const unsigned int bufferSize = 64;

		char buffer[bufferSize+1];
		buffer[bufferSize] = '\0';

		unsigned int readSize;
		do
		{
			readSize = Read(buffer, bufferSize);

			const char* ptr = std::strchr(buffer, '\n');
			if (ptr)
			{
				unsigned int pos = ptr-buffer;

				if (m_streamOptions & nzStreamOption_Text && pos > 0 && buffer[pos-1] == '\r')
					line.Append(buffer, pos-1);
				else
					line.Append(buffer, pos);

				if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
					NazaraWarning("Failed to reset cursos pos");

				break;
			}
			else
				line.Append(buffer, readSize);
		}
		while (readSize == bufferSize);
	}
	else
	{
		line.Set(lineSize, '\0');
		unsigned int readSize = Read(&line[0], lineSize);
		unsigned int pos = line.Find('\n');
		if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier)
		{
			if (m_streamOptions & nzStreamOption_Text && pos > 0 && line[pos-1] == '\r')
				line.Resize(pos);
			else
				line.Resize(pos+1);

			if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
				NazaraWarning("Failed to reset cursos pos");
		}
		else
			line.Resize(readSize);
	}

	return line;
}
예제 #2
0
	void TcpClient::OnOpened()
	{
		AbstractSocket::OnOpened();

		SocketError errorCode;

		if (!SocketImpl::SetNoDelay(m_handle, m_isLowDelayEnabled, &errorCode))
			NazaraWarning("Failed to set socket no delay mode (0x" + String::Number(errorCode, 16) + ')');

		if (!SocketImpl::SetKeepAlive(m_handle, m_isKeepAliveEnabled, m_keepAliveTime, m_keepAliveInterval, &errorCode))
			NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')');

		m_peerAddress = IpAddress::Invalid;
		m_openMode = OpenMode_ReadWrite;
	}
예제 #3
0
	bool RenderWindow::OnWindowCreated()
	{
		m_parameters.doubleBuffered = true;
		m_parameters.window = GetHandle();

		std::unique_ptr<Context> context(new Context);
		if (!context->Create(m_parameters))
		{
			NazaraError("Failed to create context");
			return false;
		}

		m_context = context.release();

		if (!SetActive(true)) // Les fenêtres s'activent à la création
			NazaraWarning("Failed to activate window");

		EnableVerticalSync(false);

		Vector2ui size = GetSize();

		// Le scissorBox/viewport (à la création) est de la taille de la fenêtre
		// https://www.opengl.org/sdk/docs/man/xhtml/glGet.xml
		OpenGL::SetScissorBox(Recti(0, 0, size.x, size.y));
		OpenGL::SetViewport(Recti(0, 0, size.x, size.y));

		OnRenderTargetParametersChange(this);
		OnRenderTargetSizeChange(this);

		m_clock.Restart();

		return true;
	}
예제 #4
0
	void Skeleton::UpdateJointMap() const
	{
		#ifdef NAZARA_DEBUG
		if (!m_impl)
		{
			NazaraError("Invalid skeleton");
			return;
		}
		#endif

		m_impl->jointMap.clear();
		for (std::size_t i = 0; i < m_impl->joints.size(); ++i)
		{
			String name = m_impl->joints[i].GetName();
			if (!name.IsEmpty())
			{
				#if NAZARA_UTILITY_SAFE
				auto it = m_impl->jointMap.find(name);
				if (it != m_impl->jointMap.end())
				{
					NazaraWarning("Joint name \"" + name + "\" is already present in joint map for joint #" + String::Number(it->second));
					continue;
				}
				#endif

				m_impl->jointMap[name] = i;
			}
		}

		m_impl->jointMapUpdated = true;
	}
예제 #5
0
	void SocketImpl::Close(SocketHandle handle)
	{
		NazaraAssert(handle != InvalidHandle, "Invalid handle");

		if (closesocket(handle) == SOCKET_ERROR)
			NazaraWarning("Failed to close socket: " + Error::GetLastSystemError(WSAGetLastError()));
	}
예제 #6
0
	void SocketImpl::ClearErrorCode(SocketHandle handle)
	{
		NazaraAssert(handle != InvalidHandle, "Invalid handle");

		if (GetLastError(handle, nullptr) < 0)
			NazaraWarning("Failed to clear socket error code: " + Error::GetLastSystemError(WSAGetLastError()));
	}
예제 #7
0
void NzUberShaderLibrary::Uninitialize()
{
	for (auto it : s_library)
		NazaraWarning("UberShader \"" + it.first + "\" has not been unregistred");

	s_library.clear();
}
예제 #8
0
	void ListenerSystem::OnUpdate(float /*elapsedTime*/)
	{
		std::size_t activeListenerCount = 0;

		for (const Ndk::EntityHandle& entity : GetEntities())
		{
			// Is the listener actif ?
			const ListenerComponent& listener = entity->GetComponent<ListenerComponent>();
			if (!listener.IsActive())
				continue;

			// We get the position and the rotation to affect these to the listener
			const NodeComponent& node = entity->GetComponent<NodeComponent>();
			Nz::Audio::SetListenerPosition(node.GetPosition(Nz::CoordSys_Global));
			Nz::Audio::SetListenerRotation(node.GetRotation(Nz::CoordSys_Global));

			// We verify the presence of a component of velocity
			// (The listener'speed does not move it, but disturbs the sound like Doppler effect)
			if (entity->HasComponent<VelocityComponent>())
			{
				const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>();
				Nz::Audio::SetListenerVelocity(velocity.linearVelocity);
			}

			activeListenerCount++;
		}

		if (activeListenerCount > 1)
			NazaraWarning(Nz::String::Number(activeListenerCount) + " listeners were active in the same update loop");
	}
예제 #9
0
void NzRenderTexture::Unlock() const
{
	#if NAZARA_RENDERER_SAFE
	if (!m_impl)
	{
		NazaraError("Render texture not created");
		return;
	}

	if (NzContext::GetCurrent() != m_impl->context)
	{
		NazaraError("RenderTexture cannot be used with this context");
		return;
	}

	if (lockedLevel == 0)
	{
		NazaraWarning("Unlock called on non-locked texture");
		return;
	}
	#endif

	if (--lockedLevel == 0 && lockedPrevious != m_impl->fbo) // Ici, il est important qu'un FBO soit débindé si l'ancien était 0
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lockedPrevious);
}
예제 #10
0
	void Mesh::SetMaterialCount(unsigned int matCount)
	{
		#if NAZARA_UTILITY_SAFE
		if (!m_impl)
		{
			NazaraError("Mesh not created");
			return;
		}

		if (matCount == 0)
		{
			NazaraError("A mesh should have at least a material");
			return;
		}
		#endif

		m_impl->materials.resize(matCount);

		#ifdef NAZARA_DEBUG
		for (SubMesh* subMesh : m_impl->subMeshes)
		{
			unsigned int matIndex = subMesh->GetMaterialIndex();
			if (matIndex >= matCount)
			{
				subMesh->SetMaterialIndex(0); // Pour empêcher un crash
				NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material");
			}
		}
		#endif
	}
예제 #11
0
	void Buffer::Unmap() const
	{
		NazaraAssert(m_impl, "Invalid buffer");

		if (!m_impl->Unmap())
			NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ?
	}
	void ListenerSystem::OnUpdate(float elapsedTime)
	{
		std::size_t activeListenerCount = 0;

		for (const Ndk::EntityHandle& entity : GetEntities())
		{
			// Is the listener actif ?
			const ListenerComponent& listener = entity->GetComponent<ListenerComponent>();
			if (!listener.IsActive())
				continue;

			Nz::Vector3f oldPos = Nz::Audio::GetListenerPosition();

			// We get the position and the rotation to affect these to the listener
			const NodeComponent& node = entity->GetComponent<NodeComponent>();
			Nz::Vector3f newPos = node.GetPosition(Nz::CoordSys_Global);

			Nz::Audio::SetListenerPosition(newPos);
			Nz::Audio::SetListenerRotation(node.GetRotation(Nz::CoordSys_Global));

			// Compute listener velocity based on their old/new position
			Nz::Vector3f velocity = (newPos - oldPos) / elapsedTime;
			Nz::Audio::SetListenerVelocity(velocity);

			activeListenerCount++;
		}

		if (activeListenerCount > 1)
			NazaraWarning(Nz::String::Number(activeListenerCount) + " listeners were active in the same update loop");
	}
예제 #13
0
	void Node::RemoveChild(Node* node) const
	{
		auto it = std::find(m_childs.begin(), m_childs.end(), node);
		if (it != m_childs.end())
			m_childs.erase(it);
		else
			NazaraWarning("Child not found");
	}
예제 #14
0
void NzGraphics::Uninitialize()
{
	if (s_moduleReferenceCounter != 1)
	{
		// Le module est soit encore utilisé, soit pas initialisé
		if (s_moduleReferenceCounter > 1)
			s_moduleReferenceCounter--;

		return;
	}

	// Libération du module
	s_moduleReferenceCounter = 0;

	// Libération de l'atlas s'il vient de nous
	std::shared_ptr<NzAbstractAtlas> defaultAtlas = NzFont::GetDefaultAtlas();
	if (defaultAtlas && defaultAtlas->GetStorage() & nzDataStorage_Hardware)
	{
		NzFont::SetDefaultAtlas(nullptr);

		// La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique)
		// du coup, si la police par défaut utilise un atlas hardware, on lui enlève.
		// Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant
		if (!defaultAtlas.unique())
		{
			// Encore au moins une police utilise l'atlas
			NzFont* defaultFont = NzFont::GetDefault();
			defaultFont->SetAtlas(nullptr);

			if (!defaultAtlas.unique())
			{
				// Toujours pas seuls propriétaires ? Ah ben zut.
				NazaraWarning("Default font atlas uses hardware storage and is still used");
			}
		}
	}

	defaultAtlas.reset();

	// Loaders
	NzLoaders_Mesh_Unregister();
	NzLoaders_OBJ_Unregister();
	NzLoaders_Texture_Unregister();

	NzDeferredRenderTechnique::Uninitialize();
	NzForwardRenderTechnique::Uninitialize();
	NzSkinningManager::Uninitialize();
	NzParticleRenderer::Uninitialize();
	NzParticleGenerator::Uninitialize();
	NzParticleDeclaration::Uninitialize();
	NzParticleController::Uninitialize();
	NzMaterial::Uninitialize();

	NazaraNotice("Uninitialized: Graphics module");

	// Libération des dépendances
	NzRenderer::Uninitialize();
}
/*!
 * Write bits to the stream (if any) and reset the current bit cursor

* \see ResetBitPosition
*/
void SerializationContext::FlushBits()
{
    if (currentBitPos != 8)
    {
        ResetBitPosition();

        // Serialize will reset the bit position
        if (!Serialize<UInt8>(*this, currentByte))
            NazaraWarning("Failed to flush bits");
    }
}
예제 #16
0
void NzClock::Pause()
{
	NazaraLock(m_mutex);

	if (!m_paused)
	{
		m_elapsedTime += NzGetMicroseconds()-m_refTime;
		m_paused = true;
	}
	else
		NazaraWarning("Clock is already paused, ignoring...");
}
예제 #17
0
	void Node::AddChild(Node* node) const
	{
		#ifdef NAZARA_DEBUG
		if (std::find(m_childs.begin(), m_childs.end(), node) != m_childs.end())
		{
			NazaraWarning("Child node is already a child of parent node");
			return;
		}
		#endif

		m_childs.push_back(node);
	}
예제 #18
0
void NzClock::Unpause()
{
	NazaraLock(m_mutex);

	if (m_paused)
	{
		m_refTime = NzGetMicroseconds();
		m_paused = false;
	}
	else
		NazaraWarning("Clock is not paused, ignoring...");
}
예제 #19
0
	void TextSprite::OnAtlasInvalidated(const AbstractAtlas* atlas)
	{
		#ifdef NAZARA_DEBUG
		if (m_atlases.find(atlas) == m_atlases.end())
		{
			NazaraInternalError("Not listening to " + String::Pointer(atlas));
			return;
		}
		#endif

		NazaraWarning("TextSprite " + String::Pointer(this) + " has been cleared because atlas " + String::Pointer(atlas) + " has been invalidated (cleared or released)");
		Clear();
	}
예제 #20
0
	void Buffer::Unmap() const
	{
		#if NAZARA_UTILITY_SAFE
		if (!m_impl)
		{
			NazaraError("Buffer not valid");
			return;
		}
		#endif

		if (!m_impl->Unmap())
			NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ?
	}
	bool UdpSocket::ReceivePacket(NetPacket* packet, IpAddress* from)
	{
		NazaraAssert(packet, "Invalid packet");

		// I'm not sure what's the best between having a 65k bytes buffer ready for any datagram size
		// or querying the next datagram size every time, for now I'll leave it as is
		packet->Reset(NetCode_Invalid, std::numeric_limits<UInt16>::max());
		packet->Resize(std::numeric_limits<UInt16>::max());

		std::size_t received;
		if (!Receive(packet->GetData(), static_cast<std::size_t>(packet->GetSize()), from, &received))
			return false;

		if (received == 0)
			return false; //< No datagram received

		Nz::UInt16 netCode;
		Nz::UInt32 packetSize;
		if (!NetPacket::DecodeHeader(packet->GetConstData(), &packetSize, &netCode))
		{
			m_lastError = SocketError_Packet;
			NazaraWarning("Invalid header data");
			return false;
		}

		if (packetSize != received)
		{
			m_lastError = SocketError_Packet;
			NazaraWarning("Invalid packet size (packet size is " + String::Number(packetSize) + " bytes, received " + Nz::String::Number(received) + " bytes)");
			return false;
		}

		packet->Resize(received);
		packet->SetNetCode(netCode);
		return true;
	}
예제 #22
0
	void GuillotineImageAtlas::Free(SparsePtr<const Rectui> rects, SparsePtr<unsigned int> layers, unsigned int count)
	{
		for (unsigned int i = 0; i < count; ++i)
		{
			#ifdef NAZARA_DEBUG
			if (layers[i] >= m_layers.size())
			{
				NazaraWarning("Rectangle #" + String::Number(i) + " belong to an out-of-bounds layer (" + String::Number(i) + " >= " + String::Number(m_layers.size()) + ")");
				continue;
			}
			#endif

			m_layers[layers[i]].binPack.FreeRectangle(rects[i]);
			m_layers[layers[i]].freedRectangles++;
		}
	}
예제 #23
0
	void OpenAL::CloseDevice()
	{
		if (s_device)
		{
			if (s_context)
			{
				alcMakeContextCurrent(nullptr);
				alcDestroyContext(s_context);
				s_context = nullptr;
			}

			if (!alcCloseDevice(s_device))
				// We could not close the close, this means that it's still in use
				NazaraWarning("Failed to close device");

			s_device = nullptr;
		}
	}
예제 #24
0
void NzSkeletalModel::SetMesh(NzMesh* mesh)
{
	#if NAZARA_GRAPHICS_SAFE
	if (mesh && mesh->GetAnimationType() != nzAnimationType_Skeletal)
	{
		NazaraError("Mesh animation type must be skeletal");
		return;
	}
	#endif

	NzModel::SetMesh(mesh);

	if (m_mesh)
	{
		if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount())
		{
			NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation...");
			SetAnimation(nullptr);
		}

		m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template
	}
}
예제 #25
0
void NzRenderTexture::Destroy()
{
	if (m_impl)
	{
		bool canFreeFBO = true;
		#if NAZARA_RENDERER_SAFE
		if (NzContext::GetCurrent() != m_impl->context)
		{
			NazaraWarning("RenderTexture should be destroyed by it's creation context, this will cause leaks");
			canFreeFBO = false;
		}
		#endif

		m_impl->context->RemoveResourceListener(this);

		for (const Attachment& attachment : m_impl->attachements)
		{
			if (attachment.isUsed)
			{
				if (attachment.isBuffer)
					glDeleteRenderbuffers(1, &attachment.buffer); // Les Renderbuffers sont partagés entre les contextes: Ne posera pas de problème
				else
				{
					attachment.texture->SetRenderTexture(nullptr);
					attachment.texture->RemoveResourceListener(this);
				}
			}
		}

		if (canFreeFBO)
			glDeleteFramebuffers(1, &m_impl->fbo);

		delete m_impl;
		m_impl = nullptr;
	}
}
예제 #26
0
void NzOBJParser::Warning(const NzString& message)
{
	NazaraWarning(message + " at line #" + NzString::Number(m_lineCount));
}
NzDeferredRenderTechnique::NzDeferredRenderTechnique() :
m_renderQueue(static_cast<NzForwardRenderQueue*>(m_forwardTechnique.GetRenderQueue())),
m_GBufferSize(0U)
{
	m_depthStencilBuffer = new NzRenderBuffer;
	m_depthStencilBuffer->SetPersistent(false);

	for (unsigned int i = 0; i < 2; ++i)
	{
		m_workTextures[i] = new NzTexture;
		m_workTextures[i]->SetPersistent(false);
	}

	for (unsigned int i = 0; i < 3; ++i)
	{
		m_GBuffer[i] = new NzTexture;
		m_GBuffer[i]->SetPersistent(false);
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);

		ResetPass(nzRenderPassType_Final, 0);
		ResetPass(nzRenderPassType_Geometry, 0);
		ResetPass(nzRenderPassType_Lighting, 0);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);

		NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled);

		NazaraError("Failed to add geometry and/or phong lighting pass");
		throw;
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);
		ResetPass(nzRenderPassType_AA, 0);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add FXAA pass");
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);
		ResetPass(nzRenderPassType_Bloom, 0);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add bloom pass");
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);

		NzDeferredRenderPass* dofPass = ResetPass(nzRenderPassType_DOF, 0);
		dofPass->Enable(false);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add DOF pass");
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);

		NzDeferredRenderPass* fogPass = ResetPass(nzRenderPassType_Fog, 0);
		fogPass->Enable(false);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add fog pass");
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);
		ResetPass(nzRenderPassType_Forward, 0);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add forward pass");
	}

	try
	{
		NzErrorFlags errFlags(nzErrorFlag_ThrowException);
		ResetPass(nzRenderPassType_SSAO, 0);
	}
	catch (const std::exception& e)
	{
        NazaraUnused(e);
		NazaraWarning("Failed to add SSAO pass");
	}
}
bool NzDeferredRenderTechnique::Initialize()
{
	const nzUInt8 fragmentSource_BloomBright[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/BloomBright.frag.h>
	};

	const nzUInt8 fragmentSource_BloomFinal[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/BloomFinal.frag.h>
	};

	const nzUInt8 fragmentSource_DirectionalLight[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/DirectionalLight.frag.h>
	};

	const nzUInt8 fragmentSource_FXAA[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/FXAA.frag.h>
	};

	const nzUInt8 fragmentSource_GBufferClear[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/GBufferClear.frag.h>
	};

	const nzUInt8 fragmentSource_GaussianBlur[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/GaussianBlur.frag.h>
	};

	const nzUInt8 fragmentSource_PointSpotLight[] = {
		#include <Nazara/Graphics/Resources/DeferredShading/Shaders/PointSpotLight.frag.h>
	};

	const char vertexSource_Basic[] =
	"#version 140\n"

	"in vec3 VertexPosition;\n"
	"uniform mat4 WorldViewProjMatrix;\n"

	"void main()\n"
	"{\n"
		"gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n"
	"}\n";

	const char vertexSource_PostProcess[] =
	"#version 140\n"

	"in vec3 VertexPosition;\n"

	"void main()\n"
	"{\n"
		"gl_Position = vec4(VertexPosition, 1.0);"
	"}\n";

	NzShaderStage basicVertexStage(nzShaderStage_Vertex);
	if (!basicVertexStage.IsValid())
	{
		NazaraError("Failed to create basic vertex shader");
		return false;
	}

	basicVertexStage.SetSource(vertexSource_Basic, sizeof(vertexSource_Basic));

	if (!basicVertexStage.Compile())
	{
		NazaraError("Failed to compile basic vertex shader");
		return false;
	}


	NzShaderStage ppVertexStage(nzShaderStage_Vertex);
	if (!ppVertexStage.IsValid())
	{
		NazaraError("Failed to create vertex shader");
		return false;
	}

	ppVertexStage.SetSource(vertexSource_PostProcess, sizeof(vertexSource_PostProcess));

	if (!ppVertexStage.Compile())
	{
		NazaraError("Failed to compile vertex shader");
		return false;
	}


	NzString error;
	NzShader* shader;

	// Shaders critiques (Nécessaires pour le Deferred Shading minimal)
	shader = RegisterDeferredShader("DeferredGBufferClear", fragmentSource_GBufferClear, sizeof(fragmentSource_GBufferClear), ppVertexStage, &error);
	if (!shader)
	{
		NazaraError("Failed to register critical shader: " + error);
		return false;
	}


	shader = RegisterDeferredShader("DeferredDirectionnalLight", fragmentSource_DirectionalLight, sizeof(fragmentSource_DirectionalLight), ppVertexStage, &error);
	if (!shader)
	{
		NazaraError("Failed to register critical shader: " + error);
		return false;
	}

	shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0);
	shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1);
	shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2);


	shader = RegisterDeferredShader("DeferredPointSpotLight", fragmentSource_PointSpotLight, sizeof(fragmentSource_PointSpotLight), basicVertexStage, &error);
	if (!shader)
	{
		NazaraError("Failed to register critical shader: " + error);
		return false;
	}

	shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0);
	shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1);
	shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2);


	// Shaders optionnels (S'ils ne sont pas présents, le rendu minimal sera quand même assuré)
	shader = RegisterDeferredShader("DeferredBloomBright", fragmentSource_BloomBright, sizeof(fragmentSource_BloomBright), ppVertexStage, &error);
	if (shader)
		shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0);
	else
	{
		NazaraWarning("Failed to register bloom (bright pass) shader, certain features will not work: " + error);
	}


	shader = RegisterDeferredShader("DeferredBloomFinal", fragmentSource_BloomFinal, sizeof(fragmentSource_BloomFinal), ppVertexStage, &error);
	if (shader)
	{
		shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0);
		shader->SendInteger(shader->GetUniformLocation("BloomTexture"), 1);
	}
	else
	{
		NazaraWarning("Failed to register bloom (final pass) shader, certain features will not work: " + error);
	}


	shader = RegisterDeferredShader("DeferredFXAA", fragmentSource_FXAA, sizeof(fragmentSource_FXAA), ppVertexStage, &error);
	if (shader)
		shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0);
	else
	{
		NazaraWarning("Failed to register FXAA shader, certain features will not work: " + error);
	}


	shader = RegisterDeferredShader("DeferredGaussianBlur", fragmentSource_GaussianBlur, sizeof(fragmentSource_GaussianBlur), ppVertexStage, &error);
	if (shader)
		shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0);
	else
	{
		NazaraWarning("Failed to register gaussian blur shader, certain features will not work: " + error);
	}

	return true;
}
예제 #29
0
	bool Graphics::Initialize()
	{
		if (IsInitialized())
		{
			s_moduleReferenceCounter++;
			return true; // Already initialized
		}

		// Initialisation of dependances
		if (!Renderer::Initialize())
		{
			NazaraError("Failed to initialize Renderer module");
			return false;
		}

		s_moduleReferenceCounter++;

		// Initialisation of the module
		CallOnExit onExit(Graphics::Uninitialize);

		// Materials
		if (!MaterialPipeline::Initialize())
		{
			NazaraError("Failed to initialize material pipelines");
			return false;
		}

		if (!Material::Initialize())
		{
			NazaraError("Failed to initialize materials");
			return false;
		}

		// Renderables
		if (!ParticleController::Initialize())
		{
			NazaraError("Failed to initialize particle controllers");
			return false;
		}

		if (!ParticleDeclaration::Initialize())
		{
			NazaraError("Failed to initialize particle declarations");
			return false;
		}

		if (!ParticleGenerator::Initialize())
		{
			NazaraError("Failed to initialize particle generators");
			return false;
		}

		if (!ParticleRenderer::Initialize())
		{
			NazaraError("Failed to initialize particle renderers");
			return false;
		}

		if (!SkinningManager::Initialize())
		{
			NazaraError("Failed to initialize skinning manager");
			return false;
		}

		if (!SkyboxBackground::Initialize())
		{
			NazaraError("Failed to initialize skybox backgrounds");
			return false;
		}

		if (!Sprite::Initialize())
		{
			NazaraError("Failed to initialize sprites");
			return false;
		}

		if (!TileMap::Initialize())
		{
			NazaraError("Failed to initialize tilemaps");
			return false;
		}

		// Generic loaders
		Loaders::RegisterMesh();
		Loaders::RegisterTexture();

		// Render techniques
		if (!DepthRenderTechnique::Initialize())
		{
			NazaraError("Failed to initialize Depth Rendering");
			return false;
		}

		if (!ForwardRenderTechnique::Initialize())
		{
			NazaraError("Failed to initialize Forward Rendering");
			return false;
		}

		RenderTechniques::Register(RenderTechniques::ToString(RenderTechniqueType_BasicForward), 0, []() -> AbstractRenderTechnique* { return new ForwardRenderTechnique; });

		if (DeferredRenderTechnique::IsSupported())
		{
			if (DeferredRenderTechnique::Initialize())
				RenderTechniques::Register(RenderTechniques::ToString(RenderTechniqueType_DeferredShading), 20, []() -> AbstractRenderTechnique* { return new DeferredRenderTechnique; });
			else
			{
				NazaraWarning("Failed to initialize Deferred Rendering");
			}
		}

		Font::SetDefaultAtlas(std::make_shared<GuillotineTextureAtlas>());

		// Textures
		std::array<UInt8, 6> whitePixels = { { 255, 255, 255, 255, 255, 255 } };

		Nz::TextureRef whiteTexture = Nz::Texture::New();
		whiteTexture->Create(ImageType_2D, PixelFormatType_L8, 1, 1);
		whiteTexture->Update(whitePixels.data());

		TextureLibrary::Register("White2D", std::move(whiteTexture));

		Nz::TextureRef whiteCubemap = Nz::Texture::New();
		whiteCubemap->Create(ImageType_Cubemap, PixelFormatType_L8, 1, 1);
		whiteCubemap->Update(whitePixels.data());

		TextureLibrary::Register("WhiteCubemap", std::move(whiteCubemap));

		onExit.Reset();

		NazaraNotice("Initialized: Graphics module");
		return true;
	}
예제 #30
0
	void Graphics::Uninitialize()
	{
		if (s_moduleReferenceCounter != 1)
		{
			// The module is still in use, or can not be uninitialized
			if (s_moduleReferenceCounter > 1)
				s_moduleReferenceCounter--;

			return;
		}

		// Free of module
		s_moduleReferenceCounter = 0;

		// Free of atlas if it is ours
		std::shared_ptr<AbstractAtlas> defaultAtlas = Font::GetDefaultAtlas();
		if (defaultAtlas && defaultAtlas->GetStorage() == DataStorage_Hardware)
		{
			Font::SetDefaultAtlas(nullptr);

			// The default police can make live one hardware atlas after the free of a module (which could be problematic)
			// So, if the default police use a hardware atlas, we stole it.
			// I don't like this solution, but I don't have any better
			if (!defaultAtlas.unique())
			{
				// Still at least one police use the atlas
				Font* defaultFont = Font::GetDefault();
				defaultFont->SetAtlas(nullptr);

				if (!defaultAtlas.unique())
				{
					// Still not the only one to own it ? Then crap.
					NazaraWarning("Default font atlas uses hardware storage and is still used");
				}
			}
		}

		defaultAtlas.reset();

		// Textures
		TextureLibrary::Unregister("White2D");
		TextureLibrary::Unregister("WhiteCubemap");

		// Loaders
		Loaders::UnregisterMesh();
		Loaders::UnregisterTexture();

		// Renderables
		ParticleRenderer::Uninitialize();
		ParticleGenerator::Uninitialize();
		ParticleDeclaration::Uninitialize();
		ParticleController::Uninitialize();
		SkyboxBackground::Uninitialize();
		Sprite::Uninitialize();
		TileMap::Uninitialize();

		// Render techniques
		DeferredRenderTechnique::Uninitialize();
		DepthRenderTechnique::Uninitialize();
		ForwardRenderTechnique::Uninitialize();
		SkinningManager::Uninitialize();

		// Materials
		Material::Uninitialize();
		MaterialPipeline::Uninitialize();

		NazaraNotice("Uninitialized: Graphics module");

		// Free of dependances
		Renderer::Uninitialize();
	}