Merge remote-tracking branch 'refs/remotes/origin/master' into culling

This commit is contained in:
Lynix
2016-10-12 16:51:18 +02:00
95 changed files with 2139 additions and 348 deletions

View File

@@ -11,10 +11,22 @@ namespace Nz
void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4])
{
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
asm volatile ("cpuid" // Besoin d'être volatile ?
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output
: "a" (functionId), "c" (subFunctionId)); // input
// https://en.wikipedia.org/wiki/CPUID
asm volatile(
#ifdef NAZARA_PLATFORM_x64
"pushq %%rbx \n\t" // save %rbx
#else
"pushl %%ebx \n\t" // save %ebx
#endif
"cpuid \n\t"
"movl %%ebx ,%[ebx] \n\t" // write the result into output var
#ifdef NAZARA_PLATFORM_x64
"popq %%rbx \n\t"
#else
"popl %%ebx \n\t"
#endif
: "=a"(registers[0]), [ebx] "=r"(registers[1]), "=c"(registers[2]), "=d"(registers[3])
: "a"(functionId), "c" (subFunctionId));
#else
NazaraInternalError("Cpuid has been called although it is not supported");
#endif
@@ -22,7 +34,7 @@ namespace Nz
unsigned int HardwareInfoImpl::GetProcessorCount()
{
// Plus simple (et plus portable) que de passer par le CPUID
// Simpler (and more portable) than using CPUID
return sysconf(_SC_NPROCESSORS_CONF);
}
@@ -37,7 +49,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported()
{
#ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits
return true; // cpuid is always supported on x64 arch
#else
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
int supported;

View File

@@ -44,14 +44,19 @@ namespace Nz
}
/*!
* \brief Reads characters in the stream
* \brief Reads a line from the stream
*
* Reads the stream until a line separator or the end of the stream is found.
*
* If lineSize does not equal zero, it represents the maximum character count to be read from the stream.
*
* \param lineSize Maximum number of characters to read, or zero for no limit
*
* \return Line containing characters
*
* \param lineSize Number of characters to read, if lineSize is 0, read as much as possible
*
* \remark Produces a NazaraWarning if cursor position could not be reset
* \remark With the text stream option, "\r\n" is treated as "\n"
* \remark The line separator character is not returned as part of the string
*/
String Stream::ReadLine(unsigned int lineSize)
{
String line;
@@ -71,19 +76,33 @@ namespace Nz
if (ptr)
{
std::ptrdiff_t pos = ptr - buffer;
if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos - 1] == '\r')
line.Append(buffer, pos - 1);
else
line.Append(buffer, pos);
if (ptr != buffer)
{
if (m_streamOptions & StreamOption_Text && 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");
NazaraWarning("Failed to reset cursor pos");
break;
if (!line.IsEmpty())
break;
}
else
line.Append(buffer, readSize);
{
std::size_t length = readSize;
if (m_streamOptions & StreamOption_Text && buffer[length - 1] == '\r')
{
if (!SetCursorPos(GetCursorPos() - 1))
NazaraWarning("Failed to reset cursor pos");
length--;
}
line.Append(buffer, length);
}
}
while (readSize == bufferSize);
}

View File

