Merge remote-tracking branch 'upstream/master'

Conflicts:
	include/Nazara/Noise/NoiseMachine.hpp
	src/Nazara/Noise/ComplexNoiseBase.cpp
	src/Nazara/Noise/NoiseMachine.cpp

Former-commit-id: 54af2e19e336cfacee63cabe785d7b05fa392b53
This commit is contained in:
Remi Beges
2012-10-05 17:53:41 +02:00
332 changed files with 10964 additions and 23504 deletions

285
src/Nazara/Audio/Audio.cpp Normal file
View File

@@ -0,0 +1,285 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/Enums.hpp>
#include <Nazara/Audio/Loaders/sndfile.hpp>
#include <AL/al.h>
#include <AL/alc.h>
#include <Nazara/Audio/Debug.hpp>
namespace
{
ALenum formats[nzAudioFormat_Max+1] = {0};
ALCdevice* device = nullptr;
ALCcontext* context = nullptr;
}
nzAudioFormat NzAudio::GetAudioFormat(unsigned int channelCount)
{
switch (channelCount)
{
case 1:
case 2:
case 4:
case 6:
case 7:
case 8:
return static_cast<nzAudioFormat>(channelCount);
default:
NazaraError("Invalid channel count: " + NzString::Number(channelCount));
return nzAudioFormat_Unknown;
}
}
float NzAudio::GetDopplerFactor()
{
return alGetFloat(AL_DOPPLER_FACTOR);
}
float NzAudio::GetGlobalVolume()
{
ALfloat gain = 0.f;
alGetListenerf(AL_GAIN, &gain);
return gain*100.f;
}
NzVector3f NzAudio::GetListenerDirection()
{
ALfloat orientation[6];
alGetListenerfv(AL_ORIENTATION, orientation);
return NzVector3f(orientation[0], orientation[1], orientation[2]);
}
NzVector3f NzAudio::GetListenerPosition()
{
NzVector3f position;
alGetListenerfv(AL_POSITION, position);
return position;
}
/*
NzQuaternionf NzAudio::GetListenerRotation()
{
// http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another
float orientation[6];
alGetListenerfv(AL_ORIENTATION, orientation);
NzVector3f forward(orientation[0], orientation[1], orientation[2]);
NzVector3f up(orientation[3], orientation[4], orientation[5]);
NzQuaternionf rotation;
NzVector3f a = NzVector3f::CrossProduct(forward, up);
rotation.x = a.x;
rotation.y = a.y;
rotation.z = a.z;
rotation.w = std::sqrt(forward.SquaredLength() * up.SquaredLength()) + NzVector3f::DotProduct(forward, up);
return rotation;
}
*/
NzVector3f NzAudio::GetListenerVelocity()
{
NzVector3f velocity;
alGetListenerfv(AL_VELOCITY, velocity);
return velocity;
}
float NzAudio::GetSpeedOfSound()
{
return alGetFloat(AL_SPEED_OF_SOUND);
}
bool NzAudio::Initialize()
{
if (s_moduleReferenceCouter++ != 0)
return true; // Déjà initialisé
// Initialisation des dépendances
if (!NzCore::Initialize())
{
NazaraError("Failed to initialize core module");
return false;
}
// Initialisation du module
device = alcOpenDevice(nullptr); // On choisit le device par défaut
if (!device)
{
NazaraError("Failed to open default device");
return false;
}
// Un seul contexte nous suffira
context = alcCreateContext(device, nullptr);
if (!context)
{
NazaraError("Failed to create context");
alcCloseDevice(device);
return false;
}
if (!alcMakeContextCurrent(context))
{
NazaraError("Failed to activate context");
alcDestroyContext(context);
alcCloseDevice(device);
return false;
}
// Définition de l'orientation
/*{
NzVector3f forward = NzVector3f::Forward();
NzVector3f up = NzVector3f::Up();
ALfloat orientation[6] =
{
forward.x, forward.y, forward.z,
up.x, up.y, up.z
};
alListenerfv(AL_ORIENTATION, orientation);
}*/
formats[nzAudioFormat_Mono] = AL_FORMAT_MONO16;
formats[nzAudioFormat_Stereo] = AL_FORMAT_STEREO16;
formats[nzAudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16");
formats[nzAudioFormat_5_1] = alGetEnumValue("AL_FORMAT_51CHN16");
formats[nzAudioFormat_6_1] = alGetEnumValue("AL_FORMAT_61CHN16");
formats[nzAudioFormat_7_1] = alGetEnumValue("AL_FORMAT_71CHN16");
NzLoaders_sndfile_Register();
NazaraNotice("Initialized: Audio module");
return true;
}
bool NzAudio::IsFormatSupported(nzAudioFormat format)
{
if (format == nzAudioFormat_Unknown)
return false;
return formats[format] != 0;
}
bool NzAudio::IsInitialized()
{
return s_moduleReferenceCouter != 0;
}
void NzAudio::SetDopplerFactor(float dopplerFactor)
{
alDopplerFactor(dopplerFactor);
}
void NzAudio::SetGlobalVolume(float volume)
{
alListenerf(AL_GAIN, volume*0.01f);
}
void NzAudio::SetListenerDirection(const NzVector3f& direction)
{
ALfloat orientation[6] =
{
direction.x, direction.y, direction.z,
0.f, 1.f, 0.f
};
alListenerfv(AL_ORIENTATION, orientation);
}
void NzAudio::SetListenerDirection(float dirX, float dirY, float dirZ)
{
ALfloat orientation[6] =
{
dirX, dirY, dirZ,
0.f, 1.f, 0.f
};
alListenerfv(AL_ORIENTATION, orientation);
}
void NzAudio::SetListenerPosition(const NzVector3f& position)
{
alListenerfv(AL_POSITION, position);
}
void NzAudio::SetListenerPosition(float x, float y, float z)
{
alListener3f(AL_POSITION, x, y, z);
}
/*
void NzAudio::SetListenerRotation(const NzQuaternionf& rotation)
{
NzVector3f forward = rotation * NzVector3f::Forward();
NzVector3f up = NzVector3f::Up();
ALfloat orientation[6] =
{
forward.x, forward.y, forward.z,
up.x, up.y, up.z
};
alListenerfv(AL_ORIENTATION, orientation);
}
*/
void NzAudio::SetListenerVelocity(const NzVector3f& velocity)
{
alListenerfv(AL_VELOCITY, velocity);
}
void NzAudio::SetListenerVelocity(float velX, float velY, float velZ)
{
alListener3f(AL_VELOCITY, velX, velY, velZ);
}
void NzAudio::SetSpeedOfSound(float speed)
{
alSpeedOfSound(speed);
}
void NzAudio::Uninitialize()
{
if (--s_moduleReferenceCouter != 0)
return; // Encore utilisé
// Libération du module
alcMakeContextCurrent(nullptr);
alcDestroyContext(context);
if (!alcCloseDevice(device))
// Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation
NazaraWarning("Failed to close device");
NazaraNotice("Uninitialized: Audio module");
// Libération des dépendances
NzCore::Uninitialize();
}
unsigned int NzAudio::GetOpenALFormat(nzAudioFormat format)
{
#ifdef NAZARA_DEBUG
if (format == nzAudioFormat_Unknown)
{
NazaraInternalError("Invalid audio format");
return 0;
}
#endif
return formats[format];
}
unsigned int NzAudio::s_moduleReferenceCouter = 0;

View File

@@ -1,29 +0,0 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/Config.hpp>
#if NAZARA_AUDIO_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}
#endif

View File

@@ -0,0 +1,15 @@
// Copyright (C) 2012 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
#pragma once
#ifndef NAZARA_LOADERS_SNDFILE_HPP
#define NAZARA_LOADERS_SNDFILE_HPP
#include <Nazara/Prerequesites.hpp>
void NzLoaders_sndfile_Register();
void NzLoaders_sndfile_Unregister();
#endif // NAZARA_LOADERS_SNDFILE_HPP

View File

@@ -0,0 +1,135 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/Loaders/sndfile.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/SoundBuffer.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Core/MemoryStream.hpp>
#include <sndfile/sndfile.h>
#include <Nazara/Audio/Debug.hpp>
namespace
{
sf_count_t GetSize(void* user_data)
{
NzInputStream* stream = static_cast<NzInputStream*>(user_data);
return stream->GetSize();
}
sf_count_t Read(void* ptr, sf_count_t count, void* user_data)
{
NzInputStream* stream = static_cast<NzInputStream*>(user_data);
return stream->Read(ptr, count);
}
sf_count_t Seek(sf_count_t offset, int whence, void* user_data)
{
NzInputStream* stream = static_cast<NzInputStream*>(user_data);
switch (whence)
{
case SEEK_CUR:
stream->Read(nullptr, offset);
break;
case SEEK_END:
stream->SetCursorPos(stream->GetSize()+offset);
break;
case SEEK_SET:
stream->SetCursorPos(offset);
break;
default:
NazaraInternalError("Seek mode not handled");
}
return stream->GetCursorPos();
}
sf_count_t Tell(void* user_data)
{
NzInputStream* stream = reinterpret_cast<NzInputStream*>(user_data);
return stream->GetCursorPos();
}
static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell};
bool NzLoader_sndfile_Check(NzInputStream& stream, const NzSoundBufferParams& parameters)
{
NazaraUnused(parameters);
SF_INFO info;
SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream);
if (file)
{
sf_close(file);
return true;
}
else
return false;
}
bool NzLoader_sndfile_Load(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters)
{
NazaraUnused(parameters);
SF_INFO infos;
SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
if (!file)
{
NazaraError("Failed to load sound file: " + NzString(sf_strerror(file)));
return false;
}
nzAudioFormat format = NzAudio::GetAudioFormat(infos.channels);
if (format == nzAudioFormat_Unknown)
{
NazaraError("Channel count not handled");
sf_close(file);
return false;
}
unsigned int sampleCount = infos.frames*infos.channels;
nzInt16* samples = new nzInt16[sampleCount];
if (sf_read_short(file, samples, sampleCount) != sampleCount)
{
NazaraError("Failed to read samples");
delete[] samples;
sf_close(file);
return false;
}
if (!soundBuffer->Create(format, infos.frames*infos.channels, infos.samplerate, samples))
{
NazaraError("Failed to create sound buffer");
sf_close(file);
return false;
}
delete[] samples;
return true;
}
}
void NzLoaders_sndfile_Register()
{
NzSoundBufferLoader::RegisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve",
NzLoader_sndfile_Check,
NzLoader_sndfile_Load);
}
void NzLoaders_sndfile_Unregister()
{
NzSoundBufferLoader::UnregisterLoader("aiff,au,avr,caf,flac,htk,ircam,mat4,mat5,mpc2k,nist,ogg,paf,pvf,raw,rf64,sd2,sds,svx,voc,w64,wav,wve",
NzLoader_sndfile_Check,
NzLoader_sndfile_Load);
}

180
src/Nazara/Audio/Sound.cpp Normal file
View File

@@ -0,0 +1,180 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/Sound.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstring>
#include <stdexcept>
#include <AL/al.h>
#include <Nazara/Audio/Debug.hpp>
NzSound::NzSound(const NzSoundBuffer* soundBuffer)
{
SetBuffer(soundBuffer);
}
NzSound::NzSound(const NzSound& sound) :
NzSoundEmitter(sound)
{
SetBuffer(sound.m_buffer);
}
NzSound::~NzSound()
{
Stop();
if (m_buffer)
m_buffer->RemoveResourceReference();
}
void NzSound::EnableLooping(bool loop)
{
alSourcei(m_source, AL_LOOPING, loop);
}
const NzSoundBuffer* NzSound::GetBuffer() const
{
return m_buffer;
}
nzUInt32 NzSound::GetDuration() const
{
#if NAZARA_AUDIO_SAFE
if (!m_buffer)
{
NazaraError("No sound buffer");
return 0;
}
#endif
return m_buffer->GetDuration();
}
nzUInt32 NzSound::GetPlayingOffset() const
{
ALfloat seconds = -1.f;
alGetSourcef(m_source, AL_SEC_OFFSET, &seconds);
return static_cast<nzUInt32>(seconds*1000);
}
nzSoundStatus NzSound::GetStatus() const
{
return GetInternalStatus();
}
bool NzSound::IsLooping() const
{
ALint loop;
alGetSourcei(m_source, AL_LOOPING, &loop);
return loop != AL_FALSE;
}
bool NzSound::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
{
NzSoundBuffer* buffer = new NzSoundBuffer;
if (!buffer->LoadFromFile(filePath, params))
{
NazaraError("Failed to load buffer from file (" + filePath + ')');
delete buffer;
return false;
}
SetBuffer(buffer);
buffer->SetPersistent(false);
return true;
}
bool NzSound::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
{
NzSoundBuffer* buffer = new NzSoundBuffer;
if (!buffer->LoadFromMemory(data, size, params))
{
NazaraError("Failed to load buffer from memory (" + NzString::Pointer(data) + ')');
delete buffer;
return false;
}
SetBuffer(buffer);
buffer->SetPersistent(false);
return true;
}
bool NzSound::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
{
NzSoundBuffer* buffer = new NzSoundBuffer;
if (!buffer->LoadFromStream(stream, params))
{
NazaraError("Failed to load buffer from stream");
delete buffer;
return false;
}
SetBuffer(buffer);
buffer->SetPersistent(false);
return true;
}
void NzSound::Pause()
{
alSourcePause(m_source);
}
bool NzSound::Play()
{
#if NAZARA_AUDIO_SAFE
if (!m_buffer)
{
NazaraError("No sound buffer to play");
return false;
}
#endif
alSourcePlay(m_source);
return true;
}
void NzSound::SetBuffer(const NzSoundBuffer* buffer)
{
if (m_buffer == buffer)
return;
Stop();
if (m_buffer)
m_buffer->RemoveResourceReference();
m_buffer = buffer;
if (m_buffer)
{
m_buffer->AddResourceReference();
alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer());
}
else
alSourcei(m_source, AL_BUFFER, AL_NONE);
}
void NzSound::SetPlayingOffset(nzUInt32 offset)
{
alSourcef(m_source, AL_SEC_OFFSET, offset/1000.f);
}
void NzSound::Stop()
{
alSourceStop(m_source);
}

View File

@@ -0,0 +1,229 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Audio/SoundBuffer.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstring>
#include <stdexcept>
#include <AL/al.h>
#include <Nazara/Audio/Debug.hpp>
///FIXME: Adapter la création
bool NzSoundBufferParams::IsValid() const
{
return true;
}
struct NzSoundBufferImpl
{
ALuint buffer;
nzAudioFormat format;
nzUInt32 duration;
nzInt16* samples;
unsigned int sampleCount;
unsigned int sampleRate;
};
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
{
Create(format, sampleCount, sampleRate, samples);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create sound buffer");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzSoundBuffer::~NzSoundBuffer()
{
Destroy();
}
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
{
Destroy();
#if NAZARA_AUDIO_SAFE
if (!IsFormatSupported(format))
{
NazaraError("Audio format is not supported");
return false;
}
if (sampleCount == 0)
{
NazaraError("Sample rate must be different from zero");
return false;
}
if (sampleRate == 0)
{
NazaraError("Sample rate must be different from zero");
return false;
}
if (!samples)
{
NazaraError("Invalid sample source");
return false;
}
#endif
// On vide le stack d'erreurs
while (alGetError() != AL_NO_ERROR);
ALuint buffer;
alGenBuffers(1, &buffer);
if (alGetError() != AL_NO_ERROR)
{
NazaraError("Failed to create OpenAL buffer");
return false;
}
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
if (alGetError() != AL_NO_ERROR)
{
NazaraError("Failed to set OpenAL buffer");
alDeleteBuffers(1, &buffer);
return false;
}
m_impl = new NzSoundBufferImpl;
m_impl->buffer = buffer;
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
m_impl->format = format;
m_impl->sampleCount = sampleCount;
m_impl->sampleRate = sampleRate;
m_impl->samples = new nzInt16[sampleCount];
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
NotifyCreated();
return true;
}
void NzSoundBuffer::Destroy()
{
if (m_impl)
{
NotifyDestroy();
delete[] m_impl->samples;
delete m_impl;
m_impl = nullptr;
}
}
nzUInt32 NzSoundBuffer::GetDuration() const
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Sound buffer not created");
return 0;
}
#endif
return m_impl->duration;
}
nzAudioFormat NzSoundBuffer::GetFormat() const
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Sound buffer not created");
return nzAudioFormat_Unknown;
}
#endif
return m_impl->format;
}
const nzInt16* NzSoundBuffer::GetSamples() const
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Sound buffer not created");
return nullptr;
}
#endif
return m_impl->samples;
}
unsigned int NzSoundBuffer::GetSampleCount() const
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Sound buffer not created");
return 0;
}
#endif
return m_impl->sampleCount;
}
unsigned int NzSoundBuffer::GetSampleRate() const
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Sound buffer not created");
return 0;
}
#endif
return m_impl->sampleRate;
}
bool NzSoundBuffer::IsValid() const
{
return m_impl != nullptr;
}
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
{
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
}
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
{
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
}
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
{
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
}
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
{
return NzAudio::IsFormatSupported(format);
}
unsigned int NzSoundBuffer::GetOpenALBuffer() const
{
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraInternalError("Sound buffer not created");
return AL_NONE;
}
#endif
return m_impl->buffer;
}
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;

View File

@@ -0,0 +1,156 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// http://connect.creativelabs.com/openal/Documentation/OpenAL_Programmers_Guide.pdf
#include <Nazara/Audio/SoundEmitter.hpp>
#include <Nazara/Core/Error.hpp>
#include <AL/al.h>
#include <Nazara/Audio/Debug.hpp>
NzSoundEmitter::NzSoundEmitter()
{
alGenSources(1, &m_source);
}
NzSoundEmitter::NzSoundEmitter(const NzSoundEmitter& emitter)
{
alGenSources(1, &m_source);
SetAttenuation(emitter.GetAttenuation());
SetMinDistance(emitter.GetMinDistance());
SetPitch(emitter.GetPitch());
// Pas de copie de position ou de vitesse
SetVolume(emitter.GetVolume());
}
NzSoundEmitter::~NzSoundEmitter()
{
alDeleteSources(1, &m_source);
}
void NzSoundEmitter::EnableSpatialization(bool spatialization)
{
alSourcei(m_source, AL_SOURCE_RELATIVE, spatialization);
}
float NzSoundEmitter::GetAttenuation() const
{
ALfloat attenuation;
alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation);
return attenuation;
}
float NzSoundEmitter::GetMinDistance() const
{
ALfloat distance;
alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance);
return distance;
}
float NzSoundEmitter::GetPitch() const
{
ALfloat pitch;
alGetSourcef(m_source, AL_PITCH, &pitch);
return pitch;
}
NzVector3f NzSoundEmitter::GetPosition() const
{
NzVector3f position;
alGetSourcefv(m_source, AL_POSITION, position);
return position;
}
NzVector3f NzSoundEmitter::GetVelocity() const
{
NzVector3f velocity;
alGetSourcefv(m_source, AL_VELOCITY, velocity);
return velocity;
}
float NzSoundEmitter::GetVolume() const
{
ALfloat gain;
alGetSourcef(m_source, AL_GAIN, &gain);
return gain * 100.f;
}
bool NzSoundEmitter::IsSpatialized() const
{
ALint relative;
alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative);
return relative != AL_FALSE;
}
void NzSoundEmitter::SetAttenuation(float attenuation)
{
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
}
void NzSoundEmitter::SetMinDistance(float minDistance)
{
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
}
void NzSoundEmitter::SetPitch(float pitch)
{
alSourcef(m_source, AL_PITCH, pitch);
}
void NzSoundEmitter::SetPosition(const NzVector3f& position)
{
alSourcefv(m_source, AL_POSITION, position);
}
void NzSoundEmitter::SetPosition(float x, float y, float z)
{
alSource3f(m_source, AL_POSITION, x, y, z);
}
void NzSoundEmitter::SetVelocity(const NzVector3f& velocity)
{
alSourcefv(m_source, AL_VELOCITY, velocity);
}
void NzSoundEmitter::SetVelocity(float velX, float velY, float velZ)
{
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
}
void NzSoundEmitter::SetVolume(float volume)
{
alSourcef(m_source, AL_GAIN, volume*0.01f);
}
nzSoundStatus NzSoundEmitter::GetInternalStatus() const
{
ALint state;
alGetSourcei(m_source, AL_SOURCE_STATE, &state);
switch (state)
{
case AL_INITIAL:
case AL_STOPPED:
return nzSoundStatus_Stopped;
case AL_PAUSED:
return nzSoundStatus_Paused;
case AL_PLAYING:
return nzSoundStatus_Playing;
default:
NazaraInternalError("Source state unrecognized");
}
return nzSoundStatus_Stopped;
}

View File