@@ -3461,6 +3461,7 @@ namespace Nz
p--;
*p = '\0';
newString->size = p - str;
return String(std::move(newString));
}
@@ -4552,7 +4553,7 @@ namespace Nz
String& String::operator=(String&& string) noexcept
{
return Set(string);
return Set(std::move(string));
}
/*!
@@ -5851,7 +5852,7 @@ namespace Nz
if (!m_sharedString.unique())
{
auto newSharedString = std::make_shared<SharedString>(GetSize(), GetCapacity());
if (!discardContent)
if (!discardContent && newSharedString->size > 0)
std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()+1);
m_sharedString = std::move(newSharedString);
@@ -5878,7 +5879,7 @@ namespace Nz
*/
bool Serialize(SerializationContext& context, const String& string)
{
if (!Serialize<UInt32>(context, string.GetSize()))
if (!Serialize(context, UInt32(string.GetSize())))
return false;
return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize();

View File

@@ -12,7 +12,7 @@ namespace Nz
{
ConditionVariableImpl::ConditionVariableImpl()
{
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
InitializeConditionVariable(&m_cv);
#else
m_count = 0;
@@ -21,7 +21,7 @@ namespace Nz
#endif
}
#if !NAZARA_CORE_WINDOWS_VISTA
#if !NAZARA_CORE_WINDOWS_NT6
ConditionVariableImpl::~ConditionVariableImpl()
{
CloseHandle(m_events[BROADCAST]);
@@ -31,7 +31,7 @@ namespace Nz
void ConditionVariableImpl::Signal()
{
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
WakeConditionVariable(&m_cv);
#else
if (m_count > 0)
@@ -41,7 +41,7 @@ namespace Nz
void ConditionVariableImpl::SignalAll()
{
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
WakeAllConditionVariable(&m_cv);
#else
if (m_count > 0)
@@ -56,8 +56,8 @@ namespace Nz
bool ConditionVariableImpl::Wait(MutexImpl* mutex, UInt32 timeout)
{
#if NAZARA_CORE_WINDOWS_VISTA
return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout);
#if NAZARA_CORE_WINDOWS_NT6
return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout) == TRUE;
#else
m_count++;

View File

@@ -21,7 +21,7 @@ namespace Nz
{
public:
ConditionVariableImpl();
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
~ConditionVariableImpl() = default;
#else
~ConditionVariableImpl();
@@ -34,7 +34,7 @@ namespace Nz
bool Wait(MutexImpl* mutex, UInt32 timeout);
private:
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
CONDITION_VARIABLE m_cv;
#else
enum

View File

@@ -22,10 +22,22 @@ namespace Nz
// Visual propose une fonction intrinsèque pour le cpuid
__cpuidex(reinterpret_cast<int*>(registers), static_cast<int>(functionId), static_cast<int>(subFunctionId));
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
asm volatile ("cpuid" // Besoin d'être volatile ?
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output
: "a" (functionId), "c" (subFunctionId)); // input
// https://en.wikipedia.org/wiki/CPUID
asm volatile(
#ifdef NAZARA_PLATFORM_x64
"pushq %%rbx \n\t" // save %rbx
#else
"pushl %%ebx \n\t" // save %ebx
#endif
"cpuid \n\t"
"movl %%ebx ,%[ebx] \n\t" // write the result into output var
#ifdef NAZARA_PLATFORM_x64
"popq %%rbx \n\t"
#else
"popl %%ebx \n\t"
#endif
: "=a"(registers[0]), [ebx] "=r"(registers[1]), "=c"(registers[2]), "=d"(registers[3]) // output
: "a"(functionId), "c" (subFunctionId)); // input
#else
NazaraInternalError("Cpuid has been called although it is not supported");
#endif
@@ -33,7 +45,7 @@ namespace Nz
unsigned int HardwareInfoImpl::GetProcessorCount()
{
// Plus simple (et plus portable) que de passer par le CPUID
// Simpler (and more portable) than using CPUID
SYSTEM_INFO infos;
GetNativeSystemInfo(&infos);
@@ -52,7 +64,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported()
{
#ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits
return true; // cpuid is always supported on x64 arch
#else
#if defined(NAZARA_COMPILER_MSVC)
int supported;

View File

@@ -469,6 +469,8 @@ namespace Nz
Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4);
}
while (billboardCount > 0);
billboardVector.clear();
}
}
}
@@ -769,6 +771,7 @@ namespace Nz
}
}
}
instances.clear();
}
}
}

View File

@@ -291,6 +291,7 @@ namespace Nz
declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal));
declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position));
declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, rotation));
declaration->EnableComponent(ParticleComponent_Size, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Billboard, size));
declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, velocity));
NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Billboard), "Invalid stride for declaration ParticleLayout_Billboard");

View File

@@ -68,7 +68,12 @@ namespace Nz
std::size_t x = tileIndex % m_mapSize.x;
std::size_t y = tileIndex / m_mapSize.x;
Vector3f tileLeftCorner(x * m_tileSize.x, y * -m_tileSize.y, 0.f);
Vector3f tileLeftCorner;
if (m_isometricModeEnabled)
tileLeftCorner.Set(x * m_tileSize.x + m_tileSize.x/2.f * (y % 2), y/2.f * -m_tileSize.y, 0.f);
else
tileLeftCorner.Set(x * m_tileSize.x, y * -m_tileSize.y, 0.f);
*colorPtr++ = tile.color;
*posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner);

View File

@@ -0,0 +1,112 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Linux/SocketPollerImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Posix/SocketImpl.hpp>
#include <cstring>
#include <unistd.h>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
SocketPollerImpl::SocketPollerImpl()
{
m_handle = epoll_create1(0);
}
SocketPollerImpl::~SocketPollerImpl()
{
close(m_handle);
}
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
return m_sockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
epoll_event event;
event.events = EPOLLIN;
event.data.fd = socket;
if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &event) != 0)
{
NazaraError("Failed to add socket to epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
return false;
}
m_sockets.insert(socket);
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
m_activeSockets.erase(socket);
m_sockets.erase(socket);
if (epoll_ctl(m_handle, EPOLL_CTL_DEL, socket, nullptr) != 0)
NazaraWarning("An error occured while removing socket from epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
int activeSockets;
// Reset status of sockets
m_events.resize(m_sockets.size());
std::memset(m_events.data(), 0, m_events.size() * sizeof(epoll_event));
activeSockets = epoll_wait(m_handle, m_events.data(), static_cast<int>(m_events.size()), static_cast<int>(msTimeout));
if (activeSockets == -1)
{
if (error)
*error = SocketImpl::TranslateErrnoToResolveError(errno);
return 0;
}
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketCount = activeSockets;
for (int i = 0; i < socketCount; ++i)
{
if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
{
m_activeSockets.insert(m_events[i].data.fd);
if (m_events[i].events & EPOLLERR)
NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll with EPOLLERR status");
}
else
{
NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll without EPOLLIN (events: 0x" + String::Number(m_events[i].events, 16) + ')');
activeSockets--;
}
}
}
if (error)
*error = SocketError_NoError;
return activeSockets;
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <unordered_set>
#include <vector>
#include <sys/epoll.h>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl();
~SocketPollerImpl();
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_sockets;
std::vector<epoll_event> m_events;
int m_handle;
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@@ -2,6 +2,11 @@
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_IPADDRESSIMPL_HPP
#define NAZARA_IPADDRESSIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <netdb.h>
#include <netinet/in.h>
@@ -30,3 +35,5 @@ namespace Nz
static ResolveError TranslateEAIErrorToResolveError(int error);
};
}
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@@ -9,6 +9,7 @@
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <poll.h>
#include <unistd.h>
#include <cstring>
#include <Nazara/Network/Debug.hpp>
@@ -397,6 +398,23 @@ namespace Nz
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
}
int SocketImpl::Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error)
{
NazaraAssert(fdarray && nfds > 0, "Invalid fdarray");
static_assert(sizeof(PollSocket) == sizeof(pollfd), "PollSocket size must match WSAPOLLFD size");
int result = poll(reinterpret_cast<pollfd*>(fdarray), static_cast<nfds_t>(nfds), timeout);
if (result < 0)
{
if (error)
*error = TranslateErrnoToResolveError(GetLastErrorCode());
return 0;
}
return result;
}
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
{

View File

@@ -2,12 +2,26 @@
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp>
#define NAZARA_NETWORK_POLL_SUPPORT 1
namespace Nz
{
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl
{
public:
@@ -42,6 +56,8 @@ namespace Nz
static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr);
static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr);
static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error);
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@@ -66,3 +82,5 @@ namespace Nz
static socketID s_socket;
};
}
#endif // NAZARA_SOCKETIMPL_HPP

View File