@@ -1,4 +1,9 @@
/*#include <Nazara/Core/ByteArray.hpp>
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
/*
#include <Nazara/Core/ByteArray.hpp>
#include <algorithm>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
@@ -12,7 +17,7 @@ inline unsigned int nzPow2(unsigned int n)
return x;
}
// Cet algorithme est inspiré de la documentation de Qt
// Cet algorithme est inspiré de la documentation de Qt
inline unsigned int nzGetNewSize(unsigned int newSize)
{
if (newSize < 20)
@@ -56,7 +61,7 @@ m_sharedArray(buffer.m_sharedArray)
}
}
NzByteArray::NzByteArray(NzByteArray&& buffer) :
NzByteArray::NzByteArray(NzByteArray&& buffer) noexcept :
m_sharedArray(buffer.m_sharedArray)
{
buffer.m_sharedArray = &emptyArray;
@@ -146,7 +151,7 @@ NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bu
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
// Si le buffer est déjà suffisamment grand
// Si le buffer est déjà suffisamment grand
if (m_sharedArray->capacity >= m_sharedArray->size + bufferLength)
{
EnsureOwnership();
@@ -195,7 +200,7 @@ NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray)
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
// Si le buffer est déjà suffisamment grand
// Si le buffer est déjà suffisamment grand
if (m_sharedArray->capacity >= m_sharedArray->size + string.m_sharedArray->size)
{
EnsureOwnership();

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Clock.hpp>
@@ -15,6 +15,24 @@
#include <Nazara/Core/Debug.hpp>
namespace
{
nzUInt64 NzGetMicrosecondsLowPrecision()
{
return NzClockImplGetMilliseconds()*1000ULL;
}
nzUInt64 NzGetMicrosecondsFirstRun()
{
if (NzClockImplInitializeHighPrecision())
NzGetMicroseconds = NzClockImplGetMicroseconds;
else
NzGetMicroseconds = NzGetMicrosecondsLowPrecision;
return NzGetMicroseconds();
}
}
NzClock::NzClock() :
m_elapsedTime(0),
m_refTime(NzGetMicroseconds()),
@@ -81,20 +99,5 @@ void NzClock::Unpause()
NazaraWarning("Clock is not paused, ignoring...");
}
nzUInt64 NzGetMicrosecondsLowPrecision()
{
return NzClockImplGetMilliseconds()*1000ULL;
}
nzUInt64 NzGetMicrosecondsFirstRun()
{
if (NzClockImplInitializeHighPrecision())
NzGetMicroseconds = NzClockImplGetMicroseconds;
else
NzGetMicroseconds = NzGetMicrosecondsLowPrecision;
return NzGetMicroseconds();
}
NzClockFunction NzGetMicroseconds = NzGetMicrosecondsFirstRun;
NzClockFunction NzGetMilliseconds = NzClockImplGetMilliseconds;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Color.hpp>

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Mutex.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/ConditionVariableImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/ConditionVariableImpl.hpp>
#else
#error Thread condition has no implementation
#endif
#include <Nazara/Core/Debug.hpp>
NzConditionVariable::NzConditionVariable()
{
m_impl = new NzConditionVariableImpl;
}
NzConditionVariable::~NzConditionVariable()
{
delete m_impl;
}
void NzConditionVariable::Signal()
{
m_impl->Signal();
}
void NzConditionVariable::SignalAll()
{
m_impl->SignalAll();
}
void NzConditionVariable::Wait(NzMutex* mutex)
{
m_impl->Wait(mutex->m_impl);
}
bool NzConditionVariable::Wait(NzMutex* mutex, nzUInt32 timeout)
{
return m_impl->Wait(mutex->m_impl, timeout);
}

39
src/Nazara/Core/Core.cpp Normal file
View File

@@ -0,0 +1,39 @@
// Copyright (C) 2012 AUTHORS
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/Debug.hpp>
bool NzCore::Initialize()
{
if (s_moduleReferenceCouter++ != 0)
return true; // Déjà initialisé
// Initialisation du module
// Le noyau de Nazara n'a pour l'instant aucun besoin d'initialisation, mais dans le futur il est très probable que ce soit le cas.
// Donc en prévision, tous les modules initialisent le noyau
NazaraNotice("Initialized: Core");
return true;
}
bool NzCore::IsInitialized()
{
return s_moduleReferenceCouter != 0;
}
void NzCore::Uninitialize()
{
if (--s_moduleReferenceCouter != 0)
return; // Encore utilisé
// Libération du module
NazaraNotice("Uninitialized: Core");
}
unsigned int NzCore::s_moduleReferenceCouter = 0;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Config.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
@@ -73,7 +73,14 @@ void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file,
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
if (!ptr)
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
{
// Pas d'information de temps (Car nécessitant une allocation)
FILE* log = std::fopen(MLTFileName, "a");
std::fprintf(log, "Failed to allocate memory (%d bytes)\n", size);
std::fclose(log);
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
}
ptr->array = multi;
ptr->file = file;
@@ -119,19 +126,16 @@ void NzMemoryManager::Free(void* pointer, bool multi)
if (nextFreeFile)
{
if (multi)
std::fprintf(log, "%s Warning: delete[] on new at %s:%d\n", time, nextFreeFile, nextFreeLine);
std::fprintf(log, "%s Warning: delete[] after new at %s:%d\n", time, nextFreeFile, nextFreeLine);
else
std::fprintf(log, "%s Warning: delete on new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
nextFreeFile = nullptr;
nextFreeLine = 0;
std::fprintf(log, "%s Warning: delete after new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
}
else
{
if (multi)
std::fprintf(log, "%s Warning: delete[] on new at unknown position\n", time);
std::fprintf(log, "%s Warning: delete[] after new at unknown position\n", time);
else
std::fprintf(log, "%s Warning: delete on new[] at unknown position\n", time);
std::fprintf(log, "%s Warning: delete after new[] at unknown position\n", time);
}
std::fclose(log);
@@ -145,6 +149,9 @@ void NzMemoryManager::Free(void* pointer, bool multi)
std::free(ptr);
nextFreeFile = nullptr;
nextFreeLine = 0;
#if defined(NAZARA_PLATFORM_WINDOWS)
LeaveCriticalSection(&mutex);
#elif defined(NAZARA_PLATFORM_POSIX)

View File

@@ -1,12 +1,12 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Directory.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
//#include <Nazara/ThreadLocalVar.h>
//#include <Nazara/Core/ThreadLocal.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/DirectoryImpl.hpp>
@@ -21,18 +21,18 @@
namespace
{
NzString currentPath(NzDirectoryImpl::GetCurrent());
//static ThreadLocalVar<NzString> currentPath(NzDirectoryImpl::GetCurrent());
//static ThreadLocal<NzString> currentPath(NzDirectoryImpl::GetCurrent());
}
NzDirectory::NzDirectory() :
m_impl(nullptr)
m_pattern('*')
{
}
NzDirectory::NzDirectory(const NzString& dirPath) :
m_impl(nullptr)
m_dirPath(dirPath),
m_pattern('*')
{
SetDirectory(dirPath);
}
NzDirectory::~NzDirectory()
@@ -42,18 +42,27 @@ NzDirectory::~NzDirectory()
void NzDirectory::Close()
{
NazaraLock(m_mutex);
if (m_impl)
{
m_impl->Close();
delete m_impl;
m_impl = nullptr;
NazaraMutexUnlock(m_mutex);
}
}
NzString NzDirectory::GetPattern() const
{
NazaraLock(m_mutex);
return m_pattern;
}
NzString NzDirectory::GetResultName() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
{
@@ -67,6 +76,8 @@ NzString NzDirectory::GetResultName() const
NzString NzDirectory::GetResultPath() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
{
@@ -80,6 +91,8 @@ NzString NzDirectory::GetResultPath() const
nzUInt64 NzDirectory::GetResultSize() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
{
@@ -91,8 +104,17 @@ nzUInt64 NzDirectory::GetResultSize() const
return m_impl->GetResultSize();
}
bool NzDirectory::IsOpen() const
{
NazaraLock(m_mutex);
return m_impl != nullptr;
}
bool NzDirectory::IsResultDirectory() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
{
@@ -106,6 +128,8 @@ bool NzDirectory::IsResultDirectory() const
bool NzDirectory::NextResult(bool skipDots)
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
{
@@ -114,41 +138,40 @@ bool NzDirectory::NextResult(bool skipDots)
}
#endif
if (skipDots)
NzString name;
do
{
NzString name;
do
{
if (!m_impl->NextResult())
return false;
if (!m_impl->NextResult())
return false;
name = m_impl->GetResultName();
}
while (name == '.' || name == "..");
name = m_impl->GetResultName();
return true;
if (skipDots && (name == '.' || name == ".."))
continue;
if (name.Match(m_pattern))
break;
}
else
return m_impl->NextResult();
while (true);
return true;
}
bool NzDirectory::Open()
{
NazaraLock(m_mutex);
Close();
if (!Exists(m_dirPath))
return false;
NazaraMutexLock(m_mutex);
m_impl = new NzDirectoryImpl(this);
if (!m_impl->Open(m_dirPath))
{
delete m_impl;
m_impl = nullptr;
NazaraMutexUnlock(m_mutex);
return false;
}
@@ -157,11 +180,20 @@ bool NzDirectory::Open()
void NzDirectory::SetDirectory(const NzString& dirPath)
{
NazaraLock(m_mutex);
Close();
m_dirPath = NzFile::AbsolutePath(dirPath);
}
void NzDirectory::SetPattern(const NzString& pattern)
{
NazaraLock(m_mutex);
m_pattern = pattern;
}
bool NzDirectory::Copy(const NzString& sourcePath, const NzString& destPath)
{
if (sourcePath.IsEmpty() || destPath.IsEmpty())
@@ -187,12 +219,12 @@ bool NzDirectory::Copy(const NzString& sourcePath, const NzString& destPath)
{
if (dir.IsResultDirectory())
{
if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
return false;
}
else if (!NzFile::Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
{
NazaraError("Unable to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"');
NazaraError("Failed to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"');
return false;
}
}
@@ -215,7 +247,7 @@ bool NzDirectory::Create(const NzString& dirPath, bool recursive)
return false;
#ifdef NAZARA_PLATFORM_WINDOWS
// Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop")
// Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop")
if (path.Match("\\\\*"))
{
foundPos = path.Find('\\', 2);
@@ -272,7 +304,7 @@ bool NzDirectory::Remove(const NzString& dirPath, bool emptyDirectory)
{
NzDirectory dir(dirPath);
if (!dir.Open())
return NzDirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer
return NzDirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer
while (dir.NextResult(true))
{

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/DynLib.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
@@ -42,7 +42,7 @@ NzString NzGetLastSystemError(unsigned int code)
wchar_t* buffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
0,
nullptr,
code,
0,
reinterpret_cast<LPWSTR>(&buffer),
@@ -52,7 +52,7 @@ NzString NzGetLastSystemError(unsigned int code)
NzString error(NzString::Unicode(buffer));
LocalFree(buffer);
error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message
error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message
return error;
#elif defined(NAZARA_PLATFORM_POSIX)

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/File.hpp>
@@ -45,7 +45,7 @@ m_openMode(0)
Open(openMode);
}
NzFile::NzFile(NzFile&& file) :
NzFile::NzFile(NzFile&& file) noexcept :
m_endianness(file.m_endianness),
m_filePath(std::move(file.m_filePath)),
m_impl(file.m_impl),
@@ -100,6 +100,11 @@ bool NzFile::EndOfFile() const
return m_impl->EndOfFile();
}
bool NzFile::EndOfStream() const
{
return EndOfFile();
}
bool NzFile::Exists() const
{
NazaraLock(m_mutex)
@@ -188,72 +193,6 @@ time_t NzFile::GetLastWriteTime() const
return GetLastWriteTime(m_filePath);
}
NzString NzFile::GetLine(unsigned int lineSize)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return NzString();
}
if ((m_openMode & ReadOnly) == 0 && (m_openMode & ReadWrite) == 0)
{
NazaraError("File not opened with read access");
return NzString();
}
#endif
NzString line;
if (lineSize == 0) // Taille maximale indéterminée
{
while (!m_impl->EndOfFile())
{
char c;
if (m_impl->Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
{
if (m_openMode & Text && line.EndsWith('\r'))
line.Resize(-1);
break;
}
line += c;
}
else
break;
}
}
else
{
line.Reserve(lineSize);
for (unsigned int i = 0; i < lineSize; ++i)
{
char c;
if (m_impl->Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
{
if (m_openMode & Text && line.EndsWith('\r'))
line.Resize(-1);
break;
}
line += c;
}
else
break;
}
}
return line;
}
nzUInt64 NzFile::GetSize() const
{
NazaraLock(m_mutex)
@@ -293,7 +232,7 @@ std::size_t NzFile::Read(void* buffer, std::size_t size)
return m_impl->Read(buffer, size);
else
{
// Si nous ne devons rien lire, nous avançons simplement
// Si nous ne devons rien lire, nous avançons simplement
nzUInt64 currentPos = m_impl->GetCursorPos();
m_impl->SetCursorPos(NzFile::AtCurrent, size);
@@ -308,7 +247,7 @@ std::size_t NzFile::Read(void* buffer, std::size_t typeSize, unsigned int count)
if (byteRead == 0)
return 0;
if (buffer && m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness() && typeSize != 1)
if (buffer && typeSize != 1 && m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness())
{
unsigned int typeCount = byteRead/typeSize;
for (unsigned int i = 0; i < typeCount; ++i)
@@ -359,6 +298,9 @@ bool NzFile::Open(unsigned long openMode)
return false;
}
if (m_openMode & Text)
m_streamOptions &= nzStreamOption_Text;
return true;
}
@@ -446,6 +388,9 @@ bool NzFile::SetOpenMode(unsigned int openMode)
delete m_impl;
m_impl = impl;
if (m_openMode & Text)
m_streamOptions &= nzStreamOption_Text;
}
m_openMode = openMode;
@@ -459,12 +404,12 @@ bool NzFile::Write(const NzString& string)
NzString temp(string);
if (m_openMode & Text)
if (m_streamOptions & nzStreamOption_Text)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
temp.Replace("\n", "\r\n");
#elif defined(NAZARA_PLATFORM_LINUX)
// Rien à faire
// Rien à faire
#elif defined(NAZARA_PLATFORM_MACOS)
temp.Replace('\n', '\r');
#else
@@ -525,7 +470,7 @@ NzFile& NzFile::operator=(const NzString& filePath)
return *this;
}
NzFile& NzFile::operator=(NzFile&& file)
NzFile& NzFile::operator=(NzFile&& file) noexcept
{
NazaraLock(m_mutex)
@@ -554,7 +499,7 @@ NzString NzFile::AbsolutePath(const NzString& filePath)
base = "\\\\";
start = 2;
}
else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
{
NzString drive = NzDirectory::GetCurrent().SubstrTo('\\');
NzString end = path.Substr(1, -1);
@@ -570,7 +515,7 @@ NzString NzFile::AbsolutePath(const NzString& filePath)
NazaraError("Path unrecognized");
return path;
}
#elif NAZARA_PLATEFORM_LINUX
#elif defined(NAZARA_PLATEFORM_LINUX)
base = '/';
start = 0;
#else
@@ -594,7 +539,7 @@ NzString NzFile::AbsolutePath(const NzString& filePath)
sep.erase(sep.begin() + i--);
else if (sep[i] == "..")
{
if (i > start) // Si nous ne sommes pas dans la partie protégée
if (i > start) // Si nous ne sommes pas dans la partie protégée
sep.erase(sep.begin() + i--);
sep.erase(sep.begin() + i--);
@@ -605,7 +550,7 @@ NzString NzFile::AbsolutePath(const NzString& filePath)
pathLen += sep.size()-1;
///FIXME: Le destructeur de NzStringStream provoque un bug lors de la libération de son vector
///FIXME: Le destructeur de NzStringStream provoque un bug lors de la libération de son vector
//NzStringStream stream(base);
NzString stream;
@@ -714,11 +659,11 @@ bool NzFile::IsAbsolute(const NzString& path)
return true;
else if (path.Match("\\\\*"))
return true;
else if (wpath.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
else if (wpath.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
return true;
else
return false;
#elif NAZARA_PLATEFORM_LINUX
#elif defined(NAZARA_PLATEFORM_LINUX)
return wpath.StartsWith('/');
#else
#error OS case not implemented
@@ -752,7 +697,7 @@ NzString NzFile::NormalizeSeparators(const NzString& filePath)
#elif defined(NAZARA_PLATFORM_LINUX)
path.Replace('\\', '/');
#else
#error OS not handled
#error OS case not implemented
#endif
return path;
@@ -793,4 +738,4 @@ bool NzFile::FillHash(NzHashImpl* hash) const
}
return true;
} // Fermeture auttomatique du fichier
} // Fermeture automatique du fichier

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/CRC32.hpp>
@@ -70,7 +70,7 @@ NzHashCRC32::NzHashCRC32(nzUInt32 polynomial)
m_state = new NzHashCRC32_state;
if (polynomial == 0x04c11db7)
m_state->table = crc32_table; // Table précalculée (Bien plus rapide)
m_state->table = crc32_table; // Table précalculée (Bien plus rapide)
else
{
nzUInt32* table = new nzUInt32[256];

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/Fletcher16.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
/*
@@ -136,7 +136,7 @@ namespace
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - reinterpret_cast<const nzUInt8*>(0)) & 3))
if (!(data - static_cast<const nzUInt8*>(nullptr)) & 3)
{
/* data are properly aligned */
X = reinterpret_cast<const nzUInt32*>(data);

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
/*
@@ -315,119 +315,122 @@ void SHA1_Init(SHA_CTX* context)
(b) = ROTL32(30, b); \
j++;
void SHA1_Internal_Transform(SHA_CTX* context, const nzUInt32* data)
namespace
{
nzUInt32 a, b, c, d, e;
nzUInt32 T1, *W1;
int j;
void SHA1_Internal_Transform(SHA_CTX* context, const nzUInt32* data)
{
nzUInt32 a, b, c, d, e;
nzUInt32 T1, *W1;
int j;
W1 = reinterpret_cast<nzUInt32*>(context->s1.buffer);
W1 = reinterpret_cast<nzUInt32*>(context->s1.buffer);
/* Initialize registers with the prev. intermediate value */
a = context->s1.state[0];
b = context->s1.state[1];
c = context->s1.state[2];
d = context->s1.state[3];
e = context->s1.state[4];
/* Initialize registers with the prev. intermediate value */
a = context->s1.state[0];
b = context->s1.state[1];
c = context->s1.state[2];
d = context->s1.state[3];
e = context->s1.state[4];
j = 0;
j = 0;
/* Rounds 0 to 15 unrolled: */
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
/* Rounds 0 to 15 unrolled: */
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
ROUND1_0_TO_15(e,a,b,c,d);
ROUND1_0_TO_15(d,e,a,b,c);
ROUND1_0_TO_15(c,d,e,a,b);
ROUND1_0_TO_15(b,c,d,e,a);
ROUND1_0_TO_15(a,b,c,d,e);
/* Rounds 16 to 19 unrolled: */
ROUND1_16_TO_19(e,a,b,c,d);
ROUND1_16_TO_19(d,e,a,b,c);
ROUND1_16_TO_19(c,d,e,a,b);
ROUND1_16_TO_19(b,c,d,e,a);
/* Rounds 16 to 19 unrolled: */
ROUND1_16_TO_19(e,a,b,c,d);
ROUND1_16_TO_19(d,e,a,b,c);
ROUND1_16_TO_19(c,d,e,a,b);
ROUND1_16_TO_19(b,c,d,e,a);
/* Rounds 20 to 39 unrolled: */
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
/* Rounds 20 to 39 unrolled: */
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
ROUND1_20_TO_39(a,b,c,d,e);
ROUND1_20_TO_39(e,a,b,c,d);
ROUND1_20_TO_39(d,e,a,b,c);
ROUND1_20_TO_39(c,d,e,a,b);
ROUND1_20_TO_39(b,c,d,e,a);
/* Rounds 40 to 59 unrolled: */
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
/* Rounds 40 to 59 unrolled: */
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
ROUND1_40_TO_59(a,b,c,d,e);
ROUND1_40_TO_59(e,a,b,c,d);
ROUND1_40_TO_59(d,e,a,b,c);
ROUND1_40_TO_59(c,d,e,a,b);
ROUND1_40_TO_59(b,c,d,e,a);
/* Rounds 60 to 79 unrolled: */
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
/* Rounds 60 to 79 unrolled: */
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
ROUND1_60_TO_79(a,b,c,d,e);
ROUND1_60_TO_79(e,a,b,c,d);
ROUND1_60_TO_79(d,e,a,b,c);
ROUND1_60_TO_79(c,d,e,a,b);
ROUND1_60_TO_79(b,c,d,e,a);
/* Compute the current intermediate hash value */
context->s1.state[0] += a;
context->s1.state[1] += b;
context->s1.state[2] += c;
context->s1.state[3] += d;
context->s1.state[4] += e;
/* Compute the current intermediate hash value */
context->s1.state[0] += a;
context->s1.state[1] += b;
context->s1.state[2] += c;
context->s1.state[3] += d;
context->s1.state[4] += e;
}
}
void SHA1_Update(SHA_CTX* context, const nzUInt8* data, std::size_t len)
@@ -766,9 +769,12 @@ void SHA224_Init(SHA_CTX* context)
SHA256_Internal_Init(context, sha224_initial_hash_value);
}
void SHA224_Internal_Transform(SHA_CTX* context, const nzUInt32* data)
namespace
{
SHA256_Internal_Transform(context, data);
void SHA224_Internal_Transform(SHA_CTX* context, const nzUInt32* data)
{
SHA256_Internal_Transform(context, data);
}
}
void SHA224_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len)

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
/*

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/SHA1.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/SHA224.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/SHA256.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/SHA384.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/SHA512.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
/**

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/HashDigest.hpp>
@@ -42,7 +42,7 @@ m_digestLength(rhs.m_digestLength)
m_digest = nullptr;
}
NzHashDigest::NzHashDigest(NzHashDigest&& rhs) :
NzHashDigest::NzHashDigest(NzHashDigest&& rhs) noexcept :
m_hashName(std::move(rhs.m_hashName)),
m_digest(rhs.m_digest),
m_digestLength(rhs.m_digestLength)
@@ -118,7 +118,7 @@ NzHashDigest& NzHashDigest::operator=(const NzHashDigest& rhs)
return *this;
}
NzHashDigest& NzHashDigest::operator=(NzHashDigest&& rhs)
NzHashDigest& NzHashDigest::operator=(NzHashDigest&& rhs) noexcept
{
std::swap(m_hashName, rhs.m_hashName);
std::swap(m_digest, rhs.m_digest);

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hashable.hpp>

View File

@@ -1,8 +1,52 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/InputStream.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Core/Debug.hpp>
NzInputStream::~NzInputStream() = default;
NzString NzInputStream::GetLine(unsigned int lineSize)
{
NzString line;
if (lineSize == 0) // Taille maximale indéterminée
{
while (!EndOfStream())
{
char c;
if (Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
break;
line += c;
}
else
break;
}
}
else
{
line.Reserve(lineSize);
for (unsigned int i = 0; i < lineSize; ++i)
{
char c;
if (Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
break;
line += c;
}
else
break;
}
}
if (m_streamOptions & nzStreamOption_Text && !EndOfStream() && line.EndsWith('\r'))
line.Resize(-1);
return line;
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/LockGuard.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Log.hpp>
@@ -8,8 +8,9 @@
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Math/Basic.hpp>
#include <ctime>
#include <cstring>
#if NAZARA_CORE_REDIRECT_TO_CERR_ON_LOG_FAILURE
#if NAZARA_CORE_DUPLICATE_TO_COUT
#include <cstdio>
#endif
@@ -17,7 +18,7 @@
namespace
{
NzString errorType[] = {
const char* errorType[] = {
"Assert failed: ", // nzErrorType_AssertFailed
"Internal error: ", // nzErrorType_Internal
"Error: ", // nzErrorType_Normal
@@ -124,12 +125,11 @@ void NzLog::Write(const NzString& string)
line += string;
line += '\n';
#if NAZARA_CORE_REDIRECT_TO_CERR_ON_LOG_FAILURE
if (!m_file->IsOpen() || !m_file->Write(line))
std::fputs(line.GetBuffer(), stderr);
#else
if (m_file->IsOpen())
m_file->Write(line);
#if NAZARA_CORE_DUPLICATE_TO_COUT
std::fputs(line.GetConstBuffer(), stderr);
#endif
}
}
@@ -137,7 +137,7 @@ void NzLog::Write(const NzString& string)
void NzLog::WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func)
{
NzString stream;
stream.Reserve(errorType[type].GetSize() + error.GetSize() + 2 + file.GetSize() + 1 + NzGetNumberLength(line) +2 + func.GetSize() + 1);
stream.Reserve(std::strlen(errorType[type]) + error.GetSize() + 2 + file.GetSize() + 1 + NzGetNumberLength(line) +2 + func.GetSize() + 1);
stream += errorType[type];
stream += error;
stream += " (";

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/MemoryStream.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Mutex.hpp>

View File

@@ -0,0 +1,138 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Core/Debug.hpp>
NzResource::NzResource(bool persistent) :
m_resourcePersistent(persistent),
m_resourceReferenceCount(0)
{
}
NzResource::NzResource(const NzResource& resource) :
m_resourcePersistent(resource.m_resourcePersistent),
m_resourceReferenceCount(0)
{
}
NzResource::~NzResource()
{
EnsureResourceListenerUpdate();
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
(*it).listener->OnResourceReleased(this, (*it).index);
}
void NzResource::AddResourceListener(NzResourceListener* listener, int index) const
{
NazaraLock(m_mutex)
if (m_resourceListeners.insert(NzResourceEntry(listener, index)).second)
{
m_resourceListenerUpdated = false;
// AddResourceReference()
m_resourceReferenceCount++;
}
}
void NzResource::AddResourceReference() const
{
NazaraLock(m_mutex)
m_resourceReferenceCount++;
}
bool NzResource::IsPersistent() const
{
NazaraLock(m_mutex)
return m_resourcePersistent;
}
void NzResource::RemoveResourceListener(NzResourceListener* listener) const
{
NazaraLock(m_mutex)
if (m_resourceListeners.erase(listener) != 0)
m_resourceListenerUpdated = false;
else
NazaraError(NzString::Pointer(listener) + " is not listening to " + NzString::Pointer(this));
RemoveResourceReference();
}
void NzResource::RemoveResourceReference() const
{
NazaraMutexLock(m_mutex);
#if NAZARA_CORE_SAFE
if (m_resourceReferenceCount == 0)
{
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
return;
}
#endif
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
{
NazaraMutexUnlock(m_mutex);
delete this;
}
else
{
NazaraMutexUnlock(m_mutex);
}
}
void NzResource::SetPersistent(bool persistent)
{
NazaraMutexLock(m_mutex);
m_resourcePersistent = persistent;
if (!persistent && m_resourceReferenceCount == 0)
{
NazaraMutexUnlock(m_mutex);
delete this;
}
else
{
NazaraMutexUnlock(m_mutex);
}
}
void NzResource::NotifyCreated()
{
NazaraLock(m_mutex)
EnsureResourceListenerUpdate();
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
(*it).listener->OnResourceCreated(this, (*it).index);
}
void NzResource::NotifyDestroy()
{
NazaraLock(m_mutex)
EnsureResourceListenerUpdate();
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
(*it).listener->OnResourceDestroy(this, (*it).index);
}
void NzResource::EnsureResourceListenerUpdate() const
{
// Déjà bloqué par une mutex
if (!m_resourceListenerUpdated)
{
m_resourceListenersCache = m_resourceListeners;
m_resourceListenerUpdated = true;
}
}

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Core/Debug.hpp>
NzResourceListener::~NzResourceListener() = default;
void NzResourceListener::OnResourceCreated(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
}
void NzResourceListener::OnResourceDestroy(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
}
void NzResourceListener::OnResourceReleased(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Semaphore.hpp>

View File

@@ -0,0 +1,18 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/Debug.hpp>
NzStream::~NzStream() = default;
unsigned int NzStream::GetStreamOptions() const
{
return m_streamOptions;
}
void NzStream::SetStreamOptions(unsigned int options)
{
m_streamOptions = options;
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/String.hpp>
@@ -11,6 +11,7 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <limits>
#include <sstream>
#include <Utfcpp/utf8.h>
#include <Nazara/Core/Debug.hpp>
@@ -19,13 +20,13 @@ inline unsigned int nzPow2(unsigned int n)
{
unsigned int x = 1;
// Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux
// Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux
while(x <= n)
x <<= 1;
return x;
}
// Cet algorithme est inspiré de la documentation de Qt
// Cet algorithme est inspiré de la documentation de Qt
inline unsigned int nzGetNewSize(unsigned int newSize)
{
if (newSize < 20)
@@ -108,7 +109,7 @@ NzString::NzString(const char* string)
m_sharedString->capacity = size;
m_sharedString->size = size;
m_sharedString->string = new char[size+1];
std::strcpy(m_sharedString->string, string);
std::memcpy(m_sharedString->string, string, size+1);
}
else
m_sharedString = &emptyString;
@@ -125,7 +126,7 @@ NzString::NzString(const std::string& string)
m_sharedString->capacity = string.capacity();
m_sharedString->size = string.size();
m_sharedString->string = new char[string.capacity()+1];
std::strcpy(m_sharedString->string, string.c_str());
std::memcpy(m_sharedString->string, string.c_str(), string.size()+1);
}
else
m_sharedString = &emptyString;
@@ -142,7 +143,7 @@ m_sharedString(string.m_sharedString)
}
}
NzString::NzString(NzString&& string) :
NzString::NzString(NzString&& string) noexcept :
m_sharedString(string.m_sharedString)
{
string.m_sharedString = &emptyString;
@@ -180,7 +181,7 @@ NzString& NzString::Append(char character)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::memcpy(str, m_sharedString->string, m_sharedString->size);
str[m_sharedString->size] = character;
str[newSize] = '\0';
@@ -207,7 +208,7 @@ NzString& NzString::Append(const char* string)
{
EnsureOwnership();
std::strcpy(&m_sharedString->string[m_sharedString->size], string);
std::memcpy(&m_sharedString->string[m_sharedString->size], string, length+1);
m_sharedString->size += length;
}
else
@@ -216,8 +217,8 @@ NzString& NzString::Append(const char* string)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string, length+1);
ReleaseString();
m_sharedString = new SharedString;
@@ -241,7 +242,7 @@ NzString& NzString::Append(const NzString& string)
{
EnsureOwnership();
std::strcpy(&m_sharedString->string[m_sharedString->size], string.m_sharedString->string);
std::memcpy(&m_sharedString->string[m_sharedString->size], string.m_sharedString->string, string.m_sharedString->size+1);
m_sharedString->size += string.m_sharedString->size;
}
else
@@ -250,8 +251,8 @@ NzString& NzString::Append(const NzString& string)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string.m_sharedString->string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string.m_sharedString->string, string.m_sharedString->size+1);
ReleaseString();
m_sharedString = new SharedString;
@@ -307,7 +308,6 @@ unsigned int NzString::Count(char character, int start, nzUInt32 flags) const
{
char character_lower = nzToLower(character);
char character_upper = nzToUpper(character);
unsigned int count = 0;
do
{
if (*str == character_lower || *str == character_upper)
@@ -807,14 +807,14 @@ unsigned int NzString::Find(const char* string, int start, nzUInt32 flags) const
{
if (NzUnicode::GetLowercase(*it) == c)
{
const char* pos = it.base();
const char* ptrPos = it.base();
++it;
utf8::unchecked::iterator<const char*> it2(t);
while (true)
{
if (*it2 == '\0')
return static_cast<unsigned int>(pos - m_sharedString->string);
return static_cast<unsigned int>(ptrPos - m_sharedString->string);
if (*it == '\0')
return npos;
@@ -836,14 +836,14 @@ unsigned int NzString::Find(const char* string, int start, nzUInt32 flags) const
{
if (nzToLower(*str) == c)
{
char* pos = str;
char* ptrPos = str;
str++;
const char* ptr = &string[1];
while (true)
{
if (*ptr == '\0')
return static_cast<unsigned int>(pos - m_sharedString->string);
return static_cast<unsigned int>(ptrPos - m_sharedString->string);
if (*str == '\0')
return npos;
@@ -897,14 +897,14 @@ unsigned int NzString::Find(const NzString& string, int start, nzUInt32 flags) c
{
if (NzUnicode::GetLowercase(*it) == c)
{
const char* pos = it.base();
const char* ptrPos = it.base();
++it;
utf8::unchecked::iterator<const char*> it2(t);
while (true)
{
if (*it2 == '\0')
return static_cast<unsigned int>(pos - m_sharedString->string);
return static_cast<unsigned int>(ptrPos - m_sharedString->string);
if (*it == '\0')
return npos;
@@ -926,14 +926,14 @@ unsigned int NzString::Find(const NzString& string, int start, nzUInt32 flags) c
{
if (nzToLower(*str) == c)
{
char* pos = str;
char* ptrPos = str;
str++;
const char* ptr = &string.m_sharedString->string[1];
while (true)
{
if (*ptr == '\0')
return static_cast<unsigned int>(pos - m_sharedString->string);
return static_cast<unsigned int>(ptrPos - m_sharedString->string);
if (*str == '\0')
return npos;
@@ -1175,7 +1175,7 @@ unsigned int NzString::FindLast(const char* string, int start, nzUInt32 flags) c
if (flags & HandleUtf8)
{
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
const char* t = string;
@@ -1283,9 +1283,9 @@ unsigned int NzString::FindLast(const NzString& string, int start, nzUInt32 flag
{
if (flags & HandleUtf8)
{
///Algo 1.FindLast#3 (Itérateur non-adapté)
///Algo 1.FindLast#3 (Itérateur non-adapté)
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
const char* t = string.m_sharedString->string;
@@ -1560,13 +1560,13 @@ unsigned int NzString::FindLastWord(const char* string, int start, nzUInt32 flag
if (flags & HandleUtf8)
{
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
if (flags & CaseInsensitive)
{
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
{
@@ -1608,7 +1608,7 @@ unsigned int NzString::FindLastWord(const char* string, int start, nzUInt32 flag
}
else
{
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = utf8::unchecked::next(t);
do
{
@@ -1743,13 +1743,13 @@ unsigned int NzString::FindLastWord(const NzString& string, int start, nzUInt32
if (flags & HandleUtf8)
{
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
if (flags & CaseInsensitive)
{
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
{
@@ -1791,7 +1791,7 @@ unsigned int NzString::FindLastWord(const NzString& string, int start, nzUInt32
}
else
{
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = utf8::unchecked::next(t);
do
{
@@ -1918,13 +1918,13 @@ unsigned int NzString::FindWord(const char* string, int start, nzUInt32 flags) c
if (flags & HandleUtf8)
{
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
if (flags & CaseInsensitive)
{
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
@@ -1964,7 +1964,7 @@ unsigned int NzString::FindWord(const char* string, int start, nzUInt32 flags) c
}
else
{
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
@@ -2088,15 +2088,15 @@ unsigned int NzString::FindWord(const NzString& string, int start, nzUInt32 flag
char* ptr = m_sharedString->string;
if (flags & HandleUtf8)
{
///Algo 3.FindWord#3 (Itérateur trop lent pour #2)
///Algo 3.FindWord#3 (Itérateur trop lent pour #2)
if (utf8::internal::is_trail(*ptr))
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère
utf8::unchecked::iterator<const char*> it(ptr);
if (flags & CaseInsensitive)
{
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
@@ -2136,7 +2136,7 @@ unsigned int NzString::FindWord(const NzString& string, int start, nzUInt32 flag
}
else
{
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
const char* t = string.m_sharedString->string; // utf8(::unchecked)::next affecte l'itérateur en argument
nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t));
do
@@ -2214,7 +2214,7 @@ unsigned int NzString::FindWord(const NzString& string, int start, nzUInt32 flag
{
while ((ptr = std::strstr(ptr, string.m_sharedString->string)))
{
// Si le mot est bien isolé
// Si le mot est bien isolé
if ((ptr == m_sharedString->string || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size))))
return ptr - m_sharedString->string;
@@ -2271,7 +2271,7 @@ char* NzString::GetUtf8Buffer(unsigned int* size) const
return nullptr;
char* buffer = new char[m_sharedString->size+1];
std::strcpy(buffer, m_sharedString->string);
std::memcpy(buffer, m_sharedString->string, m_sharedString->size+1);
if (size)
*size = m_sharedString->size;
@@ -2296,7 +2296,7 @@ char16_t* NzString::GetUtf16Buffer(unsigned int* size) const
catch (const utf8::exception& exception)
{
NazaraError("UTF-8 error : " + NzString(exception.what()));
return 0;
return nullptr;
}
#endif
@@ -2340,7 +2340,7 @@ char32_t* NzString::GetUtf32Buffer(unsigned int* size) const
catch (const utf8::exception& exception)
{
NazaraError("UTF-8 error : " + NzString(exception.what()));
return 0;
return nullptr;
}
#endif
}
@@ -2373,7 +2373,7 @@ wchar_t* NzString::GetWideBuffer(unsigned int* size) const
if (cp <= 0xFFFF && (cp < 0xD800 || cp > 0xDFFF)) // @Laurent Gomila
*ptr++ = static_cast<wchar_t>(cp);
else
*ptr++ = static_cast<wchar_t>('?');
*ptr++ = L'?';
}
while (*it++);
}
@@ -2387,7 +2387,7 @@ wchar_t* NzString::GetWideBuffer(unsigned int* size) const
catch (const utf8::exception& exception)
{
NazaraError("UTF-8 error : " + NzString(exception.what()));
return 0;
return nullptr;
}
#endif
}
@@ -2397,11 +2397,11 @@ NzString NzString::GetWord(unsigned int index, nzUInt32 flags) const
if (m_sharedString->size == 0)
return NzString();
NzString temp = Simplified(flags); // Évitons les mauvaises surprises
NzString temp = Simplified(flags); // Évitons les mauvaises surprises
if (temp.IsEmpty())
return NzString();
unsigned int foundPos = temp.Find(' '); // Simplified nous assure que nous n'avons plus que des espaces comme séparation
unsigned int foundPos = temp.Find(' '); // Simplified nous assure que nous n'avons plus que des espaces comme séparation
unsigned int lastPos = 0;
for (; index > 0; --index)
{
@@ -2476,12 +2476,12 @@ NzString& NzString::Insert(int pos, char character)
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedString->size);
// Si le buffer est déjà suffisamment grand
// Si le buffer est déjà suffisamment grand
if (m_sharedString->capacity >= m_sharedString->size+1)
{
EnsureOwnership();
std::memmove(&m_sharedString->string[start+1], &m_sharedString->string[start], m_sharedString->size*sizeof(char));
std::memmove(&m_sharedString->string[start+1], &m_sharedString->string[start], m_sharedString->size);
m_sharedString->string[start] = character;
m_sharedString->size += 1;
@@ -2521,14 +2521,14 @@ NzString& NzString::Insert(int pos, const char* string)
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedString->size);
// Si le buffer est déjà suffisamment grand
// Si le buffer est déjà suffisamment grand
unsigned int len = std::strlen(string);
if (m_sharedString->capacity >= m_sharedString->size+len)
{
EnsureOwnership();
std::memmove(&m_sharedString->string[start+len], &m_sharedString->string[start], m_sharedString->size*sizeof(char));
std::memcpy(&m_sharedString->string[start], string, len*sizeof(char));
std::memmove(&m_sharedString->string[start+len], &m_sharedString->string[start], m_sharedString->size);
std::memcpy(&m_sharedString->string[start], string, len+1);
m_sharedString->size += len;
}
@@ -2572,13 +2572,13 @@ NzString& NzString::Insert(int pos, const NzString& string)
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedString->size);
// Si le buffer est déjà suffisamment grand
// Si le buffer est déjà suffisamment grand
if (m_sharedString->capacity >= m_sharedString->size + string.m_sharedString->size)
{
EnsureOwnership();
std::memmove(&m_sharedString->string[start+string.m_sharedString->size], &m_sharedString->string[start], m_sharedString->size*sizeof(char));
std::memcpy(&m_sharedString->string[start], string.m_sharedString->string, string.m_sharedString->size*sizeof(char));
std::memmove(&m_sharedString->string[start+string.m_sharedString->size], &m_sharedString->string[start], m_sharedString->size);
std::memcpy(&m_sharedString->string[start], string.m_sharedString->string, string.m_sharedString->size+1);
m_sharedString->size += string.m_sharedString->size;
}
@@ -2621,7 +2621,7 @@ bool NzString::IsNull() const
bool NzString::IsNumber(nzUInt8 base, nzUInt32 flags) const
{
#if !NAZARA_UNSAFE
#if NAZARA_CORE_SAFE
if (base < 2 || base > 36)
{
NazaraError("Base must be between 2 and 36");
@@ -2770,11 +2770,11 @@ unsigned int NzString::Replace(char oldCharacter, char newCharacter, int start,
{
if (!found)
{
unsigned int pos = ptr-m_sharedString->string;
unsigned int offset = ptr-m_sharedString->string;
EnsureOwnership();
ptr = &m_sharedString->string[pos];
ptr = &m_sharedString->string[offset];
found = true;
}
@@ -2790,11 +2790,11 @@ unsigned int NzString::Replace(char oldCharacter, char newCharacter, int start,
{
if (!found)
{
unsigned int pos = ptr-m_sharedString->string;
unsigned int offset = ptr-m_sharedString->string;
EnsureOwnership();
ptr = &m_sharedString->string[pos];
ptr = &m_sharedString->string[offset];
found = true;
}
@@ -2829,7 +2829,7 @@ unsigned int NzString::Replace(const char* oldString, const char* replaceString,
{
bool found = false;
// Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide
// Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide
while ((pos = Find(oldString, pos, flags)) != npos)
{
if (!found)
@@ -2838,7 +2838,7 @@ unsigned int NzString::Replace(const char* oldString, const char* replaceString,
found = true;
}
std::memcpy(&m_sharedString->string[pos], replaceString, oSize*sizeof(char));
std::memcpy(&m_sharedString->string[pos], replaceString, oSize);
pos += oSize;
++count;
@@ -2860,9 +2860,9 @@ unsigned int NzString::Replace(const char* oldString, const char* replaceString,
{
const char* r = &m_sharedString->string[pos];
std::memcpy(ptr, p, (r-p)*sizeof(char));
std::memcpy(ptr, p, r-p);
ptr += r-p;
std::memcpy(ptr, replaceString, rSize*sizeof(char));
std::memcpy(ptr, replaceString, rSize);
ptr += rSize;
p = r+oSize;
pos += oSize;
@@ -2870,7 +2870,7 @@ unsigned int NzString::Replace(const char* oldString, const char* replaceString,
count++;
}
std::strcpy(ptr, p); // Ajoute le caractère de fin par la même occasion
std::strcpy(ptr, p); // Ajoute le caractère de fin par la même occasion
ReleaseString();
m_sharedString = new SharedString;
@@ -2899,7 +2899,7 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
{
bool found = false;
// Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide
// Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide
while ((pos = Find(oldString, pos, flags)) != npos)
{
if (!found)
@@ -2908,7 +2908,7 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
found = true;
}
std::memcpy(&m_sharedString->string[pos], replaceString.m_sharedString->string, oldString.m_sharedString->size*sizeof(char));
std::memcpy(&m_sharedString->string[pos], replaceString.m_sharedString->string, oldString.m_sharedString->size);
pos += oldString.m_sharedString->size;
++count;
@@ -2930,9 +2930,9 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
{
const char* r = &m_sharedString->string[pos];
std::memcpy(ptr, p, (r-p)*sizeof(char));
std::memcpy(ptr, p, r-p);
ptr += r-p;
std::memcpy(ptr, replaceString.m_sharedString->string, replaceString.m_sharedString->size*sizeof(char));
std::memcpy(ptr, replaceString.m_sharedString->string, replaceString.m_sharedString->size);
ptr += replaceString.m_sharedString->size;
p = r+oldString.m_sharedString->size;
pos += oldString.m_sharedString->size;
@@ -2940,7 +2940,7 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
count++;
}
std::strcpy(ptr, p); // Ajoute le caractère de fin par la même occasion
std::strcpy(ptr, p); // Ajoute le caractère de fin par la même occasion
ReleaseString();
m_sharedString = new SharedString;
@@ -2954,6 +2954,7 @@ unsigned int NzString::Replace(const NzString& oldString, const NzString& replac
unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharacter, int start, nzUInt32 flags)
{
///FIXME: Ne gère pas l'UTF-8
if (!oldCharacters || !oldCharacters[0])
return 0;
@@ -2982,11 +2983,11 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
{
if (!found)
{
unsigned int pos = ptr-m_sharedString->string;
unsigned int offset = ptr-m_sharedString->string;
EnsureOwnership();
ptr = &m_sharedString->string[pos];
ptr = &m_sharedString->string[offset];
found = true;
}
@@ -3006,11 +3007,11 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
{
if (!found)
{
unsigned int pos = ptr-m_sharedString->string;
unsigned int offset = ptr-m_sharedString->string;
EnsureOwnership();
ptr = &m_sharedString->string[pos];
ptr = &m_sharedString->string[offset];
found = true;
}
@@ -3040,7 +3041,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
unsigned int count = 0;
if (rSize == 1) // On utilise un algorithme optimisé
if (rSize == 1) // On utilise un algorithme optimisé
{
EnsureOwnership();
@@ -3070,7 +3071,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
unsigned int j = 0;
for (unsigned int i = 0; i < m_sharedString->size; ++i)
{
if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier
if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier
newString[j++] = m_sharedString->string[i];
else
{
@@ -3084,7 +3085,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
++count;
found = true;
break; // Simple façon d'éviter la ligne après la boucle
break; // Simple façon d'éviter la ligne après la boucle
}
}
@@ -3119,7 +3120,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
unsigned int count = 0;
if (replaceString.m_sharedString->size == 1) // On utilise un algorithme optimisé
if (replaceString.m_sharedString->size == 1) // On utilise un algorithme optimisé
{
EnsureOwnership();
@@ -3149,7 +3150,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
unsigned int j = 0;
for (unsigned int i = 0; i < m_sharedString->size; ++i)
{
if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier
if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier
newString[j++] = m_sharedString->string[i];
else
{
@@ -3163,7 +3164,7 @@ unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharact
++count;
found = true;
break; // Simple façon d'éviter la ligne après la boucle
break; // Simple façon d'éviter la ligne après la boucle
}
}
@@ -3189,7 +3190,7 @@ void NzString::Reserve(unsigned int bufferSize)
char* ptr = new char[bufferSize+1];
if (m_sharedString->size > 0)
std::strcpy(ptr, m_sharedString->string);
std::memcpy(ptr, m_sharedString->string, m_sharedString->size+1);
unsigned int size = m_sharedString->size;
@@ -3203,7 +3204,10 @@ void NzString::Reserve(unsigned int bufferSize)
NzString& NzString::Resize(int size, char character)
{
if (size == 0)
{
Clear(true);
return *this;
}
if (size < 0)
size = std::max(static_cast<int>(m_sharedString->size + size), 0);
@@ -3214,7 +3218,7 @@ NzString& NzString::Resize(int size, char character)
{
EnsureOwnership();
// Nous avons déjà la place requise, contentons-nous de remplir le buffer
// Nous avons déjà la place requise, contentons-nous de remplir le buffer
if (character != '\0' && newSize > m_sharedString->size)
{
char* ptr = &m_sharedString->string[m_sharedString->size];
@@ -3226,11 +3230,11 @@ NzString& NzString::Resize(int size, char character)
m_sharedString->size = newSize;
m_sharedString->string[newSize] = '\0';
}
else // On veut forcément agrandir la chaine
else // On veut forcément agrandir la chaine
{
char* newString = new char[newSize+1];
if (m_sharedString->size != 0)
std::memcpy(newString, m_sharedString->string, newSize*sizeof(char));
std::memcpy(newString, m_sharedString->string, newSize);
char* ptr = &newString[m_sharedString->size];
char* limit = &newString[newSize];
@@ -3249,9 +3253,6 @@ NzString& NzString::Resize(int size, char character)
NzString NzString::Resized(int size, char character) const
{
if (size == 0)
return NzString();
if (size < 0)
size = m_sharedString->size + size;
@@ -3317,6 +3318,9 @@ NzString NzString::Reversed() const
NzString NzString::Simplified(nzUInt32 flags) const
{
if (m_sharedString->size == 0)
return NzString();
char* str = new char[m_sharedString->size+1];
char* p = str;
@@ -3673,7 +3677,7 @@ bool NzString::StartsWith(const NzString& string, nzUInt32 flags) const
}
}
else
return std::memcmp(m_sharedString->string, string.m_sharedString->string, string.m_sharedString->size*sizeof(char)) == 0;
return std::memcmp(m_sharedString->string, string.m_sharedString->string, string.m_sharedString->size) == 0;
return false;
}
@@ -3692,14 +3696,14 @@ NzString NzString::Substr(int startPos, int endPos) const
return NzString();
}
unsigned int end = std::min(static_cast<unsigned int>(endPos), m_sharedString->size-1);
unsigned int minEnd = std::min(static_cast<unsigned int>(endPos), m_sharedString->size-1);
if (start > end || start >= m_sharedString->size)
if (start > minEnd || start >= m_sharedString->size)
return NzString();
unsigned int size = end-start+1;
unsigned int size = minEnd-start+1;
char* str = new char[size+1];
std::memcpy(str, &m_sharedString->string[start], size*sizeof(char));
std::memcpy(str, &m_sharedString->string[start], size);
str[size] = '\0';
return NzString(new SharedString(1, size, size, str));
@@ -3832,7 +3836,7 @@ bool NzString::ToBool(bool* value, nzUInt32 flags) const
else
{
if (flags & CaseInsensitive)
word = word.ToLower(); // Les mots identifiés sont en ASCII, inutile de passer le flag unicode
word = word.ToLower(); // Les mots identifiés sont en ASCII, inutile de passer le flag unicode
if (word == "true")
{
@@ -4185,7 +4189,7 @@ NzString& NzString::operator=(const char* string)
}
m_sharedString->size = size;
std::strcpy(m_sharedString->string, string);
std::memcpy(m_sharedString->string, string, size+1);
}
else
ReleaseString();
@@ -4209,7 +4213,7 @@ NzString& NzString::operator=(const std::string& string)
}
m_sharedString->size = string.size();
std::strcpy(m_sharedString->string, string.c_str());
std::memcpy(m_sharedString->string, string.c_str(), string.size()+1);
}
else
ReleaseString();
@@ -4232,7 +4236,7 @@ NzString& NzString::operator=(const NzString& string)
return *this;
}
NzString& NzString::operator=(NzString&& string)
NzString& NzString::operator=(NzString&& string) noexcept
{
std::swap(m_sharedString, string.m_sharedString);
@@ -4246,7 +4250,7 @@ NzString NzString::operator+(char character) const
unsigned int totalSize = m_sharedString->size+1;
char* str = new char[totalSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::memcpy(str, m_sharedString->string, m_sharedString->size);
str[m_sharedString->size] = character;
str[totalSize] = '\0';
@@ -4268,8 +4272,8 @@ NzString NzString::operator+(const char* string) const
unsigned int totalSize = m_sharedString->size + length;
char* str = new char[totalSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string, length+1);
return NzString(new SharedString(1, totalSize, totalSize, str));
}
@@ -4284,8 +4288,8 @@ NzString NzString::operator+(const std::string& string) const
unsigned int totalSize = m_sharedString->size + string.size();
char* str = new char[totalSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string.c_str());
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string.c_str(), string.size()+1);
return NzString(new SharedString(1, totalSize, totalSize, str));
}
@@ -4300,8 +4304,8 @@ NzString NzString::operator+(const NzString& string) const
unsigned int totalSize = m_sharedString->size + string.m_sharedString->size;
char* str = new char[totalSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string.m_sharedString->string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string.m_sharedString->string, string.m_sharedString->size+1);
return NzString(new SharedString(1, totalSize, totalSize, str));
}
@@ -4328,7 +4332,7 @@ NzString& NzString::operator+=(char character)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::memcpy(str, m_sharedString->string, m_sharedString->size);
str[m_sharedString->size] = character;
str[newSize] = '\0';
@@ -4350,25 +4354,25 @@ NzString& NzString::operator+=(const char* string)
if (m_sharedString->size == 0)
return operator=(string);
unsigned int length = std::strlen(string);
if (length == 0)
unsigned int size = std::strlen(string);
if (size == 0)
return *this;
if (m_sharedString->capacity >= m_sharedString->size + length)
if (m_sharedString->capacity >= m_sharedString->size + size)
{
EnsureOwnership();
std::strcpy(&m_sharedString->string[m_sharedString->size], string);
m_sharedString->size += length;
std::memcpy(&m_sharedString->string[m_sharedString->size], string, size+1);
m_sharedString->size += size;
}
else
{
unsigned int newSize = m_sharedString->size + length;
unsigned int newSize = m_sharedString->size + size;
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string, size+1);
ReleaseString();
m_sharedString = new SharedString;
@@ -4392,7 +4396,7 @@ NzString& NzString::operator+=(const std::string& string)
{
EnsureOwnership();
std::strcpy(&m_sharedString->string[m_sharedString->size], string.c_str());
std::memcpy(&m_sharedString->string[m_sharedString->size], string.c_str(), string.size()+1);
m_sharedString->size += string.size();
}
else
@@ -4401,8 +4405,8 @@ NzString& NzString::operator+=(const std::string& string)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string.c_str());
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string.c_str(), string.size()+1);
ReleaseString();
m_sharedString = new SharedString;
@@ -4426,7 +4430,7 @@ NzString& NzString::operator+=(const NzString& string)
{
EnsureOwnership();
std::strcpy(&m_sharedString->string[m_sharedString->size], string.m_sharedString->string);
std::memcpy(&m_sharedString->string[m_sharedString->size], string.m_sharedString->string, string.m_sharedString->size+1);
m_sharedString->size += string.m_sharedString->size;
}
else
@@ -4435,8 +4439,8 @@ NzString& NzString::operator+=(const NzString& string)
unsigned int bufferSize = nzGetNewSize(newSize);
char* str = new char[bufferSize+1];
std::memcpy(str, m_sharedString->string, m_sharedString->size*sizeof(char));
std::strcpy(&str[m_sharedString->size], string.m_sharedString->string);
std::memcpy(str, m_sharedString->string, m_sharedString->size);
std::memcpy(&str[m_sharedString->size], string.m_sharedString->string, string.m_sharedString->size+1);
ReleaseString();
m_sharedString = new SharedString;
@@ -4902,7 +4906,7 @@ NzString operator+(char character, const NzString& string)
unsigned int totalSize = string.m_sharedString->size+1;
char* str = new char[totalSize+1];
str[0] = character;
std::strcpy(str, string.m_sharedString->string);
std::memcpy(str, string.m_sharedString->string, string.m_sharedString->size+1);
return NzString(new NzString::SharedString(1, totalSize, totalSize, str));
}
@@ -4918,8 +4922,8 @@ NzString operator+(const char* string, const NzString& nstring)
unsigned int size = std::strlen(string);
unsigned int totalSize = size + nstring.m_sharedString->size;
char* str = new char[totalSize+1];
std::memcpy(str, string, size*sizeof(char));
std::strcpy(&str[size], nstring.m_sharedString->string);
std::memcpy(str, string, size);
std::memcpy(&str[size], nstring.m_sharedString->string, nstring.m_sharedString->size+1);
return NzString(new NzString::SharedString(1, totalSize, totalSize, str));
}
@@ -4934,8 +4938,8 @@ NzString operator+(const std::string& string, const NzString& nstring)
unsigned int totalSize = string.size() + nstring.m_sharedString->size;
char* str = new char[totalSize+1];
std::memcpy(str, string.c_str(), string.size()*sizeof(char));
std::strcpy(&str[string.size()], nstring.m_sharedString->string);
std::memcpy(str, string.c_str(), string.size());
std::memcpy(&str[string.size()], nstring.m_sharedString->string, nstring.m_sharedString->size+1);
return NzString(new NzString::SharedString(1, totalSize, totalSize, str));
}
@@ -5083,7 +5087,7 @@ void NzString::EnsureOwnership()
m_sharedString->refCount--;
char* string = new char[m_sharedString->capacity+1];
std::strcpy(string, m_sharedString->string);
std::memcpy(string, m_sharedString->string, m_sharedString->size+1);
m_sharedString = new SharedString(1, m_sharedString->capacity, m_sharedString->size, string);
}
@@ -5107,7 +5111,6 @@ void NzString::ReleaseString()
if (freeSharedString)
{
NazaraMutexUnlock(m_sharedString->mutex);
delete[] m_sharedString->string;
delete m_sharedString;
}
@@ -5116,7 +5119,7 @@ void NzString::ReleaseString()
}
NzString::SharedString NzString::emptyString(0, 0, 0, nullptr);
unsigned int NzString::npos(static_cast<unsigned int>(-1));
const unsigned int NzString::npos(std::numeric_limits<unsigned int>::max());
namespace std
{

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>

View File

@@ -1,8 +1,8 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Inspiré du code de la SFML par Laurent Gomila
// Inspiré du code de la SFML par Laurent Gomila
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Core/Config.hpp>

View File

@@ -1,46 +0,0 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ThreadCondition.hpp>
#include <Nazara/Core/Mutex.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/ThreadConditionImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/ThreadConditionImpl.hpp>
#else
#error Thread condition has no implementation
#endif
#include <Nazara/Core/Debug.hpp>
NzThreadCondition::NzThreadCondition()
{
m_impl = new NzThreadConditionImpl;
}
NzThreadCondition::~NzThreadCondition()
{
delete m_impl;
}
void NzThreadCondition::Signal()
{
m_impl->Signal();
}
void NzThreadCondition::SignalAll()
{
m_impl->SignalAll();
}
void NzThreadCondition::Wait(NzMutex* mutex)
{
m_impl->Wait(mutex->m_impl);
}
bool NzThreadCondition::Wait(NzMutex* mutex, nzUInt32 timeout)
{
return m_impl->Wait(mutex->m_impl, timeout);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Unicode.hpp>
@@ -9,16 +9,16 @@
#if NAZARA_CORE_INCLUDE_UNICODEDATA
struct Character
{
nzUInt16 category; // Le type du caractère
nzUInt8 direction; // Le sens de lecure du caractère
nzUInt32 lowerCase; // Le caractère correspondant en minuscule
nzUInt32 titleCase; // Le caractère correspondant en titre
nzUInt32 upperCase; // Le caractère correspondant en majuscule
nzUInt16 category; // Le type du caractère
nzUInt8 direction; // Le sens de lecure du caractère
nzUInt32 lowerCase; // Le caractère correspondant en minuscule
nzUInt32 titleCase; // Le caractère correspondant en titre
nzUInt32 upperCase; // Le caractère correspondant en majuscule
};
#include <Nazara/Core/UnicodeData.hpp>
#else // Implémentation bidon
#else // Implémentation bidon
NzUnicode::Category NzUnicode::GetCategory(char32_t character)
{

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/ClockImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,16 +1,16 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Source: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
#include <Nazara/Core/Win32/ThreadConditionImpl.hpp>
#include <Nazara/Core/Win32/ConditionVariableImpl.hpp>
#include <Nazara/Core/Win32/MutexImpl.hpp>
#include <Nazara/Core/Debug.hpp>
NzThreadConditionImpl::NzThreadConditionImpl()
NzConditionVariableImpl::NzConditionVariableImpl()
{
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
#if NAZARA_CORE_WINDOWS_VISTA
InitializeConditionVariable(&m_cv);
#else
m_count = 0;
@@ -20,16 +20,16 @@ NzThreadConditionImpl::NzThreadConditionImpl()
#endif
}
#ifndef NAZARA_PLATFORM_WINDOWSVISTA
NzThreadConditionImpl::~NzThreadConditionImpl()
#if !NAZARA_CORE_WINDOWS_VISTA
NzConditionVariableImpl::~NzConditionVariableImpl()
{
DeleteCriticalSection(&m_countLock);
}
#endif
void NzThreadConditionImpl::Signal()
void NzConditionVariableImpl::Signal()
{
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
#if NAZARA_CORE_WINDOWS_VISTA
WakeConditionVariable(&m_cv);
#else
// Avoid race conditions.
@@ -42,9 +42,9 @@ void NzThreadConditionImpl::Signal()
#endif
}
void NzThreadConditionImpl::SignalAll()
void NzConditionVariableImpl::SignalAll()
{
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
#if NAZARA_CORE_WINDOWS_VISTA
WakeAllConditionVariable(&m_cv);
#else
// Avoid race conditions.
@@ -57,14 +57,14 @@ void NzThreadConditionImpl::SignalAll()
#endif
}
void NzThreadConditionImpl::Wait(NzMutexImpl* mutex)
void NzConditionVariableImpl::Wait(NzMutexImpl* mutex)
{
Wait(mutex, INFINITE);
}
bool NzThreadConditionImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout)
bool NzConditionVariableImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout)
{
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
#if NAZARA_CORE_WINDOWS_VISTA
return SleepConditionVariableCS(&m_cv, mutex->m_criticalSection, timeout);
#else
// Avoid race conditions.

View File

@@ -1,27 +1,27 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
#pragma once
#ifndef NAZARA_THREADCONDITIONIMPL_HPP
#define NAZARA_THREADCONDITIONIMPL_HPP
#ifndef NAZARA_CONDITIONVARIABLEIMPL_HPP
#define NAZARA_CONDITIONVARIABLEIMPL_HPP
#include <Nazara/Prerequesites.hpp>
#include <windows.h>
class NzMutexImpl;
class NzThreadConditionImpl
class NzConditionVariableImpl
{
public:
NzThreadConditionImpl();
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
~NzThreadConditionImpl() = default;
NzConditionVariableImpl();
#if NAZARA_CORE_WINDOWS_VISTA
~NzConditionVariableImpl() = default;
#else
~NzThreadConditionImpl();
~NzConditionVariableImpl();
#endif
void Signal();
@@ -31,7 +31,7 @@ class NzThreadConditionImpl
bool Wait(NzMutexImpl* mutex, nzUInt32 timeout);
private:
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
#if NAZARA_CORE_WINDOWS_VISTA
CONDITION_VARIABLE m_cv;
#else
enum
@@ -48,4 +48,4 @@ class NzThreadConditionImpl
};
#endif // NAZARA_THREADCONDITIONIMPL_HPP
#endif // NAZARA_CONDITIONVARIABLEIMPL_HPP

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/DirectoryImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/DynLibImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/FileImpl.hpp>
@@ -113,11 +113,11 @@ std::size_t NzFileImpl::Read(void* buffer, std::size_t size)
m_endOfFileUpdated = true;
return read;
///FIXME: D'après la documenation, read vaut 0 si ReadFile atteint la fin du fichier
/// D'après les tests, ce n'est pas le cas, la taille lue est inférieure à la taille en argument, mais pas nulle
/// Peut-être ais-je mal compris la documentation
/// Le correctif (dans le cas où la doc serait vraie) est commenté en début de fonction et après ce commentaire
/// Il est cependant plus lourd, et ne fonctionne pas selon les tests...
///FIXME: D'après la documentation, read vaut 0 si ReadFile atteint la fin du fichier
/// D'après les tests, ce n'est pas le cas, la taille lue est inférieure à la taille en argument, mais pas nulle
/// Peut-être ais-je mal compris la documentation
/// Le correctif (dans le cas où la doc serait vraie) est commenté en début de fonction et après ce commentaire
/// Il est cependant plus lourd, et ne fonctionne pas avec le comportement observé de la fonction
/*
if (read == 0)
{
@@ -254,7 +254,7 @@ time_t NzFileImpl::GetCreationTime(const NzString& filePath)
CloseHandle(handle);
return FileTimeToTime(&creationTime);
return NzFileTimeToTime(&creationTime);
}
time_t NzFileImpl::GetLastAccessTime(const NzString& filePath)
@@ -277,7 +277,7 @@ time_t NzFileImpl::GetLastAccessTime(const NzString& filePath)
CloseHandle(handle);
return FileTimeToTime(&accessTime);
return NzFileTimeToTime(&accessTime);
}
time_t NzFileImpl::GetLastWriteTime(const NzString& filePath)
@@ -300,7 +300,7 @@ time_t NzFileImpl::GetLastWriteTime(const NzString& filePath)
CloseHandle(handle);
return FileTimeToTime(&writeTime);
return NzFileTimeToTime(&writeTime);
}
nzUInt64 NzFileImpl::GetSize(const NzString& filePath)

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/MutexImpl.hpp>
@@ -7,7 +7,11 @@
NzMutexImpl::NzMutexImpl()
{
#if NAZARA_CORE_WINDOWS_CS_SPINLOCKS > 0
InitializeCriticalSectionAndSpinCount(&m_criticalSection, NAZARA_CORE_WINDOWS_CS_SPINLOCKS);
#else
InitializeCriticalSection(&m_criticalSection);
#endif
}
NzMutexImpl::~NzMutexImpl()

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -9,11 +9,9 @@
#include <windows.h>
class NzThreadConditionImpl;
class NzMutexImpl
{
friend class NzThreadConditionImpl;
friend class NzConditionVariableImpl;
public:
NzMutexImpl();

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/SemaphoreImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Inspiré du code de la SFML par Laurent Gomila

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Inspiré du code de la SFML par Laurent Gomila

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Win32/Time.hpp>
time_t NzFileTimeToTime(FILETIME* time)
{
SYSTEMTIME stUTC, stLocal;
FileTimeToSystemTime(time, &stUTC);
SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal);
std::tm timeinfo;
timeinfo.tm_sec = stLocal.wSecond;
timeinfo.tm_min = stLocal.wMinute;
timeinfo.tm_hour = stLocal.wHour;
timeinfo.tm_mday = stLocal.wDay;
timeinfo.tm_mon = stLocal.wMonth-1;
timeinfo.tm_year = stLocal.wYear-1900;
timeinfo.tm_isdst = -1;
return std::mktime(&timeinfo);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -10,23 +10,6 @@
#include <ctime>
#include <windows.h>
time_t FileTimeToTime(FILETIME* time)
{
SYSTEMTIME stUTC, stLocal;
FileTimeToSystemTime(time, &stUTC);
SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal);
std::tm timeinfo;
timeinfo.tm_sec = stLocal.wSecond;
timeinfo.tm_min = stLocal.wMinute;
timeinfo.tm_hour = stLocal.wHour;
timeinfo.tm_mday = stLocal.wDay;
timeinfo.tm_mon = stLocal.wMonth-1;
timeinfo.tm_year = stLocal.wYear-1900;
timeinfo.tm_isdst = -1;
return std::mktime(&timeinfo);
}
time_t NzFileTimeToTime(FILETIME* time);
#endif // NAZARA_WINDOWS_TIME_HPP

View File

@@ -1,29 +0,0 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Config.hpp>
#if NAZARA_NETWORK_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}
#endif

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine - Noise module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Noise/Config.hpp>

View File

@@ -1,59 +1,49 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine - Noise module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Noise/Noise.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Noise/Config.hpp>
#include <Nazara/Noise/Debug.hpp>
NzNoise::NzNoise()
{
}
NzNoise::~NzNoise()
{
if (s_initialized)
Uninitialize();
}
bool NzNoise::Initialize()
{
#if NAZARA_NOISE_SAFE
if (s_initialized)
if (s_moduleReferenceCouter++ != 0)
return true; // Déjà initialisé
// Initialisation des dépendances
if (!NzCore::Initialize())
{
NazaraError("NzNoise already initialized");
return true;
NazaraError("Failed to initialize core module");
return false;
}
#endif
// Initialisation du module
s_initialized = true;
NazaraNotice("Initialized: Noise module");
return true;
}
void NzNoise::Uninitialize()
{
#if NAZARA_NOISE_SAFE
if (!s_initialized)
{
NazaraError("NzNoise not initialized");
return;
}
#endif
// Libération du module
s_initialized = false;
}
bool NzNoise::IsInitialized()
{
return s_initialized;
return s_moduleReferenceCouter != 0;
}
bool NzNoise::s_initialized = false;
void NzNoise::Uninitialize()
{
if (--s_moduleReferenceCouter != 0)
return; // Encore utilisé
//#include <Nazara/Core/DebugOff.hpp> //A INCLURE ?
// Libération du module
// Libération des dépendances
NzCore::Uninitialize();
NazaraNotice("Uninitialized: Noise module");
}
unsigned int NzNoise::s_moduleReferenceCouter = 0;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine - Noise module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Noise/NoiseBase.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -37,32 +37,32 @@ namespace
ss << "\n-Source: ";
switch (source)
{
case GL_DEBUG_SOURCE_API_ARB:
case GL_DEBUG_SOURCE_API:
ss << "OpenGL";
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
ss << "Operating system";
break;
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
case GL_DEBUG_SOURCE_SHADER_COMPILER:
ss << "Shader compiler";
break;
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
case GL_DEBUG_SOURCE_THIRD_PARTY:
ss << "Shader compiler";
break;
case GL_DEBUG_SOURCE_APPLICATION_ARB:
case GL_DEBUG_SOURCE_APPLICATION:
ss << "Application";
break;
case GL_DEBUG_SOURCE_OTHER_ARB:
case GL_DEBUG_SOURCE_OTHER:
ss << "Other";
break;
default:
// Peut être rajouté par une extension
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
@@ -71,32 +71,32 @@ namespace
ss << "-Type: ";
switch (type)
{
case GL_DEBUG_TYPE_ERROR_ARB:
case GL_DEBUG_TYPE_ERROR:
ss << "Error";
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
ss << "Deprecated behavior";
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
ss << "Undefined behavior";
break;
case GL_DEBUG_TYPE_PORTABILITY_ARB:
case GL_DEBUG_TYPE_PORTABILITY:
ss << "Portability";
break;
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
case GL_DEBUG_TYPE_PERFORMANCE:
ss << "Performance";
break;
case GL_DEBUG_TYPE_OTHER_ARB:
case GL_DEBUG_TYPE_OTHER:
ss << "Other";
break;
default:
// Peut être rajouté par une extension
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
@@ -105,20 +105,20 @@ namespace
ss << "-Severity: ";
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH_ARB:
case GL_DEBUG_SEVERITY_HIGH:
ss << "High";
break;
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
case GL_DEBUG_SEVERITY_MEDIUM:
ss << "Medium";
break;
case GL_DEBUG_SEVERITY_LOW_ARB:
case GL_DEBUG_SEVERITY_LOW:
ss << "Low";
break;
default:
// Peut être rajouté par une extension
// Peut être rajouté par une extension
ss << "Unknown";
break;
}
@@ -130,11 +130,6 @@ namespace
}
}
NzContext::NzContext() :
m_impl(nullptr)
{
}
NzContext::~NzContext()
{
Destroy();
@@ -172,15 +167,17 @@ bool NzContext::Create(const NzContextParameters& parameters)
if (m_parameters.antialiasingLevel > 0)
glEnable(GL_MULTISAMPLE);
if (NzOpenGL::IsSupported(NzOpenGL::DebugOutput) && m_parameters.debugMode)
if (NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput) && m_parameters.debugMode)
{
glDebugMessageCallback(&DebugCallback, this);
#ifdef NAZARA_DEBUG
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
#endif
}
NotifyCreated();
return true;
}
@@ -188,6 +185,8 @@ void NzContext::Destroy()
{
if (m_impl)
{
NotifyDestroy();
if (currentContext == this)
NzContextImpl::Desactivate();
@@ -230,7 +229,7 @@ bool NzContext::SetActive(bool active)
}
#endif
// Si le contexte est déjà activé/désactivé
// Si le contexte est déjà activé/désactivé
if ((currentContext == this) == active)
return true;
@@ -322,7 +321,7 @@ bool NzContext::Initialize()
{
NzContextParameters parameters;
// parameters.compatibilityProfile = true;
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
s_reference = new NzContext;
if (!s_reference->Create(parameters))
@@ -333,7 +332,7 @@ bool NzContext::Initialize()
return false;
}
// Le contexte de référence doit rester désactivé pour le partage
// Le contexte de référence doit rester désactivé pour le partage
s_reference->SetActive(false);
NzContextParameters::defaultShareContext = s_reference;
@@ -346,7 +345,7 @@ void NzContext::Uninitialize()
for (NzContext* context : contexts)
delete context;
contexts.clear(); // On supprime tous les contextes créés
contexts.clear(); // On supprime tous les contextes créés
delete s_reference;
s_reference = nullptr;

View File

@@ -1,24 +1,24 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Debug.hpp>
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
nzUInt8 NzContextParameters::defaultMajorVersion;
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize()
nzUInt8 NzContextParameters::defaultMinorVersion;
// Contexte de partage par défaut, initialisé par NzOpenGL::Initialize()
// Contexte de partage par défaut, initialisé par NzOpenGL::Initialize()
const NzContext* NzContextParameters::defaultShareContext = nullptr;
// Si possible, garder la compatibilité avec les fonctionnalités dépréciées
// Si possible, garder la compatibilité avec les fonctionnalités dépréciées
bool NzContextParameters::defaultCompatibilityProfile = false;
// Mode debug d'OpenGL par défaut
// Mode debug d'OpenGL par défaut
#if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG)
bool NzContextParameters::defaultDebugMode = true;
#else

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/Config.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -14,22 +14,6 @@
namespace
{
///FIXME: Déclaré deux fois (ici et dans Renderer.cpp)
const nzUInt8 attribIndex[] =
{
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
0, // nzElementUsage_Position
3, // nzElementUsage_Tangent
4 // nzElementUsage_TexCoord
};
const GLenum shaderType[nzShaderType_Max+1] = {
GL_FRAGMENT_SHADER, // nzShaderType_Fragment
GL_GEOMETRY_SHADER, // nzShaderType_Geometry
GL_VERTEX_SHADER // nzShaderType_Vertex
};
GLuint lockedPrevious = 0;
nzUInt8 lockedLevel = 0;
}
@@ -41,6 +25,8 @@ m_parent(parent)
NzGLSLShader::~NzGLSLShader()
{
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
it->second.texture->RemoveResourceListener(this);
}
bool NzGLSLShader::Bind()
@@ -63,11 +49,22 @@ bool NzGLSLShader::Bind()
glUseProgram(m_program);
return true;
}
bool NzGLSLShader::BindTextures()
{
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
{
glActiveTexture(GL_TEXTURE0 + it->second.unit);
if (!it->second.texture->Bind())
NazaraWarning("Failed to bind texture");
TextureSlot& slot = it->second;
if (slot.enabled && !slot.updated)
{
glActiveTexture(GL_TEXTURE0 + slot.unit);
if (!slot.texture->Prepare())
NazaraWarning("Failed to prepare texture");
slot.updated = true;
}
}
return true;
@@ -78,6 +75,7 @@ bool NzGLSLShader::Compile()
NzContext::EnsureContext();
m_idCache.clear();
m_textures.clear();
glLinkProgram(m_program);
@@ -86,8 +84,8 @@ bool NzGLSLShader::Compile()
if (success == GL_TRUE)
{
static NzString success("Linkage successful");
m_log = success;
static NzString successStr("Linkage successful");
m_log = successStr;
return true;
}
@@ -99,9 +97,9 @@ bool NzGLSLShader::Compile()
if (length > 1)
{
m_log.Clear(true);
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
m_log.Prepend("Linkage error: ");
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
glGetProgramInfoLog(m_program, length-1, nullptr, &m_log[19]);
}
@@ -125,17 +123,35 @@ bool NzGLSLShader::Create()
return false;
}
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Position], "Position");
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Normal], "Normal");
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Diffuse], "Diffuse");
glBindAttribLocation(m_program, attribIndex[nzElementUsage_Tangent], "Tangent");
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Position], "Position");
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Normal], "Normal");
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Diffuse], "Diffuse");
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Tangent], "Tangent");
NzString uniform = "TexCoord";
unsigned int maxTexCoords = NazaraRenderer->GetMaxTextureUnits();
NzString uniform;
static const unsigned int maxTexCoords = NzRenderer::GetMaxTextureUnits();
uniform.Reserve(10); // 8 + 2
uniform = "TexCoord";
for (unsigned int i = 0; i < maxTexCoords; ++i)
{
NzString uniformName = uniform + NzString::Number(i);
glBindAttribLocation(m_program, attribIndex[nzElementUsage_TexCoord]+i, uniformName.GetConstBuffer());
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_TexCoord]+i, uniformName.GetConstBuffer());
}
static const bool mrtSupported = NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets);
if (mrtSupported)
{
static const unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets();
uniform.Reserve(14); // 12 + 2
uniform = "RenderTarget";
for (unsigned int i = 0; i < maxRenderTargets; ++i)
{
NzString uniformName = uniform + NzString::Number(i);
glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer());
}
}
for (int i = 0; i <= nzShaderType_Max; ++i)
@@ -148,6 +164,9 @@ void NzGLSLShader::Destroy()
{
NzContext::EnsureContext();
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
it->second.texture->RemoveResourceReference();
for (GLuint shader : m_shaders)
if (shader)
glDeleteShader(shader);
@@ -176,14 +195,14 @@ NzString NzGLSLShader::GetSourceCode(nzShaderType type) const
glGetShaderiv(m_shaders[type], GL_SHADER_SOURCE_LENGTH, &length);
if (length > 1)
{
source.Resize(length-1); // La taille retournée est celle du buffer (Avec caractère de fin)
source.Resize(length-1); // La taille retournée est celle du buffer (Avec caractère de fin)
glGetShaderSource(m_shaders[type], length, nullptr, &source[0]);
}
return source;
}
GLint NzGLSLShader::GetUniformLocation(const NzString& name) const
int NzGLSLShader::GetUniformLocation(const NzString& name) const
{
std::map<NzString, GLint>::const_iterator it = m_idCache.find(name);
GLint id;
@@ -209,7 +228,7 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
{
NzContext::EnsureContext();
GLuint shader = glCreateShader(shaderType[type]);
GLuint shader = glCreateShader(NzOpenGL::ShaderType[type]);
if (!shader)
{
m_log = "Failed to create shader object";
@@ -232,8 +251,8 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
glAttachShader(m_program, shader);
m_shaders[type] = shader;
static NzString success("Compilation successful");
m_log = success;
static NzString successStr("Compilation successful");
m_log = successStr;
return true;
}
@@ -245,9 +264,9 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
if (length > 1)
{
m_log.Clear(true);
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
m_log.Reserve(length+19-1); // La taille retournée est celle du buffer (Avec caractère de fin)
m_log.Prepend("Compilation error: ");
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
m_log.Resize(length+19-1); // Extension du buffer d'écriture pour ajouter le log
glGetShaderInfoLog(shader, length-1, nullptr, &m_log[19]);
}
@@ -280,226 +299,316 @@ bool NzGLSLShader::Lock()
return true;
}
bool NzGLSLShader::SendBoolean(const NzString& name, bool value)
bool NzGLSLShader::SendBoolean(int location, bool value)
{
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
glProgramUniform1i(m_program, location, value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendDouble(const NzString& name, double value)
bool NzGLSLShader::SendDouble(int location, double value)
{
if (glProgramUniform1d)
glProgramUniform1d(m_program, GetUniformLocation(name), value);
glProgramUniform1d(m_program, location, value);
else
{
Lock();
glUniform1d(GetUniformLocation(name), value);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1d(location, value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendFloat(const NzString& name, float value)
bool NzGLSLShader::SendFloat(int location, float value)
{
if (glProgramUniform1f)
glProgramUniform1f(m_program, GetUniformLocation(name), value);
glProgramUniform1f(m_program, location, value);
else
{
Lock();
glUniform1f(GetUniformLocation(name), value);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1f(location, value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendInteger(const NzString& name, int value)
bool NzGLSLShader::SendInteger(int location, int value)
{
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
glProgramUniform1i(m_program, location, value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
bool NzGLSLShader::SendMatrix(int location, const NzMatrix4d& matrix)
{
if (glProgramUniformMatrix4dv)
glProgramUniformMatrix4dv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniformMatrix4dv(location, 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
bool NzGLSLShader::SendMatrix(int location, const NzMatrix4f& matrix)
{
if (glProgramUniformMatrix4fv)
glProgramUniformMatrix4fv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2d& vector)
{
if (glProgramUniform2dv)
glProgramUniform2dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector2f& vector)
{
if (glProgramUniform2fv)
glProgramUniform2fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform2fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3d& vector)
{
if (glProgramUniform3dv)
glProgramUniform3dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector3f& vector)
{
if (glProgramUniform3fv)
glProgramUniform3fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform3fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4d& vector)
{
if (glProgramUniform4dv)
glProgramUniform4dv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4dv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(const NzString& name, const NzVector4f& vector)
{
if (glProgramUniform4fv)
glProgramUniform4fv(m_program, GetUniformLocation(name), 1, vector);
else
{
Lock();
glUniform4fv(GetUniformLocation(name), 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendTexture(const NzString& name, NzTexture* texture)
{
static const unsigned int maxUnits = NazaraRenderer->GetMaxTextureUnits();
unsigned int unitUsed = m_textures.size();
if (unitUsed >= maxUnits)
{
NazaraError("Unable to use texture \"" + name + "\" for shader: all available texture units are used");
return false;
}
// À partir d'ici nous savons qu'il y a au moins un identifiant de texture libre
GLint location = GetUniformLocation(name);
if (location == -1)
{
NazaraError("Parameter name \"" + name + "\" not found in shader");
return false;
}
nzUInt8 unit;
if (unitUsed == 0)
// Pas d'unité utilisée, la tâche est simple
unit = 0;
else
{
auto it = m_textures.rbegin(); // Itérateur vers la fin de la map
unit = it->second.unit;
if (unit == maxUnits-1)
if (!Lock())
{
// Il y a une place libre, mais pas à la fin
for (; it != m_textures.rend(); ++it)
NazaraError("Failed to lock shader");
return false;
}
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendTexture(int location, const NzTexture* texture)
{
auto it = m_textures.find(location);
if (it != m_textures.end())
{
// Slot déjà utilisé
TextureSlot& slot = it->second;
if (slot.texture != texture)
{
slot.texture->RemoveResourceListener(this);
if (texture)
{
if (unit - it->second.unit > 1) // Si l'espace entre les indices est supérieur à 1, alors il y a une place libre
slot.texture = texture;
slot.texture->AddResourceListener(this, location);
slot.updated = false;
}
else
m_textures.erase(it); // On supprime le slot
}
}
else
{
static const unsigned int maxUnits = NzRenderer::GetMaxTextureUnits();
unsigned int unitUsed = m_textures.size();
if (unitUsed >= maxUnits)
{
NazaraError("Unable to use texture for shader: all available texture units are used");
return false;
}
// À partir d'ici nous savons qu'il y a au moins un identifiant de texture libre
nzUInt8 unit;
if (unitUsed == 0)
// Pas d'unité utilisée, la tâche est simple
unit = 0;
else
{
auto it2 = m_textures.rbegin(); // Itérateur vers la fin de la map
unit = it2->second.unit;
if (unit == maxUnits-1)
{
// Il y a une place libre, mais pas à la fin
for (; it2 != m_textures.rend(); ++it2)
{
unit--;
break;
if (unit - it2->second.unit > 1) // Si l'espace entre les indices est supérieur à 1, alors il y a une place libre
{
unit--;
break;
}
}
}
else
// Il y a une place libre à la fin
unit++;
}
TextureSlot slot;
slot.enabled = texture->IsValid();
slot.unit = unit;
slot.texture = texture;
texture->AddResourceListener(this, location);
m_textures[location] = slot;
if (slot.enabled)
{
if (glProgramUniform1i)
glProgramUniform1i(m_program, location, unit);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, unit);
Unlock();
}
}
else
// Il y a une place libre à la fin
unit++;
}
m_textures[location] = TextureSlot{unit, texture};
return true;
}
if (glProgramUniform1i)
glProgramUniform1i(m_program, location, unit);
bool NzGLSLShader::SendVector(int location, const NzVector2d& vector)
{
if (glProgramUniform2dv)
glProgramUniform2dv(m_program, location, 1, vector);
else
{
Lock();
glUniform1i(location, unit);
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform2dv(location, 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(int location, const NzVector2f& vector)
{
if (glProgramUniform2fv)
glProgramUniform2fv(m_program, location, 1, vector);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform2fv(location, 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(int location, const NzVector3d& vector)
{
if (glProgramUniform3dv)
glProgramUniform3dv(m_program, location, 1, vector);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform3dv(location, 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(int location, const NzVector3f& vector)
{
if (glProgramUniform3fv)
glProgramUniform3fv(m_program, location, 1, vector);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform3fv(location, 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(int location, const NzVector4d& vector)
{
if (glProgramUniform4dv)
glProgramUniform4dv(m_program, location, 1, vector);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform4dv(location, 1, vector);
Unlock();
}
return true;
}
bool NzGLSLShader::SendVector(int location, const NzVector4f& vector)
{
if (glProgramUniform4fv)
glProgramUniform4fv(m_program, location, 1, vector);
else
{
if (!Lock())
{
NazaraError("Failed to lock shader");
return false;
}
glUniform4fv(location, 1, vector);
Unlock();
}
@@ -540,3 +649,64 @@ void NzGLSLShader::Unlock()
if (--lockedLevel == 0 && lockedPrevious != m_program)
glUseProgram(lockedPrevious);
}
void NzGLSLShader::OnResourceCreated(const NzResource* resource, int index)
{
NazaraUnused(resource);
auto it = m_textures.find(index);
#ifdef NAZARA_DEBUG
if (it == m_textures.end())
{
NazaraInternalError("Invalid index (" + NzString::Number(index) + ')');
return;
}
#endif
TextureSlot& slot = it->second;
#ifdef NAZARA_DEBUG
if (slot.texture != resource)
{
NazaraInternalError("Wrong texture at location #" + NzString::Number(index));
return;
}
#endif
slot.enabled = true;
slot.updated = false;
}
void NzGLSLShader::OnResourceDestroy(const NzResource* resource, int index)
{
NazaraUnused(resource);
auto it = m_textures.find(index);
#ifdef NAZARA_DEBUG
if (it == m_textures.end())
{
NazaraInternalError("Invalid index (" + NzString::Number(index) + ')');
return;
}
#endif
TextureSlot& slot = it->second;
#ifdef NAZARA_DEBUG
if (slot.texture != resource)
{
NazaraInternalError("Wrong texture at location #" + NzString::Number(index));
return;
}
#endif
slot.enabled = false;
}
void NzGLSLShader::OnResourceReleased(const NzResource* resource, int index)
{
if (m_textures.erase(index) == 0)
NazaraInternalError("Texture " + NzString::Pointer(resource) + " not found");
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -7,57 +7,67 @@
#ifndef NAZARA_GLSLSHADER_HPP
#define NAZARA_GLSLSHADER_HPP
#include <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Shader.hpp>
#include <Nazara/Renderer/ShaderImpl.hpp>
#include <map>
class NzGLSLShader : public NzShaderImpl
class NzResource;
class NzGLSLShader : public NzShaderImpl, NzResourceListener
{
public:
NzGLSLShader(NzShader* parent);
~NzGLSLShader();
bool Bind();
bool BindTextures();
bool Compile();
bool Create();
bool Create();
void Destroy();
NzString GetLog() const;
nzShaderLanguage GetLanguage() const;
NzString GetSourceCode(nzShaderType type) const;
GLint GetUniformLocation(const NzString& name) const;
int GetUniformLocation(const NzString& name) const;
bool IsLoaded(nzShaderType type) const;
bool Load(nzShaderType type, const NzString& source);
bool Lock();
bool SendBoolean(const NzString& name, bool value);
bool SendDouble(const NzString& name, double value);
bool SendFloat(const NzString& name, float value);
bool SendInteger(const NzString& name, int value);
bool SendMatrix(const NzString& name, const NzMatrix4d& matrix);
bool SendMatrix(const NzString& name, const NzMatrix4f& matrix);
bool SendVector(const NzString& name, const NzVector2d& vector);
bool SendVector(const NzString& name, const NzVector2f& vector);
bool SendVector(const NzString& name, const NzVector3d& vector);
bool SendVector(const NzString& name, const NzVector3f& vector);
bool SendVector(const NzString& name, const NzVector4d& vector);
bool SendVector(const NzString& name, const NzVector4f& vector);
bool SendTexture(const NzString& name, NzTexture* texture);
bool SendBoolean(int location, bool value);
bool SendDouble(int location, double value);
bool SendFloat(int location, float value);
bool SendInteger(int location, int value);
bool SendMatrix(int location, const NzMatrix4d& matrix);
bool SendMatrix(int location, const NzMatrix4f& matrix);
bool SendTexture(int location, const NzTexture* texture);
bool SendVector(int location, const NzVector2d& vector);
bool SendVector(int location, const NzVector2f& vector);
bool SendVector(int location, const NzVector3d& vector);
bool SendVector(int location, const NzVector3f& vector);
bool SendVector(int location, const NzVector4d& vector);
bool SendVector(int location, const NzVector4f& vector);
void Unbind();
void Unlock();
private:
void OnResourceCreated(const NzResource* resource, int index) override;
void OnResourceDestroy(const NzResource* resource, int index) override;
void OnResourceReleased(const NzResource* resource, int index) override;
struct TextureSlot
{
bool enabled;
bool updated = false;
nzUInt8 unit;
NzTexture* texture;
const NzTexture* texture;
};
mutable std::map<NzString, GLint> m_idCache;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -12,39 +12,7 @@
namespace
{
GLenum bufferLock[] = {
GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite
GL_READ_ONLY, // nzBufferAccess_ReadOnly
GL_READ_WRITE, // nzBufferAccess_ReadWrite
GL_WRITE_ONLY // nzBufferAccess_WriteOnly
};
GLenum bufferLockRange[] = {
GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite
GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite
GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly
};
GLenum bufferTarget[] = {
GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index,
GL_ARRAY_BUFFER, // nzBufferType_Vertex
};
GLenum bufferTargetBinding[] = {
GL_ELEMENT_ARRAY_BUFFER_BINDING, // nzBufferType_Index,
GL_ARRAY_BUFFER_BINDING, // nzBufferType_Vertex
};
GLenum bufferUsage[] = {
// J'ai choisi DYNAMIC à la place de STREAM car DYNAMIC semble plus adapté au profil "une mise à jour pour quelques rendus"
// Ce qui est je pense le scénario qui arrivera le plus souvent (Prévoir une option pour permettre d'utiliser le STREAM_DRAW ?)
// Source: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=160839
GL_DYNAMIC_DRAW, // nzBufferUsage_Dynamic
GL_STATIC_DRAW // nzBufferUsage_Static
};
typedef nzUInt8* (*LockRoutine)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
using LockRoutine = nzUInt8* (*)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
@@ -52,17 +20,17 @@ namespace
if (access == nzBufferAccess_DiscardAndWrite)
{
GLint bufferSize;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &bufferSize);
GLint bufSize;
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
GLint bufferUsage;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &bufferUsage);
GLint bufUsage;
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
// On discard le buffer
glBufferData(bufferTargetBinding[type], bufferSize, nullptr, bufferUsage);
glBufferData(NzOpenGL::BufferTargetBinding[type], bufSize, nullptr, bufUsage);
}
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
void* ptr = glMapBuffer(NzOpenGL::BufferTarget[type], NzOpenGL::BufferLock[access]);
if (ptr)
return reinterpret_cast<nzUInt8*>(ptr) + offset;
else
@@ -71,7 +39,7 @@ namespace
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[access]));
return reinterpret_cast<nzUInt8*>(glMapBufferRange(NzOpenGL::BufferTarget[type], offset, size, NzOpenGL::BufferLockRange[access]));
}
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
@@ -109,7 +77,7 @@ void NzHardwareBuffer::Bind()
}
#endif
glBindBuffer(bufferTarget[m_type], m_buffer);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
}
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
@@ -120,14 +88,14 @@ bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
glGenBuffers(1, &m_buffer);
GLint previous;
glGetIntegerv(bufferTargetBinding[m_type], &previous);
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
glBindBuffer(bufferTarget[m_type], m_buffer);
glBufferData(bufferTarget[m_type], size, nullptr, bufferUsage[usage]);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[usage]);
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
if (previous != 0)
glBindBuffer(bufferTarget[m_type], previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return true;
}
@@ -144,10 +112,10 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
// Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil
// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
@@ -155,9 +123,9 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
{
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
if (size == m_parent->GetSize())
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetUsage()]); // Discard
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
glBufferSubData(bufferTarget[m_type], offset, size, data);
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
}
else
{
@@ -170,20 +138,20 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
std::memcpy(ptr, data, size);
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
return false;
}
}
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
if (previous != m_buffer && previous != 0)
glBindBuffer(bufferTarget[m_type], previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return true;
}
@@ -202,18 +170,18 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
{
NzContext::EnsureContext();
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
void* ptr = mapBuffer(m_type, access, offset, size);
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
if (previous != m_buffer && previous != 0)
glBindBuffer(bufferTarget[m_type], previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return ptr;
}
@@ -223,28 +191,28 @@ bool NzHardwareBuffer::Unmap()
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
if (previous != m_buffer && previous != 0)
glBindBuffer(bufferTarget[m_type], previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return false;
}
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
if (previous != m_buffer && previous != 0)
glBindBuffer(bufferTarget[m_type], previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return true;
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -14,21 +14,17 @@
NzOcclusionQuery::NzOcclusionQuery() :
m_id(0)
{
#if NAZARA_RENDERER_SAFE
if (IsSupported())
{
#endif
NzContext::EnsureContext();
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
#if NAZARA_RENDERER_SAFE
}
else
{
NazaraError("Occlusion queries not supported");
return;
}
#endif
#ifdef NAZARA_DEBUG
if (!m_id)
@@ -98,5 +94,5 @@ bool NzOcclusionQuery::IsResultAvailable() const
bool NzOcclusionQuery::IsSupported()
{
return NazaraRenderer->HasCapability(nzRendererCap_OcclusionQuery);
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderTarget.hpp>
@@ -10,20 +10,20 @@ NzRenderTarget::~NzRenderTarget() = default;
bool NzRenderTarget::IsActive() const
{
return NazaraRenderer->GetTarget() == this;
return NzRenderer::GetTarget() == this;
}
bool NzRenderTarget::SetActive(bool active)
{
if (active)
return NazaraRenderer->SetTarget(this);
else if (NazaraRenderer->GetTarget() == this)
return NazaraRenderer->SetTarget(nullptr);
return NzRenderer::SetTarget(this);
else if (NzRenderer::GetTarget() == this)
return NzRenderer::SetTarget(nullptr);
return true;
}
void NzRenderTarget::Desactivate()
{
// Seuls les target sans contextes (ex: NzRenderTexture) nécessitent une désactivation
// Seuls les target sans contextes (ex: NzRenderTexture) nécessitent une désactivation
}

View File

@@ -0,0 +1,728 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/RenderTexture.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <vector>
#include <Nazara/Renderer/Debug.hpp>
namespace
{
struct Attachment
{
union
{
GLuint buffer;
NzTexture* texture;
};
bool isBuffer;
bool isUsed = false;
};
unsigned int attachmentIndex[nzAttachmentPoint_Max+1] =
{
2, // nzAttachmentPoint_Color
0, // nzAttachmentPoint_Depth
0, // nzAttachmentPoint_DepthStencil
1 // nzAttachmentPoint_Stencil
};
nzAttachmentPoint formatTypeToAttachment[nzPixelFormatType_Max+1] =
{
nzAttachmentPoint_Color, // nzPixelFormatType_Color
nzAttachmentPoint_Depth, // nzPixelFormatType_Depth
nzAttachmentPoint_DepthStencil, // nzPixelFormatType_DepthStencil
nzAttachmentPoint_Stencil // nzPixelFormatType_Stencil
};
GLuint lockedPrevious = 0;
nzUInt8 lockedLevel = 0;
}
struct NzRenderTextureImpl
{
GLuint fbo;
std::vector<Attachment> attachements;
std::vector<GLenum> drawBuffers;
NzContext* context;
bool checked = false;
bool complete = false;
bool drawBuffersUpdated = true;
unsigned int height;
unsigned int width;
};
NzRenderTexture::~NzRenderTexture()
{
Destroy();
}
bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return false;
}
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
{
NazaraError("Index must be 0 for non-color attachments");
return false;
}
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
m_impl->attachements[depthStencilIndex].isUsed)
{
NazaraError("Stencil target already attached by DepthStencil attachment");
return false;
}
if (formatTypeToAttachment[NzPixelFormat::GetType(format)] != attachmentPoint)
{
NazaraError("Pixel format type does not match attachment point type");
return false;
}
#endif
NzOpenGL::Format openglFormat;
if (!NzOpenGL::TranslateFormat(format, &openglFormat, NzOpenGL::FormatType_RenderBuffer))
{
NazaraError("Failed to translate pixel format into OpenGL format");
return false;
}
if (!Lock())
{
NazaraError("Failed to lock render texture");
return false;
}
// Détachement de l'attache précédente (Si il y a)
Detach(attachmentPoint, index);
GLuint renderBuffer = 0;
glGenRenderbuffers(1, &renderBuffer);
if (!renderBuffer)
{
NazaraError("Failed to create renderbuffer");
return false;
}
GLint previous;
glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous);
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, m_impl->width, m_impl->height);
if (previous != 0)
glBindRenderbuffer(GL_RENDERBUFFER, previous);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, renderBuffer);
Unlock();
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
if (m_impl->attachements.size() < minSize)
m_impl->attachements.resize(minSize);
Attachment& attachment = m_impl->attachements[minSize-1];
attachment.isBuffer = true;
attachment.isUsed = true;
attachment.buffer = renderBuffer;
m_impl->checked = false;
m_impl->drawBuffersUpdated = false;
return true;
}
bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return false;
}
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
{
NazaraError("Index must be 0 for non-color attachments");
return false;
}
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
m_impl->attachements[depthStencilIndex].isUsed)
{
NazaraError("Stencil target already attached by DepthStencil attachment");
return false;
}
if (!texture || !texture->IsValid())
{
NazaraError("Invalid texture");
return false;
}
if (texture->GetWidth() < m_impl->width || texture->GetHeight() < m_impl->height)
{
NazaraError("Texture cannot be smaller than render texture");
return false;
}
if (texture->GetRenderTexture() != nullptr)
{
NazaraError("Texture already used by another render texture");
return false;
}
if (formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())] != attachmentPoint)
{
NazaraError("Pixel format type does not match attachment point type");
return false;
}
#endif
if (!Lock())
{
NazaraError("Failed to lock render texture");
return false;
}
// Détachement de l'attache précédente (Si il y a)
Detach(attachmentPoint, index);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0);
Unlock();
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
if (m_impl->attachements.size() < minSize)
m_impl->attachements.resize(minSize);
Attachment& attachment = m_impl->attachements[minSize-1];
attachment.isBuffer = true;
attachment.isUsed = true;
attachment.texture = texture;
texture->AddResourceListener(this, minSize-1);
texture->SetRenderTexture(this);
m_impl->checked = false;
m_impl->drawBuffersUpdated = false;
return true;
}
bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return false;
}
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
{
NazaraError("Index must be 0 for non-color attachments");
return false;
}
if (attachmentPoint == nzAttachmentPoint_Stencil)
{
NazaraError("Targeting stencil-only textures is not supported");
return false;
}
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
m_impl->attachements[depthStencilIndex].isUsed)
{
NazaraError("Stencil target already attached by DepthStencil attachment");
return false;
}
if (!texture || !texture->IsValid())
{
NazaraError("Invalid texture");
return false;
}
if (texture->GetWidth() < m_impl->width || texture->GetHeight() < m_impl->height)
{
NazaraError("Texture cannot be smaller than render texture");
return false;
}
unsigned int depth = (texture->GetType() == nzImageType_Cubemap) ? 6 : texture->GetDepth();
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return false;
}
if (texture->GetRenderTexture() != nullptr)
{
NazaraError("Texture already used by another render texture");
return false;
}
if (formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())] != attachmentPoint)
{
NazaraError("Pixel format type does not match attachment point type");
return false;
}
#endif
if (!Lock())
{
NazaraError("Failed to lock render texture");
return false;
}
// Détachement de l'attache précédente (Si il y a)
Detach(attachmentPoint, index);
switch (texture->GetType())
{
case nzImageType_1D:
glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_1D, texture->GetOpenGLID(), 0);
break;
case nzImageType_1D_Array:
case nzImageType_2D_Array:
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0, z);
break;
case nzImageType_2D:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, NzOpenGL::TextureTarget[texture->GetType()], texture->GetOpenGLID(), 0);
break;
case nzImageType_3D:
glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_3D, texture->GetOpenGLID(), 0, z);
break;
case nzImageType_Cubemap:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, NzOpenGL::CubemapFace[z], texture->GetOpenGLID(), 0);
break;
}
Unlock();
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
if (m_impl->attachements.size() < minSize)
m_impl->attachements.resize(minSize);
Attachment& attachment = m_impl->attachements[minSize-1];
attachment.isBuffer = true;
attachment.isUsed = true;
attachment.texture = texture;
texture->AddResourceListener(this);
texture->SetRenderTexture(this);
m_impl->checked = false;
m_impl->drawBuffersUpdated = false;
return true;
}
bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock)
{
if (!IsSupported())
{
NazaraError("Render textures not supported");
return false;
}
Destroy();
#if NAZARA_RENDERER_SAFE
if (width == 0)
{
NazaraError("Width must be at least 1 (0)");
return false;
}
if (height == 0)
{
NazaraError("Height must be at least 1 (0)");
return false;
}
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
NzRenderTextureImpl* impl = new NzRenderTextureImpl;
impl->width = width;
impl->height = height;
impl->context = NzContext::GetCurrent();
impl->context->AddResourceListener(this);
impl->fbo = 0;
glGenFramebuffers(1, &impl->fbo);
if (!impl->fbo)
{
NazaraError("Failed to create framebuffer");
delete impl;
return false;
}
m_impl = impl;
if (lock && !Lock())
{
NazaraError("Failed to lock render texture");
delete impl;
m_impl = nullptr;
return false;
}
return true;
}
void NzRenderTexture::Destroy()
{
if (m_impl)
{
#if NAZARA_RENDERER_SAFE
if (NzContext::GetCurrent() != m_impl->context)
{
NazaraError("RenderTexture can only be used with it's creation context");
return;
}
#endif
m_impl->context->RemoveResourceListener(this);
for (Attachment& attachment : m_impl->attachements)
{
if (attachment.isUsed)
{
if (attachment.isBuffer)
glDeleteRenderbuffers(1, &attachment.buffer);
else
{
attachment.texture->RemoveResourceListener(this);
attachment.texture->SetRenderTexture(nullptr);
}
}
}
glDeleteFramebuffers(1, &m_impl->fbo);
delete m_impl;
m_impl = nullptr;
}
}
void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return;
}
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
{
NazaraError("Index must be 0 for non-color attachments");
return;
}
#endif
unsigned int attachIndex = attachmentIndex[attachmentPoint]+index;
if (attachIndex >= m_impl->attachements.size())
return;
Attachment& attachement = m_impl->attachements[attachIndex];
if (!attachement.isUsed)
return;
if (!Lock())
{
NazaraError("Failed to lock render texture");
return;
}
attachement.isUsed = false;
if (attachement.isBuffer)
{
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0);
glDeleteRenderbuffers(1, &attachement.buffer);
}
else
{
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0);
attachement.texture->RemoveResourceListener(this);
attachement.texture->SetRenderTexture(nullptr);
}
Unlock();
m_impl->checked = false;
m_impl->drawBuffersUpdated = false;
}
unsigned int NzRenderTexture::GetHeight() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return 0;
}
#endif
return m_impl->height;
}
NzRenderTargetParameters NzRenderTexture::GetParameters() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return NzRenderTargetParameters();
}
#endif
return NzRenderTargetParameters();
}
unsigned int NzRenderTexture::GetWidth() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return 0;
}
#endif
return m_impl->width;
}
bool NzRenderTexture::IsComplete() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return false;
}
#endif
if (!m_impl->checked)
{
if (!Lock())
{
NazaraError("Failed to lock render texture");
return false;
}
GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
Unlock();
m_impl->complete = false;
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
m_impl->complete = true;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
NazaraError("Incomplete attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
NazaraInternalError("Incomplete draw buffer");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
NazaraInternalError("Incomplete read buffer");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
NazaraError("Incomplete missing attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
NazaraError("Incomplete multisample");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
NazaraError("Incomplete layer targets");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
NazaraError("Render texture has unsupported attachments");
break;
default:
NazaraInternalError("Unknown error");
}
m_impl->checked = true;
}
return m_impl->complete;
}
bool NzRenderTexture::IsRenderable() const
{
return IsComplete();
}
bool NzRenderTexture::IsValid() const
{
return m_impl != nullptr;
}
bool NzRenderTexture::Lock() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Render texture not created");
return false;
}
if (NzContext::GetCurrent() != m_impl->context)
{
NazaraError("RenderTexture cannot be used with this context");
return false;
}
#endif
if (lockedLevel++ == 0)
{
GLint previous;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previous);
lockedPrevious = previous;
if (lockedPrevious != m_impl->fbo)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo);
}
return true;
}
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);
}
bool NzRenderTexture::HasContext() const
{
return false;
}
bool NzRenderTexture::IsSupported()
{
return NzRenderer::HasCapability(nzRendererCap_RenderTexture);
}
bool NzRenderTexture::Activate()
{
#if NAZARA_RENDERER_SAFE
if (NzContext::GetCurrent() != m_impl->context)
{
NazaraError("RenderTexture cannot be used with this context");
return false;
}
#endif
if (!m_impl->drawBuffersUpdated)
{
m_impl->drawBuffers.clear();
m_impl->drawBuffers.reserve(m_impl->attachements.size());
for (unsigned int i = attachmentIndex[nzAttachmentPoint_Color]; i < m_impl->attachements.size(); ++i)
{
if (m_impl->attachements[i].isUsed)
m_impl->drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i - attachmentIndex[nzAttachmentPoint_Color]);
}
m_impl->drawBuffersUpdated = true;
}
glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo);
return true;
}
void NzRenderTexture::Desactivate()
{
#if NAZARA_RENDERER_SAFE
if (NzContext::GetCurrent() != m_impl->context)
{
NazaraError("RenderTexture cannot be used with this context");
return;
}
#endif
glFlush();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
void NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
{
if (resource == m_impl->context)
// Notre context a été détruit, libérons la RenderTexture pour éviter un leak
Destroy();
else
{
// Sinon, c'est une texture
// La ressource n'est plus, du coup nous mettons à jour
Attachment& attachement = m_impl->attachements[index];
attachement.isUsed = false;
m_impl->checked = false;
m_impl->drawBuffersUpdated = false;
}
}

View File

@@ -1,22 +1,17 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
NzRenderWindow::NzRenderWindow() :
m_context(nullptr)
{
}
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters) :
m_context(nullptr)
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
{
Create(mode, title, style, parameters);
@@ -29,8 +24,7 @@ m_context(nullptr)
#endif
}
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters) :
m_context(nullptr)
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
{
Create(handle, parameters);
@@ -45,6 +39,8 @@ m_context(nullptr)
NzRenderWindow::~NzRenderWindow()
{
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
OnWindowDestroy();
}
bool NzRenderWindow::CopyToImage(NzImage* image)
@@ -136,6 +132,15 @@ bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& pa
void NzRenderWindow::Display()
{
if (m_framerateLimit > 0)
{
int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds();
if (remainingTime > 0)
NzThread::Sleep(remainingTime);
m_clock.Restart();
}
if (m_context && m_parameters.doubleBuffered)
m_context->SwapBuffers();
}
@@ -173,17 +178,6 @@ void NzRenderWindow::EnableVerticalSync(bool enabled)
NazaraError("No context");
}
NzContextParameters NzRenderWindow::GetContextParameters() const
{
if (m_context)
return m_context->GetParameters();
else
{
NazaraError("Window not created/context not initialized");
return NzContextParameters();
}
}
unsigned int NzRenderWindow::GetHeight() const
{
return NzWindow::GetHeight();
@@ -208,16 +202,32 @@ unsigned int NzRenderWindow::GetWidth() const
return NzWindow::GetWidth();
}
bool NzRenderWindow::IsRenderable() const
{
return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi
}
void NzRenderWindow::SetFramerateLimit(unsigned int limit)
{
m_framerateLimit = limit;
}
NzContextParameters NzRenderWindow::GetContextParameters() const
{
if (m_context)
return m_context->GetParameters();
else
{
NazaraError("Window not created/context not initialized");
return NzContextParameters();
}
}
bool NzRenderWindow::HasContext() const
{
return true;
}
bool NzRenderWindow::IsValid() const
{
return m_impl != nullptr && m_context != nullptr;
}
bool NzRenderWindow::Activate()
{
if (m_context->SetActive(true))
@@ -232,12 +242,7 @@ bool NzRenderWindow::Activate()
}
}
void NzRenderWindow::OnClose()
{
delete m_context;
}
bool NzRenderWindow::OnCreate()
bool NzRenderWindow::OnWindowCreated()
{
m_parameters.doubleBuffered = true;
m_parameters.window = GetHandle();
@@ -253,10 +258,19 @@ bool NzRenderWindow::OnCreate()
EnableVerticalSync(false);
#if NAZARA_RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION
if (!SetActive(true)) // Les fenêtres s'activent à la création
if (!SetActive(true)) // Les fenêtres s'activent à la création
NazaraWarning("Failed to activate window");
#endif
m_clock.Restart();
return true;
}
void NzRenderWindow::OnWindowDestroy()
{
if (m_context)
{
delete m_context;
m_context = nullptr;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -14,15 +14,7 @@
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
NzShader::NzShader() :
m_impl(nullptr),
m_compiled(false)
{
}
NzShader::NzShader(nzShaderLanguage language) :
m_impl(nullptr),
m_compiled(false)
NzShader::NzShader(nzShaderLanguage language)
{
Create(language);
@@ -68,6 +60,7 @@ bool NzShader::Create(nzShaderLanguage language)
return false;
}
NotifyCreated();
return true;
}
@@ -94,6 +87,8 @@ void NzShader::Destroy()
{
if (m_impl)
{
NotifyDestroy();
m_impl->Destroy();
delete m_impl;
m_impl = nullptr;
@@ -161,6 +156,32 @@ NzString NzShader::GetSourceCode(nzShaderType type) const
return m_impl->GetSourceCode(type);
}
int NzShader::GetUniformLocation(const NzString& name) const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->GetUniformLocation(name);
}
bool NzShader::HasUniform(const NzString& name) const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->GetUniformLocation(name) != -1;
}
bool NzShader::IsCompiled() const
{
#if NAZARA_RENDERER_SAFE
@@ -282,7 +303,7 @@ bool NzShader::Lock()
return m_impl->Lock();
}
bool NzShader::SendBoolean(const NzString& name, bool value)
bool NzShader::SendBoolean(int location, bool value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -290,57 +311,43 @@ bool NzShader::SendBoolean(const NzString& name, bool value)
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendBoolean(name, value);
return m_impl->SendBoolean(location, value);
}
bool NzShader::SendDouble(const NzString& name, double value)
bool NzShader::SendDouble(int location, double value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
if (!NzRenderer::HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendDouble(name, value);
}
bool NzShader::SendFloat(const NzString& name, float value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendFloat(name, value);
}
bool NzShader::SendInteger(const NzString& name, int value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
if (location == -1)
{
NazaraError("Shader not created");
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendInteger(name, value);
return m_impl->SendDouble(location, value);
}
bool NzShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
bool NzShader::SendFloat(int location, float value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -349,30 +356,61 @@ bool NzShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendFloat(location, value);
}
bool NzShader::SendInteger(int location, int value)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendInteger(location, value);
}
bool NzShader::SendMatrix(int location, const NzMatrix4d& matrix)
{
#if NAZARA_RENDERER_SAFE
if (!NzRenderer::HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendMatrix(name, matrix);
}
bool NzShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendMatrix(name, matrix);
return m_impl->SendMatrix(location, matrix);
}
bool NzShader::SendVector(const NzString& name, const NzVector2d& vector)
bool NzShader::SendMatrix(int location, const NzMatrix4f& matrix)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -381,30 +419,61 @@ bool NzShader::SendVector(const NzString& name, const NzVector2d& vector)
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendMatrix(location, matrix);
}
bool NzShader::SendTexture(int location, const NzTexture* texture)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendTexture(location, texture);
}
bool NzShader::SendVector(int location, const NzVector2d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!NzRenderer::HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector2f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendVector(name, vector);
return m_impl->SendVector(location, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector3d& vector)
bool NzShader::SendVector(int location, const NzVector2f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -413,30 +482,42 @@ bool NzShader::SendVector(const NzString& name, const NzVector3d& vector)
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendVector(location, vector);
}
bool NzShader::SendVector(int location, const NzVector3d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!NzRenderer::HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector3f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendVector(name, vector);
return m_impl->SendVector(location, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4d& vector)
bool NzShader::SendVector(int location, const NzVector3f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -445,17 +526,42 @@ bool NzShader::SendVector(const NzString& name, const NzVector4d& vector)
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendVector(location, vector);
}
bool NzShader::SendVector(int location, const NzVector4d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!NzRenderer::HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (location == -1)
{
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendVector(name, vector);
return m_impl->SendVector(location, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4f& vector)
bool NzShader::SendVector(int location, const NzVector4f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -463,22 +569,15 @@ bool NzShader::SendVector(const NzString& name, const NzVector4f& vector)
NazaraError("Shader not created");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendTexture(const NzString& name, NzTexture* texture)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
if (location == -1)
{
NazaraError("Shader not created");
NazaraError("Invalid location");
return false;
}
#endif
return m_impl->SendTexture(name, texture);
return m_impl->SendVector(location, vector);
}
void NzShader::Unlock()
@@ -499,7 +598,7 @@ bool NzShader::IsLanguageSupported(nzShaderLanguage language)
switch (language)
{
case nzShaderLanguage_Cg:
return false; // ??
return false; //FIXME: ??
case nzShaderLanguage_GLSL:
return true;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ShaderImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
@@ -9,7 +9,6 @@
#include <Nazara/Renderer/Shader.hpp>
class NzRenderer;
class NzTexture;
class NzVertexBuffer;
class NzVertexDeclaration;
@@ -23,6 +22,7 @@ class NzShaderImpl
virtual ~NzShaderImpl();
virtual bool Bind() = 0;
virtual bool BindTextures() = 0;
virtual bool Compile() = 0;
virtual bool Create() = 0;
@@ -32,6 +32,7 @@ class NzShaderImpl
virtual NzString GetLog() const = 0;
virtual nzShaderLanguage GetLanguage() const = 0;
virtual NzString GetSourceCode(nzShaderType type) const = 0;
virtual int GetUniformLocation(const NzString& name) const = 0;
virtual bool IsLoaded(nzShaderType type) const = 0;
@@ -39,19 +40,19 @@ class NzShaderImpl
virtual bool Lock() = 0;
virtual bool SendBoolean(const NzString& name, bool value) = 0;
virtual bool SendDouble(const NzString& name, double value) = 0;
virtual bool SendFloat(const NzString& name, float value) = 0;
virtual bool SendInteger(const NzString& name, int value) = 0;
virtual bool SendMatrix(const NzString& name, const NzMatrix4d& matrix) = 0;
virtual bool SendMatrix(const NzString& name, const NzMatrix4f& matrix) = 0;
virtual bool SendVector(const NzString& name, const NzVector2d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector2f& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector3d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector3f& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector4d& vector) = 0;
virtual bool SendVector(const NzString& name, const NzVector4f& vector) = 0;
virtual bool SendTexture(const NzString& name, NzTexture* texture) = 0;
virtual bool SendBoolean(int location, bool value) = 0;
virtual bool SendDouble(int location, double value) = 0;
virtual bool SendFloat(int location, float value) = 0;
virtual bool SendInteger(int location, int value) = 0;
virtual bool SendMatrix(int location, const NzMatrix4d& matrix) = 0;
virtual bool SendMatrix(int location, const NzMatrix4f& matrix) = 0;
virtual bool SendTexture(int location, const NzTexture* texture) = 0;
virtual bool SendVector(int location, const NzVector2d& vector) = 0;
virtual bool SendVector(int location, const NzVector2f& vector) = 0;
virtual bool SendVector(int location, const NzVector3d& vector) = 0;
virtual bool SendVector(int location, const NzVector3f& vector) = 0;
virtual bool SendVector(int location, const NzVector4d& vector) = 0;
virtual bool SendVector(int location, const NzVector4f& vector) = 0;
virtual void Unbind() = 0;
virtual void Unlock() = 0;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/OpenGL.hpp>
@@ -17,7 +17,7 @@ struct NzTextureImpl
nzImageType type;
nzPixelFormat format;
nzUInt8 levelCount;
bool isTarget = false;
NzRenderTexture* renderTexture = nullptr;
bool mipmapping = false;
bool mipmapsUpdated = true;
unsigned int depth;
@@ -27,131 +27,25 @@ struct NzTextureImpl
namespace
{
GLenum cubemapFace[] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ
};
GLenum openglTarget[] =
{
GL_TEXTURE_1D, // nzImageType_1D
GL_TEXTURE_2D, // nzImageType_2D
GL_TEXTURE_3D, // nzImageType_3D
GL_TEXTURE_CUBE_MAP // nzImageType_Cubemap
};
GLenum openglTargetBinding[] =
{
GL_TEXTURE_BINDING_1D, // nzImageType_1D
GL_TEXTURE_BINDING_2D, // nzImageType_2D
GL_TEXTURE_BINDING_3D, // nzImageType_3D
GL_TEXTURE_BINDING_CUBE_MAP // nzImageType_Cubemap
};
struct OpenGLFormat
{
GLint internalFormat;
GLenum dataFormat;
GLenum dataType;
};
bool GetOpenGLFormat(nzPixelFormat pixelFormat, OpenGLFormat* format)
{
switch (pixelFormat)
{
case nzPixelFormat_BGR8:
format->dataFormat = GL_BGR;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
return true;
case nzPixelFormat_BGRA8:
format->dataFormat = GL_BGRA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
return true;
case nzPixelFormat_DXT1:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
return true;
case nzPixelFormat_DXT3:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
return true;
case nzPixelFormat_DXT5:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
return true;
case nzPixelFormat_L8:
case nzPixelFormat_LA8:
NazaraError("Pixel format not supported");
return false;
case nzPixelFormat_RGB5A1:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_5_5_5_1;
format->internalFormat = GL_RGB5_A1;
return true;
case nzPixelFormat_RGB8:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
return true;
case nzPixelFormat_RGBA4:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_4_4_4_4;
format->internalFormat = GL_RGBA4;
return true;
case nzPixelFormat_RGBA8:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
return true;
case nzPixelFormat_Undefined:
NazaraInternalError("Invalid pixel format");
return false;
}
NazaraError("Pixel format not handled");
return false;
}
bool CreateTexture(NzTextureImpl* impl, bool proxy)
{
OpenGLFormat openGLFormat;
if (!GetOpenGLFormat(impl->format, &openGLFormat))
NzOpenGL::Format openGLFormat;
if (!NzOpenGL::TranslateFormat(impl->format, &openGLFormat, NzOpenGL::FormatType_Texture))
{
NazaraError("Failed to get OpenGL format");
NazaraError("Format not supported by OpenGL");
return false;
}
GLenum target;
GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[impl->type] : NzOpenGL::TextureTarget[impl->type];
GLint previous;
glGetIntegerv(NzOpenGL::TextureTargetBinding[impl->type], &previous);
switch (impl->type)
{
case nzImageType_1D:
{
target = (proxy) ? GL_TEXTURE_1D : GL_PROXY_TEXTURE_1D;
/*if (glTexStorage1D)
if (glTexStorage1D)
glTexStorage1D(target, impl->levelCount, openGLFormat.internalFormat, impl->width);
else*/
else
{
unsigned int w = impl->width;
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
@@ -164,13 +58,12 @@ namespace
break;
}
case nzImageType_1D_Array:
case nzImageType_2D:
{
target = (proxy) ? GL_TEXTURE_2D : GL_PROXY_TEXTURE_2D;
/*if (glTexStorage2D)
if (glTexStorage2D)
glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height);
else*/
else
{
unsigned int w = impl->width;
unsigned int h = impl->height;
@@ -187,13 +80,12 @@ namespace
break;
}
case nzImageType_2D_Array:
case nzImageType_3D:
{
target = (proxy) ? GL_TEXTURE_3D : GL_PROXY_TEXTURE_3D;
/*if (glTexStorage3D)
if (glTexStorage3D)
glTexStorage3D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height, impl->depth);
else*/
else
{
unsigned int w = impl->width;
unsigned int h = impl->height;
@@ -216,16 +108,14 @@ namespace
case nzImageType_Cubemap:
{
target = (proxy) ? GL_TEXTURE_CUBE_MAP : GL_PROXY_TEXTURE_CUBE_MAP;
/*if (glTexStorage2D)
if (glTexStorage2D)
glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height);
else*/
else
{
unsigned int size = impl->width; // Les cubemaps ont une longueur et largeur identique
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
for (GLenum face : cubemapFace)
for (GLenum face : NzOpenGL::CubemapFace)
glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
if (size > 1U)
@@ -234,15 +124,11 @@ namespace
}
break;
}
default:
NazaraInternalError("Image type not handled");
return false;
}
if (proxy)
{
GLint internalFormat;
GLint internalFormat = 0;
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat);
if (internalFormat == 0)
return false;
@@ -261,12 +147,12 @@ namespace
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(openglTargetBinding[impl->type], &previous);
glGetIntegerv(NzOpenGL::TextureTargetBinding[impl->type], &previous);
lockedPrevious[impl->type] = static_cast<GLuint>(previous);
if (lockedPrevious[impl->type] != impl->id)
glBindTexture(openglTarget[impl->type], impl->id);
glBindTexture(NzOpenGL::TextureTarget[impl->type], impl->id);
}
}
@@ -301,7 +187,7 @@ namespace
#endif
if (--lockedLevel[impl->type] == 0 && lockedPrevious[impl->type] != impl->id)
glBindTexture(openglTarget[impl->type], lockedPrevious[impl->type]);
glBindTexture(NzOpenGL::TextureTarget[impl->type], lockedPrevious[impl->type]);
}
}
@@ -329,42 +215,10 @@ NzTexture::~NzTexture()
Destroy();
}
bool NzTexture::Bind() const
{
#if NAZARA_RENDERER_SAFE
if (lockedLevel[m_impl->type] > 0)
{
NazaraError("Cannot bind texture while a texture is locked");
return false;
}
#endif
glBindTexture(openglTarget[m_impl->type], m_impl->id);
if (m_impl->mipmapping && !m_impl->mipmapsUpdated)
{
glGenerateMipmap(openglTarget[m_impl->type]);
m_impl->mipmapsUpdated = true;
}
return true;
}
bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount, bool lock)
{
#if NAZARA_RENDERER_SAFE
if (m_impl && m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be recreated");
return false;
}
#endif
Destroy();
if (width == 0 || height == 0 || depth == 0)
return true;
#if NAZARA_RENDERER_SAFE
if (!IsTypeSupported(type))
{
@@ -384,6 +238,24 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
return false;
}
if (width == 0)
{
NazaraError("Width must be at least 1 (0)");
return false;
}
if (height == 0)
{
NazaraError("Height must be at least 1 (0)");
return false;
}
if (depth == 0)
{
NazaraError("Depth must be at least 1 (0)");
return false;
}
switch (type)
{
case nzImageType_1D:
@@ -400,6 +272,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
}
break;
case nzImageType_1D_Array:
case nzImageType_2D:
if (depth > 1)
{
@@ -408,6 +281,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
}
break;
case nzImageType_2D_Array:
case nzImageType_3D:
break;
@@ -424,10 +298,6 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
return false;
}
break;
default:
NazaraInternalError("Image type not handled");
return false;
}
#endif
@@ -453,8 +323,8 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
LockTexture(impl);
// Vérification du support par la carte graphique
if (!CreateTexture(impl, true))
// Vérification du support par la carte graphique
/*if (!CreateTexture(impl, true))
{
NazaraError("Texture's parameters not supported by driver");
UnlockTexture(impl);
@@ -462,9 +332,9 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
delete impl;
return false;
}
}*/
// Création de la texture
// Création de la texture
if (!CreateTexture(impl, false))
{
NazaraError("Failed to create texture");
@@ -477,7 +347,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
m_impl = impl;
// Paramètres par défaut
// Paramètres par défaut
SetFilterMode(nzTextureFilter_Nearest);
SetMipmapRange(0, m_impl->levelCount);
SetWrapMode(nzTextureWrap_Repeat);
@@ -488,6 +358,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
if (!lock)
UnlockTexture(impl);
NotifyCreated();
return true;
}
@@ -495,13 +366,7 @@ void NzTexture::Destroy()
{
if (m_impl)
{
#if NAZARA_RENDERER_SAFE
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be destroyed");
return;
}
#endif
NotifyDestroy();
NzContext::EnsureContext();
@@ -514,7 +379,7 @@ void NzTexture::Destroy()
bool NzTexture::Download(NzImage* image) const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -527,8 +392,8 @@ bool NzTexture::Download(NzImage* image) const
}
#endif
OpenGLFormat format;
if (!GetOpenGLFormat(m_impl->format, &format))
NzOpenGL::Format format;
if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture))
{
NazaraError("Failed to get OpenGL format");
return false;
@@ -546,10 +411,10 @@ bool NzTexture::Download(NzImage* image) const
unsigned int height = m_impl->height;
unsigned int depth = m_impl->depth;
// Téléchargement...
// Téléchargement...
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
{
glGetTexImage(openglTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level));
glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level));
if (width > 1)
width >>= 1;
@@ -563,7 +428,7 @@ bool NzTexture::Download(NzImage* image) const
UnlockTexture(m_impl);
// Inversion de la texture pour le repère d'OpenGL
// Inversion de la texture pour le repère d'OpenGL
if (!image->FlipVertically())
NazaraWarning("Failed to flip image");
@@ -573,7 +438,7 @@ bool NzTexture::Download(NzImage* image) const
bool NzTexture::EnableMipmapping(bool enable)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -600,19 +465,16 @@ bool NzTexture::EnableMipmapping(bool enable)
unsigned int NzTexture::GetAnisotropyLevel() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return 1;
}
if (!NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter))
{
NazaraError("Anisotropic filter not supported");
return 1;
return 0;
}
#endif
if (!NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter))
return 1;
LockTexture(m_impl);
GLint anisotropyLevel;
@@ -623,23 +485,23 @@ unsigned int NzTexture::GetAnisotropyLevel() const
return anisotropyLevel;
}
nzUInt8 NzTexture::GetBPP() const
nzUInt8 NzTexture::GetBytesPerPixel() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return 0;
}
#endif
return NzPixelFormat::GetBPP(m_impl->format);
return NzPixelFormat::GetBytesPerPixel(m_impl->format);
}
unsigned int NzTexture::GetDepth() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return 0;
@@ -652,7 +514,7 @@ unsigned int NzTexture::GetDepth() const
nzTextureFilter NzTexture::GetFilterMode() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return nzTextureFilter_Unknown;
@@ -689,7 +551,7 @@ nzTextureFilter NzTexture::GetFilterMode() const
nzPixelFormat NzTexture::GetFormat() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return nzPixelFormat_Undefined;
@@ -702,7 +564,7 @@ nzPixelFormat NzTexture::GetFormat() const
unsigned int NzTexture::GetHeight() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return 0;
@@ -715,7 +577,7 @@ unsigned int NzTexture::GetHeight() const
nzImageType NzTexture::GetType() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return nzImageType_2D;
@@ -728,7 +590,7 @@ nzImageType NzTexture::GetType() const
unsigned int NzTexture::GetWidth() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return 0;
@@ -741,7 +603,7 @@ unsigned int NzTexture::GetWidth() const
nzTextureWrap NzTexture::GetWrapMode() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return nzTextureWrap_Unknown;
@@ -773,7 +635,7 @@ nzTextureWrap NzTexture::GetWrapMode() const
bool NzTexture::IsCompressed() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -786,7 +648,7 @@ bool NzTexture::IsCompressed() const
bool NzTexture::IsCubemap() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -799,14 +661,14 @@ bool NzTexture::IsCubemap() const
bool NzTexture::IsTarget() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
#endif
return m_impl->isTarget;
return m_impl->renderTexture != nullptr;
}
bool NzTexture::IsValid() const
@@ -915,7 +777,7 @@ bool NzTexture::LoadFromStream(NzInputStream& stream, const NzImageParams& param
bool NzTexture::Lock()
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -930,14 +792,14 @@ bool NzTexture::Lock()
bool NzTexture::SetAnisotropyLevel(unsigned int anistropyLevel)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
#endif
if (!NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter))
if (anistropyLevel > 1 && !NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter))
{
NazaraError("Anisotropic filter not supported");
return false;
@@ -955,7 +817,7 @@ bool NzTexture::SetAnisotropyLevel(unsigned int anistropyLevel)
bool NzTexture::SetFilterMode(nzTextureFilter filter)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -970,7 +832,7 @@ bool NzTexture::SetFilterMode(nzTextureFilter filter)
LockTexture(m_impl);
GLenum target = openglTarget[m_impl->type];
GLenum target = NzOpenGL::TextureTarget[m_impl->type];
switch (filter)
{
case nzTextureFilter_Bilinear:
@@ -1008,7 +870,7 @@ bool NzTexture::SetFilterMode(nzTextureFilter filter)
bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -1028,8 +890,8 @@ bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
#endif
LockTexture(m_impl);
glTexParameteri(openglTarget[m_impl->type], GL_TEXTURE_BASE_LEVEL, minLevel);
glTexParameteri(openglTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, std::min(m_impl->levelCount, maxLevel));
glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_BASE_LEVEL, minLevel);
glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, std::min(m_impl->levelCount, maxLevel));
UnlockTexture(m_impl);
return true;
@@ -1038,7 +900,7 @@ bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
bool NzTexture::SetWrapMode(nzTextureWrap wrap)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -1063,16 +925,18 @@ bool NzTexture::SetWrapMode(nzTextureWrap wrap)
LockTexture(m_impl);
GLenum target = openglTarget[m_impl->type];
GLenum target = NzOpenGL::TextureTarget[m_impl->type];
switch (m_impl->type)
{
// Notez l'absence de "break" ici
case nzImageType_3D:
glTexParameteri(target, GL_TEXTURE_WRAP_R, wrapMode);
case nzImageType_2D:
case nzImageType_2D_Array:
case nzImageType_Cubemap:
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
case nzImageType_1D:
case nzImageType_1D_Array:
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
break;
@@ -1173,14 +1037,14 @@ bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level
bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
#endif
if (m_impl->type == nzImageType_3D)
if (m_impl->type == nzImageType_3D || m_impl->type == nzImageType_2D_Array)
return Update(pixels, NzCubeui(0, 0, 0, std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U), std::max(m_impl->depth >> level, 1U)), level);
else
return Update(pixels, NzRectui(0, 0, std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U)), 0, level);
@@ -1189,13 +1053,13 @@ bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
if (m_impl->isTarget)
if (m_impl->renderTexture)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
@@ -1242,16 +1106,16 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
}
#endif
OpenGLFormat format;
if (!GetOpenGLFormat(m_impl->format, &format))
NzOpenGL::Format format;
if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture))
{
NazaraError("Failed to get OpenGL format");
return false;
}
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
// Inversion de la texture pour le repère d'OpenGL
NzImage mirrored;
mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height);
mirrored.Update(pixels);
@@ -1268,16 +1132,19 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
glTexSubImage1D(GL_TEXTURE_1D, level, rect.x, rect.width, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_1D_Array:
case nzImageType_2D:
glTexSubImage2D(GL_TEXTURE_2D, level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_2D_Array:
case nzImageType_3D:
glTexSubImage3D(GL_TEXTURE_3D, level, rect.x, height-rect.height-rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored.GetConstPixels());
glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, rect.x, height-rect.height-rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
default:
NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')');
case nzImageType_Cubemap:
NazaraError("Update used on a cubemap texture, please enable safe mode");
break;
}
UnlockTexture(m_impl);
@@ -1287,13 +1154,13 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
if (m_impl->isTarget)
if (m_impl->renderTexture)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
@@ -1336,16 +1203,16 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
}
#endif
OpenGLFormat format;
if (!GetOpenGLFormat(m_impl->format, &format))
NzOpenGL::Format format;
if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture))
{
NazaraError("Failed to get OpenGL format");
return false;
}
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
// Inversion de la texture pour le repère d'OpenGL
unsigned int size = cube.width*cube.height*cube.depth*bpp;
nzUInt8* mirrored = new nzUInt8[size];
if (!NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_impl->format, cube.width, cube.height, cube.depth, pixels, mirrored))
@@ -1363,16 +1230,19 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_1D_Array:
case nzImageType_2D:
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_2D_Array:
case nzImageType_3D:
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
break;
default:
NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')');
case nzImageType_Cubemap:
NazaraError("Update used on a cubemap texture, please enable safe mode");
break;
}
UnlockTexture(m_impl);
@@ -1428,7 +1298,7 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, const NzRec
bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
@@ -1441,13 +1311,13 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 le
bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return false;
}
if (m_impl->isTarget)
if (m_impl->renderTexture)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
@@ -1488,16 +1358,16 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
}
#endif
OpenGLFormat format;
if (!GetOpenGLFormat(m_impl->format, &format))
NzOpenGL::Format format;
if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture))
{
NazaraError("Failed to get OpenGL format");
return false;
}
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
// Inversion de la texture pour le repère d'OpenGL
unsigned int size = rect.width*rect.height*bpp;
nzUInt8* mirrored = new nzUInt8[size];
if (!NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_impl->format, rect.width, rect.height, 1, pixels, mirrored))
@@ -1509,7 +1379,7 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
SetUnpackAlignement(bpp);
LockTexture(m_impl);
glTexSubImage2D(cubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored);
glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored);
UnlockTexture(m_impl);
@@ -1519,7 +1389,7 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
void NzTexture::Unlock()
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
if (!m_impl)
{
NazaraError("Texture must be valid");
return;
@@ -1529,9 +1399,43 @@ void NzTexture::Unlock()
UnlockTexture(m_impl);
}
unsigned int NzTexture::GetOpenGLID() const
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Texture must be valid");
return 0;
}
#endif
return m_impl->id;
}
bool NzTexture::Prepare() const
{
#if NAZARA_RENDERER_SAFE
if (lockedLevel[m_impl->type] > 0)
{
NazaraError("Cannot bind texture while a texture is locked");
return false;
}
#endif
glBindTexture(NzOpenGL::TextureTarget[m_impl->type], m_impl->id);
if (m_impl->mipmapping && !m_impl->mipmapsUpdated)
{
glGenerateMipmap(NzOpenGL::TextureTarget[m_impl->type]);
m_impl->mipmapsUpdated = true;
}
return true;
}
unsigned int NzTexture::GetValidSize(unsigned int size)
{
if (NazaraRenderer->HasCapability(nzRendererCap_TextureNPOT))
if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT))
return size;
else
{
@@ -1554,12 +1458,29 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
case nzPixelFormat_RGBA8:
return true;
// Packed formats supportés depuis OpenGL 1.2
// Packed formats supportés depuis OpenGL 1.2
case nzPixelFormat_RGB5A1:
case nzPixelFormat_RGBA4:
return true;
// Dépréciés depuis OpenGL 3 (FIXME: Il doit bien exister des remplaçants ..)
// Formats de profondeur (Supportés avec les FBOs)
case nzPixelFormat_Depth16:
case nzPixelFormat_Depth24:
case nzPixelFormat_Depth32:
case nzPixelFormat_Depth24Stencil8:
{
static const bool supported = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject);
return supported;
}
// Formats de stencil (Non supportés pour les textures)
case nzPixelFormat_Stencil1:
case nzPixelFormat_Stencil4:
case nzPixelFormat_Stencil8:
case nzPixelFormat_Stencil16:
return false;
// Dépréciés depuis OpenGL 3 (FIXME: Il doit bien exister des remplaçants ..)
case nzPixelFormat_L8:
case nzPixelFormat_LA8:
return false;
@@ -1568,7 +1489,7 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
case nzPixelFormat_DXT3:
case nzPixelFormat_DXT5:
{
static const bool supported = NzOpenGL::IsSupported(NzOpenGL::TextureCompression_s3tc);
static const bool supported = NzOpenGL::IsSupported(nzOpenGLExtension_TextureCompression_s3tc);
return supported;
}
@@ -1594,22 +1515,42 @@ bool NzTexture::IsTypeSupported(nzImageType type)
case nzImageType_2D:
case nzImageType_3D:
case nzImageType_Cubemap:
return true; // Tous supportés nativement dans OpenGL 2
return true; // Tous supportés nativement dans OpenGL 2
default:
return false;
case nzImageType_1D_Array:
case nzImageType_2D_Array:
{
static bool supported = NzOpenGL::IsSupported(nzOpenGLExtension_TextureArray);
return supported;
}
}
NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')');
return false;
}
void NzTexture::SetTarget(bool isTarget)
NzRenderTexture* NzTexture::GetRenderTexture() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraInternalError("Texture must be valid");
return nullptr;
}
#endif
return m_impl->renderTexture;
}
void NzTexture::SetRenderTexture(NzRenderTexture* renderTexture)
{
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraInternalError("Texture must be valid");
return;
}
#endif
m_impl->isTarget = isTarget;
m_impl->renderTexture = renderTexture;
}