@@ -0,0 +1,93 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Posix/SocketPollerImpl.hpp>
#include <poll.h>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_allSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
return m_allSockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
PollSocket entry = {
socket,
POLLRDNORM,
0
};
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
if (m_sockets.size() > 1U)
{
// Instead of using vector::erase, let's move the last element to the now unoccupied position
std::size_t entry = m_allSockets[socket];
// Get the last element and update it's position
const PollSocket& lastElement = m_sockets.back();
m_allSockets[lastElement.fd] = entry;
// Now move it properly (lastElement is invalid after the following line) and pop it
m_sockets[entry] = std::move(m_sockets.back());
}
m_sockets.pop_back();
m_activeSockets.erase(socket);
m_allSockets.erase(socket);
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
int activeSockets;
// Reset status of sockets
for (PollSocket& entry : m_sockets)
entry.revents = 0;
activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
{
m_activeSockets.insert(entry.fd);
if (--socketRemaining == 0)
break;
}
}
}
return activeSockets;
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Posix/SocketImpl.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl() = default;
~SocketPollerImpl() = default;
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@@ -0,0 +1,170 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/SocketPoller.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Network/Win32/SocketPollerImpl.hpp>
#elif defined(NAZARA_PLATFORM_LINUX)
#include <Nazara/Network/Linux/SocketPollerImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Network/Posix/SocketPollerImpl.hpp>
#else
#error Missing implementation: SocketPoller
#endif
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
/*!
* \ingroup network
* \class Nz::SocketPoller
* \brief Network class allowing an application to wait on multiples sockets for them to become active (readable)
*/
/*!
* \brief Constructs an empty SocketPoller object
*/
SocketPoller::SocketPoller() :
m_impl(new SocketPollerImpl)
{
}
/*!
* \brief Destructs the SocketPoller
*
* \remark When the SocketPoller gets destroyed, all sockets are automatically unregistered from it.
*/
SocketPoller::~SocketPoller()
{
delete m_impl;
}
/*!
* \brief Clears the SocketPoller
*
* This function reverts the SocketPoller to the initial state, unregistering every socket from the SocketPoller.
*
* \see Unregister
*/
void SocketPoller::Clear()
{
m_impl->Clear();
}
/*!
* \brief Checks if a specific socket is ready to read data
*
* This function allows you to read the results of the last Wait operation and if a specific socket is ready.
*
* A socket in the ready state (with the exception of TcpServer) has incoming data and can be read without blocking.
*
* \remark When used on a TcpServer socket, this function returns true if the server is ready to accept a new client.
* \remark You must call Wait before using this function in order to refresh the state.
*
* \param socket Reference to the socket to check
*
* \return True if the socket is available for reading without blocking, false otherwise
*
* \see Wait
*/
bool SocketPoller::IsReady(const AbstractSocket& socket) const
{
NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller");
return m_impl->IsReady(socket.GetNativeHandle());
}
/*!
* \brief Checks if a specific socket is registered in the SocketPoller
*
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations.
*
* \param socket Reference to the socket to check
*
* \return True if the socket is registered, false otherwise
*
* \see RegisterSocket
* \see UnregisterSocket
*/
bool SocketPoller::IsRegistered(const AbstractSocket& socket) const
{
return m_impl->IsRegistered(socket.GetNativeHandle());
}
/*!
* \brief Register a socket in the SocketPoller
*
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations.
*
* The SocketPoller keeps a reference to the internal handle of registered socket, which should not be freed while it is registered in the SocketPooler.
*
* It is possible for this function to fail if too many sockets are registered in the SocketPoller, the maximum number of socket handled limit is OS-dependent.
*
* \remark It is an error to register a socket twice in the same SocketPoller.
* \remark The socket should not be freed while it is registered in the SocketPooler.
*
* \param socket Reference to the socket to register
*
* \return True if the socket is registered, false otherwise
*
* \see IsRegistered
* \see UnregisterSocket
*/
bool SocketPoller::RegisterSocket(AbstractSocket& socket)
{
NazaraAssert(!IsRegistered(socket), "This socket is already registered in this SocketPoller");
return m_impl->RegisterSocket(socket.GetNativeHandle());
}
/*!
* \brief Unregister a socket from the SocketPoller
*
* After calling UnregisterSocket, the socket is no longer part of the SocketPoller and thus, not taken into account by any further Wait call until registered again.
*
* This function must be called before destroying a socket part of the SocketPoller.
*
* \remark It is an error to try to unregister a non-registered socket from a SocketPoller.
*
* \param socket Reference to the socket to unregister
*
* \see IsRegistered
* \see RegisterSocket
*/
void SocketPoller::UnregisterSocket(AbstractSocket& socket)
{
NazaraAssert(IsRegistered(socket), "This socket is not registered in this SocketPoller");
return m_impl->UnregisterSocket(socket.GetNativeHandle());
}
/*!
* \brief Wait until any registered socket switches to a ready state
*
* Waits a specific/undetermined amount of time until at least one socket part of the SocketPoller becomes ready.
* To query the ready state of the registered socket, use the IsReady function.
*
* \param msTimeout Maximum time to wait in milliseconds, 0 for infinity
*
* \remark It is an error to try to unregister a non-registered socket from a SocketPoller.
*
* \see IsReady
* \see RegisterSocket
*/
bool SocketPoller::Wait(UInt64 msTimeout)
{
SocketError error;
int readySockets = m_impl->Wait(msTimeout, &error);
if (error != SocketError_NoError)
{
NazaraError("SocketPoller encountered an error (code: 0x" + String::Number(error, 16) + ')');
return false;
}
return readySockets > 0;
}
}

View File

@@ -262,6 +262,17 @@ namespace Nz
if (m_pendingPacket.headerReceived)
{
UInt16 packetSize = static_cast<UInt16>(m_pendingPacket.data.GetSize()); //< Total packet size
if (packetSize == 0)
{
// Special case: our packet carry no data
packet->Reset(m_pendingPacket.netcode);
// And reset every state
m_pendingPacket.data.Clear();
m_pendingPacket.headerReceived = false;
m_pendingPacket.received = 0;
return true;
}
std::size_t received;
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received))

View File

@@ -13,12 +13,12 @@ namespace Nz
{
namespace Detail
{
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
using addrinfoImpl = addrinfoW;
int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results)
{
return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), &hints, &servinfo);
return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), hints, results);
}
int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags)
@@ -26,14 +26,14 @@ namespace Nz
std::array<wchar_t, NI_MAXHOST> hostnameBuffer;
std::array<wchar_t, NI_MAXSERV> serviceBuffer;
int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags);
int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), static_cast<DWORD>(hostnameBuffer.size()), serviceBuffer.data(), static_cast<DWORD>(serviceBuffer.size()), flags);
if (result == 0)
{
if (hostname)
hostname->Set(hostnameBuffer.data());
*hostname = std::move(String::Unicode(hostnameBuffer.data()));
if (service)
service->Set(serviceBuffer.data());
*service = std::move(String::Unicode(serviceBuffer.data()));
}
return result;
@@ -105,7 +105,7 @@ namespace Nz
return IpAddress::Invalid;
}
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info)
{
switch (info->ai_family)

View File

@@ -2,6 +2,11 @@
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_IPADDRESSIMPL_HPP
#define NAZARA_IPADDRESSIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -17,7 +22,7 @@ namespace Nz
~IpAddressImpl() = delete;
static IpAddress FromAddrinfo(const addrinfo* info);
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
static IpAddress FromAddrinfo(const addrinfoW* info);
#endif
static IpAddress FromSockAddr(const sockaddr* address);
@@ -33,3 +38,5 @@ namespace Nz
static ResolveError TranslateWSAErrorToResolveError(int error);
};
}
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@@ -7,18 +7,21 @@
#include <Nazara/Core/Log.hpp>
#include <Nazara/Network/Win32/IpAddressImpl.hpp>
#include <Winsock2.h>
#if defined(NAZARA_COMPILER_MINGW) && __GNUC__ < 5
// Some compilers (olders versions of MinGW) are lacking Mstcpip.h which defines the following struct/#define
// Define them ourself for now
struct tcp_keepalive
{
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#else
#include <Mstcpip.h>
#endif
#include <Winsock2.h>
#include <Nazara/Network/Debug.hpp>
@@ -412,6 +415,34 @@ namespace Nz
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
}
int SocketImpl::Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error)
{
NazaraAssert(fdarray && nfds > 0, "Invalid fdarray");
#if NAZARA_NETWORK_POLL_SUPPORT
static_assert(sizeof(PollSocket) == sizeof(WSAPOLLFD), "PollSocket size must match WSAPOLLFD size");
int result = WSAPoll(reinterpret_cast<WSAPOLLFD*>(fdarray), static_cast<ULONG>(nfds), timeout);
if (result == SOCKET_ERROR)
{
int errorCode = WSAGetLastError();
if (error)
*error = TranslateWSAErrorToSocketError(errorCode);
return 0;
}
if (error)
*error = SocketError_NoError;
return result;
#else
if (error)
*error = SocketError_NotSupported;
return 0;
#endif
}
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
{

View File

@@ -2,13 +2,27 @@
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h>
#define NAZARA_NETWORK_POLL_SUPPORT NAZARA_CORE_WINDOWS_NT6
namespace Nz
{
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl
{
public:
@@ -43,6 +57,8 @@ namespace Nz
static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr);
static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr);
static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error);
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@@ -66,3 +82,5 @@ namespace Nz
static WSADATA s_WSA;
};
}
#endif // NAZARA_SOCKETIMPL_HPP

View File