View File

@@ -1,8 +1,8 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
@@ -129,7 +129,7 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
return false;
}
// Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte
// Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte
if (DescribePixelFormat(m_deviceContext, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor) != 0)
{
parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits;
@@ -153,28 +153,19 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
*attrib++ = parameters.minorVersion;
int flags = 0;
if (parameters.majorVersion >= 3)
{
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
if (parameters.compatibilityProfile)
*attrib++ = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
else
{
*attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
}
*attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
}
if (parameters.debugMode)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (flags)
{
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = flags;
*attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB;
// Les contextes forward-compatible ne sont plus utilisés pour cette raison :
// http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile
}
*attrib++ = 0;
@@ -210,13 +201,25 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
void NzContextImpl::Destroy()
{
if (m_context)
{
if (wglGetCurrentContext() == m_context)
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(m_context);
m_context = nullptr;
}
if (m_deviceContext)
{
ReleaseDC(m_window, m_deviceContext);
m_deviceContext = nullptr;
}
if (m_ownsWindow)
{
DestroyWindow(m_window);
m_window = nullptr;
}
}
void NzContextImpl::SwapBuffers()

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2012 Jérôme Leclercq
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp

View File

@@ -1,10 +1,11 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Animation.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Config.hpp>
#include <map>
#include <vector>
#include <Nazara/Utility/Debug.hpp>
@@ -32,13 +33,13 @@ NzAnimation::~NzAnimation()
Destroy();
}
unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
bool NzAnimation::AddSequence(const NzSequence& sequence)
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Animation not created");
return 0;
return false;
}
#endif
@@ -51,7 +52,7 @@ unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
if (it != m_impl->sequenceMap.end())
{
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
return 0;
return false;
}
#endif
@@ -60,7 +61,7 @@ unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
m_impl->sequences.push_back(sequence);
return index;
return true;
}
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
@@ -85,6 +86,7 @@ bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
m_impl->frameCount = frameCount;
m_impl->type = type;
NotifyCreated();
return true;
}
@@ -92,6 +94,8 @@ void NzAnimation::Destroy()
{
if (m_impl)
{
NotifyDestroy();
delete m_impl;
m_impl = nullptr;
}
@@ -205,6 +209,28 @@ unsigned int NzAnimation::GetSequenceCount() const
return m_impl->sequences.size();
}
int NzAnimation::GetSequenceIndex(const NzString& sequenceName) const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Animation not created");
return -1;
}
auto it = m_impl->sequenceMap.find(sequenceName);
if (it == m_impl->sequenceMap.end())
{
NazaraError("Sequence not found");
return -1;
}
return it->second;
#else
return m_impl->sequenceMap[sequenceName];
#endif
}
nzAnimationType NzAnimation::GetType() const
{
#if NAZARA_UTILITY_SAFE
@@ -276,13 +302,13 @@ void NzAnimation::RemoveSequence(const NzString& identifier)
auto it = m_impl->sequenceMap.find(identifier);
if (it == m_impl->sequenceMap.end())
{
NazaraError("SubMesh not found");
NazaraError("Sequence not found");
return;
}
unsigned int index = it->second;
int index = it->second;
#else
unsigned int index = m_impl->sequenceMap[identifier];
int index = m_impl->sequenceMap[identifier];
#endif
auto it2 = m_impl->sequences.begin();
@@ -313,6 +339,4 @@ void NzAnimation::RemoveSequence(unsigned int index)
m_impl->sequences.erase(it);
}
std::list<NzAnimationLoader::MemoryLoader> NzAnimation::s_memoryLoaders;
std::list<NzAnimationLoader::StreamLoader> NzAnimation::s_streamLoaders;
std::multimap<NzString, NzAnimationLoader::LoadFileFunction> NzAnimation::s_fileLoaders;
NzAnimationLoader::LoaderList NzAnimation::s_loaders;