@@ -0,0 +1,149 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Win32/SocketPollerImpl.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
SocketPollerImpl::SocketPollerImpl()
{
#if !NAZARA_NETWORK_POLL_SUPPORT
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
#endif
}
void SocketPollerImpl::Clear()
{
#if NAZARA_NETWORK_POLL_SUPPORT
m_activeSockets.clear();
m_allSockets.clear();
m_sockets.clear();
#else
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
#endif
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_activeSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_activeSockets) != 0;
#endif
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_allSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_sockets) != 0;
#endif
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
#if NAZARA_NETWORK_POLL_SUPPORT
PollSocket entry = {
socket,
POLLRDNORM,
0
};
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
#else
if (m_sockets.fd_count > FD_SETSIZE)
{
NazaraError("Socket count exceeding FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
return false;
}
FD_SET(socket, &m_sockets);
#endif
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
#if NAZARA_NETWORK_POLL_SUPPORT
if (m_sockets.size() > 1U)
{
// Instead of using vector::erase, let's move the last element to the now unoccupied position
std::size_t entry = m_allSockets[socket];
// Get the last element and update it's position
const PollSocket& lastElement = m_sockets.back();
m_allSockets[lastElement.fd] = entry;
// Now move it properly (lastElement is invalid after the following line) and pop it
m_sockets[entry] = std::move(m_sockets.back());
}
m_sockets.pop_back();
m_activeSockets.erase(socket);
m_allSockets.erase(socket);
#else
FD_CLR(socket, &m_activeSockets);
FD_CLR(socket, &m_sockets);
#endif
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
int activeSockets;
#if NAZARA_NETWORK_POLL_SUPPORT
// Reset status of sockets
for (PollSocket& entry : m_sockets)
entry.revents = 0;
activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
{
m_activeSockets.insert(entry.fd);
if (--socketRemaining == 0)
break;
}
}
}
#else
m_activeSockets = m_sockets;
timeval tv;
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
activeSockets = ::select(0xDEADBEEF, &m_activeSockets, nullptr, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
if (activeSockets == SOCKET_ERROR)
{
if (error)
*error = SocketImpl::TranslateWSAErrorToSocketError(WSAGetLastError());
return 0;
}
if (error)
*error = SocketError_NoError;
#endif
return activeSockets;
}
}

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Win32/SocketImpl.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <winsock2.h>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl();
~SocketPollerImpl() = default;
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
#if NAZARA_NETWORK_POLL_SUPPORT
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
#else
fd_set m_sockets;
fd_set m_activeSockets;
#endif
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@@ -76,7 +76,7 @@ namespace Nz
code << "#define GLSL_VERSION " << glslVersion << "\n\n";
code << "#define EARLY_FRAGMENT_TEST " << (glslVersion >= 420 || OpenGL::IsSupported(OpenGLExtension_Shader_ImageLoadStore)) << "\n\n";
code << "#define EARLY_FRAGMENT_TEST " << ((glslVersion >= 420 || OpenGL::IsSupported(OpenGLExtension_Shader_ImageLoadStore)) ? '1' : '0') << "\n\n";
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n';

View File

@@ -37,6 +37,10 @@ namespace Nz
if (parameters.custom.GetBooleanParameter("SkipNativeOBJLoader", &skip) && skip)
return Ternary_False;
OBJParser parser;
if (!parser.Check(stream))
return Ternary_False;
return Ternary_Unknown;
}

View File

@@ -13,9 +13,87 @@
namespace Nz
{
bool OBJParser::Check(Stream& stream)
{
m_currentStream = &stream;
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
// Force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode;
if ((stream.GetStreamOptions() & StreamOption_Text) == 0)
{
stream.EnableTextMode(true);
resetTextMode.Reset([&stream] ()
{
stream.EnableTextMode(false);
});
}
unsigned int failureCount = 0;
while (Advance(false))
{
switch (std::tolower(m_currentLine[0]))
{
case '#': //< Comment
failureCount--;
break;
case 'f': //< Face
case 'g': //< Group (inside a mesh)
case 'o': //< Object (defines a mesh)
case 's': //< Smooth
{
if (m_currentLine.GetSize() > 1 && m_currentLine[1] == ' ')
return true;
break;
}
case 'm': //< MTLLib
if (m_currentLine.GetWord(0).ToLower() == "mtllib")
return true;
break;
case 'u': //< Usemtl
if (m_currentLine.GetWord(0).ToLower() == "usemtl")
return true;
break;
case 'v': //< Position/Normal/Texcoords
{
String word = m_currentLine.GetWord(0).ToLower();
if (word == 'v')
return true;
else if (word == "vn")
return true;
else if (word == "vt")
return true;
break;
}
default:
break;
}
if (++failureCount > 20U)
return false;
}
return false;
}
bool OBJParser::Parse(Nz::Stream& stream, UInt32 reservedVertexCount)
{
m_currentStream = &stream;
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
// Force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode;
@@ -31,9 +109,6 @@ namespace Nz
String matName, meshName;
matName = meshName = "default";
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
m_meshes.clear();
m_mtlLib.Clear();

View File

@@ -1284,6 +1284,9 @@ namespace Nz
bool PixelFormat::Initialize()
{
Bitset<> b32(0xFFFFFFFF);
b32.Resize(128);
// Setup informations about every pixel format
s_pixelFormatInfos[PixelFormatType_A8] = PixelFormatInfo("A8", PixelFormatContent_ColorRGBA, 0, 0, 0, 0xFF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_BGR8] = PixelFormatInfo("BGR8", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned);
@@ -1317,18 +1320,18 @@ namespace Nz
s_pixelFormatInfos[PixelFormatType_RGB16F] = PixelFormatInfo("RGB16F", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGB16I] = PixelFormatInfo("RGB16I", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB16UI] = PixelFormatInfo("RGB16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Float);
s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA4] = PixelFormatInfo("RGBA4", PixelFormatContent_ColorRGBA, 0xF000, 0x0F00, 0x00F0, 0x000F, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB5A1] = PixelFormatInfo("RGB5A1", PixelFormatContent_ColorRGBA, 0xF800, 0x07C0, 0x003E, 0x0001, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA8] = PixelFormatInfo("RGBA8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA16F] = PixelFormatInfo("RGBA16F", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGBA16I] = PixelFormatInfo("RGBA16I", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA16UI] = PixelFormatInfo("RGBA16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA32F] = PixelFormatInfo("RGBA32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA32F] = PixelFormatInfo("RGBA32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Float);
s_pixelFormatInfos[PixelFormatType_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth16] = PixelFormatInfo("Depth16", PixelFormatContent_DepthStencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth24] = PixelFormatInfo("Depth24", PixelFormatContent_DepthStencil, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth24Stencil8] = PixelFormatInfo("Depth24Stencil8", PixelFormatContent_DepthStencil, 0xFFFFFF00, 0x000000FF, 0, 0, PixelFormatSubType_Unsigned);

View File

@@ -102,10 +102,14 @@ namespace Nz
return false;
}
if (!Window::Initialize())
bool bParam;
if (!s_initializationParameters.GetBooleanParameter("NoWindowSystem", &bParam) || !bParam)
{
NazaraError("Failed to initialize window's system");
return false;
if (!Window::Initialize())
{
NazaraError("Failed to initialize window's system");
return false;
}
}
// On enregistre les loaders pour les extensions
@@ -147,6 +151,11 @@ namespace Nz
return s_moduleReferenceCounter != 0;
}
void Utility::SetParameters(const ParameterList& parameters)
{
s_initializationParameters = parameters;
}
void Utility::Uninitialize()
{
if (s_moduleReferenceCounter != 1)
@@ -227,5 +236,6 @@ namespace Nz
static_assert(ComponentType_Max+1 == 14, "Component stride array is incomplete");
ParameterList Utility::s_initializationParameters;
unsigned int Utility::s_moduleReferenceCounter = 0;
}

View File

@@ -29,6 +29,11 @@ namespace Nz
Window* fullscreenWindow = nullptr;
}
Window::~Window()
{
Destroy();
}
bool Window::Create(VideoMode mode, const String& title, UInt32 style)
{
// Si la fenêtre est déjà ouverte, nous conservons sa position

View File

@@ -9,7 +9,17 @@
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Utility/X11/Display.hpp>
#include <xcb/xcb_image.h>
#include <xcb/xcb_renderutil.h>
// Some older versions of xcb/util-renderutil (notably the one available on Travis CI) use `template` as an argument name
// This is a fixed bug (https://cgit.freedesktop.org/xcb/util-renderutil/commit/?id=8d15acc45a47dc4c922eee5b99885db42bc62c17) but until Travis-CI
// has upgraded their Ubuntu version, I'm forced to use this ugly trick.
#define template ptemplate
extern "C"
{
#include <xcb/xcb_renderutil.h>
}
#undef template
#include <Nazara/Utility/Debug.hpp>
namespace Nz