View File

@@ -0,0 +1,162 @@
// Copyright (C) 2012 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/Utility/AxisAlignedBox.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Debug.hpp>
NzAxisAlignedBox::NzAxisAlignedBox() :
m_extend(nzExtend_Null)
{
}
NzAxisAlignedBox::NzAxisAlignedBox(const NzVector3f& vec1, const NzVector3f& vec2) :
m_extend(nzExtend_Finite),
m_cube(vec1, vec2)
{
}
NzAxisAlignedBox::NzAxisAlignedBox(nzExtend extend) :
m_extend(extend)
{
}
bool NzAxisAlignedBox::Contains(const NzAxisAlignedBox& box)
{
if (m_extend == nzExtend_Null || box.m_extend == nzExtend_Null)
return false;
else if (m_extend == nzExtend_Infinite || box.m_extend == nzExtend_Infinite)
return true;
return m_cube.Contains(box.m_cube);
}
void NzAxisAlignedBox::ExtendTo(const NzAxisAlignedBox& box)
{
switch (m_extend)
{
case nzExtend_Finite:
{
switch (box.m_extend)
{
case nzExtend_Finite:
m_cube.ExtendTo(box.m_cube);
break;
case nzExtend_Infinite:
SetInfinite();
break;
case nzExtend_Null:
break;
break;
}
case nzExtend_Infinite:
// Rien à faire
break;
case nzExtend_Null:
operator=(box);
break;
}
}
}
void NzAxisAlignedBox::ExtendTo(const NzVector3f& vector)
{
switch (m_extend)
{
case nzExtend_Finite:
m_cube.ExtendTo(vector);
break;
case nzExtend_Infinite:
// Rien à faire
break;
case nzExtend_Null:
// Nous étendons l'AABB en la construisant de l'origine jusqu'au vecteur
m_cube.x = 0.f;
m_cube.y = 0.f;
m_cube.z = 0.f;
m_cube.width = std::fabs(vector.x);
m_cube.height = std::fabs(vector.y);
m_cube.depth = std::fabs(vector.z);
break;
}
}
nzExtend NzAxisAlignedBox::GetExtend() const
{
return m_extend;
}
NzVector3f NzAxisAlignedBox::GetMaximum() const
{
return NzVector3f(m_cube.x+m_cube.width, m_cube.y+m_cube.height, m_cube.z+m_cube.depth);
}
NzVector3f NzAxisAlignedBox::GetMinimum() const
{
return NzVector3f(m_cube.x, m_cube.y, m_cube.z);
}
bool NzAxisAlignedBox::IsFinite() const
{
return m_extend == nzExtend_Finite;
}
bool NzAxisAlignedBox::IsInfinite() const
{
return m_extend == nzExtend_Infinite;
}
bool NzAxisAlignedBox::IsNull() const
{
return m_extend == nzExtend_Null;
}
void NzAxisAlignedBox::SetInfinite()
{
m_extend = nzExtend_Infinite;
}
void NzAxisAlignedBox::SetExtends(const NzVector3f& vec1, const NzVector3f& vec2)
{
m_extend = nzExtend_Finite;
m_cube.Set(vec1, vec2);
}
void NzAxisAlignedBox::SetNull()
{
m_extend = nzExtend_Null;
}
NzString NzAxisAlignedBox::ToString() const
{
switch (m_extend)
{
case nzExtend_Finite:
return "NzAxisAlignedBox(min=" + GetMinimum().ToString() + ", max=" + GetMaximum().ToString() + ')';
case nzExtend_Infinite:
return "NzAxisAlignedBox(Infinite)";
case nzExtend_Null:
return "NzAxisAlignedBox(Null)";
}
return "NzAxisAlignedBox(ERROR)";
}
const NzAxisAlignedBox NzAxisAlignedBox::Infinite(nzExtend_Infinite);
const NzAxisAlignedBox NzAxisAlignedBox::Null(nzExtend_Null);
std::ostream& operator<<(std::ostream& out, const NzAxisAlignedBox& aabb)
{
out << aabb.ToString();
return out;
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Buffer.hpp>
@@ -88,7 +88,7 @@ bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage sto
{
Destroy();
// On tente d'abord de faire un buffer hardware, si supporté
// On tente d'abord de faire un buffer hardware, si supporté
if (s_bufferFunctions[storage])
{
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
@@ -113,14 +113,16 @@ bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage sto
m_storage = storage;
m_usage = usage;
// Si on arrive ici c'est que tout s'est bien passé.
return true;
NotifyCreated();
return true; // Si on arrive ici c'est que tout s'est bien passé.
}
void NzBuffer::Destroy()
{
if (m_impl)
{
NotifyDestroy();
m_impl->Destroy();
delete m_impl;
m_impl = nullptr;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/BufferImpl.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Cursor.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Config.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Icon.hpp>

View File

@@ -1,11 +1,12 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Image.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Config.hpp>
#include <cmath>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>
namespace
@@ -17,7 +18,7 @@ namespace
inline nzUInt8* GetPixelPtr(nzUInt8* base, nzUInt8 bpp, unsigned int x, unsigned int y, unsigned int z, unsigned int width, unsigned int height)
{
return &base[(width*(height*z+y) + x) * bpp];
return &base[(width*(height*z + y) + x)*bpp];
}
}
@@ -31,6 +32,20 @@ m_sharedImage(&emptyImage)
{
}
NzImage::NzImage(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) :
m_sharedImage(&emptyImage)
{
Create(type, format, width, height, depth, levelCount);
#ifdef NAZARA_DEBUG
if (!m_sharedImage)
{
NazaraError("Failed to create image");
throw std::runtime_error("Constructor failed");
}
#endif
}
NzImage::NzImage(const NzImage& image) :
NzResource(image),
m_sharedImage(image.m_sharedImage)
@@ -43,7 +58,7 @@ m_sharedImage(image.m_sharedImage)
}
}
NzImage::NzImage(NzImage&& image) :
NzImage::NzImage(NzImage&& image) noexcept :
m_sharedImage(image.m_sharedImage)
{
image.m_sharedImage = &emptyImage;
@@ -57,7 +72,7 @@ NzImage::~NzImage()
bool NzImage::Convert(nzPixelFormat format)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -84,25 +99,26 @@ bool NzImage::Convert(nzPixelFormat format)
unsigned int width = m_sharedImage->width;
unsigned int height = m_sharedImage->height;
// Les images 3D et cubemaps sont stockés de la même façon
// Les images 3D et cubemaps sont stockés de la même façon
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i)
{
unsigned int pixelsPerFace = width*height;
nzUInt8* ptr = new nzUInt8[pixelsPerFace*depth*NzPixelFormat::GetBPP(format)];
nzUInt8* ptr = new nzUInt8[pixelsPerFace*depth*NzPixelFormat::GetBytesPerPixel(format)];
nzUInt8* pixels = m_sharedImage->pixels[i];
unsigned int srcStride = pixelsPerFace * NzPixelFormat::GetBPP(m_sharedImage->format);
unsigned int dstStride = pixelsPerFace * NzPixelFormat::GetBPP(format);
levels[i] = ptr;
unsigned int srcStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
unsigned int dstStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(format);
for (unsigned int d = 0; d < depth; ++d)
{
if (!NzPixelFormat::Convert(m_sharedImage->format, format, pixels, &pixels[srcStride], ptr))
{
NazaraError("Failed to convert image");
for (unsigned int j = 0; j <= i; ++j)
// Nettoyage de la mémoire
delete[] ptr; // Permet une optimisation de boucle (GCC)
for (unsigned int j = 0; j < i; ++j)
delete[] levels[j];
delete[] levels;
@@ -114,6 +130,8 @@ bool NzImage::Convert(nzPixelFormat format)
ptr += dstStride;
}
levels[i] = ptr;
if (width > 1)
width >>= 1;
@@ -156,13 +174,13 @@ bool NzImage::Copy(const NzImage& source, const NzCubeui& srcCube, const NzVecto
}
/*
Correctif temporaire : Update veut de la mémoire contigüe
Il est donc nécessaire de prendre la partie de la texture que nous voulons mettre à jour
Correctif temporaire : Update veut de la mémoire contigüe
Il est donc nécessaire de prendre la partie de la texture que nous voulons mettre à jour
FIXME: Trouver une interface pour gérer ce genre de problème (Façon OpenGL?)
(Appliquer l'interface à NzTexture également)
///FIXME: Trouver une interface pour gérer ce genre de problème (Façon OpenGL?)
(Appliquer l'interface à NzTexture également)
*/
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
unsigned int dstLineStride = srcCube.width*bpp;
unsigned int dstFaceStride = dstLineStride*srcCube.height;
unsigned int srcLineStride = m_sharedImage->width*bpp;
@@ -197,9 +215,6 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
{
ReleaseImage();
if (width == 0 || height == 0 || depth == 0)
return true;
#if NAZARA_UTILITY_SAFE
if (!NzPixelFormat::IsValid(format))
{
@@ -207,6 +222,24 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
return false;
}
if (width == 0)
{
NazaraError("Width must be at least 1 (0)");
return false;
}
if (height == 0)
{
NazaraError("Height must be at least 1 (0)");
return false;
}
if (depth == 0)
{
NazaraError("Depth must be at least 1 (0)");
return false;
}
switch (type)
{
case nzImageType_1D:
@@ -223,6 +256,7 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
}
break;
case nzImageType_1D_Array:
case nzImageType_2D:
if (depth > 1)
{
@@ -231,6 +265,7 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
}
break;
case nzImageType_2D_Array:
case nzImageType_3D:
break;
@@ -264,10 +299,10 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
for (unsigned int i = 0; i < levelCount; ++i)
{
// Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs
// Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs
try
{
levels[i] = new nzUInt8[w * h * d * NzPixelFormat::GetBPP(format)];
levels[i] = new nzUInt8[w * h * d * NzPixelFormat::GetBytesPerPixel(format)];
if (w > 1)
w >>= 1;
@@ -281,7 +316,10 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
catch (const std::exception& e)
{
NazaraError("Failed to allocate image's level " + NzString::Number(i) + " (" + NzString(e.what()) + ')');
for (unsigned int j = 0; j <= i; ++j)
// Nettoyage
delete[] levels[i]; // Permet une optimisation de boucle (GCC)
for (unsigned int j = 0; j < i; ++j)
delete[] levels[j];
delete[] levels;
@@ -292,18 +330,20 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
m_sharedImage = new SharedImage(1, type, format, levelCount, levels, width, height, depth);
NotifyCreated();
return true;
}
void NzImage::Destroy()
{
NotifyDestroy();
ReleaseImage();
}
bool NzImage::Fill(const NzColor& color)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
#if NAZARA_UTILITY_SAFE
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -318,7 +358,7 @@ bool NzImage::Fill(const NzColor& color)
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
@@ -361,7 +401,7 @@ bool NzImage::Fill(const NzColor& color)
bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -389,7 +429,7 @@ bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z)
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
@@ -399,6 +439,7 @@ bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z)
return false;
}
///FIXME: L'algorithme a du mal avec un bpp non multiple de 2
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, rect.x, rect.y, z, m_sharedImage->width, m_sharedImage->height);
unsigned int srcStride = rect.width * bpp;
unsigned int dstStride = m_sharedImage->width * bpp;
@@ -415,13 +456,15 @@ bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z)
dstPixels += dstStride;
}
delete[] pixels;
return true;
}
bool NzImage::Fill(const NzColor& color, const NzCubeui& cube)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -442,7 +485,7 @@ bool NzImage::Fill(const NzColor& color, const NzCubeui& cube)
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
@@ -452,6 +495,7 @@ bool NzImage::Fill(const NzColor& color, const NzCubeui& cube)
return false;
}
///FIXME: L'algorithme a du mal avec un bpp non multiple de 2
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, cube.x, cube.y, cube.z, m_sharedImage->width, m_sharedImage->height);
unsigned int srcStride = cube.width * bpp;
unsigned int dstStride = m_sharedImage->width * bpp;
@@ -483,7 +527,7 @@ bool NzImage::Fill(const NzColor& color, const NzCubeui& cube)
bool NzImage::FlipHorizontally()
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -522,7 +566,7 @@ bool NzImage::FlipHorizontally()
bool NzImage::FlipVertically()
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -557,26 +601,20 @@ bool NzImage::FlipVertically()
return true;
}
nzUInt8 NzImage::GetBPP() const
nzUInt8 NzImage::GetBytesPerPixel() const
{
return NzPixelFormat::GetBPP(m_sharedImage->format);
return NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
}
const nzUInt8* NzImage::GetConstPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z) const
const nzUInt8* NzImage::GetConstPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level) const
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return nullptr;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
if (x >= m_sharedImage->width)
{
NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')');
@@ -595,9 +633,15 @@ const nzUInt8* NzImage::GetConstPixels(nzUInt8 level, unsigned int x, unsigned i
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return nullptr;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
#endif
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
}
unsigned int NzImage::GetDepth(nzUInt8 level) const
@@ -644,7 +688,7 @@ nzUInt8 NzImage::GetMaxLevel() const
NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return NzColor();
@@ -676,7 +720,7 @@ NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) c
}
#endif
const nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
const nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
NzColor color;
if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r))
@@ -685,21 +729,15 @@ NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) c
return color;
}
nzUInt8* NzImage::GetPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z)
nzUInt8* NzImage::GetPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return nullptr;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
if (x >= m_sharedImage->width)
{
NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')');
@@ -718,11 +756,18 @@ nzUInt8* NzImage::GetPixels(nzUInt8 level, unsigned int x, unsigned int y, unsig
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return nullptr;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
#endif
EnsureOwnership();
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
}
unsigned int NzImage::GetSize() const
@@ -749,7 +794,7 @@ unsigned int NzImage::GetSize() const
if (m_sharedImage->type == nzImageType_Cubemap)
size *= 6;
return size * NzPixelFormat::GetBPP(m_sharedImage->format);
return size * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
}
unsigned int NzImage::GetSize(nzUInt8 level) const
@@ -765,7 +810,7 @@ unsigned int NzImage::GetSize(nzUInt8 level) const
return (GetLevelSize(m_sharedImage->width, level)) *
(GetLevelSize(m_sharedImage->height, level)) *
((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) *
NzPixelFormat::GetBPP(m_sharedImage->format);
NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
}
nzImageType NzImage::GetType() const
@@ -819,7 +864,7 @@ bool NzImage::LoadFromStream(NzInputStream& stream, const NzImageParams& params)
bool NzImage::SetLevelCount(nzUInt8 levelCount)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -864,7 +909,7 @@ bool NzImage::SetLevelCount(nzUInt8 levelCount)
bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y, unsigned int z)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -896,7 +941,7 @@ bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y
}
#endif
nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixel))
{
@@ -910,7 +955,7 @@ bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y
bool NzImage::Update(const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -939,7 +984,7 @@ bool NzImage::Update(const nzUInt8* pixels, nzUInt8 level)
bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, nzUInt8 level)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -977,14 +1022,14 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level);
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')');
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, rect.x, rect.y, z, width, height);
unsigned int srcStride = rect.width * bpp;
unsigned int dstStride = m_sharedImage->width * bpp;
@@ -1000,9 +1045,9 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
///FIXME: Vérifier que ça fonctionne correctement
///FIXME: Vérifier que ça fonctionne correctement
#if NAZARA_UTILITY_SAFE
if (!IsValid())
if (!m_sharedImage)
{
NazaraError("Image must be valid");
return false;
@@ -1041,7 +1086,7 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format);
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, cube.x, cube.y, cube.z, width, height);
unsigned int srcStride = cube.width * bpp;
unsigned int dstStride = width * bpp;
@@ -1077,7 +1122,7 @@ NzImage& NzImage::operator=(const NzImage& image)
return *this;
}
NzImage& NzImage::operator=(NzImage&& image)
NzImage& NzImage::operator=(NzImage&& image) noexcept
{
std::swap(m_sharedImage, image.m_sharedImage);
@@ -1086,11 +1131,11 @@ NzImage& NzImage::operator=(NzImage&& image)
nzUInt8 NzImage::GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth)
{
static const float l2 = std::log(2);
static const float l2 = std::log(2.f);
unsigned int widthLevel = std::log(width)/l2;
unsigned int heightLevel = std::log(height)/l2;
unsigned int depthLevel = std::log(depth)/l2;
unsigned int widthLevel = std::log(static_cast<float>(width))/l2;
unsigned int heightLevel = std::log(static_cast<float>(height))/l2;
unsigned int depthLevel = std::log(static_cast<float>(depth))/l2;
return std::max(std::max(std::max(widthLevel, heightLevel), depthLevel), 1U);
}
@@ -1139,6 +1184,4 @@ void NzImage::ReleaseImage()
}
NzImage::SharedImage NzImage::emptyImage(0, nzImageType_2D, nzPixelFormat_Undefined, 1, nullptr, 0, 0, 0);
std::list<NzImageLoader::MemoryLoader> NzImage::s_memoryLoaders;
std::list<NzImageLoader::StreamLoader> NzImage::s_streamLoaders;
std::multimap<NzString, NzImageLoader::LoadFileFunction> NzImage::s_fileLoaders;
NzImageLoader::LoaderList NzImage::s_loaders;

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/IndexBuffer.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/Keyboard.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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/Utility/KeyframeMesh.hpp>

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// Copyright (C) 2012 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
#pragma once

View File

@@ -1,6 +1,6 @@
// Copyright (C) 2011 Jérôme Leclercq
// This file is part of the "Ungine".
// For conditions of distribution and use, see copyright notice in Core.h
// Copyright (C) 2012 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/Utility/Loaders/MD2/Constants.hpp>

Some files were not shown because too many files have changed in this diff Show More